Drop Rialto <> Millau bridges (#2663) (#2694)

* drop Rialto <> Millau bridges

* clippy
This commit is contained in:
Svyatoslav Nikolsky
2023-11-14 11:50:26 +03:00
committed by Bastian Köcher
parent 1c2b6b21da
commit 7a8c87a450
114 changed files with 363 additions and 17323 deletions
-19
View File
@@ -25,19 +25,12 @@ strum = { version = "0.25.0", features = ["derive"] }
bp-header-chain = { path = "../../primitives/header-chain" }
bp-messages = { path = "../../primitives/messages" }
bp-parachains = { path = "../../primitives/parachains" }
bp-millau = { path = "../../primitives/chain-millau" }
bp-polkadot-bulletin = { path = "../../primitives/chain-polkadot-bulletin" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-rialto = { path = "../../primitives/chain-rialto" }
bp-rialto-parachain = { path = "../../primitives/chain-rialto-parachain" }
bp-runtime = { path = "../../primitives/runtime" }
bridge-runtime-common = { path = "../../bin/runtime-common" }
millau-runtime = { path = "../../bin/millau/runtime" }
pallet-bridge-parachains = { path = "../../modules/parachains" }
parachains-relay = { path = "../parachains" }
relay-millau-client = { path = "../client-millau" }
relay-rialto-client = { path = "../client-rialto" }
relay-rialto-parachain-client = { path = "../client-rialto-parachain" }
relay-bridge-hub-kusama-client = { path = "../client-bridge-hub-kusama" }
relay-bridge-hub-polkadot-client = { path = "../client-bridge-hub-polkadot" }
relay-bridge-hub-rococo-client = { path = "../client-bridge-hub-rococo" }
@@ -51,10 +44,6 @@ relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
relay-westend-client = { path = "../client-westend" }
relay-wococo-client = { path = "../client-wococo" }
rialto-runtime = { path = "../../bin/rialto/runtime" }
# we are not using this runtime to craft call or transactions, but we still need it
# to prepare large XCM messages
rialto-parachain-runtime = { path = "../../bin/rialto-parachain/runtime" }
substrate-relay-helper = { path = "../lib-substrate-relay" }
# Substrate Dependencies
@@ -63,14 +52,6 @@ frame-support = { git = "https://github.com/paritytech/polkadot-sdk", branch = "
sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
# Polkadot Dependencies
polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
xcm = { package = "staging-xcm", git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
[dev-dependencies]
bp-test-utils = { path = "../../primitives/test-utils" }
hex-literal = "0.4"
@@ -18,8 +18,5 @@
pub mod kusama_polkadot;
pub mod polkadot_bulletin;
pub mod rialto_millau;
pub mod rialto_parachain_millau;
pub mod rococo_westend;
pub mod rococo_wococo;
pub mod westend_millau;
@@ -1,74 +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/>.
//! Millau-to-Rialto headers sync entrypoint.
use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use substrate_relay_helper::{
equivocation::{
DirectReportGrandpaEquivocationCallBuilder, SubstrateEquivocationDetectionPipeline,
},
finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline},
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
};
/// Description of Millau -> Rialto finalized headers bridge.
#[derive(Clone, Debug)]
pub struct MillauFinalityToRialto;
impl SubstrateFinalityPipeline for MillauFinalityToRialto {
type SourceChain = relay_millau_client::Millau;
type TargetChain = relay_rialto_client::Rialto;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
type SubmitFinalityProofCallBuilder = DirectSubmitGrandpaFinalityProofCallBuilder<
Self,
rialto_runtime::Runtime,
rialto_runtime::MillauGrandpaInstance,
>;
}
impl SubstrateEquivocationDetectionPipeline for MillauFinalityToRialto {
type ReportEquivocationCallBuilder =
DirectReportGrandpaEquivocationCallBuilder<Self, millau_runtime::Runtime>;
}
/// `Millau` to `Rialto` bridge definition.
pub struct MillauToRialtoCliBridge {}
impl CliBridgeBase for MillauToRialtoCliBridge {
type Source = relay_millau_client::Millau;
type Target = relay_rialto_client::Rialto;
}
impl RelayToRelayHeadersCliBridge for MillauToRialtoCliBridge {
type Finality = MillauFinalityToRialto;
}
impl RelayToRelayEquivocationDetectionCliBridge for MillauToRialtoCliBridge {
type Equivocation = MillauFinalityToRialto;
}
impl MessagesCliBridge for MillauToRialtoCliBridge {
type MessagesLane =
crate::bridges::rialto_millau::millau_messages_to_rialto::MillauMessagesToRialto;
}
@@ -1,47 +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/>.
//! Millau-to-Rialto messages sync entrypoint.
use relay_millau_client::Millau;
use relay_rialto_client::Rialto;
use substrate_relay_helper::messages_lane::{
DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder,
SubstrateMessageLane,
};
/// Description of Millau -> Rialto messages bridge.
#[derive(Clone, Debug)]
pub struct MillauMessagesToRialto;
impl SubstrateMessageLane for MillauMessagesToRialto {
type SourceChain = Millau;
type TargetChain = Rialto;
type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
Self,
rialto_runtime::Runtime,
rialto_runtime::WithMillauMessagesInstance,
>;
type ReceiveMessagesDeliveryProofCallBuilder = DirectReceiveMessagesDeliveryProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::WithRialtoMessagesInstance,
>;
type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
@@ -1,22 +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/>.
//! Declaration of all bridges between Rialto and Millau.
pub mod millau_headers_to_rialto;
pub mod millau_messages_to_rialto;
pub mod rialto_headers_to_millau;
pub mod rialto_messages_to_millau;
@@ -1,74 +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/>.
//! Rialto-to-Millau headers sync entrypoint.
use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use substrate_relay_helper::{
equivocation::{
DirectReportGrandpaEquivocationCallBuilder, SubstrateEquivocationDetectionPipeline,
},
finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline},
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
};
/// Description of Millau -> Rialto finalized headers bridge.
#[derive(Clone, Debug)]
pub struct RialtoFinalityToMillau;
impl SubstrateFinalityPipeline for RialtoFinalityToMillau {
type SourceChain = relay_rialto_client::Rialto;
type TargetChain = relay_millau_client::Millau;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
type SubmitFinalityProofCallBuilder = DirectSubmitGrandpaFinalityProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::RialtoGrandpaInstance,
>;
}
impl SubstrateEquivocationDetectionPipeline for RialtoFinalityToMillau {
type ReportEquivocationCallBuilder =
DirectReportGrandpaEquivocationCallBuilder<Self, rialto_runtime::Runtime>;
}
/// `Rialto` to `Millau` bridge definition.
pub struct RialtoToMillauCliBridge {}
impl CliBridgeBase for RialtoToMillauCliBridge {
type Source = relay_rialto_client::Rialto;
type Target = relay_millau_client::Millau;
}
impl RelayToRelayHeadersCliBridge for RialtoToMillauCliBridge {
type Finality = RialtoFinalityToMillau;
}
impl RelayToRelayEquivocationDetectionCliBridge for RialtoToMillauCliBridge {
type Equivocation = RialtoFinalityToMillau;
}
impl MessagesCliBridge for RialtoToMillauCliBridge {
type MessagesLane =
crate::bridges::rialto_millau::rialto_messages_to_millau::RialtoMessagesToMillau;
}
@@ -1,47 +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/>.
//! Rialto-to-Millau messages sync entrypoint.
use relay_millau_client::Millau;
use relay_rialto_client::Rialto;
use substrate_relay_helper::messages_lane::{
DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder,
SubstrateMessageLane,
};
/// Description of Rialto -> Millau messages bridge.
#[derive(Clone, Debug)]
pub struct RialtoMessagesToMillau;
impl SubstrateMessageLane for RialtoMessagesToMillau {
type SourceChain = Rialto;
type TargetChain = Millau;
type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::WithRialtoMessagesInstance,
>;
type ReceiveMessagesDeliveryProofCallBuilder = DirectReceiveMessagesDeliveryProofCallBuilder<
Self,
rialto_runtime::Runtime,
rialto_runtime::WithMillauMessagesInstance,
>;
type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
@@ -1,95 +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/>.
//! Millau-to-RialtoParachain headers sync entrypoint.
// 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/>.
//! Millau-to-RialtoParachain headers sync entrypoint.
use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use substrate_relay_helper::{
equivocation::{
DirectReportGrandpaEquivocationCallBuilder, SubstrateEquivocationDetectionPipeline,
},
finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
};
substrate_relay_helper::generate_submit_finality_proof_call_builder!(
MillauFinalityToRialtoParachain,
MillauFinalityToRialtoParachainCallBuilder,
relay_rialto_parachain_client::RuntimeCall::BridgeMillauGrandpa,
relay_rialto_parachain_client::BridgeGrandpaCall::submit_finality_proof
);
/// Description of Millau -> Rialto finalized headers bridge.
#[derive(Clone, Debug)]
pub struct MillauFinalityToRialtoParachain;
impl SubstrateFinalityPipeline for MillauFinalityToRialtoParachain {
type SourceChain = relay_millau_client::Millau;
type TargetChain = relay_rialto_parachain_client::RialtoParachain;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
impl SubstrateFinalitySyncPipeline for MillauFinalityToRialtoParachain {
type SubmitFinalityProofCallBuilder = MillauFinalityToRialtoParachainCallBuilder;
}
impl SubstrateEquivocationDetectionPipeline for MillauFinalityToRialtoParachain {
type ReportEquivocationCallBuilder =
DirectReportGrandpaEquivocationCallBuilder<Self, millau_runtime::Runtime>;
}
/// `Millau` to `RialtoParachain` bridge definition.
pub struct MillauToRialtoParachainCliBridge {}
impl CliBridgeBase for MillauToRialtoParachainCliBridge {
type Source = relay_millau_client::Millau;
type Target = relay_rialto_parachain_client::RialtoParachain;
}
impl RelayToRelayHeadersCliBridge for MillauToRialtoParachainCliBridge {
type Finality = MillauFinalityToRialtoParachain;
}
impl RelayToRelayEquivocationDetectionCliBridge for MillauToRialtoParachainCliBridge {
type Equivocation = MillauFinalityToRialtoParachain;
}
impl MessagesCliBridge for MillauToRialtoParachainCliBridge {
type MessagesLane =
crate::bridges::rialto_parachain_millau::millau_messages_to_rialto_parachain::MillauMessagesToRialtoParachain;
}
@@ -1,51 +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/>.
//! Millau-to-RialtoParachain messages sync entrypoint.
use relay_millau_client::Millau;
use relay_rialto_parachain_client::RialtoParachain;
use substrate_relay_helper::{
messages_lane::{DirectReceiveMessagesDeliveryProofCallBuilder, SubstrateMessageLane},
UtilityPalletBatchCallBuilder,
};
substrate_relay_helper::generate_receive_message_proof_call_builder!(
MillauMessagesToRialtoParachain,
MillauMessagesToRialtoParachainReceiveMessagesProofCallBuilder,
relay_rialto_parachain_client::RuntimeCall::BridgeMillauMessages,
relay_rialto_parachain_client::BridgeMessagesCall::receive_messages_proof
);
/// Description of Millau -> RialtoParachain messages bridge.
#[derive(Clone, Debug)]
pub struct MillauMessagesToRialtoParachain;
impl SubstrateMessageLane for MillauMessagesToRialtoParachain {
type SourceChain = Millau;
type TargetChain = RialtoParachain;
type ReceiveMessagesProofCallBuilder =
MillauMessagesToRialtoParachainReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder = DirectReceiveMessagesDeliveryProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::WithRialtoParachainMessagesInstance,
>;
type SourceBatchCallBuilder = UtilityPalletBatchCallBuilder<Millau>;
type TargetBatchCallBuilder = ();
}
@@ -1,22 +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/>.
//! Declaration of all bridges between Rialto Parachain and Millau.
pub mod millau_headers_to_rialto_parachain;
pub mod millau_messages_to_rialto_parachain;
pub mod rialto_parachain_messages_to_millau;
pub mod rialto_parachains_to_millau;
@@ -1,51 +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/>.
//! RialtoParachain-to-Millau messages sync entrypoint.
use relay_millau_client::Millau;
use relay_rialto_parachain_client::RialtoParachain;
use substrate_relay_helper::{
messages_lane::{DirectReceiveMessagesProofCallBuilder, SubstrateMessageLane},
UtilityPalletBatchCallBuilder,
};
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
RialtoParachainMessagesToMillau,
RialtoParachainMessagesToMillauReceiveMessagesDeliveryProofCallBuilder,
relay_rialto_parachain_client::RuntimeCall::BridgeMillauMessages,
relay_rialto_parachain_client::BridgeMessagesCall::receive_messages_delivery_proof
);
/// Description of RialtoParachain -> Millau messages bridge.
#[derive(Clone, Debug)]
pub struct RialtoParachainMessagesToMillau;
impl SubstrateMessageLane for RialtoParachainMessagesToMillau {
type SourceChain = RialtoParachain;
type TargetChain = Millau;
type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::WithRialtoParachainMessagesInstance,
>;
type ReceiveMessagesDeliveryProofCallBuilder =
RialtoParachainMessagesToMillauReceiveMessagesDeliveryProofCallBuilder;
type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = UtilityPalletBatchCallBuilder<Millau>;
}
@@ -1,65 +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/>.
//! Rialto-to-Millau parachains sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
use relay_millau_client::Millau;
use relay_rialto_client::Rialto;
use relay_rialto_parachain_client::RialtoParachain;
use substrate_relay_helper::parachains::{
DirectSubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
};
/// Rialto-to-Millau parachains sync description.
#[derive(Clone, Debug)]
pub struct RialtoParachainsToMillau;
impl SubstrateParachainsPipeline for RialtoParachainsToMillau {
type SourceParachain = RialtoParachain;
type SourceRelayChain = Rialto;
type TargetChain = Millau;
type SubmitParachainHeadsCallBuilder = RialtoParachainsToMillauSubmitParachainHeadsCallBuilder;
}
/// `submit_parachain_heads` call builder for Rialto-to-Millau parachains sync pipeline.
pub type RialtoParachainsToMillauSubmitParachainHeadsCallBuilder =
DirectSubmitParachainHeadsCallBuilder<
RialtoParachainsToMillau,
millau_runtime::Runtime,
millau_runtime::WithRialtoParachainsInstance,
>;
/// `RialtoParachain` to `Millau` bridge definition.
pub struct RialtoParachainToMillauCliBridge {}
impl CliBridgeBase for RialtoParachainToMillauCliBridge {
type Source = RialtoParachain;
type Target = Millau;
}
impl ParachainToRelayHeadersCliBridge for RialtoParachainToMillauCliBridge {
type SourceRelay = Rialto;
type ParachainFinality = RialtoParachainsToMillau;
type RelayFinality =
crate::bridges::rialto_millau::rialto_headers_to_millau::RialtoFinalityToMillau;
}
impl MessagesCliBridge for RialtoParachainToMillauCliBridge {
type MessagesLane =
crate::bridges::rialto_parachain_millau::rialto_parachain_messages_to_millau::RialtoParachainMessagesToMillau;
}
@@ -1,20 +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/>.
//! Declaration of all bridges between Westend and Millau.
pub mod westend_headers_to_millau;
pub mod westend_parachains_to_millau;
@@ -1,54 +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/>.
//! Westend-to-Millau headers sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge};
use substrate_relay_helper::{
finality::{DirectSubmitGrandpaFinalityProofCallBuilder, SubstrateFinalitySyncPipeline},
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
};
/// Description of Westend -> Millau finalized headers bridge.
#[derive(Clone, Debug)]
pub struct WestendFinalityToMillau;
impl SubstrateFinalityPipeline for WestendFinalityToMillau {
type SourceChain = relay_westend_client::Westend;
type TargetChain = relay_millau_client::Millau;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
type SubmitFinalityProofCallBuilder = DirectSubmitGrandpaFinalityProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::WestendGrandpaInstance,
>;
}
/// `Westend` to `Millau` bridge definition.
pub struct WestendToMillauCliBridge {}
impl CliBridgeBase for WestendToMillauCliBridge {
type Source = relay_westend_client::Westend;
type Target = relay_millau_client::Millau;
}
impl RelayToRelayHeadersCliBridge for WestendToMillauCliBridge {
type Finality = WestendFinalityToMillau;
}
@@ -1,90 +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/>.
//! Westend-to-Millau parachains sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge};
use relay_millau_client::Millau;
use relay_westend_client::Westend;
use substrate_relay_helper::parachains::{
DirectSubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
};
/// Westend-to-Millau parachains sync description.
#[derive(Clone, Debug)]
pub struct WestendParachainsToMillau;
impl SubstrateParachainsPipeline for WestendParachainsToMillau {
type SourceParachain = relay_asset_hub_westend_client::AssetHubWestend;
type SourceRelayChain = Westend;
type TargetChain = Millau;
type SubmitParachainHeadsCallBuilder = WestendParachainsToMillauSubmitParachainHeadsCallBuilder;
}
/// `submit_parachain_heads` call builder for Rialto-to-Millau parachains sync pipeline.
pub type WestendParachainsToMillauSubmitParachainHeadsCallBuilder =
DirectSubmitParachainHeadsCallBuilder<
WestendParachainsToMillau,
millau_runtime::Runtime,
millau_runtime::WithWestendParachainsInstance,
>;
/// `WestendParachain` to `Millau` bridge definition.
pub struct AssetHubWestendToMillauCliBridge {}
impl ParachainToRelayHeadersCliBridge for AssetHubWestendToMillauCliBridge {
type SourceRelay = Westend;
type ParachainFinality = WestendParachainsToMillau;
type RelayFinality =
crate::bridges::westend_millau::westend_headers_to_millau::WestendFinalityToMillau;
}
impl CliBridgeBase for AssetHubWestendToMillauCliBridge {
type Source = relay_asset_hub_westend_client::AssetHubWestend;
type Target = Millau;
}
/// TODO: Note: I know this does not belong here, but I don't want to add it to the
/// `chain-asset-hub-westend` or `chain-westend`, because we wont use it for production and I don't
/// want to bring this to the bridges subtree now. Anyway, we plan to retire millau/rialto, so this
/// hack will disappear with that.
pub mod relay_asset_hub_westend_client {
use bp_runtime::{ChainId, UnderlyingChainProvider};
use relay_substrate_client::Chain;
use std::time::Duration;
/// `AssetHubWestend` parachain definition
#[derive(Debug, Clone, Copy)]
pub struct AssetHubWestend;
impl UnderlyingChainProvider for AssetHubWestend {
type Chain = millau_runtime::bp_bridged_chain::AssetHubWestend;
}
// Westmint seems to use the same configuration as all Polkadot-like chains, so we'll use
// Westend primitives here.
impl Chain for AssetHubWestend {
const ID: ChainId = bp_runtime::ASSET_HUB_WESTEND_CHAIN_ID;
const NAME: &'static str = "Westmint";
const BEST_FINALIZED_HEADER_ID_METHOD: &'static str =
millau_runtime::bp_bridged_chain::BEST_FINALIZED_ASSETHUBWESTEND_HEADER_METHOD;
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_polkadot_core::SignedBlock;
type Call = ();
}
}
@@ -1,75 +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/>.
//! Millau chain specification for CLI.
use crate::cli::{encode_message::CliEncodeMessage, CliChain};
use bp_runtime::EncodedOrDecodedCall;
use bridge_runtime_common::CustomNetworkId;
use relay_millau_client::Millau;
use relay_substrate_client::SimpleRuntimeVersion;
use xcm_executor::traits::ExportXcm;
impl CliEncodeMessage for Millau {
fn encode_wire_message(
target: xcm::v3::NetworkId,
at_target_xcm: xcm::v3::Xcm<()>,
) -> anyhow::Result<Vec<u8>> {
anyhow::ensure!(
[
CustomNetworkId::Rialto.as_network_id(),
CustomNetworkId::RialtoParachain.as_network_id()
]
.contains(&target),
anyhow::format_err!("Unsupported target chain: {:?}", target)
);
Ok(millau_runtime::xcm_config::ToRialtoOrRialtoParachainSwitchExporter::validate(
target,
0,
&mut Some(Self::dummy_universal_source()?),
&mut Some(target.into()),
&mut Some(at_target_xcm),
)
.map_err(|e| anyhow::format_err!("Failed to prepare outbound message: {:?}", e))?
.0
.1
.0)
}
fn encode_execute_xcm(
message: xcm::VersionedXcm<Self::Call>,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
Ok(millau_runtime::RuntimeCall::XcmPallet(millau_runtime::XcmCall::execute {
message: Box::new(message),
max_weight: Self::estimate_execute_xcm_weight(),
})
.into())
}
}
impl CliChain for Millau {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
Some(SimpleRuntimeVersion::from_runtime_version(&millau_runtime::VERSION));
}
/// TODO: Note: I know this does not belong here, but I don't want to add it to the
/// `chain-asset-hub-westend` or `chain-westend`, because we wont use it for production and I don't
/// want to bring this to the bridges subtree now. Anyway, we plan to retire millau/rialto, so this
/// hack will disappear with that.
impl CliChain for crate::bridges::westend_millau::westend_parachains_to_millau::relay_asset_hub_westend_client::AssetHubWestend {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> = None;
}
@@ -17,95 +17,8 @@
//! Chain-specific relayer configuration.
mod kusama;
mod millau;
mod polkadot;
mod polkadot_bulletin;
mod rialto;
mod rialto_parachain;
mod rococo;
mod westend;
mod wococo;
#[cfg(test)]
mod tests {
use crate::cli::encode_message;
use bp_messages::source_chain::TargetHeaderChain;
use bp_runtime::Chain as _;
use codec::Encode;
use relay_millau_client::Millau;
use relay_rialto_client::Rialto;
use relay_substrate_client::{ChainWithTransactions, SignParam, UnsignedTransaction};
#[test]
fn maximal_rialto_to_millau_message_size_is_computed_correctly() {
use rialto_runtime::millau_messages::MillauAsTargetHeaderChain;
let maximal_message_size = encode_message::compute_maximal_message_size(
bp_rialto::Rialto::max_extrinsic_size(),
bp_millau::Millau::max_extrinsic_size(),
);
let message = vec![42; maximal_message_size as _];
assert_eq!(MillauAsTargetHeaderChain::verify_message(&message), Ok(()));
let message = vec![42; (maximal_message_size + 1) as _];
assert!(MillauAsTargetHeaderChain::verify_message(&message).is_err());
}
#[test]
fn maximal_size_remark_to_rialto_is_generated_correctly() {
assert!(
bridge_runtime_common::messages::target::maximal_incoming_message_size(
bp_rialto::Rialto::max_extrinsic_size()
) > bp_millau::Millau::max_extrinsic_size(),
"We can't actually send maximal messages to Rialto from Millau, because Millau extrinsics can't be that large",
)
}
#[test]
fn rialto_tx_extra_bytes_constant_is_correct() {
let rialto_call = rialto_runtime::RuntimeCall::System(rialto_runtime::SystemCall::remark {
remark: vec![],
});
let rialto_tx = Rialto::sign_transaction(
SignParam {
spec_version: 1,
transaction_version: 1,
genesis_hash: Default::default(),
signer: sp_keyring::AccountKeyring::Alice.pair(),
},
UnsignedTransaction::new(rialto_call.clone().into(), 0),
)
.unwrap();
let extra_bytes_in_transaction = rialto_tx.encode().len() - rialto_call.encode().len();
assert!(
bp_rialto::TX_EXTRA_BYTES as usize >= extra_bytes_in_transaction,
"Hardcoded number of extra bytes in Rialto transaction {} is lower than actual value: {}",
bp_rialto::TX_EXTRA_BYTES,
extra_bytes_in_transaction,
);
}
#[test]
fn millau_tx_extra_bytes_constant_is_correct() {
let millau_call = millau_runtime::RuntimeCall::System(millau_runtime::SystemCall::remark {
remark: vec![],
});
let millau_tx = Millau::sign_transaction(
SignParam {
spec_version: 0,
transaction_version: 0,
genesis_hash: Default::default(),
signer: sp_keyring::AccountKeyring::Alice.pair(),
},
UnsignedTransaction::new(millau_call.clone().into(), 0),
)
.unwrap();
let extra_bytes_in_transaction = millau_tx.encode().len() - millau_call.encode().len();
assert!(
bp_millau::TX_EXTRA_BYTES as usize >= extra_bytes_in_transaction,
"Hardcoded number of extra bytes in Millau transaction {} is lower than actual value: {}",
bp_millau::TX_EXTRA_BYTES,
extra_bytes_in_transaction,
);
}
}
@@ -1,62 +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/>.
//! Rialto chain specification for CLI.
use crate::cli::{encode_message::CliEncodeMessage, CliChain};
use bp_runtime::EncodedOrDecodedCall;
use bridge_runtime_common::CustomNetworkId;
use relay_rialto_client::Rialto;
use relay_substrate_client::SimpleRuntimeVersion;
use xcm_executor::traits::ExportXcm;
impl CliEncodeMessage for Rialto {
fn encode_wire_message(
target: xcm::v3::NetworkId,
at_target_xcm: xcm::v3::Xcm<()>,
) -> anyhow::Result<Vec<u8>> {
anyhow::ensure!(
target == CustomNetworkId::Millau.as_network_id(),
anyhow::format_err!("Unsupported target chain: {:?}", target)
);
Ok(rialto_runtime::millau_messages::ToMillauBlobExporter::validate(
target,
0,
&mut Some(Self::dummy_universal_source()?),
&mut Some(target.into()),
&mut Some(at_target_xcm),
)
.map_err(|e| anyhow::format_err!("Failed to prepare outbound message: {:?}", e))?
.0
.0)
}
fn encode_execute_xcm(
message: xcm::VersionedXcm<Self::Call>,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
Ok(rialto_runtime::RuntimeCall::XcmPallet(rialto_runtime::XcmCall::execute {
message: Box::new(message),
max_weight: Self::estimate_execute_xcm_weight(),
})
.into())
}
}
impl CliChain for Rialto {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
Some(SimpleRuntimeVersion::from_runtime_version(&rialto_runtime::VERSION));
}
@@ -1,65 +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/>.
//! Rialto parachain specification for CLI.
use crate::cli::{encode_message::CliEncodeMessage, CliChain};
use bp_runtime::EncodedOrDecodedCall;
use bridge_runtime_common::CustomNetworkId;
use relay_rialto_parachain_client::RialtoParachain;
use relay_substrate_client::SimpleRuntimeVersion;
use xcm_executor::traits::ExportXcm;
impl CliEncodeMessage for RialtoParachain {
fn encode_wire_message(
target: xcm::v3::NetworkId,
at_target_xcm: xcm::v3::Xcm<()>,
) -> anyhow::Result<Vec<u8>> {
anyhow::ensure!(
target == CustomNetworkId::Millau.as_network_id(),
anyhow::format_err!("Unsupported target chain: {:?}", target)
);
Ok(rialto_parachain_runtime::millau_messages::ToMillauBlobExporter::validate(
target,
0,
&mut Some(Self::dummy_universal_source()?),
&mut Some(target.into()),
&mut Some(at_target_xcm),
)
.map_err(|e| anyhow::format_err!("Failed to prepare outbound message: {:?}", e))?
.0
.0)
}
fn encode_execute_xcm(
message: xcm::VersionedXcm<Self::Call>,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>> {
type RuntimeCall = relay_rialto_parachain_client::RuntimeCall;
type XcmCall = relay_rialto_parachain_client::runtime_types::pallet_xcm::pallet::Call;
let xcm_call = XcmCall::execute {
message: Box::new(unsafe { std::mem::transmute(message) }),
max_weight: Self::estimate_execute_xcm_weight(),
};
Ok(RuntimeCall::PolkadotXcm(xcm_call).into())
}
}
impl CliChain for RialtoParachain {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> = None;
}
@@ -29,10 +29,6 @@ use substrate_relay_helper::{
#[strum(serialize_all = "kebab_case")]
/// Supported full bridges (headers + messages).
pub enum FullBridge {
MillauToRialto,
RialtoToMillau,
MillauToRialtoParachain,
RialtoParachainToMillau,
BridgeHubRococoToBridgeHubWococo,
BridgeHubWococoToBridgeHubRococo,
BridgeHubRococoToBridgeHubWestend,
@@ -129,29 +129,6 @@ macro_rules! declare_chain_connection_params_cli_schema {
};
}
/// Helper trait to override transaction parameters differently.
pub trait TransactionParamsProvider {
/// Returns `true` if transaction parameters are defined by this provider.
fn is_defined(&self) -> bool;
/// Returns transaction parameters.
fn transaction_params<Chain: ChainWithTransactions>(
&self,
) -> anyhow::Result<TransactionParams<AccountKeyPairOf<Chain>>>;
/// Returns transaction parameters, defined by `self` provider or, if they're not defined,
/// defined by `other` provider.
fn transaction_params_or<Chain: ChainWithTransactions, T: TransactionParamsProvider>(
&self,
other: &T,
) -> anyhow::Result<TransactionParams<AccountKeyPairOf<Chain>>> {
if self.is_defined() {
self.transaction_params::<Chain>()
} else {
other.transaction_params::<Chain>()
}
}
}
/// Create chain-specific set of signing parameters.
#[macro_export]
macro_rules! declare_chain_signing_params_cli_schema {
@@ -239,15 +216,12 @@ macro_rules! declare_chain_signing_params_cli_schema {
suri_password.as_deref()
).map_err(|e| anyhow::format_err!("{:?}", e))
}
}
#[allow(dead_code)]
impl TransactionParamsProvider for [<$chain SigningParams>] {
fn is_defined(&self) -> bool {
self.[<$chain_prefix _signer>].is_some() || self.[<$chain_prefix _signer_file>].is_some()
}
fn transaction_params<Chain: ChainWithTransactions>(&self) -> anyhow::Result<TransactionParams<AccountKeyPairOf<Chain>>> {
/// Return transaction parameters.
#[allow(dead_code)]
pub fn transaction_params<Chain: ChainWithTransactions>(
&self,
) -> anyhow::Result<TransactionParams<AccountKeyPairOf<Chain>>> {
Ok(TransactionParams {
mortality: self.transactions_mortality()?,
signer: self.to_keypair::<Chain>()?,
@@ -310,7 +284,7 @@ mod tests {
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.to_keypair::<relay_polkadot_client::Polkadot>()
.map(|p| p.public())
.map_err(drop),
Ok(alice.public()),
@@ -327,7 +301,7 @@ mod tests {
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.to_keypair::<relay_polkadot_client::Polkadot>()
.map(|p| p.public())
.map_err(drop),
Ok(bob.public()),
@@ -344,7 +318,7 @@ mod tests {
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.to_keypair::<relay_polkadot_client::Polkadot>()
.map(|p| p.public())
.map_err(drop),
Ok(bob_with_alice_password.public()),
@@ -361,7 +335,7 @@ mod tests {
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.to_keypair::<relay_polkadot_client::Polkadot>()
.map(|p| p.public())
.map_err(drop),
Ok(alice.public()),
@@ -20,11 +20,6 @@ use crate::{
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
},
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rococo_wococo::{
rococo_headers_to_bridge_hub_wococo::RococoToBridgeHubWococoCliBridge,
wococo_headers_to_bridge_hub_rococo::WococoToBridgeHubRococoCliBridge,
@@ -58,9 +53,6 @@ pub struct DetectEquivocations {
#[strum(serialize_all = "kebab_case")]
/// Equivocations detection bridge.
pub enum DetectEquivocationsBridge {
MillauToRialto,
RialtoToMillau,
MillauToRialtoParachain,
RococoToBridgeHubWococo,
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
@@ -90,9 +82,6 @@ where
}
}
impl EquivocationsDetector for MillauToRialtoCliBridge {}
impl EquivocationsDetector for RialtoToMillauCliBridge {}
impl EquivocationsDetector for MillauToRialtoParachainCliBridge {}
impl EquivocationsDetector for RococoToBridgeHubWococoCliBridge {}
impl EquivocationsDetector for WococoToBridgeHubRococoCliBridge {}
impl EquivocationsDetector for KusamaToBridgeHubPolkadotCliBridge {}
@@ -102,10 +91,6 @@ impl DetectEquivocations {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
DetectEquivocationsBridge::MillauToRialto => MillauToRialtoCliBridge::start(self),
DetectEquivocationsBridge::RialtoToMillau => RialtoToMillauCliBridge::start(self),
DetectEquivocationsBridge::MillauToRialtoParachain =>
MillauToRialtoParachainCliBridge::start(self),
DetectEquivocationsBridge::RococoToBridgeHubWococo =>
RococoToBridgeHubWococoCliBridge::start(self),
DetectEquivocationsBridge::WococoToBridgeHubRococo =>
@@ -1,189 +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::cli::{ExplicitOrMaximal, HexBytes};
use bp_runtime::EncodedOrDecodedCall;
use bridge_runtime_common::CustomNetworkId;
use codec::Encode;
use frame_support::weights::Weight;
use relay_substrate_client::Chain;
use structopt::StructOpt;
use xcm::latest::prelude::*;
/// All possible messages that may be delivered to generic Substrate chain.
///
/// Note this enum may be used in the context of both Source (as part of `encode-call`)
/// and Target chain (as part of `encode-message/send-message`).
#[derive(StructOpt, Debug, PartialEq, Eq)]
pub enum Message {
/// Raw bytes for the message.
Raw {
/// Raw message bytes.
data: HexBytes,
},
/// Message with given size.
Sized {
/// Sized of the message.
size: ExplicitOrMaximal<u32>,
},
}
/// Raw, SCALE-encoded message payload used in expected deployment.
pub type RawMessage = Vec<u8>;
pub trait CliEncodeMessage: Chain {
/// Returns dummy `AccountId32` universal source given this network id.
fn dummy_universal_source() -> anyhow::Result<xcm::v3::Junctions> {
use xcm::v3::prelude::*;
let this_network = CustomNetworkId::try_from(Self::ID)
.map(|n| n.as_network_id())
.map_err(|_| anyhow::format_err!("Unsupported chain: {:?}", Self::ID))?;
Ok(X2(
GlobalConsensus(this_network),
AccountId32 { network: Some(this_network), id: [0u8; 32] },
))
}
/// Returns XCM blob that is passed to the `send_message` function of the messages pallet
/// and then is sent over the wire.
fn encode_wire_message(target: NetworkId, at_target_xcm: Xcm<()>) -> anyhow::Result<Vec<u8>>;
/// Encode an `execute` XCM call of the XCM pallet.
fn encode_execute_xcm(
message: xcm::VersionedXcm<Self::Call>,
) -> anyhow::Result<EncodedOrDecodedCall<Self::Call>>;
/// Estimate value of `max_weight` argument for the `execute` XCM call of the XCM pallet.
fn estimate_execute_xcm_weight() -> Weight {
// we are only executing XCM on our testnets and 1/100 of max extrinsic weight is ok
Self::max_extrinsic_weight() / 100
}
}
/// Encode message payload passed through CLI flags.
pub(crate) fn encode_message<Source: CliEncodeMessage, Target: Chain>(
message: &Message,
) -> anyhow::Result<RawMessage> {
Ok(match message {
Message::Raw { ref data } => data.0.clone(),
Message::Sized { ref size } => {
let destination = CustomNetworkId::try_from(Target::ID)
.map(|n| n.as_network_id())
.map_err(|_| anyhow::format_err!("Unsupported target chain: {:?}", Target::ID))?;
let expected_size = match *size {
ExplicitOrMaximal::Explicit(size) => size,
ExplicitOrMaximal::Maximal => compute_maximal_message_size(
Source::max_extrinsic_size(),
Target::max_extrinsic_size(),
),
} as usize;
let at_target_xcm = vec![ExpectPallet {
index: 0,
name: vec![42; expected_size],
module_name: vec![],
crate_major: 0,
min_crate_minor: 0,
}]
.into();
let at_target_xcm_size =
Source::encode_wire_message(destination, at_target_xcm)?.encoded_size();
let at_target_xcm_overhead = at_target_xcm_size.saturating_sub(expected_size);
let at_target_xcm = vec![ExpectPallet {
index: 0,
name: vec![42; expected_size.saturating_sub(at_target_xcm_overhead)],
module_name: vec![],
crate_major: 0,
min_crate_minor: 0,
}]
.into();
xcm::VersionedXcm::<()>::V3(
vec![ExportMessage {
network: destination,
destination: destination.into(),
xcm: at_target_xcm,
}]
.into(),
)
.encode()
},
})
}
/// Compute maximal message size, given max extrinsic size at source and target chains.
pub(crate) fn compute_maximal_message_size(
maximal_source_extrinsic_size: u32,
maximal_target_extrinsic_size: u32,
) -> u32 {
// assume that both signed extensions and other arguments fit 1KB
let service_tx_bytes_on_source_chain = 1024;
let maximal_source_extrinsic_size =
maximal_source_extrinsic_size - service_tx_bytes_on_source_chain;
let maximal_message_size =
bridge_runtime_common::messages::target::maximal_incoming_message_size(
maximal_target_extrinsic_size,
);
std::cmp::min(maximal_message_size, maximal_source_extrinsic_size)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cli::send_message::decode_xcm;
use bp_runtime::Chain;
use relay_millau_client::Millau;
use relay_rialto_client::Rialto;
fn approximate_message_size<Source: CliEncodeMessage>(xcm_msg_len: usize) -> usize {
xcm_msg_len + Source::dummy_universal_source().unwrap().encoded_size()
}
#[test]
fn encode_explicit_size_message_works() {
let msg = encode_message::<Rialto, Millau>(&Message::Sized {
size: ExplicitOrMaximal::Explicit(100),
})
.unwrap();
// since it isn't the returned XCM what is sent over the wire, we can only check if
// it is close to what we need
assert!(
(1f64 - (approximate_message_size::<Rialto>(msg.len()) as f64) / 100_f64).abs() < 0.1
);
// check that it decodes to valid xcm
let _ = decode_xcm::<()>(msg).unwrap();
}
#[test]
fn encode_maximal_size_message_works() {
let maximal_size = compute_maximal_message_size(
Rialto::max_extrinsic_size(),
Millau::max_extrinsic_size(),
);
let msg =
encode_message::<Rialto, Millau>(&Message::Sized { size: ExplicitOrMaximal::Maximal })
.unwrap();
// since it isn't the returned XCM what is sent over the wire, we can only check if
// it is close to what we need
assert!(
(1f64 - approximate_message_size::<Rialto>(msg.len()) as f64 / maximal_size as f64)
.abs() < 0.1
);
// check that it decodes to valid xcm
let _ = decode_xcm::<()>(msg).unwrap();
}
}
@@ -27,11 +27,6 @@ use crate::{
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
},
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rococo_westend::{
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
@@ -40,7 +35,6 @@ use crate::{
rococo_headers_to_bridge_hub_wococo::RococoToBridgeHubWococoCliBridge,
wococo_headers_to_bridge_hub_rococo::WococoToBridgeHubRococoCliBridge,
},
westend_millau::westend_headers_to_millau::WestendToMillauCliBridge,
},
cli::{bridge::CliBridgeBase, chain_schema::*},
};
@@ -72,10 +66,6 @@ pub struct InitBridge {
#[strum(serialize_all = "kebab_case")]
/// Bridge to initialize.
pub enum InitBridgeName {
MillauToRialto,
RialtoToMillau,
WestendToMillau,
MillauToRialtoParachain,
RococoToBridgeHubWococo,
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
@@ -126,72 +116,6 @@ where
}
}
impl BridgeInitializer for MillauToRialtoCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
rialto_runtime::SudoCall::sudo {
call: Box::new(rialto_runtime::BridgeGrandpaCall::initialize { init_data }.into()),
}
.into()
}
}
impl BridgeInitializer for MillauToRialtoParachainCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
type RuntimeCall = relay_rialto_parachain_client::RuntimeCall;
type BridgeGrandpaCall = relay_rialto_parachain_client::BridgeGrandpaCall;
type SudoCall = relay_rialto_parachain_client::SudoCall;
let initialize_call =
RuntimeCall::BridgeMillauGrandpa(BridgeGrandpaCall::initialize { init_data });
RuntimeCall::Sudo(SudoCall::sudo { call: Box::new(initialize_call) })
}
}
impl BridgeInitializer for RialtoToMillauCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
let initialize_call = millau_runtime::BridgeGrandpaCall::<
millau_runtime::Runtime,
millau_runtime::RialtoGrandpaInstance,
>::initialize {
init_data,
};
millau_runtime::SudoCall::sudo { call: Box::new(initialize_call.into()) }.into()
}
}
impl BridgeInitializer for WestendToMillauCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
// at Westend -> Millau initialization we're not using sudo, because otherwise
// our deployments may fail, because we need to initialize both Rialto -> Millau
// and Westend -> Millau bridge. => since there's single possible sudo account,
// one of transaction may fail with duplicate nonce error
millau_runtime::BridgeGrandpaCall::<
millau_runtime::Runtime,
millau_runtime::WestendGrandpaInstance,
>::initialize {
init_data,
}
.into()
}
}
impl BridgeInitializer for RococoToBridgeHubWococoCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
@@ -305,11 +229,6 @@ impl InitBridge {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
InitBridgeName::MillauToRialto => MillauToRialtoCliBridge::init_bridge(self),
InitBridgeName::RialtoToMillau => RialtoToMillauCliBridge::init_bridge(self),
InitBridgeName::WestendToMillau => WestendToMillauCliBridge::init_bridge(self),
InitBridgeName::MillauToRialtoParachain =>
MillauToRialtoParachainCliBridge::init_bridge(self),
InitBridgeName::RococoToBridgeHubWococo =>
RococoToBridgeHubWococoCliBridge::init_bridge(self),
InitBridgeName::WococoToBridgeHubRococo =>
+1 -46
View File
@@ -16,8 +16,6 @@
//! Deal with CLI args of substrate-to-substrate relay.
use std::convert::TryInto;
use async_std::prelude::*;
use codec::{Decode, Encode};
use futures::{select, FutureExt};
@@ -31,18 +29,14 @@ use bp_messages::LaneId;
use relay_substrate_client::SimpleRuntimeVersion;
pub(crate) mod bridge;
pub(crate) mod encode_message;
pub(crate) mod send_message;
mod chain_schema;
mod detect_equivocations;
mod init_bridge;
mod register_parachain;
mod relay_headers;
mod relay_headers_and_messages;
mod relay_messages;
mod relay_parachains;
mod resubmit_transactions;
/// The target that will be used when publishing logs related to this pallet.
pub const LOG_TARGET: &str = "bridge";
@@ -77,16 +71,6 @@ pub enum Command {
///
/// Sends initialization transaction to bootstrap the bridge with current finalized block data.
InitBridge(init_bridge::InitBridge),
/// Send custom message over the bridge.
///
/// Allows interacting with the bridge by sending messages over `Messages` component.
/// The message is being sent to the source chain, delivered to the target chain and dispatched
/// there.
SendMessage(send_message::SendMessage),
/// Resubmit transactions with increased tip if they are stalled.
ResubmitTransactions(resubmit_transactions::ResubmitTransactions),
/// Register parachain.
RegisterParachain(register_parachain::RegisterParachain),
/// Relay parachain heads.
RelayParachains(relay_parachains::RelayParachains),
/// Detect and report equivocations.
@@ -121,9 +105,6 @@ impl Command {
Self::RelayMessages(arg) => arg.run().await?,
Self::RelayHeadersAndMessages(arg) => arg.run().await?,
Self::InitBridge(arg) => arg.run().await?,
Self::SendMessage(arg) => arg.run().await?,
Self::ResubmitTransactions(arg) => arg.run().await?,
Self::RegisterParachain(arg) => arg.run().await?,
Self::RelayParachains(arg) => arg.run().await?,
Self::DetectEquivocations(arg) => arg.run().await?,
}
@@ -169,33 +150,7 @@ arg_enum! {
}
}
/// Generic balance type.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Balance(pub u128);
impl std::fmt::Display for Balance {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
use num_format::{Locale, ToFormattedString};
write!(fmt, "{}", self.0.to_formatted_string(&Locale::en))
}
}
impl std::str::FromStr for Balance {
type Err = <u128 as std::str::FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.parse()?))
}
}
impl Balance {
/// Cast balance to `u64` type, panicking if it's too large.
pub fn cast(&self) -> u64 {
self.0.try_into().expect("Balance is too high for this chain.")
}
}
// Bridge-supported network definition.
/// Bridge-supported network definition.
///
/// Used to abstract away CLI commands.
pub trait CliChain: relay_substrate_client::Chain {
@@ -1,324 +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::cli::{chain_schema::*, Balance};
use codec::Encode;
use frame_support::Twox64Concat;
use num_traits::Zero;
use polkadot_parachain_primitives::primitives::{
HeadData as ParaHeadData, Id as ParaId, ValidationCode as ParaValidationCode,
};
use polkadot_runtime_common::{
paras_registrar::Call as ParaRegistrarCall, slots::Call as ParaSlotsCall,
};
use polkadot_runtime_parachains::paras::ParaLifecycle;
use relay_substrate_client::{AccountIdOf, CallOf, Chain, Client, UnsignedTransaction};
use relay_utils::{TrackedTransactionStatus, TransactionTracker};
use rialto_runtime::SudoCall;
use sp_core::{
storage::{well_known_keys::CODE, StorageKey},
Pair,
};
use structopt::StructOpt;
use strum::{EnumString, EnumVariantNames, VariantNames};
/// Name of the `NextFreeParaId` value in the `polkadot_runtime_common::paras_registrar` pallet.
const NEXT_FREE_PARA_ID_STORAGE_NAME: &str = "NextFreeParaId";
/// Name of the `ParaLifecycles` map in the `polkadot_runtime_parachains::paras` pallet.
const PARAS_LIFECYCLES_STORAGE_NAME: &str = "ParaLifecycles";
/// Register parachain.
#[derive(StructOpt, Debug, PartialEq, Eq)]
pub struct RegisterParachain {
/// A parachain to register.
#[structopt(possible_values = Parachain::VARIANTS, case_insensitive = true)]
parachain: Parachain,
/// Parachain deposit.
#[structopt(long, default_value = "0")]
deposit: Balance,
/// Lease begin.
#[structopt(long, default_value = "0")]
lease_begin: u32,
/// Lease end.
#[structopt(long, default_value = "256")]
lease_end: u32,
#[structopt(flatten)]
relay_connection: RelaychainConnectionParams,
#[structopt(flatten)]
relay_sign: RelaychainSigningParams,
#[structopt(flatten)]
para_connection: ParachainConnectionParams,
}
/// Parachain to register.
#[derive(Debug, EnumString, EnumVariantNames, PartialEq, Eq)]
#[strum(serialize_all = "kebab_case")]
pub enum Parachain {
RialtoParachain,
}
macro_rules! select_bridge {
($bridge: expr, $generic: tt) => {
match $bridge {
Parachain::RialtoParachain => {
type Relaychain = relay_rialto_client::Rialto;
type Parachain = relay_rialto_parachain_client::RialtoParachain;
use bp_rialto::{PARAS_PALLET_NAME, PARAS_REGISTRAR_PALLET_NAME};
$generic
},
}
};
}
impl RegisterParachain {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
select_bridge!(self.parachain, {
let relay_client = self.relay_connection.into_client::<Relaychain>().await?;
let relay_sign = self.relay_sign.to_keypair::<Relaychain>()?;
let para_client = self.para_connection.into_client::<Parachain>().await?;
// hopefully we're the only actor that is registering parachain right now
// => read next parachain id
let para_id_key = bp_runtime::storage_value_final_key(
PARAS_REGISTRAR_PALLET_NAME.as_bytes(),
NEXT_FREE_PARA_ID_STORAGE_NAME.as_bytes(),
);
let para_id: ParaId = relay_client
.storage_value(StorageKey(para_id_key.to_vec()), None)
.await?
.unwrap_or(polkadot_primitives::v6::LOWEST_PUBLIC_ID)
.max(polkadot_primitives::v6::LOWEST_PUBLIC_ID);
log::info!(target: "bridge", "Going to reserve parachain id: {:?}", para_id);
// step 1: reserve a parachain id
let relay_sudo_account: AccountIdOf<Relaychain> = relay_sign.public().into();
let reserve_parachain_id_call: CallOf<Relaychain> =
ParaRegistrarCall::reserve {}.into();
let reserve_result = relay_client
.submit_and_watch_signed_extrinsic(&relay_sign, move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(
reserve_parachain_id_call.into(),
transaction_nonce,
))
})
.await?
.wait()
.await;
if reserve_result == TrackedTransactionStatus::Lost {
return Err(anyhow::format_err!(
"Failed to finalize `reserve-parachain-id` transaction"
))
}
log::info!(target: "bridge", "Reserved parachain id: {:?}", para_id);
// step 2: register parathread
let para_genesis_header = para_client.header_by_number(Zero::zero()).await?;
let para_code = para_client
.raw_storage_value(StorageKey(CODE.to_vec()), Some(para_genesis_header.hash()))
.await?
.ok_or_else(|| {
anyhow::format_err!("Cannot fetch validation code of {}", Parachain::NAME)
})?
.0;
log::info!(
target: "bridge",
"Going to register parachain {:?}: genesis len = {} code len = {}",
para_id,
para_genesis_header.encode().len(),
para_code.len(),
);
let register_parathread_call: CallOf<Relaychain> = ParaRegistrarCall::register {
id: para_id,
genesis_head: ParaHeadData(para_genesis_header.encode()),
validation_code: ParaValidationCode(para_code),
}
.into();
let register_result = relay_client
.submit_and_watch_signed_extrinsic(&relay_sign, move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(register_parathread_call.into(), transaction_nonce))
})
.await?
.wait()
.await;
if register_result == TrackedTransactionStatus::Lost {
return Err(anyhow::format_err!(
"Failed to finalize `register-parathread` transaction"
))
}
log::info!(target: "bridge", "Registered parachain: {:?}. Waiting for onboarding", para_id);
// wait until parathread is onboarded
let para_state_key = bp_runtime::storage_map_final_key::<Twox64Concat>(
PARAS_PALLET_NAME,
PARAS_LIFECYCLES_STORAGE_NAME,
&para_id.encode(),
);
wait_para_state(
&relay_client,
&para_state_key.0,
&[ParaLifecycle::Onboarding, ParaLifecycle::Parathread],
ParaLifecycle::Parathread,
)
.await?;
// step 3: force parachain leases
let lease_begin = self.lease_begin;
let lease_end = self.lease_end;
let para_deposit = self.deposit.cast().into();
log::info!(
target: "bridge",
"Going to force leases of parachain {:?}: [{}; {}]",
para_id,
lease_begin,
lease_end,
);
let force_lease_call: CallOf<Relaychain> = SudoCall::sudo {
call: Box::new(
ParaSlotsCall::force_lease {
para: para_id,
leaser: relay_sudo_account.clone(),
amount: para_deposit,
period_begin: lease_begin,
period_count: lease_end.saturating_sub(lease_begin).saturating_add(1),
}
.into(),
),
}
.into();
relay_client
.submit_signed_extrinsic(&relay_sign, move |_, transaction_nonce| {
Ok(UnsignedTransaction::new(force_lease_call.into(), transaction_nonce))
})
.await?;
log::info!(target: "bridge", "Registered parachain leases: {:?}. Waiting for onboarding", para_id);
// wait until parachain is onboarded
wait_para_state(
&relay_client,
&para_state_key.0,
&[
ParaLifecycle::Onboarding,
ParaLifecycle::UpgradingParathread,
ParaLifecycle::Parathread,
],
ParaLifecycle::Parachain,
)
.await?;
Ok(())
})
}
}
/// Wait until parachain state is changed.
async fn wait_para_state<Relaychain: Chain>(
relay_client: &Client<Relaychain>,
para_state_key: &[u8],
from_states: &[ParaLifecycle],
to_state: ParaLifecycle,
) -> anyhow::Result<()> {
loop {
let para_state: ParaLifecycle = relay_client
.storage_value(StorageKey(para_state_key.to_vec()), None)
.await?
.ok_or_else(|| {
anyhow::format_err!(
"Cannot fetch next free parachain lifecycle from the runtime storage of {}",
Relaychain::NAME,
)
})?;
if para_state == to_state {
log::info!(target: "bridge", "Parachain state is now: {:?}", to_state);
return Ok(())
}
if !from_states.contains(&para_state) {
return Err(anyhow::format_err!("Invalid parachain lifecycle: {:?}", para_state))
}
log::info!(target: "bridge", "Parachain state: {:?}. Waiting for {:?}", para_state, to_state);
async_std::task::sleep(Relaychain::AVERAGE_BLOCK_INTERVAL).await;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn register_rialto_parachain() {
let register_parachain = RegisterParachain::from_iter(vec![
"register-parachain",
"rialto-parachain",
"--parachain-host",
"127.0.0.1",
"--parachain-port",
"11949",
"--relaychain-host",
"127.0.0.1",
"--relaychain-port",
"9944",
"--relaychain-signer",
"//Alice",
"--deposit",
"42",
"--lease-begin",
"100",
"--lease-end",
"200",
]);
assert_eq!(
register_parachain,
RegisterParachain {
parachain: Parachain::RialtoParachain,
deposit: Balance(42),
lease_begin: 100,
lease_end: 200,
relay_connection: RelaychainConnectionParams {
relaychain_host: "127.0.0.1".into(),
relaychain_port: 9944,
relaychain_secure: false,
relaychain_runtime_version: RelaychainRuntimeVersionParams {
relaychain_version_mode: RuntimeVersionType::Bundle,
relaychain_spec_version: None,
relaychain_transaction_version: None,
}
},
relay_sign: RelaychainSigningParams {
relaychain_signer: Some("//Alice".into()),
relaychain_signer_password: None,
relaychain_signer_file: None,
relaychain_signer_password_file: None,
relaychain_transactions_mortality: None,
},
para_connection: ParachainConnectionParams {
parachain_host: "127.0.0.1".into(),
parachain_port: 11949,
parachain_secure: false,
parachain_runtime_version: ParachainRuntimeVersionParams {
parachain_version_mode: RuntimeVersionType::Bundle,
parachain_spec_version: None,
parachain_transaction_version: None,
}
},
}
);
}
}
@@ -27,16 +27,10 @@ use crate::bridges::{
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
},
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rococo_wococo::{
rococo_headers_to_bridge_hub_wococo::RococoToBridgeHubWococoCliBridge,
wococo_headers_to_bridge_hub_rococo::WococoToBridgeHubRococoCliBridge,
},
westend_millau::westend_headers_to_millau::WestendToMillauCliBridge,
};
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline;
@@ -67,10 +61,6 @@ pub struct RelayHeaders {
#[strum(serialize_all = "kebab_case")]
/// Headers relay bridge.
pub enum RelayHeadersBridge {
MillauToRialto,
RialtoToMillau,
WestendToMillau,
MillauToRialtoParachain,
RococoToBridgeHubWococo,
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
@@ -110,10 +100,6 @@ trait HeadersRelayer: RelayToRelayHeadersCliBridge {
}
}
impl HeadersRelayer for MillauToRialtoCliBridge {}
impl HeadersRelayer for RialtoToMillauCliBridge {}
impl HeadersRelayer for WestendToMillauCliBridge {}
impl HeadersRelayer for MillauToRialtoParachainCliBridge {}
impl HeadersRelayer for RococoToBridgeHubWococoCliBridge {}
impl HeadersRelayer for WococoToBridgeHubRococoCliBridge {}
impl HeadersRelayer for KusamaToBridgeHubPolkadotCliBridge {}
@@ -125,11 +111,6 @@ impl RelayHeaders {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
RelayHeadersBridge::MillauToRialto => MillauToRialtoCliBridge::relay_headers(self),
RelayHeadersBridge::RialtoToMillau => RialtoToMillauCliBridge::relay_headers(self),
RelayHeadersBridge::WestendToMillau => WestendToMillauCliBridge::relay_headers(self),
RelayHeadersBridge::MillauToRialtoParachain =>
MillauToRialtoParachainCliBridge::relay_headers(self),
RelayHeadersBridge::RococoToBridgeHubWococo =>
RococoToBridgeHubWococoCliBridge::relay_headers(self),
RelayHeadersBridge::WococoToBridgeHubRococo =>
@@ -36,7 +36,6 @@ use structopt::StructOpt;
use futures::{FutureExt, TryFutureExt};
use relay_to_parachain::*;
use relay_to_relay::*;
use crate::{
bridges::{
@@ -48,14 +47,6 @@ use crate::{
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
},
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::{
millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
},
rococo_westend::{
rococo_parachains_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendCliBridge,
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
@@ -203,9 +194,6 @@ where
}
// All supported chains.
declare_chain_cli_schema!(Millau, millau);
declare_chain_cli_schema!(Rialto, rialto);
declare_chain_cli_schema!(RialtoParachain, rialto_parachain);
declare_chain_cli_schema!(Rococo, rococo);
declare_chain_cli_schema!(BridgeHubRococo, bridge_hub_rococo);
declare_chain_cli_schema!(Wococo, wococo);
@@ -217,53 +205,7 @@ declare_chain_cli_schema!(BridgeHubKusama, bridge_hub_kusama);
declare_chain_cli_schema!(Polkadot, polkadot);
declare_chain_cli_schema!(BridgeHubPolkadot, bridge_hub_polkadot);
declare_chain_cli_schema!(PolkadotBulletin, polkadot_bulletin);
// Means to override signers of different layer transactions.
declare_chain_cli_schema!(MillauHeadersToRialto, millau_headers_to_rialto);
declare_chain_cli_schema!(MillauHeadersToRialtoParachain, millau_headers_to_rialto_parachain);
declare_chain_cli_schema!(RialtoHeadersToMillau, rialto_headers_to_millau);
declare_chain_cli_schema!(RialtoParachainsToMillau, rialto_parachains_to_millau);
declare_chain_cli_schema!(RococoHeadersToBridgeHubWococo, rococo_headers_to_bridge_hub_wococo);
declare_chain_cli_schema!(
RococoParachainsToBridgeHubWococo,
rococo_parachains_to_bridge_hub_wococo
);
declare_chain_cli_schema!(WococoHeadersToBridgeHubRococo, wococo_headers_to_bridge_hub_rococo);
declare_chain_cli_schema!(
WococoParachainsToBridgeHubRococo,
wococo_parachains_to_bridge_hub_rococo
);
declare_chain_cli_schema!(RococoHeadersToBridgeHubWestend, rococo_headers_to_bridge_hub_westend);
declare_chain_cli_schema!(
RococoParachainsToBridgeHubWestend,
rococo_parachains_to_bridge_hub_westend
);
declare_chain_cli_schema!(WestendHeadersToBridgeHubRococo, westend_headers_to_bridge_hub_rococo);
declare_chain_cli_schema!(
WestendParachainsToBridgeHubRococo,
westend_parachains_to_bridge_hub_rococo
);
declare_chain_cli_schema!(KusamaHeadersToBridgeHubPolkadot, kusama_headers_to_bridge_hub_polkadot);
declare_chain_cli_schema!(
KusamaParachainsToBridgeHubPolkadot,
kusama_parachains_to_bridge_hub_polkadot
);
declare_chain_cli_schema!(PolkadotHeadersToBridgeHubKusama, polkadot_headers_to_bridge_hub_kusama);
declare_chain_cli_schema!(
PolkadotParachainsToBridgeHubKusama,
polkadot_parachains_to_bridge_hub_kusama
);
declare_chain_cli_schema!(
PolkadotBulletinHeadersToBridgeHubPolkadot,
polkadot_bulletin_headers_to_bridge_hub_polkadot
);
declare_chain_cli_schema!(PolkadotHeadersToPolkadotBulletin, polkadot_headers_to_polkadot_bulletin);
declare_chain_cli_schema!(
PolkadotParachainsToPolkadotBulletin,
polkadot_parachains_to_polkadot_bulletin
);
// All supported bridges.
declare_relay_to_relay_bridge_schema!(Millau, Rialto);
declare_relay_to_parachain_bridge_schema!(Millau, RialtoParachain, Rialto);
declare_parachain_to_parachain_bridge_schema!(BridgeHubRococo, Rococo, BridgeHubWococo, Wococo);
declare_parachain_to_parachain_bridge_schema!(BridgeHubRococo, Rococo, BridgeHubWestend, Westend);
declare_parachain_to_parachain_bridge_schema!(BridgeHubKusama, Kusama, BridgeHubPolkadot, Polkadot);
@@ -434,58 +376,6 @@ where
}
}
/// Millau <> Rialto complex relay.
pub struct MillauRialtoFull2WayBridge {
base: <Self as Full2WayBridge>::Base,
}
#[async_trait]
impl Full2WayBridge for MillauRialtoFull2WayBridge {
type Base = RelayToRelayBridge<Self::L2R, Self::R2L>;
type Left = relay_millau_client::Millau;
type Right = relay_rialto_client::Rialto;
type L2R = MillauToRialtoCliBridge;
type R2L = RialtoToMillauCliBridge;
fn new(base: Self::Base) -> anyhow::Result<Self> {
Ok(Self { base })
}
fn base(&self) -> &Self::Base {
&self.base
}
fn mut_base(&mut self) -> &mut Self::Base {
&mut self.base
}
}
/// Millau <> RialtoParachain complex relay.
pub struct MillauRialtoParachainFull2WayBridge {
base: <Self as Full2WayBridge>::Base,
}
#[async_trait]
impl Full2WayBridge for MillauRialtoParachainFull2WayBridge {
type Base = RelayToParachainBridge<Self::L2R, Self::R2L>;
type Left = relay_millau_client::Millau;
type Right = relay_rialto_parachain_client::RialtoParachain;
type L2R = MillauToRialtoParachainCliBridge;
type R2L = RialtoParachainToMillauCliBridge;
fn new(base: Self::Base) -> anyhow::Result<Self> {
Ok(Self { base })
}
fn base(&self) -> &Self::Base {
&self.base
}
fn mut_base(&mut self) -> &mut Self::Base {
&mut self.base
}
}
/// BridgeHubRococo <> BridgeHubWococo complex relay.
pub struct BridgeHubRococoBridgeHubWococoFull2WayBridge {
base: <Self as Full2WayBridge>::Base,
@@ -593,10 +483,6 @@ impl Full2WayBridge for PolkadotBulletinBridgeHubPolkadotFull2WayBridge {
/// Complex headers+messages relay.
#[derive(Debug, PartialEq, StructOpt)]
pub enum RelayHeadersAndMessages {
/// Millau <> Rialto relay.
MillauRialto(MillauRialtoHeadersAndMessages),
/// Millau <> RialtoParachain relay.
MillauRialtoParachain(MillauRialtoParachainHeadersAndMessages),
/// BridgeHubRococo <> BridgeHubWococo relay.
BridgeHubRococoBridgeHubWococo(BridgeHubRococoBridgeHubWococoHeadersAndMessages),
/// BridgeHubKusama <> BridgeHubPolkadot relay.
@@ -611,12 +497,6 @@ impl RelayHeadersAndMessages {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self {
RelayHeadersAndMessages::MillauRialto(params) =>
MillauRialtoFull2WayBridge::new(params.into_bridge().await?)?.run().await,
RelayHeadersAndMessages::MillauRialtoParachain(params) =>
MillauRialtoParachainFull2WayBridge::new(params.into_bridge().await?)?
.run()
.await,
RelayHeadersAndMessages::BridgeHubRococoBridgeHubWococo(params) =>
BridgeHubRococoBridgeHubWococoFull2WayBridge::new(params.into_bridge().await?)?
.run()
@@ -642,130 +522,34 @@ mod tests {
use super::*;
#[test]
fn should_parse_relay_to_relay_options() {
fn should_parse_parachain_to_parachain_options() {
// when
let res = RelayHeadersAndMessages::from_iter(vec![
"relay-headers-and-messages",
"millau-rialto",
"--millau-host",
"millau-node-alice",
"--millau-port",
"bridge-hub-kusama-bridge-hub-polkadot",
"--bridge-hub-kusama-host",
"bridge-hub-kusama-node-collator1",
"--bridge-hub-kusama-port",
"9944",
"--millau-signer",
"//Charlie",
"--millau-transactions-mortality",
"64",
"--rialto-host",
"rialto-node-alice",
"--rialto-port",
"9944",
"--rialto-signer",
"//Charlie",
"--rialto-transactions-mortality",
"64",
"--lane",
"00000000",
"--lane",
"73776170",
"--prometheus-host",
"0.0.0.0",
]);
// then
assert_eq!(
res,
RelayHeadersAndMessages::MillauRialto(MillauRialtoHeadersAndMessages {
shared: HeadersAndMessagesSharedParams {
lane: vec![
HexLaneId([0x00, 0x00, 0x00, 0x00]),
HexLaneId([0x73, 0x77, 0x61, 0x70])
],
only_mandatory_headers: false,
prometheus_params: PrometheusParams {
no_prometheus: false,
prometheus_host: "0.0.0.0".into(),
prometheus_port: 9616,
},
},
left: MillauConnectionParams {
millau_host: "millau-node-alice".into(),
millau_port: 9944,
millau_secure: false,
millau_runtime_version: MillauRuntimeVersionParams {
millau_version_mode: RuntimeVersionType::Bundle,
millau_spec_version: None,
millau_transaction_version: None,
},
},
left_sign: MillauSigningParams {
millau_signer: Some("//Charlie".into()),
millau_signer_password: None,
millau_signer_file: None,
millau_signer_password_file: None,
millau_transactions_mortality: Some(64),
},
left_headers_to_right_sign_override: MillauHeadersToRialtoSigningParams {
millau_headers_to_rialto_signer: None,
millau_headers_to_rialto_signer_password: None,
millau_headers_to_rialto_signer_file: None,
millau_headers_to_rialto_signer_password_file: None,
millau_headers_to_rialto_transactions_mortality: None,
},
right: RialtoConnectionParams {
rialto_host: "rialto-node-alice".into(),
rialto_port: 9944,
rialto_secure: false,
rialto_runtime_version: RialtoRuntimeVersionParams {
rialto_version_mode: RuntimeVersionType::Bundle,
rialto_spec_version: None,
rialto_transaction_version: None,
},
},
right_sign: RialtoSigningParams {
rialto_signer: Some("//Charlie".into()),
rialto_signer_password: None,
rialto_signer_file: None,
rialto_signer_password_file: None,
rialto_transactions_mortality: Some(64),
},
right_headers_to_left_sign_override: RialtoHeadersToMillauSigningParams {
rialto_headers_to_millau_signer: None,
rialto_headers_to_millau_signer_password: None,
rialto_headers_to_millau_signer_file: None,
rialto_headers_to_millau_signer_password_file: None,
rialto_headers_to_millau_transactions_mortality: None,
},
}),
);
}
#[test]
fn should_parse_relay_to_parachain_options() {
// when
let res = RelayHeadersAndMessages::from_iter(vec![
"relay-headers-and-messages",
"millau-rialto-parachain",
"--millau-host",
"millau-node-alice",
"--millau-port",
"9944",
"--millau-signer",
"--bridge-hub-kusama-signer",
"//Iden",
"--rialto-headers-to-millau-signer",
"//Ken",
"--millau-transactions-mortality",
"--bridge-hub-kusama-transactions-mortality",
"64",
"--rialto-parachain-host",
"rialto-parachain-collator-charlie",
"--rialto-parachain-port",
"--kusama-host",
"kusama-alice",
"--kusama-port",
"9944",
"--rialto-parachain-signer",
"--bridge-hub-polkadot-host",
"bridge-hub-polkadot-collator1",
"--bridge-hub-polkadot-port",
"9944",
"--bridge-hub-polkadot-signer",
"//George",
"--rialto-parachain-transactions-mortality",
"--bridge-hub-polkadot-transactions-mortality",
"64",
"--rialto-host",
"rialto-node-alice",
"--rialto-port",
"--polkadot-host",
"polkadot-alice",
"--polkadot-port",
"9944",
"--lane",
"00000000",
@@ -776,8 +560,8 @@ mod tests {
// then
assert_eq!(
res,
RelayHeadersAndMessages::MillauRialtoParachain(
MillauRialtoParachainHeadersAndMessages {
RelayHeadersAndMessages::BridgeHubKusamaBridgeHubPolkadot(
BridgeHubKusamaBridgeHubPolkadotHeadersAndMessages {
shared: HeadersAndMessagesSharedParams {
lane: vec![HexLaneId([0x00, 0x00, 0x00, 0x00])],
only_mandatory_headers: false,
@@ -787,70 +571,59 @@ mod tests {
prometheus_port: 9616,
},
},
left: MillauConnectionParams {
millau_host: "millau-node-alice".into(),
millau_port: 9944,
millau_secure: false,
millau_runtime_version: MillauRuntimeVersionParams {
millau_version_mode: RuntimeVersionType::Bundle,
millau_spec_version: None,
millau_transaction_version: None,
left_relay: KusamaConnectionParams {
kusama_host: "kusama-alice".into(),
kusama_port: 9944,
kusama_secure: false,
kusama_runtime_version: KusamaRuntimeVersionParams {
kusama_version_mode: RuntimeVersionType::Bundle,
kusama_spec_version: None,
kusama_transaction_version: None,
},
},
left_sign: MillauSigningParams {
millau_signer: Some("//Iden".into()),
millau_signer_password: None,
millau_signer_file: None,
millau_signer_password_file: None,
millau_transactions_mortality: Some(64),
},
left_headers_to_right_sign_override:
MillauHeadersToRialtoParachainSigningParams {
millau_headers_to_rialto_parachain_signer: None,
millau_headers_to_rialto_parachain_signer_password: None,
millau_headers_to_rialto_parachain_signer_file: None,
millau_headers_to_rialto_parachain_signer_password_file: None,
millau_headers_to_rialto_parachain_transactions_mortality: None,
},
right: RialtoParachainConnectionParams {
rialto_parachain_host: "rialto-parachain-collator-charlie".into(),
rialto_parachain_port: 9944,
rialto_parachain_secure: false,
rialto_parachain_runtime_version: RialtoParachainRuntimeVersionParams {
rialto_parachain_version_mode: RuntimeVersionType::Bundle,
rialto_parachain_spec_version: None,
rialto_parachain_transaction_version: None,
left: BridgeHubKusamaConnectionParams {
bridge_hub_kusama_host: "bridge-hub-kusama-node-collator1".into(),
bridge_hub_kusama_port: 9944,
bridge_hub_kusama_secure: false,
bridge_hub_kusama_runtime_version: BridgeHubKusamaRuntimeVersionParams {
bridge_hub_kusama_version_mode: RuntimeVersionType::Bundle,
bridge_hub_kusama_spec_version: None,
bridge_hub_kusama_transaction_version: None,
},
},
right_sign: RialtoParachainSigningParams {
rialto_parachain_signer: Some("//George".into()),
rialto_parachain_signer_password: None,
rialto_parachain_signer_file: None,
rialto_parachain_signer_password_file: None,
rialto_parachain_transactions_mortality: Some(64),
left_sign: BridgeHubKusamaSigningParams {
bridge_hub_kusama_signer: Some("//Iden".into()),
bridge_hub_kusama_signer_password: None,
bridge_hub_kusama_signer_file: None,
bridge_hub_kusama_signer_password_file: None,
bridge_hub_kusama_transactions_mortality: Some(64),
},
right_relay_headers_to_left_sign_override: RialtoHeadersToMillauSigningParams {
rialto_headers_to_millau_signer: Some("//Ken".into()),
rialto_headers_to_millau_signer_password: None,
rialto_headers_to_millau_signer_file: None,
rialto_headers_to_millau_signer_password_file: None,
rialto_headers_to_millau_transactions_mortality: None,
right: BridgeHubPolkadotConnectionParams {
bridge_hub_polkadot_host: "bridge-hub-polkadot-collator1".into(),
bridge_hub_polkadot_port: 9944,
bridge_hub_polkadot_secure: false,
bridge_hub_polkadot_runtime_version:
BridgeHubPolkadotRuntimeVersionParams {
bridge_hub_polkadot_version_mode: RuntimeVersionType::Bundle,
bridge_hub_polkadot_spec_version: None,
bridge_hub_polkadot_transaction_version: None,
},
},
right_parachains_to_left_sign_override: RialtoParachainsToMillauSigningParams {
rialto_parachains_to_millau_signer: None,
rialto_parachains_to_millau_signer_password: None,
rialto_parachains_to_millau_signer_file: None,
rialto_parachains_to_millau_signer_password_file: None,
rialto_parachains_to_millau_transactions_mortality: None,
right_sign: BridgeHubPolkadotSigningParams {
bridge_hub_polkadot_signer: Some("//George".into()),
bridge_hub_polkadot_signer_password: None,
bridge_hub_polkadot_signer_file: None,
bridge_hub_polkadot_signer_password_file: None,
bridge_hub_polkadot_transactions_mortality: Some(64),
},
right_relay: RialtoConnectionParams {
rialto_host: "rialto-node-alice".into(),
rialto_port: 9944,
rialto_secure: false,
rialto_runtime_version: RialtoRuntimeVersionParams {
rialto_version_mode: RuntimeVersionType::Bundle,
rialto_spec_version: None,
rialto_transaction_version: None,
right_relay: PolkadotConnectionParams {
polkadot_host: "polkadot-alice".into(),
polkadot_port: 9944,
polkadot_secure: false,
polkadot_runtime_version: PolkadotRuntimeVersionParams {
polkadot_version_mode: RuntimeVersionType::Bundle,
polkadot_spec_version: None,
polkadot_transaction_version: None,
},
},
}
@@ -33,7 +33,6 @@ use substrate_relay_helper::{
on_demand::{
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
},
TaggedAccount, TransactionParams,
};
/// A base relay between two parachain from different consensus systems.
@@ -54,20 +53,6 @@ pub struct ParachainToParachainBridge<
pub left_relay: Client<<L2R as ParachainToRelayHeadersCliBridge>::SourceRelay>,
/// Client of the right relay chain.
pub right_relay: Client<<R2L as ParachainToRelayHeadersCliBridge>::SourceRelay>,
/// Override for right_relay->left headers signer.
pub right_headers_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for right->left parachains signer.
pub right_parachains_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for left_relay->right headers signer.
pub left_headers_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
/// Override for left->right parachains signer.
pub left_parachains_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
}
macro_rules! declare_parachain_to_parachain_bridge_schema {
@@ -86,12 +71,6 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
// default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)]
left_sign: [<$left_parachain SigningParams>],
// override for right_relay->left-parachain headers signer
#[structopt(flatten)]
right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_parachain SigningParams>],
// override for right->left parachains signer
#[structopt(flatten)]
right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_parachain SigningParams>],
#[structopt(flatten)]
left_relay: [<$left_chain ConnectionParams>],
@@ -101,12 +80,6 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)]
right_sign: [<$right_parachain SigningParams>],
// override for left_relay->right-parachain headers signer
#[structopt(flatten)]
left_relay_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>],
// override for left->right parachains signer
#[structopt(flatten)]
left_parachains_to_right_sign_override: [<$left_chain ParachainsTo $right_parachain SigningParams>],
#[structopt(flatten)]
right_relay: [<$right_chain ConnectionParams>],
@@ -143,18 +116,6 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
)?,
left_relay: self.left_relay.into_client::<LeftRelay>().await?,
right_relay: self.right_relay.into_client::<RightRelay>().await?,
right_headers_to_left_transaction_params: self
.right_relay_headers_to_left_sign_override
.transaction_params_or::<Left, _>(&self.left_sign)?,
left_headers_to_right_transaction_params: self
.left_relay_headers_to_right_sign_override
.transaction_params_or::<Right, _>(&self.right_sign)?,
right_parachains_to_left_transaction_params: self
.right_parachains_to_left_sign_override
.transaction_params_or::<Left, _>(&self.left_sign)?,
left_parachains_to_right_transaction_params: self
.left_parachains_to_right_sign_override
.transaction_params_or::<Right, _>(&self.right_sign)?,
})
}
}
@@ -199,23 +160,6 @@ where
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)> {
self.common.left.accounts.push(TaggedAccount::Headers {
id: self.right_headers_to_left_transaction_params.signer.public().into(),
bridged_chain: RightRelay::NAME.to_string(),
});
self.common.left.accounts.push(TaggedAccount::Parachains {
id: self.right_parachains_to_left_transaction_params.signer.public().into(),
bridged_chain: RightRelay::NAME.to_string(),
});
self.common.right.accounts.push(TaggedAccount::Headers {
id: self.left_headers_to_right_transaction_params.signer.public().into(),
bridged_chain: Left::NAME.to_string(),
});
self.common.right.accounts.push(TaggedAccount::Parachains {
id: self.left_parachains_to_right_transaction_params.signer.public().into(),
bridged_chain: LeftRelay::NAME.to_string(),
});
<L2R as ParachainToRelayHeadersCliBridge>::RelayFinality::start_relay_guards(
&self.common.right.client,
self.common.right.client.can_start_version_guard(),
@@ -231,7 +175,7 @@ where
OnDemandHeadersRelay::<<L2R as ParachainToRelayHeadersCliBridge>::RelayFinality>::new(
self.left_relay.clone(),
self.common.right.client.clone(),
self.left_headers_to_right_transaction_params.clone(),
self.common.right.tx_params.clone(),
self.common.shared.only_mandatory_headers,
Some(self.common.metrics_params.clone()),
);
@@ -239,7 +183,7 @@ where
OnDemandHeadersRelay::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_headers_to_left_transaction_params.clone(),
self.common.left.tx_params.clone(),
self.common.shared.only_mandatory_headers,
Some(self.common.metrics_params.clone()),
);
@@ -249,7 +193,7 @@ where
>::new(
self.left_relay.clone(),
self.common.right.client.clone(),
self.left_parachains_to_right_transaction_params.clone(),
self.common.right.tx_params.clone(),
Arc::new(left_relay_to_right_on_demand_headers),
);
let right_to_left_on_demand_parachains = OnDemandParachainsRelay::<
@@ -257,7 +201,7 @@ where
>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_parachains_to_left_transaction_params.clone(),
self.common.left.tx_params.clone(),
Arc::new(right_relay_to_left_on_demand_headers),
);
@@ -36,7 +36,6 @@ use substrate_relay_helper::{
on_demand::{
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
},
TaggedAccount, TransactionParams,
};
/// A base relay between standalone (relay) chain and a parachain from another consensus system.
@@ -54,17 +53,6 @@ pub struct RelayToParachainBridge<
Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
/// Client of the right relay chain.
pub right_relay: Client<<R2L as ParachainToRelayHeadersCliBridge>::SourceRelay>,
/// Override for right_relay->left headers signer.
pub right_headers_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for right->left parachains signer.
pub right_parachains_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for left->right headers signer.
pub left_headers_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
}
macro_rules! declare_relay_to_parachain_bridge_schema {
@@ -83,21 +71,12 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
// default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)]
left_sign: [<$left_chain SigningParams>],
// override for right_relay->left headers signer
#[structopt(flatten)]
right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>],
// override for right->left parachains signer
#[structopt(flatten)]
right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_chain SigningParams>],
#[structopt(flatten)]
right: [<$right_parachain ConnectionParams>],
// default signer, which is always used to sign messages relay transactions on the right chain
#[structopt(flatten)]
right_sign: [<$right_parachain SigningParams>],
// override for left->right headers signer
#[structopt(flatten)]
left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>],
#[structopt(flatten)]
right_relay: [<$right_chain ConnectionParams>],
@@ -130,19 +109,6 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
},
)?,
right_relay: self.right_relay.into_client::<RightRelay>().await?,
right_headers_to_left_transaction_params: self
.right_relay_headers_to_left_sign_override
.transaction_params_or::<Left, _>(
&self.left_sign,
)?,
right_parachains_to_left_transaction_params: self
.right_parachains_to_left_sign_override
.transaction_params_or::<Left, _>(
&self.left_sign,
)?,
left_headers_to_right_transaction_params: self
.left_headers_to_right_sign_override
.transaction_params_or::<Right, _>(&self.right_sign)?,
})
}
}
@@ -185,19 +151,6 @@ where
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)> {
self.common.left.accounts.push(TaggedAccount::Headers {
id: self.right_headers_to_left_transaction_params.signer.public().into(),
bridged_chain: RightRelay::NAME.to_string(),
});
self.common.left.accounts.push(TaggedAccount::Parachains {
id: self.right_parachains_to_left_transaction_params.signer.public().into(),
bridged_chain: RightRelay::NAME.to_string(),
});
self.common.right.accounts.push(TaggedAccount::Headers {
id: self.left_headers_to_right_transaction_params.signer.public().into(),
bridged_chain: Left::NAME.to_string(),
});
<L2R as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
&self.common.right.client,
self.common.right.client.can_start_version_guard(),
@@ -213,7 +166,7 @@ where
OnDemandHeadersRelay::<<L2R as RelayToRelayHeadersCliBridge>::Finality>::new(
self.common.left.client.clone(),
self.common.right.client.clone(),
self.left_headers_to_right_transaction_params.clone(),
self.common.right.tx_params.clone(),
self.common.shared.only_mandatory_headers,
None,
);
@@ -221,7 +174,7 @@ where
OnDemandHeadersRelay::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_headers_to_left_transaction_params.clone(),
self.common.left.tx_params.clone(),
self.common.shared.only_mandatory_headers,
Some(self.common.metrics_params.clone()),
);
@@ -230,7 +183,7 @@ where
>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_parachains_to_left_transaction_params.clone(),
self.common.left.tx_params.clone(),
Arc::new(right_relay_to_left_on_demand_headers),
);
@@ -14,6 +14,10 @@
// 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/>.
// we don't have any relay/standalone <> relay/standalone chain bridges, but we may need it in a
// future
#![allow(unused_macros)]
use async_trait::async_trait;
use std::sync::Arc;
@@ -27,7 +31,6 @@ use sp_core::Pair;
use substrate_relay_helper::{
finality::SubstrateFinalitySyncPipeline,
on_demand::{headers::OnDemandHeadersRelay, OnDemandRelay},
TaggedAccount, TransactionParams,
};
/// A base relay between two standalone (relay) chains.
@@ -40,12 +43,6 @@ pub struct RelayToRelayBridge<
/// Parameters that are shared by all bridge types.
pub common:
Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
/// Override for right->left headers signer.
pub right_to_left_transaction_params:
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
/// Override for left->right headers signer.
pub left_to_right_transaction_params:
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
}
macro_rules! declare_relay_to_relay_bridge_schema {
@@ -62,18 +59,12 @@ macro_rules! declare_relay_to_relay_bridge_schema {
// default signer, which is always used to sign messages relay transactions on the left chain
#[structopt(flatten)]
left_sign: [<$left_chain SigningParams>],
// override for right->left headers signer
#[structopt(flatten)]
right_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>],
#[structopt(flatten)]
right: [<$right_chain ConnectionParams>],
#[structopt(flatten)]
// default signer, which is always used to sign messages relay transactions on the right chain
right_sign: [<$right_chain SigningParams>],
// override for left->right headers signer
#[structopt(flatten)]
left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_chain SigningParams>],
}
impl [<$left_chain $right_chain HeadersAndMessages>] {
@@ -99,12 +90,8 @@ macro_rules! declare_relay_to_relay_bridge_schema {
accounts: vec![],
},
)?,
right_to_left_transaction_params: self
.right_headers_to_left_sign_override
.transaction_params_or::<Left, _>(&self.left_sign)?,
left_to_right_transaction_params: self
.left_headers_to_right_sign_override
.transaction_params_or::<Right, _>(&self.right_sign)?,
right_to_left_transaction_params: self.left_sign.transaction_params::<Left>(),
left_to_right_transaction_params: self.right_sign.transaction_params::<Right>(),
})
}
}
@@ -145,15 +132,6 @@ where
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)> {
self.common.right.accounts.push(TaggedAccount::Headers {
id: self.left_to_right_transaction_params.signer.public().into(),
bridged_chain: Self::Left::NAME.to_string(),
});
self.common.left.accounts.push(TaggedAccount::Headers {
id: self.right_to_left_transaction_params.signer.public().into(),
bridged_chain: Self::Right::NAME.to_string(),
});
<L2R as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
&self.common.right.client,
self.common.right.client.can_start_version_guard(),
@@ -169,7 +147,7 @@ where
OnDemandHeadersRelay::<<L2R as RelayToRelayHeadersCliBridge>::Finality>::new(
self.common.left.client.clone(),
self.common.right.client.clone(),
self.left_to_right_transaction_params.clone(),
self.common.right.tx_params.clone(),
self.common.shared.only_mandatory_headers,
None,
);
@@ -177,7 +155,7 @@ where
OnDemandHeadersRelay::<<R2L as RelayToRelayHeadersCliBridge>::Finality>::new(
self.common.right.client.clone(),
self.common.left.client.clone(),
self.right_to_left_transaction_params.clone(),
self.common.left.tx_params.clone(),
self.common.shared.only_mandatory_headers,
None,
);
@@ -28,14 +28,6 @@ use crate::bridges::{
bridge_hub_polkadot_messages_to_polkadot_bulletin::BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge,
polkadot_bulletin_messages_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge,
},
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::{
millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
},
rococo_westend::{
bridge_hub_rococo_messages_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendMessagesCliBridge,
bridge_hub_westend_messages_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoMessagesCliBridge,
@@ -109,10 +101,6 @@ where
}
}
impl MessagesRelayer for MillauToRialtoCliBridge {}
impl MessagesRelayer for RialtoToMillauCliBridge {}
impl MessagesRelayer for MillauToRialtoParachainCliBridge {}
impl MessagesRelayer for RialtoParachainToMillauCliBridge {}
impl MessagesRelayer for BridgeHubRococoToBridgeHubWococoMessagesCliBridge {}
impl MessagesRelayer for BridgeHubWococoToBridgeHubRococoMessagesCliBridge {}
impl MessagesRelayer for BridgeHubRococoToBridgeHubWestendMessagesCliBridge {}
@@ -126,12 +114,6 @@ impl RelayMessages {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
FullBridge::MillauToRialto => MillauToRialtoCliBridge::relay_messages(self),
FullBridge::RialtoToMillau => RialtoToMillauCliBridge::relay_messages(self),
FullBridge::MillauToRialtoParachain =>
MillauToRialtoParachainCliBridge::relay_messages(self),
FullBridge::RialtoParachainToMillau =>
RialtoParachainToMillauCliBridge::relay_messages(self),
FullBridge::BridgeHubRococoToBridgeHubWococo =>
BridgeHubRococoToBridgeHubWococoMessagesCliBridge::relay_messages(self),
FullBridge::BridgeHubWococoToBridgeHubRococo =>
@@ -20,7 +20,6 @@ use crate::bridges::{
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
},
polkadot_bulletin::polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
rialto_parachain_millau::rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
rococo_westend::{
rococo_parachains_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendCliBridge,
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
@@ -29,7 +28,6 @@ use crate::bridges::{
rococo_parachains_to_bridge_hub_wococo::BridgeHubRococoToBridgeHubWococoCliBridge,
wococo_parachains_to_bridge_hub_rococo::BridgeHubWococoToBridgeHubRococoCliBridge,
},
westend_millau::westend_parachains_to_millau::AssetHubWestendToMillauCliBridge,
};
use async_std::sync::Mutex;
use async_trait::async_trait;
@@ -70,8 +68,6 @@ pub struct RelayParachains {
#[derive(Debug, EnumString, EnumVariantNames)]
#[strum(serialize_all = "kebab_case")]
pub enum RelayParachainsBridge {
RialtoToMillau,
WestendToMillau,
RococoToBridgeHubWococo,
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
@@ -122,8 +118,6 @@ where
}
}
impl ParachainsRelayer for RialtoParachainToMillauCliBridge {}
impl ParachainsRelayer for AssetHubWestendToMillauCliBridge {}
impl ParachainsRelayer for BridgeHubRococoToBridgeHubWococoCliBridge {}
impl ParachainsRelayer for BridgeHubWococoToBridgeHubRococoCliBridge {}
impl ParachainsRelayer for BridgeHubRococoToBridgeHubWestendCliBridge {}
@@ -136,10 +130,6 @@ impl RelayParachains {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
RelayParachainsBridge::RialtoToMillau =>
RialtoParachainToMillauCliBridge::relay_parachains(self),
RelayParachainsBridge::WestendToMillau =>
AssetHubWestendToMillauCliBridge::relay_parachains(self),
RelayParachainsBridge::RococoToBridgeHubWococo =>
BridgeHubRococoToBridgeHubWococoCliBridge::relay_parachains(self),
RelayParachainsBridge::WococoToBridgeHubRococo =>
@@ -1,560 +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::cli::{chain_schema::*, Balance};
use bp_runtime::HeaderIdProvider;
use codec::{Decode, Encode};
use num_traits::{One, Zero};
use relay_substrate_client::{
AccountKeyPairOf, BlockWithJustification, Chain, ChainWithTransactions, Client,
Error as SubstrateError, HeaderIdOf, HeaderOf, SignParam,
};
use relay_utils::FailedClient;
use sp_core::Bytes;
use sp_runtime::{
traits::{Hash, Header as HeaderT},
transaction_validity::TransactionPriority,
};
use structopt::StructOpt;
use strum::{EnumString, EnumVariantNames, VariantNames};
use substrate_relay_helper::TransactionParams;
/// Start resubmit transactions process.
#[derive(StructOpt)]
pub struct ResubmitTransactions {
/// A bridge instance to relay headers for.
#[structopt(possible_values = RelayChain::VARIANTS, case_insensitive = true)]
chain: RelayChain,
#[structopt(flatten)]
target: TargetConnectionParams,
#[structopt(flatten)]
target_sign: TargetSigningParams,
/// Number of blocks we see before considering queued transaction as stalled.
#[structopt(long, default_value = "5")]
stalled_blocks: u32,
/// Tip limit. We'll never submit transaction with larger tip.
#[structopt(long)]
tip_limit: Balance,
/// Tip increase step. We'll be checking updated transaction priority by increasing its tip by
/// this step.
#[structopt(long)]
tip_step: Balance,
/// Priority selection strategy.
#[structopt(subcommand)]
strategy: PrioritySelectionStrategy,
}
/// Chain, which transactions we're going to track && resubmit.
#[derive(Debug, EnumString, EnumVariantNames)]
#[strum(serialize_all = "kebab_case")]
pub enum RelayChain {
Millau,
}
/// Strategy to use for priority selection.
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy)]
pub enum PrioritySelectionStrategy {
/// Strategy selects tip that changes transaction priority to be better than priority of
/// the first transaction of previous block.
///
/// It only makes sense to use this strategy for Millau transactions. Millau has transactions
/// that are close to block limits, so if there are any other queued transactions, 'large'
/// transaction won't fit the block && will be postponed. To avoid this, we change its priority
/// to some large value, making it best transaction => it'll be 'mined' first.
MakeItBestTransaction,
/// Strategy selects tip that changes transaction priority to be better than priority of
/// selected queued transaction.
///
/// When we first see stalled transaction, we make it better than worst 1/4 of queued
/// transactions. If it is still stalled, we'll make it better than 1/3 of queued transactions,
/// ...
MakeItBetterThanQueuedTransaction,
}
macro_rules! select_bridge {
($bridge: expr, $generic: tt) => {
match $bridge {
RelayChain::Millau => {
type Target = relay_millau_client::Millau;
$generic
},
}
};
}
impl ResubmitTransactions {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
select_bridge!(self.chain, {
let relay_loop_name = format!("ResubmitTransactions{}", Target::NAME);
let client = self.target.into_client::<Target>().await?;
let transaction_params = TransactionParams {
signer: self.target_sign.to_keypair::<Target>()?,
mortality: self.target_sign.target_transactions_mortality,
};
relay_utils::relay_loop((), client)
.run(relay_loop_name, move |_, client, _| {
run_until_connection_lost(
client,
transaction_params.clone(),
Context {
strategy: self.strategy,
best_header: HeaderOf::<Target>::new(
Default::default(),
Default::default(),
Default::default(),
Default::default(),
Default::default(),
),
transaction: None,
resubmitted: 0,
stalled_for: Zero::zero(),
stalled_for_limit: self.stalled_blocks as _,
tip_step: self.tip_step.cast() as _,
tip_limit: self.tip_limit.cast() as _,
},
)
})
.await
.map_err(Into::into)
})
}
}
impl PrioritySelectionStrategy {
/// Select target priority.
async fn select_target_priority<C: ChainWithTransactions>(
&self,
client: &Client<C>,
context: &Context<C>,
) -> Result<Option<TransactionPriority>, SubstrateError> {
match *self {
PrioritySelectionStrategy::MakeItBestTransaction =>
read_previous_block_best_priority(client, context).await,
PrioritySelectionStrategy::MakeItBetterThanQueuedTransaction =>
select_priority_from_queue(client, context).await,
}
}
}
#[derive(Debug)]
struct Context<C: Chain> {
/// Priority selection strategy.
strategy: PrioritySelectionStrategy,
/// Best known block header.
best_header: C::Header,
/// Hash of the (potentially) stalled transaction.
transaction: Option<C::Hash>,
/// How many times we have resubmitted this `transaction`?
resubmitted: u32,
/// This transaction is in pool for `stalled_for` wakeup intervals.
stalled_for: C::BlockNumber,
/// When `stalled_for` reaching this limit, transaction is considered stalled.
stalled_for_limit: C::BlockNumber,
/// Tip step interval.
tip_step: C::Balance,
/// Maximal tip.
tip_limit: C::Balance,
}
impl<C: Chain> Context<C> {
/// Return true if transaction has stalled.
fn is_stalled(&self) -> bool {
self.stalled_for >= self.stalled_for_limit
}
/// Notice resubmitted transaction.
fn notice_resubmitted_transaction(mut self, transaction: C::Hash) -> Self {
self.transaction = Some(transaction);
self.stalled_for = Zero::zero();
self.resubmitted += 1;
self
}
/// Notice transaction from the transaction pool.
fn notice_transaction(mut self, transaction: C::Hash) -> Self {
if self.transaction == Some(transaction) {
self.stalled_for += One::one();
} else {
self.transaction = Some(transaction);
self.stalled_for = One::one();
self.resubmitted = 0;
}
self
}
}
/// Run resubmit transactions loop.
async fn run_until_connection_lost<C: ChainWithTransactions>(
client: Client<C>,
transaction_params: TransactionParams<AccountKeyPairOf<C>>,
mut context: Context<C>,
) -> Result<(), FailedClient> {
loop {
async_std::task::sleep(C::AVERAGE_BLOCK_INTERVAL).await;
let result = run_loop_iteration(client.clone(), transaction_params.clone(), context).await;
context = match result {
Ok(context) => context,
Err(error) => {
log::error!(
target: "bridge",
"Resubmit {} transactions loop has failed with error: {:?}",
C::NAME,
error,
);
return Err(FailedClient::Target)
},
};
}
}
/// Run single loop iteration.
async fn run_loop_iteration<C: ChainWithTransactions>(
client: Client<C>,
transaction_params: TransactionParams<AccountKeyPairOf<C>>,
mut context: Context<C>,
) -> Result<Context<C>, SubstrateError> {
// correct best header is required for all other actions
context.best_header = client.best_header().await?;
// check if there's queued transaction, signed by given author
let original_transaction =
match lookup_signer_transaction(&client, &transaction_params.signer).await? {
Some(original_transaction) => original_transaction,
None => {
log::trace!(target: "bridge", "No {} transactions from required signer in the txpool", C::NAME);
return Ok(context)
},
};
let original_transaction_hash = C::Hasher::hash(&original_transaction.encode());
let context = context.notice_transaction(original_transaction_hash);
// if transaction hasn't been mined for `stalled_blocks`, we'll need to resubmit it
if !context.is_stalled() {
log::trace!(
target: "bridge",
"{} transaction {:?} is not yet stalled ({:?}/{:?})",
C::NAME,
context.transaction,
context.stalled_for,
context.stalled_for_limit,
);
return Ok(context)
}
// select priority for updated transaction
let target_priority = match context.strategy.select_target_priority(&client, &context).await? {
Some(target_priority) => target_priority,
None => {
log::trace!(target: "bridge", "Failed to select target priority");
return Ok(context)
},
};
// update transaction tip
let (is_updated, updated_transaction) = update_transaction_tip(
&client,
&transaction_params,
context.best_header.id(),
original_transaction,
context.tip_step,
context.tip_limit,
target_priority,
)
.await?;
if !is_updated {
log::trace!(target: "bridge", "{} transaction tip can not be updated. Reached limit?", C::NAME);
return Ok(context)
}
let updated_transaction = updated_transaction.encode();
let updated_transaction_hash = C::Hasher::hash(&updated_transaction);
client.submit_unsigned_extrinsic(Bytes(updated_transaction)).await?;
log::info!(
target: "bridge",
"Replaced {} transaction {} with {} in txpool",
C::NAME,
original_transaction_hash,
updated_transaction_hash,
);
Ok(context.notice_resubmitted_transaction(updated_transaction_hash))
}
/// Search transaction pool for transaction, signed by given key pair.
async fn lookup_signer_transaction<C: ChainWithTransactions>(
client: &Client<C>,
key_pair: &AccountKeyPairOf<C>,
) -> Result<Option<C::SignedTransaction>, SubstrateError> {
let pending_transactions = client.pending_extrinsics().await?;
for pending_transaction in pending_transactions {
let pending_transaction = C::SignedTransaction::decode(&mut &pending_transaction.0[..])
.map_err(SubstrateError::ResponseParseFailed)?;
if !C::is_signed_by(key_pair, &pending_transaction) {
continue
}
return Ok(Some(pending_transaction))
}
Ok(None)
}
/// Read priority of best signed transaction of previous block.
async fn read_previous_block_best_priority<C: ChainWithTransactions>(
client: &Client<C>,
context: &Context<C>,
) -> Result<Option<TransactionPriority>, SubstrateError> {
let best_block = client.get_block(Some(context.best_header.hash())).await?;
let best_transaction = best_block
.extrinsics()
.iter()
.filter_map(|xt| C::SignedTransaction::decode(&mut &xt[..]).ok())
.find(|xt| C::is_signed(xt));
match best_transaction {
Some(best_transaction) => Ok(Some(
client
.validate_transaction(*context.best_header.parent_hash(), best_transaction)
.await??
.priority,
)),
None => Ok(None),
}
}
/// Select priority of some queued transaction.
async fn select_priority_from_queue<C: ChainWithTransactions>(
client: &Client<C>,
context: &Context<C>,
) -> Result<Option<TransactionPriority>, SubstrateError> {
// select transaction from the queue
let queued_transactions = client.pending_extrinsics().await?;
let selected_transaction = match select_transaction_from_queue(queued_transactions, context) {
Some(selected_transaction) => selected_transaction,
None => return Ok(None),
};
let selected_transaction = C::SignedTransaction::decode(&mut &selected_transaction[..])
.map_err(SubstrateError::ResponseParseFailed)?;
let target_priority = client
.validate_transaction(context.best_header.hash(), selected_transaction)
.await??
.priority;
Ok(Some(target_priority))
}
/// Select transaction with target priority from the vec of queued transactions.
fn select_transaction_from_queue<C: Chain>(
mut queued_transactions: Vec<Bytes>,
context: &Context<C>,
) -> Option<Bytes> {
if queued_transactions.is_empty() {
return None
}
// the more times we resubmit transaction (`context.resubmitted`), the closer we move
// to the front of the transaction queue
let total_transactions = queued_transactions.len();
let resubmitted_factor = context.resubmitted;
let divisor =
1usize.saturating_add(1usize.checked_shl(resubmitted_factor).unwrap_or(usize::MAX));
let transactions_to_skip = total_transactions / divisor;
Some(
queued_transactions
.swap_remove(std::cmp::min(total_transactions - 1, transactions_to_skip)),
)
}
/// Try to find appropriate tip for transaction so that its priority is larger than given.
async fn update_transaction_tip<C: ChainWithTransactions>(
client: &Client<C>,
transaction_params: &TransactionParams<AccountKeyPairOf<C>>,
at_block: HeaderIdOf<C>,
tx: C::SignedTransaction,
tip_step: C::Balance,
tip_limit: C::Balance,
target_priority: TransactionPriority,
) -> Result<(bool, C::SignedTransaction), SubstrateError> {
let stx = format!("{tx:?}");
let mut current_priority = client.validate_transaction(at_block.1, tx.clone()).await??.priority;
let mut unsigned_tx = C::parse_transaction(tx).ok_or_else(|| {
SubstrateError::Custom(format!("Failed to parse {} transaction {stx}", C::NAME,))
})?;
let old_tip = unsigned_tx.tip;
let runtime_version = client.simple_runtime_version().await?;
while current_priority < target_priority {
let next_tip = unsigned_tx.tip + tip_step;
if next_tip > tip_limit {
break
}
log::trace!(
target: "bridge",
"{} transaction priority with tip={:?}: {}. Target priority: {}",
C::NAME,
unsigned_tx.tip,
current_priority,
target_priority,
);
unsigned_tx.tip = next_tip;
current_priority = client
.validate_transaction(
at_block.1,
C::sign_transaction(
SignParam {
spec_version: runtime_version.spec_version,
transaction_version: runtime_version.transaction_version,
genesis_hash: *client.genesis_hash(),
signer: transaction_params.signer.clone(),
},
unsigned_tx.clone(),
)?,
)
.await??
.priority;
}
log::debug!(
target: "bridge",
"{} transaction tip has changed from {:?} to {:?}",
C::NAME,
old_tip,
unsigned_tx.tip,
);
Ok((
old_tip != unsigned_tx.tip,
C::sign_transaction(
SignParam {
spec_version: runtime_version.spec_version,
transaction_version: runtime_version.transaction_version,
genesis_hash: *client.genesis_hash(),
signer: transaction_params.signer.clone(),
},
unsigned_tx.era(relay_substrate_client::TransactionEra::new(
at_block,
transaction_params.mortality,
)),
)?,
))
}
#[cfg(test)]
mod tests {
use super::*;
use bp_rialto::Hash;
use relay_rialto_client::Rialto;
fn context() -> Context<Rialto> {
Context {
strategy: PrioritySelectionStrategy::MakeItBestTransaction,
best_header: HeaderOf::<Rialto>::new(
Default::default(),
Default::default(),
Default::default(),
Default::default(),
Default::default(),
),
transaction: None,
resubmitted: 0,
stalled_for: Zero::zero(),
stalled_for_limit: 3,
tip_step: 100,
tip_limit: 1000,
}
}
#[test]
fn context_works() {
let mut context = context();
// when transaction is noticed 2/3 times, it isn't stalled
context = context.notice_transaction(Default::default());
assert!(!context.is_stalled());
assert_eq!(context.stalled_for, 1);
assert_eq!(context.resubmitted, 0);
context = context.notice_transaction(Default::default());
assert!(!context.is_stalled());
assert_eq!(context.stalled_for, 2);
assert_eq!(context.resubmitted, 0);
// when transaction is noticed for 3rd time in a row, it is considered stalled
context = context.notice_transaction(Default::default());
assert!(context.is_stalled());
assert_eq!(context.stalled_for, 3);
assert_eq!(context.resubmitted, 0);
// and after we resubmit it, we forget previous transaction
context = context.notice_resubmitted_transaction(Hash::from([1; 32]));
assert_eq!(context.transaction, Some(Hash::from([1; 32])));
assert_eq!(context.resubmitted, 1);
assert_eq!(context.stalled_for, 0);
}
#[test]
fn select_transaction_from_queue_works_with_empty_queue() {
assert_eq!(select_transaction_from_queue(vec![], &context()), None);
}
#[test]
fn select_transaction_from_queue_works() {
let mut context = context();
let queued_transactions = vec![
Bytes(vec![1]),
Bytes(vec![2]),
Bytes(vec![3]),
Bytes(vec![4]),
Bytes(vec![5]),
Bytes(vec![6]),
];
// when we resubmit tx for the first time, 1/2 of queue is skipped
assert_eq!(
select_transaction_from_queue(queued_transactions.clone(), &context),
Some(Bytes(vec![4])),
);
// when we resubmit tx for the second time, 1/3 of queue is skipped
context = context.notice_resubmitted_transaction(Hash::from([1; 32]));
assert_eq!(
select_transaction_from_queue(queued_transactions.clone(), &context),
Some(Bytes(vec![3])),
);
// when we resubmit tx for the third time, 1/5 of queue is skipped
context = context.notice_resubmitted_transaction(Hash::from([2; 32]));
assert_eq!(
select_transaction_from_queue(queued_transactions.clone(), &context),
Some(Bytes(vec![2])),
);
// when we resubmit tx for the second time, 1/9 of queue is skipped
context = context.notice_resubmitted_transaction(Hash::from([3; 32]));
assert_eq!(
select_transaction_from_queue(queued_transactions, &context),
Some(Bytes(vec![1])),
);
}
}
@@ -1,177 +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::{
bridges::{
rialto_millau::{
millau_headers_to_rialto::MillauToRialtoCliBridge,
rialto_headers_to_millau::RialtoToMillauCliBridge,
},
rialto_parachain_millau::{
millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge,
rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
},
},
cli::{
bridge::{FullBridge, MessagesCliBridge},
chain_schema::*,
encode_message::{self, CliEncodeMessage, RawMessage},
CliChain,
},
};
use async_trait::async_trait;
use codec::{Decode, Encode};
use relay_substrate_client::{
AccountIdOf, AccountKeyPairOf, Chain, ChainBase, ChainWithTransactions, UnsignedTransaction,
};
use sp_core::Pair;
use sp_runtime::AccountId32;
use std::fmt::Display;
use structopt::StructOpt;
use strum::VariantNames;
/// Send bridge message.
#[derive(StructOpt)]
pub struct SendMessage {
/// A bridge instance to encode call for.
#[structopt(possible_values = FullBridge::VARIANTS, case_insensitive = true)]
bridge: FullBridge,
#[structopt(flatten)]
source: SourceConnectionParams,
#[structopt(flatten)]
source_sign: SourceSigningParams,
/// Message type.
#[structopt(subcommand)]
message: crate::cli::encode_message::Message,
}
#[async_trait]
trait MessageSender: MessagesCliBridge
where
Self::Source: ChainBase<Nonce = u32> + ChainWithTransactions + CliChain + CliEncodeMessage,
<Self::Source as ChainBase>::Balance: Display + From<u64> + Into<u128>,
<Self::Source as Chain>::Call: Sync,
<Self::Source as ChainWithTransactions>::SignedTransaction: Sync,
AccountIdOf<Self::Source>: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
AccountId32: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
{
async fn send_message(data: SendMessage) -> anyhow::Result<()> {
let payload = encode_message::encode_message::<Self::Source, Self::Target>(&data.message)?;
let source_client = data.source.into_client::<Self::Source>().await?;
let source_sign = data.source_sign.to_keypair::<Self::Source>()?;
let payload_len = payload.encoded_size();
let send_message_call = Self::Source::encode_execute_xcm(decode_xcm(payload)?)?;
source_client
.submit_signed_extrinsic(&source_sign, move |_, transaction_nonce| {
let unsigned = UnsignedTransaction::new(send_message_call, transaction_nonce);
log::info!(
target: "bridge",
"Sending message to {}. Size: {}",
Self::Target::NAME,
payload_len,
);
Ok(unsigned)
})
.await?;
Ok(())
}
}
impl MessageSender for MillauToRialtoCliBridge {}
impl MessageSender for RialtoToMillauCliBridge {}
impl MessageSender for MillauToRialtoParachainCliBridge {}
impl MessageSender for RialtoParachainToMillauCliBridge {}
impl SendMessage {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
match self.bridge {
FullBridge::MillauToRialto => MillauToRialtoCliBridge::send_message(self),
FullBridge::RialtoToMillau => RialtoToMillauCliBridge::send_message(self),
FullBridge::MillauToRialtoParachain =>
MillauToRialtoParachainCliBridge::send_message(self),
FullBridge::RialtoParachainToMillau =>
RialtoParachainToMillauCliBridge::send_message(self),
// all our (soon to retire_ testnets are above, so if is fine to use `_`
_ => unimplemented!("Sending message from in {:?} is not supported", self.bridge,),
}
.await
}
}
/// Decode SCALE encoded raw XCM message.
pub(crate) fn decode_xcm<Call>(message: RawMessage) -> anyhow::Result<xcm::VersionedXcm<Call>> {
Decode::decode(&mut &message[..])
.map_err(|e| anyhow::format_err!("Failed to decode XCM program: {:?}", e))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cli::{ExplicitOrMaximal, HexBytes};
#[test]
fn send_raw_rialto_to_millau() {
// given
let send_message = SendMessage::from_iter(vec![
"send-message",
"rialto-to-millau",
"--source-port",
"1234",
"--source-signer",
"//Alice",
"raw",
"dead",
]);
// then
assert_eq!(send_message.bridge, FullBridge::RialtoToMillau);
assert_eq!(send_message.source.source_port, 1234);
assert_eq!(send_message.source_sign.source_signer, Some("//Alice".into()));
assert_eq!(
send_message.message,
crate::cli::encode_message::Message::Raw { data: HexBytes(vec![0xDE, 0xAD]) }
);
}
#[test]
fn send_sized_rialto_to_millau() {
// given
let send_message = SendMessage::from_iter(vec![
"send-message",
"rialto-to-millau",
"--source-port",
"1234",
"--source-signer",
"//Alice",
"sized",
"max",
]);
// then
assert_eq!(send_message.bridge, FullBridge::RialtoToMillau);
assert_eq!(send_message.source.source_port, 1234);
assert_eq!(send_message.source_sign.source_signer, Some("//Alice".into()));
assert_eq!(
send_message.message,
crate::cli::encode_message::Message::Sized { size: ExplicitOrMaximal::Maximal }
);
}
}