diff --git a/cumulus/polkadot-parachains/parachains-common/src/lib.rs b/cumulus/polkadot-parachains/parachains-common/src/lib.rs index f592b94e56b14200f25a4f42ee2ecc2bfad28a49..c04f0a37798bf18385e25f2313bbd245f53783f4 100644 --- a/cumulus/polkadot-parachains/parachains-common/src/lib.rs +++ b/cumulus/polkadot-parachains/parachains-common/src/lib.rs @@ -52,6 +52,13 @@ mod types { // Aura consensus authority. pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; + // Aura consensus authority used by Statemint. + // + // Because of registering the authorities with an ed25519 key before switching from Shell + // to Statemint, we were required to deploy a hotfix that changed Statemint to ed22519. + // In the future that may change again. + pub type StatemintAuraId = sp_consensus_aura::ed25519::AuthorityId; + // Id used for identifying assets. pub type AssetId = u32; } diff --git a/cumulus/polkadot-parachains/src/chain_spec.rs b/cumulus/polkadot-parachains/src/chain_spec.rs index b0cbda9d9f0efdb37be62a765b5246c00ed7e49b..c0ea616343137cfcc8751356d6ce6effa778d1a0 100644 --- a/cumulus/polkadot-parachains/src/chain_spec.rs +++ b/cumulus/polkadot-parachains/src/chain_spec.rs @@ -220,7 +220,7 @@ fn seedling_testnet_genesis( } } -use parachains_common::Balance as StatemintBalance; +use parachains_common::{Balance as StatemintBalance, StatemintAuraId}; /// Specialized `ChainSpec` for the normal parachain runtime. pub type StatemintChainSpec = @@ -244,14 +244,14 @@ pub fn get_public_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pa /// Generate collator keys from seed. /// /// This function's return type must always match the session keys of the chain in tuple format. -pub fn get_collator_keys_from_seed(seed: &str) -> AuraId { +pub fn get_collator_keys_from_seed<AuraId: Public>(seed: &str) -> <AuraId::Pair as Pair>::Public { get_public_from_seed::<AuraId>(seed) } /// Generate the session keys from individual elements. /// /// The input must be a tuple of individual keys (a single arg for now since we have just one key). -pub fn statemint_session_keys(keys: AuraId) -> statemint_runtime::SessionKeys { +pub fn statemint_session_keys(keys: StatemintAuraId) -> statemint_runtime::SessionKeys { statemint_runtime::SessionKeys { aura: keys } } @@ -286,7 +286,7 @@ pub fn statemint_development_config() -> StatemintChainSpec { // initial collators. vec![( get_account_id_from_seed::<sr25519::Public>("Alice"), - get_collator_keys_from_seed("Alice"), + get_collator_keys_from_seed::<StatemintAuraId>("Alice"), )], vec![ get_account_id_from_seed::<sr25519::Public>("Alice"), @@ -324,11 +324,11 @@ pub fn statemint_local_config() -> StatemintChainSpec { vec![ ( get_account_id_from_seed::<sr25519::Public>("Alice"), - get_collator_keys_from_seed("Alice"), + get_collator_keys_from_seed::<StatemintAuraId>("Alice"), ), ( get_account_id_from_seed::<sr25519::Public>("Bob"), - get_collator_keys_from_seed("Bob"), + get_collator_keys_from_seed::<StatemintAuraId>("Bob"), ), ], vec![ @@ -418,7 +418,7 @@ pub fn statemint_config() -> StatemintChainSpec { } fn statemint_genesis( - invulnerables: Vec<(AccountId, AuraId)>, + invulnerables: Vec<(AccountId, StatemintAuraId)>, endowed_accounts: Vec<AccountId>, id: ParaId, ) -> statemint_runtime::GenesisConfig { @@ -474,7 +474,7 @@ pub fn statemine_development_config() -> StatemineChainSpec { // initial collators. vec![( get_account_id_from_seed::<sr25519::Public>("Alice"), - get_collator_keys_from_seed("Alice"), + get_collator_keys_from_seed::<AuraId>("Alice"), )], vec![ get_account_id_from_seed::<sr25519::Public>("Alice"), @@ -512,11 +512,11 @@ pub fn statemine_local_config() -> StatemineChainSpec { vec![ ( get_account_id_from_seed::<sr25519::Public>("Alice"), - get_collator_keys_from_seed("Alice"), + get_collator_keys_from_seed::<AuraId>("Alice"), ), ( get_account_id_from_seed::<sr25519::Public>("Bob"), - get_collator_keys_from_seed("Bob"), + get_collator_keys_from_seed::<AuraId>("Bob"), ), ], vec![ @@ -657,7 +657,7 @@ pub fn westmint_development_config() -> WestmintChainSpec { // initial collators. vec![( get_account_id_from_seed::<sr25519::Public>("Alice"), - get_collator_keys_from_seed("Alice"), + get_collator_keys_from_seed::<AuraId>("Alice"), )], vec![ get_account_id_from_seed::<sr25519::Public>("Alice"), @@ -694,11 +694,11 @@ pub fn westmint_local_config() -> WestmintChainSpec { vec![ ( get_account_id_from_seed::<sr25519::Public>("Alice"), - get_collator_keys_from_seed("Alice"), + get_collator_keys_from_seed::<AuraId>("Alice"), ), ( get_account_id_from_seed::<sr25519::Public>("Bob"), - get_collator_keys_from_seed("Bob"), + get_collator_keys_from_seed::<AuraId>("Bob"), ), ], vec![ diff --git a/cumulus/polkadot-parachains/src/command.rs b/cumulus/polkadot-parachains/src/command.rs index 73a9690fd9208aa918ae38394d1bf24a65201374..4f0ed19b69488b149a4d32dc14af9826dbca75c3 100644 --- a/cumulus/polkadot-parachains/src/command.rs +++ b/cumulus/polkadot-parachains/src/command.rs @@ -27,6 +27,7 @@ use codec::Encode; use cumulus_client_service::genesis::generate_genesis_block; use cumulus_primitives_core::ParaId; use log::info; +use parachains_common::{AuraId, StatemintAuraId}; use polkadot_parachain::primitives::AccountIdConversion; use sc_cli::{ ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, @@ -254,7 +255,7 @@ macro_rules! construct_async_run { runner.async_run(|$config| { let $components = new_partial::<westmint_runtime::RuntimeApi, WestmintRuntimeExecutor, _>( &$config, - crate::service::statemint_build_import_queue, + crate::service::statemint_build_import_queue::<_, _, AuraId>, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) @@ -263,7 +264,7 @@ macro_rules! construct_async_run { runner.async_run(|$config| { let $components = new_partial::<statemine_runtime::RuntimeApi, StatemineRuntimeExecutor, _>( &$config, - crate::service::statemint_build_import_queue, + crate::service::statemint_build_import_queue::<_, _, AuraId>, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) @@ -272,7 +273,7 @@ macro_rules! construct_async_run { runner.async_run(|$config| { let $components = new_partial::<statemint_runtime::RuntimeApi, StatemintRuntimeExecutor, _>( &$config, - crate::service::statemint_build_import_queue, + crate::service::statemint_build_import_queue::<_, _, StatemintAuraId>, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) @@ -502,6 +503,7 @@ pub fn run() -> Result<()> { crate::service::start_statemint_node::< statemint_runtime::RuntimeApi, StatemintRuntimeExecutor, + StatemintAuraId, >(config, polkadot_config, id) .await .map(|r| r.0) @@ -510,6 +512,7 @@ pub fn run() -> Result<()> { crate::service::start_statemint_node::< statemine_runtime::RuntimeApi, StatemineRuntimeExecutor, + AuraId, >(config, polkadot_config, id) .await .map(|r| r.0) @@ -518,6 +521,7 @@ pub fn run() -> Result<()> { crate::service::start_statemint_node::< westmint_runtime::RuntimeApi, WestmintRuntimeExecutor, + AuraId, >(config, polkadot_config, id) .await .map(|r| r.0) diff --git a/cumulus/polkadot-parachains/src/service.rs b/cumulus/polkadot-parachains/src/service.rs index d248240a5a75cc1181431c9ed4d9bb09af6bfc9c..c8001eef541f3eaa5f7033841d76c5443698ba68 100644 --- a/cumulus/polkadot-parachains/src/service.rs +++ b/cumulus/polkadot-parachains/src/service.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see <http://www.gnu.org/licenses/>. +use codec::Codec; use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion}; use cumulus_client_consensus_common::{ ParachainBlockImport, ParachainCandidate, ParachainConsensus, @@ -46,13 +47,15 @@ use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClie use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; use sp_api::{ApiExt, ConstructRuntimeApi}; use sp_consensus::{CacheKeyId, SlotData}; -use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi}; +use sp_consensus_aura::AuraApi; +use sp_core::crypto::Pair; use sp_keystore::SyncCryptoStorePtr; use sp_runtime::{ + app_crypto::AppKey, generic::BlockId, traits::{BlakeTwo256, Header as HeaderT}, }; -use std::{sync::Arc, time::Duration}; +use std::{marker::PhantomData, sync::Arc, time::Duration}; use substrate_prometheus_endpoint::Registry; /// Native executor instance. @@ -907,27 +910,30 @@ impl<R> BuildOnAccess<R> { /// Special [`ParachainConsensus`] implementation that waits for the upgrade from /// shell to a parachain runtime that implements Aura. -struct WaitForAuraConsensus<Client> { +struct WaitForAuraConsensus<Client, AuraId> { client: Arc<Client>, aura_consensus: Arc<Mutex<BuildOnAccess<Box<dyn ParachainConsensus<Block>>>>>, relay_chain_consensus: Arc<Mutex<Box<dyn ParachainConsensus<Block>>>>, + _phantom: PhantomData<AuraId>, } -impl<Client> Clone for WaitForAuraConsensus<Client> { +impl<Client, AuraId> Clone for WaitForAuraConsensus<Client, AuraId> { fn clone(&self) -> Self { Self { client: self.client.clone(), aura_consensus: self.aura_consensus.clone(), relay_chain_consensus: self.relay_chain_consensus.clone(), + _phantom: PhantomData, } } } #[async_trait::async_trait] -impl<Client> ParachainConsensus<Block> for WaitForAuraConsensus<Client> +impl<Client, AuraId> ParachainConsensus<Block> for WaitForAuraConsensus<Client, AuraId> where Client: sp_api::ProvideRuntimeApi<Block> + Send + Sync, Client::Api: AuraApi<Block, AuraId>, + AuraId: Send + Codec + Sync, { async fn produce_candidate( &mut self, @@ -958,17 +964,19 @@ where } } -struct Verifier<Client> { +struct Verifier<Client, AuraId> { client: Arc<Client>, aura_verifier: BuildOnAccess<Box<dyn VerifierT<Block>>>, relay_chain_verifier: Box<dyn VerifierT<Block>>, + _phantom: PhantomData<AuraId>, } #[async_trait::async_trait] -impl<Client> VerifierT<Block> for Verifier<Client> +impl<Client, AuraId> VerifierT<Block> for Verifier<Client, AuraId> where Client: sp_api::ProvideRuntimeApi<Block> + Send + Sync, Client::Api: AuraApi<Block, AuraId>, + AuraId: Send + Sync + Codec, { async fn verify( &mut self, @@ -990,7 +998,7 @@ where } /// Build the import queue for the statemint/statemine/westmine runtime. -pub fn statemint_build_import_queue<RuntimeApi, Executor>( +pub fn statemint_build_import_queue<RuntimeApi, Executor, AuraId: AppKey>( client: Arc<TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>>, config: &Configuration, telemetry_handle: Option<TelemetryHandle>, @@ -1015,38 +1023,39 @@ where StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>, > + sp_offchain::OffchainWorkerApi<Block> + sp_block_builder::BlockBuilder<Block> - + sp_consensus_aura::AuraApi<Block, AuraId>, + + sp_consensus_aura::AuraApi<Block, <<AuraId as AppKey>::Pair as Pair>::Public>, sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>, Executor: sc_executor::NativeExecutionDispatch + 'static, + <<AuraId as AppKey>::Pair as Pair>::Signature: + TryFrom<Vec<u8>> + std::hash::Hash + sp_runtime::traits::Member + Codec, { let client2 = client.clone(); let aura_verifier = move || { let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client2).unwrap(); - Box::new(cumulus_client_consensus_aura::build_verifier::< - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - >(cumulus_client_consensus_aura::BuildVerifierParams { - client: client2.clone(), - create_inherent_data_providers: move |_, _| async move { - let time = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = + Box::new( + cumulus_client_consensus_aura::build_verifier::<<AuraId as AppKey>::Pair, _, _, _>( + cumulus_client_consensus_aura::BuildVerifierParams { + client: client2.clone(), + create_inherent_data_providers: move |_, _| async move { + let time = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( *time, slot_duration.slot_duration(), ); - Ok((time, slot)) - }, - can_author_with: sp_consensus::CanAuthorWithNativeVersion::new( - client2.executor().clone(), + Ok((time, slot)) + }, + can_author_with: sp_consensus::CanAuthorWithNativeVersion::new( + client2.executor().clone(), + ), + telemetry: telemetry_handle, + }, ), - telemetry: telemetry_handle, - })) as Box<_> + ) as Box<_> }; let relay_chain_verifier = @@ -1056,6 +1065,7 @@ where client: client.clone(), relay_chain_verifier, aura_verifier: BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier))), + _phantom: PhantomData, }; let registry = config.prometheus_registry().clone(); @@ -1071,7 +1081,7 @@ where } /// Start a statemint/statemine/westmint parachain node. -pub async fn start_statemint_node<RuntimeApi, Executor>( +pub async fn start_statemint_node<RuntimeApi, Executor, AuraId: AppKey>( parachain_config: Configuration, polkadot_config: Configuration, id: ParaId, @@ -1093,18 +1103,20 @@ where > + sp_offchain::OffchainWorkerApi<Block> + sp_block_builder::BlockBuilder<Block> + cumulus_primitives_core::CollectCollationInfo<Block> - + sp_consensus_aura::AuraApi<Block, AuraId> + + sp_consensus_aura::AuraApi<Block, <<AuraId as AppKey>::Pair as Pair>::Public> + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance> + frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>, sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>, Executor: sc_executor::NativeExecutionDispatch + 'static, + <<AuraId as AppKey>::Pair as Pair>::Signature: + TryFrom<Vec<u8>> + std::hash::Hash + sp_runtime::traits::Member + Codec, { start_node_impl::<RuntimeApi, Executor, _, _, _>( parachain_config, polkadot_config, id, |_| Ok(Default::default()), - statemint_build_import_queue, + statemint_build_import_queue::<_, _, AuraId>, |client, prometheus_registry, telemetry, @@ -1132,7 +1144,7 @@ where telemetry2.clone(), ); - AuraConsensus::build::<sp_consensus_aura::sr25519::AuthorityPair, _, _, _, _, _, _>( + AuraConsensus::build::<<AuraId as AppKey>::Pair, _, _, _, _, _, _>( BuildAuraConsensusParams { proposer_factory, create_inherent_data_providers: @@ -1220,6 +1232,7 @@ where client: client.clone(), aura_consensus: Arc::new(Mutex::new(aura_consensus)), relay_chain_consensus: Arc::new(Mutex::new(relay_chain_consensus)), + _phantom: PhantomData, }); Ok(parachain_consensus) diff --git a/cumulus/polkadot-parachains/statemint/src/lib.rs b/cumulus/polkadot-parachains/statemint/src/lib.rs index b83752e267dcdc39145c1710688c52528e553a3e..566eff5a051c6c02ca232a0055f7e86fb0f37e1b 100644 --- a/cumulus/polkadot-parachains/statemint/src/lib.rs +++ b/cumulus/polkadot-parachains/statemint/src/lib.rs @@ -57,8 +57,9 @@ use frame_system::{ pub use parachains_common as common; use parachains_common::{ impls::{AssetsToBlockAuthor, DealWithFees, NonZeroIssuance}, - opaque, AccountId, AssetId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature, - AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, + opaque, AccountId, AssetId, Balance, BlockNumber, Hash, Header, Index, Signature, + StatemintAuraId as AuraId, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, + NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; #[cfg(any(feature = "std", test))]