diff --git a/bridges/bin/rialto/node/Cargo.toml b/bridges/bin/rialto/node/Cargo.toml
index 99c9eb80d1..833cea604d 100644
--- a/bridges/bin/rialto/node/Cargo.toml
+++ b/bridges/bin/rialto/node/Cargo.toml
@@ -10,9 +10,13 @@ repository = "https://github.com/paritytech/parity-bridges-common/"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
+futures = "0.3"
jsonrpc-core = "15.1.0"
+kvdb = "0.10"
+kvdb-rocksdb = "0.12"
structopt = "0.3.21"
serde_json = "1.0.59"
+thiserror = "1.0"
# Bridge dependencies
@@ -23,31 +27,73 @@ rialto-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" }
+frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
node-inspect = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
+pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["wasmtime"] }
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sc-consensus-uncles = { git = "https://github.com/paritytech/substrate", branch = "master" }
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-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" }
sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
+sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-timestamp = { 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" }
+
+# Polkadot (parachain) Dependencies
+
+polkadot-approval-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+polkadot-availability-bitfield-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+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-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" }
+polkadot-node-core-approval-voting = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+polkadot-node-core-av-store = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+polkadot-node-core-backing = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+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-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-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" }
+polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" }
+polkadot-statement-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }
[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/bridges/bin/rialto/node/src/chain_spec.rs b/bridges/bin/rialto/node/src/chain_spec.rs
index 977ee17946..b77b1d6acf 100644
--- a/bridges/bin/rialto/node/src/chain_spec.rs
+++ b/bridges/bin/rialto/node/src/chain_spec.rs
@@ -15,11 +15,14 @@
// along with Parity Bridges Common. If not, see .
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, SessionConfig, SessionKeys, Signature, SudoConfig, SystemConfig, WASM_BINARY,
+ GenesisConfig, GrandpaConfig, ParachainsConfigurationConfig, SessionConfig, SessionKeys, Signature, SudoConfig,
+ SystemConfig, WASM_BINARY,
};
use serde_json::json;
+use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_consensus_babe::AuthorityId as BabeId;
use sp_core::{sr25519, Pair, Public};
use sp_finality_grandpa::AuthorityId as GrandpaId;
@@ -56,12 +59,24 @@ where
AccountPublic::from(get_from_seed::(seed)).into_account()
}
-/// Helper function to generate an authority key for Babe
-pub fn get_authority_keys_from_seed(s: &str) -> (AccountId, BabeId, GrandpaId) {
+/// Helper function to generate authority keys.
+pub fn get_authority_keys_from_seed(
+ s: &str,
+) -> (
+ AccountId,
+ BabeId,
+ GrandpaId,
+ ValidatorId,
+ AssignmentId,
+ AuthorityDiscoveryId,
+) {
(
get_account_id_from_seed::(s),
get_from_seed::(s),
get_from_seed::(s),
+ get_from_seed::(s),
+ get_from_seed::(s),
+ get_from_seed::(s),
)
}
@@ -172,12 +187,31 @@ impl Alternative {
}
}
-fn session_keys(babe: BabeId, grandpa: GrandpaId) -> SessionKeys {
- SessionKeys { babe, grandpa }
+fn session_keys(
+ babe: BabeId,
+ grandpa: GrandpaId,
+ para_validator: ValidatorId,
+ para_assignment: AssignmentId,
+ authority_discovery: AuthorityDiscoveryId,
+) -> SessionKeys {
+ SessionKeys {
+ babe,
+ grandpa,
+ para_validator,
+ para_assignment,
+ authority_discovery,
+ }
}
fn testnet_genesis(
- initial_authorities: Vec<(AccountId, BabeId, GrandpaId)>,
+ initial_authorities: Vec<(
+ AccountId,
+ BabeId,
+ GrandpaId,
+ ValidatorId,
+ AssignmentId,
+ AuthorityDiscoveryId,
+ )>,
root_key: AccountId,
endowed_accounts: Vec,
_enable_println: bool,
@@ -203,9 +237,62 @@ fn testnet_genesis(
session: SessionConfig {
keys: initial_authorities
.iter()
- .map(|x| (x.0.clone(), x.0.clone(), session_keys(x.1.clone(), x.2.clone())))
+ .map(|x| {
+ (
+ x.0.clone(),
+ x.0.clone(),
+ session_keys(x.1.clone(), x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()),
+ )
+ })
.collect::>(),
},
+ authority_discovery: Default::default(),
+ 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 {
+ config: polkadot_runtime_parachains::configuration::HostConfiguration {
+ validation_upgrade_frequency: 1u32,
+ validation_upgrade_delay: 1,
+ code_retention_period: 1200,
+ max_code_size: polkadot_primitives::v1::MAX_CODE_SIZE,
+ max_pov_size: polkadot_primitives::v1::MAX_POV_SIZE,
+ max_head_data_size: 32 * 1024,
+ group_rotation_frequency: 20,
+ chain_availability_period: 4,
+ thread_availability_period: 4,
+ max_upward_queue_count: 8,
+ max_upward_queue_size: 1024 * 1024,
+ max_downward_message_size: 1024,
+ // this is approximatelly 4ms.
+ //
+ // Same as `4 * frame_support::weights::WEIGHT_PER_MILLIS`. We don't bother with
+ // an import since that's a made up number and should be replaced with a constant
+ // obtained by benchmarking anyway.
+ 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_sender_deposit: 0,
+ hrmp_recipient_deposit: 0,
+ hrmp_channel_max_capacity: 8,
+ hrmp_channel_max_total_size: 8 * 1024,
+ hrmp_max_parachain_inbound_channels: 4,
+ hrmp_max_parathread_inbound_channels: 4,
+ hrmp_channel_max_message_size: 1024 * 1024,
+ hrmp_max_parachain_outbound_channels: 4,
+ hrmp_max_parathread_outbound_channels: 4,
+ hrmp_max_message_num_per_candidate: 5,
+ dispute_period: 6,
+ no_show_slots: 2,
+ n_delay_tranches: 25,
+ needed_approvals: 2,
+ relay_vrf_modulo_samples: 2,
+ zeroth_delay_tranche_width: 0,
+ ..Default::default()
+ },
+ },
+ paras: Default::default(),
bridge_millau_messages: BridgeMillauMessagesConfig {
owner: Some(get_account_id_from_seed::("MillauMessagesOwner")),
..Default::default()
diff --git a/bridges/bin/rialto/node/src/cli.rs b/bridges/bin/rialto/node/src/cli.rs
index 086def633c..3f85a69a71 100644
--- a/bridges/bin/rialto/node/src/cli.rs
+++ b/bridges/bin/rialto/node/src/cli.rs
@@ -67,4 +67,19 @@ pub enum Subcommand {
/// Benchmark runtime pallets.
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
+
+ /// FOR INTERNAL USE: analog of the "prepare-worker" command of the polkadot binary.
+ #[structopt(name = "prepare-worker", setting = structopt::clap::AppSettings::Hidden)]
+ PvfPrepareWorker(ValidationWorkerCommand),
+
+ /// FOR INTERNAL USE: analog of the "execute-worker" command of the polkadot binary.
+ #[structopt(name = "execute-worker", setting = structopt::clap::AppSettings::Hidden)]
+ PvfExecuteWorker(ValidationWorkerCommand),
+}
+
+/// Validation worker command.
+#[derive(Debug, StructOpt)]
+pub struct ValidationWorkerCommand {
+ /// The path to the validation host's socket.
+ pub socket_path: String,
}
diff --git a/bridges/bin/rialto/node/src/command.rs b/bridges/bin/rialto/node/src/command.rs
index 226a21d841..4fe40251e6 100644
--- a/bridges/bin/rialto/node/src/command.rs
+++ b/bridges/bin/rialto/node/src/command.rs
@@ -15,7 +15,6 @@
// along with Parity Bridges Common. If not, see .
use crate::cli::{Cli, Subcommand};
-use crate::service;
use crate::service::new_partial;
use rialto_runtime::{Block, RuntimeApi};
use sc_cli::{ChainSpec, Role, RuntimeVersion, SubstrateCli};
@@ -78,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. \
@@ -97,43 +96,43 @@ pub fn run() -> sc_cli::Result<()> {
}
Some(Subcommand::CheckBlock(cmd)) => {
let runner = cli.create_runner(cmd)?;
- runner.async_run(|config| {
+ runner.async_run(|mut config| {
let PartialComponents {
client,
task_manager,
import_queue,
..
- } = new_partial(&config)?;
+ } = new_partial(&mut config).map_err(service_error)?;
Ok((cmd.run(client, import_queue), task_manager))
})
}
Some(Subcommand::ExportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
- runner.async_run(|config| {
+ runner.async_run(|mut config| {
let PartialComponents {
client, task_manager, ..
- } = new_partial(&config)?;
+ } = new_partial(&mut config).map_err(service_error)?;
Ok((cmd.run(client, config.database), task_manager))
})
}
Some(Subcommand::ExportState(cmd)) => {
let runner = cli.create_runner(cmd)?;
- runner.async_run(|config| {
+ runner.async_run(|mut config| {
let PartialComponents {
client, task_manager, ..
- } = new_partial(&config)?;
+ } = new_partial(&mut config).map_err(service_error)?;
Ok((cmd.run(client, config.chain_spec), task_manager))
})
}
Some(Subcommand::ImportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
- runner.async_run(|config| {
+ runner.async_run(|mut config| {
let PartialComponents {
client,
task_manager,
import_queue,
..
- } = new_partial(&config)?;
+ } = new_partial(&mut config).map_err(service_error)?;
Ok((cmd.run(client, import_queue), task_manager))
})
}
@@ -143,32 +142,62 @@ pub fn run() -> sc_cli::Result<()> {
}
Some(Subcommand::Revert(cmd)) => {
let runner = cli.create_runner(cmd)?;
- runner.async_run(|config| {
+ runner.async_run(|mut config| {
let PartialComponents {
client,
task_manager,
backend,
..
- } = new_partial(&config)?;
+ } = new_partial(&mut config).map_err(service_error)?;
Ok((cmd.run(client, backend), task_manager))
})
}
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("");
+ builder.with_colors(false);
+ let _ = builder.init();
+
+ polkadot_node_core_pvf::prepare_worker_entrypoint(&cmd.socket_path);
+ Ok(())
+ }
+ Some(crate::cli::Subcommand::PvfExecuteWorker(cmd)) => {
+ let mut builder = sc_cli::LoggerBuilder::new("");
+ builder.with_colors(false);
+ let _ = builder.init();
+
+ polkadot_node_core_pvf::execute_worker_entrypoint(&cmd.socket_path);
+ Ok(())
}
None => {
let runner = cli.create_runner(&cli.run)?;
- runner
- .run_node_until_exit(|config| async move {
- match config.role {
- Role::Light => Err(sc_service::Error::Other(
- "Light client is not supported by this node".into(),
- )),
- _ => service::new_full(config),
- }
- })
- .map_err(sc_cli::Error::Service)
+
+ // some parameters that are used by polkadot nodes, but that are not used by our binary
+ // let jaeger_agent = None;
+ // let grandpa_pause = None;
+ // let no_beefy = true;
+ // let telemetry_worker_handler = None;
+ // let is_collator = crate::service::IsCollator::No;
+ let overseer_gen = crate::overseer::RealOverseerGen;
+ runner.run_node_until_exit(|config| async move {
+ match config.role {
+ Role::Light => Err(sc_cli::Error::Service(sc_service::Error::Other(
+ "Light client is not supported by this node".into(),
+ ))),
+ _ => crate::service::build_full(config, overseer_gen)
+ .map(|full| full.task_manager)
+ .map_err(service_error),
+ }
+ })
}
}
}
+
+// We don't want to change 'service.rs' too much to ease future updates => it'll keep using
+// its own error enum like original polkadot service does.
+fn service_error(err: crate::service::Error) -> sc_cli::Error {
+ sc_cli::Error::Application(Box::new(err))
+}
diff --git a/bridges/bin/rialto/node/src/main.rs b/bridges/bin/rialto/node/src/main.rs
index f319d1437a..824814224e 100644
--- a/bridges/bin/rialto/node/src/main.rs
+++ b/bridges/bin/rialto/node/src/main.rs
@@ -23,6 +23,8 @@ mod chain_spec;
mod service;
mod cli;
mod command;
+mod overseer;
+mod parachains_db;
/// Run the Rialto Node
fn main() -> sc_cli::Result<()> {
diff --git a/bridges/bin/rialto/node/src/overseer.rs b/bridges/bin/rialto/node/src/overseer.rs
new file mode 100644
index 0000000000..f7aaef4b5d
--- /dev/null
+++ b/bridges/bin/rialto/node/src/overseer.rs
@@ -0,0 +1,245 @@
+// 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 .
+
+//! This is almost 1:1 copy of `node/service/src/overseer.rs` file from Polkadot repository.
+//! The only exception is that we don't support db upgrades => no `upgrade.rs` module.
+
+// this warning comes from `polkadot_overseer::AllSubsystems` type
+#![allow(clippy::type_complexity)]
+
+use crate::service::Error;
+
+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::{AllSubsystems, BlockInfo, Overseer, OverseerHandler};
+use polkadot_primitives::v1::{Block, Hash, 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;
+use std::sync::Arc;
+use substrate_prometheus_endpoint::Registry;
+
+pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem;
+pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as BitfieldDistributionSubsystem;
+pub use polkadot_availability_distribution::AvailabilityDistributionSubsystem;
+pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
+pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide};
+pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem;
+pub use polkadot_network_bridge::NetworkBridge as NetworkBridgeSubsystem;
+pub use polkadot_node_collation_generation::CollationGenerationSubsystem;
+pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem;
+pub use polkadot_node_core_av_store::AvailabilityStoreSubsystem;
+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_provisioner::ProvisioningSubsystem as ProvisionerSubsystem;
+pub use polkadot_node_core_runtime_api::RuntimeApiSubsystem;
+pub use polkadot_statement_distribution::StatementDistribution as StatementDistributionSubsystem;
+
+/// Arguments passed for overseer construction.
+pub struct OverseerGenArgs<'a, Spawner, RuntimeClient>
+where
+ RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore,
+ RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi,
+ Spawner: 'static + SpawnNamed + Clone + Unpin,
+{
+ /// Set of initial relay chain leaves to track.
+ pub leaves: Vec,
+ /// The keystore to use for i.e. validator keys.
+ pub keystore: Arc,
+ /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others.
+ 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,
+ /// 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 candidate validation subsystem.
+ pub candidate_validation_config: CandidateValidationConfig,
+}
+
+/// 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(
+ OverseerGenArgs {
+ keystore,
+ runtime_client,
+ parachains_db,
+ availability_config,
+ approval_voting_config,
+ network_service,
+ authority_discovery_service,
+ request_multiplexer,
+ registry,
+ spawner,
+ candidate_validation_config,
+ ..
+ }: OverseerGenArgs,
+) -> Result<
+ AllSubsystems<
+ CandidateValidationSubsystem,
+ CandidateBackingSubsystem,
+ StatementDistributionSubsystem,
+ AvailabilityDistributionSubsystem,
+ AvailabilityRecoverySubsystem,
+ BitfieldSigningSubsystem,
+ BitfieldDistributionSubsystem,
+ ProvisionerSubsystem,
+ RuntimeApiSubsystem,
+ AvailabilityStoreSubsystem,
+ NetworkBridgeSubsystem>, AuthorityDiscoveryService>,
+ ChainApiSubsystem,
+ CollationGenerationSubsystem,
+ CollatorProtocolSubsystem,
+ ApprovalDistributionSubsystem,
+ ApprovalVotingSubsystem,
+ GossipSupportSubsystem,
+ >,
+ Error,
+>
+where
+ RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore,
+ RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi,
+ Spawner: 'static + SpawnNamed + Clone + Unpin,
+{
+ use polkadot_node_subsystem_util::metrics::Metrics;
+
+ let all_subsystems = AllSubsystems {
+ availability_distribution: AvailabilityDistributionSubsystem::new(
+ keystore.clone(),
+ Metrics::register(registry)?,
+ ),
+ availability_recovery: AvailabilityRecoverySubsystem::with_chunks_only(),
+ availability_store: AvailabilityStoreSubsystem::new(
+ parachains_db.clone(),
+ availability_config,
+ Metrics::register(registry)?,
+ ),
+ bitfield_distribution: BitfieldDistributionSubsystem::new(Metrics::register(registry)?),
+ bitfield_signing: BitfieldSigningSubsystem::new(
+ spawner.clone(),
+ keystore.clone(),
+ Metrics::register(registry)?,
+ ),
+ candidate_backing: CandidateBackingSubsystem::new(
+ spawner.clone(),
+ keystore.clone(),
+ Metrics::register(registry)?,
+ ),
+ candidate_validation: CandidateValidationSubsystem::with_config(
+ candidate_validation_config,
+ Metrics::register(registry)?,
+ ),
+ 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)
+ },
+ network_bridge: NetworkBridgeSubsystem::new(
+ network_service.clone(),
+ authority_discovery_service,
+ request_multiplexer,
+ 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)?),
+ approval_distribution: ApprovalDistributionSubsystem::new(Metrics::register(registry)?),
+ approval_voting: ApprovalVotingSubsystem::with_config(
+ approval_voting_config,
+ parachains_db,
+ keystore.clone(),
+ Box::new(network_service),
+ Metrics::register(registry)?,
+ ),
+ gossip_support: GossipSupportSubsystem::new(keystore),
+ };
+ Ok(all_subsystems)
+}
+
+/// Trait for the `fn` generating the overseer.
+///
+/// Default behavior is to create an unmodified overseer, as `RealOverseerGen`
+/// would do.
+pub trait OverseerGen {
+ /// Overwrite the full generation of the overseer, including the subsystems.
+ fn generate(
+ &self,
+ args: OverseerGenArgs,
+ ) -> Result<(Overseer>, OverseerHandler), Error>
+ where
+ RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore,
+ RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi,
+ Spawner: 'static + SpawnNamed + Clone + Unpin,
+ {
+ let gen = RealOverseerGen;
+ RealOverseerGen::generate::(&gen, args)
+ }
+ // It would be nice to make `create_subsystems` part of this trait,
+ // but the amount of generic arguments that would be required as
+ // as consequence make this rather annoying to implement and use.
+}
+
+/// The regular set of subsystems.
+pub struct RealOverseerGen;
+
+impl OverseerGen for RealOverseerGen {
+ fn generate(
+ &self,
+ args: OverseerGenArgs,
+ ) -> Result<(Overseer>, OverseerHandler), Error>
+ where
+ RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore,
+ RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi,
+ Spawner: 'static + SpawnNamed + Clone + Unpin,
+ {
+ let spawner = args.spawner.clone();
+ let leaves = args.leaves.clone();
+ let runtime_client = args.runtime_client.clone();
+ let registry = args.registry;
+
+ let all_subsystems = create_default_subsystems::(args)?;
+
+ Overseer::new(leaves, all_subsystems, registry, runtime_client, spawner).map_err(|e| e.into())
+ }
+}
diff --git a/bridges/bin/rialto/node/src/parachains_db.rs b/bridges/bin/rialto/node/src/parachains_db.rs
new file mode 100644
index 0000000000..aa70d45cd7
--- /dev/null
+++ b/bridges/bin/rialto/node/src/parachains_db.rs
@@ -0,0 +1,99 @@
+// 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 .
+
+//! This is almost 1:1 copy of `node/service/parachains_db/mod.rs` file from Polkadot repository.
+//! The only exception is that we don't support db upgrades => no `upgrade.rs` module.
+
+use {kvdb::KeyValueDB, std::io, std::path::PathBuf, std::sync::Arc};
+
+mod columns {
+ pub const NUM_COLUMNS: u32 = 3;
+
+ pub const COL_AVAILABILITY_DATA: u32 = 0;
+ pub const COL_AVAILABILITY_META: u32 = 1;
+ pub const COL_APPROVAL_DATA: u32 = 2;
+}
+
+/// Columns used by different subsystems.
+#[derive(Debug, Clone)]
+pub struct ColumnsConfig {
+ /// The column used by the av-store for data.
+ pub col_availability_data: u32,
+ /// The column used by the av-store for meta information.
+ pub col_availability_meta: u32,
+ /// The column used by approval voting for data.
+ pub col_approval_data: u32,
+}
+
+/// The real columns used by the parachains DB.
+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,
+};
+
+/// The cache size for each column, in megabytes.
+#[derive(Debug, Clone)]
+pub struct CacheSizes {
+ /// Cache used by availability data.
+ pub availability_data: usize,
+ /// Cache used by availability meta.
+ pub availability_meta: usize,
+ /// Cache used by approval data.
+ pub approval_data: usize,
+}
+
+impl Default for CacheSizes {
+ fn default() -> Self {
+ CacheSizes {
+ availability_data: 25,
+ availability_meta: 1,
+ approval_data: 5,
+ }
+ }
+}
+
+fn other_io_error(err: String) -> io::Error {
+ io::Error::new(io::ErrorKind::Other, err)
+}
+
+/// Open the database on disk, creating it if it doesn't exist.
+pub fn open_creating(root: PathBuf, cache_sizes: CacheSizes) -> io::Result> {
+ use kvdb_rocksdb::{Database, DatabaseConfig};
+
+ let path = root.join("parachains").join("db");
+
+ let mut db_config = DatabaseConfig::with_columns(columns::NUM_COLUMNS);
+
+ let _ = db_config
+ .memory_budget
+ .insert(columns::COL_AVAILABILITY_DATA, cache_sizes.availability_data);
+ let _ = db_config
+ .memory_budget
+ .insert(columns::COL_AVAILABILITY_META, cache_sizes.availability_meta);
+ let _ = db_config
+ .memory_budget
+ .insert(columns::COL_APPROVAL_DATA, cache_sizes.approval_data);
+
+ let path_str = path
+ .to_str()
+ .ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?;
+
+ std::fs::create_dir_all(&path_str)?;
+ let db = Database::open(&db_config, path_str)?;
+
+ Ok(Arc::new(db))
+}
diff --git a/bridges/bin/rialto/node/src/service.rs b/bridges/bin/rialto/node/src/service.rs
index 77d63a68dd..71ab93d858 100644
--- a/bridges/bin/rialto/node/src/service.rs
+++ b/bridges/bin/rialto/node/src/service.rs
@@ -14,30 +14,36 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
-//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
+//! Rialto chain node service.
+//!
+//! The code is mostly copy of `service/src/lib.rs` file from Polkadot repository
+//! without optional functions.
-// =====================================================================================
-// =====================================================================================
-// =====================================================================================
-// There's no easy way to update this file. Currently it is a merge of two files:
-// 1) node-template/src/service.rs from Substrate repo;
-// 2) node/service/src/lib.rs from Polkadot repo.
-//
-// The main things to notice when updating are:
-// 1) we are using Babe for authoring blocks;
-// 2) support for light client is dropped as we are not using it now.
-// ===========================================s==========================================
-// =====================================================================================
-// =====================================================================================
+// this warning comes from Error enum (sc_cli::Error in particular) && it isn't easy to use box there
+#![allow(clippy::large_enum_variant)]
+// this warning comes from `sc_service::PartialComponents` type
+#![allow(clippy::type_complexity)]
+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_primitives::v1::BlockId;
use rialto_runtime::{self, opaque::Block, RuntimeApi};
use sc_client_api::ExecutorProvider;
-use sc_consensus_babe::SlotProportion;
-use sc_executor::native_executor_instance;
-use sc_keystore::LocalKeystore;
-use sc_service::{error::Error as ServiceError, Configuration, TaskManager};
+use sc_executor::{native_executor_instance, 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;
@@ -49,34 +55,126 @@ native_executor_instance!(
frame_benchmarking::benchmarking::HostFunctions,
);
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+ #[error(transparent)]
+ Io(#[from] std::io::Error),
+
+ #[error(transparent)]
+ Cli(#[from] sc_cli::Error),
+
+ #[error(transparent)]
+ Blockchain(#[from] sp_blockchain::Error),
+
+ #[error(transparent)]
+ Consensus(#[from] sp_consensus::Error),
+
+ #[error(transparent)]
+ Service(#[from] sc_service::Error),
+
+ #[error(transparent)]
+ Telemetry(#[from] sc_telemetry::Error),
+
+ #[error("Failed to create an overseer")]
+ Overseer(#[from] polkadot_overseer::SubsystemError),
+
+ #[error(transparent)]
+ Prometheus(#[from] substrate_prometheus_endpoint::PrometheusError),
+
+ #[error("Authorities require the real overseer implementation")]
+ AuthoritiesRequireRealOverseer,
+
+ #[error("Creating a custom database is required for validators")]
+ DatabasePathRequired,
+}
+
type FullClient = sc_service::TFullClient;
type FullBackend = sc_service::TFullBackend;
type FullSelectChain = sc_consensus::LongestChain;
type FullGrandpaBlockImport = sc_finality_grandpa::GrandpaBlockImport;
+type FullTransactionPool = sc_transaction_pool::FullPool;
+type FullBabeBlockImport = sc_consensus_babe::BabeBlockImport;
+type FullBabeLink = sc_consensus_babe::BabeLink;
+type FullGrandpaLink = sc_finality_grandpa::LinkHalf;
+
+/// A set of APIs that polkadot-like runtimes must implement.
+///
+/// This is the copy of `polkadot_service::RuntimeApiCollection` with some APIs removed
+/// (right now - MMR and BEEFY).
+pub trait RequiredApiCollection:
+ sp_transaction_pool::runtime_api::TaggedTransactionQueue
+ + sp_api::ApiExt
+ + sp_consensus_babe::BabeApi
+ + sp_finality_grandpa::GrandpaApi
+ + polkadot_primitives::v1::ParachainHost
+ + sp_block_builder::BlockBuilder
+ + frame_system_rpc_runtime_api::AccountNonceApi
+ + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi
+ + sp_api::Metadata
+ + sp_offchain::OffchainWorkerApi
+ + sp_session::SessionKeys
+ + sp_authority_discovery::AuthorityDiscoveryApi
+where
+ >::StateBackend: sp_api::StateBackend,
+{
+}
+
+impl RequiredApiCollection for Api
+where
+ Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue
+ + sp_api::ApiExt
+ + sp_consensus_babe::BabeApi
+ + sp_finality_grandpa::GrandpaApi
+ + polkadot_primitives::v1::ParachainHost
+ + sp_block_builder::BlockBuilder
+ + frame_system_rpc_runtime_api::AccountNonceApi
+ + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi
+ + sp_api::Metadata
+ + sp_offchain::OffchainWorkerApi
+ + sp_session::SessionKeys
+ + sp_authority_discovery::AuthorityDiscoveryApi,
+ >::StateBackend: sp_api::StateBackend,
+{
+}
+
+// If we're using prometheus, use a registry with a prefix of `polkadot`.
+fn set_prometheus_registry(config: &mut Configuration) -> Result<(), Error> {
+ if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() {
+ *registry = Registry::new_custom(Some("polkadot".into()), None)?;
+ }
+
+ Ok(())
+}
-#[allow(clippy::type_complexity)]
pub fn new_partial(
- config: &Configuration,
+ config: &mut Configuration,
) -> Result<
sc_service::PartialComponents<
FullClient,
FullBackend,
FullSelectChain,
sp_consensus::DefaultImportQueue,
- sc_transaction_pool::FullPool,
+ FullTransactionPool,
(
- FullGrandpaBlockImport,
- sc_finality_grandpa::LinkHalf,
- sc_consensus_babe::BabeBlockImport,
- sc_consensus_babe::BabeLink,
+ impl Fn(
+ sc_rpc::DenyUnsafe,
+ sc_rpc::SubscriptionTaskExecutor,
+ ) -> jsonrpc_core::IoHandler,
+ (FullBabeBlockImport, FullGrandpaLink, FullBabeLink),
+ sc_finality_grandpa::SharedVoterState,
+ std::time::Duration,
Option,
),
>,
- ServiceError,
-> {
- if config.keystore_remote.is_some() {
- return Err(ServiceError::Other("Remote Keystores are not supported.".to_string()));
- }
+ Error,
+>
+where
+ RuntimeApi: ConstructRuntimeApi + Send + Sync + 'static,
+ >::RuntimeApi:
+ RequiredApiCollection>,
+ Executor: NativeExecutionDispatch + 'static,
+{
+ set_prometheus_registry(config)?;
let telemetry = config
.telemetry_endpoints
@@ -110,24 +208,23 @@ pub fn new_partial(
client.clone(),
);
- let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import(
+ let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import_with_authority_set_hard_forks(
client.clone(),
&(client.clone() as Arc<_>),
select_chain.clone(),
+ Vec::new(),
telemetry.as_ref().map(|x| x.handle()),
)?;
let justification_import = grandpa_block_import.clone();
- let (babe_block_import, babe_link) = sc_consensus_babe::block_import(
- sc_consensus_babe::Config::get_or_compute(&*client)?,
- grandpa_block_import.clone(),
- client.clone(),
- )?;
+ let babe_config = sc_consensus_babe::Config::get_or_compute(&*client)?;
+ let (block_import, babe_link) =
+ sc_consensus_babe::block_import(babe_config.clone(), grandpa_block_import, client.clone())?;
let slot_duration = babe_link.config().slot_duration();
let import_queue = sc_consensus_babe::import_queue(
babe_link.clone(),
- babe_block_import.clone(),
+ block_import.clone(),
Some(Box::new(justification_import)),
client.clone(),
select_chain.clone(),
@@ -147,61 +244,203 @@ pub fn new_partial(
telemetry.as_ref().map(|x| x.handle()),
)?;
+ let justification_stream = grandpa_link.justification_stream();
+ let shared_authority_set = grandpa_link.shared_authority_set().clone();
+ let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty();
+
+ let import_setup = (block_import, grandpa_link, babe_link);
+ let rpc_setup = shared_voter_state.clone();
+
+ let slot_duration = babe_config.slot_duration();
+
+ let rpc_extensions_builder = {
+ let client = client.clone();
+ let transaction_pool = transaction_pool.clone();
+ let backend = backend.clone();
+
+ move |deny_unsafe,
+ subscription_executor: sc_rpc::SubscriptionTaskExecutor|
+ -> jsonrpc_core::IoHandler {
+ use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
+ use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler};
+ use substrate_frame_rpc_system::{FullSystem, SystemApi};
+
+ let backend = backend.clone();
+ let client = client.clone();
+ let pool = transaction_pool.clone();
+
+ let shared_voter_state = shared_voter_state.clone();
+
+ let finality_proof_provider =
+ GrandpaFinalityProofProvider::new_for_service(backend, Some(shared_authority_set.clone()));
+
+ let mut io = jsonrpc_core::IoHandler::default();
+ io.extend_with(SystemApi::to_delegate(FullSystem::new(
+ client.clone(),
+ pool,
+ deny_unsafe,
+ )));
+ io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client)));
+ io.extend_with(GrandpaApi::to_delegate(GrandpaRpcHandler::new(
+ shared_authority_set.clone(),
+ shared_voter_state,
+ justification_stream.clone(),
+ subscription_executor,
+ finality_proof_provider,
+ )));
+
+ io
+ }
+ };
+
Ok(sc_service::PartialComponents {
client,
backend,
task_manager,
- import_queue,
keystore_container,
select_chain,
+ import_queue,
transaction_pool,
other: (
- grandpa_block_import,
- grandpa_link,
- babe_block_import,
- babe_link,
+ rpc_extensions_builder,
+ import_setup,
+ rpc_setup,
+ slot_duration,
telemetry,
),
})
}
-fn remote_keystore(_url: &str) -> Result, &'static str> {
- // FIXME: here would the concrete keystore be built,
- // must return a concrete type (NOT `LocalKeystore`) that
- // implements `CryptoStore` and `SyncCryptoStore`
- Err("Remote Keystore not supported.")
+pub struct NewFull {
+ pub task_manager: TaskManager,
+ pub client: C,
+ pub overseer_handler: Option,
+ pub network: Arc::Hash>>,
+ pub rpc_handlers: sc_service::RpcHandlers,
+ pub backend: Arc,
}
-/// Builds a new service for a full client.
-pub fn new_full(mut config: Configuration) -> Result {
+/// The maximum number of active leaves we forward to the [`Overseer`] on startup.
+const MAX_ACTIVE_LEAVES: usize = 4;
+
+/// Returns the active leaves the overseer should start with.
+async fn active_leaves(
+ select_chain: &sc_consensus::LongestChain,
+ client: &FullClient,
+) -> Result, Error>
+where
+ RuntimeApi: ConstructRuntimeApi + Send + Sync + 'static,
+ >::RuntimeApi:
+ RequiredApiCollection>,
+ Executor: NativeExecutionDispatch + 'static,
+{
+ let best_block = select_chain.best_chain().await?;
+
+ let mut leaves = select_chain
+ .leaves()
+ .await
+ .unwrap_or_default()
+ .into_iter()
+ .filter_map(|hash| {
+ let number = client.number(hash).ok()??;
+
+ // Only consider leaves that are in maximum an uncle of the best block.
+ if number < best_block.number().saturating_sub(1) || hash == best_block.hash() {
+ return None;
+ }
+
+ let parent_hash = client.header(&BlockId::Hash(hash)).ok()??.parent_hash;
+
+ Some(BlockInfo {
+ hash,
+ parent_hash,
+ number,
+ })
+ })
+ .collect::>();
+
+ // Sort by block number and get the maximum number of leaves
+ leaves.sort_by_key(|b| b.number);
+
+ leaves.push(BlockInfo {
+ hash: best_block.hash(),
+ parent_hash: *best_block.parent_hash(),
+ number: *best_block.number(),
+ });
+
+ Ok(leaves.into_iter().rev().take(MAX_ACTIVE_LEAVES).collect())
+}
+
+// Create a new full node.
+pub fn new_full(
+ mut config: Configuration,
+ program_path: Option,
+ overseer_gen: impl OverseerGen,
+) -> Result>, Error>
+where
+ RuntimeApi: ConstructRuntimeApi + Send + Sync + 'static,
+ >::RuntimeApi:
+ RequiredApiCollection>,
+ Executor: NativeExecutionDispatch + 'static,
+{
+ let is_collator = false;
+
+ let role = config.role.clone();
+ let force_authoring = config.force_authoring;
+ let backoff_authoring_blocks = Some(sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default());
+
+ let disable_grandpa = config.disable_grandpa;
+ let name = config.network.node_name.clone();
+
let sc_service::PartialComponents {
client,
backend,
mut task_manager,
- import_queue,
- mut keystore_container,
+ keystore_container,
select_chain,
+ import_queue,
transaction_pool,
- other: (_grandpa_block_import, grandpa_link, babe_block_import, babe_link, mut telemetry),
- } = new_partial(&config)?;
+ other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry),
+ } = new_partial(&mut config)?;
- if let Some(url) = &config.keystore_remote {
- match remote_keystore(url) {
- Ok(k) => keystore_container.set_remote_keystore(k),
- Err(e) => {
- return Err(ServiceError::Other(format!(
- "Error hooking up remote keystore for {}: {}",
- url, e
- )))
- }
- };
- }
+ let prometheus_registry = config.prometheus_registry().cloned();
+ let shared_voter_state = rpc_setup;
+ let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht;
+
+ // Note: GrandPa is pushed before the Polkadot-specific protocols. This doesn't change
+ // anything in terms of behaviour, but makes the logs more consistent with the other
+ // Substrate nodes.
config
.network
.extra_sets
.push(sc_finality_grandpa::grandpa_peers_set_config());
+ {
+ use polkadot_network_bridge::{peer_sets_info, IsAuthority};
+ let is_authority = if role.is_authority() {
+ IsAuthority::Yes
+ } else {
+ IsAuthority::No
+ };
+ 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 (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
client: client.clone(),
@@ -213,75 +452,146 @@ pub fn new_full(mut config: Configuration) -> Result
})?;
if config.offchain_worker.enabled {
- sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone());
+ let _ =
+ sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone());
}
- let role = config.role.clone();
- let force_authoring = config.force_authoring;
- let backoff_authoring_blocks: Option<()> = None;
- let name = config.network.node_name.clone();
- let enable_grandpa = !config.disable_grandpa;
- let prometheus_registry = config.prometheus_registry().cloned();
+ let parachains_db = crate::parachains_db::open_creating(
+ config.database.path().ok_or(Error::DatabasePathRequired)?.into(),
+ crate::parachains_db::CacheSizes::default(),
+ )?;
- let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty();
-
- let rpc_extensions_builder = {
- use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
-
- use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
- use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler};
- use sc_rpc::DenyUnsafe;
- use substrate_frame_rpc_system::{FullSystem, SystemApi};
-
- let backend = backend.clone();
- let client = client.clone();
- let pool = transaction_pool.clone();
-
- let justification_stream = grandpa_link.justification_stream();
- let shared_authority_set = grandpa_link.shared_authority_set().clone();
- let shared_voter_state = shared_voter_state.clone();
-
- let finality_proof_provider =
- GrandpaFinalityProofProvider::new_for_service(backend, Some(shared_authority_set.clone()));
-
- Box::new(move |_, subscription_executor| {
- let mut io = jsonrpc_core::IoHandler::default();
- io.extend_with(SystemApi::to_delegate(FullSystem::new(
- client.clone(),
- pool.clone(),
- DenyUnsafe::No,
- )));
- io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(
- client.clone(),
- )));
- io.extend_with(GrandpaApi::to_delegate(GrandpaRpcHandler::new(
- shared_authority_set.clone(),
- shared_voter_state.clone(),
- justification_stream.clone(),
- subscription_executor,
- finality_proof_provider.clone(),
- )));
-
- io
- })
+ let availability_config = AvailabilityConfig {
+ col_data: crate::parachains_db::REAL_COLUMNS.col_availability_data,
+ col_meta: crate::parachains_db::REAL_COLUMNS.col_availability_meta,
};
- let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
- network: network.clone(),
+ let approval_voting_config = ApprovalVotingConfig {
+ col_data: crate::parachains_db::REAL_COLUMNS.col_approval_data,
+ slot_duration_millis: slot_duration.as_millis() as u64,
+ };
+
+ let candidate_validation_config = CandidateValidationConfig {
+ artifacts_cache_path: config
+ .database
+ .path()
+ .ok_or(Error::DatabasePathRequired)?
+ .join("pvf-artifacts"),
+ program_path: match program_path {
+ None => std::env::current_exe()?,
+ Some(p) => p,
+ },
+ };
+
+ let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
+ config,
+ backend: backend.clone(),
client: client.clone(),
keystore: keystore_container.sync_keystore(),
- task_manager: &mut task_manager,
+ network: network.clone(),
+ rpc_extensions_builder: Box::new(rpc_extensions_builder),
transaction_pool: transaction_pool.clone(),
- rpc_extensions_builder,
+ task_manager: &mut task_manager,
on_demand: None,
remote_blockchain: None,
- backend,
system_rpc_tx,
- config,
telemetry: telemetry.as_mut(),
})?;
+ let (block_import, link_half, babe_link) = import_setup;
+
+ let overseer_client = client.clone();
+ let spawner = task_manager.spawn_handle();
+ let active_leaves = futures::executor::block_on(active_leaves(&select_chain, &*client))?;
+
+ let authority_discovery_service = if role.is_authority() || is_collator {
+ use futures::StreamExt;
+ use sc_network::Event;
+
+ let authority_discovery_role = if role.is_authority() {
+ sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore())
+ } else {
+ // don't publish our addresses when we're only a collator
+ sc_authority_discovery::Role::Discover
+ };
+ let dht_event_stream = network.event_stream("authority-discovery").filter_map(|e| async move {
+ match e {
+ Event::Dht(e) => Some(e),
+ _ => None,
+ }
+ });
+ let (worker, service) = sc_authority_discovery::new_worker_and_service_with_config(
+ sc_authority_discovery::WorkerConfig {
+ publish_non_global_ips: auth_disc_publish_non_global_ips,
+ ..Default::default()
+ },
+ client.clone(),
+ network.clone(),
+ Box::pin(dht_event_stream),
+ authority_discovery_role,
+ prometheus_registry.clone(),
+ );
+
+ task_manager
+ .spawn_handle()
+ .spawn("authority-discovery-worker", worker.run());
+ Some(service)
+ } else {
+ None
+ };
+
+ // we'd say let overseer_handler = authority_discovery_service.map(|authority_discovery_service|, ...),
+ // but in that case we couldn't use ? to propagate errors
+ 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) =
+ overseer_gen.generate::(OverseerGenArgs {
+ leaves: active_leaves,
+ keystore,
+ runtime_client: overseer_client.clone(),
+ parachains_db,
+ availability_config,
+ approval_voting_config,
+ network_service: network.clone(),
+ authority_discovery_service,
+ request_multiplexer,
+ registry: prometheus_registry.as_ref(),
+ spawner,
+ candidate_validation_config,
+ })?;
+ let overseer_handler_clone = overseer_handler.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 = forward.fuse();
+ let overseer_fut = overseer.run().fuse();
+
+ pin_mut!(overseer_fut);
+ pin_mut!(forward);
+
+ select! {
+ _ = forward => (),
+ _ = overseer_fut => (),
+ complete => (),
+ }
+ }),
+ );
+
+ Some(overseer_handler)
+ } else {
+ None
+ };
+
if role.is_authority() {
+ let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
+
let proposer = sc_basic_authorship::ProposerFactory::new(
task_manager.spawn_handle(),
client.clone(),
@@ -290,85 +600,118 @@ pub fn new_full(mut config: Configuration) -> Result
telemetry.as_ref().map(|x| x.handle()),
);
- let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
-
+ let client_clone = client.clone();
+ let overseer_handler = overseer_handler
+ .as_ref()
+ .ok_or(Error::AuthoritiesRequireRealOverseer)?
+ .clone();
let slot_duration = babe_link.config().slot_duration();
let babe_config = sc_consensus_babe::BabeParams {
keystore: keystore_container.sync_keystore(),
- client,
+ client: client.clone(),
select_chain,
+ block_import,
env: proposer,
- block_import: babe_block_import,
sync_oracle: network.clone(),
justification_sync_link: network.clone(),
- create_inherent_data_providers: move |_parent, ()| async move {
- let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
+ create_inherent_data_providers: move |parent, ()| {
+ let client_clone = client_clone.clone();
+ let overseer_handler = overseer_handler.clone();
+ async move {
+ let parachain = polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::create(
+ &*client_clone,
+ overseer_handler,
+ parent,
+ )
+ .await
+ .map_err(Box::new)?;
- let slot = sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
- *timestamp,
- slot_duration,
- );
+ let uncles = sc_consensus_uncles::create_uncles_inherent_data_provider(&*client_clone, parent)?;
- Ok((timestamp, slot))
+ let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
+
+ let slot = sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
+ *timestamp,
+ slot_duration,
+ );
+
+ Ok((timestamp, slot, uncles, parachain))
+ }
},
force_authoring,
backoff_authoring_blocks,
babe_link,
can_author_with,
- block_proposal_slot_portion: SlotProportion::new(0.5),
+ block_proposal_slot_portion: sc_consensus_babe::SlotProportion::new(2f32 / 3f32),
max_block_proposal_slot_portion: None,
telemetry: telemetry.as_ref().map(|x| x.handle()),
};
let babe = sc_consensus_babe::start_babe(babe_config)?;
- task_manager
- .spawn_essential_handle()
- .spawn_blocking("babe-proposer", babe);
+ task_manager.spawn_essential_handle().spawn_blocking("babe", babe);
}
// if the node isn't actively participating in consensus then it doesn't
// need a keystore, regardless of which protocol we use below.
- let keystore = if role.is_authority() {
+ let keystore_opt = if role.is_authority() {
Some(keystore_container.sync_keystore())
} else {
None
};
- let grandpa_config = sc_finality_grandpa::Config {
- // FIXME #1578 make this available through chainspec
- gossip_duration: Duration::from_millis(333),
+ let config = sc_finality_grandpa::Config {
+ // FIXME substrate#1578 make this available through chainspec
+ gossip_duration: Duration::from_millis(1000),
justification_period: 512,
name: Some(name),
observer_enabled: false,
- keystore,
+ keystore: keystore_opt,
local_role: role,
telemetry: telemetry.as_ref().map(|x| x.handle()),
};
+ let enable_grandpa = !disable_grandpa;
if enable_grandpa {
// start the full GRANDPA voter
- // NOTE: non-authorities could run the GRANDPA observer protocol, but at
- // this point the full voter should provide better guarantees of block
- // and vote data availability than the observer. The observer has not
- // been tested extensively yet and having most nodes in a network run it
- // could lead to finality stalls.
+ // NOTE: unlike in substrate we are currently running the full
+ // GRANDPA voter protocol for all full nodes (regardless of whether
+ // they're validators or not). at this point the full voter should
+ // provide better guarantees of block and vote data availability than
+ // the observer.
+
+ // add a custom voting rule to temporarily stop voting for new blocks
+ // after the given pause block is finalized and restarting after the
+ // given delay.
+ let builder = sc_finality_grandpa::VotingRulesBuilder::default();
+
+ let voting_rule = builder.build();
let grandpa_config = sc_finality_grandpa::GrandpaParams {
- config: grandpa_config,
- link: grandpa_link,
- network,
- voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),
+ config,
+ link: link_half,
+ network: network.clone(),
+ voting_rule,
prometheus_registry,
shared_voter_state,
telemetry: telemetry.as_ref().map(|x| x.handle()),
};
- // the GRANDPA voter task is considered infallible, i.e.
- // if it fails we take down the service with it.
task_manager
.spawn_essential_handle()
.spawn_blocking("grandpa-voter", sc_finality_grandpa::run_grandpa_voter(grandpa_config)?);
}
network_starter.start_network();
- Ok(task_manager)
+
+ Ok(NewFull {
+ task_manager,
+ client,
+ overseer_handler,
+ network,
+ rpc_handlers,
+ backend,
+ })
+}
+
+pub fn build_full(config: Configuration, overseer_gen: impl OverseerGen) -> Result>, Error> {
+ new_full(config, None, overseer_gen)
}
diff --git a/bridges/bin/rialto/runtime/Cargo.toml b/bridges/bin/rialto/runtime/Cargo.toml
index b6e971eec0..4c0e51ad3c 100644
--- a/bridges/bin/rialto/runtime/Cargo.toml
+++ b/bridges/bin/rialto/runtime/Cargo.toml
@@ -39,6 +39,7 @@ frame-executive = { git = "https://github.com/paritytech/substrate", branch = "m
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-babe = { 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-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -49,6 +50,7 @@ pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "
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 }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+sp-authority-discovery = { 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-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -63,6 +65,11 @@ sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+# Polkadot (parachain) Dependencies
+
+polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false }
+polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false }
+polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false }
[dev-dependencies]
libsecp256k1 = { version = "0.3.4", features = ["hmac"] }
@@ -89,6 +96,7 @@ std = [
"frame-system-rpc-runtime-api/std",
"frame-system/std",
"log/std",
+ "pallet-authority-discovery/std",
"pallet-babe/std",
"pallet-balances/std",
"pallet-bridge-currency-exchange/std",
@@ -103,8 +111,12 @@ std = [
"pallet-timestamp/std",
"pallet-transaction-payment-rpc-runtime-api/std",
"pallet-transaction-payment/std",
+ "polkadot-primitives/std",
+ "polkadot-runtime-common/std",
+ "polkadot-runtime-parachains/std",
"serde",
"sp-api/std",
+ "sp-authority-discovery/std",
"sp-block-builder/std",
"sp-consensus-babe/std",
"sp-core/std",
diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs
index 8b46020a1b..fd3b5c9424 100644
--- a/bridges/bin/rialto/runtime/src/lib.rs
+++ b/bridges/bin/rialto/runtime/src/lib.rs
@@ -36,6 +36,7 @@ pub mod exchange;
pub mod benches;
pub mod kovan;
pub mod millau_messages;
+pub mod parachains;
pub mod rialto_poa;
use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge};
@@ -44,14 +45,15 @@ use bridge_runtime_common::messages::{source::estimate_message_dispatch_and_deli
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use pallet_transaction_payment::{FeeDetails, Multiplier, RuntimeDispatchInfo};
use sp_api::impl_runtime_apis;
+use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
-use sp_runtime::traits::{Block as BlockT, IdentityLookup, NumberFor, OpaqueKeys};
+use sp_runtime::traits::{AccountIdLookup, Block as BlockT, NumberFor, OpaqueKeys};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult, FixedPointNumber, MultiSignature, MultiSigner, Perquintill,
};
-use sp_std::prelude::*;
+use sp_std::{collections::btree_map::BTreeMap, prelude::*};
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
@@ -127,6 +129,9 @@ impl_opaque_keys! {
pub struct SessionKeys {
pub babe: Babe,
pub grandpa: Grandpa,
+ pub para_validator: Initializer,
+ pub para_assignment: SessionInfo,
+ pub authority_discovery: AuthorityDiscovery,
}
}
@@ -168,7 +173,7 @@ impl frame_system::Config for Runtime {
/// 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 = IdentityLookup;
+ type Lookup = AccountIdLookup;
/// The index type for storing how many extrinsics an account has signed.
type Index = Index;
/// The index type for blocks.
@@ -220,7 +225,7 @@ pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
};
parameter_types! {
- pub const EpochDuration: u64 = bp_rialto::time_units::EPOCH_DURATION_IN_SLOTS as u64;
+ pub const EpochDuration: u64 = bp_rialto::EPOCH_DURATION_IN_SLOTS as u64;
pub const ExpectedBlockTime: bp_rialto::Moment = bp_rialto::time_units::MILLISECS_PER_BLOCK;
}
@@ -442,6 +447,8 @@ impl pallet_session::Config for Runtime {
type WeightInfo = ();
}
+impl pallet_authority_discovery::Config for Runtime {}
+
parameter_types! {
/// This is a pretty unscientific cap.
///
@@ -545,6 +552,7 @@ construct_runtime!(
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
// Consensus support.
+ AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config},
Session: pallet_session::{Pallet, Call, Storage, Event, Config},
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event},
ShiftSessionManager: pallet_shift_session_manager::{Pallet},
@@ -560,11 +568,30 @@ construct_runtime!(
BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event},
BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config},
+
+ // Parachain modules.
+ ParachainsOrigin: polkadot_runtime_parachains::origin::{Pallet, Origin},
+ ParachainsConfiguration: 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},
+ 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},
+
+ // Parachain Onboarding Pallets
+ Registrar: polkadot_runtime_common::paras_registrar::{Pallet, Call, Storage, Event},
+ Slots: polkadot_runtime_common::slots::{Pallet, Call, Storage, Event},
+ ParasSudoWrapper: polkadot_runtime_common::paras_sudo_wrapper::{Pallet, Call},
}
);
/// The address format for describing accounts.
-pub type Address = AccountId;
+pub type Address = sp_runtime::MultiAddress;
/// Block header type as expected by this runtime.
pub type Header = generic::Header;
/// Block type as expected by this runtime.
@@ -769,6 +796,95 @@ impl_runtime_apis! {
}
}
+ impl polkadot_primitives::v1::ParachainHost for Runtime {
+ fn validators() -> Vec {
+ polkadot_runtime_parachains::runtime_api_impl::v1::validators::()
+ }
+
+ fn validator_groups() -> (
+ Vec>,
+ polkadot_primitives::v1::GroupRotationInfo,
+ ) {
+ polkadot_runtime_parachains::runtime_api_impl::v1::validator_groups::()
+ }
+
+ fn availability_cores() -> Vec> {
+ polkadot_runtime_parachains::runtime_api_impl::v1::availability_cores::()
+ }
+
+ fn persisted_validation_data(
+ para_id: polkadot_primitives::v1::Id,
+ assumption: polkadot_primitives::v1::OccupiedCoreAssumption,
+ )
+ -> Option> {
+ polkadot_runtime_parachains::runtime_api_impl::v1::persisted_validation_data::(para_id, assumption)
+ }
+
+ fn check_validation_outputs(
+ para_id: polkadot_primitives::v1::Id,
+ outputs: polkadot_primitives::v1::CandidateCommitments,
+ ) -> bool {
+ polkadot_runtime_parachains::runtime_api_impl::v1::check_validation_outputs::(para_id, outputs)
+ }
+
+ fn session_index_for_child() -> polkadot_primitives::v1::SessionIndex {
+ polkadot_runtime_parachains::runtime_api_impl::v1::session_index_for_child::()
+ }
+
+ fn validation_code(
+ para_id: polkadot_primitives::v1::Id,
+ assumption: polkadot_primitives::v1::OccupiedCoreAssumption,
+ )
+ -> Option {
+ polkadot_runtime_parachains::runtime_api_impl::v1::validation_code::(para_id, assumption)
+ }
+
+ fn candidate_pending_availability(
+ para_id: polkadot_primitives::v1::Id,
+ ) -> Option> {
+ polkadot_runtime_parachains::runtime_api_impl::v1::candidate_pending_availability::(para_id)
+ }
+
+ fn candidate_events() -> Vec> {
+ polkadot_runtime_parachains::runtime_api_impl::v1::candidate_events::(|ev| {
+ match ev {
+ Event::Inclusion(ev) => {
+ Some(ev)
+ }
+ _ => None,
+ }
+ })
+ }
+
+ fn session_info(index: polkadot_primitives::v1::SessionIndex) -> Option {
+ polkadot_runtime_parachains::runtime_api_impl::v1::session_info::(index)
+ }
+
+ fn dmq_contents(
+ recipient: polkadot_primitives::v1::Id,
+ ) -> Vec> {
+ polkadot_runtime_parachains::runtime_api_impl::v1::dmq_contents::(recipient)
+ }
+
+ fn inbound_hrmp_channels_contents(
+ recipient: polkadot_primitives::v1::Id
+ ) -> BTreeMap>> {
+ polkadot_runtime_parachains::runtime_api_impl::v1::inbound_hrmp_channels_contents::(recipient)
+ }
+
+ fn validation_code_by_hash(
+ hash: polkadot_primitives::v1::ValidationCodeHash,
+ ) -> Option {
+ polkadot_runtime_parachains::runtime_api_impl::v1::validation_code_by_hash::(hash)
+ }
+ }
+
+ impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime {
+ fn authorities() -> Vec {
+ polkadot_runtime_parachains::runtime_api_impl::v1::relevant_authority_ids::()
+ }
+ }
+
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Block,
Balance,
diff --git a/bridges/bin/rialto/runtime/src/parachains.rs b/bridges/bin/rialto/runtime/src/parachains.rs
new file mode 100644
index 0000000000..47fc6722a1
--- /dev/null
+++ b/bridges/bin/rialto/runtime/src/parachains.rs
@@ -0,0 +1,158 @@
+// 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 .
+
+//! Parachains support in Rialto runtime.
+
+use crate::{
+ AccountId, Balance, Balances, BlockNumber, Event, Origin, RandomnessCollectiveFlip, Registrar, Runtime, Slots,
+};
+
+use frame_support::{parameter_types, weights::Weight};
+use frame_system::EnsureRoot;
+use polkadot_primitives::v1::ValidatorIndex;
+use polkadot_runtime_common::{paras_registrar, paras_sudo_wrapper, slots};
+use polkadot_runtime_parachains::configuration as parachains_configuration;
+use polkadot_runtime_parachains::dmp as parachains_dmp;
+use polkadot_runtime_parachains::hrmp as parachains_hrmp;
+use polkadot_runtime_parachains::inclusion as parachains_inclusion;
+use polkadot_runtime_parachains::initializer as parachains_initializer;
+use polkadot_runtime_parachains::origin as parachains_origin;
+use polkadot_runtime_parachains::paras as parachains_paras;
+use polkadot_runtime_parachains::paras_inherent as parachains_paras_inherent;
+use polkadot_runtime_parachains::scheduler as parachains_scheduler;
+use polkadot_runtime_parachains::session_info as parachains_session_info;
+use polkadot_runtime_parachains::shared as parachains_shared;
+use polkadot_runtime_parachains::ump as parachains_ump;
+
+/// Special `RewardValidators` that does nothing ;)
+pub struct RewardValidators;
+impl polkadot_runtime_parachains::inclusion::RewardValidators for RewardValidators {
+ fn reward_backing(_: impl IntoIterator- ) {}
+ fn reward_bitfields(_: impl IntoIterator
- ) {}
+}
+
+// all required parachain modules from `polkadot-runtime-parachains` crate
+
+impl parachains_configuration::Config for Runtime {}
+
+impl parachains_dmp::Config for Runtime {}
+
+impl parachains_hrmp::Config for Runtime {
+ type Event = Event;
+ type Origin = Origin;
+ type Currency = Balances;
+}
+
+impl parachains_inclusion::Config for Runtime {
+ type Event = Event;
+ type RewardValidators = RewardValidators;
+}
+
+impl parachains_initializer::Config for Runtime {
+ type Randomness = RandomnessCollectiveFlip;
+ type ForceOrigin = EnsureRoot;
+}
+
+impl parachains_origin::Config for Runtime {}
+
+impl parachains_paras::Config for Runtime {
+ type Origin = Origin;
+ type Event = Event;
+}
+
+impl parachains_paras_inherent::Config for Runtime {}
+
+impl parachains_scheduler::Config for Runtime {}
+
+impl parachains_session_info::Config for Runtime {}
+
+impl parachains_shared::Config for Runtime {}
+
+parameter_types! {
+ pub const FirstMessageFactorPercent: u64 = 100;
+}
+
+impl parachains_ump::Config for Runtime {
+ type Event = Event;
+ type UmpSink = ();
+ type FirstMessageFactorPercent = FirstMessageFactorPercent;
+}
+
+// required onboarding pallets. We're not going to use auctions or crowdloans, so they're missing
+
+parameter_types! {
+ pub const ParaDeposit: Balance = 0;
+ pub const DataDepositPerByte: Balance = 0;
+}
+
+impl paras_registrar::Config for Runtime {
+ type Event = Event;
+ type Origin = Origin;
+ type Currency = Balances;
+ type OnSwap = Slots;
+ type ParaDeposit = ParaDeposit;
+ type DataDepositPerByte = DataDepositPerByte;
+ type WeightInfo = paras_registrar::TestWeightInfo;
+}
+
+parameter_types! {
+ pub const LeasePeriod: BlockNumber = 10 * bp_rialto::MINUTES;
+}
+
+impl slots::Config for Runtime {
+ type Event = Event;
+ type Currency = Balances;
+ type Registrar = Registrar;
+ type LeasePeriod = LeasePeriod;
+ type WeightInfo = slots::TestWeightInfo;
+}
+
+impl paras_sudo_wrapper::Config for Runtime {}
+
+pub struct ZeroWeights;
+
+impl polkadot_runtime_common::paras_registrar::WeightInfo for ZeroWeights {
+ fn reserve() -> Weight {
+ 0
+ }
+ fn register() -> Weight {
+ 0
+ }
+ fn force_register() -> Weight {
+ 0
+ }
+ fn deregister() -> Weight {
+ 0
+ }
+ fn swap() -> Weight {
+ 0
+ }
+}
+
+impl polkadot_runtime_common::slots::WeightInfo for ZeroWeights {
+ fn force_lease() -> Weight {
+ 0
+ }
+ fn manage_lease_period_start(_c: u32, _t: u32) -> Weight {
+ 0
+ }
+ fn clear_all_leases() -> Weight {
+ 0
+ }
+ fn trigger_onboard() -> Weight {
+ 0
+ }
+}
diff --git a/bridges/primitives/chain-rialto/src/lib.rs b/bridges/primitives/chain-rialto/src/lib.rs
index b7b382f52b..6ab3431e45 100644
--- a/bridges/primitives/chain-rialto/src/lib.rs
+++ b/bridges/primitives/chain-rialto/src/lib.rs
@@ -42,7 +42,7 @@ pub const EXTRA_STORAGE_PROOF_SIZE: u32 = 1024;
/// Number of bytes, included in the signed Rialto transaction apart from the encoded call itself.
///
/// Can be computed by subtracting encoded call size from raw transaction size.
-pub const TX_EXTRA_BYTES: u32 = 103;
+pub const TX_EXTRA_BYTES: u32 = 104;
/// Maximal size (in bytes) of encoded (using `Encode::encode()`) account id.
pub const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32 = 32;
diff --git a/bridges/relays/bin-substrate/src/chains/rialto.rs b/bridges/relays/bin-substrate/src/chains/rialto.rs
index 995ae7ae0d..2e27342baa 100644
--- a/bridges/relays/bin-substrate/src/chains/rialto.rs
+++ b/bridges/relays/bin-substrate/src/chains/rialto.rs
@@ -40,9 +40,9 @@ impl CliEncodeCall for Rialto {
Call::Remark { remark_payload, .. } => rialto_runtime::Call::System(rialto_runtime::SystemCall::remark(
remark_payload.as_ref().map(|x| x.0.clone()).unwrap_or_default(),
)),
- Call::Transfer { recipient, amount } => {
- rialto_runtime::Call::Balances(rialto_runtime::BalancesCall::transfer(recipient.raw_id(), amount.0))
- }
+ Call::Transfer { recipient, amount } => rialto_runtime::Call::Balances(
+ rialto_runtime::BalancesCall::transfer(recipient.raw_id().into(), amount.0),
+ ),
Call::BridgeSendMessage {
lane,
payload,
diff --git a/bridges/relays/bin-substrate/src/cli/encode_call.rs b/bridges/relays/bin-substrate/src/cli/encode_call.rs
index 343b44c378..d7a9f840b1 100644
--- a/bridges/relays/bin-substrate/src/cli/encode_call.rs
+++ b/bridges/relays/bin-substrate/src/cli/encode_call.rs
@@ -209,7 +209,7 @@ mod tests {
// then
assert_eq!(
format!("{:?}", hex),
- "0x0400d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de5c0"
+ "0x040000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de5c0"
);
}
diff --git a/bridges/relays/client-rialto/src/lib.rs b/bridges/relays/client-rialto/src/lib.rs
index ed0cec314a..f7ba2ca65c 100644
--- a/bridges/relays/client-rialto/src/lib.rs
+++ b/bridges/relays/client-rialto/src/lib.rs
@@ -100,7 +100,7 @@ impl TransactionSignScheme for Rialto {
let signer: sp_runtime::MultiSigner = signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
- rialto_runtime::UncheckedExtrinsic::new_signed(call, signer.into_account(), signature.into(), extra)
+ rialto_runtime::UncheckedExtrinsic::new_signed(call, signer.into_account().into(), signature.into(), extra)
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
@@ -110,7 +110,7 @@ impl TransactionSignScheme for Rialto {
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
- .map(|(address, _, _)| *address == rialto_runtime::Address::from(*signer.public().as_array_ref()))
+ .map(|(address, _, _)| *address == rialto_runtime::Address::Id(signer.public().into()))
.unwrap_or(false)
}