Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bin/node-template/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ sp-consensus = { version = "0.8.0-alpha.2", path = "../../../primitives/consensu
grandpa = { version = "0.8.0-alpha.2", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" }
grandpa-primitives = { version = "2.0.0-alpha.2", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" }
sc-client = { version = "0.8.0-alpha.2", path = "../../../client/" }
sc-client-api = { version = "2.0.0-alpha.2", path = "../../../client/api" }
sp-runtime = { version = "2.0.0-alpha.2", path = "../../../primitives/runtime" }
sc-basic-authorship = { path = "../../../client/basic-authorship" , version = "0.8.0-alpha.2"}

Expand Down
27 changes: 18 additions & 9 deletions bin/node-template/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
use std::sync::Arc;
use std::time::Duration;
use sc_client::LongestChain;
use sc_client_api::ExecutorProvider;
use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi};
use sc_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};
use sp_inherents::InherentDataProviders;
use sc_executor::native_executor_instance;
pub use sc_executor::NativeExecutor;
use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider};

// Our native executor instance.
native_executor_instance!(
Expand All @@ -24,6 +25,7 @@ native_executor_instance!(
/// be able to perform chain operations.
macro_rules! new_full_start {
($config:expr) => {{
use std::sync::Arc;
let mut import_setup = None;
let inherent_data_providers = sp_inherents::InherentDataProviders::new();

Expand All @@ -42,7 +44,7 @@ macro_rules! new_full_start {
.ok_or_else(|| sc_service::Error::SelectChainRequired)?;

let (grandpa_block_import, grandpa_link) =
grandpa::block_import(client.clone(), &*client, select_chain)?;
grandpa::block_import(client.clone(), &(client.clone() as Arc<_>), select_chain)?;

let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(
grandpa_block_import.clone(), client.clone(),
Expand Down Expand Up @@ -87,9 +89,11 @@ pub fn new_full(config: Configuration<GenesisConfig>)
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");

let service = builder
.with_finality_proof_provider(|client, backend|
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)
)?
.with_finality_proof_provider(|client, backend| {
// GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
})?
.build()?;

if participates_in_consensus {
Expand Down Expand Up @@ -201,7 +205,10 @@ pub fn new_light(config: Configuration<GenesisConfig>)
.map(|fetcher| fetcher.checker().clone())
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
let grandpa_block_import = grandpa::light_block_import(
client.clone(), backend, &*client.clone(), Arc::new(fetch_checker),
client.clone(),
backend,
&(client.clone() as Arc<_>),
Arc::new(fetch_checker),
)?;
let finality_proof_import = grandpa_block_import.clone();
let finality_proof_request_builder =
Expand All @@ -218,8 +225,10 @@ pub fn new_light(config: Configuration<GenesisConfig>)

Ok((import_queue, finality_proof_request_builder))
})?
.with_finality_proof_provider(|client, backend|
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)
)?
.with_finality_proof_provider(|client, backend| {
// GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
})?
.build()
}
27 changes: 16 additions & 11 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::sync::Arc;

use sc_consensus_babe;
use sc_client::{self, LongestChain};
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider};
use node_executor;
use node_primitives::Block;
use node_runtime::{GenesisConfig, RuntimeApi};
Expand All @@ -45,6 +45,7 @@ use sc_offchain::OffchainWorkers;
/// be able to perform chain operations.
macro_rules! new_full_start {
($config:expr) => {{
use std::sync::Arc;
type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
let mut import_setup = None;
let inherent_data_providers = sp_inherents::InherentDataProviders::new();
Expand All @@ -64,7 +65,7 @@ macro_rules! new_full_start {
.ok_or_else(|| sc_service::Error::SelectChainRequired)?;
let (grandpa_block_import, grandpa_link) = grandpa::block_import(
client.clone(),
&*client,
&(client.clone() as Arc<_>),
select_chain,
)?;
let justification_import = grandpa_block_import.clone();
Expand Down Expand Up @@ -116,6 +117,7 @@ macro_rules! new_full {
($config:expr, $with_startup_data: expr) => {{
use futures::prelude::*;
use sc_network::Event;
use sc_client_api::ExecutorProvider;

let (
is_authority,
Expand All @@ -139,9 +141,11 @@ macro_rules! new_full {
let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config);

let service = builder
.with_finality_proof_provider(|client, backend|
Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, client)) as _)
)?
.with_finality_proof_provider(|client, backend| {
// GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, provider)) as _)
})?
.build()?;

let (block_import, grandpa_link, babe_link) = import_setup.take()
Expand Down Expand Up @@ -255,8 +259,7 @@ type ConcreteBlock = node_primitives::Block;
type ConcreteClient =
Client<
Backend<ConcreteBlock>,
LocalCallExecutor<Backend<ConcreteBlock>,
NativeExecutor<node_executor::Executor>>,
LocalCallExecutor<Backend<ConcreteBlock>, NativeExecutor<node_executor::Executor>>,
ConcreteBlock,
node_runtime::RuntimeApi
>;
Expand Down Expand Up @@ -317,7 +320,7 @@ pub fn new_light(config: NodeConfiguration)
let grandpa_block_import = grandpa::light_block_import(
client.clone(),
backend,
&*client,
&(client.clone() as Arc<_>),
Arc::new(fetch_checker),
)?;

Expand All @@ -342,9 +345,11 @@ pub fn new_light(config: NodeConfiguration)

Ok((import_queue, finality_proof_request_builder))
})?
.with_finality_proof_provider(|client, backend|
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)
)?
.with_finality_proof_provider(|client, backend| {
// GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
})?
.with_rpc_extensions(|builder,| ->
Result<RpcExtension, _>
{
Expand Down
1 change: 1 addition & 0 deletions client/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../.
sp-state-machine = { version = "0.8.0-alpha.2", path = "../../primitives/state-machine" }
sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" }
sp-trie = { version = "2.0.0-alpha.2", path = "../../primitives/trie" }
sp-storage = { version = "2.0.0-alpha.2", path = "../../primitives/storage" }
sp-transaction-pool = { version = "2.0.0-alpha.2", path = "../../primitives/transaction-pool" }

[dev-dependencies]
Expand Down
119 changes: 119 additions & 0 deletions client/api/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use sp_state_machine::{
ChangesTrieState, ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction,
StorageCollection, ChildStorageCollection,
};
use sp_storage::{StorageData, StorageKey, ChildInfo};
use crate::{
blockchain::{
Backend as BlockchainBackend, well_known_cache_keys
Expand All @@ -38,6 +39,7 @@ use sp_consensus::BlockOrigin;
use parking_lot::RwLock;

pub use sp_state_machine::Backend as StateBackend;
use std::marker::PhantomData;

/// Extracts the state backend type for the given backend.
pub type StateBackendFor<B, Block> = <B as Backend<Block>>::State;
Expand Down Expand Up @@ -237,6 +239,123 @@ pub trait AuxStore {
fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result<Option<Vec<u8>>>;
}

/// An `Iterator` that iterates keys in a given block under a prefix.
pub struct KeyIterator<'a, State, Block> {
state: State,
prefix: Option<&'a StorageKey>,
current_key: Vec<u8>,
_phantom: PhantomData<Block>,
}

impl <'a, State, Block> KeyIterator<'a, State, Block> {
/// create a KeyIterator instance
pub fn new(state: State, prefix: Option<&'a StorageKey>, current_key: Vec<u8>) -> Self {
Self {
state,
prefix,
current_key,
_phantom: PhantomData,
}
}
}

impl<'a, State, Block> Iterator for KeyIterator<'a, State, Block> where
Block: BlockT,
State: StateBackend<HashFor<Block>>,
{
type Item = StorageKey;

fn next(&mut self) -> Option<Self::Item> {
let next_key = self.state
.next_storage_key(&self.current_key)
.ok()
.flatten()?;
// this terminates the iterator the first time it fails.
if let Some(prefix) = self.prefix {
if !next_key.starts_with(&prefix.0[..]) {
return None;
}
}
self.current_key = next_key.clone();
Some(StorageKey(next_key))
}
}
/// Provides acess to storage primitives
pub trait StorageProvider<Block: BlockT, B: Backend<Block>> {
/// Given a `BlockId` and a key, return the value under the key in that block.
fn storage(&self, id: &BlockId<Block>, key: &StorageKey) -> sp_blockchain::Result<Option<StorageData>>;

/// Given a `BlockId` and a key prefix, return the matching storage keys in that block.
fn storage_keys(&self, id: &BlockId<Block>, key_prefix: &StorageKey) -> sp_blockchain::Result<Vec<StorageKey>>;

/// Given a `BlockId` and a key, return the value under the hash in that block.
fn storage_hash(&self, id: &BlockId<Block>, key: &StorageKey) -> sp_blockchain::Result<Option<Block::Hash>>;

/// Given a `BlockId` and a key prefix, return the matching child storage keys and values in that block.
fn storage_pairs(
&self,
id: &BlockId<Block>,
key_prefix: &StorageKey
) -> sp_blockchain::Result<Vec<(StorageKey, StorageData)>>;

/// Given a `BlockId` and a key prefix, return a `KeyIterator` iterates matching storage keys in that block.
fn storage_keys_iter<'a>(
&self,
id: &BlockId<Block>,
prefix: Option<&'a StorageKey>,
start_key: Option<&StorageKey>
) -> sp_blockchain::Result<KeyIterator<'a, B::State, Block>>;

/// Given a `BlockId`, a key and a child storage key, return the value under the key in that block.
fn child_storage(
&self,
id: &BlockId<Block>,
storage_key: &StorageKey,
child_info: ChildInfo,
key: &StorageKey
) -> sp_blockchain::Result<Option<StorageData>>;

/// Given a `BlockId`, a key prefix, and a child storage key, return the matching child storage keys.
fn child_storage_keys(
&self,
id: &BlockId<Block>,
child_storage_key: &StorageKey,
child_info: ChildInfo,
key_prefix: &StorageKey
) -> sp_blockchain::Result<Vec<StorageKey>>;

/// Given a `BlockId`, a key and a child storage key, return the hash under the key in that block.
fn child_storage_hash(
&self,
id: &BlockId<Block>,
storage_key: &StorageKey,
child_info: ChildInfo,
key: &StorageKey
) -> sp_blockchain::Result<Option<Block::Hash>>;

/// Get longest range within [first; last] that is possible to use in `key_changes`
/// and `key_changes_proof` calls.
/// Range could be shortened from the beginning if some changes tries have been pruned.
/// Returns Ok(None) if changes tries are not supported.
fn max_key_changes_range(
&self,
first: NumberFor<Block>,
last: BlockId<Block>,
) -> sp_blockchain::Result<Option<(NumberFor<Block>, BlockId<Block>)>>;

/// Get pairs of (block, extrinsic) where key has been changed at given blocks range.
/// Works only for runtimes that are supporting changes tries.
///
/// Changes are returned in descending order (i.e. last block comes first).
fn key_changes(
&self,
first: NumberFor<Block>,
last: BlockId<Block>,
storage_key: Option<&StorageKey>,
key: &StorageKey
) -> sp_blockchain::Result<Vec<(NumberFor<Block>, u32)>>;
}

/// Client backend.
///
/// Manages the data layer.
Expand Down
12 changes: 12 additions & 0 deletions client/api/src/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ use sp_externalities::Extensions;
use sp_core::NativeOrEncoded;

use sp_api::{ProofRecorder, InitializeBlock, StorageTransactionCache};
use crate::execution_extensions::ExecutionExtensions;

/// Executor Provider
pub trait ExecutorProvider<Block: BlockT> {
/// executor instance
type Executor: CallExecutor<Block>;
/// Get call executor reference.
fn executor(&self) -> &Self::Executor;

/// Get a reference to the execution extensions.
fn execution_extensions(&self) -> &ExecutionExtensions<Block>;
}

/// Method call executor.
pub trait CallExecutor<B: BlockT> {
Expand Down
8 changes: 6 additions & 2 deletions client/api/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use futures::channel::mpsc;
use sp_core::storage::StorageKey;
use sp_runtime::{
traits::{Block as BlockT, NumberFor},
generic::BlockId
generic::{BlockId, SignedBlock}
};
use sp_consensus::BlockOrigin;

Expand Down Expand Up @@ -76,9 +76,13 @@ pub trait BlockchainEvents<Block: BlockT> {
/// Fetch block body by ID.
pub trait BlockBody<Block: BlockT> {
/// Get block body by ID. Returns `None` if the body is not stored.
fn block_body(&self,
fn block_body(
&self,
id: &BlockId<Block>
) -> sp_blockchain::Result<Option<Vec<<Block as BlockT>::Extrinsic>>>;

/// Get full block by id.
fn block(&self, id: &BlockId<Block>) -> sp_blockchain::Result<Option<SignedBlock<Block>>>;
}

/// Provide a list of potential uncle headers for a given block.
Expand Down
2 changes: 2 additions & 0 deletions client/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod client;
pub mod execution_extensions;
pub mod light;
pub mod notifications;
pub mod proof_provider;

pub use sp_blockchain as blockchain;
pub use backend::*;
Expand All @@ -31,6 +32,7 @@ pub use call_executor::*;
pub use client::*;
pub use light::*;
pub use notifications::*;
pub use proof_provider::*;

pub use sp_state_machine::{StorageProof, ExecutionStrategy};

Expand Down
Loading