feat(pruner): account history (#4000)

This commit is contained in:
Alexey Shekhirin
2023-08-02 15:12:53 +01:00
committed by GitHub
parent 9510a5ca7e
commit 88f83fca39
8 changed files with 353 additions and 73 deletions

View File

@ -191,21 +191,22 @@ pub fn random_block_range<R: Rng>(
blocks
}
type Transition = Vec<(Address, Account, Vec<StorageEntry>)>;
/// Collection of account and storage entry changes
pub type ChangeSet = Vec<(Address, Account, Vec<StorageEntry>)>;
type AccountState = (Account, Vec<StorageEntry>);
/// Generate a range of transitions for given blocks and accounts.
/// Generate a range of changesets for given blocks and accounts.
/// Assumes all accounts start with an empty storage.
///
/// Returns a Vec of account and storage changes for each transition,
/// Returns a Vec of account and storage changes for each block,
/// along with the final state of all accounts and storages.
pub fn random_transition_range<'a, R: Rng, IBlk, IAcc>(
pub fn random_changeset_range<'a, R: Rng, IBlk, IAcc>(
rng: &mut R,
blocks: IBlk,
accounts: IAcc,
n_changes: std::ops::Range<u64>,
n_storage_changes: std::ops::Range<u64>,
key_range: std::ops::Range<u64>,
) -> (Vec<Transition>, BTreeMap<Address, AccountState>)
) -> (Vec<ChangeSet>, BTreeMap<Address, AccountState>)
where
IBlk: IntoIterator<Item = &'a SealedBlock>,
IAcc: IntoIterator<Item = (Address, (Account, Vec<StorageEntry>))>,
@ -217,16 +218,20 @@ where
let valid_addresses = state.keys().copied().collect();
let mut transitions = Vec::new();
let mut changesets = Vec::new();
blocks.into_iter().for_each(|block| {
let mut transition = Vec::new();
let (from, to, mut transfer, new_entries) =
random_account_change(rng, &valid_addresses, n_changes.clone(), key_range.clone());
let mut changeset = Vec::new();
let (from, to, mut transfer, new_entries) = random_account_change(
rng,
&valid_addresses,
n_storage_changes.clone(),
key_range.clone(),
);
// extract from sending account
let (prev_from, _) = state.get_mut(&from).unwrap();
transition.push((from, *prev_from, Vec::new()));
changeset.push((from, *prev_from, Vec::new()));
transfer = max(min(transfer, prev_from.balance), U256::from(1));
prev_from.balance = prev_from.balance.wrapping_sub(transfer);
@ -250,11 +255,11 @@ where
})
.collect();
transition.push((to, *prev_to, old_entries));
changeset.push((to, *prev_to, old_entries));
prev_to.balance = prev_to.balance.wrapping_add(transfer);
transitions.push(transition);
changesets.push(changeset);
});
let final_state = state
@ -263,7 +268,7 @@ where
(addr, (acc, storage.into_iter().map(|v| v.into()).collect()))
})
.collect();
(transitions, final_state)
(changesets, final_state)
}
/// Generate a random account change.
@ -272,7 +277,7 @@ where
pub fn random_account_change<R: Rng>(
rng: &mut R,
valid_addresses: &Vec<Address>,
n_changes: std::ops::Range<u64>,
n_storage_changes: std::ops::Range<u64>,
key_range: std::ops::Range<u64>,
) -> (Address, Address, U256, Vec<StorageEntry>) {
let mut addresses = valid_addresses.choose_multiple(rng, 2).cloned();
@ -282,9 +287,13 @@ pub fn random_account_change<R: Rng>(
let balance_change = U256::from(rng.gen::<u64>());
let storage_changes = (0..n_changes.sample_single(rng))
.map(|_| random_storage_entry(rng, key_range.clone()))
.collect();
let storage_changes = if n_storage_changes.is_empty() {
Vec::new()
} else {
(0..n_storage_changes.sample_single(rng))
.map(|_| random_storage_entry(rng, key_range.clone()))
.collect()
};
(addr_from, addr_to, balance_change, storage_changes)
}