Merge bulletin chain changes into polkadot staging (#2574)

* polkadot-staging for v1.0.0

* Add polkadot bulletin chain primitives (#2542)

* add polkadot bulletin chain primitives

* also impl ChainWithMessages

* clippy

* instead of requiring sp_std::vec::Vec import when using runtime API generation macro, let's use full type path directly in macro (#2551)

* Polkadot Bulletin Chain client (#2552)

* relay-polkadot-bulletin-client

* generate Polkadot Bulletin Chain Runtime

* Add relays that will be used in Polkadot Bulletin <> Polkadot.BH bridge (#2556)

* added Polkadot.BH <> Polkadot Bulletin chain relays

* uncommented ED stuff

* complex PolkadotBulletin <> Polkadot.BH relay

* removed TODO

* spelling

* prepare refund extension infra to add refund extension for messages from standalone chain (#2558)

* prepare refund extension infra to add refund extension for messages from standalone chain

* spelling

* apply adapter to fix compilation

* clippy

* added POLKADOT_BULLETIN_CHAIN_ID constant

* RefundBridgedGrandpaMessages to refund transaction costs for messages coming to/from bridged standalone/relay chain (#2566)

* RefundBridgedGrandpaMessages to refund transaction costs for messages coming to/from bridged standalone/relay chain

* clippy

* fix compilation

* fix codec dependency (#2567)

* Support message relay limits override (#2570)

* support message relay limits overrides for bridges

* spelling

* export EXTRA_STORAGE_PROOF_SIZE for Polkadot Bulletin (#2572)
This commit is contained in:
Svyatoslav Nikolsky
2023-09-19 15:02:41 +03:00
committed by Bastian Köcher
parent 4cd9e2fe79
commit 0bbd2b20a2
41 changed files with 3351 additions and 361 deletions
+2
View File
@@ -26,6 +26,7 @@ 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" }
@@ -43,6 +44,7 @@ relay-bridge-hub-rococo-client = { path = "../client-bridge-hub-rococo" }
relay-bridge-hub-wococo-client = { path = "../client-bridge-hub-wococo" }
relay-kusama-client = { path = "../client-kusama" }
relay-polkadot-client = { path = "../client-polkadot" }
relay-polkadot-bulletin-client = { path = "../client-polkadot-bulletin" }
relay-rococo-client = { path = "../client-rococo" }
relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
@@ -17,6 +17,7 @@
//! Declaration of all bridges that the relay is able to serve.
pub mod kusama_polkadot;
pub mod polkadot_bulletin;
pub mod rialto_millau;
pub mod rialto_parachain_millau;
pub mod rococo_wococo;
@@ -0,0 +1,65 @@
// Copyright 2022 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/>.
//! BridgeHubPolkadot-to-PolkadotBulletin messages sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
use relay_polkadot_bulletin_client::PolkadotBulletin;
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
/// BridgeHubPolkadot-to-PolkadotBulletin messages bridge.
pub struct BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {}
impl CliBridgeBase for BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {
type Source = BridgeHubPolkadot;
type Target = PolkadotBulletin;
}
impl MessagesCliBridge for BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {
type MessagesLane = BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane;
}
substrate_relay_helper::generate_receive_message_proof_call_builder!(
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane,
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLaneReceiveMessagesProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotBridgeHubMessages,
relay_polkadot_bulletin_client::BridgePolkadotBridgeHubMessagesCall::receive_messages_proof
);
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane,
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLaneReceiveMessagesDeliveryProofCallBuilder,
relay_bridge_hub_polkadot_client::runtime::Call::BridgePolkadotBulletinMessages,
relay_bridge_hub_polkadot_client::runtime::BridgePolkadotBulletinMessagesCall::receive_messages_delivery_proof
);
/// BridgeHubPolkadot-to-PolkadotBulletin messages lane.
#[derive(Clone, Debug)]
pub struct BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane;
impl SubstrateMessageLane for BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane {
type SourceChain = BridgeHubPolkadot;
type TargetChain = PolkadotBulletin;
type ReceiveMessagesProofCallBuilder =
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLaneReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder =
BridgeHubPolkadotMessagesToPolkadotBulletinMessageLaneReceiveMessagesDeliveryProofCallBuilder;
type SourceBatchCallBuilder = UtilityPalletBatchCallBuilder<BridgeHubPolkadot>;
type TargetBatchCallBuilder = ();
}
@@ -0,0 +1,23 @@
// 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 Polkadot Bulletin Chain and Polkadot Bridge Hub.
pub mod bridge_hub_polkadot_messages_to_polkadot_bulletin;
pub mod polkadot_bulletin_headers_to_bridge_hub_polkadot;
pub mod polkadot_bulletin_messages_to_bridge_hub_polkadot;
pub mod polkadot_headers_to_polkadot_bulletin;
pub mod polkadot_parachains_to_polkadot_bulletin;
@@ -0,0 +1,101 @@
// Copyright 2022 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/>.
//! PolkadotBulletin-to-BridgeHubPolkadot headers sync entrypoint.
use crate::cli::bridge::{
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait;
use relay_substrate_client::{AccountKeyPairOf, Client};
use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
TransactionParams,
};
/// Description of `PolkadotBulletin` -> `PolkadotBridgeHub` finalized headers bridge.
#[derive(Clone, Debug)]
pub struct PolkadotBulletinFinalityToBridgeHubPolkadot;
substrate_relay_helper::generate_submit_finality_proof_call_builder!(
PolkadotBulletinFinalityToBridgeHubPolkadot,
SubmitFinalityProofCallBuilder,
relay_bridge_hub_polkadot_client::runtime::Call::BridgePolkadotBulletinGrandpa,
relay_bridge_hub_polkadot_client::runtime::BridgePolkadotBulletinGrandpaCall::submit_finality_proof
);
substrate_relay_helper::generate_report_equivocation_call_builder!(
PolkadotBulletinFinalityToBridgeHubPolkadot,
ReportEquivocationCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::Grandpa,
relay_polkadot_bulletin_client::GrandpaCall::report_equivocation
);
#[async_trait]
impl SubstrateFinalityPipeline for PolkadotBulletinFinalityToBridgeHubPolkadot {
type SourceChain = relay_polkadot_bulletin_client::PolkadotBulletin;
type TargetChain = relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
#[async_trait]
impl SubstrateFinalitySyncPipeline for PolkadotBulletinFinalityToBridgeHubPolkadot {
type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
async fn start_relay_guards(
target_client: &Client<Self::TargetChain>,
_transaction_params: &TransactionParams<AccountKeyPairOf<Self::TargetChain>>,
enable_version_guard: bool,
) -> relay_substrate_client::Result<()> {
if enable_version_guard {
relay_substrate_client::guard::abort_on_spec_version_change(
target_client.clone(),
target_client.simple_runtime_version().await?.spec_version,
);
}
Ok(())
}
}
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for PolkadotBulletinFinalityToBridgeHubPolkadot {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `PolkadotBulletin` to BridgeHub `Polkadot` bridge definition.
pub struct PolkadotBulletinToBridgeHubPolkadotCliBridge {}
impl CliBridgeBase for PolkadotBulletinToBridgeHubPolkadotCliBridge {
type Source = relay_polkadot_bulletin_client::PolkadotBulletin;
type Target = relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
}
impl RelayToRelayHeadersCliBridge for PolkadotBulletinToBridgeHubPolkadotCliBridge {
type Finality = PolkadotBulletinFinalityToBridgeHubPolkadot;
}
impl RelayToRelayEquivocationDetectionCliBridge for PolkadotBulletinToBridgeHubPolkadotCliBridge {
type Equivocation = PolkadotBulletinFinalityToBridgeHubPolkadot;
}
impl MessagesCliBridge for PolkadotBulletinToBridgeHubPolkadotCliBridge {
type MessagesLane = crate::bridges::polkadot_bulletin::polkadot_bulletin_messages_to_bridge_hub_polkadot::PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane;
}
@@ -0,0 +1,65 @@
// Copyright 2022 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/>.
//! PolkadotBulletin-to-BridgeHubPolkadot messages sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
use relay_polkadot_bulletin_client::PolkadotBulletin;
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
/// PolkadotBulletin-to-BridgeHubPolkadot messages bridge.
pub struct PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {}
impl CliBridgeBase for PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {
type Source = PolkadotBulletin;
type Target = BridgeHubPolkadot;
}
impl MessagesCliBridge for PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {
type MessagesLane = PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane;
}
substrate_relay_helper::generate_receive_message_proof_call_builder!(
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane,
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLaneReceiveMessagesProofCallBuilder,
relay_bridge_hub_polkadot_client::runtime::Call::BridgePolkadotBulletinMessages,
relay_bridge_hub_polkadot_client::runtime::BridgePolkadotBulletinMessagesCall::receive_messages_proof
);
substrate_relay_helper::generate_receive_message_delivery_proof_call_builder!(
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane,
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLaneReceiveMessagesDeliveryProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotBridgeHubMessages,
relay_polkadot_bulletin_client::BridgePolkadotBridgeHubMessagesCall::receive_messages_delivery_proof
);
/// PolkadotBulletin-to-BridgeHubPolkadot messages lane.
#[derive(Clone, Debug)]
pub struct PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane;
impl SubstrateMessageLane for PolkadotBulletinMessagesToBridgeHubPolkadotMessageLane {
type SourceChain = PolkadotBulletin;
type TargetChain = BridgeHubPolkadot;
type ReceiveMessagesProofCallBuilder =
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLaneReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder =
PolkadotBulletinMessagesToBridgeHubPolkadotMessageLaneReceiveMessagesDeliveryProofCallBuilder;
type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = UtilityPalletBatchCallBuilder<BridgeHubPolkadot>;
}
@@ -0,0 +1,96 @@
// Copyright 2022 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot-to-PolkadotBulletin headers sync entrypoint.
use crate::cli::bridge::{
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
};
use async_trait::async_trait;
use relay_substrate_client::{AccountKeyPairOf, Client};
use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline,
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
TransactionParams,
};
/// Description of Polkadot -> `PolkadotBulletin` finalized headers bridge.
#[derive(Clone, Debug)]
pub struct PolkadotFinalityToPolkadotBulletin;
substrate_relay_helper::generate_submit_finality_proof_call_builder!(
PolkadotFinalityToPolkadotBulletin,
SubmitFinalityProofCallBuilder,
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotGrandpa,
relay_polkadot_bulletin_client::BridgePolkadotGrandpaCall::submit_finality_proof
);
substrate_relay_helper::generate_report_equivocation_call_builder!(
PolkadotFinalityToPolkadotBulletin,
ReportEquivocationCallBuilder,
relay_polkadot_client::RuntimeCall::Grandpa,
relay_polkadot_client::GrandpaCall::report_equivocation
);
#[async_trait]
impl SubstrateFinalityPipeline for PolkadotFinalityToPolkadotBulletin {
type SourceChain = relay_polkadot_client::Polkadot;
type TargetChain = relay_polkadot_bulletin_client::PolkadotBulletin;
type FinalityEngine = GrandpaFinalityEngine<Self::SourceChain>;
}
#[async_trait]
impl SubstrateFinalitySyncPipeline for PolkadotFinalityToPolkadotBulletin {
type SubmitFinalityProofCallBuilder = SubmitFinalityProofCallBuilder;
async fn start_relay_guards(
target_client: &Client<Self::TargetChain>,
_transaction_params: &TransactionParams<AccountKeyPairOf<Self::TargetChain>>,
enable_version_guard: bool,
) -> relay_substrate_client::Result<()> {
if enable_version_guard {
relay_substrate_client::guard::abort_on_spec_version_change(
target_client.clone(),
target_client.simple_runtime_version().await?.spec_version,
);
}
Ok(())
}
}
#[async_trait]
impl SubstrateEquivocationDetectionPipeline for PolkadotFinalityToPolkadotBulletin {
type ReportEquivocationCallBuilder = ReportEquivocationCallBuilder;
}
/// `Polkadot` to BridgeHub `PolkadotBulletin` bridge definition.
pub struct PolkadotToPolkadotBulletinCliBridge {}
impl CliBridgeBase for PolkadotToPolkadotBulletinCliBridge {
type Source = relay_polkadot_client::Polkadot;
type Target = relay_polkadot_bulletin_client::PolkadotBulletin;
}
impl RelayToRelayHeadersCliBridge for PolkadotToPolkadotBulletinCliBridge {
type Finality = PolkadotFinalityToPolkadotBulletin;
}
impl RelayToRelayEquivocationDetectionCliBridge for PolkadotToPolkadotBulletinCliBridge {
type Equivocation = PolkadotFinalityToPolkadotBulletin;
}
@@ -0,0 +1,92 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot-to-PolkadotBulletin parachains sync entrypoint.
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
use bp_runtime::Chain;
use relay_substrate_client::{CallOf, HeaderIdOf};
use substrate_relay_helper::{
messages_lane::MessagesRelayLimits,
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
};
/// Polkadot-to-PolkadotBulletin parachain sync description.
#[derive(Clone, Debug)]
pub struct PolkadotToPolkadotBulletin;
impl SubstrateParachainsPipeline for PolkadotToPolkadotBulletin {
type SourceParachain = relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
type SourceRelayChain = relay_polkadot_client::Polkadot;
type TargetChain = relay_polkadot_bulletin_client::PolkadotBulletin;
type SubmitParachainHeadsCallBuilder = PolkadotToPolkadotBulletinCallBuilder;
}
pub struct PolkadotToPolkadotBulletinCallBuilder;
impl SubmitParachainHeadsCallBuilder<PolkadotToPolkadotBulletin>
for PolkadotToPolkadotBulletinCallBuilder
{
fn build_submit_parachain_heads_call(
at_relay_block: HeaderIdOf<relay_polkadot_client::Polkadot>,
parachains: Vec<(ParaId, ParaHash)>,
parachain_heads_proof: ParaHeadsProof,
) -> CallOf<relay_polkadot_bulletin_client::PolkadotBulletin> {
relay_polkadot_bulletin_client::RuntimeCall::BridgePolkadotParachains(
relay_polkadot_bulletin_client::BridgePolkadotParachainsCall::submit_parachain_heads {
at_relay_block: (at_relay_block.0, at_relay_block.1),
parachains,
parachain_heads_proof,
},
)
}
}
/// Polkadot-to-PolkadotBulletin parachain sync description for the CLI.
pub struct PolkadotToPolkadotBulletinCliBridge {}
impl ParachainToRelayHeadersCliBridge for PolkadotToPolkadotBulletinCliBridge {
type SourceRelay = relay_polkadot_client::Polkadot;
type ParachainFinality = PolkadotToPolkadotBulletin;
type RelayFinality =
crate::bridges::polkadot_bulletin::polkadot_headers_to_polkadot_bulletin::PolkadotFinalityToPolkadotBulletin;
}
impl CliBridgeBase for PolkadotToPolkadotBulletinCliBridge {
type Source = relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
type Target = relay_polkadot_bulletin_client::PolkadotBulletin;
}
impl MessagesCliBridge for PolkadotToPolkadotBulletinCliBridge {
type MessagesLane =
crate::bridges::polkadot_bulletin::bridge_hub_polkadot_messages_to_polkadot_bulletin::BridgeHubPolkadotMessagesToPolkadotBulletinMessageLane;
fn maybe_messages_limits() -> Option<MessagesRelayLimits> {
// Polkadot Bulletin chain is missing the `TransactionPayment` runtime API (as well as the
// transaction payment pallet itself), so we can't estimate limits using runtime calls.
// Let's do it here.
//
// Folloiung constants are just safe **underestimations**. Normally, we are able to deliver
// and dispatch thousands of messages in the same transaction.
Some(MessagesRelayLimits {
max_messages_in_single_batch: 128,
max_messages_weight_in_single_batch:
bp_polkadot_bulletin::PolkadotBulletin::max_extrinsic_weight() / 20,
})
}
}
@@ -19,6 +19,7 @@
mod kusama;
mod millau;
mod polkadot;
mod polkadot_bulletin;
mod rialto;
mod rialto_parachain;
mod rococo;
@@ -0,0 +1,26 @@
// Copyright 2022 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot + Polkadot parachains specification for CLI.
use crate::cli::CliChain;
use relay_polkadot_bulletin_client::PolkadotBulletin;
use relay_substrate_client::SimpleRuntimeVersion;
impl CliChain for PolkadotBulletin {
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
Some(SimpleRuntimeVersion { spec_version: 100, transaction_version: 1 });
}
+13 -2
View File
@@ -19,8 +19,10 @@ use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumbe
use relay_substrate_client::{Chain, ChainWithTransactions, Parachain, RelayChain};
use strum::{EnumString, EnumVariantNames};
use substrate_relay_helper::{
equivocation::SubstrateEquivocationDetectionPipeline, finality::SubstrateFinalitySyncPipeline,
messages_lane::SubstrateMessageLane, parachains::SubstrateParachainsPipeline,
equivocation::SubstrateEquivocationDetectionPipeline,
finality::SubstrateFinalitySyncPipeline,
messages_lane::{MessagesRelayLimits, SubstrateMessageLane},
parachains::SubstrateParachainsPipeline,
};
#[derive(Debug, PartialEq, Eq, EnumString, EnumVariantNames)]
@@ -35,6 +37,8 @@ pub enum FullBridge {
BridgeHubWococoToBridgeHubRococo,
BridgeHubKusamaToBridgeHubPolkadot,
BridgeHubPolkadotToBridgeHubKusama,
PolkadotBulletinToBridgeHubPolkadot,
BridgeHubPolkadotToPolkadotBulletin,
}
/// Minimal bridge representation that can be used from the CLI.
@@ -109,4 +113,11 @@ where
pub trait MessagesCliBridge: CliBridgeBase {
/// The Source -> Destination messages synchronization pipeline.
type MessagesLane: SubstrateMessageLane<SourceChain = Self::Source, TargetChain = Self::Target>;
/// Optional messages delivery transaction limits that the messages relay is going
/// to use. If it returns `None`, limits are estimated using `TransactionPayment` API
/// at the target chain.
fn maybe_messages_limits() -> Option<MessagesRelayLimits> {
None
}
}
@@ -23,6 +23,10 @@ use crate::{
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
},
polkadot_bulletin::{
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,
@@ -72,6 +76,8 @@ pub enum InitBridgeName {
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
PolkadotToBridgeHubKusama,
PolkadotToPolkadotBulletin,
PolkadotBulletinToBridgeHubPolkadot,
}
#[async_trait]
@@ -232,6 +238,37 @@ impl BridgeInitializer for PolkadotToBridgeHubKusamaCliBridge {
}
}
impl BridgeInitializer for PolkadotToPolkadotBulletinCliBridge {
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_polkadot_bulletin_client::RuntimeCall;
type BridgePolkadotGrandpaCall = relay_polkadot_bulletin_client::BridgePolkadotGrandpaCall;
type SudoCall = relay_polkadot_bulletin_client::SudoCall;
let initialize_call =
RuntimeCall::BridgePolkadotGrandpa(BridgePolkadotGrandpaCall::initialize { init_data });
RuntimeCall::Sudo(SudoCall::sudo { call: Box::new(initialize_call) })
}
}
impl BridgeInitializer for PolkadotBulletinToBridgeHubPolkadotCliBridge {
type Engine = GrandpaFinalityEngine<Self::Source>;
fn encode_init_bridge(
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
) -> <Self::Target as Chain>::Call {
relay_bridge_hub_polkadot_client::runtime::Call::BridgePolkadotBulletinGrandpa(
relay_bridge_hub_polkadot_client::runtime::BridgePolkadotBulletinGrandpaCall::initialize {
init_data,
},
)
}
}
impl InitBridge {
/// Run the command.
pub async fn run(self) -> anyhow::Result<()> {
@@ -249,6 +286,10 @@ impl InitBridge {
KusamaToBridgeHubPolkadotCliBridge::init_bridge(self),
InitBridgeName::PolkadotToBridgeHubKusama =>
PolkadotToBridgeHubKusamaCliBridge::init_bridge(self),
InitBridgeName::PolkadotToPolkadotBulletin =>
PolkadotToPolkadotBulletinCliBridge::init_bridge(self),
InitBridgeName::PolkadotBulletinToBridgeHubPolkadot =>
PolkadotBulletinToBridgeHubPolkadotCliBridge::init_bridge(self),
}
.await
}
@@ -23,6 +23,10 @@ use crate::bridges::{
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
},
polkadot_bulletin::{
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,
@@ -71,6 +75,8 @@ pub enum RelayHeadersBridge {
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
PolkadotToBridgeHubKusama,
PolkadotToPolkadotBulletin,
PolkadotBulletinToBridgeHubPolkadot,
}
#[async_trait]
@@ -116,6 +122,8 @@ impl HeadersRelayer for RococoToBridgeHubWococoCliBridge {}
impl HeadersRelayer for WococoToBridgeHubRococoCliBridge {}
impl HeadersRelayer for KusamaToBridgeHubPolkadotCliBridge {}
impl HeadersRelayer for PolkadotToBridgeHubKusamaCliBridge {}
impl HeadersRelayer for PolkadotToPolkadotBulletinCliBridge {}
impl HeadersRelayer for PolkadotBulletinToBridgeHubPolkadotCliBridge {}
impl RelayHeaders {
/// Run the command.
@@ -134,6 +142,10 @@ impl RelayHeaders {
KusamaToBridgeHubPolkadotCliBridge::relay_headers(self),
RelayHeadersBridge::PolkadotToBridgeHubKusama =>
PolkadotToBridgeHubKusamaCliBridge::relay_headers(self),
RelayHeadersBridge::PolkadotToPolkadotBulletin =>
PolkadotToPolkadotBulletinCliBridge::relay_headers(self),
RelayHeadersBridge::PolkadotBulletinToBridgeHubPolkadot =>
PolkadotBulletinToBridgeHubPolkadotCliBridge::relay_headers(self),
}
.await
}
@@ -44,6 +44,10 @@ use crate::{
kusama_parachains_to_bridge_hub_polkadot::BridgeHubKusamaToBridgeHubPolkadotCliBridge,
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
},
polkadot_bulletin::{
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,
@@ -77,7 +81,9 @@ use relay_substrate_client::{
use relay_utils::metrics::MetricsParams;
use sp_core::Pair;
use substrate_relay_helper::{
messages_lane::MessagesRelayParams, on_demand::OnDemandRelay, TaggedAccount, TransactionParams,
messages_lane::{MessagesRelayLimits, MessagesRelayParams},
on_demand::OnDemandRelay,
TaggedAccount, TransactionParams,
};
/// Parameters that have the same names across all bridges.
@@ -176,6 +182,7 @@ where
source_to_target_headers_relay: Arc<dyn OnDemandRelay<Source, Target>>,
target_to_source_headers_relay: Arc<dyn OnDemandRelay<Target, Source>>,
lane_id: LaneId,
maybe_limits: Option<MessagesRelayLimits>,
) -> MessagesRelayParams<Bridge::MessagesLane> {
MessagesRelayParams {
source_client: self.source.client.clone(),
@@ -185,6 +192,7 @@ where
source_to_target_headers_relay: Some(source_to_target_headers_relay),
target_to_source_headers_relay: Some(target_to_source_headers_relay),
lane_id,
limits: maybe_limits,
metrics_params: self.metrics_params.clone().disable(),
}
}
@@ -202,6 +210,7 @@ declare_chain_cli_schema!(Kusama, kusama);
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);
@@ -227,11 +236,21 @@ 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!(BridgeHubKusama, Kusama, BridgeHubPolkadot, Polkadot);
declare_relay_to_parachain_bridge_schema!(PolkadotBulletin, BridgeHubPolkadot, Polkadot);
/// Base portion of the bidirectional complex relay.
///
@@ -370,6 +389,7 @@ where
left_to_right_on_demand_headers.clone(),
right_to_left_on_demand_headers.clone(),
lane,
Self::L2R::maybe_messages_limits(),
))
.map_err(|e| anyhow::format_err!("{}", e))
.boxed();
@@ -381,6 +401,7 @@ where
right_to_left_on_demand_headers.clone(),
left_to_right_on_demand_headers.clone(),
lane,
Self::R2L::maybe_messages_limits(),
))
.map_err(|e| anyhow::format_err!("{}", e))
.boxed();
@@ -500,6 +521,32 @@ impl Full2WayBridge for BridgeHubKusamaBridgeHubPolkadotFull2WayBridge {
}
}
/// `PolkadotBulletin` <> `BridgeHubPolkadot` complex relay.
pub struct PolkadotBulletinBridgeHubPolkadotFull2WayBridge {
base: <Self as Full2WayBridge>::Base,
}
#[async_trait]
impl Full2WayBridge for PolkadotBulletinBridgeHubPolkadotFull2WayBridge {
type Base = RelayToParachainBridge<Self::L2R, Self::R2L>;
type Left = relay_polkadot_bulletin_client::PolkadotBulletin;
type Right = relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
type L2R = PolkadotBulletinToBridgeHubPolkadotCliBridge;
type R2L = PolkadotToPolkadotBulletinCliBridge;
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
}
}
/// Complex headers+messages relay.
#[derive(Debug, PartialEq, StructOpt)]
pub enum RelayHeadersAndMessages {
@@ -511,6 +558,8 @@ pub enum RelayHeadersAndMessages {
BridgeHubRococoBridgeHubWococo(BridgeHubRococoBridgeHubWococoHeadersAndMessages),
/// BridgeHubKusama <> BridgeHubPolkadot relay.
BridgeHubKusamaBridgeHubPolkadot(BridgeHubKusamaBridgeHubPolkadotHeadersAndMessages),
/// `PolkadotBulletin` <> `BridgeHubPolkadot` relay.
PolkadotBulletinBridgeHubPolkadot(PolkadotBulletinBridgeHubPolkadotHeadersAndMessages),
}
impl RelayHeadersAndMessages {
@@ -531,6 +580,10 @@ impl RelayHeadersAndMessages {
BridgeHubKusamaBridgeHubPolkadotFull2WayBridge::new(params.into_bridge().await?)?
.run()
.await,
RelayHeadersAndMessages::PolkadotBulletinBridgeHubPolkadot(params) =>
PolkadotBulletinBridgeHubPolkadotFull2WayBridge::new(params.into_bridge().await?)?
.run()
.await,
}
}
}
@@ -24,6 +24,10 @@ use crate::bridges::{
bridge_hub_kusama_messages_to_bridge_hub_polkadot::BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge,
bridge_hub_polkadot_messages_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge,
},
polkadot_bulletin::{
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,
@@ -93,6 +97,7 @@ where
source_to_target_headers_relay: None,
target_to_source_headers_relay: None,
lane_id: data.lane.into(),
limits: Self::maybe_messages_limits(),
metrics_params: data.prometheus_params.into_metrics_params()?,
})
.await
@@ -108,6 +113,8 @@ impl MessagesRelayer for BridgeHubRococoToBridgeHubWococoMessagesCliBridge {}
impl MessagesRelayer for BridgeHubWococoToBridgeHubRococoMessagesCliBridge {}
impl MessagesRelayer for BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge {}
impl MessagesRelayer for BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge {}
impl MessagesRelayer for PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {}
impl MessagesRelayer for BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {}
impl RelayMessages {
/// Run the command.
@@ -127,6 +134,10 @@ impl RelayMessages {
BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
FullBridge::BridgeHubPolkadotToBridgeHubKusama =>
BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge::relay_messages(self),
FullBridge::PolkadotBulletinToBridgeHubPolkadot =>
PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
FullBridge::BridgeHubPolkadotToPolkadotBulletin =>
BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge::relay_messages(self),
}
.await
}
@@ -19,6 +19,7 @@ use crate::bridges::{
kusama_parachains_to_bridge_hub_polkadot::BridgeHubKusamaToBridgeHubPolkadotCliBridge,
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
},
polkadot_bulletin::polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
rialto_parachain_millau::rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
rococo_wococo::{
rococo_parachains_to_bridge_hub_wococo::BridgeHubRococoToBridgeHubWococoCliBridge,
@@ -71,6 +72,7 @@ pub enum RelayParachainsBridge {
WococoToBridgeHubRococo,
KusamaToBridgeHubPolkadot,
PolkadotToBridgeHubKusama,
PolkadotToPolkadotBulletin,
}
#[async_trait]
@@ -120,6 +122,7 @@ impl ParachainsRelayer for BridgeHubRococoToBridgeHubWococoCliBridge {}
impl ParachainsRelayer for BridgeHubWococoToBridgeHubRococoCliBridge {}
impl ParachainsRelayer for BridgeHubKusamaToBridgeHubPolkadotCliBridge {}
impl ParachainsRelayer for BridgeHubPolkadotToBridgeHubKusamaCliBridge {}
impl ParachainsRelayer for PolkadotToPolkadotBulletinCliBridge {}
impl RelayParachains {
/// Run the command.
@@ -137,6 +140,8 @@ impl RelayParachains {
BridgeHubKusamaToBridgeHubPolkadotCliBridge::relay_parachains(self),
RelayParachainsBridge::PolkadotToBridgeHubKusama =>
BridgeHubPolkadotToBridgeHubKusamaCliBridge::relay_parachains(self),
RelayParachainsBridge::PolkadotToPolkadotBulletin =>
PolkadotToPolkadotBulletinCliBridge::relay_parachains(self),
}
.await
}
@@ -109,18 +109,8 @@ impl SendMessage {
MillauToRialtoParachainCliBridge::send_message(self),
FullBridge::RialtoParachainToMillau =>
RialtoParachainToMillauCliBridge::send_message(self),
FullBridge::BridgeHubRococoToBridgeHubWococo => unimplemented!(
"Sending message from BridgeHubRococo to BridgeHubWococo is not supported"
),
FullBridge::BridgeHubWococoToBridgeHubRococo => unimplemented!(
"Sending message from BridgeHubWococo to BridgeHubRococo is not supported"
),
FullBridge::BridgeHubKusamaToBridgeHubPolkadot => unimplemented!(
"Sending message from BridgeHubKusama to BridgeHubPolkadot is not supported"
),
FullBridge::BridgeHubPolkadotToBridgeHubKusama => unimplemented!(
"Sending message from BridgeHubPolkadot to BridgeHubKusama is not supported"
),
// 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
}
@@ -17,7 +17,8 @@ bp-bridge-hub-polkadot = { path = "../../primitives/chain-bridge-hub-polkadot" }
bp-header-chain = { path = "../../primitives/header-chain" }
bp-messages = { path = "../../primitives/messages" }
bp-parachains = { path = "../../primitives/parachains" }
bp-polkadot-core= { path = "../../primitives/polkadot-core" }
bp-polkadot-bulletin = { path = "../../primitives/chain-polkadot-bulletin" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-kusama = { path = "../../primitives/chain-kusama" }
bp-runtime = { path = "../../primitives/runtime" }
@@ -29,11 +29,18 @@ pub use relay_substrate_client::calls::{SystemCall, UtilityCall};
/// Unchecked BridgeHubPolkadot extrinsic.
pub type UncheckedExtrinsic = bp_bridge_hub_polkadot::UncheckedExtrinsic<Call, SignedExtension>;
// The indirect pallet call used to sync `Kusama` GRANDPA finality to `BHPolkadot`.
/// The indirect pallet call used to sync `Kusama` GRANDPA finality to `BHPolkadot`.
pub type BridgeKusamaGrandpaCall = BridgeGrandpaCallOf<bp_kusama::Kusama>;
// The indirect pallet call used to sync `BridgeHubKusama` messages to `BridgeHubPolkadot`.
/// The indirect pallet call used to sync `BridgeHubKusama` messages to `BridgeHubPolkadot`.
pub type BridgeKusamaMessagesCall = BridgeMessagesCallOf<bp_bridge_hub_kusama::BridgeHubKusama>;
/// The indirect pallet call used to sync `PolkadotBulletin` GRANDPA finality to `BHPolkadot`.
pub type BridgePolkadotBulletinGrandpaCall =
BridgeGrandpaCallOf<bp_polkadot_bulletin::PolkadotBulletin>;
/// The indirect pallet call used to sync `PolkadotBulletin` messages to `BridgeHubPolkadot`.
pub type BridgePolkadotBulletinMessagesCall =
BridgeMessagesCallOf<bp_polkadot_bulletin::PolkadotBulletin>;
/// `BridgeHubPolkadot` Runtime `Call` enum.
///
/// The enum represents a subset of possible `Call`s we can send to `BridgeHubPolkadot` chain.
@@ -52,15 +59,22 @@ pub enum Call {
#[codec(index = 40)]
Utility(UtilityCall<Call>),
/// Kusama bridge pallet.
/// Kusama grandpa bridge pallet.
#[codec(index = 51)]
BridgeKusamaGrandpa(BridgeKusamaGrandpaCall),
/// Kusama parachain bridge pallet.
/// Kusama parachains bridge pallet.
#[codec(index = 52)]
BridgeKusamaParachain(BridgeParachainCall),
/// Kusama messages bridge pallet.
#[codec(index = 53)]
BridgeKusamaMessages(BridgeKusamaMessagesCall),
/// Polkadot Bulletin grandpa bridge pallet.
#[codec(index = 55)]
BridgePolkadotBulletinGrandpa(BridgePolkadotBulletinGrandpaCall),
/// Polkadot Bulletin messages bridge pallet.
#[codec(index = 56)]
BridgePolkadotBulletinMessages(BridgePolkadotBulletinMessagesCall),
}
impl From<UtilityCall<Call>> for Call {
@@ -0,0 +1,30 @@
[package]
name = "relay-polkadot-bulletin-client"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] }
scale-info = { version = "2.9.0", default-features = false, features = ["derive"] }
subxt = { version = "0.31.0", default-features = false, features = ["native"] }
# Bridge dependencies
bp-header-chain = { path = "../../primitives/header-chain" }
bp-messages = { path = "../../primitives/messages" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-polkadot-bulletin = { path = "../../primitives/chain-polkadot-bulletin" }
bp-runtime = { path = "../../primitives/runtime" }
bridge-runtime-common = { path = "../../bin/runtime-common" }
relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" }
# Substrate Dependencies
sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
sp-session = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
sp-weights = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,158 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Types used to connect to the Polkadot Bulletin chain.
mod codegen_runtime;
use bp_messages::MessageNonce;
use bp_polkadot_bulletin::POLKADOT_BULLETIN_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
use bp_runtime::ChainId;
use codec::Encode;
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, ChainWithTransactions,
Error as SubstrateError, SignParam, UnderlyingChainProvider, UnsignedTransaction,
};
use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
use sp_session::MembershipProof;
use std::time::Duration;
pub use codegen_runtime::api::runtime_types;
/// Call of the Polkadot Bulletin Chain runtime.
pub type RuntimeCall = runtime_types::polkadot_bulletin_chain_runtime::RuntimeCall;
/// Call of the `Sudo` pallet.
pub type SudoCall = runtime_types::pallet_sudo::pallet::Call;
/// Call of the GRANDPA pallet.
pub type GrandpaCall = runtime_types::pallet_grandpa::pallet::Call;
/// Call of the with-PolkadotBridgeHub bridge GRANDPA pallet.
pub type BridgePolkadotGrandpaCall = runtime_types::pallet_bridge_grandpa::pallet::Call;
/// Call of the with-PolkadotBridgeHub bridge parachains pallet.
pub type BridgePolkadotParachainsCall = runtime_types::pallet_bridge_parachains::pallet::Call;
/// Call of the with-PolkadotBridgeHub bridge messages pallet.
pub type BridgePolkadotBridgeHubMessagesCall = runtime_types::pallet_bridge_messages::pallet::Call;
/// Polkadot header id.
pub type HeaderId =
relay_utils::HeaderId<bp_polkadot_bulletin::Hash, bp_polkadot_bulletin::BlockNumber>;
/// Polkadot header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_polkadot_bulletin::Header>;
/// The address format for describing accounts.
pub type Address = MultiAddress<bp_polkadot_bulletin::AccountId, ()>;
/// Polkadot chain definition
#[derive(Debug, Clone, Copy)]
pub struct PolkadotBulletin;
impl UnderlyingChainProvider for PolkadotBulletin {
type Chain = bp_polkadot_bulletin::PolkadotBulletin;
}
impl Chain for PolkadotBulletin {
const ID: ChainId = *b"pbch";
const NAME: &'static str = "PolkadotBulletin";
const BEST_FINALIZED_HEADER_ID_METHOD: &'static str =
bp_polkadot_bulletin::BEST_FINALIZED_POLKADOT_BULLETIN_HEADER_METHOD;
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_polkadot_bulletin::SignedBlock;
type Call = RuntimeCall;
}
impl ChainWithGrandpa for PolkadotBulletin {
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
POLKADOT_BULLETIN_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
type KeyOwnerProof = MembershipProof;
}
impl ChainWithMessages for PolkadotBulletin {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
bp_polkadot_bulletin::WITH_POLKADOT_BULLETIN_MESSAGES_PALLET_NAME;
// this is not critical (some metrics will be missing from the storage), but probably it needs
// to be changed when we'll polish the bridge configuration
const WITH_CHAIN_RELAYERS_PALLET_NAME: Option<&'static str> = None;
const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
bp_polkadot_bulletin::TO_POLKADOT_BULLETIN_MESSAGE_DETAILS_METHOD;
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
bp_polkadot_bulletin::FROM_POLKADOT_BULLETIN_MESSAGE_DETAILS_METHOD;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
bp_polkadot_bulletin::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
bp_polkadot_bulletin::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
impl ChainWithBalances for PolkadotBulletin {
fn account_info_storage_key(_account_id: &Self::AccountId) -> StorageKey {
// no balances at this chain
StorageKey(vec![])
}
}
impl ChainWithTransactions for PolkadotBulletin {
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction =
bp_polkadot_bulletin::UncheckedExtrinsic<Self::Call, bp_polkadot_bulletin::SignedExtension>;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
let raw_payload = SignedPayload::new(
unsigned.call,
bp_polkadot_bulletin::SignedExtension::from_params(
param.spec_version,
param.transaction_version,
unsigned.era,
param.genesis_hash,
unsigned.nonce,
),
)?;
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
let signer: sp_runtime::MultiSigner = param.signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
Ok(Self::SignedTransaction::new_signed(
call,
signer.into_account().into(),
signature.into(),
extra,
))
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
tx.signature.is_some()
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
.map(|(address, _, _)| *address == Address::Id(signer.public().into()))
.unwrap_or(false)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
let extra = &tx.signature.as_ref()?.2;
Some(UnsignedTransaction::new(tx.function, extra.nonce()))
}
}
+4 -4
View File
@@ -17,7 +17,7 @@
//! Pallet provides a set of guard functions that are running in background threads
//! and are aborting process if some condition fails.
use crate::{error::Error, Chain, ChainWithBalances, Client};
use crate::{error::Error, Chain, Client};
use async_trait::async_trait;
use sp_version::RuntimeVersion;
@@ -28,7 +28,7 @@ use std::{
/// Guards environment.
#[async_trait]
pub trait Environment<C: ChainWithBalances>: Send + Sync + 'static {
pub trait Environment<C>: Send + Sync + 'static {
/// Error type.
type Error: Display + Send + Sync + 'static;
@@ -52,7 +52,7 @@ pub trait Environment<C: ChainWithBalances>: Send + Sync + 'static {
}
/// Abort when runtime spec version is different from specified.
pub fn abort_on_spec_version_change<C: ChainWithBalances>(
pub fn abort_on_spec_version_change<C: Chain>(
mut env: impl Environment<C>,
expected_spec_version: u32,
) {
@@ -98,7 +98,7 @@ fn conditions_check_delay<C: Chain>() -> Duration {
}
#[async_trait]
impl<C: ChainWithBalances> Environment<C> for Client<C> {
impl<C: Chain> Environment<C> for Client<C> {
type Error = Error;
async fn runtime_version(&mut self) -> Result<RuntimeVersion, Self::Error> {
@@ -105,10 +105,21 @@ pub struct MessagesRelayParams<P: SubstrateMessageLane> {
Option<Arc<dyn OnDemandRelay<P::TargetChain, P::SourceChain>>>,
/// Identifier of lane that needs to be served.
pub lane_id: LaneId,
/// Messages relay limits. If not provided, the relay tries to determine it automatically,
/// using `TransactionPayment` pallet runtime API.
pub limits: Option<MessagesRelayLimits>,
/// Metrics parameters.
pub metrics_params: MetricsParams,
}
/// Delivery transaction limits.
pub struct MessagesRelayLimits {
/// Maximal number of messages in the delivery transaction.
pub max_messages_in_single_batch: MessageNonce,
/// Maximal cumulative weight of messages in the delivery transaction.
pub max_messages_weight_in_single_batch: Weight,
}
/// Batch transaction that brings headers + and messages delivery/receiving confirmations to the
/// source node.
#[derive(Clone)]
@@ -178,15 +189,18 @@ where
let max_messages_size_in_single_batch = P::TargetChain::max_extrinsic_size() / 3;
// we don't know exact weights of the Polkadot runtime. So to guess weights we'll be using
// weights from Rialto and then simply dividing it by x2.
let limits = match params.limits {
Some(limits) => limits,
None =>
select_delivery_transaction_limits_rpc::<P>(
&params,
P::TargetChain::max_extrinsic_weight(),
P::SourceChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
)
.await?,
};
let (max_messages_in_single_batch, max_messages_weight_in_single_batch) =
select_delivery_transaction_limits_rpc::<P>(
&params,
P::TargetChain::max_extrinsic_weight(),
P::SourceChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
)
.await?;
let (max_messages_in_single_batch, max_messages_weight_in_single_batch) =
(max_messages_in_single_batch / 2, max_messages_weight_in_single_batch / 2);
(limits.max_messages_in_single_batch / 2, limits.max_messages_weight_in_single_batch / 2);
let source_client = params.source_client;
let target_client = params.target_client;
@@ -457,7 +471,7 @@ async fn select_delivery_transaction_limits_rpc<P: SubstrateMessageLane>(
params: &MessagesRelayParams<P>,
max_extrinsic_weight: Weight,
max_unconfirmed_messages_at_inbound_lane: MessageNonce,
) -> anyhow::Result<(MessageNonce, Weight)>
) -> anyhow::Result<MessagesRelayLimits>
where
AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
{
@@ -515,7 +529,10 @@ where
"Relay shall be able to deliver messages with dispatch weight = max_extrinsic_weight / 2",
);
Ok((max_number_of_messages, weight_for_messages_dispatch))
Ok(MessagesRelayLimits {
max_messages_in_single_batch: max_number_of_messages,
max_messages_weight_in_single_batch: weight_for_messages_dispatch,
})
}
/// Returns dummy message delivery transaction with zero messages and `1kb` proof.