Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Fixes storage_hash caching issue and enables better caching for Cum…
Browse files Browse the repository at this point in the history
…ulus (#8518)

* Fixes `storage_hash` caching issue and enables better caching for Cumulus

There was a caching issue with `storage_hash` that resulted in not
reverting cached storage hashes when required. In Cumulus this resulted
in nodes failing to import new blocks after a runtime upgrade, because
they were using the old runtime version.

Besides that, this pr optimizes for the Cumulus use case. In particular
that we always import blocks first as non-best blocks and enact them
later. In current version of the caching that would mean we would always
throw away the complete cache of the latest imported block. Now, we
always update the cache for the first block of a new block height. This
enables us to use the cache if this block will enacted as best block
later. If there is a fork and that is enacted as best, we revert all the
changes to the cache.

* Apply suggestions from code review

Co-authored-by: Arkadiy Paronyan <arkady.paronyan@gmail.com>

* Indentation

* Update client/db/src/storage_cache.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

Co-authored-by: Arkadiy Paronyan <arkady.paronyan@gmail.com>
Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 3, 2021
1 parent 07b3b91 commit 85eef08
Show file tree
Hide file tree
Showing 2 changed files with 366 additions and 88 deletions.
94 changes: 94 additions & 0 deletions client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2744,6 +2744,100 @@ pub(crate) mod tests {
}
}

#[test]
fn storage_hash_is_cached_correctly() {
let backend = Backend::<Block>::new_test(10, 10);

let hash0 = {
let mut op = backend.begin_operation().unwrap();
backend.begin_state_operation(&mut op, BlockId::Hash(Default::default())).unwrap();
let mut header = Header {
number: 0,
parent_hash: Default::default(),
state_root: Default::default(),
digest: Default::default(),
extrinsics_root: Default::default(),
};

let storage = vec![(b"test".to_vec(), b"test".to_vec())];

header.state_root = op.old_state.storage_root(storage
.iter()
.map(|(x, y)| (&x[..], Some(&y[..])))
).0.into();
let hash = header.hash();

op.reset_storage(Storage {
top: storage.into_iter().collect(),
children_default: Default::default(),
}).unwrap();
op.set_block_data(
header.clone(),
Some(vec![]),
None,
NewBlockState::Best,
).unwrap();

backend.commit_operation(op).unwrap();

hash
};

let block0_hash = backend.state_at(BlockId::Hash(hash0))
.unwrap()
.storage_hash(&b"test"[..])
.unwrap();

let hash1 = {
let mut op = backend.begin_operation().unwrap();
backend.begin_state_operation(&mut op, BlockId::Number(0)).unwrap();
let mut header = Header {
number: 1,
parent_hash: hash0,
state_root: Default::default(),
digest: Default::default(),
extrinsics_root: Default::default(),
};

let storage = vec![(b"test".to_vec(), Some(b"test2".to_vec()))];

let (root, overlay) = op.old_state.storage_root(
storage.iter()
.map(|(k, v)| (&k[..], v.as_ref().map(|v| &v[..])))
);
op.update_db_storage(overlay).unwrap();
header.state_root = root.into();
let hash = header.hash();

op.update_storage(storage, Vec::new()).unwrap();
op.set_block_data(
header,
Some(vec![]),
None,
NewBlockState::Normal,
).unwrap();

backend.commit_operation(op).unwrap();

hash
};

{
let header = backend.blockchain().header(BlockId::Hash(hash1)).unwrap().unwrap();
let mut op = backend.begin_operation().unwrap();
backend.begin_state_operation(&mut op, BlockId::Hash(hash0)).unwrap();
op.set_block_data(header, None, None, NewBlockState::Best).unwrap();
backend.commit_operation(op).unwrap();
}

let block1_hash = backend.state_at(BlockId::Hash(hash1))
.unwrap()
.storage_hash(&b"test"[..])
.unwrap();

assert_ne!(block0_hash, block1_hash);
}

#[test]
fn test_finalize_non_sequential() {
let backend = Backend::<Block>::new_test(10, 10);
Expand Down
Loading

0 comments on commit 85eef08

Please sign in to comment.