Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow updates to all item slots #737

Merged
merged 15 commits into from
Jun 11, 2024
28 changes: 21 additions & 7 deletions objects/src/accounts/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ impl AccountStorage {
let slots = SimpleSmt::<STORAGE_TREE_DEPTH>::with_leaves(entries)
.map_err(AccountError::DuplicateStorageItems)?;

if maps.len() > num_maps {
// make sure the number of provide maps matches the number of map slots
if maps.len() != num_maps {
return Err(AccountError::StorageMapTooManyMaps {
expected: num_maps,
actual: maps.len(),
Expand Down Expand Up @@ -263,13 +264,8 @@ impl AccountStorage {
/// - The updates violate storage layout constraints.
/// - The updated value has an arity different from 0.
pub(super) fn apply_delta(&mut self, delta: &AccountStorageDelta) -> Result<(), AccountError> {
for &slot_idx in delta.cleared_items.iter() {
self.set_item(slot_idx, Word::default())?;
}

for &(slot_idx, slot_value) in delta.updated_items.iter() {
self.set_item(slot_idx, slot_value)?;
}
// --- update storage maps --------------------------------------------

for &(slot_idx, ref map_delta) in delta.updated_maps.iter() {
// layout commitment slot cannot be updated
Expand All @@ -283,6 +279,18 @@ impl AccountStorage {
storage_map.apply_delta(map_delta)?;
}

// --- update storage slots -------------------------------------------
// this will also update roots of updated storage maps, and thus should be run after we
// update storage maps - otherwise the roots won't match
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the order doesn't matter, the storage root update is queued in updated_items and the maps update in updated_maps. Both are triggered in MASM in set_map_item

Copy link
Contributor

@bobbinth bobbinth Jun 12, 2024

Choose a reason for hiding this comment

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

In combination with the code I linked above, the order does matter (otherwise tests won't pass). But also, this code is separate from MASM: when executing MASM we are building the delta, here we are applying it - which happens later.


for &slot_idx in delta.cleared_items.iter() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I've also added this code which ensures that slots corresponding to storage maps can be set only to the roots of these maps. So, if we try to update the roots first (before updating the maps themselves), the assertion would get triggered.

self.set_item(slot_idx, Word::default())?;
}

for &(slot_idx, slot_value) in delta.updated_items.iter() {
self.set_item(slot_idx, slot_value)?;
}

Ok(())
}

Expand Down Expand Up @@ -318,6 +326,12 @@ impl AccountStorage {
actual: value_arity,
});
}

// make sure the value matches the root of the corresponding storage map
// TODO: we should remove handling of storage map updates from set_item();
// once this is done, these checks would not be necessary
let storage_map = self.maps.get(&index).expect("storage map not found");
assert_eq!(storage_map.root(), value.into());
},
slot_type => Err(AccountError::StorageSlotArrayNotAllowed(index, slot_type))?,
}
Expand Down
Loading