From 70f87e826c20c70d0e053b048ab7657f9bd4e9c5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 23 Sep 2021 00:13:12 +0300 Subject: [PATCH] Add rialto-parachain runtime and node (#1142) * Substrate: 63b32fbaa2764c0a8ee76b70cdfa0fcb59b7181f Polkadot: 7229ab87acf5bc5d4d10655ad1a9819a1e317442 Cumulus: d5284b0e78be3a18a3371103dd00449aceb082df * rialto parachain runtime * fixed tests * add node + bump refs (not compiling yet): Substrate: 630422d6108cbaaca893ab213dde69f3bdaa1f6b Polkadot: 7229ab87acf5bc5d4d10655ad1a9819a1e317442 Cumulus: 5af2990cfd3711f86c7cb8606b22364208a5c32d GrandpaBridgeGadget: c152c45ac331eb8ab40d956ab1d008d181810ef4 * fix compilation (collator is not working) * more fixes * fmt * spellcheck * fix warnings * fix compilation * fmt * trigger CI * trigger CI * Revert "trigger CI" This reverts commit a31f53cec47909817b31a48f3c9f1abd9321f72c. * benchmarks * fix benchmarks * fix again * Revert "Revert "trigger CI"" This reverts commit 1dea8b42ac8bca830dea982fd2613eb89d607a6c. * Revert "Revert "Revert "trigger CI""" This reverts commit 8fb74fa5eba483b7f6a3ce3e25a60757aef4c6bc. * try fix * lost lock file * spellcheck * try to disable sccache for cargo check * Revert "Revert "Revert "Revert "trigger CI"""" This reverts commit f157461482d4c1d19156715c4b1ee2acb169531b. * try to disable again * disable sccache for test --- bridges/bin/millau/node/Cargo.toml | 2 +- bridges/bin/millau/node/src/command.rs | 4 +- bridges/bin/millau/node/src/service.rs | 59 +- bridges/bin/millau/runtime/Cargo.toml | 2 +- bridges/bin/millau/runtime/src/lib.rs | 16 +- bridges/bin/rialto-parachain/node/Cargo.toml | 89 +++ bridges/bin/rialto-parachain/node/build.rs | 22 + .../rialto-parachain/node/src/chain_spec.rs | 166 +++++ bridges/bin/rialto-parachain/node/src/cli.rs | 146 ++++ .../bin/rialto-parachain/node/src/command.rs | 414 +++++++++++ bridges/bin/rialto-parachain/node/src/lib.rs | 18 + bridges/bin/rialto-parachain/node/src/main.rs | 29 + .../bin/rialto-parachain/node/src/service.rs | 461 ++++++++++++ .../bin/rialto-parachain/runtime/Cargo.toml | 115 +++ bridges/bin/rialto-parachain/runtime/build.rs | 25 + .../bin/rialto-parachain/runtime/src/lib.rs | 682 ++++++++++++++++++ bridges/bin/rialto/node/Cargo.toml | 9 +- bridges/bin/rialto/node/src/chain_spec.rs | 8 +- bridges/bin/rialto/node/src/command.rs | 4 +- bridges/bin/rialto/node/src/overseer.rs | 127 +++- bridges/bin/rialto/node/src/parachains_db.rs | 10 +- bridges/bin/rialto/node/src/service.rs | 131 ++-- bridges/bin/rialto/runtime/Cargo.toml | 2 +- bridges/bin/rialto/runtime/src/lib.rs | 51 +- bridges/bin/rialto/runtime/src/parachains.rs | 1 + bridges/modules/currency-exchange/src/lib.rs | 2 +- bridges/modules/dispatch/src/lib.rs | 12 +- bridges/modules/ethereum/src/mock.rs | 2 +- bridges/modules/grandpa/src/mock.rs | 2 +- bridges/modules/messages/src/mock.rs | 2 +- .../modules/shift-session-manager/src/lib.rs | 2 +- bridges/modules/token-swap/src/mock.rs | 2 +- bridges/primitives/chain-millau/Cargo.toml | 4 +- bridges/primitives/messages/Cargo.toml | 2 +- .../bin-substrate/src/cli/encode_call.rs | 2 +- .../bin-substrate/src/cli/encode_message.rs | 2 +- .../bin-substrate/src/cli/send_message.rs | 4 +- bridges/relays/client-substrate/Cargo.toml | 2 +- bridges/relays/client-substrate/src/chain.rs | 2 +- bridges/relays/client-substrate/src/client.rs | 4 +- bridges/relays/client-substrate/src/guard.rs | 2 + bridges/relays/headers/src/sync.rs | 4 +- bridges/relays/headers/src/sync_loop.rs | 8 +- 43 files changed, 2504 insertions(+), 149 deletions(-) create mode 100644 bridges/bin/rialto-parachain/node/Cargo.toml create mode 100644 bridges/bin/rialto-parachain/node/build.rs create mode 100644 bridges/bin/rialto-parachain/node/src/chain_spec.rs create mode 100644 bridges/bin/rialto-parachain/node/src/cli.rs create mode 100644 bridges/bin/rialto-parachain/node/src/command.rs create mode 100644 bridges/bin/rialto-parachain/node/src/lib.rs create mode 100644 bridges/bin/rialto-parachain/node/src/main.rs create mode 100644 bridges/bin/rialto-parachain/node/src/service.rs create mode 100644 bridges/bin/rialto-parachain/runtime/Cargo.toml create mode 100644 bridges/bin/rialto-parachain/runtime/build.rs create mode 100644 bridges/bin/rialto-parachain/runtime/src/lib.rs diff --git a/bridges/bin/millau/node/Cargo.toml b/bridges/bin/millau/node/Cargo.toml index 18d301d354..3307d6031d 100644 --- a/bridges/bin/millau/node/Cargo.toml +++ b/bridges/bin/millau/node/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/parity-bridges-common/" license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] -jsonrpc-core = "15.1.0" +jsonrpc-core = "18.0" structopt = "0.3.21" serde_json = "1.0.59" diff --git a/bridges/bin/millau/node/src/command.rs b/bridges/bin/millau/node/src/command.rs index d73f9b1ac9..61786452e0 100644 --- a/bridges/bin/millau/node/src/command.rs +++ b/bridges/bin/millau/node/src/command.rs @@ -79,7 +79,7 @@ pub fn run() -> sc_cli::Result<()> { if cfg!(feature = "runtime-benchmarks") { let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run::(config)) + runner.sync_run(|config| cmd.run::(config)) } else { println!( "Benchmarking wasn't enabled when building the node. \ @@ -156,7 +156,7 @@ pub fn run() -> sc_cli::Result<()> { } Some(Subcommand::Inspect(cmd)) => { let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run::(config)) + runner.sync_run(|config| cmd.run::(config)) } None => { let runner = cli.create_runner(&cli.run)?; diff --git a/bridges/bin/millau/node/src/service.rs b/bridges/bin/millau/node/src/service.rs index 2373d0fbdc..3e8d16f596 100644 --- a/bridges/bin/millau/node/src/service.rs +++ b/bridges/bin/millau/node/src/service.rs @@ -31,8 +31,7 @@ use millau_runtime::{self, opaque::Block, RuntimeApi}; use sc_client_api::{ExecutorProvider, RemoteBackend}; use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; -use sc_executor::native_executor_instance; -pub use sc_executor::NativeExecutor; +pub use sc_executor::NativeElseWasmExecutor; use sc_keystore::LocalKeystore; use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; @@ -41,15 +40,24 @@ use sp_consensus::SlotData; use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; use std::{sync::Arc, time::Duration}; -// Our native executor instance. -native_executor_instance!( - pub Executor, - millau_runtime::api::dispatch, - millau_runtime::native_version, - frame_benchmarking::benchmarking::HostFunctions, -); +type Executor = NativeElseWasmExecutor; -type FullClient = sc_service::TFullClient; +// Our native executor instance. +pub struct ExecutorDispatch; + +impl sc_executor::NativeExecutionDispatch for ExecutorDispatch { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + + fn dispatch(method: &str, data: &[u8]) -> Option> { + millau_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + millau_runtime::native_version() + } +} + +type FullClient = sc_service::TFullClient>; type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; @@ -61,7 +69,7 @@ pub fn new_partial( FullClient, FullBackend, FullSelectChain, - sp_consensus::DefaultImportQueue, + sc_consensus::DefaultImportQueue, sc_transaction_pool::FullPool, ( sc_finality_grandpa::GrandpaBlockImport, @@ -86,9 +94,16 @@ pub fn new_partial( }) .transpose()?; + let executor = NativeElseWasmExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + ); + let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::( config, telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, )?; let client = Arc::new(client); @@ -185,6 +200,10 @@ pub fn new_full(mut config: Configuration) -> Result .network .extra_sets .push(sc_finality_grandpa::grandpa_peers_set_config()); + let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + grandpa_link.shared_authority_set().clone(), + )); let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -194,6 +213,7 @@ pub fn new_full(mut config: Configuration) -> Result import_queue, on_demand: None, block_announce_validator_builder: None, + warp_sync: Some(warp_sync), })?; if config.offchain_worker.enabled { @@ -244,7 +264,7 @@ pub fn new_full(mut config: Configuration) -> Result subscription_executor, finality_proof_provider.clone(), ))); - io + Ok(io) }) }; @@ -369,10 +389,17 @@ pub fn new_light(mut config: Configuration) -> Result }) .transpose()?; + let executor = NativeElseWasmExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + ); + let (client, backend, keystore_container, mut task_manager, on_demand) = sc_service::new_light_parts::( &config, telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, )?; let mut telemetry = telemetry.map(|(worker, telemetry)| { @@ -425,6 +452,11 @@ pub fn new_light(mut config: Configuration) -> Result telemetry: telemetry.as_ref().map(|x| x.handle()), })?; + let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + grandpa_link.shared_authority_set().clone(), + )); + let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, client: client.clone(), @@ -433,6 +465,7 @@ pub fn new_light(mut config: Configuration) -> Result import_queue, on_demand: Some(on_demand.clone()), block_announce_validator_builder: None, + warp_sync: Some(warp_sync), })?; if config.offchain_worker.enabled { @@ -464,7 +497,7 @@ pub fn new_light(mut config: Configuration) -> Result transaction_pool, task_manager: &mut task_manager, on_demand: Some(on_demand), - rpc_extensions_builder: Box::new(|_, _| ()), + rpc_extensions_builder: Box::new(|_, _| Ok(())), config, client, keystore: keystore_container.sync_keystore(), diff --git a/bridges/bin/millau/runtime/Cargo.toml b/bridges/bin/millau/runtime/Cargo.toml index 271ff3cc98..68d10168e4 100644 --- a/bridges/bin/millau/runtime/Cargo.toml +++ b/bridges/bin/millau/runtime/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.124", optional = true, features = ["derive"] } +serde = { version = "1.0", optional = true, features = ["derive"] } # Bridge dependencies diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 3aa42ef8bd..ce3ca28d39 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -156,7 +156,7 @@ parameter_types! { impl frame_system::Config for Runtime { /// The basic call filter to use in dispatchable. - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. @@ -206,14 +206,20 @@ impl frame_system::Config for Runtime { impl pallet_randomness_collective_flip::Config for Runtime {} +parameter_types! { + pub const MaxAuthorities: u32 = 10; +} + impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; + type MaxAuthorities = MaxAuthorities; + type DisabledValidators = (); } impl pallet_bridge_dispatch::Config for Runtime { type Event = Event; type BridgeMessageId = (bp_messages::LaneId, bp_messages::MessageNonce); type Call = Call; - type CallFilter = (); + type CallFilter = frame_support::traits::Everything; type EncodedCall = crate::rialto_messages::FromRialtoEncodedCall; type SourceChainAccountId = bp_rialto::AccountId; type TargetChainAccountPublic = MultiSigner; @@ -555,7 +561,7 @@ impl_runtime_apis! { } fn authorities() -> Vec { - Aura::authorities() + Aura::authorities().to_vec() } } @@ -584,6 +590,10 @@ impl_runtime_apis! { } impl fg_primitives::GrandpaApi for Runtime { + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + fn grandpa_authorities() -> GrandpaAuthorityList { Grandpa::grandpa_authorities() } diff --git a/bridges/bin/rialto-parachain/node/Cargo.toml b/bridges/bin/rialto-parachain/node/Cargo.toml new file mode 100644 index 0000000000..8adc998e47 --- /dev/null +++ b/bridges/bin/rialto-parachain/node/Cargo.toml @@ -0,0 +1,89 @@ +[package] +name = "rialto-parachain-collator" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/parity-bridges-common/" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[build-dependencies] +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[[bin]] +name = 'rialto-parachain-collator' + +[features] +default = [] +runtime-benchmarks = ['rialto-parachain-runtime/runtime-benchmarks'] + +[dependencies] +derive_more = '0.99.2' +log = '0.4.14' +codec = { package = 'parity-scale-codec', version = '2.0.0' } +structopt = '0.3.8' +serde = { version = '1.0', features = ['derive'] } +hex-literal = '0.3.1' + +# RPC related Dependencies +jsonrpc-core = '18.0' + +# Local Dependencies +rialto-parachain-runtime = { path = '../runtime' } + +# Substrate Dependencies +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } + +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } + +substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" } + +## Substrate Client Dependencies +sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master", features = ['wasmtime'] } +sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } + +## Substrate Primitive Dependencies +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } + +# Cumulus dependencies +cumulus-client-consensus-aura = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-client-consensus-common = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-client-collator = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-client-cli = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-client-network = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-client-service = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "master" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus", branch = "master" } + +# Polkadot dependencies +polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "master" } \ No newline at end of file diff --git a/bridges/bin/rialto-parachain/node/build.rs b/bridges/bin/rialto-parachain/node/build.rs new file mode 100644 index 0000000000..8ba8a31e9a --- /dev/null +++ b/bridges/bin/rialto-parachain/node/build.rs @@ -0,0 +1,22 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; + +fn main() { + generate_cargo_keys(); + rerun_if_git_head_changed(); +} diff --git a/bridges/bin/rialto-parachain/node/src/chain_spec.rs b/bridges/bin/rialto-parachain/node/src/chain_spec.rs new file mode 100644 index 0000000000..728c4a0a8e --- /dev/null +++ b/bridges/bin/rialto-parachain/node/src/chain_spec.rs @@ -0,0 +1,166 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use cumulus_primitives_core::ParaId; +use rialto_parachain_runtime::{AccountId, AuraId, Signature}; +use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; +use sc_service::ChainType; +use serde::{Deserialize, Serialize}; +use sp_core::{sr25519, Pair, Public}; +use sp_runtime::traits::{IdentifyAccount, Verify}; + +/// Specialized `ChainSpec` for the normal parachain runtime. +pub type ChainSpec = sc_service::GenericChainSpec; + +/// Helper function to generate a crypto pair from seed +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +/// The extensions for the [`ChainSpec`]. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] +#[serde(deny_unknown_fields)] +pub struct Extensions { + /// The relay chain of the Parachain. + pub relay_chain: String, + /// The id of the Parachain. + pub para_id: u32, +} + +impl Extensions { + /// Try to get the extension from the given `ChainSpec`. + pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> { + sc_chain_spec::get_extension(chain_spec.extensions()) + } +} + +type AccountPublic = ::Signer; + +/// Helper function to generate an account ID from seed +pub fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public>, +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +pub fn development_config(id: ParaId) -> ChainSpec { + // Give your base currency a unit name and decimal places + let mut properties = sc_chain_spec::Properties::new(); + properties.insert("tokenSymbol".into(), "UNIT".into()); + properties.insert("tokenDecimals".into(), 12.into()); + + ChainSpec::from_genesis( + // Name + "Development", + // ID + "dev", + ChainType::Local, + move || { + testnet_genesis( + get_account_id_from_seed::("Alice"), + vec![get_from_seed::("Alice"), get_from_seed::("Bob")], + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + ], + id, + ) + }, + vec![], + None, + None, + None, + Extensions { + relay_chain: "rococo-local".into(), // You MUST set this to the correct network! + para_id: id.into(), + }, + ) +} + +pub fn local_testnet_config(id: ParaId) -> ChainSpec { + // Give your base currency a unit name and decimal places + let mut properties = sc_chain_spec::Properties::new(); + properties.insert("tokenSymbol".into(), "UNIT".into()); + properties.insert("tokenDecimals".into(), 12.into()); + + ChainSpec::from_genesis( + // Name + "Local Testnet", + // ID + "local_testnet", + ChainType::Local, + move || { + testnet_genesis( + get_account_id_from_seed::("Alice"), + vec![get_from_seed::("Alice"), get_from_seed::("Bob")], + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + id, + ) + }, + Vec::new(), + None, + None, + None, + Extensions { + relay_chain: "rococo-local".into(), // You MUST set this to the correct network! + para_id: id.into(), + }, + ) +} + +fn testnet_genesis( + root_key: AccountId, + initial_authorities: Vec, + endowed_accounts: Vec, + id: ParaId, +) -> rialto_parachain_runtime::GenesisConfig { + rialto_parachain_runtime::GenesisConfig { + system: rialto_parachain_runtime::SystemConfig { + code: rialto_parachain_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + changes_trie_config: Default::default(), + }, + balances: rialto_parachain_runtime::BalancesConfig { + balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), + }, + sudo: rialto_parachain_runtime::SudoConfig { key: root_key }, + parachain_info: rialto_parachain_runtime::ParachainInfoConfig { parachain_id: id }, + aura: rialto_parachain_runtime::AuraConfig { + authorities: initial_authorities, + }, + aura_ext: Default::default(), + // parachain_system: Default::default(), + } +} diff --git a/bridges/bin/rialto-parachain/node/src/cli.rs b/bridges/bin/rialto-parachain/node/src/cli.rs new file mode 100644 index 0000000000..865d8eb92b --- /dev/null +++ b/bridges/bin/rialto-parachain/node/src/cli.rs @@ -0,0 +1,146 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use crate::chain_spec; +use cumulus_client_cli; +use sc_cli; +use std::path::PathBuf; +use structopt::StructOpt; + +/// Sub-commands supported by the collator. +#[derive(Debug, StructOpt)] +pub enum Subcommand { + /// Export the genesis state of the parachain. + #[structopt(name = "export-genesis-state")] + ExportGenesisState(ExportGenesisStateCommand), + + /// Export the genesis wasm of the parachain. + #[structopt(name = "export-genesis-wasm")] + ExportGenesisWasm(ExportGenesisWasmCommand), + + /// Build a chain specification. + BuildSpec(sc_cli::BuildSpecCmd), + + /// Validate blocks. + CheckBlock(sc_cli::CheckBlockCmd), + + /// Export blocks. + ExportBlocks(sc_cli::ExportBlocksCmd), + + /// Export the state of a given block into a chain spec. + ExportState(sc_cli::ExportStateCmd), + + /// Import blocks. + ImportBlocks(sc_cli::ImportBlocksCmd), + + /// Remove the whole chain. + PurgeChain(cumulus_client_cli::PurgeChainCmd), + + /// Revert the chain to a previous state. + Revert(sc_cli::RevertCmd), + + /// The custom benchmark subcommmand benchmarking runtime pallets. + #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")] + Benchmark(frame_benchmarking_cli::BenchmarkCmd), +} + +/// Command for exporting the genesis state of the parachain +#[derive(Debug, StructOpt)] +pub struct ExportGenesisStateCommand { + /// Output file name or stdout if unspecified. + #[structopt(parse(from_os_str))] + pub output: Option, + + /// Id of the parachain this state is for. + /// + /// Default: 100 + #[structopt(long, conflicts_with = "chain")] + pub parachain_id: Option, + + /// Write output in binary. Default is to write in hex. + #[structopt(short, long)] + pub raw: bool, + + /// The name of the chain for that the genesis state should be exported. + #[structopt(long, conflicts_with = "parachain-id")] + pub chain: Option, +} + +/// Command for exporting the genesis wasm file. +#[derive(Debug, StructOpt)] +pub struct ExportGenesisWasmCommand { + /// Output file name or stdout if unspecified. + #[structopt(parse(from_os_str))] + pub output: Option, + + /// Write output in binary. Default is to write in hex. + #[structopt(short, long)] + pub raw: bool, + + /// The name of the chain for that the genesis wasm file should be exported. + #[structopt(long)] + pub chain: Option, +} + +#[derive(Debug, StructOpt)] +#[structopt(settings = &[ + structopt::clap::AppSettings::GlobalVersion, + structopt::clap::AppSettings::ArgsNegateSubcommands, + structopt::clap::AppSettings::SubcommandsNegateReqs, +])] +pub struct Cli { + #[structopt(subcommand)] + pub subcommand: Option, + + #[structopt(flatten)] + pub run: cumulus_client_cli::RunCmd, + + /// Relaychain arguments + #[structopt(raw = true)] + pub relaychain_args: Vec, +} + +#[derive(Debug)] +pub struct RelayChainCli { + /// The actual relay chain cli object. + pub base: polkadot_cli::RunCmd, + + /// Optional chain id that should be passed to the relay chain. + pub chain_id: Option, + + /// The base path that should be used by the relay chain. + pub base_path: Option, +} + +impl RelayChainCli { + /// Parse the relay chain CLI parameters using the para chain `Configuration`. + pub fn new<'a>( + para_config: &sc_service::Configuration, + relay_chain_args: impl Iterator, + ) -> Self { + let extension = chain_spec::Extensions::try_get(&*para_config.chain_spec); + let chain_id = extension.map(|e| e.relay_chain.clone()); + let base_path = para_config + .base_path + .as_ref() + .map(|x| x.path().join("rialto-bridge-node")); + Self { + base_path, + chain_id, + base: polkadot_cli::RunCmd::from_iter(relay_chain_args), + } + } +} diff --git a/bridges/bin/rialto-parachain/node/src/command.rs b/bridges/bin/rialto-parachain/node/src/command.rs new file mode 100644 index 0000000000..a37673a5b9 --- /dev/null +++ b/bridges/bin/rialto-parachain/node/src/command.rs @@ -0,0 +1,414 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use crate::{ + chain_spec, + cli::{Cli, RelayChainCli, Subcommand}, + service::{new_partial, ParachainRuntimeExecutor}, +}; +use codec::Encode; +use cumulus_client_service::genesis::generate_genesis_block; +use cumulus_primitives_core::ParaId; +use log::info; +use polkadot_parachain::primitives::AccountIdConversion; +use rialto_parachain_runtime::{Block, RuntimeApi}; +use sc_cli::{ + ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams, Result, + RuntimeVersion, SharedParams, SubstrateCli, +}; +use sc_service::config::{BasePath, PrometheusConfig}; +use sp_core::hexdisplay::HexDisplay; +use sp_runtime::traits::Block as BlockT; +use std::{io::Write, net::SocketAddr}; + +fn load_spec(id: &str, para_id: ParaId) -> std::result::Result, String> { + Ok(match id { + "dev" => Box::new(chain_spec::development_config(para_id)), + "" | "local" => Box::new(chain_spec::local_testnet_config(para_id)), + path => Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?), + }) +} + +impl SubstrateCli for Cli { + fn impl_name() -> String { + "Parachain Collator Template".into() + } + + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() + } + + fn description() -> String { + format!( + "Parachain Collator Template\n\nThe command-line arguments provided first will be \ + passed to the parachain node, while the arguments provided after -- will be passed \ + to the relaychain node.\n\n\ + {} [parachain-args] -- [relaychain-args]", + Self::executable_name() + ) + } + + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } + + fn support_url() -> String { + "https://github.com/substrate-developer-hub/substrate-parachain-template/issues/new".into() + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn load_spec(&self, id: &str) -> std::result::Result, String> { + load_spec(id, self.run.parachain_id.unwrap_or(2000).into()) + } + + fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { + &rialto_parachain_runtime::VERSION + } +} + +impl SubstrateCli for RelayChainCli { + fn impl_name() -> String { + "Parachain Collator Template".into() + } + + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() + } + + fn description() -> String { + "Parachain Collator Template\n\nThe command-line arguments provided first will be \ + passed to the parachain node, while the arguments provided after -- will be passed \ + to the relaychain node.\n\n\ + parachain-collator [parachain-args] -- [relaychain-args]" + .into() + } + + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } + + fn support_url() -> String { + "https://github.com/substrate-developer-hub/substrate-parachain-template/issues/new".into() + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn load_spec(&self, id: &str) -> std::result::Result, String> { + polkadot_cli::Cli::from_iter([RelayChainCli::executable_name().to_string()].iter()).load_spec(id) + } + + fn native_runtime_version(chain_spec: &Box) -> &'static RuntimeVersion { + polkadot_cli::Cli::native_runtime_version(chain_spec) + } +} + +fn extract_genesis_wasm(chain_spec: &Box) -> Result> { + let mut storage = chain_spec.build_storage()?; + + storage + .top + .remove(sp_core::storage::well_known_keys::CODE) + .ok_or_else(|| "Could not find wasm file in genesis state!".into()) +} + +macro_rules! construct_async_run { + (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ + let runner = $cli.create_runner($cmd)?; + runner.async_run(|$config| { + let $components = new_partial::< + RuntimeApi, + ParachainRuntimeExecutor, + _ + >( + &$config, + crate::service::parachain_build_import_queue, + )?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }) + }} +} + +/// Parse command line arguments into service configuration. +pub fn run() -> Result<()> { + let cli = Cli::from_args(); + sp_core::crypto::set_default_ss58_version(sp_core::crypto::Ss58AddressFormat::Custom( + rialto_parachain_runtime::SS58Prefix::get() as u16, + )); + + match &cli.subcommand { + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) + } + Some(Subcommand::CheckBlock(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { + Ok(cmd.run(components.client, components.import_queue)) + }) + } + Some(Subcommand::ExportBlocks(cmd)) => { + construct_async_run!(|components, cli, cmd, config| Ok(cmd.run(components.client, config.database))) + } + Some(Subcommand::ExportState(cmd)) => { + construct_async_run!(|components, cli, cmd, config| Ok(cmd.run(components.client, config.chain_spec))) + } + Some(Subcommand::ImportBlocks(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { + Ok(cmd.run(components.client, components.import_queue)) + }) + } + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + + runner.sync_run(|config| { + let polkadot_cli = RelayChainCli::new( + &config, + [RelayChainCli::executable_name().to_string()] + .iter() + .chain(cli.relaychain_args.iter()), + ); + + let polkadot_config = + SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, config.tokio_handle.clone()) + .map_err(|err| format!("Relay chain argument error: {}", err))?; + + cmd.run(config, polkadot_config) + }) + } + Some(Subcommand::Revert(cmd)) => { + construct_async_run!(|components, cli, cmd, config| Ok(cmd.run(components.client, components.backend))) + } + Some(Subcommand::ExportGenesisState(params)) => { + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_profiling(sc_tracing::TracingReceiver::Log, ""); + let _ = builder.init(); + + let block: Block = generate_genesis_block(&load_spec( + ¶ms.chain.clone().unwrap_or_default(), + params.parachain_id.expect("Missing ParaId").into(), + )?)?; + let raw_header = block.header().encode(); + let output_buf = if params.raw { + raw_header + } else { + format!("0x{:?}", HexDisplay::from(&block.header().encode())).into_bytes() + }; + + if let Some(output) = ¶ms.output { + std::fs::write(output, output_buf)?; + } else { + std::io::stdout().write_all(&output_buf)?; + } + + Ok(()) + } + Some(Subcommand::ExportGenesisWasm(params)) => { + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_profiling(sc_tracing::TracingReceiver::Log, ""); + let _ = builder.init(); + + let raw_wasm_blob = extract_genesis_wasm(&cli.load_spec(¶ms.chain.clone().unwrap_or_default())?)?; + let output_buf = if params.raw { + raw_wasm_blob + } else { + format!("0x{:?}", HexDisplay::from(&raw_wasm_blob)).into_bytes() + }; + + if let Some(output) = ¶ms.output { + std::fs::write(output, output_buf)?; + } else { + std::io::stdout().write_all(&output_buf)?; + } + + Ok(()) + } + Some(Subcommand::Benchmark(cmd)) => { + if cfg!(feature = "runtime-benchmarks") { + let runner = cli.create_runner(cmd)?; + + runner.sync_run(|config| cmd.run::(config)) + } else { + Err("Benchmarking wasn't enabled when building the node. \ + You can enable it with `--features runtime-benchmarks`." + .into()) + } + } + None => { + let runner = cli.create_runner(&cli.run.normalize())?; + + runner.run_node_until_exit(|config| async move { + let para_id = chain_spec::Extensions::try_get(&*config.chain_spec).map(|e| e.para_id); + + let polkadot_cli = RelayChainCli::new( + &config, + [RelayChainCli::executable_name().to_string()] + .iter() + .chain(cli.relaychain_args.iter()), + ); + + let id = ParaId::from(cli.run.parachain_id.or(para_id).expect("Missing ParaId")); + + let parachain_account = AccountIdConversion::::into_account(&id); + + let block: Block = generate_genesis_block(&config.chain_spec).map_err(|e| format!("{:?}", e))?; + let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode())); + + let polkadot_config = + SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, config.tokio_handle.clone()) + .map_err(|err| format!("Relay chain argument error: {}", err))?; + + info!("Parachain id: {:?}", id); + info!("Parachain Account: {}", parachain_account); + info!("Parachain genesis state: {}", genesis_state); + info!( + "Is collating: {}", + if config.role.is_authority() { "yes" } else { "no" } + ); + + crate::service::start_node(config, polkadot_config, id) + .await + .map(|r| r.0) + .map_err(Into::into) + }) + } + } +} + +impl DefaultConfigurationValues for RelayChainCli { + fn p2p_listen_port() -> u16 { + 30334 + } + + fn rpc_ws_listen_port() -> u16 { + 9945 + } + + fn rpc_http_listen_port() -> u16 { + 9934 + } + + fn prometheus_listen_port() -> u16 { + 9616 + } +} + +impl CliConfiguration for RelayChainCli { + fn shared_params(&self) -> &SharedParams { + self.base.base.shared_params() + } + + fn import_params(&self) -> Option<&ImportParams> { + self.base.base.import_params() + } + + fn network_params(&self) -> Option<&NetworkParams> { + self.base.base.network_params() + } + + fn keystore_params(&self) -> Option<&KeystoreParams> { + self.base.base.keystore_params() + } + + fn base_path(&self) -> Result> { + Ok(self + .shared_params() + .base_path() + .or_else(|| self.base_path.clone().map(Into::into))) + } + + fn rpc_http(&self, default_listen_port: u16) -> Result> { + self.base.base.rpc_http(default_listen_port) + } + + fn rpc_ipc(&self) -> Result> { + self.base.base.rpc_ipc() + } + + fn rpc_ws(&self, default_listen_port: u16) -> Result> { + self.base.base.rpc_ws(default_listen_port) + } + + fn prometheus_config(&self, default_listen_port: u16) -> Result> { + self.base.base.prometheus_config(default_listen_port) + } + + fn init(&self) -> Result<()> { + unreachable!("PolkadotCli is never initialized; qed"); + } + + fn chain_id(&self, is_dev: bool) -> Result { + let chain_id = self.base.base.chain_id(is_dev)?; + + Ok(if chain_id.is_empty() { + self.chain_id.clone().unwrap_or_default() + } else { + chain_id + }) + } + + fn role(&self, is_dev: bool) -> Result { + self.base.base.role(is_dev) + } + + fn transaction_pool(&self) -> Result { + self.base.base.transaction_pool() + } + + fn state_cache_child_ratio(&self) -> Result> { + self.base.base.state_cache_child_ratio() + } + + fn rpc_methods(&self) -> Result { + self.base.base.rpc_methods() + } + + fn rpc_ws_max_connections(&self) -> Result> { + self.base.base.rpc_ws_max_connections() + } + + fn rpc_cors(&self, is_dev: bool) -> Result>> { + self.base.base.rpc_cors(is_dev) + } + + fn default_heap_pages(&self) -> Result> { + self.base.base.default_heap_pages() + } + + fn force_authoring(&self) -> Result { + self.base.base.force_authoring() + } + + fn disable_grandpa(&self) -> Result { + self.base.base.disable_grandpa() + } + + fn max_runtime_instances(&self) -> Result> { + self.base.base.max_runtime_instances() + } + + fn announce_block(&self) -> Result { + self.base.base.announce_block() + } + + fn telemetry_endpoints(&self, chain_spec: &Box) -> Result> { + self.base.base.telemetry_endpoints(chain_spec) + } +} diff --git a/bridges/bin/rialto-parachain/node/src/lib.rs b/bridges/bin/rialto-parachain/node/src/lib.rs new file mode 100644 index 0000000000..3ec291596b --- /dev/null +++ b/bridges/bin/rialto-parachain/node/src/lib.rs @@ -0,0 +1,18 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +pub mod chain_spec; +pub mod service; diff --git a/bridges/bin/rialto-parachain/node/src/main.rs b/bridges/bin/rialto-parachain/node/src/main.rs new file mode 100644 index 0000000000..2b4e0b438d --- /dev/null +++ b/bridges/bin/rialto-parachain/node/src/main.rs @@ -0,0 +1,29 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +//! Substrate Parachain Node Template CLI + +#![warn(missing_docs)] + +mod chain_spec; +#[macro_use] +mod service; +mod cli; +mod command; + +fn main() -> sc_cli::Result<()> { + command::run() +} diff --git a/bridges/bin/rialto-parachain/node/src/service.rs b/bridges/bin/rialto-parachain/node/src/service.rs new file mode 100644 index 0000000000..a812358edf --- /dev/null +++ b/bridges/bin/rialto-parachain/node/src/service.rs @@ -0,0 +1,461 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +// std +use std::sync::Arc; + +// Local Runtime Types +use rialto_parachain_runtime::RuntimeApi; + +// Cumulus Imports +use cumulus_client_consensus_aura::{build_aura_consensus, BuildAuraConsensusParams, SlotProportion}; +use cumulus_client_consensus_common::ParachainConsensus; +use cumulus_client_network::build_block_announce_validator; +use cumulus_client_service::{ + prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams, +}; +use cumulus_primitives_core::ParaId; + +// Substrate Imports +use sc_client_api::ExecutorProvider; +use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch}; +use sc_network::NetworkService; +use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager}; +use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; +use sp_api::ConstructRuntimeApi; +use sp_consensus::SlotData; +use sp_keystore::SyncCryptoStorePtr; +use sp_runtime::traits::BlakeTwo256; +use substrate_prometheus_endpoint::Registry; + +// Runtime type overrides +type BlockNumber = u32; +type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +type Hash = sp_core::H256; + +pub type ParachainRuntimeExecutor = ExecutorDispatch; + +// Our native executor instance. +pub struct ExecutorDispatch; + +impl NativeExecutionDispatch for ExecutorDispatch { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + + fn dispatch(method: &str, data: &[u8]) -> Option> { + rialto_parachain_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + rialto_parachain_runtime::native_version() + } +} + +/// Starts a `ServiceBuilder` for a full service. +/// +/// Use this macro if you don't actually need the full service, but just the builder in order to +/// be able to perform chain operations. +pub fn new_partial( + config: &Configuration, + build_import_queue: BIQ, +) -> Result< + PartialComponents< + TFullClient>, + TFullBackend, + (), + sc_consensus::DefaultImportQueue>>, + sc_transaction_pool::FullPool>>, + (Option, Option), + >, + sc_service::Error, +> +where + RuntimeApi: ConstructRuntimeApi>> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt, Block>> + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder, + sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, + Executor: NativeExecutionDispatch + 'static, + BIQ: FnOnce( + Arc>>, + &Configuration, + Option, + &TaskManager, + ) -> Result< + sc_consensus::DefaultImportQueue>>, + sc_service::Error, + >, +{ + let telemetry = config + .telemetry_endpoints + .clone() + .filter(|x| !x.is_empty()) + .map(|endpoints| -> Result<_, sc_telemetry::Error> { + let worker = TelemetryWorker::new(16)?; + let telemetry = worker.handle().new_telemetry(endpoints); + Ok((worker, telemetry)) + }) + .transpose()?; + + let executor = sc_executor::NativeElseWasmExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + ); + + let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::( + &config, + telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, + )?; + let client = Arc::new(client); + + let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle()); + + let telemetry = telemetry.map(|(worker, telemetry)| { + task_manager.spawn_handle().spawn("telemetry", worker.run()); + telemetry + }); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.role.is_authority().into(), + config.prometheus_registry(), + task_manager.spawn_essential_handle(), + client.clone(), + ); + + let import_queue = build_import_queue( + client.clone(), + config, + telemetry.as_ref().map(|telemetry| telemetry.handle()), + &task_manager, + )?; + + let params = PartialComponents { + backend, + client, + import_queue, + keystore_container, + task_manager, + transaction_pool, + select_chain: (), + other: (telemetry, telemetry_worker_handle), + }; + + Ok(params) +} + +/// Start a node with the given parachain `Configuration` and relay chain `Configuration`. +/// +/// This is the actual implementation that is abstract over the executor and the runtime api. +#[sc_tracing::logging::prefix_logs_with("Parachain")] +async fn start_node_impl( + parachain_config: Configuration, + polkadot_config: Configuration, + id: ParaId, + rpc_ext_builder: RB, + build_import_queue: BIQ, + build_consensus: BIC, +) -> sc_service::error::Result<( + TaskManager, + Arc>>, +)> +where + RuntimeApi: ConstructRuntimeApi>> + + Send + + Sync + + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt, Block>> + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder + + cumulus_primitives_core::CollectCollationInfo, + sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, + Executor: NativeExecutionDispatch + 'static, + RB: Fn( + Arc>>, + ) -> jsonrpc_core::IoHandler + + Send + + 'static, + BIQ: FnOnce( + Arc>>, + &Configuration, + Option, + &TaskManager, + ) -> Result< + sc_consensus::DefaultImportQueue>>, + sc_service::Error, + >, + BIC: FnOnce( + Arc>>, + Option<&Registry>, + Option, + &TaskManager, + &polkadot_service::NewFull, + Arc>>>, + Arc>, + SyncCryptoStorePtr, + bool, + ) -> Result>, sc_service::Error>, +{ + if matches!(parachain_config.role, Role::Light) { + return Err("Light client not supported!".into()); + } + + let parachain_config = prepare_node_config(parachain_config); + + let params = new_partial::(¶chain_config, build_import_queue)?; + let (mut telemetry, telemetry_worker_handle) = params.other; + + let relay_chain_full_node = + cumulus_client_service::build_polkadot_full_node(polkadot_config, telemetry_worker_handle).map_err( + |e| match e { + polkadot_service::Error::Sub(x) => x, + s => format!("{}", s).into(), + }, + )?; + + let client = params.client.clone(); + let backend = params.backend.clone(); + let block_announce_validator = build_block_announce_validator( + relay_chain_full_node.client.clone(), + id, + Box::new(relay_chain_full_node.network.clone()), + relay_chain_full_node.backend.clone(), + ); + + let force_authoring = parachain_config.force_authoring; + let validator = parachain_config.role.is_authority(); + let prometheus_registry = parachain_config.prometheus_registry().cloned(); + let transaction_pool = params.transaction_pool.clone(); + let mut task_manager = params.task_manager; + let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue); + let (network, system_rpc_tx, start_network) = sc_service::build_network(sc_service::BuildNetworkParams { + config: ¶chain_config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue: import_queue.clone(), + on_demand: None, + block_announce_validator_builder: Some(Box::new(|_| block_announce_validator)), + warp_sync: None, + })?; + + let rpc_client = client.clone(); + let rpc_extensions_builder = Box::new(move |_, _| Ok(rpc_ext_builder(rpc_client.clone()))); + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + on_demand: None, + remote_blockchain: None, + rpc_extensions_builder, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + task_manager: &mut task_manager, + config: parachain_config, + keystore: params.keystore_container.sync_keystore(), + backend: backend.clone(), + network: network.clone(), + system_rpc_tx, + telemetry: telemetry.as_mut(), + })?; + + let announce_block = { + let network = network.clone(); + Arc::new(move |hash, data| network.announce_block(hash, data)) + }; + + if validator { + let parachain_consensus = build_consensus( + client.clone(), + prometheus_registry.as_ref(), + telemetry.as_ref().map(|t| t.handle()), + &task_manager, + &relay_chain_full_node, + transaction_pool, + network, + params.keystore_container.sync_keystore(), + force_authoring, + )?; + + let spawner = task_manager.spawn_handle(); + + let params = StartCollatorParams { + para_id: id, + block_status: client.clone(), + announce_block, + client: client.clone(), + task_manager: &mut task_manager, + relay_chain_full_node, + spawner, + parachain_consensus, + import_queue, + }; + + start_collator(params).await?; + } else { + let params = StartFullNodeParams { + client: client.clone(), + announce_block, + task_manager: &mut task_manager, + para_id: id, + relay_chain_full_node, + }; + + start_full_node(params)?; + } + + start_network.start_network(); + + Ok((task_manager, client)) +} + +/// Build the import queue for the the parachain runtime. +pub fn parachain_build_import_queue( + client: Arc>>, + config: &Configuration, + telemetry: Option, + task_manager: &TaskManager, +) -> Result< + sc_consensus::DefaultImportQueue< + Block, + TFullClient>, + >, + sc_service::Error, +> { + let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + + cumulus_client_consensus_aura::import_queue::( + cumulus_client_consensus_aura::ImportQueueParams { + block_import: client.clone(), + client: client.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)) + }, + registry: config.prometheus_registry().clone(), + can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), + spawner: &task_manager.spawn_essential_handle(), + telemetry, + }, + ) + .map_err(Into::into) +} + +/// Start a normal parachain node. +pub async fn start_node( + parachain_config: Configuration, + polkadot_config: Configuration, + id: ParaId, +) -> sc_service::error::Result<( + TaskManager, + Arc>>, +)> { + start_node_impl::( + parachain_config, + polkadot_config, + id, + |_| Default::default(), + parachain_build_import_queue, + |client, + prometheus_registry, + telemetry, + task_manager, + relay_chain_node, + transaction_pool, + sync_oracle, + keystore, + force_authoring| { + let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry.clone(), + telemetry.clone(), + ); + + let relay_chain_backend = relay_chain_node.backend.clone(); + let relay_chain_client = relay_chain_node.client.clone(); + Ok(build_aura_consensus::< + sp_consensus_aura::sr25519::AuthorityPair, + _, + _, + _, + _, + _, + _, + _, + _, + _, + >(BuildAuraConsensusParams { + proposer_factory, + create_inherent_data_providers: move |_, (relay_parent, validation_data)| { + let parachain_inherent = + cumulus_primitives_parachain_inherent::ParachainInherentData::create_at_with_client( + relay_parent, + &relay_chain_client, + &*relay_chain_backend, + &validation_data, + id, + ); + 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(), + ); + + let parachain_inherent = parachain_inherent.ok_or_else(|| { + Box::::from("Failed to create parachain inherent") + })?; + Ok((time, slot, parachain_inherent)) + } + }, + block_import: client.clone(), + relay_chain_client: relay_chain_node.client.clone(), + relay_chain_backend: relay_chain_node.backend.clone(), + para_client: client.clone(), + backoff_authoring_blocks: Option::<()>::None, + sync_oracle, + keystore, + force_authoring, + slot_duration, + // We got around 500ms for proposing + block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32), + telemetry, + max_block_proposal_slot_portion: None, + })) + }, + ) + .await +} diff --git a/bridges/bin/rialto-parachain/runtime/Cargo.toml b/bridges/bin/rialto-parachain/runtime/Cargo.toml new file mode 100644 index 0000000000..09916f508b --- /dev/null +++ b/bridges/bin/rialto-parachain/runtime/Cargo.toml @@ -0,0 +1,115 @@ +[package] +name = "rialto-parachain-runtime" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/parity-bridges-common/" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dependencies] +codec = { package = 'parity-scale-codec', version = '2.0.0', default-features = false, features = ['derive']} +log = { version = "0.4.14", default-features = false } +serde = { version = '1.0', optional = true, features = ['derive'] } + +# Substrate Dependencies +## Substrate Primitive Dependencies +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-block-builder = { 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-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-offchain = { 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-session = { 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-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +## Substrate FRAME Dependencies +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +## Substrate Pallet Dependencies +pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +# Cumulus Dependencies +cumulus-pallet-aura-ext = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-primitives-timestamp = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +cumulus-primitives-utility = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } +parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "master", default-features = false } + +# Polkadot Dependencies +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } +xcm = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } +xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } +xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } + +[features] +default = ['std'] +runtime-benchmarks = [ + 'sp-runtime/runtime-benchmarks', + 'frame-benchmarking', + 'frame-support/runtime-benchmarks', + 'frame-system-benchmarking', + 'frame-system/runtime-benchmarks', + 'pallet-balances/runtime-benchmarks', + 'pallet-timestamp/runtime-benchmarks', +] +std = [ + "codec/std", + "serde", + "log/std", + "sp-api/std", + "sp-std/std", + "sp-io/std", + "sp-core/std", + "sp-runtime/std", + "sp-version/std", + "sp-offchain/std", + "sp-session/std", + "sp-block-builder/std", + "sp-transaction-pool/std", + "sp-inherents/std", + "frame-support/std", + "frame-executive/std", + "frame-system/std", + "pallet-balances/std", + "pallet-randomness-collective-flip/std", + "pallet-timestamp/std", + "pallet-sudo/std", + "pallet-transaction-payment/std", + "parachain-info/std", + "cumulus-pallet-aura-ext/std", + "cumulus-pallet-parachain-system/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-pallet-xcm/std", + "cumulus-primitives-core/std", + "cumulus-primitives-timestamp/std", + "cumulus-primitives-utility/std", + "xcm/std", + "xcm-builder/std", + "xcm-executor/std", + "pallet-aura/std", + "sp-consensus-aura/std", +] diff --git a/bridges/bin/rialto-parachain/runtime/build.rs b/bridges/bin/rialto-parachain/runtime/build.rs new file mode 100644 index 0000000000..65095bd1b7 --- /dev/null +++ b/bridges/bin/rialto-parachain/runtime/build.rs @@ -0,0 +1,25 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .build() +} diff --git a/bridges/bin/rialto-parachain/runtime/src/lib.rs b/bridges/bin/rialto-parachain/runtime/src/lib.rs new file mode 100644 index 0000000000..58f592bea8 --- /dev/null +++ b/bridges/bin/rialto-parachain/runtime/src/lib.rs @@ -0,0 +1,682 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +//! The Rialto parachain runtime. This can be compiled with `#[no_std]`, ready for Wasm. +//! +//! Originally a copypaste of runtime from https://github.com/substrate-developer-hub/substrate-parachain-template. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use sp_api::impl_runtime_apis; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, MultiSignature, +}; + +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; + +// A few exports that help ease life for downstream crates. +pub use frame_support::{ + construct_runtime, match_type, parameter_types, + traits::{Everything, IsInVec, Randomness}, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + DispatchClass, IdentityFee, Weight, + }, + StorageValue, +}; +use frame_system::limits::{BlockLength, BlockWeights}; +pub use pallet_balances::Call as BalancesCall; +pub use pallet_timestamp::Call as TimestampCall; +pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; +pub use sp_runtime::{MultiAddress, Perbill, Permill}; + +// Polkadot & XCM imports +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin, + FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, ParentAsSuperuser, ParentIsDefault, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, +}; +use xcm_executor::{Config, XcmExecutor}; + +// /// Import the template pallet. +// pub use template; + +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = MultiSignature; +/// Some way of identifying an account on the chain. We intentionally make it equivalent +/// to the public key of our transaction signing scheme. +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; +/// Balance of an account. +pub type Balance = u128; +/// Index of a transaction in the chain. +pub type Index = u32; +/// A hash of some data used by the chain. +pub type Hash = sp_core::H256; +/// An index to a block. +pub type BlockNumber = u32; +/// The address format for describing accounts. +pub type Address = MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// BlockId type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckSpecVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = generic::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = + frame_executive::Executive, Runtime, AllPallets>; + +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } +} + +/// This runtime version. +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("template-parachain"), + impl_name: create_runtime_str!("template-parachain"), + authoring_version: 1, + spec_version: 1, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, +}; + +/// This determines the average expected block time that we are targeting. +/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. +/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked +/// up by `pallet_aura` to implement `fn slot_duration()`. +/// +/// Change this to adjust the block time. +pub const MILLISECS_PER_BLOCK: u64 = 12000; + +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; + +// Time is measured by number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +// Unit = the base number of indivisible units for balances +pub const UNIT: Balance = 1_000_000_000_000; +pub const MILLIUNIT: Balance = 1_000_000_000; +pub const MICROUNIT: Balance = 1_000_000; + +// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. +pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); + +/// The version information used to identify this runtime when compiled natively. +#[cfg(feature = "std")] +pub fn native_version() -> NativeVersion { + NativeVersion { + runtime_version: VERSION, + can_author_with: Default::default(), + } +} + +/// We assume that approximately 10 percent of the block weight is consumed by `on_initalize` handlers. +/// This is used to limit the maximal weight of a single extrinsic. +const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); +/// We allow `Normal` extrinsics to fill up the block up to 75 percent, the rest can be used +/// by Operational extrinsics. +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// We allow for 2 seconds of compute with a 12 second average block time. +const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND * 2; + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; + pub const Version: RuntimeVersion = VERSION; + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + pub const SS58Prefix: u8 = 48; +} + +// Configure FRAME pallets to include in runtime. + +impl frame_system::Config for Runtime { + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = AccountIdLookup; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = generic::Header; + /// The ubiquitous event type. + type Event = Event; + /// The ubiquitous origin type. + type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// Runtime version. + type Version = Version; + /// Converts a module to an index of this module in the runtime. + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// The weight of database operations that the runtime can invoke. + type DbWeight = (); + /// The basic call filter to use in dispatchable. + type BaseCallFilter = Everything; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = (); + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// The action to take on a Runtime Upgrade + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} + +impl pallet_timestamp::Config for Runtime { + /// A timestamp: milliseconds since the Unix epoch. + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 1 * MILLIUNIT; + pub const TransferFee: u128 = 1 * MILLIUNIT; + pub const CreationFee: u128 = 1 * MILLIUNIT; + pub const TransactionByteFee: u128 = 1 * MICROUNIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; +} + +impl pallet_transaction_payment::Config for Runtime { + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = IdentityFee; + type FeeMultiplierUpdate = (); +} + +impl pallet_sudo::Config for Runtime { + type Call = Call; + type Event = Event; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type Event = Event; + type OnValidationData = (); + type SelfParaId = parachain_info::Pallet; + type OutboundXcmpMessageSource = XcmpQueue; + type DmpMessageHandler = DmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type XcmpMessageHandler = XcmpQueue; + type ReservedXcmpWeight = ReservedXcmpWeight; +} + +impl parachain_info::Config for Runtime {} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +impl pallet_randomness_collective_flip::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Polkadot; + pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); +} + +/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// when determining ownership of accounts for asset transacting and when attempting to use XCM +/// `Transact` in order to determine the dispatch Origin. +pub type LocationToAccountId = ( + // The parent (Relay-chain) origin converts to the default `AccountId`. + ParentIsDefault, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +/// Means for transacting assets on this chain. +pub type LocalAssetTransactor = CurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We don't track any teleports. + (), +>; + +/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, +/// ready for dispatching a transaction with XCM `Transact`. There is an `OriginKind` which can +/// biases the kind of local `Origin` it will become. +pub type XcmOriginToTransactDispatchOrigin = ( + // Sovereign account converter; this attempts to derive an `AccountId` from the origin location + // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for + // foreign chains who want to have a local sovereign account on this chain which they control. + SovereignSignedViaLocation, + // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when + // recognised. + RelayChainAsNative, + // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when + // recognised. + SiblingParachainAsNative, + // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a + // transaction from the Root origin. + ParentAsSuperuser, + // Native signed account converter; this just converts an `AccountId32` origin into a normal + // `Origin::Signed` origin of the same 32-byte value. + SignedAccountId32AsNative, + // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. + XcmPassthrough, +); + +parameter_types! { + // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate. + pub UnitWeightCost: Weight = 1_000_000; + // One UNIT buys 1 second of weight. + pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), UNIT); + pub const MaxInstructions: u32 = 100; + pub const MaxAuthorities: u32 = 100_000; +} + +match_type! { + pub type ParentOrParentsUnitPlurality: impl Contains = { + MultiLocation { parents: 1, interior: Here } | + MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } + }; +} + +pub type Barrier = ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + AllowUnpaidExecutionFrom, + // ^^^ Parent & its unit plurality gets free execution +); + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + // How to withdraw and deposit an asset. + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of UNIT + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = UsingComponents, RelayLocation, AccountId, Balances, ()>; + type ResponseHandler = PolkadotXcm; + type AssetTrap = PolkadotXcm; + type AssetClaims = PolkadotXcm; + type SubscriptionService = PolkadotXcm; +} + +/// No local origins on this chain are allowed to dispatch XCM sends/executions. +pub type LocalOriginToLocation = SignedToAccountId32; + +/// The means for routing XCM messages which are not for local execution into the right message +/// queues. +pub type XcmRouter = ( + // Two routers - use UMP to communicate with the relay chain: + cumulus_primitives_utility::ParentAsUmp, + // ..and XCMP to communicate with the sibling chains. + XcmpQueue, +); + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Everything; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type Origin = Origin; + type Call = Call; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ParachainSystem; + type VersionWrapper = (); +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; +} + +impl pallet_aura::Config for Runtime { + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; +} + +// /// Configure the pallet template in pallets/template. +// impl template::Config for Runtime { +// type Event = Event; +// } + +// Create the runtime by composing the FRAME pallets that were previously configured. +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = generic::Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event} = 20, + ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, + + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, + + Aura: pallet_aura::{Pallet, Config}, + AuraExt: cumulus_pallet_aura_ext::{Pallet, Config}, + + // XCM helpers. + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin} = 51, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 53, + + // //Template + // TemplatePallet: template::{Pallet, Call, Storage, Event}, + } +); + +impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic( + extrinsic: ::Extrinsic, + ) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + } + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + Aura::authorities().to_vec() + } + } + + impl cumulus_primitives_core::CollectCollationInfo for Runtime { + fn collect_collation_info() -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info() + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + + use frame_system_benchmarking::Pallet as SystemBench; + impl frame_system_benchmarking::Config for Runtime {} + + let whitelist: Vec = vec![ + // Block Number + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), + // Total Issuance + hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), + // Execution Phase + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), + // Event Count + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), + // System Events + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), + ]; + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmark!(params, batches, frame_system, SystemBench::); + add_benchmark!(params, batches, pallet_balances, Balances); + add_benchmark!(params, batches, pallet_timestamp, Timestamp); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } +} + +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + block: &Block, + relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + let relay_chain_slot = relay_state_proof + .read_slot() + .expect("Could not read the relay chain slot from the proof"); + + let inherent_data = cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration( + relay_chain_slot, + sp_std::time::Duration::from_secs(6), + ) + .create_inherent_data() + .expect("Could not create the timestamp inherent data"); + + inherent_data.check_extrinsics(&block) + } +} + +cumulus_pallet_parachain_system::register_validate_block!( + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, + CheckInherents = CheckInherents, +); diff --git a/bridges/bin/rialto/node/Cargo.toml b/bridges/bin/rialto/node/Cargo.toml index 833cea604d..08c72ce676 100644 --- a/bridges/bin/rialto/node/Cargo.toml +++ b/bridges/bin/rialto/node/Cargo.toml @@ -11,7 +11,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] futures = "0.3" -jsonrpc-core = "15.1.0" +jsonrpc-core = "18.0" kvdb = "0.10" kvdb-rocksdb = "0.12" structopt = "0.3.21" @@ -44,7 +44,7 @@ sc-consensus-uncles = { git = "https://github.com/paritytech/substrate", branch sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-finality-grandpa-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } -sc-finality-grandpa-warp-sync = { git = "https://github.com/paritytech/substrate", branch = "master" } +#sc-finality-grandpa-warp-sync = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } @@ -76,6 +76,7 @@ polkadot-availability-bitfield-distribution = { git = "https://github.com/parity polkadot-availability-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-availability-recovery = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-collator-protocol = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-dispute-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-gossip-support = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-network-bridge = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-collation-generation = { git = "https://github.com/paritytech/polkadot", branch = "master" } @@ -85,10 +86,14 @@ polkadot-node-core-backing = { git = "https://github.com/paritytech/polkadot", b polkadot-node-core-bitfield-signing = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-core-candidate-validation = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-core-chain-api = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-node-core-chain-selection = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-node-core-dispute-participation = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-core-parachains-inherent = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-core-provisioner = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-core-pvf = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-core-runtime-api = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-node-core-dispute-coordinator = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-node-network-protocol = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-node-subsystem-util = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } diff --git a/bridges/bin/rialto/node/src/chain_spec.rs b/bridges/bin/rialto/node/src/chain_spec.rs index be631109fa..68a2928ed2 100644 --- a/bridges/bin/rialto/node/src/chain_spec.rs +++ b/bridges/bin/rialto/node/src/chain_spec.rs @@ -18,8 +18,8 @@ use bp_rialto::derive_account_from_millau_id; use polkadot_primitives::v1::{AssignmentId, ValidatorId}; use rialto_runtime::{ AccountId, BabeConfig, BalancesConfig, BridgeKovanConfig, BridgeMillauMessagesConfig, BridgeRialtoPoaConfig, - GenesisConfig, GrandpaConfig, ParachainsConfigurationConfig, SessionConfig, SessionKeys, Signature, SudoConfig, - SystemConfig, WASM_BINARY, + ConfigurationConfig, GenesisConfig, GrandpaConfig, SessionConfig, SessionKeys, Signature, SudoConfig, SystemConfig, + WASM_BINARY, }; use serde_json::json; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; @@ -251,7 +251,7 @@ fn testnet_genesis( hrmp: Default::default(), // this configuration is exact copy of configuration from Polkadot repo // (see /node/service/src/chain_spec.rs:default_parachains_host_configuration) - parachains_configuration: ParachainsConfigurationConfig { + configuration: ConfigurationConfig { config: polkadot_runtime_parachains::configuration::HostConfiguration { validation_upgrade_frequency: 1u32, validation_upgrade_delay: 1, @@ -273,7 +273,7 @@ fn testnet_genesis( ump_service_total_weight: 4 * 1_000_000_000, max_upward_message_size: 1024 * 1024, max_upward_message_num_per_candidate: 5, - hrmp_open_request_ttl: 5, + _hrmp_open_request_ttl: 5, hrmp_sender_deposit: 0, hrmp_recipient_deposit: 0, hrmp_channel_max_capacity: 8, diff --git a/bridges/bin/rialto/node/src/command.rs b/bridges/bin/rialto/node/src/command.rs index 4fe40251e6..308cb10344 100644 --- a/bridges/bin/rialto/node/src/command.rs +++ b/bridges/bin/rialto/node/src/command.rs @@ -77,7 +77,7 @@ pub fn run() -> sc_cli::Result<()> { if cfg!(feature = "runtime-benchmarks") { let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run::(config)) + runner.sync_run(|config| cmd.run::(config)) } else { println!( "Benchmarking wasn't enabled when building the node. \ @@ -154,7 +154,7 @@ pub fn run() -> sc_cli::Result<()> { } Some(Subcommand::Inspect(cmd)) => { let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run::(config)) + runner.sync_run(|config| cmd.run::(config)) } Some(Subcommand::PvfPrepareWorker(cmd)) => { let mut builder = sc_cli::LoggerBuilder::new(""); diff --git a/bridges/bin/rialto/node/src/overseer.rs b/bridges/bin/rialto/node/src/overseer.rs index f7aaef4b5d..ff82db8b0e 100644 --- a/bridges/bin/rialto/node/src/overseer.rs +++ b/bridges/bin/rialto/node/src/overseer.rs @@ -20,19 +20,22 @@ // this warning comes from `polkadot_overseer::AllSubsystems` type #![allow(clippy::type_complexity)] -use crate::service::Error; +use crate::service::{AuthorityDiscoveryApi, Error}; +use rialto_runtime::{opaque::Block, Hash}; -use polkadot_network_bridge::RequestMultiplexer; +use polkadot_availability_distribution::IncomingRequestReceivers; use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig; use polkadot_node_core_av_store::Config as AvailabilityConfig; use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig; -use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandler}; -use polkadot_primitives::v1::{Block, Hash, ParachainHost}; +use polkadot_node_core_chain_selection::Config as ChainSelectionConfig; +use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig; +use polkadot_node_network_protocol::request_response::{v1 as request_v1, IncomingRequestReceiver}; +use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandle}; +use polkadot_primitives::v1::ParachainHost; use sc_authority_discovery::Service as AuthorityDiscoveryService; use sc_client_api::AuxStore; use sc_keystore::LocalKeystore; use sp_api::ProvideRuntimeApi; -use sp_authority_discovery::AuthorityDiscoveryApi; use sp_blockchain::HeaderBackend; use sp_consensus_babe::BabeApi; use sp_core::traits::SpawnNamed; @@ -44,6 +47,7 @@ pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as Bit pub use polkadot_availability_distribution::AvailabilityDistributionSubsystem; pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem; pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide}; +pub use polkadot_dispute_distribution::DisputeDistributionSubsystem; pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem; pub use polkadot_network_bridge::NetworkBridge as NetworkBridgeSubsystem; pub use polkadot_node_collation_generation::CollationGenerationSubsystem; @@ -53,6 +57,9 @@ pub use polkadot_node_core_backing::CandidateBackingSubsystem; pub use polkadot_node_core_bitfield_signing::BitfieldSigningSubsystem; pub use polkadot_node_core_candidate_validation::CandidateValidationSubsystem; pub use polkadot_node_core_chain_api::ChainApiSubsystem; +pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem; +pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem; +pub use polkadot_node_core_dispute_participation::DisputeParticipationSubsystem; pub use polkadot_node_core_provisioner::ProvisioningSubsystem as ProvisionerSubsystem; pub use polkadot_node_core_runtime_api::RuntimeApiSubsystem; pub use polkadot_statement_distribution::StatementDistribution as StatementDistributionSubsystem; @@ -72,43 +79,58 @@ where pub runtime_client: Arc, /// The underlying key value store for the parachains. pub parachains_db: Arc, - /// Configuration for the availability store subsystem. - pub availability_config: AvailabilityConfig, - /// Configuration for the approval voting subsystem. - pub approval_voting_config: ApprovalVotingConfig, /// Underlying network service implementation. pub network_service: Arc>, /// Underlying authority discovery service. pub authority_discovery_service: AuthorityDiscoveryService, - /// A multiplexer to arbitrate incoming `IncomingRequest`s from the network. - pub request_multiplexer: RequestMultiplexer, + /// POV request receiver + pub pov_req_receiver: IncomingRequestReceiver, + pub chunk_req_receiver: IncomingRequestReceiver, + pub collation_req_receiver: IncomingRequestReceiver, + pub available_data_req_receiver: IncomingRequestReceiver, + pub statement_req_receiver: IncomingRequestReceiver, + pub dispute_req_receiver: IncomingRequestReceiver, /// Prometheus registry, commonly used for production systems, less so for test. pub registry: Option<&'a Registry>, /// Task spawner to be used throughout the overseer and the APIs it provides. pub spawner: Spawner, + /// Configuration for the approval voting subsystem. + pub approval_voting_config: ApprovalVotingConfig, + /// Configuration for the availability store subsystem. + pub availability_config: AvailabilityConfig, /// Configuration for the candidate validation subsystem. pub candidate_validation_config: CandidateValidationConfig, + /// Configuration for the chain selection subsystem. + pub chain_selection_config: ChainSelectionConfig, + /// Configuration for the dispute coordinator subsystem. + pub dispute_coordinator_config: DisputeCoordinatorConfig, } /// Create a default, unaltered set of subsystems. /// /// A convenience for usage with malus, to avoid /// repetitive code across multiple behavior strain implementations. -pub fn create_default_subsystems( +pub fn create_default_subsystems<'a, Spawner, RuntimeClient>( OverseerGenArgs { keystore, runtime_client, parachains_db, - availability_config, - approval_voting_config, network_service, authority_discovery_service, - request_multiplexer, + pov_req_receiver, + chunk_req_receiver, + available_data_req_receiver, + statement_req_receiver, + dispute_req_receiver, registry, spawner, + approval_voting_config, + availability_config, candidate_validation_config, + chain_selection_config, + dispute_coordinator_config, .. - }: OverseerGenArgs, + }: OverseerGenArgs<'a, Spawner, RuntimeClient>, ) -> Result< AllSubsystems< CandidateValidationSubsystem, @@ -128,6 +150,10 @@ pub fn create_default_subsystems( ApprovalDistributionSubsystem, ApprovalVotingSubsystem, GossipSupportSubsystem, + DisputeCoordinatorSubsystem, + DisputeParticipationSubsystem, + DisputeDistributionSubsystem, + ChainSelectionSubsystem, >, Error, > @@ -141,9 +167,16 @@ where let all_subsystems = AllSubsystems { availability_distribution: AvailabilityDistributionSubsystem::new( keystore.clone(), + IncomingRequestReceivers { + pov_req_receiver, + chunk_req_receiver, + }, + Metrics::register(registry)?, + ), + availability_recovery: AvailabilityRecoverySubsystem::with_chunks_only( + available_data_req_receiver, Metrics::register(registry)?, ), - availability_recovery: AvailabilityRecoverySubsystem::with_chunks_only(), availability_store: AvailabilityStoreSubsystem::new( parachains_db.clone(), availability_config, @@ -162,37 +195,51 @@ where ), candidate_validation: CandidateValidationSubsystem::with_config( candidate_validation_config, - Metrics::register(registry)?, + Metrics::register(registry)?, // candidate-validation metrics + Metrics::register(registry)?, // validation host metrics ), chain_api: ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?), collation_generation: CollationGenerationSubsystem::new(Metrics::register(registry)?), - collator_protocol: { - let side = ProtocolSide::Validator { - keystore: keystore.clone(), - eviction_policy: Default::default(), - metrics: Metrics::register(registry)?, - }; - CollatorProtocolSubsystem::new(side) - }, + collator_protocol: CollatorProtocolSubsystem::new(ProtocolSide::Validator { + keystore: keystore.clone(), + eviction_policy: Default::default(), + metrics: Metrics::register(registry)?, + }), network_bridge: NetworkBridgeSubsystem::new( network_service.clone(), - authority_discovery_service, - request_multiplexer, + authority_discovery_service.clone(), Box::new(network_service.clone()), Metrics::register(registry)?, ), provisioner: ProvisionerSubsystem::new(spawner.clone(), (), Metrics::register(registry)?), - runtime_api: RuntimeApiSubsystem::new(runtime_client, Metrics::register(registry)?, spawner), - statement_distribution: StatementDistributionSubsystem::new(keystore.clone(), Metrics::register(registry)?), + runtime_api: RuntimeApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?, spawner.clone()), + statement_distribution: StatementDistributionSubsystem::new( + keystore.clone(), + statement_req_receiver, + Metrics::register(registry)?, + ), approval_distribution: ApprovalDistributionSubsystem::new(Metrics::register(registry)?), approval_voting: ApprovalVotingSubsystem::with_config( approval_voting_config, - parachains_db, + parachains_db.clone(), keystore.clone(), - Box::new(network_service), + Box::new(network_service.clone()), Metrics::register(registry)?, ), - gossip_support: GossipSupportSubsystem::new(keystore), + gossip_support: GossipSupportSubsystem::new(keystore.clone()), + dispute_coordinator: DisputeCoordinatorSubsystem::new( + parachains_db.clone(), + dispute_coordinator_config, + keystore.clone(), + ), + dispute_participation: DisputeParticipationSubsystem::new(), + dispute_distribution: DisputeDistributionSubsystem::new( + keystore.clone(), + dispute_req_receiver, + authority_discovery_service.clone(), + Metrics::register(registry)?, + ), + chain_selection: ChainSelectionSubsystem::new(chain_selection_config, parachains_db), }; Ok(all_subsystems) } @@ -203,10 +250,10 @@ where /// would do. pub trait OverseerGen { /// Overwrite the full generation of the overseer, including the subsystems. - fn generate( + fn generate<'a, Spawner, RuntimeClient>( &self, - args: OverseerGenArgs, - ) -> Result<(Overseer>, OverseerHandler), Error> + args: OverseerGenArgs<'a, Spawner, RuntimeClient>, + ) -> Result<(Overseer>, OverseerHandle), Error> where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, @@ -224,10 +271,10 @@ pub trait OverseerGen { pub struct RealOverseerGen; impl OverseerGen for RealOverseerGen { - fn generate( + fn generate<'a, Spawner, RuntimeClient>( &self, - args: OverseerGenArgs, - ) -> Result<(Overseer>, OverseerHandler), Error> + args: OverseerGenArgs<'a, Spawner, RuntimeClient>, + ) -> Result<(Overseer>, OverseerHandle), Error> where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, @@ -236,7 +283,7 @@ impl OverseerGen for RealOverseerGen { let spawner = args.spawner.clone(); let leaves = args.leaves.clone(); let runtime_client = args.runtime_client.clone(); - let registry = args.registry; + let registry = args.registry.clone(); let all_subsystems = create_default_subsystems::(args)?; diff --git a/bridges/bin/rialto/node/src/parachains_db.rs b/bridges/bin/rialto/node/src/parachains_db.rs index aa70d45cd7..976191fc80 100644 --- a/bridges/bin/rialto/node/src/parachains_db.rs +++ b/bridges/bin/rialto/node/src/parachains_db.rs @@ -20,11 +20,13 @@ use {kvdb::KeyValueDB, std::io, std::path::PathBuf, std::sync::Arc}; mod columns { - pub const NUM_COLUMNS: u32 = 3; + pub const NUM_COLUMNS: u32 = 5; pub const COL_AVAILABILITY_DATA: u32 = 0; pub const COL_AVAILABILITY_META: u32 = 1; pub const COL_APPROVAL_DATA: u32 = 2; + pub const COL_CHAIN_SELECTION_DATA: u32 = 3; + pub const COL_DISPUTE_COORDINATOR_DATA: u32 = 4; } /// Columns used by different subsystems. @@ -36,6 +38,10 @@ pub struct ColumnsConfig { pub col_availability_meta: u32, /// The column used by approval voting for data. pub col_approval_data: u32, + /// The column used by chain selection for data. + pub col_chain_selection_data: u32, + /// The column used by dispute coordinator for data. + pub col_dispute_coordinator_data: u32, } /// The real columns used by the parachains DB. @@ -43,6 +49,8 @@ pub const REAL_COLUMNS: ColumnsConfig = ColumnsConfig { col_availability_data: columns::COL_AVAILABILITY_DATA, col_availability_meta: columns::COL_AVAILABILITY_META, col_approval_data: columns::COL_APPROVAL_DATA, + col_chain_selection_data: columns::COL_CHAIN_SELECTION_DATA, + col_dispute_coordinator_data: columns::COL_DISPUTE_COORDINATOR_DATA, }; /// The cache size for each column, in megabytes. diff --git a/bridges/bin/rialto/node/src/service.rs b/bridges/bin/rialto/node/src/service.rs index 71ab93d858..dd7aea1b9c 100644 --- a/bridges/bin/rialto/node/src/service.rs +++ b/bridges/bin/rialto/node/src/service.rs @@ -26,34 +26,51 @@ use crate::overseer::{OverseerGen, OverseerGenArgs}; -use polkadot_network_bridge::RequestMultiplexer; use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig; use polkadot_node_core_av_store::Config as AvailabilityConfig; use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig; -use polkadot_overseer::{BlockInfo, OverseerHandler}; +use polkadot_node_core_chain_selection::Config as ChainSelectionConfig; +use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig; +use polkadot_node_network_protocol::request_response::IncomingRequest; +use polkadot_overseer::BlockInfo; use polkadot_primitives::v1::BlockId; use rialto_runtime::{self, opaque::Block, RuntimeApi}; use sc_client_api::ExecutorProvider; -use sc_executor::{native_executor_instance, NativeExecutionDispatch}; +use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch}; use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider; use sc_service::{config::PrometheusConfig, Configuration, TaskManager}; use sc_telemetry::{Telemetry, TelemetryWorker}; use sp_api::{ConstructRuntimeApi, HeaderT}; -use sp_blockchain::HeaderBackend; use sp_consensus::SelectChain; use sp_runtime::traits::{BlakeTwo256, Block as BlockT}; use std::{sync::Arc, time::Duration}; use substrate_prometheus_endpoint::Registry; -pub use sc_executor::NativeExecutor; +pub use { + polkadot_overseer::{Handle, Overseer, OverseerHandle}, + polkadot_primitives::v1::ParachainHost, + sc_client_api::AuxStore, + sp_authority_discovery::AuthorityDiscoveryApi, + sp_blockchain::HeaderBackend, + sp_consensus_babe::BabeApi, +}; + +pub type Executor = NativeElseWasmExecutor; // Our native executor instance. -native_executor_instance!( - pub Executor, - rialto_runtime::api::dispatch, - rialto_runtime::native_version, - frame_benchmarking::benchmarking::HostFunctions, -); +pub struct ExecutorDispatch; + +impl sc_executor::NativeExecutionDispatch for ExecutorDispatch { + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + + fn dispatch(method: &str, data: &[u8]) -> Option> { + rialto_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + rialto_runtime::native_version() + } +} #[derive(thiserror::Error, Debug)] pub enum Error { @@ -153,13 +170,13 @@ pub fn new_partial( FullClient, FullBackend, FullSelectChain, - sp_consensus::DefaultImportQueue, + sc_consensus::DefaultImportQueue, FullTransactionPool, ( impl Fn( sc_rpc::DenyUnsafe, sc_rpc::SubscriptionTaskExecutor, - ) -> jsonrpc_core::IoHandler, + ) -> Result, sc_service::Error>, (FullBabeBlockImport, FullGrandpaLink, FullBabeLink), sc_finality_grandpa::SharedVoterState, std::time::Duration, @@ -172,7 +189,7 @@ where RuntimeApi: ConstructRuntimeApi + Send + Sync + 'static, >::RuntimeApi: RequiredApiCollection>, - Executor: NativeExecutionDispatch + 'static, + ExecutorDispatch: NativeExecutionDispatch + 'static, { set_prometheus_registry(config)?; @@ -187,9 +204,16 @@ where }) .transpose()?; + let executor = NativeElseWasmExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + ); + let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::( config, telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, )?; let client = Arc::new(client); @@ -260,7 +284,7 @@ where move |deny_unsafe, subscription_executor: sc_rpc::SubscriptionTaskExecutor| - -> jsonrpc_core::IoHandler { + -> Result, sc_service::Error> { use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler}; use substrate_frame_rpc_system::{FullSystem, SystemApi}; @@ -289,7 +313,7 @@ where finality_proof_provider, ))); - io + Ok(io) } }; @@ -314,7 +338,7 @@ where pub struct NewFull { pub task_manager: TaskManager, pub client: C, - pub overseer_handler: Option, + pub overseer_handle: Option, pub network: Arc::Hash>>, pub rpc_handlers: sc_service::RpcHandlers, pub backend: Arc, @@ -332,7 +356,7 @@ where RuntimeApi: ConstructRuntimeApi + Send + Sync + 'static, >::RuntimeApi: RequiredApiCollection>, - Executor: NativeExecutionDispatch + 'static, + ExecutorDispatch: NativeExecutionDispatch + 'static, { let best_block = select_chain.best_chain().await?; @@ -381,7 +405,7 @@ where RuntimeApi: ConstructRuntimeApi + Send + Sync + 'static, >::RuntimeApi: RequiredApiCollection>, - Executor: NativeExecutionDispatch + 'static, + ExecutorDispatch: NativeExecutionDispatch + 'static, { let is_collator = false; @@ -426,20 +450,23 @@ where config.network.extra_sets.extend(peer_sets_info(is_authority)); } - config - .network - .request_response_protocols - .push(sc_finality_grandpa_warp_sync::request_response_config_for_chain( - &config, - task_manager.spawn_handle(), - backend.clone(), - import_setup.1.shared_authority_set().clone(), - )); - let request_multiplexer = { - let (multiplexer, configs) = RequestMultiplexer::new(); - config.network.request_response_protocols.extend(configs); - multiplexer - }; + let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + config.network.request_response_protocols.push(cfg); + let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + config.network.request_response_protocols.push(cfg); + let (collation_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + config.network.request_response_protocols.push(cfg); + let (available_data_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + config.network.request_response_protocols.push(cfg); + let (statement_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + config.network.request_response_protocols.push(cfg); + let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + config.network.request_response_protocols.push(cfg); + + let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + import_setup.1.shared_authority_set().clone(), + )); let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -449,6 +476,7 @@ where import_queue, on_demand: None, block_announce_validator_builder: None, + warp_sync: Some(warp_sync), })?; if config.offchain_worker.enabled { @@ -483,6 +511,15 @@ where }, }; + let chain_selection_config = ChainSelectionConfig { + col_data: crate::parachains_db::REAL_COLUMNS.col_chain_selection_data, + stagnant_check_interval: polkadot_node_core_chain_selection::StagnantCheckInterval::never(), + }; + + let dispute_coordinator_config = DisputeCoordinatorConfig { + col_data: crate::parachains_db::REAL_COLUMNS.col_dispute_coordinator_data, + }; + let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { config, backend: backend.clone(), @@ -545,8 +582,8 @@ where let local_keystore = keystore_container.local_keystore(); let maybe_params = local_keystore.and_then(move |k| authority_discovery_service.map(|a| (a, k))); - let overseer_handler = if let Some((authority_discovery_service, keystore)) = maybe_params { - let (overseer, overseer_handler) = + let overseer_handle = if let Some((authority_discovery_service, keystore)) = maybe_params { + let (overseer, overseer_handle) = overseer_gen.generate::(OverseerGenArgs { leaves: active_leaves, keystore, @@ -556,19 +593,27 @@ where approval_voting_config, network_service: network.clone(), authority_discovery_service, - request_multiplexer, registry: prometheus_registry.as_ref(), spawner, candidate_validation_config, + available_data_req_receiver, + chain_selection_config, + chunk_req_receiver, + collation_req_receiver, + dispute_coordinator_config, + dispute_req_receiver, + pov_req_receiver, + statement_req_receiver, })?; - let overseer_handler_clone = overseer_handler.clone(); + let handle = Handle::Connected(overseer_handle.clone()); + let handle_clone = handle.clone(); task_manager.spawn_essential_handle().spawn_blocking( "overseer", Box::pin(async move { use futures::{pin_mut, select, FutureExt}; - let forward = polkadot_overseer::forward_events(overseer_client, overseer_handler_clone); + let forward = polkadot_overseer::forward_events(overseer_client, handle_clone); let forward = forward.fuse(); let overseer_fut = overseer.run().fuse(); @@ -584,7 +629,7 @@ where }), ); - Some(overseer_handler) + Some(handle) } else { None }; @@ -601,7 +646,7 @@ where ); let client_clone = client.clone(); - let overseer_handler = overseer_handler + let overseer_handle = overseer_handle .as_ref() .ok_or(Error::AuthoritiesRequireRealOverseer)? .clone(); @@ -616,11 +661,11 @@ where justification_sync_link: network.clone(), create_inherent_data_providers: move |parent, ()| { let client_clone = client_clone.clone(); - let overseer_handler = overseer_handler.clone(); + let overseer_handle = overseer_handle.clone(); async move { let parachain = polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::create( &*client_clone, - overseer_handler, + overseer_handle, parent, ) .await @@ -705,7 +750,7 @@ where Ok(NewFull { task_manager, client, - overseer_handler, + overseer_handle, network, rpc_handlers, backend, diff --git a/bridges/bin/rialto/runtime/Cargo.toml b/bridges/bin/rialto/runtime/Cargo.toml index 4c0e51ad3c..8f4f4ef30e 100644 --- a/bridges/bin/rialto/runtime/Cargo.toml +++ b/bridges/bin/rialto/runtime/Cargo.toml @@ -12,7 +12,7 @@ codec = { package = "parity-scale-codec", version = "2.2.0", default-features = hex-literal = "0.3" libsecp256k1 = { version = "0.3.4", optional = true, default-features = false, features = ["hmac"] } log = { version = "0.4.14", default-features = false } -serde = { version = "1.0.124", optional = true, features = ["derive"] } +serde = { version = "1.0", optional = true, features = ["derive"] } # Bridge dependencies diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 8e7f3f2e42..b440000ae6 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -167,7 +167,7 @@ parameter_types! { impl frame_system::Config for Runtime { /// The basic call filter to use in dispatchable. - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. @@ -244,6 +244,7 @@ impl pallet_babe::Config for Runtime { >::IdentificationTuple; type HandleEquivocation = (); + type DisabledValidators = (); type WeightInfo = (); } @@ -293,7 +294,7 @@ impl pallet_bridge_dispatch::Config for Runtime { type Event = Event; type BridgeMessageId = (bp_messages::LaneId, bp_messages::MessageNonce); type Call = Call; - type CallFilter = (); + type CallFilter = frame_support::traits::Everything; type EncodedCall = crate::millau_messages::FromMillauEncodedCall; type SourceChainAccountId = bp_millau::AccountId; type TargetChainAccountPublic = MultiSigner; @@ -447,7 +448,13 @@ impl pallet_session::Config for Runtime { type WeightInfo = (); } -impl pallet_authority_discovery::Config for Runtime {} +parameter_types! { + pub const MaxAuthorities: u32 = 10; +} + +impl pallet_authority_discovery::Config for Runtime { + type MaxAuthorities = MaxAuthorities; +} parameter_types! { /// This is a pretty unscientific cap. @@ -572,17 +579,17 @@ construct_runtime!( // Parachain modules. ParachainsOrigin: polkadot_runtime_parachains::origin::{Pallet, Origin}, - ParachainsConfiguration: polkadot_runtime_parachains::configuration::{Pallet, Call, Storage, Config}, + Configuration: polkadot_runtime_parachains::configuration::{Pallet, Call, Storage, Config}, Shared: polkadot_runtime_parachains::shared::{Pallet, Call, Storage}, Inclusion: polkadot_runtime_parachains::inclusion::{Pallet, Call, Storage, Event}, ParasInherent: polkadot_runtime_parachains::paras_inherent::{Pallet, Call, Storage, Inherent}, - Scheduler: polkadot_runtime_parachains::scheduler::{Pallet, Call, Storage}, + Scheduler: polkadot_runtime_parachains::scheduler::{Pallet, Storage}, Paras: polkadot_runtime_parachains::paras::{Pallet, Call, Storage, Event, Config}, Initializer: polkadot_runtime_parachains::initializer::{Pallet, Call, Storage}, Dmp: polkadot_runtime_parachains::dmp::{Pallet, Call, Storage}, Ump: polkadot_runtime_parachains::ump::{Pallet, Call, Storage, Event}, - Hrmp: polkadot_runtime_parachains::hrmp::{Pallet, Call, Storage, Event, Config}, - SessionInfo: polkadot_runtime_parachains::session_info::{Pallet, Call, Storage}, + Hrmp: polkadot_runtime_parachains::hrmp::{Pallet, Call, Storage, Event, Config}, + SessionInfo: polkadot_runtime_parachains::session_info::{Pallet, Storage}, // Parachain Onboarding Pallets Registrar: polkadot_runtime_common::paras_registrar::{Pallet, Call, Storage, Event}, @@ -911,6 +918,10 @@ impl_runtime_apis! { } impl fg_primitives::GrandpaApi for Runtime { + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + fn grandpa_authorities() -> GrandpaAuthorityList { Grandpa::grandpa_authorities() } @@ -989,6 +1000,32 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use pallet_bridge_currency_exchange::benchmarking::Pallet as BridgeCurrencyExchangeBench; + use pallet_bridge_messages::benchmarking::Pallet as MessagesBench; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, pallet_bridge_eth_poa, BridgeRialtoPoa); + list_benchmark!( + list, + extra, + pallet_bridge_currency_exchange, BridgeCurrencyExchangeBench:: + ); + list_benchmark!(list, extra, pallet_bridge_messages, MessagesBench::); + list_benchmark!(list, extra, pallet_bridge_grandpa, BridgeMillauGrandpa); + + let storage_info = AllPalletsWithSystem::storage_info(); + + return (list, storage_info) + } + fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig, ) -> Result, sp_runtime::RuntimeString> { diff --git a/bridges/bin/rialto/runtime/src/parachains.rs b/bridges/bin/rialto/runtime/src/parachains.rs index 47fc6722a1..ba7b01ea11 100644 --- a/bridges/bin/rialto/runtime/src/parachains.rs +++ b/bridges/bin/rialto/runtime/src/parachains.rs @@ -59,6 +59,7 @@ impl parachains_hrmp::Config for Runtime { impl parachains_inclusion::Config for Runtime { type Event = Event; type RewardValidators = RewardValidators; + type DisputesHandler = (); } impl parachains_initializer::Config for Runtime { diff --git a/bridges/modules/currency-exchange/src/lib.rs b/bridges/modules/currency-exchange/src/lib.rs index 290e1a9bc9..550467f5d6 100644 --- a/bridges/modules/currency-exchange/src/lib.rs +++ b/bridges/modules/currency-exchange/src/lib.rs @@ -371,7 +371,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type BlockWeights = (); type BlockLength = (); diff --git a/bridges/modules/dispatch/src/lib.rs b/bridges/modules/dispatch/src/lib.rs index b334d862d8..698d3842a0 100644 --- a/bridges/modules/dispatch/src/lib.rs +++ b/bridges/modules/dispatch/src/lib.rs @@ -36,7 +36,7 @@ use codec::Encode; use frame_support::{ dispatch::Dispatchable, ensure, - traits::{Filter, Get}, + traits::{Contains, Get}, weights::{extract_actual_weight, GetDispatchInfo}, }; use frame_system::RawOrigin; @@ -77,7 +77,7 @@ pub mod pallet { /// /// The pallet will filter all incoming calls right before they're dispatched. If this filter /// rejects the call, special event (`Event::MessageCallRejected`) is emitted. - type CallFilter: Filter<>::Call>; + type CallFilter: Contains<>::Call>; /// The type that is used to wrap the `Self::Call` when it is moved over bridge. /// /// The idea behind this is to avoid `Call` conversion/decoding until we'll be sure @@ -252,7 +252,7 @@ impl, I: 'static> MessageDispatch }; // filter the call - if !T::CallFilter::filter(&call) { + if !T::CallFilter::contains(&call) { log::trace!( target: "runtime::bridge-dispatch", "Message {:?}/{:?}: the call ({:?}) is rejected by filter", @@ -491,7 +491,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type BlockWeights = (); type BlockLength = (); @@ -523,8 +523,8 @@ mod tests { pub struct TestCallFilter; - impl Filter for TestCallFilter { - fn filter(call: &Call) -> bool { + impl Contains for TestCallFilter { + fn contains(call: &Call) -> bool { !matches!(*call, Call::System(frame_system::Call::fill_block(_))) } } diff --git a/bridges/modules/ethereum/src/mock.rs b/bridges/modules/ethereum/src/mock.rs index 90c143dc93..00c10d3cc3 100644 --- a/bridges/modules/ethereum/src/mock.rs +++ b/bridges/modules/ethereum/src/mock.rs @@ -73,7 +73,7 @@ impl frame_system::Config for TestRuntime { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type BlockWeights = (); type BlockLength = (); diff --git a/bridges/modules/grandpa/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index 363594c35f..dcbae4e60f 100644 --- a/bridges/modules/grandpa/src/mock.rs +++ b/bridges/modules/grandpa/src/mock.rs @@ -70,7 +70,7 @@ impl frame_system::Config for TestRuntime { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type DbWeight = (); type BlockWeights = (); diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/mock.rs index 88ec92ff03..84496393d5 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/mock.rs @@ -112,7 +112,7 @@ impl frame_system::Config for TestRuntime { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type BlockWeights = (); type BlockLength = (); diff --git a/bridges/modules/shift-session-manager/src/lib.rs b/bridges/modules/shift-session-manager/src/lib.rs index eef336ffd8..011b50ad59 100644 --- a/bridges/modules/shift-session-manager/src/lib.rs +++ b/bridges/modules/shift-session-manager/src/lib.rs @@ -150,7 +150,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type BlockWeights = (); type BlockLength = (); diff --git a/bridges/modules/token-swap/src/mock.rs b/bridges/modules/token-swap/src/mock.rs index c95f413b72..ed5c1b7cee 100644 --- a/bridges/modules/token-swap/src/mock.rs +++ b/bridges/modules/token-swap/src/mock.rs @@ -81,7 +81,7 @@ impl frame_system::Config for TestRuntime { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); - type BaseCallFilter = (); + type BaseCallFilter = frame_support::traits::Everything; type SystemWeightInfo = (); type BlockWeights = (); type BlockLength = (); diff --git a/bridges/primitives/chain-millau/Cargo.toml b/bridges/primitives/chain-millau/Cargo.toml index c4f30aaf6b..a0630fa8a9 100644 --- a/bridges/primitives/chain-millau/Cargo.toml +++ b/bridges/primitives/chain-millau/Cargo.toml @@ -16,8 +16,8 @@ fixed-hash = { version = "0.7.0", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } impl-codec = { version = "0.5.1", default-features = false } impl-serde = { version = "0.3.1", optional = true } -parity-util-mem = { version = "0.10.0", default-features = false, features = ["primitive-types"] } -serde = { version = "1.0.101", optional = true, features = ["derive"] } +parity-util-mem = { version = "0.10", default-features = false, features = ["primitive-types"] } +serde = { version = "1.0", optional = true, features = ["derive"] } # Substrate Based Dependencies diff --git a/bridges/primitives/messages/Cargo.toml b/bridges/primitives/messages/Cargo.toml index 2dc5ae8032..af0dcf904f 100644 --- a/bridges/primitives/messages/Cargo.toml +++ b/bridges/primitives/messages/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" bitvec = { version = "0.20", default-features = false, features = ["alloc"] } codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive", "bit-vec"] } impl-trait-for-tuples = "0.2" -serde = { version = "1.0.101", optional = true, features = ["derive"] } +serde = { version = "1.0", optional = true, features = ["derive"] } # Bridge dependencies diff --git a/bridges/relays/bin-substrate/src/cli/encode_call.rs b/bridges/relays/bin-substrate/src/cli/encode_call.rs index b5f80ffdcd..23ea4b8073 100644 --- a/bridges/relays/bin-substrate/src/cli/encode_call.rs +++ b/bridges/relays/bin-substrate/src/cli/encode_call.rs @@ -332,7 +332,7 @@ mod tests { // then assert!(format!("{:?}", call_hex).starts_with( - "0x11030000000001000000b0d60f000000000001d43593c715fdd31c61141abd04a99fd6822c8558854cc\ + "0x11030000000001000000381409000000000001d43593c715fdd31c61141abd04a99fd6822c8558854cc\ de39a5684e7a56da27d01d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01" )) } diff --git a/bridges/relays/bin-substrate/src/cli/encode_message.rs b/bridges/relays/bin-substrate/src/cli/encode_message.rs index a2e049f24f..36a4806976 100644 --- a/bridges/relays/bin-substrate/src/cli/encode_message.rs +++ b/bridges/relays/bin-substrate/src/cli/encode_message.rs @@ -102,6 +102,6 @@ mod tests { let hex = encode_message.encode().unwrap(); // then - assert_eq!(format!("{:?}", hex), "0x01000000b0d60f000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d003c000130000000000000000000000000"); + assert_eq!(format!("{:?}", hex), "0x0100000010f108000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d003c000130000000000000000000000000"); } } diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs index 68b332b069..04ce386ef0 100644 --- a/bridges/relays/bin-substrate/src/cli/send_message.rs +++ b/bridges/relays/bin-substrate/src/cli/send_message.rs @@ -320,7 +320,7 @@ mod tests { payload, MessagePayload { spec_version: relay_millau_client::Millau::RUNTIME_VERSION.spec_version, - weight: 1038000, + weight: 576000, origin: CallOrigin::SourceAccount(sp_keyring::AccountKeyring::Alice.to_account_id()), dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtSourceChain, call: hex!("0001081234").to_vec(), @@ -360,7 +360,7 @@ mod tests { payload, MessagePayload { spec_version: relay_millau_client::Millau::RUNTIME_VERSION.spec_version, - weight: 1038000, + weight: 576000, origin: CallOrigin::TargetAccount( sp_keyring::AccountKeyring::Alice.to_account_id(), sp_keyring::AccountKeyring::Bob.into(), diff --git a/bridges/relays/client-substrate/Cargo.toml b/bridges/relays/client-substrate/Cargo.toml index 807080dcc8..90e775b784 100644 --- a/bridges/relays/client-substrate/Cargo.toml +++ b/bridges/relays/client-substrate/Cargo.toml @@ -34,11 +34,11 @@ pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/bridges/relays/client-substrate/src/chain.rs b/bridges/relays/client-substrate/src/chain.rs index 60fe63230a..84db77ec6d 100644 --- a/bridges/relays/client-substrate/src/chain.rs +++ b/bridges/relays/client-substrate/src/chain.rs @@ -19,13 +19,13 @@ use codec::{Codec, Encode}; use frame_support::weights::WeightToFeePolynomial; use jsonrpsee_ws_client::{DeserializeOwned, Serialize}; use num_traits::Zero; +use sc_transaction_pool_api::TransactionStatus; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{ generic::SignedBlock, traits::{Block as BlockT, Dispatchable, Member}, EncodedJustification, }; -use sp_transaction_pool::TransactionStatus; use std::{fmt::Debug, time::Duration}; /// Substrate-based chain from minimal relay-client point of view. diff --git a/bridges/relays/client-substrate/src/client.rs b/bridges/relays/client-substrate/src/client.rs index 31f4a19d8f..be483243df 100644 --- a/bridges/relays/client-substrate/src/client.rs +++ b/bridges/relays/client-substrate/src/client.rs @@ -18,7 +18,7 @@ use crate::chain::{Chain, ChainWithBalances, TransactionStatusOf}; use crate::rpc::Substrate; -use crate::{ConnectionParams, Error, HeaderIdOf, Result}; +use crate::{ConnectionParams, Error, HashOf, HeaderIdOf, Result}; use async_std::sync::{Arc, Mutex}; use async_trait::async_trait; @@ -61,7 +61,7 @@ pub struct Client { /// Substrate RPC client. client: Arc, /// Genesis block hash. - genesis_hash: C::Hash, + genesis_hash: HashOf, /// If several tasks are submitting their transactions simultaneously using `submit_signed_extrinsic` /// method, they may get the same transaction nonce. So one of transactions will be rejected /// from the pool. This lock is here to prevent situations like that. diff --git a/bridges/relays/client-substrate/src/guard.rs b/bridges/relays/client-substrate/src/guard.rs index 6c5bf16baa..093cc50f05 100644 --- a/bridges/relays/client-substrate/src/guard.rs +++ b/bridges/relays/client-substrate/src/guard.rs @@ -39,10 +39,12 @@ pub trait Environment: Send + Sync + 'static { fn now(&self) -> Instant { Instant::now() } + /// Sleep given amount of time. async fn sleep(&mut self, duration: Duration) { async_std::task::sleep(duration).await } + /// Abort current process. Called when guard condition check fails. async fn abort(&mut self) { std::process::abort(); diff --git a/bridges/relays/headers/src/sync.rs b/bridges/relays/headers/src/sync.rs index cd5ab0906f..7e3d902029 100644 --- a/bridges/relays/headers/src/sync.rs +++ b/bridges/relays/headers/src/sync.rs @@ -131,13 +131,13 @@ impl HeadersSync

{ } // if queue is empty and best header on target is > than best header on source, - // then we shoud reorg + // then we shoud reorganization let best_queued_number = self.headers.best_queued_number(); if best_queued_number.is_zero() && source_best_number < target_best_header.0 { return Some(source_best_number); } - // we assume that there were no reorgs if we have already downloaded best header + // we assume that there were no reorganizations if we have already downloaded best header let best_downloaded_number = std::cmp::max( std::cmp::max(best_queued_number, self.headers.best_synced_number()), target_best_header.0, diff --git a/bridges/relays/headers/src/sync_loop.rs b/bridges/relays/headers/src/sync_loop.rs index c373f41520..a557eca6a2 100644 --- a/bridges/relays/headers/src/sync_loop.rs +++ b/bridges/relays/headers/src/sync_loop.rs @@ -38,13 +38,13 @@ use std::{ /// When we submit headers to target node, but see no updates of best /// source block known to target node during STALL_SYNC_TIMEOUT seconds, -/// we consider that our headers are rejected because there has been reorg in target chain. -/// This reorg could invalidate our knowledge about sync process (i.e. we have asked if -/// HeaderA is known to target, but then reorg happened and the answer is different +/// we consider that our headers are rejected because there has been reorganization in target chain. +/// This reorganization could invalidate our knowledge about sync process (i.e. we have asked if +/// HeaderA is known to target, but then reorganization happened and the answer is different /// now) => we need to reset sync. /// The other option is to receive **EVERY** best target header and check if it is /// direct child of previous best header. But: (1) subscription doesn't guarantee that -/// the subscriber will receive every best header (2) reorg won't always lead to sync +/// the subscriber will receive every best header (2) reorganization won't always lead to sync /// stall and restart is a heavy operation (we forget all in-memory headers). const STALL_SYNC_TIMEOUT: Duration = Duration::from_secs(5 * 60); /// Delay after we have seen update of best source header at target node,