Skip to content

sync_storage_maps drops the block number of each map entry #2536

Description

@Mustdzyl

NodeRpcClient::sync_storage_maps folds the node's StorageMapUpdates into StorageMapInfo.map_entries, and
the block in which each entry was last updated is lost on the way. The node sends it
(StorageMapUpdate.block_num, "Block number in which the slot was updated") and
storage_map_update_from_proto parses it, but the fold in
crates/rust-client/src/rpc/domain/storage_map.rs ignores it:

for (_, slot_name, key, value) in updates {
    map_entries.entry(slot_name).or_default().insert(key, value);
}

The only block that survives is StorageMapInfo.block_number, which is the last block of the
page. The tonic client then merges pages the same way.

In the web client this shows up as StorageMapUpdate.blockNum() returning the same number for
every entry. I checked it on testnet with account 0xce3ae4c0d1ed23d12567e7d2862202, where 53
keys were each written once across 10 different blocks (compared against a node's
account_storage_map_values table). RpcClient.syncStorageMaps() returned 120984, the chain tip,
for all 53. Calling SyncAccountStorageMaps directly over gRPC-web returned the 10 blocks
correctly.

Why I need it: I am building a two-player commit-reveal game, and the verifier has to check that
both commitments were included before either reveal. The block number a transaction script can
read is the reference block, which the client picks, so the inclusion block from the node is the
only ordering signal I can rely on.

The fold makes sense for syncing account state, so I do not think map_entries should change.
Two options I can see:

  1. Keep the fold, and also keep the block of the latest update per key in a separate field on
    StorageMapInfo.
  2. Add a method that returns the updates unfolded, with their block numbers.

Option 1 adds a field to StorageMapInfo, so the struct literals in the tests of #2503 would
need it too. Keeping the per-entry blocks would also let VerifyingRpcClient check that each
update falls inside the requested window, not only the page cursor (#2454).

Which would you prefer? I can open a PR for either. I haven't checked whether
sync_account_vault has the same pattern.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions