mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 14:01:02 +00:00
Remove obsolete bridges (#1491)
* remove Rococo<>Wococo bridge mentions * remove Kusama <> Polkadot bridge mentions * fmt * remove unneeded mocked runtimes && trait impls for obsolete bridges * remove unused deps
This commit is contained in:
committed by
Bastian Köcher
parent
46c0400f26
commit
88e95388bb
@@ -23,18 +23,14 @@ strum = { version = "0.21.0", features = ["derive"] }
|
|||||||
# Bridge dependencies
|
# Bridge dependencies
|
||||||
|
|
||||||
bp-header-chain = { path = "../../primitives/header-chain" }
|
bp-header-chain = { path = "../../primitives/header-chain" }
|
||||||
bp-kusama = { path = "../../primitives/chain-kusama" }
|
|
||||||
bp-messages = { path = "../../primitives/messages" }
|
bp-messages = { path = "../../primitives/messages" }
|
||||||
bp-millau = { path = "../../primitives/chain-millau" }
|
bp-millau = { path = "../../primitives/chain-millau" }
|
||||||
bp-parachains = { path = "../../primitives/parachains" }
|
bp-parachains = { path = "../../primitives/parachains" }
|
||||||
bp-polkadot = { path = "../../primitives/chain-polkadot" }
|
|
||||||
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
|
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
|
||||||
bp-rialto = { path = "../../primitives/chain-rialto" }
|
bp-rialto = { path = "../../primitives/chain-rialto" }
|
||||||
bp-rialto-parachain = { path = "../../primitives/chain-rialto-parachain" }
|
bp-rialto-parachain = { path = "../../primitives/chain-rialto-parachain" }
|
||||||
bp-rococo = { path = "../../primitives/chain-rococo" }
|
|
||||||
bp-runtime = { path = "../../primitives/runtime" }
|
bp-runtime = { path = "../../primitives/runtime" }
|
||||||
bp-westend = { path = "../../primitives/chain-westend" }
|
bp-westend = { path = "../../primitives/chain-westend" }
|
||||||
bp-wococo = { path = "../../primitives/chain-wococo" }
|
|
||||||
bridge-runtime-common = { path = "../../bin/runtime-common" }
|
bridge-runtime-common = { path = "../../bin/runtime-common" }
|
||||||
finality-relay = { path = "../finality" }
|
finality-relay = { path = "../finality" }
|
||||||
messages-relay = { path = "../messages" }
|
messages-relay = { path = "../messages" }
|
||||||
@@ -43,13 +39,9 @@ pallet-bridge-grandpa = { path = "../../modules/grandpa" }
|
|||||||
pallet-bridge-messages = { path = "../../modules/messages" }
|
pallet-bridge-messages = { path = "../../modules/messages" }
|
||||||
pallet-bridge-parachains = { path = "../../modules/parachains" }
|
pallet-bridge-parachains = { path = "../../modules/parachains" }
|
||||||
parachains-relay = { path = "../parachains" }
|
parachains-relay = { path = "../parachains" }
|
||||||
relay-kusama-client = { path = "../client-kusama" }
|
|
||||||
relay-millau-client = { path = "../client-millau" }
|
relay-millau-client = { path = "../client-millau" }
|
||||||
relay-polkadot-client = { path = "../client-polkadot" }
|
|
||||||
relay-rialto-client = { path = "../client-rialto" }
|
relay-rialto-client = { path = "../client-rialto" }
|
||||||
relay-rialto-parachain-client = { path = "../client-rialto-parachain" }
|
relay-rialto-parachain-client = { path = "../client-rialto-parachain" }
|
||||||
relay-rococo-client = { path = "../client-rococo" }
|
|
||||||
relay-wococo-client = { path = "../client-wococo" }
|
|
||||||
relay-substrate-client = { path = "../client-substrate" }
|
relay-substrate-client = { path = "../client-substrate" }
|
||||||
relay-utils = { path = "../utils" }
|
relay-utils = { path = "../utils" }
|
||||||
relay-westend-client = { path = "../client-westend" }
|
relay-westend-client = { path = "../client-westend" }
|
||||||
|
|||||||
@@ -1,64 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use bp_messages::LaneId;
|
|
||||||
use bp_runtime::EncodedOrDecodedCall;
|
|
||||||
use relay_kusama_client::Kusama;
|
|
||||||
use relay_substrate_client::BalanceOf;
|
|
||||||
use sp_version::RuntimeVersion;
|
|
||||||
|
|
||||||
use crate::cli::{
|
|
||||||
bridge,
|
|
||||||
encode_message::{CliEncodeMessage, RawMessage},
|
|
||||||
CliChain,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl CliEncodeMessage for Kusama {
|
|
||||||
fn encode_send_message_call(
|
|
||||||
lane: LaneId,
|
|
||||||
payload: RawMessage,
|
|
||||||
fee: BalanceOf<Self>,
|
|
||||||
bridge_instance_index: u8,
|
|
||||||
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
|
|
||||||
Ok(match bridge_instance_index {
|
|
||||||
bridge::KUSAMA_TO_POLKADOT_INDEX =>
|
|
||||||
relay_kusama_client::runtime::Call::BridgePolkadotMessages(
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotMessagesCall::send_message(
|
|
||||||
lane, payload, fee,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
_ => anyhow::bail!(
|
|
||||||
"Unsupported target bridge pallet with instance index: {}",
|
|
||||||
bridge_instance_index
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliChain for Kusama {
|
|
||||||
const RUNTIME_VERSION: RuntimeVersion = bp_kusama::VERSION;
|
|
||||||
|
|
||||||
type KeyPair = sp_core::sr25519::Pair;
|
|
||||||
type MessagePayload = Vec<u8>;
|
|
||||||
|
|
||||||
fn ss58_format() -> u16 {
|
|
||||||
sp_core::crypto::Ss58AddressFormat::from(
|
|
||||||
sp_core::crypto::Ss58AddressFormatRegistry::KusamaAccount,
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Kusama-to-Polkadot headers sync entrypoint.
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use relay_polkadot_client::Polkadot;
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
finality::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalitySyncPipeline},
|
|
||||||
TransactionParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
|
|
||||||
/// relay as gone wild.
|
|
||||||
///
|
|
||||||
/// Actual value, returned by `maximal_balance_decrease_per_day_is_sane` test is approximately 21
|
|
||||||
/// DOT, and initial value of this constant was rounded up to 30 DOT. But for actual Kusama <>
|
|
||||||
/// Polkadot deployment we'll be using the same account for delivering finality (free for mandatory
|
|
||||||
/// headers) and messages. It means that we can't predict maximal loss. But to protect funds against
|
|
||||||
/// relay/deployment issues, let's limit it so something that is much larger than this estimation -
|
|
||||||
/// e.g. to 100 DOT.
|
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/1307
|
|
||||||
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_polkadot::Balance = 100 * 10_000_000_000;
|
|
||||||
|
|
||||||
/// Description of Kusama -> Polkadot finalized headers bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct KusamaFinalityToPolkadot;
|
|
||||||
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
|
|
||||||
KusamaFinalityToPolkadot,
|
|
||||||
KusamaFinalityToPolkadotCallBuilder,
|
|
||||||
relay_polkadot_client::runtime::Call::BridgeKusamaGrandpa,
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaGrandpaCall::submit_finality_proof
|
|
||||||
);
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl SubstrateFinalitySyncPipeline for KusamaFinalityToPolkadot {
|
|
||||||
type SourceChain = relay_kusama_client::Kusama;
|
|
||||||
type TargetChain = Polkadot;
|
|
||||||
|
|
||||||
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
|
|
||||||
type SubmitFinalityProofCallBuilder = KusamaFinalityToPolkadotCallBuilder;
|
|
||||||
type TransactionSignScheme = Polkadot;
|
|
||||||
|
|
||||||
async fn start_relay_guards(
|
|
||||||
target_client: &relay_substrate_client::Client<Polkadot>,
|
|
||||||
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
|
|
||||||
enable_version_guard: bool,
|
|
||||||
) -> relay_substrate_client::Result<()> {
|
|
||||||
substrate_relay_helper::finality::guards::start::<Polkadot, Polkadot>(
|
|
||||||
target_client,
|
|
||||||
transaction_params,
|
|
||||||
enable_version_guard,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) mod tests {
|
|
||||||
use super::*;
|
|
||||||
use frame_support::weights::WeightToFeePolynomial;
|
|
||||||
use pallet_bridge_grandpa::weights::WeightInfo;
|
|
||||||
|
|
||||||
pub fn compute_maximal_balance_decrease_per_day<B, W>(expected_source_headers_per_day: u32) -> B
|
|
||||||
where
|
|
||||||
B: From<u32> + std::ops::Mul<Output = B>,
|
|
||||||
W: WeightToFeePolynomial<Balance = B>,
|
|
||||||
{
|
|
||||||
// we assume that the GRANDPA is not lagging here => ancestry length will be near to 0
|
|
||||||
// (let's round up to 2)
|
|
||||||
const AVG_VOTES_ANCESTRIES_LEN: u32 = 2;
|
|
||||||
// let's assume number of validators is 1024 (more than on any existing well-known chain
|
|
||||||
// atm) => number of precommits is *2/3 + 1
|
|
||||||
const AVG_PRECOMMITS_LEN: u32 = 1024 * 2 / 3 + 1;
|
|
||||||
|
|
||||||
// GRANDPA pallet weights. We're now using Rialto weights everywhere.
|
|
||||||
//
|
|
||||||
// Using Rialto runtime is slightly incorrect, because `DbWeight` of other runtimes may
|
|
||||||
// differ from the `DbWeight` of Rialto runtime. But now (and most probably forever) it is
|
|
||||||
// the same.
|
|
||||||
type GrandpaPalletWeights =
|
|
||||||
pallet_bridge_grandpa::weights::MillauWeight<rialto_runtime::Runtime>;
|
|
||||||
|
|
||||||
// The following formula shall not be treated as super-accurate - guard is to protect from
|
|
||||||
// mad relays, not to protect from over-average loses.
|
|
||||||
|
|
||||||
// increase number of headers a bit
|
|
||||||
let expected_source_headers_per_day = expected_source_headers_per_day * 110 / 100;
|
|
||||||
let single_source_header_submit_call_weight = GrandpaPalletWeights::submit_finality_proof(
|
|
||||||
AVG_VOTES_ANCESTRIES_LEN,
|
|
||||||
AVG_PRECOMMITS_LEN,
|
|
||||||
);
|
|
||||||
// for simplicity - add extra weight for base tx fee + fee that is paid for the tx size +
|
|
||||||
// adjusted fee
|
|
||||||
let single_source_header_submit_tx_weight = single_source_header_submit_call_weight * 3 / 2;
|
|
||||||
let single_source_header_tx_cost = W::calc(&single_source_header_submit_tx_weight);
|
|
||||||
single_source_header_tx_cost * B::from(expected_source_headers_per_day)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maximal_balance_decrease_per_day_is_sane() {
|
|
||||||
// we expect Kusama -> Polkadot relay to be running in mandatory-headers-only mode
|
|
||||||
// => we expect single header for every Kusama session
|
|
||||||
let maximal_balance_decrease = compute_maximal_balance_decrease_per_day::<
|
|
||||||
bp_polkadot::Balance,
|
|
||||||
bp_polkadot::WeightToFee,
|
|
||||||
>(bp_kusama::DAYS / bp_kusama::SESSION_LENGTH + 1);
|
|
||||||
assert!(
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY >= maximal_balance_decrease,
|
|
||||||
"Maximal expected loss per day {} is larger than hardcoded {}",
|
|
||||||
maximal_balance_decrease,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Kusama-to-Polkadot messages sync entrypoint.
|
|
||||||
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
|
|
||||||
use messages_relay::relay_strategy::MixStrategy;
|
|
||||||
use relay_kusama_client::Kusama;
|
|
||||||
use relay_polkadot_client::Polkadot;
|
|
||||||
use substrate_relay_helper::messages_lane::SubstrateMessageLane;
|
|
||||||
|
|
||||||
/// Description of Kusama -> Polkadot messages bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct KusamaMessagesToPolkadot;
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_proof_call_builder!(
|
|
||||||
KusamaMessagesToPolkadot,
|
|
||||||
KusamaMessagesToPolkadotReceiveMessagesProofCallBuilder,
|
|
||||||
relay_polkadot_client::runtime::Call::BridgeKusamaMessages,
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaMessagesCall::receive_messages_proof
|
|
||||||
);
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_builder!(
|
|
||||||
KusamaMessagesToPolkadot,
|
|
||||||
KusamaMessagesToPolkadotReceiveMessagesDeliveryProofCallBuilder,
|
|
||||||
relay_kusama_client::runtime::Call::BridgePolkadotMessages,
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotMessagesCall::receive_messages_delivery_proof
|
|
||||||
);
|
|
||||||
substrate_relay_helper::generate_mocked_update_conversion_rate_call_builder!(
|
|
||||||
Kusama,
|
|
||||||
KusamaMessagesToPolkadotUpdateConversionRateCallBuilder,
|
|
||||||
relay_kusama_client::runtime::Call::BridgePolkadotMessages,
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotMessagesCall::update_pallet_parameter,
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotMessagesParameter::PolkadotToKusamaConversionRate
|
|
||||||
);
|
|
||||||
|
|
||||||
impl SubstrateMessageLane for KusamaMessagesToPolkadot {
|
|
||||||
const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_polkadot::KUSAMA_TO_POLKADOT_CONVERSION_RATE_PARAMETER_NAME);
|
|
||||||
const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_kusama::POLKADOT_TO_KUSAMA_CONVERSION_RATE_PARAMETER_NAME);
|
|
||||||
|
|
||||||
const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_polkadot::KUSAMA_FEE_MULTIPLIER_PARAMETER_NAME);
|
|
||||||
const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_kusama::POLKADOT_FEE_MULTIPLIER_PARAMETER_NAME);
|
|
||||||
|
|
||||||
const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> =
|
|
||||||
Some(bp_kusama::TRANSACTION_PAYMENT_PALLET_NAME);
|
|
||||||
const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> =
|
|
||||||
Some(bp_polkadot::TRANSACTION_PAYMENT_PALLET_NAME);
|
|
||||||
|
|
||||||
type SourceChain = Kusama;
|
|
||||||
type TargetChain = Polkadot;
|
|
||||||
|
|
||||||
type SourceTransactionSignScheme = Kusama;
|
|
||||||
type TargetTransactionSignScheme = Polkadot;
|
|
||||||
|
|
||||||
type ReceiveMessagesProofCallBuilder = KusamaMessagesToPolkadotReceiveMessagesProofCallBuilder;
|
|
||||||
type ReceiveMessagesDeliveryProofCallBuilder =
|
|
||||||
KusamaMessagesToPolkadotReceiveMessagesDeliveryProofCallBuilder;
|
|
||||||
|
|
||||||
type TargetToSourceChainConversionRateUpdateBuilder =
|
|
||||||
KusamaMessagesToPolkadotUpdateConversionRateCallBuilder;
|
|
||||||
|
|
||||||
type RelayStrategy = MixStrategy;
|
|
||||||
}
|
|
||||||
@@ -16,33 +16,21 @@
|
|||||||
|
|
||||||
//! Chain-specific relayer configuration.
|
//! Chain-specific relayer configuration.
|
||||||
|
|
||||||
pub mod kusama_headers_to_polkadot;
|
|
||||||
pub mod kusama_messages_to_polkadot;
|
|
||||||
pub mod millau_headers_to_rialto;
|
pub mod millau_headers_to_rialto;
|
||||||
pub mod millau_headers_to_rialto_parachain;
|
pub mod millau_headers_to_rialto_parachain;
|
||||||
pub mod millau_messages_to_rialto;
|
pub mod millau_messages_to_rialto;
|
||||||
pub mod millau_messages_to_rialto_parachain;
|
pub mod millau_messages_to_rialto_parachain;
|
||||||
pub mod polkadot_headers_to_kusama;
|
|
||||||
pub mod polkadot_messages_to_kusama;
|
|
||||||
pub mod rialto_headers_to_millau;
|
pub mod rialto_headers_to_millau;
|
||||||
pub mod rialto_messages_to_millau;
|
pub mod rialto_messages_to_millau;
|
||||||
pub mod rialto_parachain_messages_to_millau;
|
pub mod rialto_parachain_messages_to_millau;
|
||||||
pub mod rialto_parachains_to_millau;
|
pub mod rialto_parachains_to_millau;
|
||||||
pub mod rococo_headers_to_wococo;
|
|
||||||
pub mod rococo_messages_to_wococo;
|
|
||||||
pub mod westend_headers_to_millau;
|
pub mod westend_headers_to_millau;
|
||||||
pub mod westend_parachains_to_millau;
|
pub mod westend_parachains_to_millau;
|
||||||
pub mod wococo_headers_to_rococo;
|
|
||||||
pub mod wococo_messages_to_rococo;
|
|
||||||
|
|
||||||
mod kusama;
|
|
||||||
mod millau;
|
mod millau;
|
||||||
mod polkadot;
|
|
||||||
mod rialto;
|
mod rialto;
|
||||||
mod rialto_parachain;
|
mod rialto_parachain;
|
||||||
mod rococo;
|
|
||||||
mod westend;
|
mod westend;
|
||||||
mod wococo;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -123,101 +111,3 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod rococo_tests {
|
|
||||||
use bp_header_chain::justification::GrandpaJustification;
|
|
||||||
use codec::Encode;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn scale_compatibility_of_bridges_call() {
|
|
||||||
// given
|
|
||||||
let header = sp_runtime::generic::Header {
|
|
||||||
parent_hash: Default::default(),
|
|
||||||
number: Default::default(),
|
|
||||||
state_root: Default::default(),
|
|
||||||
extrinsics_root: Default::default(),
|
|
||||||
digest: sp_runtime::generic::Digest { logs: vec![] },
|
|
||||||
};
|
|
||||||
|
|
||||||
let justification = GrandpaJustification {
|
|
||||||
round: 0,
|
|
||||||
commit: finality_grandpa::Commit {
|
|
||||||
target_hash: Default::default(),
|
|
||||||
target_number: Default::default(),
|
|
||||||
precommits: vec![],
|
|
||||||
},
|
|
||||||
votes_ancestries: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
let actual = relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof(
|
|
||||||
Box::new(header.clone()),
|
|
||||||
justification.clone(),
|
|
||||||
);
|
|
||||||
let expected =
|
|
||||||
millau_runtime::BridgeGrandpaCall::<millau_runtime::Runtime>::submit_finality_proof {
|
|
||||||
finality_target: Box::new(header),
|
|
||||||
justification,
|
|
||||||
};
|
|
||||||
|
|
||||||
// when
|
|
||||||
let actual_encoded = actual.encode();
|
|
||||||
let expected_encoded = expected.encode();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assert_eq!(
|
|
||||||
actual_encoded, expected_encoded,
|
|
||||||
"\n\nEncoding difference.\nGot {:#?} \nExpected: {:#?}",
|
|
||||||
actual, expected
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod westend_tests {
|
|
||||||
use bp_header_chain::justification::GrandpaJustification;
|
|
||||||
use codec::Encode;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn scale_compatibility_of_bridges_call() {
|
|
||||||
// given
|
|
||||||
let header = sp_runtime::generic::Header {
|
|
||||||
parent_hash: Default::default(),
|
|
||||||
number: Default::default(),
|
|
||||||
state_root: Default::default(),
|
|
||||||
extrinsics_root: Default::default(),
|
|
||||||
digest: sp_runtime::generic::Digest { logs: vec![] },
|
|
||||||
};
|
|
||||||
|
|
||||||
let justification = GrandpaJustification {
|
|
||||||
round: 0,
|
|
||||||
commit: finality_grandpa::Commit {
|
|
||||||
target_hash: Default::default(),
|
|
||||||
target_number: Default::default(),
|
|
||||||
precommits: vec![],
|
|
||||||
},
|
|
||||||
votes_ancestries: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
let actual = relay_kusama_client::runtime::BridgePolkadotGrandpaCall::submit_finality_proof(
|
|
||||||
Box::new(header.clone()),
|
|
||||||
justification.clone(),
|
|
||||||
);
|
|
||||||
let expected =
|
|
||||||
millau_runtime::BridgeGrandpaCall::<millau_runtime::Runtime>::submit_finality_proof {
|
|
||||||
finality_target: Box::new(header),
|
|
||||||
justification,
|
|
||||||
};
|
|
||||||
|
|
||||||
// when
|
|
||||||
let actual_encoded = actual.encode();
|
|
||||||
let expected_encoded = expected.encode();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assert_eq!(
|
|
||||||
actual_encoded, expected_encoded,
|
|
||||||
"\n\nEncoding difference.\nGot {:#?} \nExpected: {:#?}",
|
|
||||||
actual, expected
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,64 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use bp_messages::LaneId;
|
|
||||||
use bp_runtime::EncodedOrDecodedCall;
|
|
||||||
use relay_polkadot_client::Polkadot;
|
|
||||||
use relay_substrate_client::BalanceOf;
|
|
||||||
use sp_version::RuntimeVersion;
|
|
||||||
|
|
||||||
use crate::cli::{
|
|
||||||
bridge,
|
|
||||||
encode_message::{CliEncodeMessage, RawMessage},
|
|
||||||
CliChain,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl CliEncodeMessage for Polkadot {
|
|
||||||
fn encode_send_message_call(
|
|
||||||
lane: LaneId,
|
|
||||||
payload: RawMessage,
|
|
||||||
fee: BalanceOf<Self>,
|
|
||||||
bridge_instance_index: u8,
|
|
||||||
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
|
|
||||||
Ok(match bridge_instance_index {
|
|
||||||
bridge::POLKADOT_TO_KUSAMA_INDEX =>
|
|
||||||
relay_polkadot_client::runtime::Call::BridgeKusamaMessages(
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaMessagesCall::send_message(
|
|
||||||
lane, payload, fee,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
_ => anyhow::bail!(
|
|
||||||
"Unsupported target bridge pallet with instance index: {}",
|
|
||||||
bridge_instance_index
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliChain for Polkadot {
|
|
||||||
const RUNTIME_VERSION: RuntimeVersion = bp_polkadot::VERSION;
|
|
||||||
|
|
||||||
type KeyPair = sp_core::sr25519::Pair;
|
|
||||||
type MessagePayload = Vec<u8>;
|
|
||||||
|
|
||||||
fn ss58_format() -> u16 {
|
|
||||||
sp_core::crypto::Ss58AddressFormat::from(
|
|
||||||
sp_core::crypto::Ss58AddressFormatRegistry::PolkadotAccount,
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Polkadot-to-Kusama headers sync entrypoint.
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use relay_kusama_client::Kusama;
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
finality::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalitySyncPipeline},
|
|
||||||
TransactionParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
|
|
||||||
/// relay as gone wild.
|
|
||||||
///
|
|
||||||
/// Actual value, returned by `maximal_balance_decrease_per_day_is_sane` test is approximately 0.001
|
|
||||||
/// KSM, and initial value of this constant was rounded up to 0.1 KSM. But for actual Kusama <>
|
|
||||||
/// Polkadot deployment we'll be using the same account for delivering finality (free for mandatory
|
|
||||||
/// headers) and messages. It means that we can't predict maximal loss. But to protect funds against
|
|
||||||
/// relay/deployment issues, let's limit it so something that is much larger than this estimation -
|
|
||||||
/// e.g. to 2 KSM.
|
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/1307
|
|
||||||
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_kusama::Balance = 2 * 1_000_000_000_000;
|
|
||||||
|
|
||||||
/// Description of Polkadot -> Kusama finalized headers bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct PolkadotFinalityToKusama;
|
|
||||||
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
|
|
||||||
PolkadotFinalityToKusama,
|
|
||||||
PolkadotFinalityToKusamaCallBuilder,
|
|
||||||
relay_kusama_client::runtime::Call::BridgePolkadotGrandpa,
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotGrandpaCall::submit_finality_proof
|
|
||||||
);
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl SubstrateFinalitySyncPipeline for PolkadotFinalityToKusama {
|
|
||||||
type SourceChain = relay_polkadot_client::Polkadot;
|
|
||||||
type TargetChain = Kusama;
|
|
||||||
|
|
||||||
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
|
|
||||||
type SubmitFinalityProofCallBuilder = PolkadotFinalityToKusamaCallBuilder;
|
|
||||||
type TransactionSignScheme = Kusama;
|
|
||||||
|
|
||||||
async fn start_relay_guards(
|
|
||||||
target_client: &relay_substrate_client::Client<Kusama>,
|
|
||||||
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
|
|
||||||
enable_version_guard: bool,
|
|
||||||
) -> relay_substrate_client::Result<()> {
|
|
||||||
substrate_relay_helper::finality::guards::start::<Kusama, Kusama>(
|
|
||||||
target_client,
|
|
||||||
transaction_params,
|
|
||||||
enable_version_guard,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::chains::kusama_headers_to_polkadot::tests::compute_maximal_balance_decrease_per_day;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maximal_balance_decrease_per_day_is_sane() {
|
|
||||||
// we expect Polkadot -> Kusama relay to be running in mandatory-headers-only mode
|
|
||||||
// => we expect single header for every Polkadot session
|
|
||||||
let maximal_balance_decrease = compute_maximal_balance_decrease_per_day::<
|
|
||||||
bp_kusama::Balance,
|
|
||||||
bp_kusama::WeightToFee,
|
|
||||||
>(bp_polkadot::DAYS / bp_polkadot::SESSION_LENGTH + 1);
|
|
||||||
assert!(
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY >= maximal_balance_decrease,
|
|
||||||
"Maximal expected loss per day {} is larger than hardcoded {}",
|
|
||||||
maximal_balance_decrease,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Polkadot-to-Kusama messages sync entrypoint.
|
|
||||||
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use messages_relay::relay_strategy::MixStrategy;
|
|
||||||
use relay_kusama_client::Kusama;
|
|
||||||
use relay_polkadot_client::Polkadot;
|
|
||||||
use substrate_relay_helper::messages_lane::SubstrateMessageLane;
|
|
||||||
|
|
||||||
/// Description of Polkadot -> Kusama messages bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct PolkadotMessagesToKusama;
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_proof_call_builder!(
|
|
||||||
PolkadotMessagesToKusama,
|
|
||||||
PolkadotMessagesToKusamaReceiveMessagesProofCallBuilder,
|
|
||||||
relay_kusama_client::runtime::Call::BridgePolkadotMessages,
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotMessagesCall::receive_messages_proof
|
|
||||||
);
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_builder!(
|
|
||||||
PolkadotMessagesToKusama,
|
|
||||||
PolkadotMessagesToKusamaReceiveMessagesDeliveryProofCallBuilder,
|
|
||||||
relay_polkadot_client::runtime::Call::BridgeKusamaMessages,
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaMessagesCall::receive_messages_delivery_proof
|
|
||||||
);
|
|
||||||
substrate_relay_helper::generate_mocked_update_conversion_rate_call_builder!(
|
|
||||||
Polkadot,
|
|
||||||
PolkadotMessagesToKusamaUpdateConversionRateCallBuilder,
|
|
||||||
relay_polkadot_client::runtime::Call::BridgeKusamaMessages,
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaMessagesCall::update_pallet_parameter,
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaMessagesParameter::KusamaToPolkadotConversionRate
|
|
||||||
);
|
|
||||||
|
|
||||||
impl SubstrateMessageLane for PolkadotMessagesToKusama {
|
|
||||||
const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_kusama::POLKADOT_TO_KUSAMA_CONVERSION_RATE_PARAMETER_NAME);
|
|
||||||
const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_polkadot::KUSAMA_TO_POLKADOT_CONVERSION_RATE_PARAMETER_NAME);
|
|
||||||
|
|
||||||
const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_kusama::POLKADOT_FEE_MULTIPLIER_PARAMETER_NAME);
|
|
||||||
const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> =
|
|
||||||
Some(bp_polkadot::KUSAMA_FEE_MULTIPLIER_PARAMETER_NAME);
|
|
||||||
|
|
||||||
const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> =
|
|
||||||
Some(bp_polkadot::TRANSACTION_PAYMENT_PALLET_NAME);
|
|
||||||
const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> =
|
|
||||||
Some(bp_kusama::TRANSACTION_PAYMENT_PALLET_NAME);
|
|
||||||
|
|
||||||
type SourceChain = Polkadot;
|
|
||||||
type TargetChain = Kusama;
|
|
||||||
|
|
||||||
type SourceTransactionSignScheme = Polkadot;
|
|
||||||
type TargetTransactionSignScheme = Kusama;
|
|
||||||
|
|
||||||
type ReceiveMessagesProofCallBuilder = PolkadotMessagesToKusamaReceiveMessagesProofCallBuilder;
|
|
||||||
type ReceiveMessagesDeliveryProofCallBuilder =
|
|
||||||
PolkadotMessagesToKusamaReceiveMessagesDeliveryProofCallBuilder;
|
|
||||||
|
|
||||||
type TargetToSourceChainConversionRateUpdateBuilder =
|
|
||||||
PolkadotMessagesToKusamaUpdateConversionRateCallBuilder;
|
|
||||||
|
|
||||||
type RelayStrategy = MixStrategy;
|
|
||||||
}
|
|
||||||
@@ -1,60 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use bp_messages::LaneId;
|
|
||||||
use bp_runtime::EncodedOrDecodedCall;
|
|
||||||
use relay_rococo_client::Rococo;
|
|
||||||
use relay_substrate_client::BalanceOf;
|
|
||||||
use sp_version::RuntimeVersion;
|
|
||||||
|
|
||||||
use crate::cli::{
|
|
||||||
bridge,
|
|
||||||
encode_message::{CliEncodeMessage, RawMessage},
|
|
||||||
CliChain,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl CliEncodeMessage for Rococo {
|
|
||||||
fn encode_send_message_call(
|
|
||||||
lane: LaneId,
|
|
||||||
payload: RawMessage,
|
|
||||||
fee: BalanceOf<Self>,
|
|
||||||
bridge_instance_index: u8,
|
|
||||||
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
|
|
||||||
Ok(match bridge_instance_index {
|
|
||||||
bridge::ROCOCO_TO_WOCOCO_INDEX =>
|
|
||||||
relay_rococo_client::runtime::Call::BridgeWococoMessages(
|
|
||||||
relay_rococo_client::runtime::BridgeWococoMessagesCall::send_message(
|
|
||||||
lane, payload, fee,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
_ => anyhow::bail!(
|
|
||||||
"Unsupported target bridge pallet with instance index: {}",
|
|
||||||
bridge_instance_index
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl CliChain for Rococo {
|
|
||||||
const RUNTIME_VERSION: RuntimeVersion = bp_rococo::VERSION;
|
|
||||||
|
|
||||||
type KeyPair = sp_core::sr25519::Pair;
|
|
||||||
type MessagePayload = Vec<u8>;
|
|
||||||
|
|
||||||
fn ss58_format() -> u16 {
|
|
||||||
42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Rococo-to-Wococo headers sync entrypoint.
|
|
||||||
|
|
||||||
use crate::chains::wococo_headers_to_rococo::MAXIMAL_BALANCE_DECREASE_PER_DAY;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use relay_wococo_client::Wococo;
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
finality::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalitySyncPipeline},
|
|
||||||
TransactionParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Description of Rococo -> Wococo finalized headers bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct RococoFinalityToWococo;
|
|
||||||
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
|
|
||||||
RococoFinalityToWococo,
|
|
||||||
RococoFinalityToWococoCallBuilder,
|
|
||||||
relay_wococo_client::runtime::Call::BridgeGrandpaRococo,
|
|
||||||
relay_wococo_client::runtime::BridgeGrandpaRococoCall::submit_finality_proof
|
|
||||||
);
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
|
|
||||||
type SourceChain = relay_rococo_client::Rococo;
|
|
||||||
type TargetChain = Wococo;
|
|
||||||
|
|
||||||
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
|
|
||||||
type SubmitFinalityProofCallBuilder = RococoFinalityToWococoCallBuilder;
|
|
||||||
type TransactionSignScheme = Wococo;
|
|
||||||
|
|
||||||
async fn start_relay_guards(
|
|
||||||
target_client: &relay_substrate_client::Client<Wococo>,
|
|
||||||
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
|
|
||||||
enable_version_guard: bool,
|
|
||||||
) -> relay_substrate_client::Result<()> {
|
|
||||||
substrate_relay_helper::finality::guards::start::<Wococo, Wococo>(
|
|
||||||
target_client,
|
|
||||||
transaction_params,
|
|
||||||
enable_version_guard,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Rococo-to-Wococo messages sync entrypoint.
|
|
||||||
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use messages_relay::relay_strategy::MixStrategy;
|
|
||||||
use relay_rococo_client::Rococo;
|
|
||||||
use relay_wococo_client::Wococo;
|
|
||||||
use substrate_relay_helper::messages_lane::SubstrateMessageLane;
|
|
||||||
|
|
||||||
/// Description of Rococo -> Wococo messages bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct RococoMessagesToWococo;
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_proof_call_builder!(
|
|
||||||
RococoMessagesToWococo,
|
|
||||||
RococoMessagesToWococoReceiveMessagesProofCallBuilder,
|
|
||||||
relay_wococo_client::runtime::Call::BridgeRococoMessages,
|
|
||||||
relay_wococo_client::runtime::BridgeRococoMessagesCall::receive_messages_proof
|
|
||||||
);
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_builder!(
|
|
||||||
RococoMessagesToWococo,
|
|
||||||
RococoMessagesToWococoReceiveMessagesDeliveryProofCallBuilder,
|
|
||||||
relay_rococo_client::runtime::Call::BridgeWococoMessages,
|
|
||||||
relay_rococo_client::runtime::BridgeWococoMessagesCall::receive_messages_delivery_proof
|
|
||||||
);
|
|
||||||
|
|
||||||
impl SubstrateMessageLane for RococoMessagesToWococo {
|
|
||||||
const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
|
|
||||||
const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None;
|
|
||||||
const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None;
|
|
||||||
|
|
||||||
type SourceChain = Rococo;
|
|
||||||
type TargetChain = Wococo;
|
|
||||||
|
|
||||||
type SourceTransactionSignScheme = Rococo;
|
|
||||||
type TargetTransactionSignScheme = Wococo;
|
|
||||||
|
|
||||||
type ReceiveMessagesProofCallBuilder = RococoMessagesToWococoReceiveMessagesProofCallBuilder;
|
|
||||||
type ReceiveMessagesDeliveryProofCallBuilder =
|
|
||||||
RococoMessagesToWococoReceiveMessagesDeliveryProofCallBuilder;
|
|
||||||
|
|
||||||
type TargetToSourceChainConversionRateUpdateBuilder = ();
|
|
||||||
|
|
||||||
type RelayStrategy = MixStrategy;
|
|
||||||
}
|
|
||||||
@@ -1,61 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use bp_messages::LaneId;
|
|
||||||
use bp_runtime::EncodedOrDecodedCall;
|
|
||||||
use relay_substrate_client::BalanceOf;
|
|
||||||
use relay_wococo_client::Wococo;
|
|
||||||
use sp_version::RuntimeVersion;
|
|
||||||
|
|
||||||
use crate::cli::{
|
|
||||||
bridge,
|
|
||||||
encode_message::{CliEncodeMessage, RawMessage},
|
|
||||||
CliChain,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl CliEncodeMessage for Wococo {
|
|
||||||
fn encode_send_message_call(
|
|
||||||
lane: LaneId,
|
|
||||||
payload: RawMessage,
|
|
||||||
fee: BalanceOf<Self>,
|
|
||||||
bridge_instance_index: u8,
|
|
||||||
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
|
|
||||||
Ok(match bridge_instance_index {
|
|
||||||
bridge::WOCOCO_TO_ROCOCO_INDEX =>
|
|
||||||
relay_wococo_client::runtime::Call::BridgeRococoMessages(
|
|
||||||
relay_wococo_client::runtime::BridgeRococoMessagesCall::send_message(
|
|
||||||
lane, payload, fee,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
_ => anyhow::bail!(
|
|
||||||
"Unsupported target bridge pallet with instance index: {}",
|
|
||||||
bridge_instance_index
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliChain for Wococo {
|
|
||||||
const RUNTIME_VERSION: RuntimeVersion = bp_wococo::VERSION;
|
|
||||||
|
|
||||||
type KeyPair = sp_core::sr25519::Pair;
|
|
||||||
type MessagePayload = Vec<u8>;
|
|
||||||
|
|
||||||
fn ss58_format() -> u16 {
|
|
||||||
42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Wococo-to-Rococo headers sync entrypoint.
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use relay_rococo_client::Rococo;
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
finality::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalitySyncPipeline},
|
|
||||||
TransactionParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
|
|
||||||
/// relay as gone wild.
|
|
||||||
///
|
|
||||||
/// See `maximal_balance_decrease_per_day_is_sane` test for details.
|
|
||||||
/// Note that this is in plancks, so this corresponds to `1500 UNITS`.
|
|
||||||
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_rococo::Balance = 1_500_000_000_000_000;
|
|
||||||
|
|
||||||
/// Description of Wococo -> Rococo finalized headers bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct WococoFinalityToRococo;
|
|
||||||
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
|
|
||||||
WococoFinalityToRococo,
|
|
||||||
WococoFinalityToRococoCallBuilder,
|
|
||||||
relay_rococo_client::runtime::Call::BridgeGrandpaWococo,
|
|
||||||
relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof
|
|
||||||
);
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
|
|
||||||
type SourceChain = relay_wococo_client::Wococo;
|
|
||||||
type TargetChain = Rococo;
|
|
||||||
|
|
||||||
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
|
|
||||||
type SubmitFinalityProofCallBuilder = WococoFinalityToRococoCallBuilder;
|
|
||||||
type TransactionSignScheme = Rococo;
|
|
||||||
|
|
||||||
async fn start_relay_guards(
|
|
||||||
target_client: &relay_substrate_client::Client<Rococo>,
|
|
||||||
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
|
|
||||||
enable_version_guard: bool,
|
|
||||||
) -> relay_substrate_client::Result<()> {
|
|
||||||
substrate_relay_helper::finality::guards::start::<Rococo, Rococo>(
|
|
||||||
target_client,
|
|
||||||
transaction_params,
|
|
||||||
enable_version_guard,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::chains::kusama_headers_to_polkadot::tests::compute_maximal_balance_decrease_per_day;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maximal_balance_decrease_per_day_is_sane() {
|
|
||||||
// we expect Wococo -> Rococo relay to be running in all-headers mode
|
|
||||||
let maximal_balance_decrease = compute_maximal_balance_decrease_per_day::<
|
|
||||||
bp_kusama::Balance,
|
|
||||||
bp_kusama::WeightToFee,
|
|
||||||
>(bp_wococo::DAYS);
|
|
||||||
assert!(
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY >= maximal_balance_decrease,
|
|
||||||
"Maximal expected loss per day {} is larger than hardcoded {}",
|
|
||||||
maximal_balance_decrease,
|
|
||||||
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Wococo-to-Rococo messages sync entrypoint.
|
|
||||||
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
|
|
||||||
use messages_relay::relay_strategy::MixStrategy;
|
|
||||||
use relay_rococo_client::Rococo;
|
|
||||||
use relay_wococo_client::Wococo;
|
|
||||||
use substrate_relay_helper::messages_lane::SubstrateMessageLane;
|
|
||||||
|
|
||||||
/// Description of Wococo -> Rococo messages bridge.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct WococoMessagesToRococo;
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_proof_call_builder!(
|
|
||||||
WococoMessagesToRococo,
|
|
||||||
WococoMessagesToRococoReceiveMessagesProofCallBuilder,
|
|
||||||
relay_rococo_client::runtime::Call::BridgeWococoMessages,
|
|
||||||
relay_rococo_client::runtime::BridgeWococoMessagesCall::receive_messages_proof
|
|
||||||
);
|
|
||||||
substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_builder!(
|
|
||||||
WococoMessagesToRococo,
|
|
||||||
WococoMessagesToRococoReceiveMessagesDeliveryProofCallBuilder,
|
|
||||||
relay_wococo_client::runtime::Call::BridgeRococoMessages,
|
|
||||||
relay_wococo_client::runtime::BridgeRococoMessagesCall::receive_messages_delivery_proof
|
|
||||||
);
|
|
||||||
|
|
||||||
impl SubstrateMessageLane for WococoMessagesToRococo {
|
|
||||||
const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
|
|
||||||
const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None;
|
|
||||||
const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None;
|
|
||||||
const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None;
|
|
||||||
|
|
||||||
type SourceChain = Wococo;
|
|
||||||
type TargetChain = Rococo;
|
|
||||||
|
|
||||||
type SourceTransactionSignScheme = Wococo;
|
|
||||||
type TargetTransactionSignScheme = Rococo;
|
|
||||||
|
|
||||||
type ReceiveMessagesProofCallBuilder = WococoMessagesToRococoReceiveMessagesProofCallBuilder;
|
|
||||||
type ReceiveMessagesDeliveryProofCallBuilder =
|
|
||||||
WococoMessagesToRococoReceiveMessagesDeliveryProofCallBuilder;
|
|
||||||
|
|
||||||
type TargetToSourceChainConversionRateUpdateBuilder = ();
|
|
||||||
|
|
||||||
type RelayStrategy = MixStrategy;
|
|
||||||
}
|
|
||||||
@@ -25,10 +25,6 @@ use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline;
|
|||||||
pub enum FullBridge {
|
pub enum FullBridge {
|
||||||
MillauToRialto,
|
MillauToRialto,
|
||||||
RialtoToMillau,
|
RialtoToMillau,
|
||||||
RococoToWococo,
|
|
||||||
WococoToRococo,
|
|
||||||
KusamaToPolkadot,
|
|
||||||
PolkadotToKusama,
|
|
||||||
MillauToRialtoParachain,
|
MillauToRialtoParachain,
|
||||||
RialtoParachainToMillau,
|
RialtoParachainToMillau,
|
||||||
}
|
}
|
||||||
@@ -39,10 +35,6 @@ impl FullBridge {
|
|||||||
match self {
|
match self {
|
||||||
Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX,
|
Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX,
|
||||||
Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX,
|
Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX,
|
||||||
Self::RococoToWococo => ROCOCO_TO_WOCOCO_INDEX,
|
|
||||||
Self::WococoToRococo => WOCOCO_TO_ROCOCO_INDEX,
|
|
||||||
Self::KusamaToPolkadot => KUSAMA_TO_POLKADOT_INDEX,
|
|
||||||
Self::PolkadotToKusama => POLKADOT_TO_KUSAMA_INDEX,
|
|
||||||
Self::MillauToRialtoParachain => MILLAU_TO_RIALTO_PARACHAIN_INDEX,
|
Self::MillauToRialtoParachain => MILLAU_TO_RIALTO_PARACHAIN_INDEX,
|
||||||
Self::RialtoParachainToMillau => RIALTO_PARACHAIN_TO_MILLAU_INDEX,
|
Self::RialtoParachainToMillau => RIALTO_PARACHAIN_TO_MILLAU_INDEX,
|
||||||
}
|
}
|
||||||
@@ -51,10 +43,6 @@ impl FullBridge {
|
|||||||
|
|
||||||
pub const RIALTO_TO_MILLAU_INDEX: u8 = 0;
|
pub const RIALTO_TO_MILLAU_INDEX: u8 = 0;
|
||||||
pub const MILLAU_TO_RIALTO_INDEX: u8 = 0;
|
pub const MILLAU_TO_RIALTO_INDEX: u8 = 0;
|
||||||
pub const ROCOCO_TO_WOCOCO_INDEX: u8 = 0;
|
|
||||||
pub const WOCOCO_TO_ROCOCO_INDEX: u8 = 0;
|
|
||||||
pub const KUSAMA_TO_POLKADOT_INDEX: u8 = 0;
|
|
||||||
pub const POLKADOT_TO_KUSAMA_INDEX: u8 = 0;
|
|
||||||
pub const MILLAU_TO_RIALTO_PARACHAIN_INDEX: u8 = 1;
|
pub const MILLAU_TO_RIALTO_PARACHAIN_INDEX: u8 = 1;
|
||||||
pub const RIALTO_PARACHAIN_TO_MILLAU_INDEX: u8 = 0;
|
pub const RIALTO_PARACHAIN_TO_MILLAU_INDEX: u8 = 0;
|
||||||
|
|
||||||
@@ -104,82 +92,6 @@ macro_rules! select_full_bridge {
|
|||||||
|
|
||||||
$generic
|
$generic
|
||||||
},
|
},
|
||||||
FullBridge::RococoToWococo => {
|
|
||||||
type Source = relay_rococo_client::Rococo;
|
|
||||||
#[allow(dead_code)]
|
|
||||||
type Target = relay_wococo_client::Wococo;
|
|
||||||
|
|
||||||
// Derive-account
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_wococo::derive_account_from_rococo_id as derive_account;
|
|
||||||
|
|
||||||
// Relay-messages
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use $crate::chains::rococo_messages_to_wococo::RococoMessagesToWococo as MessagesLane;
|
|
||||||
|
|
||||||
// Send-message / Estimate-fee
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_wococo::TO_WOCOCO_ESTIMATE_MESSAGE_FEE_METHOD as ESTIMATE_MESSAGE_FEE_METHOD;
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
FullBridge::WococoToRococo => {
|
|
||||||
type Source = relay_wococo_client::Wococo;
|
|
||||||
#[allow(dead_code)]
|
|
||||||
type Target = relay_rococo_client::Rococo;
|
|
||||||
|
|
||||||
// Derive-account
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_rococo::derive_account_from_wococo_id as derive_account;
|
|
||||||
|
|
||||||
// Relay-messages
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use $crate::chains::wococo_messages_to_rococo::WococoMessagesToRococo as MessagesLane;
|
|
||||||
|
|
||||||
// Send-message / Estimate-fee
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_rococo::TO_ROCOCO_ESTIMATE_MESSAGE_FEE_METHOD as ESTIMATE_MESSAGE_FEE_METHOD;
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
FullBridge::KusamaToPolkadot => {
|
|
||||||
type Source = relay_kusama_client::Kusama;
|
|
||||||
#[allow(dead_code)]
|
|
||||||
type Target = relay_polkadot_client::Polkadot;
|
|
||||||
|
|
||||||
// Derive-account
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_polkadot::derive_account_from_kusama_id as derive_account;
|
|
||||||
|
|
||||||
// Relay-messages
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use $crate::chains::kusama_messages_to_polkadot::KusamaMessagesToPolkadot as MessagesLane;
|
|
||||||
|
|
||||||
// Send-message / Estimate-fee
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_polkadot::TO_POLKADOT_ESTIMATE_MESSAGE_FEE_METHOD as ESTIMATE_MESSAGE_FEE_METHOD;
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
FullBridge::PolkadotToKusama => {
|
|
||||||
type Source = relay_polkadot_client::Polkadot;
|
|
||||||
#[allow(dead_code)]
|
|
||||||
type Target = relay_kusama_client::Kusama;
|
|
||||||
|
|
||||||
// Derive-account
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_kusama::derive_account_from_polkadot_id as derive_account;
|
|
||||||
|
|
||||||
// Relay-messages
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use $crate::chains::polkadot_messages_to_kusama::PolkadotMessagesToKusama as MessagesLane;
|
|
||||||
|
|
||||||
// Send-message / Estimate-fee
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bp_kusama::TO_KUSAMA_ESTIMATE_MESSAGE_FEE_METHOD as ESTIMATE_MESSAGE_FEE_METHOD;
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
FullBridge::MillauToRialtoParachain => {
|
FullBridge::MillauToRialtoParachain => {
|
||||||
type Source = relay_millau_client::Millau;
|
type Source = relay_millau_client::Millau;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -279,54 +191,6 @@ impl CliBridge for WestendToMillauCliBridge {
|
|||||||
type Finality = crate::chains::westend_headers_to_millau::WestendFinalityToMillau;
|
type Finality = crate::chains::westend_headers_to_millau::WestendFinalityToMillau;
|
||||||
}
|
}
|
||||||
|
|
||||||
//// `Rococo` to `Wococo` bridge definition.
|
|
||||||
pub struct RococoToWococoCliBridge {}
|
|
||||||
|
|
||||||
impl CliBridgeBase for RococoToWococoCliBridge {
|
|
||||||
type Source = relay_rococo_client::Rococo;
|
|
||||||
type Target = relay_wococo_client::Wococo;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliBridge for RococoToWococoCliBridge {
|
|
||||||
type Finality = crate::chains::rococo_headers_to_wococo::RococoFinalityToWococo;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// `Wococo` to `Rococo` bridge definition.
|
|
||||||
pub struct WococoToRococoCliBridge {}
|
|
||||||
|
|
||||||
impl CliBridgeBase for WococoToRococoCliBridge {
|
|
||||||
type Source = relay_wococo_client::Wococo;
|
|
||||||
type Target = relay_rococo_client::Rococo;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliBridge for WococoToRococoCliBridge {
|
|
||||||
type Finality = crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// `Kusama` to `Polkadot` bridge definition.
|
|
||||||
pub struct KusamaToPolkadotCliBridge {}
|
|
||||||
|
|
||||||
impl CliBridgeBase for KusamaToPolkadotCliBridge {
|
|
||||||
type Source = relay_kusama_client::Kusama;
|
|
||||||
type Target = relay_polkadot_client::Polkadot;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliBridge for KusamaToPolkadotCliBridge {
|
|
||||||
type Finality = crate::chains::kusama_headers_to_polkadot::KusamaFinalityToPolkadot;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// `Polkadot` to `Kusama` bridge definition.
|
|
||||||
pub struct PolkadotToKusamaCliBridge {}
|
|
||||||
|
|
||||||
impl CliBridgeBase for PolkadotToKusamaCliBridge {
|
|
||||||
type Source = relay_polkadot_client::Polkadot;
|
|
||||||
type Target = relay_kusama_client::Kusama;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CliBridge for PolkadotToKusamaCliBridge {
|
|
||||||
type Finality = crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// `Millau` to `RialtoParachain` bridge definition.
|
//// `Millau` to `RialtoParachain` bridge definition.
|
||||||
pub struct MillauToRialtoParachainCliBridge {}
|
pub struct MillauToRialtoParachainCliBridge {}
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ use async_trait::async_trait;
|
|||||||
|
|
||||||
use crate::cli::{
|
use crate::cli::{
|
||||||
bridge::{
|
bridge::{
|
||||||
CliBridgeBase, KusamaToPolkadotCliBridge, MillauToRialtoCliBridge,
|
CliBridgeBase, MillauToRialtoCliBridge, MillauToRialtoParachainCliBridge,
|
||||||
MillauToRialtoParachainCliBridge, PolkadotToKusamaCliBridge, RialtoToMillauCliBridge,
|
RialtoToMillauCliBridge, WestendToMillauCliBridge,
|
||||||
RococoToWococoCliBridge, WestendToMillauCliBridge, WococoToRococoCliBridge,
|
|
||||||
},
|
},
|
||||||
SourceConnectionParams, TargetConnectionParams, TargetSigningParams,
|
SourceConnectionParams, TargetConnectionParams, TargetSigningParams,
|
||||||
};
|
};
|
||||||
@@ -55,10 +54,6 @@ pub enum InitBridgeName {
|
|||||||
MillauToRialto,
|
MillauToRialto,
|
||||||
RialtoToMillau,
|
RialtoToMillau,
|
||||||
WestendToMillau,
|
WestendToMillau,
|
||||||
RococoToWococo,
|
|
||||||
WococoToRococo,
|
|
||||||
KusamaToPolkadot,
|
|
||||||
PolkadotToKusama,
|
|
||||||
MillauToRialtoParachain,
|
MillauToRialtoParachain,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,54 +170,6 @@ impl BridgeInitializer for WestendToMillauCliBridge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BridgeInitializer for RococoToWococoCliBridge {
|
|
||||||
type Engine = GrandpaFinalityEngine<Self::Source>;
|
|
||||||
|
|
||||||
fn encode_init_bridge(
|
|
||||||
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
|
|
||||||
) -> <Self::Target as Chain>::Call {
|
|
||||||
relay_wococo_client::runtime::Call::BridgeGrandpaRococo(
|
|
||||||
relay_wococo_client::runtime::BridgeGrandpaRococoCall::initialize(init_data),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BridgeInitializer for WococoToRococoCliBridge {
|
|
||||||
type Engine = GrandpaFinalityEngine<Self::Source>;
|
|
||||||
|
|
||||||
fn encode_init_bridge(
|
|
||||||
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
|
|
||||||
) -> <Self::Target as Chain>::Call {
|
|
||||||
relay_rococo_client::runtime::Call::BridgeGrandpaWococo(
|
|
||||||
relay_rococo_client::runtime::BridgeGrandpaWococoCall::initialize(init_data),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BridgeInitializer for KusamaToPolkadotCliBridge {
|
|
||||||
type Engine = GrandpaFinalityEngine<Self::Source>;
|
|
||||||
|
|
||||||
fn encode_init_bridge(
|
|
||||||
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
|
|
||||||
) -> <Self::Target as Chain>::Call {
|
|
||||||
relay_polkadot_client::runtime::Call::BridgeKusamaGrandpa(
|
|
||||||
relay_polkadot_client::runtime::BridgeKusamaGrandpaCall::initialize(init_data),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BridgeInitializer for PolkadotToKusamaCliBridge {
|
|
||||||
type Engine = GrandpaFinalityEngine<Self::Source>;
|
|
||||||
|
|
||||||
fn encode_init_bridge(
|
|
||||||
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
|
|
||||||
) -> <Self::Target as Chain>::Call {
|
|
||||||
relay_kusama_client::runtime::Call::BridgePolkadotGrandpa(
|
|
||||||
relay_kusama_client::runtime::BridgePolkadotGrandpaCall::initialize(init_data),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InitBridge {
|
impl InitBridge {
|
||||||
/// Run the command.
|
/// Run the command.
|
||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
@@ -230,10 +177,6 @@ impl InitBridge {
|
|||||||
InitBridgeName::MillauToRialto => MillauToRialtoCliBridge::init_bridge(self),
|
InitBridgeName::MillauToRialto => MillauToRialtoCliBridge::init_bridge(self),
|
||||||
InitBridgeName::RialtoToMillau => RialtoToMillauCliBridge::init_bridge(self),
|
InitBridgeName::RialtoToMillau => RialtoToMillauCliBridge::init_bridge(self),
|
||||||
InitBridgeName::WestendToMillau => WestendToMillauCliBridge::init_bridge(self),
|
InitBridgeName::WestendToMillau => WestendToMillauCliBridge::init_bridge(self),
|
||||||
InitBridgeName::RococoToWococo => RococoToWococoCliBridge::init_bridge(self),
|
|
||||||
InitBridgeName::WococoToRococo => WococoToRococoCliBridge::init_bridge(self),
|
|
||||||
InitBridgeName::KusamaToPolkadot => KusamaToPolkadotCliBridge::init_bridge(self),
|
|
||||||
InitBridgeName::PolkadotToKusama => PolkadotToKusamaCliBridge::init_bridge(self),
|
|
||||||
InitBridgeName::MillauToRialtoParachain =>
|
InitBridgeName::MillauToRialtoParachain =>
|
||||||
MillauToRialtoParachainCliBridge::init_bridge(self),
|
MillauToRialtoParachainCliBridge::init_bridge(self),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ pub(crate) mod send_message;
|
|||||||
|
|
||||||
mod init_bridge;
|
mod init_bridge;
|
||||||
mod register_parachain;
|
mod register_parachain;
|
||||||
mod reinit_bridge;
|
|
||||||
mod relay_headers;
|
mod relay_headers;
|
||||||
mod relay_headers_and_messages;
|
mod relay_headers_and_messages;
|
||||||
mod relay_messages;
|
mod relay_messages;
|
||||||
@@ -70,11 +69,6 @@ pub enum Command {
|
|||||||
///
|
///
|
||||||
/// Sends initialization transaction to bootstrap the bridge with current finalized block data.
|
/// Sends initialization transaction to bootstrap the bridge with current finalized block data.
|
||||||
InitBridge(init_bridge::InitBridge),
|
InitBridge(init_bridge::InitBridge),
|
||||||
/// Reinitialize on-chain bridge pallet with current header data.
|
|
||||||
///
|
|
||||||
/// Sends all missing mandatory headers to bootstrap the bridge with current finalized block
|
|
||||||
/// data.
|
|
||||||
ReinitBridge(reinit_bridge::ReinitBridge),
|
|
||||||
/// Send custom message over the bridge.
|
/// Send custom message over the bridge.
|
||||||
///
|
///
|
||||||
/// Allows interacting with the bridge by sending messages over `Messages` component.
|
/// Allows interacting with the bridge by sending messages over `Messages` component.
|
||||||
@@ -117,7 +111,6 @@ impl Command {
|
|||||||
Self::RelayMessages(arg) => arg.run().await?,
|
Self::RelayMessages(arg) => arg.run().await?,
|
||||||
Self::RelayHeadersAndMessages(arg) => arg.run().await?,
|
Self::RelayHeadersAndMessages(arg) => arg.run().await?,
|
||||||
Self::InitBridge(arg) => arg.run().await?,
|
Self::InitBridge(arg) => arg.run().await?,
|
||||||
Self::ReinitBridge(arg) => arg.run().await?,
|
|
||||||
Self::SendMessage(arg) => arg.run().await?,
|
Self::SendMessage(arg) => arg.run().await?,
|
||||||
Self::EstimateFee(arg) => arg.run().await?,
|
Self::EstimateFee(arg) => arg.run().await?,
|
||||||
Self::ResubmitTransactions(arg) => arg.run().await?,
|
Self::ResubmitTransactions(arg) => arg.run().await?,
|
||||||
|
|||||||
@@ -1,556 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
chains::{
|
|
||||||
kusama_headers_to_polkadot::KusamaFinalityToPolkadot,
|
|
||||||
polkadot_headers_to_kusama::PolkadotFinalityToKusama,
|
|
||||||
},
|
|
||||||
cli::{
|
|
||||||
register_parachain::wait_until_transaction_is_finalized, SourceConnectionParams,
|
|
||||||
TargetConnectionParams, TargetSigningParams,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use bp_runtime::Chain;
|
|
||||||
use codec::Encode;
|
|
||||||
use finality_relay::{SourceClient, SourceHeader};
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use num_traits::One;
|
|
||||||
use pallet_bridge_grandpa::weights::WeightInfo;
|
|
||||||
use relay_substrate_client::{
|
|
||||||
AccountIdOf, BlockNumberOf, Chain as _, Client, Error as SubstrateError, HeaderOf, SignParam,
|
|
||||||
SyncHeader, TransactionEra, TransactionSignScheme, UnsignedTransaction,
|
|
||||||
};
|
|
||||||
use sp_core::{Bytes, Pair};
|
|
||||||
use std::convert::{TryFrom, TryInto};
|
|
||||||
use structopt::StructOpt;
|
|
||||||
use strum::{EnumString, EnumVariantNames, VariantNames};
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
finality::{
|
|
||||||
source::{SubstrateFinalityProof, SubstrateFinalitySource},
|
|
||||||
target::SubstrateFinalityTarget,
|
|
||||||
SubstrateFinalitySyncPipeline,
|
|
||||||
},
|
|
||||||
messages_source::read_client_state,
|
|
||||||
TransactionParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Reinitialize bridge pallet.
|
|
||||||
#[derive(Debug, PartialEq, Eq, StructOpt)]
|
|
||||||
pub struct ReinitBridge {
|
|
||||||
/// A bridge instance to reinitialize.
|
|
||||||
#[structopt(possible_values = ReinitBridgeName::VARIANTS, case_insensitive = true)]
|
|
||||||
bridge: ReinitBridgeName,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
source: SourceConnectionParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
target: TargetConnectionParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
target_sign: TargetSigningParams,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, EnumString, EnumVariantNames, PartialEq, Eq)]
|
|
||||||
#[strum(serialize_all = "kebab_case")]
|
|
||||||
/// Bridge to initialize.
|
|
||||||
pub enum ReinitBridgeName {
|
|
||||||
KusamaToPolkadot,
|
|
||||||
PolkadotToKusama,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! select_bridge {
|
|
||||||
($bridge: expr, $generic: tt) => {
|
|
||||||
match $bridge {
|
|
||||||
ReinitBridgeName::KusamaToPolkadot => {
|
|
||||||
use relay_polkadot_client::runtime;
|
|
||||||
|
|
||||||
type Finality = KusamaFinalityToPolkadot;
|
|
||||||
type Call = runtime::Call;
|
|
||||||
|
|
||||||
fn submit_finality_proof_call(
|
|
||||||
header_and_proof: HeaderAndProof<Finality>,
|
|
||||||
) -> runtime::Call {
|
|
||||||
runtime::Call::BridgeKusamaGrandpa(
|
|
||||||
runtime::BridgeKusamaGrandpaCall::submit_finality_proof(
|
|
||||||
Box::new(header_and_proof.0.into_inner()),
|
|
||||||
header_and_proof.1,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_pallet_operation_mode_call(operational: bool) -> runtime::Call {
|
|
||||||
runtime::Call::BridgeKusamaGrandpa(
|
|
||||||
runtime::BridgeKusamaGrandpaCall::set_operational(operational),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn batch_all_call(calls: Vec<Call>) -> runtime::Call {
|
|
||||||
runtime::Call::Utility(runtime::UtilityCall::batch_all(calls))
|
|
||||||
}
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
ReinitBridgeName::PolkadotToKusama => {
|
|
||||||
use relay_kusama_client::runtime;
|
|
||||||
|
|
||||||
type Finality = PolkadotFinalityToKusama;
|
|
||||||
type Call = runtime::Call;
|
|
||||||
|
|
||||||
fn submit_finality_proof_call(
|
|
||||||
header_and_proof: HeaderAndProof<Finality>,
|
|
||||||
) -> runtime::Call {
|
|
||||||
runtime::Call::BridgePolkadotGrandpa(
|
|
||||||
runtime::BridgePolkadotGrandpaCall::submit_finality_proof(
|
|
||||||
Box::new(header_and_proof.0.into_inner()),
|
|
||||||
header_and_proof.1,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_pallet_operation_mode_call(operational: bool) -> runtime::Call {
|
|
||||||
runtime::Call::BridgePolkadotGrandpa(
|
|
||||||
runtime::BridgePolkadotGrandpaCall::set_operational(operational),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn batch_all_call(calls: Vec<Call>) -> runtime::Call {
|
|
||||||
runtime::Call::Utility(runtime::UtilityCall::batch_all(calls))
|
|
||||||
}
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReinitBridge {
|
|
||||||
/// Run the command.
|
|
||||||
pub async fn run(self) -> anyhow::Result<()> {
|
|
||||||
select_bridge!(self.bridge, {
|
|
||||||
type Source = <Finality as SubstrateFinalitySyncPipeline>::SourceChain;
|
|
||||||
type Target = <Finality as SubstrateFinalitySyncPipeline>::TargetChain;
|
|
||||||
|
|
||||||
let source_client = self.source.to_client::<Source>().await?;
|
|
||||||
let target_client = self.target.to_client::<Target>().await?;
|
|
||||||
let target_sign = self.target_sign.to_keypair::<Target>()?;
|
|
||||||
let transaction_params = TransactionParams {
|
|
||||||
signer: target_sign,
|
|
||||||
mortality: self.target_sign.target_transactions_mortality,
|
|
||||||
};
|
|
||||||
|
|
||||||
let finality_source =
|
|
||||||
SubstrateFinalitySource::<Finality>::new(source_client.clone(), None);
|
|
||||||
let finality_target = SubstrateFinalityTarget::<Finality>::new(
|
|
||||||
target_client.clone(),
|
|
||||||
transaction_params.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// this subcommand assumes that the pallet at the target chain is halted
|
|
||||||
ensure_pallet_operating_mode(&finality_target, false).await?;
|
|
||||||
|
|
||||||
// we can't call `finality_target.best_finalized_source_block_id()`, because pallet is
|
|
||||||
// halted and the call will fail => just use what it uses internally
|
|
||||||
let current_number =
|
|
||||||
best_source_block_number_at_target::<Finality>(&target_client).await?;
|
|
||||||
let target_number = finality_source.best_finalized_block_number().await?;
|
|
||||||
log::info!(
|
|
||||||
target: "bridge",
|
|
||||||
"Best finalized {} header: at {}: {}, at {}: {}",
|
|
||||||
Source::NAME,
|
|
||||||
Source::NAME,
|
|
||||||
target_number,
|
|
||||||
Target::NAME,
|
|
||||||
current_number,
|
|
||||||
);
|
|
||||||
|
|
||||||
// prepare list of mandatory headers from the range `(current_number; target_number]`
|
|
||||||
let headers_to_submit = find_mandatory_headers_in_range(
|
|
||||||
&finality_source,
|
|
||||||
(current_number + 1, target_number),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let latest_mandatory_header_number = headers_to_submit.last().map(|(h, _)| h.number());
|
|
||||||
log::info!(
|
|
||||||
target: "bridge",
|
|
||||||
"Missing {} mandatory {} headers at {}",
|
|
||||||
headers_to_submit.len(),
|
|
||||||
Source::NAME,
|
|
||||||
Target::NAME,
|
|
||||||
);
|
|
||||||
|
|
||||||
// split all mandatory headers into batches
|
|
||||||
let headers_batches =
|
|
||||||
make_mandatory_headers_batches::<Finality, _>(headers_to_submit, |(_, proof)| {
|
|
||||||
// we don't have an access to the Kusama/Polkadot chain runtimes here, so we'll
|
|
||||||
// be using Millau weights. It isn't super-critical, unless real weights are
|
|
||||||
// magnitude higher or so
|
|
||||||
pallet_bridge_grandpa::weights::MillauWeight::<millau_runtime::Runtime>::submit_finality_proof(
|
|
||||||
proof.commit.precommits.len().try_into().unwrap_or(u32::MAX),
|
|
||||||
proof.votes_ancestries.len().try_into().unwrap_or(u32::MAX),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
log::info!(
|
|
||||||
target: "bridge",
|
|
||||||
"We're going to submit {} transactions to {} node",
|
|
||||||
headers_batches.len(),
|
|
||||||
Target::NAME,
|
|
||||||
);
|
|
||||||
|
|
||||||
// each batch is submitted as a separate transaction
|
|
||||||
let signer_account_id: AccountIdOf<Target> = transaction_params.signer.public().into();
|
|
||||||
let genesis_hash = *target_client.genesis_hash();
|
|
||||||
let (spec_version, transaction_version) =
|
|
||||||
target_client.simple_runtime_version().await?;
|
|
||||||
let last_batch_index = headers_batches.len() - 1;
|
|
||||||
for (i, headers_batch) in headers_batches.into_iter().enumerate() {
|
|
||||||
let is_last_batch = i == last_batch_index;
|
|
||||||
let expected_number =
|
|
||||||
headers_batch.last().expect("all batches are non-empty").0.number();
|
|
||||||
let transaction_params = transaction_params.clone();
|
|
||||||
log::info!(
|
|
||||||
target: "bridge",
|
|
||||||
"Going to submit transaction that updates best {} header at {} to {}",
|
|
||||||
Source::NAME,
|
|
||||||
Target::NAME,
|
|
||||||
expected_number,
|
|
||||||
);
|
|
||||||
|
|
||||||
// prepare `batch_all` call
|
|
||||||
let mut batch_calls = Vec::with_capacity(headers_batch.len() + 2);
|
|
||||||
// the first call is always resumes pallet operation
|
|
||||||
batch_calls.push(set_pallet_operation_mode_call(true));
|
|
||||||
// followed by submit-finality-proofs calls
|
|
||||||
for header_and_proof in headers_batch {
|
|
||||||
batch_calls.push(submit_finality_proof_call(header_and_proof));
|
|
||||||
}
|
|
||||||
// if it isn't the last batch, we shall halt pallet again
|
|
||||||
if !is_last_batch {
|
|
||||||
batch_calls.push(set_pallet_operation_mode_call(false));
|
|
||||||
}
|
|
||||||
let submit_batch_call = batch_all_call(batch_calls);
|
|
||||||
|
|
||||||
let batch_transaction_events = target_client
|
|
||||||
.submit_and_watch_signed_extrinsic(
|
|
||||||
signer_account_id.clone(),
|
|
||||||
move |best_block_id, transaction_nonce| {
|
|
||||||
Ok(Bytes(
|
|
||||||
Target::sign_transaction(SignParam {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash,
|
|
||||||
signer: transaction_params.signer.clone(),
|
|
||||||
era: TransactionEra::new(
|
|
||||||
best_block_id,
|
|
||||||
transaction_params.mortality,
|
|
||||||
),
|
|
||||||
unsigned: UnsignedTransaction::new(
|
|
||||||
submit_batch_call.into(),
|
|
||||||
transaction_nonce,
|
|
||||||
),
|
|
||||||
})?
|
|
||||||
.encode(),
|
|
||||||
))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
wait_until_transaction_is_finalized::<Target>(batch_transaction_events).await?;
|
|
||||||
|
|
||||||
// verify that the best finalized header at target has been updated
|
|
||||||
let current_number =
|
|
||||||
best_source_block_number_at_target::<Finality>(&target_client).await?;
|
|
||||||
if current_number != expected_number {
|
|
||||||
return Err(anyhow::format_err!(
|
|
||||||
"Transaction has failed to update best {} header at {} to {}. It is {}",
|
|
||||||
Source::NAME,
|
|
||||||
Target::NAME,
|
|
||||||
expected_number,
|
|
||||||
current_number,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify that the pallet is still halted (or operational if it is the last batch)
|
|
||||||
ensure_pallet_operating_mode(&finality_target, is_last_batch).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(latest_mandatory_header_number) = latest_mandatory_header_number {
|
|
||||||
log::info!(
|
|
||||||
target: "bridge",
|
|
||||||
"Successfully updated best {} header at {} to {}. Pallet is now operational",
|
|
||||||
Source::NAME,
|
|
||||||
Target::NAME,
|
|
||||||
latest_mandatory_header_number,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mandatory header and its finality proof.
|
|
||||||
type HeaderAndProof<P> = (
|
|
||||||
SyncHeader<HeaderOf<<P as SubstrateFinalitySyncPipeline>::SourceChain>>,
|
|
||||||
SubstrateFinalityProof<P>,
|
|
||||||
);
|
|
||||||
/// Vector of mandatory headers and their finality proofs.
|
|
||||||
type HeadersAndProofs<P> = Vec<HeaderAndProof<P>>;
|
|
||||||
|
|
||||||
/// Returns best finalized source header number known to the bridge GRANDPA pallet at the target
|
|
||||||
/// chain.
|
|
||||||
///
|
|
||||||
/// This function works even if bridge GRANDPA pallet at the target chain is halted.
|
|
||||||
async fn best_source_block_number_at_target<P: SubstrateFinalitySyncPipeline>(
|
|
||||||
target_client: &Client<P::TargetChain>,
|
|
||||||
) -> anyhow::Result<BlockNumberOf<P::SourceChain>> {
|
|
||||||
Ok(read_client_state::<P::TargetChain, P::SourceChain>(
|
|
||||||
target_client,
|
|
||||||
None,
|
|
||||||
P::SourceChain::BEST_FINALIZED_HEADER_ID_METHOD,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.best_finalized_peer_at_best_self
|
|
||||||
.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verify that the bridge GRANDPA pallet at the target chain is either halted, or operational.
|
|
||||||
async fn ensure_pallet_operating_mode<P: SubstrateFinalitySyncPipeline>(
|
|
||||||
finality_target: &SubstrateFinalityTarget<P>,
|
|
||||||
operational: bool,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
match (operational, finality_target.ensure_pallet_active().await) {
|
|
||||||
(true, Ok(())) => Ok(()),
|
|
||||||
(false, Err(SubstrateError::BridgePalletIsHalted)) => Ok(()),
|
|
||||||
_ => Err(anyhow::format_err!(
|
|
||||||
"Bridge GRANDPA pallet at {} is expected to be {}, but it isn't",
|
|
||||||
P::TargetChain::NAME,
|
|
||||||
if operational { "operational" } else { "halted" },
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns list of all mandatory headers in given range.
|
|
||||||
async fn find_mandatory_headers_in_range<P: SubstrateFinalitySyncPipeline>(
|
|
||||||
finality_source: &SubstrateFinalitySource<P>,
|
|
||||||
range: (BlockNumberOf<P::SourceChain>, BlockNumberOf<P::SourceChain>),
|
|
||||||
) -> anyhow::Result<HeadersAndProofs<P>> {
|
|
||||||
let mut mandatory_headers = Vec::new();
|
|
||||||
let mut current = range.0;
|
|
||||||
while current <= range.1 {
|
|
||||||
let (header, proof) = finality_source.header_and_finality_proof(current).await?;
|
|
||||||
if header.is_mandatory() {
|
|
||||||
match proof {
|
|
||||||
Some(proof) => mandatory_headers.push((header, proof)),
|
|
||||||
None =>
|
|
||||||
return Err(anyhow::format_err!(
|
|
||||||
"Missing GRANDPA justification for {} header {}",
|
|
||||||
P::SourceChain::NAME,
|
|
||||||
current,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current += One::one();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(mandatory_headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given list of mandatory headers, prepare batches of headers, so that every batch may fit into
|
|
||||||
/// single transaction.
|
|
||||||
fn make_mandatory_headers_batches<
|
|
||||||
P: SubstrateFinalitySyncPipeline,
|
|
||||||
F: Fn(&HeaderAndProof<P>) -> Weight,
|
|
||||||
>(
|
|
||||||
mut headers_to_submit: HeadersAndProofs<P>,
|
|
||||||
submit_header_weight: F,
|
|
||||||
) -> Vec<HeadersAndProofs<P>> {
|
|
||||||
// now that we have all mandatory headers, let's prepare transactions
|
|
||||||
// (let's keep all our transactions below 2/3 of max tx size/weight to have some reserve
|
|
||||||
// for utility overhead + for halting transaction)
|
|
||||||
let maximal_tx_size = P::TargetChain::max_extrinsic_size() * 2 / 3;
|
|
||||||
let maximal_tx_weight = P::TargetChain::max_extrinsic_weight() * 2 / 3;
|
|
||||||
let mut current_batch_size: u32 = 0;
|
|
||||||
let mut current_batch_weight: Weight = 0;
|
|
||||||
let mut batches = Vec::new();
|
|
||||||
let mut i = 0;
|
|
||||||
while i < headers_to_submit.len() {
|
|
||||||
let header_and_proof_size =
|
|
||||||
headers_to_submit[i].0.encode().len() + headers_to_submit[i].1.encode().len();
|
|
||||||
let header_and_proof_weight = submit_header_weight(&headers_to_submit[i]);
|
|
||||||
|
|
||||||
let new_batch_size = current_batch_size
|
|
||||||
.saturating_add(u32::try_from(header_and_proof_size).unwrap_or(u32::MAX));
|
|
||||||
let new_batch_weight = current_batch_weight.saturating_add(header_and_proof_weight);
|
|
||||||
|
|
||||||
let is_exceeding_tx_size = new_batch_size > maximal_tx_size;
|
|
||||||
let is_exceeding_tx_weight = new_batch_weight > maximal_tx_weight;
|
|
||||||
let is_new_batch_required = is_exceeding_tx_size || is_exceeding_tx_weight;
|
|
||||||
|
|
||||||
if is_new_batch_required {
|
|
||||||
// if `i` is 0 and we're here, it is a weird situation: even single header submission is
|
|
||||||
// larger than we've planned for a bunch of headers. Let's be optimistic and hope that
|
|
||||||
// the tx will still succeed.
|
|
||||||
let spit_off_index = std::cmp::max(i, 1);
|
|
||||||
let remaining_headers_to_submit = headers_to_submit.split_off(spit_off_index);
|
|
||||||
batches.push(headers_to_submit);
|
|
||||||
|
|
||||||
// we'll reiterate the same header again => so set `current_*` to zero
|
|
||||||
current_batch_size = 0;
|
|
||||||
current_batch_weight = 0;
|
|
||||||
headers_to_submit = remaining_headers_to_submit;
|
|
||||||
i = 0;
|
|
||||||
} else {
|
|
||||||
current_batch_size = new_batch_size;
|
|
||||||
current_batch_weight = new_batch_weight;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !headers_to_submit.is_empty() {
|
|
||||||
batches.push(headers_to_submit);
|
|
||||||
}
|
|
||||||
batches
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::cli::{RuntimeVersionType, SourceRuntimeVersionParams, TargetRuntimeVersionParams};
|
|
||||||
use bp_header_chain::justification::GrandpaJustification;
|
|
||||||
use bp_test_utils::{make_default_justification, test_header};
|
|
||||||
use relay_polkadot_client::Polkadot;
|
|
||||||
use sp_runtime::{traits::Header as _, DigestItem};
|
|
||||||
|
|
||||||
fn make_header_and_justification(
|
|
||||||
i: u32,
|
|
||||||
size: u32,
|
|
||||||
) -> (SyncHeader<bp_kusama::Header>, GrandpaJustification<bp_kusama::Header>) {
|
|
||||||
let size = size as usize;
|
|
||||||
let mut header: bp_kusama::Header = test_header(i);
|
|
||||||
let justification = make_default_justification(&header);
|
|
||||||
let actual_size = header.encode().len() + justification.encode().len();
|
|
||||||
// additional digest means some additional bytes, so let's decrease `additional_digest_size`
|
|
||||||
// a bit
|
|
||||||
let additional_digest_size = size.saturating_sub(actual_size).saturating_sub(100);
|
|
||||||
header.digest_mut().push(DigestItem::Other(vec![0u8; additional_digest_size]));
|
|
||||||
let justification = make_default_justification(&header);
|
|
||||||
println!("{} {}", size, header.encode().len() + justification.encode().len());
|
|
||||||
(header.into(), justification)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_parse_cli_options() {
|
|
||||||
// when
|
|
||||||
let res = ReinitBridge::from_iter(vec![
|
|
||||||
"reinit-bridge",
|
|
||||||
"kusama-to-polkadot",
|
|
||||||
"--source-host",
|
|
||||||
"127.0.0.1",
|
|
||||||
"--source-port",
|
|
||||||
"42",
|
|
||||||
"--target-host",
|
|
||||||
"127.0.0.1",
|
|
||||||
"--target-port",
|
|
||||||
"43",
|
|
||||||
"--target-signer",
|
|
||||||
"//Alice",
|
|
||||||
]);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assert_eq!(
|
|
||||||
res,
|
|
||||||
ReinitBridge {
|
|
||||||
bridge: ReinitBridgeName::KusamaToPolkadot,
|
|
||||||
source: SourceConnectionParams {
|
|
||||||
source_host: "127.0.0.1".into(),
|
|
||||||
source_port: 42,
|
|
||||||
source_secure: false,
|
|
||||||
source_runtime_version: SourceRuntimeVersionParams {
|
|
||||||
source_version_mode: RuntimeVersionType::Bundle,
|
|
||||||
source_spec_version: None,
|
|
||||||
source_transaction_version: None,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
target: TargetConnectionParams {
|
|
||||||
target_host: "127.0.0.1".into(),
|
|
||||||
target_port: 43,
|
|
||||||
target_secure: false,
|
|
||||||
target_runtime_version: TargetRuntimeVersionParams {
|
|
||||||
target_version_mode: RuntimeVersionType::Bundle,
|
|
||||||
target_spec_version: None,
|
|
||||||
target_transaction_version: None,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
target_sign: TargetSigningParams {
|
|
||||||
target_signer: Some("//Alice".into()),
|
|
||||||
target_signer_password: None,
|
|
||||||
target_signer_file: None,
|
|
||||||
target_signer_password_file: None,
|
|
||||||
target_transactions_mortality: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn make_mandatory_headers_batches_and_empty_headers() {
|
|
||||||
let batches = make_mandatory_headers_batches::<KusamaFinalityToPolkadot, _>(vec![], |_| 0);
|
|
||||||
assert!(batches.is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn make_mandatory_headers_batches_with_single_batch() {
|
|
||||||
let headers_to_submit =
|
|
||||||
vec![make_header_and_justification(10, Polkadot::max_extrinsic_size() / 3)];
|
|
||||||
let batches =
|
|
||||||
make_mandatory_headers_batches::<KusamaFinalityToPolkadot, _>(headers_to_submit, |_| 0);
|
|
||||||
assert_eq!(batches.into_iter().map(|x| x.len()).collect::<Vec<_>>(), vec![1],);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn make_mandatory_headers_batches_group_by_size() {
|
|
||||||
let headers_to_submit = vec![
|
|
||||||
make_header_and_justification(10, Polkadot::max_extrinsic_size() / 3),
|
|
||||||
make_header_and_justification(20, Polkadot::max_extrinsic_size() / 3),
|
|
||||||
make_header_and_justification(30, Polkadot::max_extrinsic_size() * 2 / 3),
|
|
||||||
make_header_and_justification(40, Polkadot::max_extrinsic_size()),
|
|
||||||
];
|
|
||||||
let batches =
|
|
||||||
make_mandatory_headers_batches::<KusamaFinalityToPolkadot, _>(headers_to_submit, |_| 0);
|
|
||||||
assert_eq!(batches.into_iter().map(|x| x.len()).collect::<Vec<_>>(), vec![2, 1, 1],);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn make_mandatory_headers_batches_group_by_weight() {
|
|
||||||
let headers_to_submit = vec![
|
|
||||||
make_header_and_justification(10, 0),
|
|
||||||
make_header_and_justification(20, 0),
|
|
||||||
make_header_and_justification(30, 0),
|
|
||||||
make_header_and_justification(40, 0),
|
|
||||||
];
|
|
||||||
let batches = make_mandatory_headers_batches::<KusamaFinalityToPolkadot, _>(
|
|
||||||
headers_to_submit,
|
|
||||||
|(header, _)| {
|
|
||||||
if header.number() == 10 || header.number() == 20 {
|
|
||||||
Polkadot::max_extrinsic_weight() / 3
|
|
||||||
} else if header.number() == 30 {
|
|
||||||
Polkadot::max_extrinsic_weight() * 2 / 3
|
|
||||||
} else {
|
|
||||||
Polkadot::max_extrinsic_weight()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
assert_eq!(batches.into_iter().map(|x| x.len()).collect::<Vec<_>>(), vec![2, 1, 1],);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,9 +25,8 @@ use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline;
|
|||||||
|
|
||||||
use crate::cli::{
|
use crate::cli::{
|
||||||
bridge::{
|
bridge::{
|
||||||
CliBridge, KusamaToPolkadotCliBridge, MillauToRialtoCliBridge,
|
CliBridge, MillauToRialtoCliBridge, MillauToRialtoParachainCliBridge,
|
||||||
MillauToRialtoParachainCliBridge, PolkadotToKusamaCliBridge, RialtoToMillauCliBridge,
|
RialtoToMillauCliBridge, WestendToMillauCliBridge,
|
||||||
RococoToWococoCliBridge, WestendToMillauCliBridge, WococoToRococoCliBridge,
|
|
||||||
},
|
},
|
||||||
PrometheusParams, SourceConnectionParams, TargetConnectionParams, TargetSigningParams,
|
PrometheusParams, SourceConnectionParams, TargetConnectionParams, TargetSigningParams,
|
||||||
};
|
};
|
||||||
@@ -59,10 +58,6 @@ pub enum RelayHeadersBridge {
|
|||||||
MillauToRialto,
|
MillauToRialto,
|
||||||
RialtoToMillau,
|
RialtoToMillau,
|
||||||
WestendToMillau,
|
WestendToMillau,
|
||||||
RococoToWococo,
|
|
||||||
WococoToRococo,
|
|
||||||
KusamaToPolkadot,
|
|
||||||
PolkadotToKusama,
|
|
||||||
MillauToRialtoParachain,
|
MillauToRialtoParachain,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,10 +101,6 @@ where
|
|||||||
impl HeadersRelayer for MillauToRialtoCliBridge {}
|
impl HeadersRelayer for MillauToRialtoCliBridge {}
|
||||||
impl HeadersRelayer for RialtoToMillauCliBridge {}
|
impl HeadersRelayer for RialtoToMillauCliBridge {}
|
||||||
impl HeadersRelayer for WestendToMillauCliBridge {}
|
impl HeadersRelayer for WestendToMillauCliBridge {}
|
||||||
impl HeadersRelayer for RococoToWococoCliBridge {}
|
|
||||||
impl HeadersRelayer for WococoToRococoCliBridge {}
|
|
||||||
impl HeadersRelayer for KusamaToPolkadotCliBridge {}
|
|
||||||
impl HeadersRelayer for PolkadotToKusamaCliBridge {}
|
|
||||||
impl HeadersRelayer for MillauToRialtoParachainCliBridge {}
|
impl HeadersRelayer for MillauToRialtoParachainCliBridge {}
|
||||||
|
|
||||||
impl RelayHeaders {
|
impl RelayHeaders {
|
||||||
@@ -119,10 +110,6 @@ impl RelayHeaders {
|
|||||||
RelayHeadersBridge::MillauToRialto => MillauToRialtoCliBridge::relay_headers(self),
|
RelayHeadersBridge::MillauToRialto => MillauToRialtoCliBridge::relay_headers(self),
|
||||||
RelayHeadersBridge::RialtoToMillau => RialtoToMillauCliBridge::relay_headers(self),
|
RelayHeadersBridge::RialtoToMillau => RialtoToMillauCliBridge::relay_headers(self),
|
||||||
RelayHeadersBridge::WestendToMillau => WestendToMillauCliBridge::relay_headers(self),
|
RelayHeadersBridge::WestendToMillau => WestendToMillauCliBridge::relay_headers(self),
|
||||||
RelayHeadersBridge::RococoToWococo => RococoToWococoCliBridge::relay_headers(self),
|
|
||||||
RelayHeadersBridge::WococoToRococo => WococoToRococoCliBridge::relay_headers(self),
|
|
||||||
RelayHeadersBridge::KusamaToPolkadot => KusamaToPolkadotCliBridge::relay_headers(self),
|
|
||||||
RelayHeadersBridge::PolkadotToKusama => PolkadotToKusamaCliBridge::relay_headers(self),
|
|
||||||
RelayHeadersBridge::MillauToRialtoParachain =>
|
RelayHeadersBridge::MillauToRialtoParachain =>
|
||||||
MillauToRialtoParachainCliBridge::relay_headers(self),
|
MillauToRialtoParachainCliBridge::relay_headers(self),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,14 @@ use strum::VariantNames;
|
|||||||
|
|
||||||
use async_std::sync::Arc;
|
use async_std::sync::Arc;
|
||||||
use bp_polkadot_core::parachains::ParaHash;
|
use bp_polkadot_core::parachains::ParaHash;
|
||||||
use codec::Encode;
|
|
||||||
use messages_relay::relay_strategy::MixStrategy;
|
use messages_relay::relay_strategy::MixStrategy;
|
||||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
AccountIdOf, AccountKeyPairOf, BlockNumberOf, CallOf, Chain, ChainRuntimeVersion, Client,
|
AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, ChainRuntimeVersion, Client,
|
||||||
SignParam, TransactionSignScheme, UnsignedTransaction,
|
TransactionSignScheme,
|
||||||
};
|
};
|
||||||
use relay_utils::metrics::MetricsParams;
|
use relay_utils::metrics::MetricsParams;
|
||||||
use sp_core::{Bytes, Pair};
|
use sp_core::Pair;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
finality::SubstrateFinalitySyncPipeline,
|
finality::SubstrateFinalitySyncPipeline,
|
||||||
messages_lane::MessagesRelayParams,
|
messages_lane::MessagesRelayParams,
|
||||||
@@ -68,8 +67,6 @@ pub(crate) const CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO: f64 = 0.05;
|
|||||||
pub enum RelayHeadersAndMessages {
|
pub enum RelayHeadersAndMessages {
|
||||||
MillauRialto(MillauRialtoHeadersAndMessages),
|
MillauRialto(MillauRialtoHeadersAndMessages),
|
||||||
MillauRialtoParachain(MillauRialtoParachainHeadersAndMessages),
|
MillauRialtoParachain(MillauRialtoParachainHeadersAndMessages),
|
||||||
RococoWococo(RococoWococoHeadersAndMessages),
|
|
||||||
KusamaPolkadot(KusamaPolkadotHeadersAndMessages),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameters that have the same names across all bridges.
|
/// Parameters that have the same names across all bridges.
|
||||||
@@ -309,168 +306,6 @@ macro_rules! select_bridge {
|
|||||||
Err(anyhow::format_err!("Account creation is not supported by this bridge"))
|
Err(anyhow::format_err!("Account creation is not supported by this bridge"))
|
||||||
}
|
}
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
RelayHeadersAndMessages::RococoWococo(_) => {
|
|
||||||
type Params = RococoWococoHeadersAndMessages;
|
|
||||||
|
|
||||||
type Left = relay_rococo_client::Rococo;
|
|
||||||
type Right = relay_wococo_client::Wococo;
|
|
||||||
|
|
||||||
type LeftAccountIdConverter = bp_rococo::AccountIdConverter;
|
|
||||||
type RightAccountIdConverter = bp_wococo::AccountIdConverter;
|
|
||||||
|
|
||||||
use crate::chains::{
|
|
||||||
rococo_messages_to_wococo::RococoMessagesToWococo as LeftToRightMessageLane,
|
|
||||||
wococo_messages_to_rococo::WococoMessagesToRococo as RightToLeftMessageLane,
|
|
||||||
};
|
|
||||||
|
|
||||||
async fn start_on_demand_relays(
|
|
||||||
params: &Params,
|
|
||||||
left_client: Client<Left>,
|
|
||||||
right_client: Client<Right>,
|
|
||||||
at_left_relay_accounts: &mut Vec<TaggedAccount<AccountIdOf<Left>>>,
|
|
||||||
at_right_relay_accounts: &mut Vec<TaggedAccount<AccountIdOf<Right>>>,
|
|
||||||
) -> anyhow::Result<(
|
|
||||||
Arc<dyn OnDemandRelay<BlockNumberOf<Left>>>,
|
|
||||||
Arc<dyn OnDemandRelay<BlockNumberOf<Right>>>,
|
|
||||||
)> {
|
|
||||||
start_on_demand_relay_to_relay::<
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
crate::chains::rococo_headers_to_wococo::RococoFinalityToWococo,
|
|
||||||
crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo,
|
|
||||||
>(
|
|
||||||
left_client,
|
|
||||||
right_client,
|
|
||||||
params.left_headers_to_right_sign_override.transaction_params_or::<Right, _>(¶ms.right_sign)?,
|
|
||||||
params.right_headers_to_left_sign_override.transaction_params_or::<Left, _>(¶ms.left_sign)?,
|
|
||||||
params.shared.only_mandatory_headers,
|
|
||||||
params.shared.only_mandatory_headers,
|
|
||||||
params.left.can_start_version_guard(),
|
|
||||||
params.right.can_start_version_guard(),
|
|
||||||
at_left_relay_accounts,
|
|
||||||
at_right_relay_accounts,
|
|
||||||
).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn left_create_account(
|
|
||||||
left_client: Client<Left>,
|
|
||||||
left_sign: <Left as TransactionSignScheme>::AccountKeyPair,
|
|
||||||
account_id: AccountIdOf<Left>,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
submit_signed_extrinsic(
|
|
||||||
left_client,
|
|
||||||
left_sign,
|
|
||||||
relay_rococo_client::runtime::Call::Balances(
|
|
||||||
relay_rococo_client::runtime::BalancesCall::transfer(
|
|
||||||
bp_rococo::AccountAddress::Id(account_id),
|
|
||||||
bp_rococo::EXISTENTIAL_DEPOSIT.into(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn right_create_account(
|
|
||||||
right_client: Client<Right>,
|
|
||||||
right_sign: <Right as TransactionSignScheme>::AccountKeyPair,
|
|
||||||
account_id: AccountIdOf<Right>,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
submit_signed_extrinsic(
|
|
||||||
right_client,
|
|
||||||
right_sign,
|
|
||||||
relay_wococo_client::runtime::Call::Balances(
|
|
||||||
relay_wococo_client::runtime::BalancesCall::transfer(
|
|
||||||
bp_wococo::AccountAddress::Id(account_id),
|
|
||||||
bp_wococo::EXISTENTIAL_DEPOSIT.into(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
RelayHeadersAndMessages::KusamaPolkadot(_) => {
|
|
||||||
type Params = KusamaPolkadotHeadersAndMessages;
|
|
||||||
|
|
||||||
type Left = relay_kusama_client::Kusama;
|
|
||||||
type Right = relay_polkadot_client::Polkadot;
|
|
||||||
|
|
||||||
type LeftAccountIdConverter = bp_kusama::AccountIdConverter;
|
|
||||||
type RightAccountIdConverter = bp_polkadot::AccountIdConverter;
|
|
||||||
|
|
||||||
use crate::chains::{
|
|
||||||
kusama_messages_to_polkadot::KusamaMessagesToPolkadot as LeftToRightMessageLane,
|
|
||||||
polkadot_messages_to_kusama::PolkadotMessagesToKusama as RightToLeftMessageLane,
|
|
||||||
};
|
|
||||||
|
|
||||||
async fn start_on_demand_relays(
|
|
||||||
params: &Params,
|
|
||||||
left_client: Client<Left>,
|
|
||||||
right_client: Client<Right>,
|
|
||||||
at_left_relay_accounts: &mut Vec<TaggedAccount<AccountIdOf<Left>>>,
|
|
||||||
at_right_relay_accounts: &mut Vec<TaggedAccount<AccountIdOf<Right>>>,
|
|
||||||
) -> anyhow::Result<(
|
|
||||||
Arc<dyn OnDemandRelay<BlockNumberOf<Left>>>,
|
|
||||||
Arc<dyn OnDemandRelay<BlockNumberOf<Right>>>,
|
|
||||||
)> {
|
|
||||||
start_on_demand_relay_to_relay::<
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
crate::chains::kusama_headers_to_polkadot::KusamaFinalityToPolkadot,
|
|
||||||
crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama,
|
|
||||||
>(
|
|
||||||
left_client,
|
|
||||||
right_client,
|
|
||||||
params.left_headers_to_right_sign_override.transaction_params_or::<Right, _>(¶ms.right_sign)?,
|
|
||||||
params.right_headers_to_left_sign_override.transaction_params_or::<Left, _>(¶ms.left_sign)?,
|
|
||||||
params.shared.only_mandatory_headers,
|
|
||||||
params.shared.only_mandatory_headers,
|
|
||||||
params.left.can_start_version_guard(),
|
|
||||||
params.right.can_start_version_guard(),
|
|
||||||
at_left_relay_accounts,
|
|
||||||
at_right_relay_accounts,
|
|
||||||
).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn left_create_account(
|
|
||||||
left_client: Client<Left>,
|
|
||||||
left_sign: <Left as TransactionSignScheme>::AccountKeyPair,
|
|
||||||
account_id: AccountIdOf<Left>,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
submit_signed_extrinsic(
|
|
||||||
left_client,
|
|
||||||
left_sign,
|
|
||||||
relay_kusama_client::runtime::Call::Balances(
|
|
||||||
relay_kusama_client::runtime::BalancesCall::transfer(
|
|
||||||
bp_kusama::AccountAddress::Id(account_id),
|
|
||||||
bp_kusama::EXISTENTIAL_DEPOSIT.into(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn right_create_account(
|
|
||||||
right_client: Client<Right>,
|
|
||||||
right_sign: <Right as TransactionSignScheme>::AccountKeyPair,
|
|
||||||
account_id: AccountIdOf<Right>,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
submit_signed_extrinsic(
|
|
||||||
right_client,
|
|
||||||
right_sign,
|
|
||||||
relay_polkadot_client::runtime::Call::Balances(
|
|
||||||
relay_polkadot_client::runtime::BalancesCall::transfer(
|
|
||||||
bp_polkadot::AccountAddress::Id(account_id),
|
|
||||||
bp_polkadot::EXISTENTIAL_DEPOSIT.into(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
$generic
|
$generic
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -481,24 +316,14 @@ macro_rules! select_bridge {
|
|||||||
declare_chain_options!(Millau, millau);
|
declare_chain_options!(Millau, millau);
|
||||||
declare_chain_options!(Rialto, rialto);
|
declare_chain_options!(Rialto, rialto);
|
||||||
declare_chain_options!(RialtoParachain, rialto_parachain);
|
declare_chain_options!(RialtoParachain, rialto_parachain);
|
||||||
declare_chain_options!(Rococo, rococo);
|
|
||||||
declare_chain_options!(Wococo, wococo);
|
|
||||||
declare_chain_options!(Kusama, kusama);
|
|
||||||
declare_chain_options!(Polkadot, polkadot);
|
|
||||||
// Means to override signers of different layer transactions.
|
// Means to override signers of different layer transactions.
|
||||||
declare_chain_options!(MillauHeadersToRialto, millau_headers_to_rialto);
|
declare_chain_options!(MillauHeadersToRialto, millau_headers_to_rialto);
|
||||||
declare_chain_options!(MillauHeadersToRialtoParachain, millau_headers_to_rialto_parachain);
|
declare_chain_options!(MillauHeadersToRialtoParachain, millau_headers_to_rialto_parachain);
|
||||||
declare_chain_options!(RialtoHeadersToMillau, rialto_headers_to_millau);
|
declare_chain_options!(RialtoHeadersToMillau, rialto_headers_to_millau);
|
||||||
declare_chain_options!(RialtoParachainsToMillau, rialto_parachains_to_millau);
|
declare_chain_options!(RialtoParachainsToMillau, rialto_parachains_to_millau);
|
||||||
declare_chain_options!(WococoHeadersToRococo, wococo_headers_to_rococo);
|
|
||||||
declare_chain_options!(RococoHeadersToWococo, rococo_headers_to_wococo);
|
|
||||||
declare_chain_options!(KusamaHeadersToPolkadot, kusama_headers_to_polkadot);
|
|
||||||
declare_chain_options!(PolkadotHeadersToKusama, polkadot_headers_to_kusama);
|
|
||||||
// All supported bridges.
|
// All supported bridges.
|
||||||
declare_bridge_options!(Millau, Rialto);
|
declare_bridge_options!(Millau, Rialto);
|
||||||
declare_bridge_options!(Millau, RialtoParachain, Rialto);
|
declare_bridge_options!(Millau, RialtoParachain, Rialto);
|
||||||
declare_bridge_options!(Rococo, Wococo);
|
|
||||||
declare_bridge_options!(Kusama, Polkadot);
|
|
||||||
|
|
||||||
impl RelayHeadersAndMessages {
|
impl RelayHeadersAndMessages {
|
||||||
/// Run the command.
|
/// Run the command.
|
||||||
@@ -912,37 +737,6 @@ where
|
|||||||
Ok((Arc::new(left_to_right_on_demand_headers), Arc::new(right_to_left_on_demand_parachains)))
|
Ok((Arc::new(left_to_right_on_demand_headers), Arc::new(right_to_left_on_demand_parachains)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sign and submit transaction with given call to the chain.
|
|
||||||
async fn submit_signed_extrinsic<C: Chain + TransactionSignScheme<Chain = C>>(
|
|
||||||
client: Client<C>,
|
|
||||||
sign: C::AccountKeyPair,
|
|
||||||
call: CallOf<C>,
|
|
||||||
) -> anyhow::Result<()>
|
|
||||||
where
|
|
||||||
AccountIdOf<C>: From<<<C as TransactionSignScheme>::AccountKeyPair as Pair>::Public>,
|
|
||||||
CallOf<C>: Send,
|
|
||||||
{
|
|
||||||
let genesis_hash = *client.genesis_hash();
|
|
||||||
let (spec_version, transaction_version) = client.simple_runtime_version().await?;
|
|
||||||
client
|
|
||||||
.submit_signed_extrinsic(sign.public().into(), move |_, transaction_nonce| {
|
|
||||||
Ok(Bytes(
|
|
||||||
C::sign_transaction(SignParam {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash,
|
|
||||||
signer: sign,
|
|
||||||
era: relay_substrate_client::TransactionEra::immortal(),
|
|
||||||
unsigned: UnsignedTransaction::new(call.into(), transaction_nonce),
|
|
||||||
})?
|
|
||||||
.encode(),
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.map(drop)
|
|
||||||
.map_err(|e| anyhow::format_err!("{}", e))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ pub struct ResubmitTransactions {
|
|||||||
#[strum(serialize_all = "kebab_case")]
|
#[strum(serialize_all = "kebab_case")]
|
||||||
pub enum RelayChain {
|
pub enum RelayChain {
|
||||||
Millau,
|
Millau,
|
||||||
Kusama,
|
|
||||||
Polkadot,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Strategy to use for priority selection.
|
/// Strategy to use for priority selection.
|
||||||
@@ -93,18 +91,6 @@ macro_rules! select_bridge {
|
|||||||
type Target = relay_millau_client::Millau;
|
type Target = relay_millau_client::Millau;
|
||||||
type TargetSign = relay_millau_client::Millau;
|
type TargetSign = relay_millau_client::Millau;
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
RelayChain::Kusama => {
|
|
||||||
type Target = relay_kusama_client::Kusama;
|
|
||||||
type TargetSign = relay_kusama_client::Kusama;
|
|
||||||
|
|
||||||
$generic
|
|
||||||
},
|
|
||||||
RelayChain::Polkadot => {
|
|
||||||
type Target = relay_polkadot_client::Polkadot;
|
|
||||||
type TargetSign = relay_polkadot_client::Polkadot;
|
|
||||||
|
|
||||||
$generic
|
$generic
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,23 +6,14 @@ edition = "2021"
|
|||||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
|
||||||
relay-substrate-client = { path = "../client-substrate" }
|
relay-substrate-client = { path = "../client-substrate" }
|
||||||
relay-utils = { path = "../utils" }
|
relay-utils = { path = "../utils" }
|
||||||
scale-info = { version = "2.1.1", features = ["derive"] }
|
|
||||||
|
|
||||||
# Bridge dependencies
|
# Bridge dependencies
|
||||||
|
|
||||||
bp-header-chain = { path = "../../primitives/header-chain" }
|
|
||||||
bp-kusama = { path = "../../primitives/chain-kusama" }
|
bp-kusama = { path = "../../primitives/chain-kusama" }
|
||||||
bp-messages = { path = "../../primitives/messages" }
|
|
||||||
bp-polkadot = { path = "../../primitives/chain-polkadot" }
|
|
||||||
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
|
|
||||||
bp-runtime = { path = "../../primitives/runtime" }
|
|
||||||
bridge-runtime-common = { path = "../../bin/runtime-common" }
|
|
||||||
|
|
||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
|
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
|
|||||||
@@ -16,19 +16,11 @@
|
|||||||
|
|
||||||
//! Types used to connect to the Kusama chain.
|
//! Types used to connect to the Kusama chain.
|
||||||
|
|
||||||
use bp_messages::MessageNonce;
|
|
||||||
use codec::Encode;
|
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa};
|
||||||
Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
|
use sp_core::storage::StorageKey;
|
||||||
Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction,
|
|
||||||
};
|
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub mod runtime;
|
|
||||||
|
|
||||||
/// Kusama header id.
|
/// Kusama header id.
|
||||||
pub type HeaderId = relay_utils::HeaderId<bp_kusama::Hash, bp_kusama::BlockNumber>;
|
pub type HeaderId = relay_utils::HeaderId<bp_kusama::Hash, bp_kusama::BlockNumber>;
|
||||||
|
|
||||||
@@ -65,7 +57,7 @@ impl Chain for Kusama {
|
|||||||
const STORAGE_PROOF_OVERHEAD: u32 = bp_kusama::EXTRA_STORAGE_PROOF_SIZE;
|
const STORAGE_PROOF_OVERHEAD: u32 = bp_kusama::EXTRA_STORAGE_PROOF_SIZE;
|
||||||
|
|
||||||
type SignedBlock = bp_kusama::SignedBlock;
|
type SignedBlock = bp_kusama::SignedBlock;
|
||||||
type Call = crate::runtime::Call;
|
type Call = ();
|
||||||
type WeightToFee = bp_kusama::WeightToFee;
|
type WeightToFee = bp_kusama::WeightToFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,80 +65,11 @@ impl ChainWithGrandpa for Kusama {
|
|||||||
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_kusama::WITH_KUSAMA_GRANDPA_PALLET_NAME;
|
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_kusama::WITH_KUSAMA_GRANDPA_PALLET_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChainWithMessages for Kusama {
|
|
||||||
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
|
|
||||||
bp_kusama::WITH_KUSAMA_MESSAGES_PALLET_NAME;
|
|
||||||
const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_kusama::TO_KUSAMA_MESSAGE_DETAILS_METHOD;
|
|
||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_kusama::FROM_KUSAMA_MESSAGE_DETAILS_METHOD;
|
|
||||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight =
|
|
||||||
bp_kusama::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
|
||||||
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_kusama::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
|
|
||||||
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_kusama::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
|
|
||||||
type WeightInfo = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChainWithBalances for Kusama {
|
impl ChainWithBalances for Kusama {
|
||||||
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
||||||
StorageKey(bp_kusama::account_info_storage_key(account_id))
|
StorageKey(bp_kusama::account_info_storage_key(account_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionSignScheme for Kusama {
|
|
||||||
type Chain = Kusama;
|
|
||||||
type AccountKeyPair = sp_core::sr25519::Pair;
|
|
||||||
type SignedTransaction = crate::runtime::UncheckedExtrinsic;
|
|
||||||
|
|
||||||
fn sign_transaction(param: SignParam<Self>) -> Result<Self::SignedTransaction, SubstrateError> {
|
|
||||||
let raw_payload = SignedPayload::new(
|
|
||||||
param.unsigned.call.clone(),
|
|
||||||
bp_kusama::SignedExtensions::new(
|
|
||||||
param.spec_version,
|
|
||||||
param.transaction_version,
|
|
||||||
param.era,
|
|
||||||
param.genesis_hash,
|
|
||||||
param.unsigned.nonce,
|
|
||||||
param.unsigned.tip,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("SignedExtension never fails.");
|
|
||||||
|
|
||||||
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
|
|
||||||
let signer: sp_runtime::MultiSigner = param.signer.public().into();
|
|
||||||
let (call, extra, _) = raw_payload.deconstruct();
|
|
||||||
|
|
||||||
Ok(bp_kusama::UncheckedExtrinsic::new_signed(
|
|
||||||
call,
|
|
||||||
sp_runtime::MultiAddress::Id(signer.into_account()),
|
|
||||||
signature.into(),
|
|
||||||
extra,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed(tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature
|
|
||||||
.as_ref()
|
|
||||||
.map(|(address, _, _)| {
|
|
||||||
*address == bp_kusama::AccountId::from(*signer.public().as_array_ref()).into()
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
|
|
||||||
let extra = &tx.signature.as_ref()?.2;
|
|
||||||
Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Kusama header type used in headers sync.
|
/// Kusama header type used in headers sync.
|
||||||
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_kusama::Header>;
|
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_kusama::Header>;
|
||||||
|
|
||||||
/// Kusama signing params.
|
|
||||||
pub type SigningParams = sp_core::sr25519::Pair;
|
|
||||||
|
|||||||
@@ -1,133 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Types that are specific to the Kusama runtime.
|
|
||||||
|
|
||||||
use bp_messages::{LaneId, UnrewardedRelayersState};
|
|
||||||
use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike};
|
|
||||||
use bp_runtime::Chain;
|
|
||||||
use codec::{Compact, Decode, Encode};
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use scale_info::TypeInfo;
|
|
||||||
use sp_runtime::FixedU128;
|
|
||||||
|
|
||||||
/// Unchecked Kusama extrinsic.
|
|
||||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
|
||||||
|
|
||||||
/// Kusama Runtime `Call` enum.
|
|
||||||
///
|
|
||||||
/// The enum represents a subset of possible `Call`s we can send to Kusama chain.
|
|
||||||
/// Ideally this code would be auto-generated from metadata, because we want to
|
|
||||||
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
|
|
||||||
///
|
|
||||||
/// All entries here (like pretty much in the entire file) must be kept in sync with Kusama
|
|
||||||
/// `construct_runtime`, so that we maintain SCALE-compatibility.
|
|
||||||
///
|
|
||||||
/// See: [link](https://github.com/paritytech/polkadot/blob/master/runtime/kusama/src/lib.rs)
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
pub enum Call {
|
|
||||||
/// System pallet.
|
|
||||||
#[codec(index = 0)]
|
|
||||||
System(SystemCall),
|
|
||||||
/// Balances pallet.
|
|
||||||
#[codec(index = 4)]
|
|
||||||
Balances(BalancesCall),
|
|
||||||
/// Utility pallet.
|
|
||||||
#[codec(index = 24)]
|
|
||||||
Utility(UtilityCall),
|
|
||||||
/// Polkadot bridge pallet.
|
|
||||||
#[codec(index = 110)]
|
|
||||||
BridgePolkadotGrandpa(BridgePolkadotGrandpaCall),
|
|
||||||
/// Polkadot messages pallet.
|
|
||||||
#[codec(index = 111)]
|
|
||||||
BridgePolkadotMessages(BridgePolkadotMessagesCall),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum SystemCall {
|
|
||||||
#[codec(index = 1)]
|
|
||||||
remark(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BalancesCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
transfer(AccountAddress, Compact<Balance>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgePolkadotGrandpaCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
submit_finality_proof(
|
|
||||||
Box<<PolkadotLike as Chain>::Header>,
|
|
||||||
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
|
|
||||||
),
|
|
||||||
#[codec(index = 1)]
|
|
||||||
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
|
|
||||||
#[codec(index = 3)]
|
|
||||||
set_operational(bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgePolkadotMessagesCall {
|
|
||||||
#[codec(index = 2)]
|
|
||||||
update_pallet_parameter(BridgePolkadotMessagesParameter),
|
|
||||||
#[codec(index = 3)]
|
|
||||||
send_message(LaneId, Vec<u8>, bp_kusama::Balance),
|
|
||||||
#[codec(index = 5)]
|
|
||||||
receive_messages_proof(
|
|
||||||
bp_polkadot::AccountId,
|
|
||||||
bridge_runtime_common::messages::target::FromBridgedChainMessagesProof<bp_polkadot::Hash>,
|
|
||||||
u32,
|
|
||||||
Weight,
|
|
||||||
),
|
|
||||||
#[codec(index = 6)]
|
|
||||||
receive_messages_delivery_proof(
|
|
||||||
bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof<
|
|
||||||
bp_polkadot::Hash,
|
|
||||||
>,
|
|
||||||
UnrewardedRelayersState,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum UtilityCall {
|
|
||||||
#[codec(index = 2)]
|
|
||||||
batch_all(Vec<Call>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
pub enum BridgePolkadotMessagesParameter {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
PolkadotToKusamaConversionRate(FixedU128),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sp_runtime::traits::Dispatchable for Call {
|
|
||||||
type Origin = ();
|
|
||||||
type Config = ();
|
|
||||||
type Info = ();
|
|
||||||
type PostInfo = ();
|
|
||||||
|
|
||||||
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
|
|
||||||
unimplemented!("The Call is not expected to be dispatched.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,23 +6,14 @@ edition = "2021"
|
|||||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
|
||||||
relay-substrate-client = { path = "../client-substrate" }
|
relay-substrate-client = { path = "../client-substrate" }
|
||||||
relay-utils = { path = "../utils" }
|
relay-utils = { path = "../utils" }
|
||||||
scale-info = { version = "2.1.1", features = ["derive"] }
|
|
||||||
|
|
||||||
# Bridge dependencies
|
# Bridge dependencies
|
||||||
|
|
||||||
bp-header-chain = { path = "../../primitives/header-chain" }
|
|
||||||
bp-kusama = { path = "../../primitives/chain-kusama" }
|
|
||||||
bp-messages = { path = "../../primitives/messages" }
|
|
||||||
bp-polkadot = { path = "../../primitives/chain-polkadot" }
|
bp-polkadot = { path = "../../primitives/chain-polkadot" }
|
||||||
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
|
|
||||||
bp-runtime = { path = "../../primitives/runtime" }
|
|
||||||
bridge-runtime-common = { path = "../../bin/runtime-common" }
|
|
||||||
|
|
||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
|
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
|
|||||||
@@ -16,19 +16,11 @@
|
|||||||
|
|
||||||
//! Types used to connect to the Polkadot chain.
|
//! Types used to connect to the Polkadot chain.
|
||||||
|
|
||||||
use bp_messages::MessageNonce;
|
|
||||||
use codec::Encode;
|
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa};
|
||||||
Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
|
use sp_core::storage::StorageKey;
|
||||||
Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction,
|
|
||||||
};
|
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub mod runtime;
|
|
||||||
|
|
||||||
/// Polkadot header id.
|
/// Polkadot header id.
|
||||||
pub type HeaderId = relay_utils::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockNumber>;
|
pub type HeaderId = relay_utils::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockNumber>;
|
||||||
|
|
||||||
@@ -65,7 +57,7 @@ impl Chain for Polkadot {
|
|||||||
const STORAGE_PROOF_OVERHEAD: u32 = bp_polkadot::EXTRA_STORAGE_PROOF_SIZE;
|
const STORAGE_PROOF_OVERHEAD: u32 = bp_polkadot::EXTRA_STORAGE_PROOF_SIZE;
|
||||||
|
|
||||||
type SignedBlock = bp_polkadot::SignedBlock;
|
type SignedBlock = bp_polkadot::SignedBlock;
|
||||||
type Call = crate::runtime::Call;
|
type Call = ();
|
||||||
type WeightToFee = bp_polkadot::WeightToFee;
|
type WeightToFee = bp_polkadot::WeightToFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,80 +66,11 @@ impl ChainWithGrandpa for Polkadot {
|
|||||||
bp_polkadot::WITH_POLKADOT_GRANDPA_PALLET_NAME;
|
bp_polkadot::WITH_POLKADOT_GRANDPA_PALLET_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChainWithMessages for Polkadot {
|
|
||||||
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
|
|
||||||
bp_polkadot::WITH_POLKADOT_MESSAGES_PALLET_NAME;
|
|
||||||
const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_polkadot::TO_POLKADOT_MESSAGE_DETAILS_METHOD;
|
|
||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_polkadot::FROM_POLKADOT_MESSAGE_DETAILS_METHOD;
|
|
||||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight =
|
|
||||||
bp_polkadot::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
|
||||||
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_polkadot::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
|
|
||||||
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_polkadot::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
|
|
||||||
type WeightInfo = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChainWithBalances for Polkadot {
|
impl ChainWithBalances for Polkadot {
|
||||||
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
||||||
StorageKey(bp_polkadot::account_info_storage_key(account_id))
|
StorageKey(bp_polkadot::account_info_storage_key(account_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionSignScheme for Polkadot {
|
|
||||||
type Chain = Polkadot;
|
|
||||||
type AccountKeyPair = sp_core::sr25519::Pair;
|
|
||||||
type SignedTransaction = crate::runtime::UncheckedExtrinsic;
|
|
||||||
|
|
||||||
fn sign_transaction(param: SignParam<Self>) -> Result<Self::SignedTransaction, SubstrateError> {
|
|
||||||
let raw_payload = SignedPayload::new(
|
|
||||||
param.unsigned.call.clone(),
|
|
||||||
bp_polkadot::SignedExtensions::new(
|
|
||||||
param.spec_version,
|
|
||||||
param.transaction_version,
|
|
||||||
param.era,
|
|
||||||
param.genesis_hash,
|
|
||||||
param.unsigned.nonce,
|
|
||||||
param.unsigned.tip,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("SignedExtension never fails.");
|
|
||||||
|
|
||||||
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
|
|
||||||
let signer: sp_runtime::MultiSigner = param.signer.public().into();
|
|
||||||
let (call, extra, _) = raw_payload.deconstruct();
|
|
||||||
|
|
||||||
Ok(bp_polkadot::UncheckedExtrinsic::new_signed(
|
|
||||||
call,
|
|
||||||
sp_runtime::MultiAddress::Id(signer.into_account()),
|
|
||||||
signature.into(),
|
|
||||||
extra,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed(tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature
|
|
||||||
.as_ref()
|
|
||||||
.map(|(address, _, _)| {
|
|
||||||
*address == bp_polkadot::AccountId::from(*signer.public().as_array_ref()).into()
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
|
|
||||||
let extra = &tx.signature.as_ref()?.2;
|
|
||||||
Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Polkadot header type used in headers sync.
|
/// Polkadot header type used in headers sync.
|
||||||
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_polkadot::Header>;
|
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_polkadot::Header>;
|
||||||
|
|
||||||
/// Polkadot signing params.
|
|
||||||
pub type SigningParams = sp_core::sr25519::Pair;
|
|
||||||
|
|||||||
@@ -1,133 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Types that are specific to the Polkadot runtime.
|
|
||||||
|
|
||||||
use bp_messages::{LaneId, UnrewardedRelayersState};
|
|
||||||
use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike};
|
|
||||||
use bp_runtime::Chain;
|
|
||||||
use codec::{Compact, Decode, Encode};
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use scale_info::TypeInfo;
|
|
||||||
use sp_runtime::FixedU128;
|
|
||||||
|
|
||||||
/// Unchecked Polkadot extrinsic.
|
|
||||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
|
||||||
|
|
||||||
/// Polkadot Runtime `Call` enum.
|
|
||||||
///
|
|
||||||
/// The enum represents a subset of possible `Call`s we can send to Polkadot chain.
|
|
||||||
/// Ideally this code would be auto-generated from metadata, because we want to
|
|
||||||
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
|
|
||||||
///
|
|
||||||
/// All entries here (like pretty much in the entire file) must be kept in sync with Polkadot
|
|
||||||
/// `construct_runtime`, so that we maintain SCALE-compatibility.
|
|
||||||
///
|
|
||||||
/// See: [link](https://github.com/paritytech/kusama/blob/master/runtime/kusam/src/lib.rs)
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
pub enum Call {
|
|
||||||
/// System pallet.
|
|
||||||
#[codec(index = 0)]
|
|
||||||
System(SystemCall),
|
|
||||||
/// Balances pallet.
|
|
||||||
#[codec(index = 5)]
|
|
||||||
Balances(BalancesCall),
|
|
||||||
/// Utility pallet.
|
|
||||||
#[codec(index = 26)]
|
|
||||||
Utility(UtilityCall),
|
|
||||||
/// Kusama bridge pallet.
|
|
||||||
#[codec(index = 110)]
|
|
||||||
BridgeKusamaGrandpa(BridgeKusamaGrandpaCall),
|
|
||||||
/// Kusama messages pallet.
|
|
||||||
#[codec(index = 111)]
|
|
||||||
BridgeKusamaMessages(BridgeKusamaMessagesCall),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum SystemCall {
|
|
||||||
#[codec(index = 1)]
|
|
||||||
remark(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BalancesCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
transfer(AccountAddress, Compact<Balance>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgeKusamaGrandpaCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
submit_finality_proof(
|
|
||||||
Box<<PolkadotLike as Chain>::Header>,
|
|
||||||
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
|
|
||||||
),
|
|
||||||
#[codec(index = 1)]
|
|
||||||
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
|
|
||||||
#[codec(index = 3)]
|
|
||||||
set_operational(bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgeKusamaMessagesCall {
|
|
||||||
#[codec(index = 2)]
|
|
||||||
update_pallet_parameter(BridgeKusamaMessagesParameter),
|
|
||||||
#[codec(index = 3)]
|
|
||||||
send_message(LaneId, Vec<u8>, bp_polkadot::Balance),
|
|
||||||
#[codec(index = 5)]
|
|
||||||
receive_messages_proof(
|
|
||||||
bp_kusama::AccountId,
|
|
||||||
bridge_runtime_common::messages::target::FromBridgedChainMessagesProof<bp_kusama::Hash>,
|
|
||||||
u32,
|
|
||||||
Weight,
|
|
||||||
),
|
|
||||||
#[codec(index = 6)]
|
|
||||||
receive_messages_delivery_proof(
|
|
||||||
bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof<
|
|
||||||
bp_kusama::Hash,
|
|
||||||
>,
|
|
||||||
UnrewardedRelayersState,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum UtilityCall {
|
|
||||||
#[codec(index = 2)]
|
|
||||||
batch_all(Vec<Call>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
pub enum BridgeKusamaMessagesParameter {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
KusamaToPolkadotConversionRate(FixedU128),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sp_runtime::traits::Dispatchable for Call {
|
|
||||||
type Origin = ();
|
|
||||||
type Config = ();
|
|
||||||
type Info = ();
|
|
||||||
type PostInfo = ();
|
|
||||||
|
|
||||||
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
|
|
||||||
unimplemented!("The Call is not expected to be dispatched.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,24 +6,14 @@ edition = "2021"
|
|||||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
|
||||||
relay-substrate-client = { path = "../client-substrate" }
|
relay-substrate-client = { path = "../client-substrate" }
|
||||||
relay-utils = { path = "../utils" }
|
relay-utils = { path = "../utils" }
|
||||||
scale-info = { version = "2.1.1", features = ["derive"] }
|
|
||||||
|
|
||||||
# Bridge dependencies
|
# Bridge dependencies
|
||||||
|
|
||||||
bridge-runtime-common = { path = "../../bin/runtime-common" }
|
|
||||||
bp-header-chain = { path = "../../primitives/header-chain" }
|
|
||||||
bp-messages = { path = "../../primitives/messages" }
|
|
||||||
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
|
|
||||||
bp-rococo = { path = "../../primitives/chain-rococo" }
|
bp-rococo = { path = "../../primitives/chain-rococo" }
|
||||||
bp-runtime = { path = "../../primitives/runtime" }
|
|
||||||
bp-wococo = { path = "../../primitives/chain-wococo" }
|
|
||||||
pallet-bridge-messages = { path = "../../modules/messages" }
|
|
||||||
|
|
||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
|
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
|
|||||||
@@ -16,19 +16,11 @@
|
|||||||
|
|
||||||
//! Types used to connect to the Rococo-Substrate chain.
|
//! Types used to connect to the Rococo-Substrate chain.
|
||||||
|
|
||||||
use bp_messages::MessageNonce;
|
|
||||||
use codec::Encode;
|
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa};
|
||||||
Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
|
use sp_core::storage::StorageKey;
|
||||||
Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction,
|
|
||||||
};
|
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub mod runtime;
|
|
||||||
|
|
||||||
/// Rococo header id.
|
/// Rococo header id.
|
||||||
pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>;
|
pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>;
|
||||||
|
|
||||||
@@ -68,7 +60,7 @@ impl Chain for Rococo {
|
|||||||
const STORAGE_PROOF_OVERHEAD: u32 = bp_rococo::EXTRA_STORAGE_PROOF_SIZE;
|
const STORAGE_PROOF_OVERHEAD: u32 = bp_rococo::EXTRA_STORAGE_PROOF_SIZE;
|
||||||
|
|
||||||
type SignedBlock = bp_rococo::SignedBlock;
|
type SignedBlock = bp_rococo::SignedBlock;
|
||||||
type Call = crate::runtime::Call;
|
type Call = ();
|
||||||
type WeightToFee = bp_rococo::WeightToFee;
|
type WeightToFee = bp_rococo::WeightToFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,77 +68,8 @@ impl ChainWithGrandpa for Rococo {
|
|||||||
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_rococo::WITH_ROCOCO_GRANDPA_PALLET_NAME;
|
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_rococo::WITH_ROCOCO_GRANDPA_PALLET_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChainWithMessages for Rococo {
|
|
||||||
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
|
|
||||||
bp_rococo::WITH_ROCOCO_MESSAGES_PALLET_NAME;
|
|
||||||
const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_rococo::TO_ROCOCO_MESSAGE_DETAILS_METHOD;
|
|
||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_rococo::FROM_ROCOCO_MESSAGE_DETAILS_METHOD;
|
|
||||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight =
|
|
||||||
bp_rococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
|
||||||
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
|
|
||||||
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
|
|
||||||
type WeightInfo = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChainWithBalances for Rococo {
|
impl ChainWithBalances for Rococo {
|
||||||
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
||||||
StorageKey(bp_rococo::account_info_storage_key(account_id))
|
StorageKey(bp_rococo::account_info_storage_key(account_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionSignScheme for Rococo {
|
|
||||||
type Chain = Rococo;
|
|
||||||
type AccountKeyPair = sp_core::sr25519::Pair;
|
|
||||||
type SignedTransaction = crate::runtime::UncheckedExtrinsic;
|
|
||||||
|
|
||||||
fn sign_transaction(param: SignParam<Self>) -> Result<Self::SignedTransaction, SubstrateError> {
|
|
||||||
let raw_payload = SignedPayload::new(
|
|
||||||
param.unsigned.call.clone(),
|
|
||||||
bp_rococo::SignedExtensions::new(
|
|
||||||
param.spec_version,
|
|
||||||
param.transaction_version,
|
|
||||||
param.era,
|
|
||||||
param.genesis_hash,
|
|
||||||
param.unsigned.nonce,
|
|
||||||
param.unsigned.tip,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("SignedExtension never fails.");
|
|
||||||
|
|
||||||
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
|
|
||||||
let signer: sp_runtime::MultiSigner = param.signer.public().into();
|
|
||||||
let (call, extra, _) = raw_payload.deconstruct();
|
|
||||||
|
|
||||||
Ok(bp_rococo::UncheckedExtrinsic::new_signed(
|
|
||||||
call,
|
|
||||||
sp_runtime::MultiAddress::Id(signer.into_account()),
|
|
||||||
signature.into(),
|
|
||||||
extra,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed(tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature
|
|
||||||
.as_ref()
|
|
||||||
.map(|(address, _, _)| {
|
|
||||||
*address == bp_rococo::AccountId::from(*signer.public().as_array_ref()).into()
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
|
|
||||||
let extra = &tx.signature.as_ref()?.2;
|
|
||||||
Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rococo signing params.
|
|
||||||
pub type SigningParams = sp_core::sr25519::Pair;
|
|
||||||
|
|||||||
@@ -1,112 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Types that are specific to the Rococo runtime.
|
|
||||||
|
|
||||||
use bp_messages::{LaneId, UnrewardedRelayersState};
|
|
||||||
use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike};
|
|
||||||
use bp_runtime::Chain;
|
|
||||||
use codec::{Compact, Decode, Encode};
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use scale_info::TypeInfo;
|
|
||||||
|
|
||||||
/// Unchecked Rococo extrinsic.
|
|
||||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
|
||||||
|
|
||||||
/// Rococo Runtime `Call` enum.
|
|
||||||
///
|
|
||||||
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
|
|
||||||
/// Ideally this code would be auto-generated from metadata, because we want to
|
|
||||||
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
|
|
||||||
///
|
|
||||||
/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo
|
|
||||||
/// `construct_runtime`, so that we maintain SCALE-compatibility.
|
|
||||||
///
|
|
||||||
/// See: [link](https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs)
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
pub enum Call {
|
|
||||||
/// System pallet.
|
|
||||||
#[codec(index = 0)]
|
|
||||||
System(SystemCall),
|
|
||||||
/// Balances pallet.
|
|
||||||
#[codec(index = 4)]
|
|
||||||
Balances(BalancesCall),
|
|
||||||
/// Wococo bridge pallet.
|
|
||||||
#[codec(index = 41)]
|
|
||||||
BridgeGrandpaWococo(BridgeGrandpaWococoCall),
|
|
||||||
/// Wococo messages pallet.
|
|
||||||
#[codec(index = 44)]
|
|
||||||
BridgeWococoMessages(BridgeWococoMessagesCall),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum SystemCall {
|
|
||||||
#[codec(index = 1)]
|
|
||||||
remark(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BalancesCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
transfer(AccountAddress, Compact<Balance>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgeGrandpaWococoCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
submit_finality_proof(
|
|
||||||
Box<<PolkadotLike as Chain>::Header>,
|
|
||||||
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
|
|
||||||
),
|
|
||||||
#[codec(index = 1)]
|
|
||||||
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgeWococoMessagesCall {
|
|
||||||
#[codec(index = 3)]
|
|
||||||
send_message(LaneId, Vec<u8>, bp_rococo::Balance),
|
|
||||||
#[codec(index = 5)]
|
|
||||||
receive_messages_proof(
|
|
||||||
bp_wococo::AccountId,
|
|
||||||
bridge_runtime_common::messages::target::FromBridgedChainMessagesProof<bp_wococo::Hash>,
|
|
||||||
u32,
|
|
||||||
Weight,
|
|
||||||
),
|
|
||||||
#[codec(index = 6)]
|
|
||||||
receive_messages_delivery_proof(
|
|
||||||
bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof<
|
|
||||||
bp_wococo::Hash,
|
|
||||||
>,
|
|
||||||
UnrewardedRelayersState,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sp_runtime::traits::Dispatchable for Call {
|
|
||||||
type Origin = ();
|
|
||||||
type Config = ();
|
|
||||||
type Info = ();
|
|
||||||
type PostInfo = ();
|
|
||||||
|
|
||||||
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
|
|
||||||
unimplemented!("The Call is not expected to be dispatched.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,22 +6,13 @@ edition = "2021"
|
|||||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
|
||||||
relay-substrate-client = { path = "../client-substrate" }
|
relay-substrate-client = { path = "../client-substrate" }
|
||||||
relay-utils = { path = "../utils" }
|
relay-utils = { path = "../utils" }
|
||||||
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
|
|
||||||
|
|
||||||
# Bridge dependencies
|
# Bridge dependencies
|
||||||
bridge-runtime-common = { path = "../../bin/runtime-common" }
|
|
||||||
bp-header-chain = { path = "../../primitives/header-chain" }
|
|
||||||
bp-messages = { path = "../../primitives/messages" }
|
|
||||||
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
|
|
||||||
bp-rococo = { path = "../../primitives/chain-rococo" }
|
|
||||||
bp-runtime = { path = "../../primitives/runtime" }
|
|
||||||
bp-wococo = { path = "../../primitives/chain-wococo" }
|
bp-wococo = { path = "../../primitives/chain-wococo" }
|
||||||
pallet-bridge-messages = { path = "../../modules/messages" }
|
|
||||||
|
|
||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
|
|||||||
@@ -16,19 +16,11 @@
|
|||||||
|
|
||||||
//! Types used to connect to the Wococo-Substrate chain.
|
//! Types used to connect to the Wococo-Substrate chain.
|
||||||
|
|
||||||
use bp_messages::MessageNonce;
|
|
||||||
use codec::Encode;
|
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa};
|
||||||
Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
|
use sp_core::storage::StorageKey;
|
||||||
Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction,
|
|
||||||
};
|
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub mod runtime;
|
|
||||||
|
|
||||||
/// Wococo header id.
|
/// Wococo header id.
|
||||||
pub type HeaderId = relay_utils::HeaderId<bp_wococo::Hash, bp_wococo::BlockNumber>;
|
pub type HeaderId = relay_utils::HeaderId<bp_wococo::Hash, bp_wococo::BlockNumber>;
|
||||||
|
|
||||||
@@ -68,7 +60,7 @@ impl Chain for Wococo {
|
|||||||
const STORAGE_PROOF_OVERHEAD: u32 = bp_wococo::EXTRA_STORAGE_PROOF_SIZE;
|
const STORAGE_PROOF_OVERHEAD: u32 = bp_wococo::EXTRA_STORAGE_PROOF_SIZE;
|
||||||
|
|
||||||
type SignedBlock = bp_wococo::SignedBlock;
|
type SignedBlock = bp_wococo::SignedBlock;
|
||||||
type Call = crate::runtime::Call;
|
type Call = ();
|
||||||
type WeightToFee = bp_wococo::WeightToFee;
|
type WeightToFee = bp_wococo::WeightToFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,77 +68,8 @@ impl ChainWithGrandpa for Wococo {
|
|||||||
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_wococo::WITH_WOCOCO_GRANDPA_PALLET_NAME;
|
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = bp_wococo::WITH_WOCOCO_GRANDPA_PALLET_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChainWithMessages for Wococo {
|
|
||||||
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
|
|
||||||
bp_wococo::WITH_WOCOCO_MESSAGES_PALLET_NAME;
|
|
||||||
const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_wococo::TO_WOCOCO_MESSAGE_DETAILS_METHOD;
|
|
||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
|
||||||
bp_wococo::FROM_WOCOCO_MESSAGE_DETAILS_METHOD;
|
|
||||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight =
|
|
||||||
bp_wococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
|
||||||
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_wococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
|
|
||||||
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
|
|
||||||
bp_wococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
|
|
||||||
type WeightInfo = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChainWithBalances for Wococo {
|
impl ChainWithBalances for Wococo {
|
||||||
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
||||||
StorageKey(bp_wococo::account_info_storage_key(account_id))
|
StorageKey(bp_wococo::account_info_storage_key(account_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionSignScheme for Wococo {
|
|
||||||
type Chain = Wococo;
|
|
||||||
type AccountKeyPair = sp_core::sr25519::Pair;
|
|
||||||
type SignedTransaction = crate::runtime::UncheckedExtrinsic;
|
|
||||||
|
|
||||||
fn sign_transaction(param: SignParam<Self>) -> Result<Self::SignedTransaction, SubstrateError> {
|
|
||||||
let raw_payload = SignedPayload::new(
|
|
||||||
param.unsigned.call.clone(),
|
|
||||||
bp_wococo::SignedExtensions::new(
|
|
||||||
param.spec_version,
|
|
||||||
param.transaction_version,
|
|
||||||
param.era,
|
|
||||||
param.genesis_hash,
|
|
||||||
param.unsigned.nonce,
|
|
||||||
param.unsigned.tip,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("SignedExtension never fails.");
|
|
||||||
|
|
||||||
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
|
|
||||||
let signer: sp_runtime::MultiSigner = param.signer.public().into();
|
|
||||||
let (call, extra, _) = raw_payload.deconstruct();
|
|
||||||
|
|
||||||
Ok(bp_wococo::UncheckedExtrinsic::new_signed(
|
|
||||||
call,
|
|
||||||
sp_runtime::MultiAddress::Id(signer.into_account()),
|
|
||||||
signature.into(),
|
|
||||||
extra,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed(tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
|
|
||||||
tx.signature
|
|
||||||
.as_ref()
|
|
||||||
.map(|(address, _, _)| {
|
|
||||||
*address == bp_wococo::AccountId::from(*signer.public().as_array_ref()).into()
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
|
|
||||||
let extra = &tx.signature.as_ref()?.2;
|
|
||||||
Some(UnsignedTransaction { call: tx.function, nonce: extra.nonce(), tip: extra.tip() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wococo signing params.
|
|
||||||
pub type SigningParams = sp_core::sr25519::Pair;
|
|
||||||
|
|||||||
@@ -1,112 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Types that are specific to the Wococo runtime.
|
|
||||||
|
|
||||||
use bp_messages::{LaneId, UnrewardedRelayersState};
|
|
||||||
use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike};
|
|
||||||
use bp_runtime::Chain;
|
|
||||||
use codec::{Compact, Decode, Encode};
|
|
||||||
use frame_support::weights::Weight;
|
|
||||||
use scale_info::TypeInfo;
|
|
||||||
|
|
||||||
/// Unchecked Wococo extrinsic.
|
|
||||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
|
||||||
|
|
||||||
/// Wococo Runtime `Call` enum.
|
|
||||||
///
|
|
||||||
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
|
|
||||||
/// Ideally this code would be auto-generated from metadata, because we want to
|
|
||||||
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
|
|
||||||
///
|
|
||||||
/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo
|
|
||||||
/// `construct_runtime`, so that we maintain SCALE-compatibility.
|
|
||||||
///
|
|
||||||
/// See: [link](https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs)
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
pub enum Call {
|
|
||||||
/// System pallet.
|
|
||||||
#[codec(index = 0)]
|
|
||||||
System(SystemCall),
|
|
||||||
/// Balances pallet.
|
|
||||||
#[codec(index = 4)]
|
|
||||||
Balances(BalancesCall),
|
|
||||||
/// Rococo bridge pallet.
|
|
||||||
#[codec(index = 40)]
|
|
||||||
BridgeGrandpaRococo(BridgeGrandpaRococoCall),
|
|
||||||
/// Rococo messages pallet.
|
|
||||||
#[codec(index = 43)]
|
|
||||||
BridgeRococoMessages(BridgeRococoMessagesCall),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum SystemCall {
|
|
||||||
#[codec(index = 1)]
|
|
||||||
remark(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BalancesCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
transfer(AccountAddress, Compact<Balance>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgeGrandpaRococoCall {
|
|
||||||
#[codec(index = 0)]
|
|
||||||
submit_finality_proof(
|
|
||||||
Box<<PolkadotLike as Chain>::Header>,
|
|
||||||
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
|
|
||||||
),
|
|
||||||
#[codec(index = 1)]
|
|
||||||
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum BridgeRococoMessagesCall {
|
|
||||||
#[codec(index = 3)]
|
|
||||||
send_message(LaneId, Vec<u8>, bp_rococo::Balance),
|
|
||||||
#[codec(index = 5)]
|
|
||||||
receive_messages_proof(
|
|
||||||
bp_rococo::AccountId,
|
|
||||||
bridge_runtime_common::messages::target::FromBridgedChainMessagesProof<bp_rococo::Hash>,
|
|
||||||
u32,
|
|
||||||
Weight,
|
|
||||||
),
|
|
||||||
#[codec(index = 6)]
|
|
||||||
receive_messages_delivery_proof(
|
|
||||||
bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof<
|
|
||||||
bp_rococo::Hash,
|
|
||||||
>,
|
|
||||||
UnrewardedRelayersState,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sp_runtime::traits::Dispatchable for Call {
|
|
||||||
type Origin = ();
|
|
||||||
type Config = ();
|
|
||||||
type Info = ();
|
|
||||||
type PostInfo = ();
|
|
||||||
|
|
||||||
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
|
|
||||||
unimplemented!("The Call is not expected to be dispatched.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -51,6 +51,7 @@ bp-rialto = { path = "../../primitives/chain-rialto" }
|
|||||||
bp-rococo = { path = "../../primitives/chain-rococo" }
|
bp-rococo = { path = "../../primitives/chain-rococo" }
|
||||||
bp-wococo = { path = "../../primitives/chain-wococo" }
|
bp-wococo = { path = "../../primitives/chain-wococo" }
|
||||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
relay-rialto-client = { path = "../client-rialto" }
|
||||||
relay-rococo-client = { path = "../client-rococo" }
|
relay-rococo-client = { path = "../client-rococo" }
|
||||||
relay-wococo-client = { path = "../client-wococo" }
|
relay-wococo-client = { path = "../client-wococo" }
|
||||||
rialto-runtime = { path = "../../bin/rialto/runtime" }
|
rialto-runtime = { path = "../../bin/rialto/runtime" }
|
||||||
|
|||||||
@@ -522,6 +522,7 @@ fn compute_prepaid_messages_refund<C: ChainWithMessages>(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use relay_rialto_client::Rialto;
|
||||||
use relay_rococo_client::Rococo;
|
use relay_rococo_client::Rococo;
|
||||||
use relay_wococo_client::Wococo;
|
use relay_wococo_client::Wococo;
|
||||||
|
|
||||||
@@ -581,10 +582,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn compute_prepaid_messages_refund_returns_sane_results() {
|
fn compute_prepaid_messages_refund_returns_sane_results() {
|
||||||
assert!(
|
assert!(
|
||||||
compute_prepaid_messages_refund::<Wococo>(
|
compute_prepaid_messages_refund::<Rialto>(
|
||||||
10,
|
10,
|
||||||
FixedU128::saturating_from_rational(110, 100),
|
FixedU128::saturating_from_rational(110, 100),
|
||||||
) > (10 * Wococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN).into()
|
) > (10 * Rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN).into()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user