Kill the light client, CHTs and change tries. (#10080)

* Remove light client, change tries and CHTs

* Update tests

* fmt

* Restore changes_root

* Fixed benches

* Cargo fmt

* fmt

* fmt
This commit is contained in:
Arkadiy Paronyan
2021-11-12 14:15:01 +01:00
committed by GitHub
parent 112b7dac47
commit 4cbbf0cf43
141 changed files with 532 additions and 17807 deletions
+8 -19
View File
@@ -30,9 +30,8 @@ use log::info;
use prometheus_endpoint::Registry;
use sc_chain_spec::get_extension;
use sc_client_api::{
execution_extensions::ExecutionExtensions, light::RemoteBlockchain,
proof_provider::ProofProvider, BadBlocks, BlockBackend, BlockchainEvents, ExecutorProvider,
ForkBlocks, StorageProvider, UsageProvider,
execution_extensions::ExecutionExtensions, proof_provider::ProofProvider, BadBlocks,
BlockBackend, BlockchainEvents, ExecutorProvider, ForkBlocks, StorageProvider, UsageProvider,
};
use sc_client_db::{Backend, DatabaseSettings};
use sc_consensus::import_queue::ImportQueue;
@@ -40,7 +39,7 @@ use sc_executor::RuntimeVersionOf;
use sc_keystore::LocalKeystore;
use sc_network::{
block_request_handler::{self, BlockRequestHandler},
config::{OnDemand, Role, SyncMode},
config::{Role, SyncMode},
light_client_requests::{self, handler::LightClientRequestHandler},
state_request_handler::{self, StateRequestHandler},
warp_request_handler::{self, RequestHandler as WarpSyncRequestHandler, WarpSyncProvider},
@@ -381,23 +380,19 @@ where
pub struct SpawnTasksParams<'a, TBl: BlockT, TCl, TExPool, TRpc, Backend> {
/// The service configuration.
pub config: Configuration,
/// A shared client returned by `new_full_parts`/`new_light_parts`.
/// A shared client returned by `new_full_parts`.
pub client: Arc<TCl>,
/// A shared backend returned by `new_full_parts`/`new_light_parts`.
/// A shared backend returned by `new_full_parts`.
pub backend: Arc<Backend>,
/// A task manager returned by `new_full_parts`/`new_light_parts`.
/// A task manager returned by `new_full_parts`.
pub task_manager: &'a mut TaskManager,
/// A shared keystore returned by `new_full_parts`/`new_light_parts`.
/// A shared keystore returned by `new_full_parts`.
pub keystore: SyncCryptoStorePtr,
/// An optional, shared data fetcher for light clients.
pub on_demand: Option<Arc<OnDemand<TBl>>>,
/// A shared transaction pool.
pub transaction_pool: Arc<TExPool>,
/// A RPC extension builder. Use `NoopRpcExtensionBuilder` if you just want to pass in the
/// extensions directly.
pub rpc_extensions_builder: Box<dyn RpcExtensionBuilder<Output = TRpc> + Send>,
/// An optional, shared remote blockchain instance. Used for light clients.
pub remote_blockchain: Option<Arc<dyn RemoteBlockchain<TBl>>>,
/// A shared network instance.
pub network: Arc<NetworkService<TBl, <TBl as BlockT>::Hash>>,
/// A Sender for RPC requests.
@@ -475,12 +470,10 @@ where
mut config,
task_manager,
client,
on_demand: _,
backend,
keystore,
transaction_pool,
rpc_extensions_builder,
remote_blockchain: _,
network,
system_rpc_tx,
telemetry,
@@ -725,7 +718,7 @@ where
pub struct BuildNetworkParams<'a, TBl: BlockT, TExPool, TImpQu, TCl> {
/// The service configuration.
pub config: &'a Configuration,
/// A shared client returned by `new_full_parts`/`new_light_parts`.
/// A shared client returned by `new_full_parts`.
pub client: Arc<TCl>,
/// A shared transaction pool.
pub transaction_pool: Arc<TExPool>,
@@ -733,8 +726,6 @@ pub struct BuildNetworkParams<'a, TBl: BlockT, TExPool, TImpQu, TCl> {
pub spawn_handle: SpawnTaskHandle,
/// An import queue.
pub import_queue: TImpQu,
/// An optional, shared data fetcher for light clients.
pub on_demand: Option<Arc<OnDemand<TBl>>>,
/// A block announce validator builder.
pub block_announce_validator_builder:
Option<Box<dyn FnOnce(Arc<TCl>) -> Box<dyn BlockAnnounceValidator<TBl> + Send> + Send>>,
@@ -773,7 +764,6 @@ where
transaction_pool,
spawn_handle,
import_queue,
on_demand,
block_announce_validator_builder,
warp_sync,
} = params;
@@ -869,7 +859,6 @@ where
},
network_config: config.network.clone(),
chain: client.clone(),
on_demand,
transaction_pool: transaction_pool_adapter as _,
import_queue: Box::new(import_queue),
protocol_id,
@@ -26,10 +26,7 @@ use sp_core::{
NativeOrEncoded, NeverNativeValue,
};
use sp_externalities::Extensions;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, NumberFor},
};
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
use sp_state_machine::{
self, backend::Backend as _, ExecutionManager, ExecutionStrategy, Ext, OverlayedChanges,
StateMachine, StorageProof,
@@ -153,8 +150,6 @@ where
extensions: Option<Extensions>,
) -> sp_blockchain::Result<Vec<u8>> {
let mut changes = OverlayedChanges::default();
let changes_trie =
backend::changes_tries_state_at_block(at, self.backend.changes_trie_storage())?;
let state = self.backend.state_at(*at)?;
let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);
let runtime_code =
@@ -168,7 +163,6 @@ where
let return_data = StateMachine::new(
&state,
changes_trie,
&mut changes,
&self.executor,
method,
@@ -208,8 +202,6 @@ where
where
ExecutionManager<EM>: Clone,
{
let changes_trie_state =
backend::changes_tries_state_at_block(at, self.backend.changes_trie_storage())?;
let mut storage_transaction_cache = storage_transaction_cache.map(|c| c.borrow_mut());
let state = self.backend.state_at(*at)?;
@@ -243,7 +235,6 @@ where
let mut state_machine = StateMachine::new(
&backend,
changes_trie_state,
changes,
&self.executor,
method,
@@ -262,7 +253,6 @@ where
None => {
let mut state_machine = StateMachine::new(
&state,
changes_trie_state,
changes,
&self.executor,
method,
@@ -286,11 +276,9 @@ where
fn runtime_version(&self, id: &BlockId<Block>) -> sp_blockchain::Result<RuntimeVersion> {
let mut overlay = OverlayedChanges::default();
let changes_trie_state =
backend::changes_tries_state_at_block(id, self.backend.changes_trie_storage())?;
let state = self.backend.state_at(*id)?;
let mut cache = StorageTransactionCache::<Block, B::State>::default();
let mut ext = Ext::new(&mut overlay, &mut cache, &state, changes_trie_state, None);
let mut ext = Ext::new(&mut overlay, &mut cache, &state, None);
let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);
let runtime_code =
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
@@ -317,7 +305,7 @@ where
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
let runtime_code = self.check_override(runtime_code, at)?;
sp_state_machine::prove_execution_on_trie_backend::<_, _, NumberFor<Block>, _, _>(
sp_state_machine::prove_execution_on_trie_backend(
&trie_backend,
&mut Default::default(),
&self.executor,
+16 -385
View File
@@ -23,7 +23,6 @@ use super::{
genesis,
};
use codec::{Decode, Encode};
use hash_db::Prefix;
use log::{info, trace, warn};
use parking_lot::{Mutex, RwLock};
use prometheus_endpoint::Registry;
@@ -31,18 +30,15 @@ use rand::Rng;
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider, RecordProof};
use sc_client_api::{
backend::{
self, apply_aux, changes_tries_state_at_block, BlockImportOperation, ClientImportOperation,
Finalizer, ImportSummary, LockImportRun, NewBlockState, PrunableStateChangesTrieStorage,
StorageProvider,
self, apply_aux, BlockImportOperation, ClientImportOperation, Finalizer, ImportSummary,
LockImportRun, NewBlockState, StorageProvider,
},
cht,
client::{
BadBlocks, BlockBackend, BlockImportNotification, BlockOf, BlockchainEvents, ClientInfo,
FinalityNotification, FinalityNotifications, ForkBlocks, ImportNotifications,
ProvideUncles,
},
execution_extensions::ExecutionExtensions,
light::ChangesProof,
notifications::{StorageEventStream, StorageNotifications},
CallExecutor, ExecutorProvider, KeyIterator, ProofProvider, UsageProvider,
};
@@ -56,39 +52,36 @@ use sp_api::{
ProvideRuntimeApi,
};
use sp_blockchain::{
self as blockchain, well_known_cache_keys::Id as CacheKeyId, Backend as ChainBackend, Cache,
CachedHeaderMetadata, Error, HeaderBackend as ChainHeaderBackend, HeaderMetadata, ProvideCache,
self as blockchain, well_known_cache_keys::Id as CacheKeyId, Backend as ChainBackend,
CachedHeaderMetadata, Error, HeaderBackend as ChainHeaderBackend, HeaderMetadata,
};
use sp_consensus::{BlockOrigin, BlockStatus, Error as ConsensusError};
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender};
use sp_core::{
convert_hash,
storage::{
well_known_keys, ChildInfo, ChildType, PrefixedStorageKey, StorageChild, StorageData,
StorageKey,
},
ChangesTrieConfiguration, NativeOrEncoded,
NativeOrEncoded,
};
#[cfg(feature = "test-helpers")]
use sp_keystore::SyncCryptoStorePtr;
use sp_runtime::{
generic::{BlockId, DigestItem, SignedBlock},
generic::{BlockId, SignedBlock},
traits::{
Block as BlockT, DigestFor, HashFor, Header as HeaderT, NumberFor, One,
SaturatedConversion, Zero,
Block as BlockT, HashFor, Header as HeaderT, NumberFor, One, SaturatedConversion, Zero,
},
BuildStorage, Justification, Justifications,
BuildStorage, Digest, Justification, Justifications,
};
use sp_state_machine::{
key_changes, key_changes_proof, prove_child_read, prove_range_read_with_child_with_size,
prove_read, read_range_proof_check_with_child_on_proving_backend, Backend as StateBackend,
ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, ChangesTrieRootsStorage,
ChangesTrieStorage, DBValue, KeyValueStates, KeyValueStorageLevel, MAX_NESTED_TRIE_DEPTH,
prove_child_read, prove_range_read_with_child_with_size, prove_read,
read_range_proof_check_with_child_on_proving_backend, Backend as StateBackend, KeyValueStates,
KeyValueStorageLevel, MAX_NESTED_TRIE_DEPTH,
};
use sp_trie::{CompactProof, StorageProof};
use std::{
collections::{BTreeMap, HashMap, HashSet},
collections::{HashMap, HashSet},
marker::PhantomData,
panic::UnwindSafe,
path::PathBuf,
@@ -413,250 +406,6 @@ where
self.executor.runtime_version(id)
}
/// Reads given header and generates CHT-based header proof for CHT of given size.
pub fn header_proof_with_cht_size(
&self,
id: &BlockId<Block>,
cht_size: NumberFor<Block>,
) -> sp_blockchain::Result<(Block::Header, StorageProof)> {
let proof_error = || {
sp_blockchain::Error::Backend(format!("Failed to generate header proof for {:?}", id))
};
let header = self.backend.blockchain().expect_header(*id)?;
let block_num = *header.number();
let cht_num = cht::block_to_cht_number(cht_size, block_num).ok_or_else(proof_error)?;
let cht_start = cht::start_number(cht_size, cht_num);
let mut current_num = cht_start;
let cht_range = ::std::iter::from_fn(|| {
let old_current_num = current_num;
current_num = current_num + One::one();
Some(old_current_num)
});
let headers = cht_range.map(|num| self.block_hash(num));
let proof = cht::build_proof::<Block::Header, HashFor<Block>, _, _>(
cht_size,
cht_num,
std::iter::once(block_num),
headers,
)?;
Ok((header, proof))
}
/// Does the same work as `key_changes_proof`, but assumes that CHTs are of passed size.
pub fn key_changes_proof_with_cht_size(
&self,
first: Block::Hash,
last: Block::Hash,
min: Block::Hash,
max: Block::Hash,
storage_key: Option<&PrefixedStorageKey>,
key: &StorageKey,
cht_size: NumberFor<Block>,
) -> sp_blockchain::Result<ChangesProof<Block::Header>> {
struct AccessedRootsRecorder<'a, Block: BlockT> {
storage: &'a dyn ChangesTrieStorage<HashFor<Block>, NumberFor<Block>>,
min: NumberFor<Block>,
required_roots_proofs: Mutex<BTreeMap<NumberFor<Block>, Block::Hash>>,
}
impl<'a, Block: BlockT> ChangesTrieRootsStorage<HashFor<Block>, NumberFor<Block>>
for AccessedRootsRecorder<'a, Block>
{
fn build_anchor(
&self,
hash: Block::Hash,
) -> Result<ChangesTrieAnchorBlockId<Block::Hash, NumberFor<Block>>, String> {
self.storage.build_anchor(hash)
}
fn root(
&self,
anchor: &ChangesTrieAnchorBlockId<Block::Hash, NumberFor<Block>>,
block: NumberFor<Block>,
) -> Result<Option<Block::Hash>, String> {
let root = self.storage.root(anchor, block)?;
if block < self.min {
if let Some(ref root) = root {
self.required_roots_proofs.lock().insert(block, root.clone());
}
}
Ok(root)
}
}
impl<'a, Block: BlockT> ChangesTrieStorage<HashFor<Block>, NumberFor<Block>>
for AccessedRootsRecorder<'a, Block>
{
fn as_roots_storage(
&self,
) -> &dyn sp_state_machine::ChangesTrieRootsStorage<HashFor<Block>, NumberFor<Block>> {
self
}
fn with_cached_changed_keys(
&self,
root: &Block::Hash,
functor: &mut dyn FnMut(&HashMap<Option<PrefixedStorageKey>, HashSet<Vec<u8>>>),
) -> bool {
self.storage.with_cached_changed_keys(root, functor)
}
fn get(&self, key: &Block::Hash, prefix: Prefix) -> Result<Option<DBValue>, String> {
self.storage.get(key, prefix)
}
}
let first_number =
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(first))?;
let (storage, configs) = self.require_changes_trie(first_number, last, true)?;
let min_number =
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(min))?;
let recording_storage = AccessedRootsRecorder::<Block> {
storage: storage.storage(),
min: min_number,
required_roots_proofs: Mutex::new(BTreeMap::new()),
};
let max_number = std::cmp::min(
self.backend.blockchain().info().best_number,
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(max))?,
);
// fetch key changes proof
let mut proof = Vec::new();
for (config_zero, config_end, config) in configs {
let last_number =
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(last))?;
let config_range = ChangesTrieConfigurationRange {
config: &config,
zero: config_zero,
end: config_end.map(|(config_end_number, _)| config_end_number),
};
let proof_range = key_changes_proof::<HashFor<Block>, _>(
config_range,
&recording_storage,
first_number,
&ChangesTrieAnchorBlockId { hash: convert_hash(&last), number: last_number },
max_number,
storage_key,
&key.0,
)
.map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err))?;
proof.extend(proof_range);
}
// now gather proofs for all changes tries roots that were touched during key_changes_proof
// execution AND are unknown (i.e. replaced with CHT) to the requester
let roots = recording_storage.required_roots_proofs.into_inner();
let roots_proof = self.changes_trie_roots_proof(cht_size, roots.keys().cloned())?;
Ok(ChangesProof {
max_block: max_number,
proof,
roots: roots.into_iter().map(|(n, h)| (n, convert_hash(&h))).collect(),
roots_proof,
})
}
/// Generate CHT-based proof for roots of changes tries at given blocks.
fn changes_trie_roots_proof<I: IntoIterator<Item = NumberFor<Block>>>(
&self,
cht_size: NumberFor<Block>,
blocks: I,
) -> sp_blockchain::Result<StorageProof> {
// most probably we have touched several changes tries that are parts of the single CHT
// => GroupBy changes tries by CHT number and then gather proof for the whole group at once
let mut proofs = Vec::new();
cht::for_each_cht_group::<Block::Header, _, _, _>(
cht_size,
blocks,
|_, cht_num, cht_blocks| {
let cht_proof =
self.changes_trie_roots_proof_at_cht(cht_size, cht_num, cht_blocks)?;
proofs.push(cht_proof);
Ok(())
},
(),
)?;
Ok(StorageProof::merge(proofs))
}
/// Generates CHT-based proof for roots of changes tries at given blocks
/// (that are part of single CHT).
fn changes_trie_roots_proof_at_cht(
&self,
cht_size: NumberFor<Block>,
cht_num: NumberFor<Block>,
blocks: Vec<NumberFor<Block>>,
) -> sp_blockchain::Result<StorageProof> {
let cht_start = cht::start_number(cht_size, cht_num);
let mut current_num = cht_start;
let cht_range = ::std::iter::from_fn(|| {
let old_current_num = current_num;
current_num = current_num + One::one();
Some(old_current_num)
});
let roots = cht_range.map(|num| {
self.header(&BlockId::Number(num)).map(|block| {
block
.and_then(|block| block.digest().log(DigestItem::as_changes_trie_root).cloned())
})
});
let proof = cht::build_proof::<Block::Header, HashFor<Block>, _, _>(
cht_size, cht_num, blocks, roots,
)?;
Ok(proof)
}
/// Returns changes trie storage and all configurations that have been active
/// in the range [first; last].
///
/// Configurations are returned in descending order (and obviously never overlap).
/// If fail_if_disabled is false, returns maximal consequent configurations ranges,
/// starting from last and stopping on either first, or when CT have been disabled.
/// If fail_if_disabled is true, fails when there's a subrange where CT have been disabled
/// inside first..last blocks range.
fn require_changes_trie(
&self,
first: NumberFor<Block>,
last: Block::Hash,
fail_if_disabled: bool,
) -> sp_blockchain::Result<(
&dyn PrunableStateChangesTrieStorage<Block>,
Vec<(NumberFor<Block>, Option<(NumberFor<Block>, Block::Hash)>, ChangesTrieConfiguration)>,
)> {
let storage = self
.backend
.changes_trie_storage()
.ok_or_else(|| sp_blockchain::Error::ChangesTriesNotSupported)?;
let mut configs = Vec::with_capacity(1);
let mut current = last;
loop {
let config_range = storage.configuration_at(&BlockId::Hash(current))?;
match config_range.config {
Some(config) => configs.push((config_range.zero.0, config_range.end, config)),
None if !fail_if_disabled => return Ok((storage, configs)),
None => return Err(sp_blockchain::Error::ChangesTriesNotSupported),
}
if config_range.zero.0 < first {
break
}
current = *self
.backend
.blockchain()
.expect_header(BlockId::Hash(config_range.zero.1))?
.parent_hash();
}
Ok((storage, configs))
}
/// Apply a checked and validated block to an operation. If a justification is provided
/// then `finalized` *must* be true.
fn apply_block(
@@ -811,7 +560,7 @@ where
sc_consensus::StorageChanges::Changes(storage_changes) => {
self.backend
.begin_state_operation(&mut operation.op, BlockId::Hash(parent_hash))?;
let (main_sc, child_sc, offchain_sc, tx, _, changes_trie_tx, tx_index) =
let (main_sc, child_sc, offchain_sc, tx, _, tx_index) =
storage_changes.into_inner();
if self.config.offchain_indexing_api {
@@ -822,9 +571,6 @@ where
operation.op.update_storage(main_sc.clone(), child_sc.clone())?;
operation.op.update_transaction_index(tx_index)?;
if let Some(changes_trie_transaction) = changes_trie_tx {
operation.op.update_changes_trie(changes_trie_transaction)?;
}
Some((main_sc, child_sc))
},
sc_consensus::StorageChanges::Import(changes) => {
@@ -1003,11 +749,8 @@ where
)?;
let state = self.backend.state_at(at)?;
let changes_trie_state =
changes_tries_state_at_block(&at, self.backend.changes_trie_storage())?;
let gen_storage_changes = runtime_api
.into_storage_changes(&state, changes_trie_state.as_ref(), *parent_hash)
.into_storage_changes(&state, *parent_hash)
.map_err(sp_blockchain::Error::Storage)?;
if import_block.header.state_root() != &gen_storage_changes.transaction_storage_root
@@ -1356,25 +1099,6 @@ where
.map(|(r, p)| (r, StorageProof::merge(vec![p, code_proof])))
}
fn header_proof(
&self,
id: &BlockId<Block>,
) -> sp_blockchain::Result<(Block::Header, StorageProof)> {
self.header_proof_with_cht_size(id, cht::size())
}
fn key_changes_proof(
&self,
first: Block::Hash,
last: Block::Hash,
min: Block::Hash,
max: Block::Hash,
storage_key: Option<&PrefixedStorageKey>,
key: &StorageKey,
) -> sp_blockchain::Result<ChangesProof<Block::Header>> {
self.key_changes_proof_with_cht_size(first, last, min, max, storage_key, key, cht::size())
}
fn read_proof_collection(
&self,
id: &BlockId<Block>,
@@ -1540,7 +1264,7 @@ where
fn new_block_at<R: Into<RecordProof>>(
&self,
parent: &BlockId<Block>,
inherent_digests: DigestFor<Block>,
inherent_digests: Digest,
record_proof: R,
) -> sp_blockchain::Result<sc_block_builder::BlockBuilder<Block, Self, B>> {
sc_block_builder::BlockBuilder::new(
@@ -1555,7 +1279,7 @@ where
fn new_block(
&self,
inherent_digests: DigestFor<Block>,
inherent_digests: Digest,
) -> sp_blockchain::Result<sc_block_builder::BlockBuilder<Block, Self, B>> {
let info = self.chain_info();
sc_block_builder::BlockBuilder::new(
@@ -1703,89 +1427,6 @@ where
.child_storage_hash(child_info, &key.0)
.map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))?)
}
fn max_key_changes_range(
&self,
first: NumberFor<Block>,
last: BlockId<Block>,
) -> sp_blockchain::Result<Option<(NumberFor<Block>, BlockId<Block>)>> {
let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?;
let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?;
if first > last_number {
return Err(sp_blockchain::Error::ChangesTrieAccessFailed(
"Invalid changes trie range".into(),
))
}
let (storage, configs) = match self.require_changes_trie(first, last_hash, false).ok() {
Some((storage, configs)) => (storage, configs),
None => return Ok(None),
};
let first_available_changes_trie = configs.last().map(|config| config.0);
match first_available_changes_trie {
Some(first_available_changes_trie) => {
let oldest_unpruned = storage.oldest_pruned_digest_range_end();
let first = std::cmp::max(first_available_changes_trie, oldest_unpruned);
Ok(Some((first, last)))
},
None => Ok(None),
}
}
fn key_changes(
&self,
first: NumberFor<Block>,
last: BlockId<Block>,
storage_key: Option<&PrefixedStorageKey>,
key: &StorageKey,
) -> sp_blockchain::Result<Vec<(NumberFor<Block>, u32)>> {
let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?;
let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?;
let (storage, configs) = self.require_changes_trie(first, last_hash, true)?;
let mut result = Vec::new();
let best_number = self.backend.blockchain().info().best_number;
for (config_zero, config_end, config) in configs {
let range_first = ::std::cmp::max(first, config_zero + One::one());
let range_anchor = match config_end {
Some((config_end_number, config_end_hash)) =>
if last_number > config_end_number {
ChangesTrieAnchorBlockId {
hash: config_end_hash,
number: config_end_number,
}
} else {
ChangesTrieAnchorBlockId {
hash: convert_hash(&last_hash),
number: last_number,
}
},
None =>
ChangesTrieAnchorBlockId { hash: convert_hash(&last_hash), number: last_number },
};
let config_range = ChangesTrieConfigurationRange {
config: &config,
zero: config_zero.clone(),
end: config_end.map(|(config_end_number, _)| config_end_number),
};
let result_range: Vec<(NumberFor<Block>, u32)> = key_changes::<HashFor<Block>, _>(
config_range,
storage.storage(),
range_first,
&range_anchor,
best_number,
storage_key,
&key.0,
)
.and_then(|r| r.map(|r| r.map(|(block, tx)| (block, tx))).collect::<Result<_, _>>())
.map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err))?;
result.extend(result_range);
}
Ok(result)
}
}
impl<B, E, Block, RA> HeaderMetadata<Block> for Client<B, E, Block, RA>
@@ -1913,16 +1554,6 @@ where
}
}
impl<B, E, Block, RA> ProvideCache<Block> for Client<B, E, Block, RA>
where
B: backend::Backend<Block>,
Block: BlockT,
{
fn cache(&self) -> Option<Arc<dyn Cache<Block>>> {
self.backend.blockchain().cache()
}
}
impl<B, E, Block, RA> ProvideRuntimeApi<Block> for Client<B, E, Block, RA>
where
B: backend::Backend<Block>,
+1 -1
View File
@@ -68,7 +68,7 @@ use sc_client_api::{blockchain::HeaderBackend, BlockchainEvents};
pub use sc_consensus::ImportQueue;
pub use sc_executor::NativeExecutionDispatch;
#[doc(hidden)]
pub use sc_network::config::{OnDemand, TransactionImport, TransactionImportFuture};
pub use sc_network::config::{TransactionImport, TransactionImportFuture};
pub use sc_rpc::Metadata as RpcMetadata;
pub use sc_tracing::TracingReceiver;
pub use sc_transaction_pool::Options as TransactionPoolOptions;