diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock
index d18327a566..194de76604 100644
--- a/polkadot/Cargo.lock
+++ b/polkadot/Cargo.lock
@@ -726,9 +726,12 @@ name = "bp-header-chain"
version = "0.1.0"
dependencies = [
"assert_matches",
+ "bp-runtime",
"bp-test-utils",
"finality-grandpa",
"frame-support",
+ "hex",
+ "hex-literal",
"parity-scale-codec",
"scale-info",
"serde",
@@ -757,10 +760,13 @@ dependencies = [
"bp-runtime",
"frame-support",
"frame-system",
+ "hex",
+ "hex-literal",
"impl-trait-for-tuples",
"parity-scale-codec",
"scale-info",
"serde",
+ "sp-core",
"sp-std",
]
@@ -853,18 +859,23 @@ dependencies = [
"bp-runtime",
"ed25519-dalek",
"frame-support",
+ "frame-system",
"hash-db",
+ "pallet-balances",
"pallet-bridge-dispatch",
"pallet-bridge-grandpa",
"pallet-bridge-messages",
"pallet-transaction-payment",
"parity-scale-codec",
"scale-info",
+ "sp-api",
"sp-core",
"sp-runtime",
"sp-state-machine",
"sp-std",
"sp-trie",
+ "sp-version",
+ "static_assertions",
]
[[package]]
@@ -5256,8 +5267,6 @@ dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
- "hex",
- "hex-literal",
"log",
"num-traits",
"pallet-balances",
diff --git a/polkadot/bridges/.gitlab-ci.yml b/polkadot/bridges/.gitlab-ci.yml
index 0e69a91af1..7d3bf6fd8a 100644
--- a/polkadot/bridges/.gitlab-ci.yml
+++ b/polkadot/bridges/.gitlab-ci.yml
@@ -47,7 +47,7 @@ default:
when:
- runner_system_failure
- unknown_failure
- - api_failure
+ - api_failure
interruptible: true
tags:
- linux-docker
@@ -240,7 +240,14 @@ build-nightly:
elif [[ "${CI_COMMIT_REF_NAME}" ]]; then
VERSION=$(echo ${CI_COMMIT_REF_NAME} | sed -r 's#/+#-#g');
fi
- - echo "Effective tags = ${VERSION} sha-${CI_COMMIT_SHORT_SHA} latest"
+ # When building from version tags (v1.0, v2.1rc1, ...) we'll use "production" to tag
+ # docker image. In all other cases, it'll be "latest".
+ - if [[ $CI_COMMIT_REF_NAME =~ ^v[0-9]+\.[0-9]+.*$ ]]; then
+ FLOATING_TAG="production";
+ else
+ FLOATING_TAG="latest";
+ fi
+ - echo "Effective tags = ${VERSION} sha-${CI_COMMIT_SHORT_SHA} ${FLOATING_TAG}"
secrets:
DOCKER_HUB_USER:
vault: cicd/gitlab/parity/DOCKER_HUB_USER@kv
@@ -260,7 +267,7 @@ build-nightly:
--build-arg VERSION="${VERSION}"
--tag "${IMAGE_NAME}:${VERSION}"
--tag "${IMAGE_NAME}:sha-${CI_COMMIT_SHORT_SHA}"
- --tag "${IMAGE_NAME}:latest"
+ --tag "${IMAGE_NAME}:${FLOATING_TAG}"
--file "${DOCKERFILE}" .
# The job will success only on the protected branch
- echo "${DOCKER_HUB_PASS}" |
@@ -268,7 +275,7 @@ build-nightly:
- buildah info
- buildah push --format=v2s2 "${IMAGE_NAME}:${VERSION}"
- buildah push --format=v2s2 "${IMAGE_NAME}:sha-${CI_COMMIT_SHORT_SHA}"
- - buildah push --format=v2s2 "${IMAGE_NAME}:latest"
+ - buildah push --format=v2s2 "${IMAGE_NAME}:${FLOATING_TAG}"
after_script:
- env REGISTRY_AUTH_FILE= buildah logout --all
diff --git a/polkadot/bridges/.maintain/rialto-weight-template.hbs b/polkadot/bridges/.maintain/rialto-weight-template.hbs
deleted file mode 100644
index cb1b58d23b..0000000000
--- a/polkadot/bridges/.maintain/rialto-weight-template.hbs
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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
-.
-
-//! Autogenerated weights for `{{pallet}}`
-//!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}}
-//! DATE: {{date}}, STEPS: {{cmd.steps}}, REPEAT: {{cmd.repeat}}
-//! LOW RANGE: {{cmd.lowest_range_values}}, HIGH RANGE: {{cmd.highest_range_values}}
-//! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}
-//! CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}}
-
-// Executed Command:
-{{#each args as |arg|~}}
-// {{arg}}
-{{/each}}
-
-#![allow(clippy::all)]
-#![allow(unused_parens)]
-#![allow(unused_imports)]
-
-use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
-use sp_std::marker::PhantomData;
-
-/// Weight functions needed for `{{pallet}}`.
-pub trait WeightInfo {
-{{~#each benchmarks as |benchmark|}}
-fn {{benchmark.name~}}
-(
-{{~#each benchmark.components as |c| ~}}
-{{c.name}}: u32, {{/each~}}
-) -> Weight;
-{{~/each}}
-}
-
-/// Weights for `{{pallet}}` using the Rialto node and recommended hardware.
-pub struct RialtoWeight(PhantomData);
- impl WeightInfo for RialtoWeight {
- {{~#each benchmarks as |benchmark|}}
- fn {{benchmark.name~}}
- (
- {{~#each benchmark.components as |c| ~}}
- {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
- ) -> Weight {
- ({{underscore benchmark.base_weight}} as Weight)
- {{~#each benchmark.component_weight as |cw|}}
- .saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
- {{~/each}}
- {{~#if (ne benchmark.base_reads "0")}}
- .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}} as Weight))
- {{~/if}}
- {{~#each benchmark.component_reads as |cr|}}
- .saturating_add(T::DbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as
- Weight)))
- {{~/each}}
- {{~#if (ne benchmark.base_writes "0")}}
- .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}} as Weight))
- {{~/if}}
- {{~#each benchmark.component_writes as |cw|}}
- .saturating_add(T::DbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as
- Weight)))
- {{~/each}}
- }
- {{~/each}}
- }
-
- // For backwards compatibility and tests
- impl WeightInfo for () {
- {{~#each benchmarks as |benchmark|}}
- fn {{benchmark.name~}}
- (
- {{~#each benchmark.components as |c| ~}}
- {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
- ) -> Weight {
- ({{underscore benchmark.base_weight}} as Weight)
- {{~#each benchmark.component_weight as |cw|}}
- .saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
- {{~/each}}
- {{~#if (ne benchmark.base_reads "0")}}
- .saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}} as Weight))
- {{~/if}}
- {{~#each benchmark.component_reads as |cr|}}
- .saturating_add(RocksDbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as
- Weight)))
- {{~/each}}
- {{~#if (ne benchmark.base_writes "0")}}
- .saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}} as Weight))
- {{~/if}}
- {{~#each benchmark.component_writes as |cw|}}
- .saturating_add(RocksDbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as
- Weight)))
- {{~/each}}
- }
- {{~/each}}
- }
\ No newline at end of file
diff --git a/polkadot/bridges/bin/millau/node/Cargo.toml b/polkadot/bridges/bin/millau/node/Cargo.toml
index c4438d0cef..3825b92b70 100644
--- a/polkadot/bridges/bin/millau/node/Cargo.toml
+++ b/polkadot/bridges/bin/millau/node/Cargo.toml
@@ -3,15 +3,15 @@ name = "millau-bridge-node"
description = "Substrate node compatible with Millau runtime"
version = "0.1.0"
authors = ["Parity Technologies "]
-edition = "2018"
+edition = "2021"
build = "build.rs"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/parity-bridges-common/"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
+clap = { version = "3.1", features = ["derive"] }
jsonrpc-core = "18.0"
-structopt = "0.3.21"
serde_json = "1.0.59"
# Bridge dependencies
diff --git a/polkadot/bridges/bin/millau/node/src/chain_spec.rs b/polkadot/bridges/bin/millau/node/src/chain_spec.rs
index d3d30b151b..a7e3c7c877 100644
--- a/polkadot/bridges/bin/millau/node/src/chain_spec.rs
+++ b/polkadot/bridges/bin/millau/node/src/chain_spec.rs
@@ -88,21 +88,14 @@ impl Alternative {
testnet_genesis(
vec![get_authority_keys_from_seed("Alice")],
get_account_id_from_seed::("Alice"),
- 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"),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Alice"),
- )),
- ],
+ endowed_accounts(),
true,
)
},
vec![],
None,
None,
+ None,
properties,
None,
),
@@ -120,54 +113,14 @@ impl Alternative {
get_authority_keys_from_seed("Eve"),
],
get_account_id_from_seed::("Alice"),
- 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::("George"),
- get_account_id_from_seed::("Harry"),
- 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"),
- get_account_id_from_seed::("George//stash"),
- get_account_id_from_seed::("Harry//stash"),
- get_account_id_from_seed::("RialtoMessagesOwner"),
- get_account_id_from_seed::("WithRialtoTokenSwap"),
- pallet_bridge_messages::relayer_fund_account_id::<
- bp_millau::AccountId,
- bp_millau::AccountIdConverter,
- >(),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Alice"),
- )),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Bob"),
- )),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Charlie"),
- )),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Dave"),
- )),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Eve"),
- )),
- derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
- get_account_id_from_seed::("Ferdie"),
- )),
- ],
+ endowed_accounts(),
true,
)
},
vec![],
None,
None,
+ None,
properties,
None,
),
@@ -175,6 +128,55 @@ impl Alternative {
}
}
+/// We're using the same set of endowed accounts on all Millau chains (dev/local) to make
+/// sure that all accounts, required for bridge to be functional (e.g. relayers fund account,
+/// accounts used by relayers in our test deployments, accounts used for demonstration
+/// purposes), are all available on these chains.
+fn endowed_accounts() -> Vec {
+ 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::("George"),
+ get_account_id_from_seed::("Harry"),
+ 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"),
+ get_account_id_from_seed::("George//stash"),
+ get_account_id_from_seed::("Harry//stash"),
+ get_account_id_from_seed::("RialtoMessagesOwner"),
+ get_account_id_from_seed::("WithRialtoTokenSwap"),
+ pallet_bridge_messages::relayer_fund_account_id::<
+ bp_millau::AccountId,
+ bp_millau::AccountIdConverter,
+ >(),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Alice"),
+ )),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Bob"),
+ )),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Charlie"),
+ )),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Dave"),
+ )),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Eve"),
+ )),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Ferdie"),
+ )),
+ ]
+}
+
fn session_keys(aura: AuraId, beefy: BeefyId, grandpa: GrandpaId) -> SessionKeys {
SessionKeys { aura, beefy, grandpa }
}
diff --git a/polkadot/bridges/bin/millau/node/src/cli.rs b/polkadot/bridges/bin/millau/node/src/cli.rs
index 086def633c..c3c3d134e3 100644
--- a/polkadot/bridges/bin/millau/node/src/cli.rs
+++ b/polkadot/bridges/bin/millau/node/src/cli.rs
@@ -14,10 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
+use clap::Parser;
use sc_cli::RunCmd;
-use structopt::StructOpt;
-#[derive(Debug, StructOpt)]
+#[derive(Debug, Parser)]
pub struct Cli {
#[structopt(subcommand)]
pub subcommand: Option,
@@ -27,9 +27,10 @@ pub struct Cli {
}
/// Possible subcommands of the main binary.
-#[derive(Debug, StructOpt)]
+#[derive(Debug, Parser)]
pub enum Subcommand {
/// Key management CLI utilities
+ #[clap(subcommand)]
Key(sc_cli::KeySubcommand),
/// Verify a signature for a message, provided on `STDIN`, with a given (public or secret) key.
diff --git a/polkadot/bridges/bin/millau/node/src/service.rs b/polkadot/bridges/bin/millau/node/src/service.rs
index 1fc7584d0a..15f88269aa 100644
--- a/polkadot/bridges/bin/millau/node/src/service.rs
+++ b/polkadot/bridges/bin/millau/node/src/service.rs
@@ -30,14 +30,13 @@
// =====================================================================================
use millau_runtime::{self, opaque::Block, RuntimeApi};
-use sc_client_api::ExecutorProvider;
+use sc_client_api::{BlockBackend, ExecutorProvider};
use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams};
pub use sc_executor::NativeElseWasmExecutor;
use sc_finality_grandpa::SharedVoterState;
use sc_keystore::LocalKeystore;
use sc_service::{error::Error as ServiceError, Configuration, TaskManager};
use sc_telemetry::{Telemetry, TelemetryWorker};
-use sp_consensus::SlotData;
use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;
use std::{sync::Arc, time::Duration};
@@ -66,6 +65,7 @@ type FullClient =
type FullBackend = sc_service::TFullBackend;
type FullSelectChain = sc_consensus::LongestChain;
+#[allow(clippy::type_complexity)]
pub fn new_partial(
config: &Configuration,
) -> Result<
@@ -89,7 +89,7 @@ pub fn new_partial(
ServiceError,
> {
if config.keystore_remote.is_some() {
- return Err(ServiceError::Other(format!("Remote Keystores are not supported.")))
+ return Err(ServiceError::Other("Remote Keystores are not supported.".into()))
}
let telemetry = config
@@ -112,7 +112,7 @@ pub fn new_partial(
let (client, backend, keystore_container, task_manager) =
sc_service::new_full_parts::(
- &config,
+ config,
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
executor,
)?;
@@ -140,7 +140,7 @@ pub fn new_partial(
telemetry.as_ref().map(|x| x.handle()),
)?;
- let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration();
+ let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
let import_queue =
sc_consensus_aura::import_queue::(ImportQueueParams {
@@ -151,7 +151,7 @@ pub fn new_partial(
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
let slot =
- sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
+ sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
*timestamp,
slot_duration,
);
@@ -179,7 +179,7 @@ pub fn new_partial(
})
}
-fn remote_keystore(_url: &String) -> Result, &'static str> {
+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`
@@ -210,8 +210,27 @@ pub fn new_full(mut config: Configuration) -> Result
};
}
- config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());
- config.network.extra_sets.push(beefy_gadget::beefy_peers_set_config());
+ // 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.
+ let grandpa_protocol_name = sc_finality_grandpa::protocol_standard_name(
+ &client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"),
+ &config.chain_spec,
+ );
+ config
+ .network
+ .extra_sets
+ .push(sc_finality_grandpa::grandpa_peers_set_config(grandpa_protocol_name.clone()));
+
+ let beefy_protocol_name = beefy_gadget::protocol_standard_name(
+ &client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"),
+ &config.chain_spec,
+ );
+ config
+ .network
+ .extra_sets
+ .push(beefy_gadget::beefy_peers_set_config(beefy_protocol_name.clone()));
+
let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new(
backend.clone(),
grandpa_link.shared_authority_set().clone(),
@@ -245,8 +264,10 @@ pub fn new_full(mut config: Configuration) -> Result
let enable_grandpa = !config.disable_grandpa;
let prometheus_registry = config.prometheus_registry().cloned();
let shared_voter_state = SharedVoterState::empty();
- let (signed_commitment_sender, signed_commitment_stream) =
- beefy_gadget::notification::BeefySignedCommitmentStream::channel();
+ let (beefy_commitment_link, beefy_commitment_stream) =
+ beefy_gadget::notification::BeefySignedCommitmentStream::::channel();
+ let (beefy_best_block_link, beefy_best_block_stream) =
+ beefy_gadget::notification::BeefyBestBlockStream::::channel();
let rpc_extensions_builder = {
use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
@@ -287,10 +308,12 @@ pub fn new_full(mut config: Configuration) -> Result
finality_proof_provider.clone(),
)));
io.extend_with(beefy_gadget_rpc::BeefyApi::to_delegate(
- beefy_gadget_rpc::BeefyRpcHandler::new(
- signed_commitment_stream.clone(),
+ beefy_gadget_rpc::BeefyRpcHandler::::new(
+ beefy_commitment_stream.clone(),
+ beefy_best_block_stream.clone(),
subscription_executor,
- ),
+ )
+ .map_err(|e| sc_service::Error::Other(format!("{}", e)))?,
));
io.extend_with(pallet_mmr_rpc::MmrApi::to_delegate(pallet_mmr_rpc::Mmr::new(
client.clone(),
@@ -325,7 +348,6 @@ pub fn new_full(mut config: Configuration) -> Result
sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
- let raw_slot_duration = slot_duration.slot_duration();
let aura = sc_consensus_aura::start_aura::(
StartAuraParams {
@@ -338,9 +360,9 @@ pub fn new_full(mut config: Configuration) -> Result
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
let slot =
- sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
+ sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
*timestamp,
- raw_slot_duration,
+ slot_duration,
);
Ok((timestamp, slot))
@@ -374,9 +396,11 @@ pub fn new_full(mut config: Configuration) -> Result
backend,
key_store: keystore.clone(),
network: network.clone(),
- signed_commitment_sender,
+ signed_commitment_sender: beefy_commitment_link,
+ beefy_best_block_sender: beefy_best_block_link,
min_block_delta: 4,
prometheus_registry: prometheus_registry.clone(),
+ protocol_name: beefy_protocol_name,
};
// Start the BEEFY bridge gadget.
@@ -395,6 +419,7 @@ pub fn new_full(mut config: Configuration) -> Result
keystore,
local_role: role,
telemetry: telemetry.as_ref().map(|x| x.handle()),
+ protocol_name: grandpa_protocol_name,
};
if enable_grandpa {
diff --git a/polkadot/bridges/bin/millau/runtime/Cargo.toml b/polkadot/bridges/bin/millau/runtime/Cargo.toml
index 13195b9519..162404b77e 100644
--- a/polkadot/bridges/bin/millau/runtime/Cargo.toml
+++ b/polkadot/bridges/bin/millau/runtime/Cargo.toml
@@ -2,20 +2,22 @@
name = "millau-runtime"
version = "0.1.0"
authors = ["Parity Technologies "]
-edition = "2018"
+edition = "2021"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/parity-bridges-common/"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
hex-literal = "0.3"
-codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive"] }
-scale-info = { version = "1.0", default-features = false, features = ["derive"] }
+codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
+libsecp256k1 = { version = "0.7", optional = true, default-features = false, features = ["hmac"] }
+scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
serde = { version = "1.0", optional = true, features = ["derive"] }
# Bridge dependencies
bp-header-chain = { path = "../../../primitives/header-chain", default-features = false }
+bp-message-dispatch = { path = "../../../primitives/message-dispatch", default-features = false }
bp-messages = { path = "../../../primitives/messages", default-features = false }
bp-millau = { path = "../../../primitives/chain-millau", default-features = false }
bp-rialto = { path = "../../../primitives/chain-rialto", default-features = false }
@@ -63,6 +65,10 @@ 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 }
+[dev-dependencies]
+bridge-runtime-common = { path = "../../runtime-common", features = ["integrity-test"] }
+static_assertions = "1.1"
+
[build-dependencies]
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -71,6 +77,7 @@ default = ["std"]
std = [
"beefy-primitives/std",
"bp-header-chain/std",
+ "bp-message-dispatch/std",
"bp-messages/std",
"bp-millau/std",
"bp-rialto/std",
@@ -116,8 +123,12 @@ std = [
"sp-version/std",
]
runtime-benchmarks = [
- "frame-benchmarking",
+ "bridge-runtime-common/runtime-benchmarks",
+ "frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
+ "libsecp256k1",
+ "pallet-bridge-messages/runtime-benchmarks",
"pallet-bridge-token-swap/runtime-benchmarks",
+ "sp-runtime/runtime-benchmarks",
]
diff --git a/polkadot/bridges/bin/millau/runtime/src/lib.rs b/polkadot/bridges/bin/millau/runtime/src/lib.rs
index 97fe4d49bc..810a4572e6 100644
--- a/polkadot/bridges/bin/millau/runtime/src/lib.rs
+++ b/polkadot/bridges/bin/millau/runtime/src/lib.rs
@@ -50,7 +50,7 @@ use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{Block as BlockT, IdentityLookup, Keccak256, NumberFor, OpaqueKeys},
transaction_validity::{TransactionSource, TransactionValidity},
- ApplyExtrinsicResult, FixedPointNumber, MultiSignature, MultiSigner, Perquintill,
+ ApplyExtrinsicResult, FixedPointNumber, FixedU128, MultiSignature, MultiSigner, Perquintill,
};
use sp_std::prelude::*;
#[cfg(feature = "std")]
@@ -136,6 +136,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
+ state_version: 0,
};
/// The version information used to identify this runtime when compiled natively.
@@ -373,12 +374,26 @@ parameter_types! {
// Note that once this is hit the pallet will essentially throttle incoming requests down to one
// call per block.
pub const MaxRequests: u32 = 50;
+}
- // Number of headers to keep.
- //
- // Assuming the worst case of every header being finalized, we will keep headers for at least a
- // week.
- pub const HeadersToKeep: u32 = 7 * bp_millau::DAYS as u32;
+#[cfg(feature = "runtime-benchmarks")]
+parameter_types! {
+ /// Number of headers to keep in benchmarks.
+ ///
+ /// In benchmarks we always populate with full number of `HeadersToKeep` to make sure that
+ /// pruning is taken into account.
+ ///
+ /// Note: This is lower than regular value, to speed up benchmarking setup.
+ pub const HeadersToKeep: u32 = 1024;
+}
+
+#[cfg(not(feature = "runtime-benchmarks"))]
+parameter_types! {
+ /// Number of headers to keep.
+ ///
+ /// Assuming the worst case of every header being finalized, we will keep headers at least for a
+ /// week.
+ pub const HeadersToKeep: u32 = 7 * bp_rialto::DAYS as u32;
}
pub type RialtoGrandpaInstance = ();
@@ -387,8 +402,7 @@ impl pallet_bridge_grandpa::Config for Runtime {
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
- // TODO [#391]: Use weights generated for the Millau runtime instead of Rialto ones.
- type WeightInfo = pallet_bridge_grandpa::weights::RialtoWeight;
+ type WeightInfo = pallet_bridge_grandpa::weights::MillauWeight;
}
pub type WestendGrandpaInstance = pallet_bridge_grandpa::Instance1;
@@ -397,8 +411,7 @@ impl pallet_bridge_grandpa::Config for Runtime {
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
- // TODO [#391]: Use weights generated for the Millau runtime instead of Rialto ones.
- type WeightInfo = pallet_bridge_grandpa::weights::RialtoWeight;
+ type WeightInfo = pallet_bridge_grandpa::weights::MillauWeight;
}
impl pallet_shift_session_manager::Config for Runtime {}
@@ -406,9 +419,9 @@ impl pallet_shift_session_manager::Config for Runtime {}
parameter_types! {
pub const MaxMessagesToPruneAtOnce: bp_messages::MessageNonce = 8;
pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce =
- bp_millau::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE;
+ bp_rialto::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce =
- bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE;
+ bp_rialto::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
// `IdentityFee` is used by Millau => we may use weight directly
pub const GetDeliveryConfirmationTransactionFee: Balance =
bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT as _;
@@ -421,8 +434,7 @@ pub type WithRialtoMessagesInstance = ();
impl pallet_bridge_messages::Config for Runtime {
type Event = Event;
- // TODO: https://github.com/paritytech/parity-bridges-common/issues/390
- type WeightInfo = pallet_bridge_messages::weights::RialtoWeight;
+ type WeightInfo = pallet_bridge_messages::weights::MillauWeight;
type Parameter = rialto_messages::MillauToRialtoMessagesParameter;
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
@@ -442,10 +454,9 @@ impl pallet_bridge_messages::Config for Runtime {
type MessageDeliveryAndDispatchPayment =
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
Runtime,
- (),
+ WithRialtoMessagesInstance,
pallet_balances::Pallet,
GetDeliveryConfirmationTransactionFee,
- RootAccountForPayments,
>;
type OnMessageAccepted = ();
type OnDeliveryConfirmed =
@@ -511,7 +522,7 @@ construct_runtime!(
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event},
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config},
- BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event},
+ BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event, Origin},
// Westend bridge modules.
BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Config, Storage},
@@ -551,7 +562,7 @@ pub type Executive = frame_executive::Executive<
Block,
frame_system::ChainContext,
Runtime,
- AllPallets,
+ AllPalletsWithSystem,
>;
#[cfg(feature = "runtime-benchmarks")]
@@ -664,7 +675,7 @@ impl_runtime_apis! {
}
impl beefy_primitives::BeefyApi for Runtime {
- fn validator_set() -> ValidatorSet {
+ fn validator_set() -> Option> {
Beefy::validator_set()
}
}
@@ -742,10 +753,6 @@ impl_runtime_apis! {
let header = BridgeRialtoGrandpa::best_finalized();
(header.number, header.hash())
}
-
- fn is_known_header(hash: bp_rialto::Hash) -> bool {
- BridgeRialtoGrandpa::is_known_header(hash)
- }
}
impl bp_westend::WestendFinalityApi for Runtime {
@@ -753,20 +760,18 @@ impl_runtime_apis! {
let header = BridgeWestendGrandpa::best_finalized();
(header.number, header.hash())
}
-
- fn is_known_header(hash: bp_westend::Hash) -> bool {
- BridgeWestendGrandpa::is_known_header(hash)
- }
}
impl bp_rialto::ToRialtoOutboundLaneApi for Runtime {
fn estimate_message_delivery_and_dispatch_fee(
_lane_id: bp_messages::LaneId,
payload: ToRialtoMessagePayload,
+ rialto_to_this_conversion_rate: Option,
) -> Option {
estimate_message_dispatch_and_delivery_fee::(
&payload,
WithRialtoMessageBridge::RELAYER_FEE_PERCENT,
+ rialto_to_this_conversion_rate,
).ok()
}
@@ -781,28 +786,6 @@ impl_runtime_apis! {
WithRialtoMessageBridge,
>(lane, begin, end)
}
-
- fn latest_received_nonce(lane: bp_messages::LaneId) -> bp_messages::MessageNonce {
- BridgeRialtoMessages::outbound_latest_received_nonce(lane)
- }
-
- fn latest_generated_nonce(lane: bp_messages::LaneId) -> bp_messages::MessageNonce {
- BridgeRialtoMessages::outbound_latest_generated_nonce(lane)
- }
- }
-
- impl bp_rialto::FromRialtoInboundLaneApi for Runtime {
- fn latest_received_nonce(lane: bp_messages::LaneId) -> bp_messages::MessageNonce {
- BridgeRialtoMessages::inbound_latest_received_nonce(lane)
- }
-
- fn latest_confirmed_nonce(lane: bp_messages::LaneId) -> bp_messages::MessageNonce {
- BridgeRialtoMessages::inbound_latest_confirmed_nonce(lane)
- }
-
- fn unrewarded_relayers_state(lane: bp_messages::LaneId) -> bp_messages::UnrewardedRelayersState {
- BridgeRialtoMessages::inbound_unrewarded_relayers_state(lane)
- }
}
#[cfg(feature = "runtime-benchmarks")]
@@ -814,8 +797,13 @@ impl_runtime_apis! {
use frame_benchmarking::{Benchmarking, BenchmarkList};
use frame_support::traits::StorageInfoTrait;
+ use pallet_bridge_messages::benchmarking::Pallet as MessagesBench;
+
let mut list = Vec::::new();
- list_benchmarks!(list, extra);
+
+ list_benchmark!(list, extra, pallet_bridge_token_swap, BridgeRialtoTokenSwap);
+ list_benchmark!(list, extra, pallet_bridge_messages, MessagesBench::);
+ list_benchmark!(list, extra, pallet_bridge_grandpa, BridgeRialtoGrandpa);
let storage_info = AllPalletsWithSystem::storage_info();
return (list, storage_info)
@@ -842,6 +830,74 @@ impl_runtime_apis! {
let mut batches = Vec::::new();
let params = (&config, &whitelist);
+ use bridge_runtime_common::messages_benchmarking::{prepare_message_delivery_proof, prepare_message_proof, prepare_outbound_message};
+ use bridge_runtime_common::messages;
+ use pallet_bridge_messages::benchmarking::{
+ Pallet as MessagesBench,
+ Config as MessagesConfig,
+ MessageDeliveryProofParams,
+ MessageParams,
+ MessageProofParams,
+ };
+ use rialto_messages::WithRialtoMessageBridge;
+
+ impl MessagesConfig for Runtime {
+ fn maximal_message_size() -> u32 {
+ messages::source::maximal_message_size::()
+ }
+
+ fn bridged_relayer_id() -> Self::InboundRelayer {
+ [0u8; 32].into()
+ }
+
+ fn account_balance(account: &Self::AccountId) -> Self::OutboundMessageFee {
+ pallet_balances::Pallet::::free_balance(account)
+ }
+
+ fn endow_account(account: &Self::AccountId) {
+ pallet_balances::Pallet::::make_free_balance_be(
+ account,
+ Balance::MAX / 100,
+ );
+ }
+
+ fn prepare_outbound_message(
+ params: MessageParams,
+ ) -> (rialto_messages::ToRialtoMessagePayload, Balance) {
+ (prepare_outbound_message::(params), Self::message_fee())
+ }
+
+ fn prepare_message_proof(
+ params: MessageProofParams,
+ ) -> (rialto_messages::FromRialtoMessagesProof, Weight) {
+ prepare_message_proof::(
+ params,
+ &VERSION,
+ Balance::MAX / 100,
+ )
+ }
+
+ fn prepare_message_delivery_proof(
+ params: MessageDeliveryProofParams,
+ ) -> rialto_messages::ToRialtoMessagesDeliveryProof {
+ prepare_message_delivery_proof::(
+ params,
+ )
+ }
+
+ fn is_message_dispatched(nonce: bp_messages::MessageNonce) -> bool {
+ frame_system::Pallet::::events()
+ .into_iter()
+ .map(|event_record| event_record.event)
+ .any(|event| matches!(
+ event,
+ Event::BridgeDispatch(pallet_bridge_dispatch::Event::::MessageDispatched(
+ _, ([0, 0, 0, 0], nonce_from_event), _,
+ )) if nonce_from_event == nonce
+ ))
+ }
+ }
+
use pallet_bridge_token_swap::benchmarking::Config as TokenSwapConfig;
impl TokenSwapConfig for Runtime {
@@ -857,9 +913,15 @@ impl_runtime_apis! {
}
}
- add_benchmarks!(params, batches);
+ add_benchmark!(
+ params,
+ batches,
+ pallet_bridge_messages,
+ MessagesBench::
+ );
+ add_benchmark!(params, batches, pallet_bridge_grandpa, BridgeRialtoGrandpa);
+ add_benchmark!(params, batches, pallet_bridge_token_swap, BridgeRialtoTokenSwap);
- if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
Ok(batches)
}
}
@@ -892,52 +954,18 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use bridge_runtime_common::messages;
-
- #[test]
- fn ensure_millau_message_lane_weights_are_correct() {
- // TODO: https://github.com/paritytech/parity-bridges-common/issues/390
- type Weights = pallet_bridge_messages::weights::RialtoWeight;
-
- pallet_bridge_messages::ensure_weights_are_correct::(
- bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT,
- bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT,
- bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
- bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT,
- DbWeight::get(),
- );
-
- let max_incoming_message_proof_size = bp_rialto::EXTRA_STORAGE_PROOF_SIZE.saturating_add(
- messages::target::maximal_incoming_message_size(bp_millau::max_extrinsic_size()),
- );
- pallet_bridge_messages::ensure_able_to_receive_message::(
- bp_millau::max_extrinsic_size(),
- bp_millau::max_extrinsic_weight(),
- max_incoming_message_proof_size,
- messages::target::maximal_incoming_message_dispatch_weight(
- bp_millau::max_extrinsic_weight(),
- ),
- );
-
- let max_incoming_inbound_lane_data_proof_size =
- bp_messages::InboundLaneData::<()>::encoded_size_hint(
- bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
- bp_rialto::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _,
- bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _,
- )
- .unwrap_or(u32::MAX);
- pallet_bridge_messages::ensure_able_to_receive_confirmation::(
- bp_millau::max_extrinsic_size(),
- bp_millau::max_extrinsic_weight(),
- max_incoming_inbound_lane_data_proof_size,
- bp_rialto::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
- bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
- DbWeight::get(),
- );
- }
#[test]
fn call_size() {
+ const BRIDGES_PALLETS_MAX_CALL_SIZE: usize = 200;
+ assert!(
+ core::mem::size_of::>() <=
+ BRIDGES_PALLETS_MAX_CALL_SIZE
+ );
+ assert!(
+ core::mem::size_of::>() <=
+ BRIDGES_PALLETS_MAX_CALL_SIZE
+ );
const MAX_CALL_SIZE: usize = 230; // value from polkadot-runtime tests
assert!(core::mem::size_of::() <= MAX_CALL_SIZE);
}
diff --git a/polkadot/bridges/bin/millau/runtime/src/rialto_messages.rs b/polkadot/bridges/bin/millau/runtime/src/rialto_messages.rs
index 6d9677c45c..d925d805dd 100644
--- a/polkadot/bridges/bin/millau/runtime/src/rialto_messages.rs
+++ b/polkadot/bridges/bin/millau/runtime/src/rialto_messages.rs
@@ -19,11 +19,11 @@
use crate::Runtime;
use bp_messages::{
- source_chain::TargetHeaderChain,
+ source_chain::{SenderOrigin, TargetHeaderChain},
target_chain::{ProvedMessages, SourceHeaderChain},
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
};
-use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID};
+use bp_runtime::{Chain, ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID};
use bridge_runtime_common::messages::{self, MessageBridge, MessageTransaction};
use codec::{Decode, Encode};
use frame_support::{
@@ -64,10 +64,10 @@ pub type FromRialtoMessagePayload =
pub type FromRialtoEncodedCall = messages::target::FromBridgedChainEncodedMessageCall;
/// Messages proof for Rialto -> Millau messages.
-type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof;
+pub type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof;
/// Messages delivery proof for Millau -> Rialto messages.
-type ToRialtoMessagesDeliveryProof =
+pub type ToRialtoMessagesDeliveryProof =
messages::source::FromBridgedChainMessagesDeliveryProof;
/// Call-dispatch based message dispatch for Rialto -> Millau messages.
@@ -86,16 +86,19 @@ impl MessageBridge for WithRialtoMessageBridge {
const RELAYER_FEE_PERCENT: u32 = 10;
const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID;
const BRIDGED_CHAIN_ID: ChainId = RIALTO_CHAIN_ID;
- const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_rialto::WITH_MILLAU_MESSAGES_PALLET_NAME;
+ const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME;
type ThisChain = Millau;
type BridgedChain = Rialto;
- fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance {
- bp_millau::Balance::try_from(
- RialtoToMillauConversionRate::get().saturating_mul_int(bridged_balance),
- )
- .unwrap_or(bp_millau::Balance::MAX)
+ fn bridged_balance_to_this_balance(
+ bridged_balance: bp_rialto::Balance,
+ bridged_to_this_conversion_rate_override: Option,
+ ) -> bp_millau::Balance {
+ let conversion_rate = bridged_to_this_conversion_rate_override
+ .unwrap_or_else(|| RialtoToMillauConversionRate::get());
+ bp_millau::Balance::try_from(conversion_rate.saturating_mul_int(bridged_balance))
+ .unwrap_or(bp_millau::Balance::MAX)
}
}
@@ -113,12 +116,23 @@ impl messages::ChainWithMessages for Millau {
}
impl messages::ThisChainWithMessages for Millau {
+ type Origin = crate::Origin;
type Call = crate::Call;
- fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
- *lane == [0, 0, 0, 0] ||
- *lane == [0, 0, 0, 1] ||
- *lane == crate::TokenSwapMessagesLane::get()
+ fn is_message_accepted(send_origin: &Self::Origin, lane: &LaneId) -> bool {
+ // lanes 0x00000000 && 0x00000001 are accepting any paid messages, while
+ // `TokenSwapMessageLane` only accepts messages from token swap pallet
+ let token_swap_dedicated_lane = crate::TokenSwapMessagesLane::get();
+ match *lane {
+ [0, 0, 0, 0] | [0, 0, 0, 1] => send_origin.linked_account().is_some(),
+ _ if *lane == token_swap_dedicated_lane => matches!(
+ send_origin.caller,
+ crate::OriginCaller::BridgeRialtoTokenSwap(
+ pallet_bridge_token_swap::RawOrigin::TokenSwap { .. }
+ )
+ ),
+ _ => false,
+ }
}
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
@@ -172,13 +186,13 @@ impl messages::ChainWithMessages for Rialto {
impl messages::BridgedChainWithMessages for Rialto {
fn maximal_extrinsic_size() -> u32 {
- bp_rialto::max_extrinsic_size()
+ bp_rialto::Rialto::max_extrinsic_size()
}
fn message_weight_limits(_message_payload: &[u8]) -> RangeInclusive {
// we don't want to relay too large messages + keep reserve for future upgrades
let upper_limit = messages::target::maximal_incoming_message_dispatch_weight(
- bp_rialto::max_extrinsic_weight(),
+ bp_rialto::Rialto::max_extrinsic_weight(),
);
// we're charging for payload bytes in `WithRialtoMessageBridge::transaction_payment`
@@ -274,6 +288,25 @@ impl SourceHeaderChain for Rialto {
}
}
+impl SenderOrigin for crate::Origin {
+ fn linked_account(&self) -> Option {
+ match self.caller {
+ crate::OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) =>
+ Some(submitter.clone()),
+ crate::OriginCaller::system(frame_system::RawOrigin::Root) |
+ crate::OriginCaller::system(frame_system::RawOrigin::None) =>
+ crate::RootAccountForPayments::get(),
+ crate::OriginCaller::BridgeRialtoTokenSwap(
+ pallet_bridge_token_swap::RawOrigin::TokenSwap {
+ ref swap_account_at_this_chain,
+ ..
+ },
+ ) => Some(swap_account_at_this_chain.clone()),
+ _ => None,
+ }
+ }
+}
+
/// Millau -> Rialto message lane pallet parameters.
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)]
pub enum MillauToRialtoMessagesParameter {
@@ -289,3 +322,107 @@ impl MessagesParameter for MillauToRialtoMessagesParameter {
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::{DbWeight, RialtoGrandpaInstance, Runtime, WithRialtoMessagesInstance};
+
+ use bp_runtime::Chain;
+ use bridge_runtime_common::{
+ assert_complete_bridge_types,
+ integrity::{
+ assert_complete_bridge_constants, AssertBridgeMessagesPalletConstants,
+ AssertBridgePalletNames, AssertChainConstants, AssertCompleteBridgeConstants,
+ },
+ messages,
+ };
+
+ #[test]
+ fn ensure_millau_message_lane_weights_are_correct() {
+ type Weights = pallet_bridge_messages::weights::MillauWeight;
+
+ pallet_bridge_messages::ensure_weights_are_correct::(
+ bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT,
+ bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT,
+ bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
+ bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT,
+ DbWeight::get(),
+ );
+
+ let max_incoming_message_proof_size = bp_rialto::EXTRA_STORAGE_PROOF_SIZE.saturating_add(
+ messages::target::maximal_incoming_message_size(bp_millau::Millau::max_extrinsic_size()),
+ );
+ pallet_bridge_messages::ensure_able_to_receive_message::(
+ bp_millau::Millau::max_extrinsic_size(),
+ bp_millau::Millau::max_extrinsic_weight(),
+ max_incoming_message_proof_size,
+ messages::target::maximal_incoming_message_dispatch_weight(
+ bp_millau::Millau::max_extrinsic_weight(),
+ ),
+ );
+
+ let max_incoming_inbound_lane_data_proof_size =
+ bp_messages::InboundLaneData::<()>::encoded_size_hint(
+ bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
+ bp_millau::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as _,
+ bp_millau::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX as _,
+ )
+ .unwrap_or(u32::MAX);
+ pallet_bridge_messages::ensure_able_to_receive_confirmation::(
+ bp_millau::Millau::max_extrinsic_size(),
+ bp_millau::Millau::max_extrinsic_weight(),
+ max_incoming_inbound_lane_data_proof_size,
+ bp_millau::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
+ bp_millau::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
+ DbWeight::get(),
+ );
+ }
+
+ #[test]
+ fn ensure_bridge_integrity() {
+ assert_complete_bridge_types!(
+ runtime: Runtime,
+ with_bridged_chain_grandpa_instance: RialtoGrandpaInstance,
+ with_bridged_chain_messages_instance: WithRialtoMessagesInstance,
+ bridge: WithRialtoMessageBridge,
+ this_chain: bp_millau::Millau,
+ bridged_chain: bp_rialto::Rialto,
+ this_chain_account_id_converter: bp_millau::AccountIdConverter
+ );
+
+ assert_complete_bridge_constants::<
+ Runtime,
+ RialtoGrandpaInstance,
+ WithRialtoMessagesInstance,
+ WithRialtoMessageBridge,
+ bp_millau::Millau,
+ >(AssertCompleteBridgeConstants {
+ this_chain_constants: AssertChainConstants {
+ block_length: bp_millau::BlockLength::get(),
+ block_weights: bp_millau::BlockWeights::get(),
+ },
+ messages_pallet_constants: AssertBridgeMessagesPalletConstants {
+ max_unrewarded_relayers_in_bridged_confirmation_tx:
+ bp_rialto::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
+ max_unconfirmed_messages_in_bridged_confirmation_tx:
+ bp_rialto::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
+ bridged_chain_id: bp_runtime::RIALTO_CHAIN_ID,
+ },
+ pallet_names: AssertBridgePalletNames {
+ with_this_chain_messages_pallet_name: bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME,
+ with_bridged_chain_grandpa_pallet_name: bp_rialto::WITH_RIALTO_GRANDPA_PALLET_NAME,
+ with_bridged_chain_messages_pallet_name:
+ bp_rialto::WITH_RIALTO_MESSAGES_PALLET_NAME,
+ },
+ });
+
+ assert_eq!(
+ RialtoToMillauConversionRate::key().to_vec(),
+ bp_runtime::storage_parameter_key(
+ bp_millau::RIALTO_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME
+ )
+ .0,
+ );
+ }
+}
diff --git a/polkadot/bridges/bin/rialto-parachain/node/Cargo.toml b/polkadot/bridges/bin/rialto-parachain/node/Cargo.toml
index 8adc998e47..41021a35ed 100644
--- a/polkadot/bridges/bin/rialto-parachain/node/Cargo.toml
+++ b/polkadot/bridges/bin/rialto-parachain/node/Cargo.toml
@@ -2,7 +2,7 @@
name = "rialto-parachain-collator"
version = "0.1.0"
authors = ["Parity Technologies "]
-edition = "2018"
+edition = "2021"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/parity-bridges-common/"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
@@ -18,10 +18,10 @@ default = []
runtime-benchmarks = ['rialto-parachain-runtime/runtime-benchmarks']
[dependencies]
+clap = { version = "3.1", features = ["derive"] }
derive_more = '0.99.2'
log = '0.4.14'
-codec = { package = 'parity-scale-codec', version = '2.0.0' }
-structopt = '0.3.8'
+codec = { package = 'parity-scale-codec', version = '3.0.0' }
serde = { version = '1.0', features = ['derive'] }
hex-literal = '0.3.1'
@@ -80,6 +80,8 @@ cumulus-client-network = { git = "https://github.com/paritytech/cumulus", branch
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" }
+cumulus-relay-chain-interface = { git = "https://github.com/paritytech/cumulus", branch = "master" }
+cumulus-relay-chain-inprocess-interface = { git = "https://github.com/paritytech/cumulus", branch = "master" }
# Polkadot dependencies
polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "master" }
diff --git a/polkadot/bridges/bin/rialto-parachain/node/src/chain_spec.rs b/polkadot/bridges/bin/rialto-parachain/node/src/chain_spec.rs
index 9ccad8c62f..6a8e751677 100644
--- a/polkadot/bridges/bin/rialto-parachain/node/src/chain_spec.rs
+++ b/polkadot/bridges/bin/rialto-parachain/node/src/chain_spec.rs
@@ -89,6 +89,7 @@ pub fn development_config(id: ParaId) -> ChainSpec {
None,
None,
None,
+ None,
Extensions {
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
para_id: id.into(),
@@ -133,6 +134,7 @@ pub fn local_testnet_config(id: ParaId) -> ChainSpec {
None,
None,
None,
+ None,
Extensions {
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
para_id: id.into(),
diff --git a/polkadot/bridges/bin/rialto-parachain/node/src/cli.rs b/polkadot/bridges/bin/rialto-parachain/node/src/cli.rs
index 78c05f90c8..89d049f022 100644
--- a/polkadot/bridges/bin/rialto-parachain/node/src/cli.rs
+++ b/polkadot/bridges/bin/rialto-parachain/node/src/cli.rs
@@ -15,18 +15,18 @@
// along with Parity Bridges Common. If not, see .
use crate::chain_spec;
+use clap::Parser;
use std::path::PathBuf;
-use structopt::StructOpt;
/// Sub-commands supported by the collator.
-#[derive(Debug, StructOpt)]
+#[derive(Debug, Parser)]
pub enum Subcommand {
/// Export the genesis state of the parachain.
- #[structopt(name = "export-genesis-state")]
+ #[clap(name = "export-genesis-state")]
ExportGenesisState(ExportGenesisStateCommand),
/// Export the genesis wasm of the parachain.
- #[structopt(name = "export-genesis-wasm")]
+ #[clap(name = "export-genesis-wasm")]
ExportGenesisWasm(ExportGenesisWasmCommand),
/// Build a chain specification.
@@ -51,66 +51,66 @@ pub enum Subcommand {
Revert(sc_cli::RevertCmd),
/// The custom benchmark subcommmand benchmarking runtime pallets.
- #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]
+ #[clap(name = "benchmark", about = "Benchmark runtime pallets.")]
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
}
/// Command for exporting the genesis state of the parachain
-#[derive(Debug, StructOpt)]
+#[derive(Debug, Parser)]
pub struct ExportGenesisStateCommand {
/// Output file name or stdout if unspecified.
- #[structopt(parse(from_os_str))]
+ #[clap(parse(from_os_str))]
pub output: Option,
/// Id of the parachain this state is for.
///
/// Default: 100
- #[structopt(long, conflicts_with = "chain")]
+ #[clap(long, conflicts_with = "chain")]
pub parachain_id: Option,
/// Write output in binary. Default is to write in hex.
- #[structopt(short, long)]
+ #[clap(short, long)]
pub raw: bool,
/// The name of the chain for that the genesis state should be exported.
- #[structopt(long, conflicts_with = "parachain-id")]
+ #[clap(long, conflicts_with = "parachain-id")]
pub chain: Option,
}
/// Command for exporting the genesis wasm file.
-#[derive(Debug, StructOpt)]
+#[derive(Debug, Parser)]
pub struct ExportGenesisWasmCommand {
/// Output file name or stdout if unspecified.
- #[structopt(parse(from_os_str))]
+ #[clap(parse(from_os_str))]
pub output: Option,
/// Write output in binary. Default is to write in hex.
- #[structopt(short, long)]
+ #[clap(short, long)]
pub raw: bool,
/// The name of the chain for that the genesis wasm file should be exported.
- #[structopt(long)]
+ #[clap(long)]
pub chain: Option,
}
-#[derive(Debug, StructOpt)]
-#[structopt(settings = &[
- structopt::clap::AppSettings::GlobalVersion,
- structopt::clap::AppSettings::ArgsNegateSubcommands,
- structopt::clap::AppSettings::SubcommandsNegateReqs,
-])]
+#[derive(Debug, Parser)]
+#[clap(
+ propagate_version = true,
+ args_conflicts_with_subcommands = true,
+ subcommand_negates_reqs = true
+)]
pub struct Cli {
- #[structopt(subcommand)]
+ #[clap(subcommand)]
pub subcommand: Option,
- #[structopt(long)]
+ #[clap(long)]
pub parachain_id: Option,
- #[structopt(flatten)]
+ #[clap(flatten)]
pub run: cumulus_client_cli::RunCmd,
/// Relaychain arguments
- #[structopt(raw = true)]
+ #[clap(raw = true)]
pub relaychain_args: Vec,
}
@@ -135,6 +135,6 @@ impl RelayChainCli {
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) }
+ Self { base_path, chain_id, base: polkadot_cli::RunCmd::parse_from(relay_chain_args) }
}
}
diff --git a/polkadot/bridges/bin/rialto-parachain/node/src/command.rs b/polkadot/bridges/bin/rialto-parachain/node/src/command.rs
index e4f52cc026..c47e742675 100644
--- a/polkadot/bridges/bin/rialto-parachain/node/src/command.rs
+++ b/polkadot/bridges/bin/rialto-parachain/node/src/command.rs
@@ -211,10 +211,12 @@ pub fn run() -> Result<()> {
builder.with_profiling(sc_tracing::TracingReceiver::Log, "");
let _ = builder.init();
- let block: Block = generate_genesis_block(&load_spec(
+ let spec = load_spec(
¶ms.chain.clone().unwrap_or_default(),
params.parachain_id.expect("Missing ParaId").into(),
- )?)?;
+ )?;
+ let state_version = Cli::native_runtime_version(&spec).state_version();
+ let block: Block = generate_genesis_block(&spec, state_version)?;
let raw_header = block.header().encode();
let output_buf = if params.raw {
raw_header
@@ -263,6 +265,7 @@ pub fn run() -> Result<()> {
},
None => {
let runner = cli.create_runner(&cli.run.normalize())?;
+ let collator_options = cli.run.collator_options();
runner.run_node_until_exit(|config| async move {
let para_id =
@@ -276,10 +279,12 @@ pub fn run() -> Result<()> {
let id = ParaId::from(cli.parachain_id.or(para_id).expect("Missing ParaId"));
let parachain_account =
- AccountIdConversion::::into_account(&id);
+ AccountIdConversion::::into_account(&id);
- let block: Block =
- generate_genesis_block(&config.chain_spec).map_err(|e| format!("{:?}", e))?;
+ let state_version =
+ RelayChainCli::native_runtime_version(&config.chain_spec).state_version();
+ let block: Block = generate_genesis_block(&config.chain_spec, state_version)
+ .map_err(|e| format!("{:?}", e))?;
let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode()));
let polkadot_config = SubstrateCli::create_configuration(
@@ -294,7 +299,7 @@ pub fn run() -> Result<()> {
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)
+ crate::service::start_node(config, polkadot_config, collator_options, id)
.await
.map(|r| r.0)
.map_err(Into::into)
@@ -357,11 +362,24 @@ impl CliConfiguration for RelayChainCli {
self.base.base.rpc_ws(default_listen_port)
}
- fn prometheus_config(&self, default_listen_port: u16) -> Result