Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 46 additions & 79 deletions crates/storage/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2379,65 +2379,7 @@ impl Store {
state_trie: &mut Trie,
account_updates: impl IntoIterator<Item = &'a AccountUpdate>,
) -> Result<AccountUpdatesList, StoreError> {
let mut ret_storage_updates = Vec::new();
let mut code_updates = Vec::new();
let state_root = state_trie.hash_no_commit(&NativeCrypto);
for update in account_updates {
let hashed_address = hash_address_fixed(&update.address);
if update.removed {
// Remove account from trie
state_trie.remove(hashed_address.as_bytes())?;
continue;
}
// Add or update AccountState in the trie
// Fetch current state or create a new state to be inserted
let mut account_state = match state_trie.get(hashed_address.as_bytes())? {
Some(encoded_state) => AccountState::decode(&encoded_state)?,
None => AccountState::default(),
};
if update.removed_storage {
account_state.storage_root = EMPTY_TRIE_HASH;
}
if let Some(info) = &update.info {
account_state.nonce = info.nonce;
account_state.balance = info.balance;
account_state.code_hash = info.code_hash;
// Store updated code in DB
if let Some(code) = &update.code {
code_updates.push((info.code_hash, code.clone()));
}
}
// Store the added storage in the account's storage trie and compute its new root
if !update.added_storage.is_empty() {
let mut storage_trie =
self.open_storage_trie(hashed_address, state_root, account_state.storage_root)?;
for (storage_key, storage_value) in &update.added_storage {
let hashed_key = hash_key(storage_key);
if storage_value.is_zero() {
storage_trie.remove(&hashed_key)?;
} else {
storage_trie.insert(hashed_key, storage_value.encode_to_vec())?;
}
}
let (storage_hash, storage_updates) =
storage_trie.collect_changes_since_last_hash(&NativeCrypto);
account_state.storage_root = storage_hash;
ret_storage_updates.push((hashed_address, storage_updates));
}
state_trie.insert(
hashed_address.as_bytes().to_vec(),
account_state.encode_to_vec(),
)?;
}
let (state_trie_hash, state_updates) =
state_trie.collect_changes_since_last_hash(&NativeCrypto);

Ok(AccountUpdatesList {
state_trie_hash,
state_updates,
storage_updates: ret_storage_updates,
code_updates,
})
self.apply_account_updates_from_trie_inner(state_trie, account_updates, None)
}

/// Performs the same actions as apply_account_updates_from_trie
Expand All @@ -2448,25 +2390,45 @@ impl Store {
account_updates: &[AccountUpdate],
mut storage_tries: StorageTries,
) -> Result<(StorageTries, AccountUpdatesList), StoreError> {
let account_updates_list = self.apply_account_updates_from_trie_inner(
&mut state_trie,
account_updates,
Some(&mut storage_tries),
)?;
Ok((storage_tries, account_updates_list))
}

/// Applies account updates to the given state trie.
///
/// With `storage_tries`, storage tries are opened through [`TrieLogger`] and
/// cached in the map (keyed by unhashed address) so witness recording spans
/// updates; without it, a fresh storage trie is opened per account at its
/// current storage root.
fn apply_account_updates_from_trie_inner<'a>(
&self,
state_trie: &mut Trie,
account_updates: impl IntoIterator<Item = &'a AccountUpdate>,
mut storage_tries: Option<&mut StorageTries>,
) -> Result<AccountUpdatesList, StoreError> {
let mut ret_storage_updates = Vec::new();

let mut code_updates = Vec::new();

let state_root = state_trie.hash_no_commit(&NativeCrypto);

for update in account_updates.iter() {
let hashed_address = hash_address(&update.address);
for update in account_updates {
let hashed_address = hash_address_fixed(&update.address);

if update.removed {
// Remove account from trie
state_trie.remove(&hashed_address)?;
state_trie.remove(hashed_address.as_bytes())?;

continue;
}

// Add or update AccountState in the trie
// Fetch current state or create a new state to be inserted
let mut account_state = match state_trie.get(&hashed_address)? {
let mut account_state = match state_trie.get(hashed_address.as_bytes())? {
Some(encoded_state) => AccountState::decode(&encoded_state)?,
None => AccountState::default(),
};
Expand All @@ -2490,16 +2452,20 @@ impl Store {

// Store the added storage in the account's storage trie and compute its new root
if !update.added_storage.is_empty() {
let (_witness, storage_trie) = match storage_tries.entry(update.address) {
Entry::Occupied(value) => value.into_mut(),
Entry::Vacant(vacant) => {
let trie = self.open_storage_trie(
H256::from_slice(&hashed_address),
state_root,
account_state.storage_root,
)?;
vacant.insert(TrieLogger::open_trie(trie))
}
let open_fresh_trie = || {
self.open_storage_trie(hashed_address, state_root, account_state.storage_root)
};

let mut local_trie = None;

let storage_trie = match storage_tries.as_deref_mut() {
Some(tries) => match tries.entry(update.address) {
Entry::Occupied(cached) => &mut cached.into_mut().1,
Entry::Vacant(vacant) => {
&mut vacant.insert(TrieLogger::open_trie(open_fresh_trie()?)).1
}
},
None => local_trie.insert(open_fresh_trie()?),
};

for (storage_key, storage_value) in &update.added_storage {
Expand All @@ -2517,23 +2483,24 @@ impl Store {

account_state.storage_root = storage_hash;

ret_storage_updates.push((H256::from_slice(&hashed_address), storage_updates));
ret_storage_updates.push((hashed_address, storage_updates));
}

state_trie.insert(hashed_address, account_state.encode_to_vec())?;
state_trie.insert(
hashed_address.as_bytes().to_vec(),
account_state.encode_to_vec(),
)?;
Comment on lines +2489 to +2492

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a good way to reduce lines of code:

Suggested change
state_trie.insert(
hashed_address.as_bytes().to_vec(),
account_state.encode_to_vec(),
)?;
let hashed_address_vec = hashed_address.as_bytes().to_vec();
state_trie.insert(hashed_address_vec, account_state.encode_to_vec())?;

}

let (state_trie_hash, state_updates) =
state_trie.collect_changes_since_last_hash(&NativeCrypto);

let account_updates_list = AccountUpdatesList {
Ok(AccountUpdatesList {
Comment on lines -2529 to +2498

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also not a good way to reduce lines of code

state_trie_hash,
state_updates,
storage_updates: ret_storage_updates,
code_updates,
};

Ok((storage_tries, account_updates_list))
})
}

/// Adds all genesis accounts and returns the genesis block's state_root
Expand Down
Loading