You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Modification of block header is dangerous as it leads to an inconsistency in the store layer where the generated block_hash doesn't match the block header content. For my use case, this was exposed by setting no_cache feature to true which prevents the caching of blocks and block headers.
Calculation of block hash
Block hash is stored as a cached field in the block header and is NOT serialized. This means we "generate" the block hash every time we serialize/deserialize a block.
/// Cached value of hash for this block.
#[borsh(skip)]
pub hash: CryptoHash,
Block hash is generated via the init function
pub fn init(&mut self) {
self.hash = BlockHeader::compute_hash(
self.prev_hash,
&borsh::to_vec(&self.inner_lite).expect("Failed to serialize"),
&borsh::to_vec(&self.inner_rest).expect("Failed to serialize"),
);
}
Store layer
While generating the block, we store the block in the database DBCol::Block column. The key here is the hash of the block and it's expected that block.hash() would match the key.
In ChainStore we also cache the block and block header.
Test pattern
In tests, after generating a block, we modify the header before processing it. In case we forget to resign the block, it can lead to an inconsistency between the stored block hash in cache and generated block hash from store.
...
let mut block = env.clients[0].produce_block(i).unwrap().unwrap();
block.mut_header().set_latest_protocol_version(protocol_version);
env.process_block(0, block.clone(), Provenance::PRODUCED);
for j in 1..env.clients.len() {
env.process_block(j, block.clone(), Provenance::NONE);
}
...
The text was updated successfully, but these errors were encountered:
Uncovered a weird issue by setting "no_cache" feature.
Another reason why the store layer cache should be removed.
Please take a look at issue
near#12160
Description
Note: This issue is related to tests only.
Modification of block header is dangerous as it leads to an inconsistency in the store layer where the generated block_hash doesn't match the block header content. For my use case, this was exposed by setting
no_cache
feature to true which prevents the caching of blocks and block headers.Calculation of block hash
Block hash is stored as a cached field in the block header and is NOT serialized. This means we "generate" the block hash every time we serialize/deserialize a block.
Block hash is generated via the
init
functionStore layer
While generating the block, we store the block in the database
DBCol::Block
column. The key here is the hash of the block and it's expected thatblock.hash()
would match the key.In
ChainStore
we also cache the block and block header.Test pattern
In tests, after generating a block, we modify the header before processing it. In case we forget to resign the block, it can lead to an inconsistency between the stored block hash in cache and generated block hash from store.
The text was updated successfully, but these errors were encountered: