diff --git a/Cargo.lock b/Cargo.lock index d969ea3cdef8..dc0d59344bda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5159,6 +5159,7 @@ dependencies = [ "sp-core", "sp-externalities", "sp-io", + "sp-runtime", "sp-std", "sp-wasm-interface", ] @@ -5509,6 +5510,7 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", + "sp-storage", "sp-transaction-pool", "sp-trie", "substrate-prometheus-endpoint", diff --git a/node/service/Cargo.toml b/node/service/Cargo.toml index cf2dc0549a20..45eb7826caac 100644 --- a/node/service/Cargo.toml +++ b/node/service/Cargo.toml @@ -31,6 +31,7 @@ sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "mas sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" } grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/node/service/src/client.rs b/node/service/src/client.rs index 28d2bccabbe5..2b596c9f1f34 100644 --- a/node/service/src/client.rs +++ b/node/service/src/client.rs @@ -16,38 +16,335 @@ //! Polkadot Client meta trait -use sp_api::{ProvideRuntimeApi, ConstructRuntimeApi, CallApiAt}; +use std::sync::Arc; +use sp_api::{ProvideRuntimeApi, CallApiAt, NumberFor}; use sp_blockchain::HeaderBackend; -use sp_runtime::traits::Block as BlockT; -use sc_client_api::{Backend as BackendT, BlockchainEvents}; +use sp_runtime::{ + Justification, generic::{BlockId, SignedBlock}, traits::{Block as BlockT, BlakeTwo256}, +}; +use sc_client_api::{Backend as BackendT, BlockchainEvents, KeyIterator}; +use sp_storage::{StorageData, StorageKey, ChildInfo, PrefixedStorageKey}; +use polkadot_primitives::v1::{Block, ParachainHost, AccountId, Nonce, Balance}; +use consensus_common::BlockStatus; -/// Polkadot client abstraction, this super trait only pulls in functionality required for -/// polkadot internal crates like polkadot-collator. -pub trait PolkadotClient: +/// A set of APIs that polkadot-like runtimes must implement. +pub trait RuntimeApiCollection: + sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::ApiExt + + babe_primitives::BabeApi + + grandpa_primitives::GrandpaApi + + ParachainHost + + sp_block_builder::BlockBuilder + + frame_system_rpc_runtime_api::AccountNonceApi + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + sp_session::SessionKeys + + authority_discovery_primitives::AuthorityDiscoveryApi +where + >::StateBackend: sp_api::StateBackend, +{} + +impl RuntimeApiCollection for Api +where + Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::ApiExt + + babe_primitives::BabeApi + + grandpa_primitives::GrandpaApi + + ParachainHost + + sp_block_builder::BlockBuilder + + frame_system_rpc_runtime_api::AccountNonceApi + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + + sp_api::Metadata + + sp_offchain::OffchainWorkerApi + + sp_session::SessionKeys + + authority_discovery_primitives::AuthorityDiscoveryApi, + >::StateBackend: sp_api::StateBackend, +{} + +/// Trait that abstracts over all available client implementations. +/// +/// For a concrete type there exists [`Client`]. +pub trait AbstractClient: BlockchainEvents + Sized + Send + Sync - + ProvideRuntimeApi + + ProvideRuntimeApi + HeaderBackend + CallApiAt< Block, Error = sp_blockchain::Error, - StateBackend = Backend ::State + StateBackend = Backend::State > where Block: BlockT, Backend: BackendT, - Runtime: ConstructRuntimeApi + Backend::State: sp_api::StateBackend, + Self::Api: RuntimeApiCollection, {} -impl PolkadotClient for Client +impl AbstractClient for Client where Block: BlockT, - Runtime: ConstructRuntimeApi, Backend: BackendT, - Client: BlockchainEvents + ProvideRuntimeApi + HeaderBackend + Backend::State: sp_api::StateBackend, + Client: BlockchainEvents + ProvideRuntimeApi + HeaderBackend + Sized + Send + Sync + CallApiAt< Block, Error = sp_blockchain::Error, - StateBackend = Backend ::State - > + StateBackend = Backend::State + >, + Client::Api: RuntimeApiCollection, {} + +/// Execute something with the client instance. +/// +/// As there exist multiple chains inside Polkadot, like Polkadot itself, Kusama, Westend etc, +/// there can exist different kinds of client types. As these client types differ in the generics +/// that are being used, we can not easily return them from a function. For returning them from a +/// function there exists [`Client`]. However, the problem on how to use this client instance still +/// exists. This trait "solves" it in a dirty way. It requires a type to implement this trait and +/// than the [`execute_with_client`](ExecuteWithClient::execute_with_client) function can be called +/// with any possible client instance. +/// +/// In a perfect world, we could make a closure work in this way. +pub trait ExecuteWithClient { + /// The return type when calling this instance. + type Output; + + /// Execute whatever should be executed with the given client instance. + fn execute_with_client(self, client: Arc) -> Self::Output + where + >::StateBackend: sp_api::StateBackend, + Backend: sc_client_api::Backend, + Backend::State: sp_api::StateBackend, + Api: crate::RuntimeApiCollection, + Client: AbstractClient + 'static; +} + +/// A handle to a Polkadot client instance. +/// +/// The Polkadot service supports multiple different runtimes (Westend, Polkadot itself, etc). As each runtime has a +/// specialized client, we need to hide them behind a trait. This is this trait. +/// +/// When wanting to work with the inner client, you need to use `execute_with`. +/// +/// See [`ExecuteWithClient`](trait.ExecuteWithClient.html) for more information. +pub trait ClientHandle { + /// Execute the given something with the client. + fn execute_with(&self, t: T) -> T::Output; +} + +/// A client instance of Polkadot. +/// +/// See [`ExecuteWithClient`] for more information. +#[derive(Clone)] +pub enum Client { + Polkadot(Arc>), + Westend(Arc>), + Kusama(Arc>), +} + +impl ClientHandle for Client { + fn execute_with(&self, t: T) -> T::Output { + match self { + Self::Polkadot(client) => { + T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone()) + }, + Self::Westend(client) => { + T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone()) + }, + Self::Kusama(client) => { + T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone()) + }, + } + } +} + +impl sc_client_api::UsageProvider for Client { + fn usage_info(&self) -> sc_client_api::ClientInfo { + match self { + Self::Polkadot(client) => client.usage_info(), + Self::Westend(client) => client.usage_info(), + Self::Kusama(client) => client.usage_info(), + } + } +} + +impl sc_client_api::BlockBackend for Client { + fn block_body( + &self, + id: &BlockId + ) -> sp_blockchain::Result::Extrinsic>>> { + match self { + Self::Polkadot(client) => client.block_body(id), + Self::Westend(client) => client.block_body(id), + Self::Kusama(client) => client.block_body(id), + } + } + + fn block(&self, id: &BlockId) -> sp_blockchain::Result>> { + match self { + Self::Polkadot(client) => client.block(id), + Self::Westend(client) => client.block(id), + Self::Kusama(client) => client.block(id), + } + } + + fn block_status(&self, id: &BlockId) -> sp_blockchain::Result { + match self { + Self::Polkadot(client) => client.block_status(id), + Self::Westend(client) => client.block_status(id), + Self::Kusama(client) => client.block_status(id), + } + } + + fn justification( + &self, + id: &BlockId + ) -> sp_blockchain::Result> { + match self { + Self::Polkadot(client) => client.justification(id), + Self::Westend(client) => client.justification(id), + Self::Kusama(client) => client.justification(id), + } + } + + fn block_hash( + &self, + number: NumberFor + ) -> sp_blockchain::Result::Hash>> { + match self { + Self::Polkadot(client) => client.block_hash(number), + Self::Westend(client) => client.block_hash(number), + Self::Kusama(client) => client.block_hash(number), + } + } +} + +impl sc_client_api::StorageProvider for Client { + fn storage( + &self, + id: &BlockId, + key: &StorageKey, + ) -> sp_blockchain::Result> { + match self { + Self::Polkadot(client) => client.storage(id, key), + Self::Westend(client) => client.storage(id, key), + Self::Kusama(client) => client.storage(id, key), + } + } + + fn storage_keys( + &self, + id: &BlockId, + key_prefix: &StorageKey, + ) -> sp_blockchain::Result> { + match self { + Self::Polkadot(client) => client.storage_keys(id, key_prefix), + Self::Westend(client) => client.storage_keys(id, key_prefix), + Self::Kusama(client) => client.storage_keys(id, key_prefix), + } + } + + fn storage_hash( + &self, + id: &BlockId, + key: &StorageKey, + ) -> sp_blockchain::Result::Hash>> { + match self { + Self::Polkadot(client) => client.storage_hash(id, key), + Self::Westend(client) => client.storage_hash(id, key), + Self::Kusama(client) => client.storage_hash(id, key), + } + } + + fn storage_pairs( + &self, + id: &BlockId, + key_prefix: &StorageKey, + ) -> sp_blockchain::Result> { + match self { + Self::Polkadot(client) => client.storage_pairs(id, key_prefix), + Self::Westend(client) => client.storage_pairs(id, key_prefix), + Self::Kusama(client) => client.storage_pairs(id, key_prefix), + } + } + + fn storage_keys_iter<'a>( + &self, + id: &BlockId, + prefix: Option<&'a StorageKey>, + start_key: Option<&StorageKey>, + ) -> sp_blockchain::Result>::State, Block>> { + match self { + Self::Polkadot(client) => client.storage_keys_iter(id, prefix, start_key), + Self::Westend(client) => client.storage_keys_iter(id, prefix, start_key), + Self::Kusama(client) => client.storage_keys_iter(id, prefix, start_key), + } + } + + fn child_storage( + &self, + id: &BlockId, + child_info: &ChildInfo, + key: &StorageKey, + ) -> sp_blockchain::Result> { + match self { + Self::Polkadot(client) => client.child_storage(id, child_info, key), + Self::Westend(client) => client.child_storage(id, child_info, key), + Self::Kusama(client) => client.child_storage(id, child_info, key), + } + } + + fn child_storage_keys( + &self, + id: &BlockId, + child_info: &ChildInfo, + key_prefix: &StorageKey, + ) -> sp_blockchain::Result> { + match self { + Self::Polkadot(client) => client.child_storage_keys(id, child_info, key_prefix), + Self::Westend(client) => client.child_storage_keys(id, child_info, key_prefix), + Self::Kusama(client) => client.child_storage_keys(id, child_info, key_prefix), + } + } + + fn child_storage_hash( + &self, + id: &BlockId, + child_info: &ChildInfo, + key: &StorageKey, + ) -> sp_blockchain::Result::Hash>> { + match self { + Self::Polkadot(client) => client.child_storage_hash(id, child_info, key), + Self::Westend(client) => client.child_storage_hash(id, child_info, key), + Self::Kusama(client) => client.child_storage_hash(id, child_info, key), + } + } + + fn max_key_changes_range( + &self, + first: NumberFor, + last: BlockId, + ) -> sp_blockchain::Result, BlockId)>> { + match self { + Self::Polkadot(client) => client.max_key_changes_range(first, last), + Self::Westend(client) => client.max_key_changes_range(first, last), + Self::Kusama(client) => client.max_key_changes_range(first, last), + } + } + + fn key_changes( + &self, + first: NumberFor, + last: BlockId, + storage_key: Option<&PrefixedStorageKey>, + key: &StorageKey, + ) -> sp_blockchain::Result, u32)>> { + match self { + Self::Polkadot(client) => client.key_changes(first, last, storage_key, key), + Self::Westend(client) => client.key_changes(first, last, storage_key, key), + Self::Kusama(client) => client.key_changes(first, last, storage_key, key), + } + } +} diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index c8295c29c55c..0377746608ca 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -22,13 +22,12 @@ mod client; use std::sync::Arc; use std::time::Duration; -use polkadot_primitives::v1::{AccountId, Nonce, Balance}; -use service::{error::Error as ServiceError}; +use service::{error::Error as ServiceError, RpcHandlers}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use sc_executor::native_executor_instance; use log::info; use sp_blockchain::HeaderBackend; -use polkadot_overseer::{self as overseer, AllSubsystems, BlockInfo, Overseer, OverseerHandler}; +use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandler}; use polkadot_subsystem::DummySubsystem; use polkadot_node_core_proposer::ProposerFactory; use sp_trie::PrefixedMemoryDB; @@ -55,7 +54,7 @@ pub use polkadot_runtime; pub use kusama_runtime; pub use westend_runtime; use prometheus_endpoint::Registry; -pub use self::client::PolkadotClient; +pub use self::client::{AbstractClient, Client, RuntimeApiCollection}; native_executor_instance!( pub PolkadotExecutor, @@ -78,40 +77,6 @@ native_executor_instance!( frame_benchmarking::benchmarking::HostFunctions, ); -/// A set of APIs that polkadot-like runtimes must implement. -pub trait RuntimeApiCollection: - sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::ApiExt - + babe_primitives::BabeApi - + grandpa_primitives::GrandpaApi - + sp_block_builder::BlockBuilder - + frame_system_rpc_runtime_api::AccountNonceApi - + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi - + sp_api::Metadata - + sp_offchain::OffchainWorkerApi - + sp_session::SessionKeys - + authority_discovery_primitives::AuthorityDiscoveryApi -where - >::StateBackend: sp_api::StateBackend>, -{} - -impl RuntimeApiCollection for Api -where - Api: - sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::ApiExt - + babe_primitives::BabeApi - + grandpa_primitives::GrandpaApi - + sp_block_builder::BlockBuilder - + frame_system_rpc_runtime_api::AccountNonceApi - + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi - + sp_api::Metadata - + sp_offchain::OffchainWorkerApi - + sp_session::SessionKeys - + authority_discovery_primitives::AuthorityDiscoveryApi, - >::StateBackend: sp_api::StateBackend>, -{} - /// Can be called for a `Configuration` to check if it is a configuration for the `Kusama` network. pub trait IdentifyVariant { /// Returns if this is a configuration for the `Kusama` network. @@ -313,13 +278,14 @@ fn real_overseer( fn new_full( mut config: Configuration, collating_for: Option<(CollatorId, ParaId)>, - _max_block_data_size: Option, - _authority_discovery_enabled: bool, - _slot_duration: u64, + authority_discovery_enabled: bool, grandpa_pause: Option<(u32, u32)>, ) -> Result<( TaskManager, Arc>, + Arc::Hash>>, + RpcHandlers, + OverseerHandler, ), Error> where RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, @@ -337,7 +303,13 @@ fn new_full( let name = config.network.node_name.clone(); let service::PartialComponents { - client, backend, mut task_manager, keystore, select_chain, import_queue, transaction_pool, + client, + backend, + mut task_manager, + keystore, + select_chain, + import_queue, + transaction_pool, inherent_data_providers, other: (rpc_extensions_builder, import_setup, rpc_setup) } = new_partial::(&mut config)?; @@ -368,7 +340,7 @@ fn new_full( let telemetry_connection_sinks = service::TelemetryConnectionSinks::default(); - service::spawn_tasks(service::SpawnTasksParams { + let rpc_handlers = service::spawn_tasks(service::SpawnTasksParams { config, backend: backend.clone(), client: client.clone(), @@ -411,7 +383,7 @@ fn new_full( task_manager.spawn_essential_handle().spawn_blocking("overseer", Box::pin(async move { use futures::{pin_mut, select, FutureExt}; - let forward = overseer::forward_events(overseer_client, handler); + let forward = polkadot_overseer::forward_events(overseer_client, handler_clone); let forward = forward.fuse(); let overseer_fut = overseer.run().fuse(); @@ -435,7 +407,7 @@ fn new_full( let proposer = ProposerFactory::new( client.clone(), transaction_pool, - handler_clone, + handler.clone(), ); let babe_config = babe::BabeParams { @@ -457,7 +429,7 @@ fn new_full( // if the node isn't actively participating in consensus then it doesn't // need a keystore, regardless of which protocol we use below. - let keystore = if is_authority { + let keystore_opt = if is_authority { Some(keystore.clone() as BareCryptoStorePtr) } else { None @@ -469,7 +441,7 @@ fn new_full( justification_period: 512, name: Some(name), observer_enabled: false, - keystore, + keystore: keystore_opt, is_authority: role.is_network_authority(), }; @@ -508,7 +480,7 @@ fn new_full( inherent_data_providers: inherent_data_providers.clone(), telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()), voting_rule, - prometheus_registry, + prometheus_registry: prometheus_registry.clone(), shared_voter_state, }; @@ -524,15 +496,51 @@ fn new_full( )?; } + if matches!(role, Role::Authority{..} | Role::Sentry{..}) { + use sc_network::Event; + use futures::StreamExt; + + if authority_discovery_enabled { + let (sentries, authority_discovery_role) = match role { + Role::Authority { ref sentry_nodes } => ( + sentry_nodes.clone(), + authority_discovery::Role::Authority ( + keystore.clone(), + ), + ), + Role::Sentry {..} => ( + vec![], + authority_discovery::Role::Sentry, + ), + _ => unreachable!("Due to outer matches! constraint; qed."), + }; + + let network_event_stream = network.event_stream("authority-discovery"); + let dht_event_stream = network_event_stream.filter_map(|e| async move { match e { + Event::Dht(e) => Some(e), + _ => None, + }}).boxed(); + let (authority_discovery_worker, _service) = authority_discovery::new_worker_and_service( + client.clone(), + network.clone(), + sentries, + dht_event_stream, + authority_discovery_role, + prometheus_registry.clone(), + ); + + task_manager.spawn_handle().spawn("authority-discovery-worker", authority_discovery_worker); + } + } + + network_starter.start_network(); - Ok((task_manager, client)) + Ok((task_manager, client, network, rpc_handlers, handler)) } -pub struct FullNodeHandles; - /// Builds a new service for a light client. -fn new_light(mut config: Configuration) -> Result +fn new_light(mut config: Configuration) -> Result<(TaskManager, RpcHandlers), Error> where Runtime: 'static + Send + Sync + ConstructRuntimeApi>, >>::RuntimeApi: @@ -617,19 +625,25 @@ fn new_light(mut config: Configuration) -> Result, - max_block_data_size: Option, - authority_discovery_enabled: bool, - slot_duration: u64, - grandpa_pause: Option<(u32, u32)>, -) - -> Result<( - TaskManager, - Arc>, - FullNodeHandles, - ), ServiceError> -{ - let (components, client) = new_full::( - config, - collating_for, - max_block_data_size, - authority_discovery_enabled, - slot_duration, - grandpa_pause, - )?; - - Ok((components, client, FullNodeHandles)) -} - -/// Create a new Kusama service for a full node. -#[cfg(feature = "full-node")] -pub fn kusama_new_full( - config: Configuration, - collating_for: Option<(CollatorId, ParaId)>, - max_block_data_size: Option, - authority_discovery_enabled: bool, - slot_duration: u64, - grandpa_pause: Option<(u32, u32)>, -) -> Result<( - TaskManager, - Arc - >, - FullNodeHandles, - ), ServiceError> -{ - let (components, client) = new_full::( - config, - collating_for, - max_block_data_size, - authority_discovery_enabled, - slot_duration, - grandpa_pause, - )?; - - Ok((components, client, FullNodeHandles)) +/// Build a new light node. +pub fn build_light(config: Configuration) -> Result<(TaskManager, RpcHandlers), ServiceError> { + if config.chain_spec.is_kusama() { + new_light::(config) + } else if config.chain_spec.is_westend() { + new_light::(config) + } else { + new_light::(config) + } } -/// Create a new Kusama service for a full node. #[cfg(feature = "full-node")] -pub fn westend_new_full( +pub fn build_full( config: Configuration, collating_for: Option<(CollatorId, ParaId)>, - max_block_data_size: Option, authority_discovery_enabled: bool, - slot_duration: u64, grandpa_pause: Option<(u32, u32)>, -) - -> Result<( - TaskManager, - Arc>, - FullNodeHandles, - ), ServiceError> -{ - let (components, client) = new_full::( - config, - collating_for, - max_block_data_size, - authority_discovery_enabled, - slot_duration, - grandpa_pause, - )?; - - Ok((components, client, FullNodeHandles)) -} - -/// Create a new Polkadot service for a light client. -pub fn polkadot_new_light(config: Configuration) -> Result -{ - new_light::(config) -} - -/// Create a new Kusama service for a light client. -pub fn kusama_new_light(config: Configuration) -> Result -{ - new_light::(config) -} - -/// Create a new Westend service for a light client. -pub fn westend_new_light(config: Configuration, ) -> Result -{ - new_light::(config) +) -> Result<(TaskManager, Client, OverseerHandler), ServiceError> { + if config.chain_spec.is_kusama() { + new_full::( + config, + collating_for, + authority_discovery_enabled, + grandpa_pause, + ).map(|(task_manager, client, _, _, handler)| (task_manager, Client::Kusama(client), handler)) + } else if config.chain_spec.is_westend() { + new_full::( + config, + collating_for, + authority_discovery_enabled, + grandpa_pause, + ).map(|(task_manager, client, _, _, handler)| (task_manager, Client::Westend(client), handler)) + } else { + new_full::( + config, + collating_for, + authority_discovery_enabled, + grandpa_pause, + ).map(|(task_manager, client, _, _, handler)| (task_manager, Client::Polkadot(client), handler)) + } } diff --git a/parachain/Cargo.toml b/parachain/Cargo.toml index 73d7f4bad5f2..027dad3539ef 100644 --- a/parachain/Cargo.toml +++ b/parachain/Cargo.toml @@ -10,7 +10,8 @@ edition = "2018" # this crate for WASM. This is critical to avoid forcing all parachain WASM into implementing # various unnecessary Substrate-specific endpoints. codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = [ "derive" ] } -sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-wasm-interface = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } polkadot-core-primitives = { path = "../core-primitives", default-features = false } @@ -36,6 +37,7 @@ std = [ "derive_more", "serde/std", "sp-std/std", + "sp-runtime/std", "shared_memory", "sp-core/std", "parking_lot", diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index d853a57439ff..12a1798b4f34 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -24,9 +24,10 @@ use sp_std::prelude::*; use sp_core::u32_trait::{_1, _2, _3, _4, _5}; use codec::{Encode, Decode}; use primitives::v1::{ - AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, + AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, ValidatorId, + ValidatorIndex, CoreState, Id, CandidateEvent, ValidationData, OccupiedCoreAssumption, + CommittedCandidateReceipt, PersistedValidationData, GroupRotationInfo, ValidationCode, }; -use primitives::v0 as p_v0; use runtime_common::{ dummy, claims, SlowAdjustingFeeUpdate, impls::{CurrencyToVoteHandler, ToAuthor}, @@ -1046,54 +1047,42 @@ sp_api::impl_runtime_apis! { } } - // Dummy implementation to continue supporting old parachains runtime temporarily. - impl p_v0::ParachainHost for Runtime { - fn validators() -> Vec { - // this is a compile-time check of size equality. note that we don't invoke - // the function and nothing here is unsafe. - let _ = core::mem::transmute::; - - // Yes, these aren't actually the parachain session keys. - // It doesn't matter, but we shouldn't return a zero-sized vector here. - // As there are no parachains - Session::validators() - .into_iter() - .map(|k| k.using_encoded(|s| Decode::decode(&mut &s[..])) - .expect("correct size and raw-bytes; qed")) - .collect() + impl primitives::v1::ParachainHost for Runtime { + fn validators() -> Vec { + Vec::new() } - fn duty_roster() -> p_v0::DutyRoster { - let v = Session::validators(); - p_v0::DutyRoster { validator_duty: (0..v.len()).map(|_| p_v0::Chain::Relay).collect() } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + (Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 }) } - fn active_parachains() -> Vec<(p_v0::Id, Option<(p_v0::CollatorId, p_v0::Retriable)>)> { + + fn availability_cores() -> Vec> { Vec::new() } - fn global_validation_data() -> p_v0::GlobalValidationData { - p_v0::GlobalValidationData { - max_code_size: 1, - max_head_data_size: 1, - block_number: System::block_number().saturating_sub(1), - } - } - fn local_validation_data(_id: p_v0::Id) -> Option { + + fn full_validation_data(_: Id, _: OccupiedCoreAssumption) + -> Option> { None } - fn parachain_code(_id: p_v0::Id) -> Option { + + fn persisted_validation_data(_: Id, _: OccupiedCoreAssumption) + -> Option> { None } - fn get_heads(_extrinsics: Vec<::Extrinsic>) - -> Option> - { + + fn session_index_for_child() -> SessionIndex { + 0 + } + + fn validation_code(_: Id, _: OccupiedCoreAssumption) -> Option { None } - fn signing_context() -> p_v0::SigningContext { - p_v0::SigningContext { - parent_hash: System::parent_hash(), - session_index: Session::current_index(), - } + + fn candidate_pending_availability(_: Id) -> Option> { + None } - fn downward_messages(_id: p_v0::Id) -> Vec { + + fn candidate_events() -> Vec> { Vec::new() } } diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index ffa3a7db9825..d7e9762ffee3 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -32,15 +32,19 @@ use sp_std::prelude::*; use sp_core::u32_trait::{_1, _2, _3, _4, _5}; use codec::{Encode, Decode}; use primitives::v1::{ - AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, + AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, ValidatorId, + ValidatorIndex, CoreState, Id, CandidateEvent, ValidationData, OccupiedCoreAssumption, + CommittedCandidateReceipt, PersistedValidationData, GroupRotationInfo, ValidationCode, +}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, ModuleId, ApplyExtrinsicResult, + KeyTypeId, Percent, Permill, Perbill, curve::PiecewiseLinear, + transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority}, + traits::{ + BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, IdentityLookup, + Extrinsic as ExtrinsicT, SaturatedConversion, Verify, + }, }; -use primitives::v0 as p_v0; -use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, ModuleId, ApplyExtrinsicResult, KeyTypeId, Percent, Permill, Perbill, transaction_validity::{ - TransactionValidity, TransactionSource, TransactionPriority, -}, curve::PiecewiseLinear, traits::{ - BlakeTwo256, Block as BlockT, OpaqueKeys, ConvertInto, IdentityLookup, - Extrinsic as ExtrinsicT, SaturatedConversion, Verify, -}}; #[cfg(feature = "runtime-benchmarks")] use sp_runtime::RuntimeString; use sp_version::RuntimeVersion; @@ -1047,54 +1051,43 @@ sp_api::impl_runtime_apis! { Executive::offchain_worker(header) } } - // Dummy implementation to continue supporting old parachains runtime temporarily. - impl p_v0::ParachainHost for Runtime { - fn validators() -> Vec { - // this is a compile-time check of size equality. note that we don't invoke - // the function and nothing here is unsafe. - let _ = core::mem::transmute::; - - // Yes, these aren't actually the parachain session keys. - // It doesn't matter, but we shouldn't return a zero-sized vector here. - // As there are no parachains - Session::validators() - .into_iter() - .map(|k| k.using_encoded(|s| Decode::decode(&mut &s[..])) - .expect("correct size and raw-bytes; qed")) - .collect() + + impl primitives::v1::ParachainHost for Runtime { + fn validators() -> Vec { + Vec::new() } - fn duty_roster() -> p_v0::DutyRoster { - let v = Session::validators(); - p_v0::DutyRoster { validator_duty: (0..v.len()).map(|_| p_v0::Chain::Relay).collect() } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + (Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 }) } - fn active_parachains() -> Vec<(p_v0::Id, Option<(p_v0::CollatorId, p_v0::Retriable)>)> { + + fn availability_cores() -> Vec> { Vec::new() } - fn global_validation_data() -> p_v0::GlobalValidationData { - p_v0::GlobalValidationData { - max_code_size: 1, - max_head_data_size: 1, - block_number: System::block_number().saturating_sub(1), - } - } - fn local_validation_data(_id: p_v0::Id) -> Option { + + fn full_validation_data(_: Id, _: OccupiedCoreAssumption) + -> Option> { None } - fn parachain_code(_id: p_v0::Id) -> Option { + + fn persisted_validation_data(_: Id, _: OccupiedCoreAssumption) + -> Option> { None } - fn get_heads(_extrinsics: Vec<::Extrinsic>) - -> Option> - { + + fn session_index_for_child() -> SessionIndex { + 0 + } + + fn validation_code(_: Id, _: OccupiedCoreAssumption) -> Option { None } - fn signing_context() -> p_v0::SigningContext { - p_v0::SigningContext { - parent_hash: System::parent_hash(), - session_index: Session::current_index(), - } + + fn candidate_pending_availability(_: Id) -> Option> { + None } - fn downward_messages(_id: p_v0::Id) -> Vec { + + fn candidate_events() -> Vec> { Vec::new() } } diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 8093b44a1fa5..7d070bc83340 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -23,9 +23,10 @@ use sp_std::prelude::*; use codec::{Encode, Decode}; use primitives::v1::{ - AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, + AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, ValidatorId, + ValidatorIndex, CoreState, Id, CandidateEvent, ValidationData, OccupiedCoreAssumption, + CommittedCandidateReceipt, PersistedValidationData, GroupRotationInfo, ValidationCode, }; -use primitives::v0 as p_v0; use runtime_common::{ dummy, purchase, SlowAdjustingFeeUpdate, impls::{CurrencyToVoteHandler, ToAuthor}, @@ -808,54 +809,42 @@ sp_api::impl_runtime_apis! { } } - // Dummy implementation to continue supporting old parachains runtime temporarily. - impl p_v0::ParachainHost for Runtime { - fn validators() -> Vec { - // this is a compile-time check of size equality. note that we don't invoke - // the function and nothing here is unsafe. - let _ = core::mem::transmute::; - - // Yes, these aren't actually the parachain session keys. - // It doesn't matter, but we shouldn't return a zero-sized vector here. - // As there are no parachains - Session::validators() - .into_iter() - .map(|k| k.using_encoded(|s| Decode::decode(&mut &s[..])) - .expect("correct size and raw-bytes; qed")) - .collect() + impl primitives::v1::ParachainHost for Runtime { + fn validators() -> Vec { + Vec::new() } - fn duty_roster() -> p_v0::DutyRoster { - let v = Session::validators(); - p_v0::DutyRoster { validator_duty: (0..v.len()).map(|_| p_v0::Chain::Relay).collect() } + + fn validator_groups() -> (Vec>, GroupRotationInfo) { + (Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 }) } - fn active_parachains() -> Vec<(p_v0::Id, Option<(p_v0::CollatorId, p_v0::Retriable)>)> { + + fn availability_cores() -> Vec> { Vec::new() } - fn global_validation_data() -> p_v0::GlobalValidationData { - p_v0::GlobalValidationData { - max_code_size: 1, - max_head_data_size: 1, - block_number: System::block_number().saturating_sub(1), - } - } - fn local_validation_data(_id: p_v0::Id) -> Option { + + fn full_validation_data(_: Id, _: OccupiedCoreAssumption) + -> Option> { None } - fn parachain_code(_id: p_v0::Id) -> Option { + + fn persisted_validation_data(_: Id, _: OccupiedCoreAssumption) + -> Option> { None } - fn get_heads(_extrinsics: Vec<::Extrinsic>) - -> Option> - { + + fn session_index_for_child() -> SessionIndex { + 0 + } + + fn validation_code(_: Id, _: OccupiedCoreAssumption) -> Option { None } - fn signing_context() -> p_v0::SigningContext { - p_v0::SigningContext { - parent_hash: System::parent_hash(), - session_index: Session::current_index(), - } + + fn candidate_pending_availability(_: Id) -> Option> { + None } - fn downward_messages(_id: p_v0::Id) -> Vec { + + fn candidate_events() -> Vec> { Vec::new() } } diff --git a/service/src/client.rs b/service/src/client.rs index 20e924078ddf..896d922d9584 100644 --- a/service/src/client.rs +++ b/service/src/client.rs @@ -19,13 +19,13 @@ use std::sync::Arc; use sp_api::{ProvideRuntimeApi, CallApiAt, NumberFor}; use sp_blockchain::HeaderBackend; -use sp_runtime::traits::{Block as BlockT, BlakeTwo256}; -use sp_runtime::generic::{BlockId, SignedBlock}; +use sp_runtime::{ + Justification, generic::{BlockId, SignedBlock}, traits::{Block as BlockT, BlakeTwo256}, +}; use consensus_common::BlockStatus; -use sp_runtime::Justification; use sp_storage::{StorageData, StorageKey, ChildInfo, PrefixedStorageKey}; use sc_client_api::{Backend as BackendT, BlockchainEvents, KeyIterator}; -use polkadot_primitives::v0::{Block, ParachainHost, AccountId, Nonce, Balance}; +use polkadot_primitives::v0::{Block, AccountId, Nonce, Balance}; /// A set of APIs that polkadot-like runtimes must implement. pub trait RuntimeApiCollection: @@ -33,7 +33,6 @@ pub trait RuntimeApiCollection: + sp_api::ApiExt + babe_primitives::BabeApi + grandpa_primitives::GrandpaApi - + ParachainHost + sp_block_builder::BlockBuilder + frame_system_rpc_runtime_api::AccountNonceApi + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi @@ -52,7 +51,6 @@ where + sp_api::ApiExt + babe_primitives::BabeApi + grandpa_primitives::GrandpaApi - + ParachainHost + sp_block_builder::BlockBuilder + frame_system_rpc_runtime_api::AccountNonceApi + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi @@ -173,7 +171,7 @@ impl sc_client_api::UsageProvider for Client { impl sc_client_api::BlockBackend for Client { fn block_body( - &self, + &self, id: &BlockId ) -> sp_blockchain::Result::Extrinsic>>> { match self { @@ -200,7 +198,7 @@ impl sc_client_api::BlockBackend for Client { } fn justification( - &self, + &self, id: &BlockId ) -> sp_blockchain::Result> { match self { @@ -211,7 +209,7 @@ impl sc_client_api::BlockBackend for Client { } fn block_hash( - &self, + &self, number: NumberFor ) -> sp_blockchain::Result::Hash>> { match self { @@ -224,9 +222,9 @@ impl sc_client_api::BlockBackend for Client { impl sc_client_api::StorageProvider for Client { fn storage( - &self, - id: &BlockId, - key: &StorageKey + &self, + id: &BlockId, + key: &StorageKey, ) -> sp_blockchain::Result> { match self { Self::Polkadot(client) => client.storage(id, key), @@ -236,9 +234,9 @@ impl sc_client_api::StorageProvider for Client { } fn storage_keys( - &self, - id: &BlockId, - key_prefix: &StorageKey + &self, + id: &BlockId, + key_prefix: &StorageKey, ) -> sp_blockchain::Result> { match self { Self::Polkadot(client) => client.storage_keys(id, key_prefix), @@ -246,11 +244,11 @@ impl sc_client_api::StorageProvider for Client { Self::Kusama(client) => client.storage_keys(id, key_prefix), } } - + fn storage_hash( - &self, - id: &BlockId, - key: &StorageKey + &self, + id: &BlockId, + key: &StorageKey, ) -> sp_blockchain::Result::Hash>> { match self { Self::Polkadot(client) => client.storage_hash(id, key), @@ -260,9 +258,9 @@ impl sc_client_api::StorageProvider for Client { } fn storage_pairs( - &self, - id: &BlockId, - key_prefix: &StorageKey + &self, + id: &BlockId, + key_prefix: &StorageKey, ) -> sp_blockchain::Result> { match self { Self::Polkadot(client) => client.storage_pairs(id, key_prefix), @@ -272,10 +270,10 @@ impl sc_client_api::StorageProvider for Client { } fn storage_keys_iter<'a>( - &self, - id: &BlockId, - prefix: Option<&'a StorageKey>, - start_key: Option<&StorageKey> + &self, + id: &BlockId, + prefix: Option<&'a StorageKey>, + start_key: Option<&StorageKey>, ) -> sp_blockchain::Result>::State, Block>> { match self { Self::Polkadot(client) => client.storage_keys_iter(id, prefix, start_key), @@ -285,10 +283,10 @@ impl sc_client_api::StorageProvider for Client { } fn child_storage( - &self, - id: &BlockId, - child_info: &ChildInfo, - key: &StorageKey + &self, + id: &BlockId, + child_info: &ChildInfo, + key: &StorageKey, ) -> sp_blockchain::Result> { match self { Self::Polkadot(client) => client.child_storage(id, child_info, key), @@ -298,10 +296,10 @@ impl sc_client_api::StorageProvider for Client { } fn child_storage_keys( - &self, - id: &BlockId, - child_info: &ChildInfo, - key_prefix: &StorageKey + &self, + id: &BlockId, + child_info: &ChildInfo, + key_prefix: &StorageKey, ) -> sp_blockchain::Result> { match self { Self::Polkadot(client) => client.child_storage_keys(id, child_info, key_prefix), @@ -311,10 +309,10 @@ impl sc_client_api::StorageProvider for Client { } fn child_storage_hash( - &self, - id: &BlockId, - child_info: &ChildInfo, - key: &StorageKey + &self, + id: &BlockId, + child_info: &ChildInfo, + key: &StorageKey, ) -> sp_blockchain::Result::Hash>> { match self { Self::Polkadot(client) => client.child_storage_hash(id, child_info, key), @@ -324,9 +322,9 @@ impl sc_client_api::StorageProvider for Client { } fn max_key_changes_range( - &self, - first: NumberFor, - last: BlockId + &self, + first: NumberFor, + last: BlockId, ) -> sp_blockchain::Result, BlockId)>> { match self { Self::Polkadot(client) => client.max_key_changes_range(first, last), @@ -336,11 +334,11 @@ impl sc_client_api::StorageProvider for Client { } fn key_changes( - &self, - first: NumberFor, - last: BlockId, - storage_key: Option<&PrefixedStorageKey>, - key: &StorageKey + &self, + first: NumberFor, + last: BlockId, + storage_key: Option<&PrefixedStorageKey>, + key: &StorageKey, ) -> sp_blockchain::Result, u32)>> { match self { Self::Polkadot(client) => client.key_changes(first, last, storage_key, key),