storage_type: Strip key proper hash and entry bytes (32 instead of 16) (#1522)

* storage_type: Strip key proper hash and entry bytes (32 instead of 16)

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* storage_type: Fix typo

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* storage/tests: Check keys decode properly and don't cause errors

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update testing/integration-tests/src/full_client/storage/mod.rs

Co-authored-by: James Wilson <james@jsdw.me>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
Alexandru Vasile
2024-04-09 14:08:36 +03:00
committed by Alexandru Vasile
parent d6bf7ae884
commit 3a3f99ad7e
2 changed files with 56 additions and 5 deletions
+5 -5
View File
@@ -255,7 +255,7 @@ where
let key_bytes = kv.key;
let cursor = &mut &key_bytes[..];
strip_storage_addess_root_bytes(cursor)?;
strip_storage_address_root_bytes(cursor)?;
let keys = <Address::Keys as StorageKey>::decode_storage_key(
cursor,
@@ -314,10 +314,10 @@ where
}
}
/// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes.
fn strip_storage_addess_root_bytes(address_bytes: &mut &[u8]) -> Result<(), StorageAddressError> {
if address_bytes.len() >= 16 {
*address_bytes = &address_bytes[16..];
/// Strips the first 32 bytes (16 for the pallet hash, 16 for the entry hash) off some storage address bytes.
fn strip_storage_address_root_bytes(address_bytes: &mut &[u8]) -> Result<(), StorageAddressError> {
if address_bytes.len() >= 32 {
*address_bytes = &address_bytes[32..];
Ok(())
} else {
Err(StorageAddressError::UnexpectedAddressBytes)
@@ -228,3 +228,54 @@ async fn storage_pallet_storage_version() -> Result<(), subxt::Error> {
.await?;
Ok(())
}
#[subxt_test]
async fn storage_iter_decode_keys() -> Result<(), subxt::Error> {
use futures::StreamExt;
let ctx = test_context().await;
let api = ctx.client();
let storage_static = node_runtime::storage().system().account_iter();
let results_static = api
.storage()
.at_latest()
.await?
.iter(storage_static)
.await?;
let storage_dynamic = subxt::dynamic::storage("System", "Account", vec![]);
let results_dynamic = api
.storage()
.at_latest()
.await?
.iter(storage_dynamic)
.await?;
// Even the testing node should have more than 3 accounts registered.
let results_static = results_static.take(3).collect::<Vec<_>>().await;
let results_dynamic = results_dynamic.take(3).collect::<Vec<_>>().await;
assert_eq!(results_static.len(), 3);
assert_eq!(results_dynamic.len(), 3);
let twox_system = sp_core::twox_128("System".as_bytes());
let twox_account = sp_core::twox_128("Account".as_bytes());
for (static_kv, dynamic_kv) in results_static.into_iter().zip(results_dynamic.into_iter()) {
let static_kv = static_kv?;
let dynamic_kv = dynamic_kv?;
// We only care about the underlying key bytes.
assert_eq!(static_kv.key_bytes, dynamic_kv.key_bytes);
let bytes = static_kv.key_bytes;
assert!(bytes.len() > 32);
// The first 16 bytes should be the twox hash of "System" and the next 16 bytes should be the twox hash of "Account".
assert_eq!(&bytes[..16], &twox_system[..]);
assert_eq!(&bytes[16..32], &twox_account[..]);
}
Ok(())
}