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

Commit 8e98643

Browse files
svyatonikchemegavofyork
committed
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 <[email protected]> * 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 <[email protected]> * Update client/db/src/changes_tries_storage.rs Co-Authored-By: cheme <[email protected]> * 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 <[email protected]> Co-authored-by: Gavin Wood <[email protected]>
1 parent 1e0c679 commit 8e98643

File tree

48 files changed

+2739
-1544
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2739
-1544
lines changed

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/api/src/backend.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
1919
use std::sync::Arc;
2020
use std::collections::HashMap;
21-
use sp_core::ChangesTrieConfiguration;
21+
use sp_core::ChangesTrieConfigurationRange;
2222
use sp_core::offchain::OffchainStorage;
2323
use sp_runtime::{generic::BlockId, Justification, Storage};
2424
use sp_runtime::traits::{Block as BlockT, NumberFor, HasherFor};
25-
use sp_state_machine::{ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction};
25+
use sp_state_machine::{ChangesTrieState, ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction};
2626
use crate::{
2727
blockchain::{
2828
Backend as BlockchainBackend, well_known_cache_keys
@@ -248,8 +248,6 @@ pub trait Backend<Block: BlockT>: AuxStore + Send + Sync {
248248
type Blockchain: BlockchainBackend<Block>;
249249
/// Associated state backend type.
250250
type State: StateBackend<HasherFor<Block>> + Send;
251-
/// Changes trie storage.
252-
type ChangesTrieStorage: PrunableStateChangesTrieStorage<Block>;
253251
/// Offchain workers local storage.
254252
type OffchainStorage: OffchainStorage;
255253

@@ -284,7 +282,7 @@ pub trait Backend<Block: BlockT>: AuxStore + Send + Sync {
284282
fn usage_info(&self) -> Option<UsageInfo>;
285283

286284
/// Returns reference to changes trie storage.
287-
fn changes_trie_storage(&self) -> Option<&Self::ChangesTrieStorage>;
285+
fn changes_trie_storage(&self) -> Option<&dyn PrunableStateChangesTrieStorage<Block>>;
288286

289287
/// Returns a handle to offchain storage.
290288
fn offchain_storage(&self) -> Option<Self::OffchainStorage>;
@@ -342,12 +340,16 @@ pub trait Backend<Block: BlockT>: AuxStore + Send + Sync {
342340
pub trait PrunableStateChangesTrieStorage<Block: BlockT>:
343341
StateChangesTrieStorage<HasherFor<Block>, NumberFor<Block>>
344342
{
345-
/// Get number block of oldest, non-pruned changes trie.
346-
fn oldest_changes_trie_block(
347-
&self,
348-
config: &ChangesTrieConfiguration,
349-
best_finalized: NumberFor<Block>,
350-
) -> NumberFor<Block>;
343+
/// Get reference to StateChangesTrieStorage.
344+
fn storage(&self) -> &dyn StateChangesTrieStorage<HasherFor<Block>, NumberFor<Block>>;
345+
/// Get configuration at given block.
346+
fn configuration_at(&self, at: &BlockId<Block>) -> sp_blockchain::Result<
347+
ChangesTrieConfigurationRange<NumberFor<Block>, Block::Hash>
348+
>;
349+
/// Get end block (inclusive) of oldest pruned max-level (or skewed) digest trie blocks range.
350+
/// It is guaranteed that we have no any changes tries before (and including) this block.
351+
/// It is guaranteed that all existing changes tries after this block are not yet pruned (if created).
352+
fn oldest_pruned_digest_range_end(&self) -> NumberFor<Block>;
351353
}
352354

353355
/// Mark for all Backend implementations, that are making use of state data, stored locally.
@@ -364,3 +366,20 @@ pub trait RemoteBackend<Block: BlockT>: Backend<Block> {
364366
/// locally, or prepares request to fetch that data from remote node.
365367
fn remote_blockchain(&self) -> Arc<dyn RemoteBlockchain<Block>>;
366368
}
369+
370+
/// Return changes tries state at given block.
371+
pub fn changes_tries_state_at_block<'a, Block: BlockT>(
372+
block: &BlockId<Block>,
373+
maybe_storage: Option<&'a dyn PrunableStateChangesTrieStorage<Block>>,
374+
) -> sp_blockchain::Result<Option<ChangesTrieState<'a, HasherFor<Block>, NumberFor<Block>>>> {
375+
let storage = match maybe_storage {
376+
Some(storage) => storage,
377+
None => return Ok(None),
378+
};
379+
380+
let config_range = storage.configuration_at(block)?;
381+
match config_range.config {
382+
Some(config) => Ok(Some(ChangesTrieState::new(config, config_range.zero.0, storage.storage()))),
383+
None => Ok(None),
384+
}
385+
}

client/api/src/light.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use sp_runtime::{
2626
},
2727
generic::BlockId
2828
};
29-
use sp_core::ChangesTrieConfiguration;
29+
use sp_core::ChangesTrieConfigurationRange;
3030
use sp_state_machine::StorageProof;
3131
use sp_blockchain::{
3232
HeaderMetadata, well_known_cache_keys, HeaderBackend, Cache as BlockchainCache,
@@ -96,8 +96,8 @@ pub struct RemoteReadChildRequest<Header: HeaderT> {
9696
/// Remote key changes read request.
9797
#[derive(Clone, Debug, PartialEq, Eq)]
9898
pub struct RemoteChangesRequest<Header: HeaderT> {
99-
/// Changes trie configuration.
100-
pub changes_trie_config: ChangesTrieConfiguration,
99+
/// All changes trie configurations that are valid within [first_block; last_block].
100+
pub changes_trie_configs: Vec<ChangesTrieConfigurationRange<Header::Number, Header::Hash>>,
101101
/// Query changes from range of blocks, starting (and including) with this hash...
102102
pub first_block: (Header::Number, Header::Hash),
103103
/// ...ending (and including) with this hash. Should come after first_block and

client/authority-discovery/src/tests.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,10 @@ impl ApiExt<Block> for RuntimeApi {
212212
unimplemented!("Not required for testing!")
213213
}
214214

215-
fn into_storage_changes<
216-
T: sp_api::ChangesTrieStorage<sp_api::HasherFor<Block>, sp_api::NumberFor<Block>>
217-
>(
215+
fn into_storage_changes(
218216
&self,
219217
_: &Self::StateBackend,
220-
_: Option<&T>,
218+
_: Option<&sp_api::ChangesTrieState<sp_api::HasherFor<Block>, sp_api::NumberFor<Block>>>,
221219
_: <Block as sp_api::BlockT>::Hash,
222220
) -> std::result::Result<sp_api::StorageChanges<Self::StateBackend, Block>, String>
223221
where Self: Sized

client/basic-authorship/src/basic_authorship.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,12 @@ mod tests {
374374
api.execute_block(&block_id, proposal.block).unwrap();
375375

376376
let state = backend.state_at(block_id).unwrap();
377-
let changes_trie_storage = backend.changes_trie_storage();
377+
let changes_trie_state = backend::changes_tries_state_at_block(
378+
&block_id,
379+
backend.changes_trie_storage(),
380+
).unwrap();
378381

379-
let storage_changes = api.into_storage_changes(&state, changes_trie_storage, genesis_hash)
382+
let storage_changes = api.into_storage_changes(&state, changes_trie_state.as_ref(), genesis_hash)
380383
.unwrap();
381384

382385
assert_eq!(

client/block-builder/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,17 @@ where
191191
let proof = self.api.extract_proof();
192192

193193
let state = self.backend.state_at(self.block_id)?;
194-
let changes_trie_storage = self.backend.changes_trie_storage();
194+
let changes_trie_state = backend::changes_tries_state_at_block(
195+
&self.block_id,
196+
self.backend.changes_trie_storage(),
197+
)?;
195198
let parent_hash = self.parent_hash;
196199

197200
// The unsafe is required because the consume requires that we drop/consume the inner api
198201
// (what we do here).
199202
let storage_changes = self.api.into_storage_changes(
200203
&state,
201-
changes_trie_storage,
204+
changes_trie_state.as_ref(),
202205
parent_hash,
203206
);
204207

client/consensus/aura/src/lib.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -675,19 +675,21 @@ fn initialize_authorities_cache<A, B, C>(client: &C) -> Result<(), ConsensusErro
675675
};
676676

677677
// check if we already have initialized the cache
678+
let map_err = |error| sp_consensus::Error::from(sp_consensus::Error::ClientImport(
679+
format!(
680+
"Error initializing authorities cache: {}",
681+
error,
682+
)));
683+
678684
let genesis_id = BlockId::Number(Zero::zero());
679685
let genesis_authorities: Option<Vec<A>> = cache
680686
.get_at(&well_known_cache_keys::AUTHORITIES, &genesis_id)
687+
.unwrap_or(None)
681688
.and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok());
682689
if genesis_authorities.is_some() {
683690
return Ok(());
684691
}
685692

686-
let map_err = |error| sp_consensus::Error::from(sp_consensus::Error::ClientImport(
687-
format!(
688-
"Error initializing authorities cache: {}",
689-
error,
690-
)));
691693
let genesis_authorities = authorities(client, &genesis_id)?;
692694
cache.initialize(&well_known_cache_keys::AUTHORITIES, genesis_authorities.encode())
693695
.map_err(map_err)?;
@@ -706,6 +708,7 @@ fn authorities<A, B, C>(client: &C, at: &BlockId<B>) -> Result<Vec<A>, Consensus
706708
.cache()
707709
.and_then(|cache| cache
708710
.get_at(&well_known_cache_keys::AUTHORITIES, at)
711+
.unwrap_or(None)
709712
.and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok())
710713
)
711714
.or_else(|| AuraApi::authorities(&*client.runtime_api(), at).ok())

client/db/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" }
3131
substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" }
3232
env_logger = "0.7.0"
3333
quickcheck = "0.9"
34+
kvdb-rocksdb = "0.4"
35+
tempdir = "0.3"
3436

3537
[features]
3638
default = []

0 commit comments

Comments
 (0)