mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Allow updating configuration of changes tries (#3201)
* DigestItem::ChangesTrieSignal * introduce changes_trie::State * introduce config activation block * ChangesTrieSignal::as_new_configuration * moved well_known_cache_keys to client * extracted DbChangesTrieStorage to separate file * change meaning of none in blockchain cache * changes trie config (FULL) cache draft * eliminating const ChangesTrieConfiguration * delay pruning * continue elimination * do not prune CT config from cache * removed redundant code * fix some TODOs * introduce ConfigurationRange * use Configuration range in build * build skewed digest * remove debug print * extracted surface iterator * key_changes works with skewed digests * fix client build * add test for NeverPrune * fix TODO * fixed some TODOs * more tests * fixing TODOs * fixed compilation * update runtime version * git rid of large tuple * too long lines * config_activation_block -> zero * obsolete TODO * removed unjustified expect * update TODOs with issue number * new CT pruning algorithm fixed cache + multiple blocks finalization track CT configuraiton on light clients support CT configuration change revert revert CT config test new CT pruning algorithm fixed cache + multiple blocks finalization track CT configuraiton on light clients support CT configuration change revert revert CT config test * BlockIdOrHeader isn't really required * removed debug leftovers + some docs * more docs * more post-merge fixes * more post-merge fixes * revertes some unnecessary changes * reverted unnecessary changes * fix compilation + unnecessary changes * (restart CI) * fix cache update when finalizing multiple blocks * fixed tests * collect_extrinsics -> set_collect_extrinsics * restore lost test * do not calculate block number twice * Update primitives/blockchain/src/error.rs Co-Authored-By: cheme <emericchevalier.pro@gmail.com> * map_err -> unwrap_or * document get_at Result * delete abandoned file * added weight for set_changes_trie_config * prefer_configs -> fail_if_disabled * Update client/api/src/backend.rs Co-Authored-By: cheme <emericchevalier.pro@gmail.com> * Update client/db/src/changes_tries_storage.rs Co-Authored-By: cheme <emericchevalier.pro@gmail.com> * CommitOperation+merge -> CommitOperations * fixed test compilation * merged two different CTRange structs * lost file * uggrade db from v0 to v1 (init CT cache + add column) * fix after merge Co-authored-by: cheme <emericchevalier.pro@gmail.com> Co-authored-by: Gavin Wood <github@gavwood.com>
This commit is contained in:
committed by
Gavin Wood
parent
45fbf09dac
commit
febf29390a
@@ -21,19 +21,22 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use sp_core::storage::{ChildInfo, OwnedChildInfo};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
use sp_core::ChangesTrieConfiguration;
|
||||
use sp_core::storage::{well_known_keys, ChildInfo, OwnedChildInfo};
|
||||
use sp_core::offchain::storage::InMemOffchainStorage;
|
||||
use sp_state_machine::{
|
||||
Backend as StateBackend, TrieBackend, InMemoryBackend, ChangesTrieTransaction
|
||||
};
|
||||
use sp_runtime::{generic::BlockId, Justification, Storage};
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor, Zero, Header, HasherFor};
|
||||
use crate::in_mem::{self, check_genesis_storage};
|
||||
use crate::in_mem::check_genesis_storage;
|
||||
use sp_blockchain::{Error as ClientError, Result as ClientResult};
|
||||
use sc_client_api::{
|
||||
backend::{
|
||||
AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState,
|
||||
StorageCollection, ChildStorageCollection,
|
||||
StorageCollection, ChildStorageCollection, PrunableStateChangesTrieStorage,
|
||||
},
|
||||
blockchain::{
|
||||
HeaderBackend as BlockchainHeaderBackend, well_known_cache_keys,
|
||||
@@ -62,6 +65,7 @@ pub struct ImportOperation<Block: BlockT, S> {
|
||||
finalized_blocks: Vec<BlockId<Block>>,
|
||||
set_head: Option<BlockId<Block>>,
|
||||
storage_update: Option<InMemoryBackend<HasherFor<Block>>>,
|
||||
changes_trie_config_update: Option<Option<ChangesTrieConfiguration>>,
|
||||
_phantom: std::marker::PhantomData<S>,
|
||||
}
|
||||
|
||||
@@ -115,7 +119,6 @@ impl<S, Block> ClientBackend<Block> for Backend<S, HasherFor<Block>>
|
||||
type BlockImportOperation = ImportOperation<Block, S>;
|
||||
type Blockchain = Blockchain<S>;
|
||||
type State = GenesisOrUnavailableState<HasherFor<Block>>;
|
||||
type ChangesTrieStorage = in_mem::ChangesTrieStorage<Block>;
|
||||
type OffchainStorage = InMemOffchainStorage;
|
||||
|
||||
fn begin_operation(&self) -> ClientResult<Self::BlockImportOperation> {
|
||||
@@ -127,6 +130,7 @@ impl<S, Block> ClientBackend<Block> for Backend<S, HasherFor<Block>>
|
||||
finalized_blocks: Vec::new(),
|
||||
set_head: None,
|
||||
storage_update: None,
|
||||
changes_trie_config_update: None,
|
||||
_phantom: Default::default(),
|
||||
})
|
||||
}
|
||||
@@ -148,6 +152,9 @@ impl<S, Block> ClientBackend<Block> for Backend<S, HasherFor<Block>>
|
||||
|
||||
if let Some(header) = operation.header {
|
||||
let is_genesis_import = header.number().is_zero();
|
||||
if let Some(new_config) = operation.changes_trie_config_update {
|
||||
operation.cache.insert(well_known_cache_keys::CHANGES_TRIE_CONFIG, new_config.encode());
|
||||
}
|
||||
self.blockchain.storage().import_header(
|
||||
header,
|
||||
operation.cache,
|
||||
@@ -194,7 +201,7 @@ impl<S, Block> ClientBackend<Block> for Backend<S, HasherFor<Block>>
|
||||
self.blockchain.storage().usage_info()
|
||||
}
|
||||
|
||||
fn changes_trie_storage(&self) -> Option<&Self::ChangesTrieStorage> {
|
||||
fn changes_trie_storage(&self) -> Option<&dyn PrunableStateChangesTrieStorage<Block>> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -296,6 +303,13 @@ impl<S, Block> BlockImportOperation<Block> for ImportOperation<Block, S>
|
||||
fn reset_storage(&mut self, input: Storage) -> ClientResult<Block::Hash> {
|
||||
check_genesis_storage(&input)?;
|
||||
|
||||
// changes trie configuration
|
||||
let changes_trie_config = input.top.iter()
|
||||
.find(|(k, _)| &k[..] == well_known_keys::CHANGES_TRIE_CONFIG)
|
||||
.map(|(_, v)| Decode::decode(&mut &v[..])
|
||||
.expect("changes trie configuration is encoded properly at genesis"));
|
||||
self.changes_trie_config_update = Some(changes_trie_config);
|
||||
|
||||
// this is only called when genesis block is imported => shouldn't be performance bottleneck
|
||||
let mut storage: HashMap<Option<(Vec<u8>, OwnedChildInfo)>, _> = HashMap::new();
|
||||
storage.insert(None, input.top);
|
||||
|
||||
@@ -259,7 +259,7 @@ fn check_execution_proof_with_make_header<Header, E, H, MakeNextHeader: Fn(&Head
|
||||
let mut changes = OverlayedChanges::default();
|
||||
let trie_backend = create_proof_check_backend(root, remote_proof)?;
|
||||
let next_header = make_next_header(&request.header);
|
||||
execution_proof_check_on_trie_backend::<H, _>(
|
||||
execution_proof_check_on_trie_backend::<H, Header::Number, _>(
|
||||
&trie_backend,
|
||||
&mut changes,
|
||||
executor,
|
||||
@@ -268,7 +268,7 @@ fn check_execution_proof_with_make_header<Header, E, H, MakeNextHeader: Fn(&Head
|
||||
)?;
|
||||
|
||||
// execute method
|
||||
execution_proof_check_on_trie_backend::<H, _>(
|
||||
execution_proof_check_on_trie_backend::<H, Header::Number, _>(
|
||||
&trie_backend,
|
||||
&mut changes,
|
||||
executor,
|
||||
|
||||
@@ -25,12 +25,12 @@ use codec::{Decode, Encode};
|
||||
use sp_core::{convert_hash, traits::CodeExecutor};
|
||||
use sp_runtime::traits::{
|
||||
Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor,
|
||||
SimpleArithmetic, CheckedConversion, Zero,
|
||||
SimpleArithmetic, CheckedConversion,
|
||||
};
|
||||
use sp_state_machine::{
|
||||
ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange,
|
||||
TrieBackend, read_proof_check, key_changes_proof_check, create_proof_check_backend_storage,
|
||||
read_child_proof_check,
|
||||
InMemoryChangesTrieStorage, TrieBackend, read_proof_check, key_changes_proof_check_with_db,
|
||||
create_proof_check_backend_storage, read_child_proof_check,
|
||||
};
|
||||
pub use sp_state_machine::StorageProof;
|
||||
use sp_blockchain::{Error as ClientError, Result as ClientResult};
|
||||
@@ -113,30 +113,34 @@ impl<E, H, B: BlockT, S: BlockchainStorage<B>> LightDataChecker<E, H, B, S> {
|
||||
)?;
|
||||
}
|
||||
|
||||
// FIXME: remove this in https://github.com/paritytech/substrate/pull/3201
|
||||
let changes_trie_config_range = ChangesTrieConfigurationRange {
|
||||
config: &request.changes_trie_config,
|
||||
zero: Zero::zero(),
|
||||
end: None,
|
||||
};
|
||||
|
||||
// and now check the key changes proof + get the changes
|
||||
key_changes_proof_check::<H, _>(
|
||||
changes_trie_config_range,
|
||||
&RootsStorage {
|
||||
roots: (request.tries_roots.0, &request.tries_roots.2),
|
||||
prev_roots: remote_roots,
|
||||
},
|
||||
remote_proof,
|
||||
request.first_block.0,
|
||||
&ChangesTrieAnchorBlockId {
|
||||
hash: convert_hash(&request.last_block.1),
|
||||
number: request.last_block.0,
|
||||
},
|
||||
remote_max_block,
|
||||
request.storage_key.as_ref().map(Vec::as_slice),
|
||||
&request.key)
|
||||
.map_err(|err| ClientError::ChangesTrieAccessFailed(err))
|
||||
let mut result = Vec::new();
|
||||
let proof_storage = InMemoryChangesTrieStorage::with_proof(remote_proof);
|
||||
for config_range in &request.changes_trie_configs {
|
||||
let result_range = key_changes_proof_check_with_db::<H, _>(
|
||||
ChangesTrieConfigurationRange {
|
||||
config: config_range.config.as_ref().ok_or(ClientError::ChangesTriesNotSupported)?,
|
||||
zero: config_range.zero.0,
|
||||
end: config_range.end.map(|(n, _)| n),
|
||||
},
|
||||
&RootsStorage {
|
||||
roots: (request.tries_roots.0, &request.tries_roots.2),
|
||||
prev_roots: &remote_roots,
|
||||
},
|
||||
&proof_storage,
|
||||
request.first_block.0,
|
||||
&ChangesTrieAnchorBlockId {
|
||||
hash: convert_hash(&request.last_block.1),
|
||||
number: request.last_block.0,
|
||||
},
|
||||
remote_max_block,
|
||||
request.storage_key.as_ref().map(Vec::as_slice),
|
||||
&request.key)
|
||||
.map_err(|err| ClientError::ChangesTrieAccessFailed(err))?;
|
||||
result.extend(result_range);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Check CHT-based proof for changes tries roots.
|
||||
@@ -284,7 +288,7 @@ impl<E, Block, H, S> FetchChecker<Block> for LightDataChecker<E, H, Block, S>
|
||||
/// A view of BTreeMap<Number, Hash> as a changes trie roots storage.
|
||||
struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> {
|
||||
roots: (Number, &'a [Hash]),
|
||||
prev_roots: BTreeMap<Number, Hash>,
|
||||
prev_roots: &'a BTreeMap<Number, Hash>,
|
||||
}
|
||||
|
||||
impl<'a, H, Number, Hash> ChangesTrieRootsStorage<H, Number> for RootsStorage<'a, Number, Hash>
|
||||
@@ -340,7 +344,7 @@ pub mod tests {
|
||||
use crate::in_mem::{Blockchain as InMemoryBlockchain};
|
||||
use crate::light::fetcher::{FetchChecker, LightDataChecker, RemoteHeaderRequest};
|
||||
use crate::light::blockchain::tests::{DummyStorage, DummyBlockchain};
|
||||
use sp_core::{blake2_256, Blake2Hasher, H256};
|
||||
use sp_core::{blake2_256, Blake2Hasher, ChangesTrieConfiguration, H256};
|
||||
use sp_core::storage::{well_known_keys, StorageKey, ChildInfo};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_state_machine::Backend;
|
||||
@@ -569,8 +573,13 @@ pub mod tests {
|
||||
|
||||
// check proof on local client
|
||||
let local_roots_range = local_roots.clone()[(begin - 1) as usize..].to_vec();
|
||||
let config = ChangesTrieConfiguration::new(4, 2);
|
||||
let request = RemoteChangesRequest::<Header> {
|
||||
changes_trie_config: runtime::changes_trie_config(),
|
||||
changes_trie_configs: vec![sp_core::ChangesTrieConfigurationRange {
|
||||
zero: (0, Default::default()),
|
||||
end: None,
|
||||
config: Some(config),
|
||||
}],
|
||||
first_block: (begin, begin_hash),
|
||||
last_block: (end, end_hash),
|
||||
max_block: (max, max_hash),
|
||||
@@ -624,8 +633,13 @@ pub mod tests {
|
||||
);
|
||||
|
||||
// check proof on local client
|
||||
let config = ChangesTrieConfiguration::new(4, 2);
|
||||
let request = RemoteChangesRequest::<Header> {
|
||||
changes_trie_config: runtime::changes_trie_config(),
|
||||
changes_trie_configs: vec![sp_core::ChangesTrieConfigurationRange {
|
||||
zero: (0, Default::default()),
|
||||
end: None,
|
||||
config: Some(config),
|
||||
}],
|
||||
first_block: (1, b1),
|
||||
last_block: (4, b4),
|
||||
max_block: (4, b4),
|
||||
@@ -665,8 +679,13 @@ pub mod tests {
|
||||
begin_hash, end_hash, begin_hash, max_hash, None, &key).unwrap();
|
||||
|
||||
let local_roots_range = local_roots.clone()[(begin - 1) as usize..].to_vec();
|
||||
let config = ChangesTrieConfiguration::new(4, 2);
|
||||
let request = RemoteChangesRequest::<Header> {
|
||||
changes_trie_config: runtime::changes_trie_config(),
|
||||
changes_trie_configs: vec![sp_core::ChangesTrieConfigurationRange {
|
||||
zero: (0, Default::default()),
|
||||
end: None,
|
||||
config: Some(config),
|
||||
}],
|
||||
first_block: (begin, begin_hash),
|
||||
last_block: (end, end_hash),
|
||||
max_block: (max, max_hash),
|
||||
|
||||
Reference in New Issue
Block a user