mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 05:41:07 +00:00
chainHead/storage: Fix storage iteration using the query key (#1665)
This PR ensures that all storage keys under a prefix are returned by the `chainHead_storage` method. Before this PR, the `storage_keys` was used with just the `start_key`. Before the pagination event was generated, the last reported key `last_key` was saved internally. When the pagination is resumed, the `last_key` will serve as the next `start_key` to the `storage_keys` API. However, this behavior does not function properly for non-prefixed storage keys. Entry keys `a`, `ab`, `abc` share a common prefix and therefore the `ab` key leads to `abc`. However, for `a`, `ab`, `aB` and `abc`, the `aB` key does not immediately lead to `abc`. To mitigate this, the PR saves the start key of the query, together with the next pagination key. Improve testing to ensure we have a key entry that doesn't share the prefix with the descendant key. @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
@@ -2352,6 +2352,7 @@ async fn check_continue_operation() {
|
||||
builder.push_storage_change(b":m".to_vec(), Some(b"a".to_vec())).unwrap();
|
||||
builder.push_storage_change(b":mo".to_vec(), Some(b"ab".to_vec())).unwrap();
|
||||
builder.push_storage_change(b":moc".to_vec(), Some(b"abc".to_vec())).unwrap();
|
||||
builder.push_storage_change(b":moD".to_vec(), Some(b"abcmoD".to_vec())).unwrap();
|
||||
builder.push_storage_change(b":mock".to_vec(), Some(b"abcd".to_vec())).unwrap();
|
||||
let block = builder.build().unwrap().block;
|
||||
let block_hash = format!("{:?}", block.header.hash());
|
||||
@@ -2430,6 +2431,25 @@ async fn check_continue_operation() {
|
||||
res.items[0].result == StorageResultType::Value(hex_string(b"ab"))
|
||||
);
|
||||
|
||||
// Pagination event.
|
||||
assert_matches!(
|
||||
get_next_event::<FollowEvent<String>>(&mut sub).await,
|
||||
FollowEvent::OperationWaitingForContinue(res) if res.operation_id == operation_id
|
||||
);
|
||||
does_not_produce_event::<FollowEvent<String>>(
|
||||
&mut sub,
|
||||
std::time::Duration::from_secs(DOES_NOT_PRODUCE_EVENTS_SECONDS),
|
||||
)
|
||||
.await;
|
||||
let _res: () = api.call("chainHead_unstable_continue", [&sub_id, &operation_id]).await.unwrap();
|
||||
assert_matches!(
|
||||
get_next_event::<FollowEvent<String>>(&mut sub).await,
|
||||
FollowEvent::OperationStorageItems(res) if res.operation_id == operation_id &&
|
||||
res.items.len() == 1 &&
|
||||
res.items[0].key == hex_string(b":moD") &&
|
||||
res.items[0].result == StorageResultType::Value(hex_string(b"abcmoD"))
|
||||
);
|
||||
|
||||
// Pagination event.
|
||||
assert_matches!(
|
||||
get_next_event::<FollowEvent<String>>(&mut sub).await,
|
||||
|
||||
Reference in New Issue
Block a user