From 8f2c12a88b737ac19c546062ea5bc2a5a08622d8 Mon Sep 17 00:00:00 2001 From: Guantong Date: Mon, 20 Feb 2023 10:07:35 +0800 Subject: [PATCH] Pangolin2 <> Pangoro2 bridge (#285) * Copy darwinia bm => pangoro bm Copy crab bm => pangolin bm * Add pangolin&pangoro bridge-messages * Add bridge related pallets for pangolin&pangoro * Add bridge palles to runtime for pangolin & pangoro * Fix compile * Missing changes * Correct bridge-dispatch * Format * Update genesis --- node/src/chain_spec/pangolin.rs | 12 ++ node/src/chain_spec/pangoro.rs | 12 ++ runtime/common/src/lib.rs | 1 + runtime/pangolin/src/bridges_message/mod.rs | 20 ++ .../pangolin/src/bridges_message/pangoro.rs | 182 ++++++++++++++++++ runtime/pangolin/src/lib.rs | 21 ++ .../pangolin/src/pallets/bridge_dispatch.rs | 109 +++++++++++ .../pangolin/src/pallets/bridge_grandpa.rs | 33 ++++ .../pangolin/src/pallets/bridge_messages.rs | 68 +++++++ .../pangolin/src/pallets/bridge_parachains.rs | 36 ++++ runtime/pangolin/src/pallets/fee_market.rs | 74 +++++++ runtime/pangolin/src/pallets/mod.rs | 16 ++ runtime/pangoro/src/bridges_message/mod.rs | 20 ++ .../pangoro/src/bridges_message/pangolin.rs | 182 ++++++++++++++++++ runtime/pangoro/src/lib.rs | 21 ++ .../pangoro/src/pallets/bridge_dispatch.rs | 109 +++++++++++ runtime/pangoro/src/pallets/bridge_grandpa.rs | 33 ++++ .../pangoro/src/pallets/bridge_messages.rs | 68 +++++++ .../pangoro/src/pallets/bridge_parachains.rs | 36 ++++ runtime/pangoro/src/pallets/fee_market.rs | 73 +++++++ runtime/pangoro/src/pallets/mod.rs | 16 ++ 21 files changed, 1142 insertions(+) create mode 100644 runtime/pangolin/src/bridges_message/mod.rs create mode 100644 runtime/pangolin/src/bridges_message/pangoro.rs create mode 100644 runtime/pangolin/src/pallets/bridge_dispatch.rs create mode 100644 runtime/pangolin/src/pallets/bridge_grandpa.rs create mode 100644 runtime/pangolin/src/pallets/bridge_messages.rs create mode 100644 runtime/pangolin/src/pallets/bridge_parachains.rs create mode 100644 runtime/pangolin/src/pallets/fee_market.rs create mode 100644 runtime/pangoro/src/bridges_message/mod.rs create mode 100644 runtime/pangoro/src/bridges_message/pangolin.rs create mode 100644 runtime/pangoro/src/pallets/bridge_dispatch.rs create mode 100644 runtime/pangoro/src/pallets/bridge_grandpa.rs create mode 100644 runtime/pangoro/src/pallets/bridge_messages.rs create mode 100644 runtime/pangoro/src/pallets/bridge_parachains.rs create mode 100644 runtime/pangoro/src/pallets/fee_market.rs diff --git a/node/src/chain_spec/pangolin.rs b/node/src/chain_spec/pangolin.rs index 404d6bf31..a59c34232 100644 --- a/node/src/chain_spec/pangolin.rs +++ b/node/src/chain_spec/pangolin.rs @@ -241,6 +241,12 @@ pub fn genesis_config() -> ChainSpec { ) }, }, + + // S2S stuff. + bridge_moonbase_grandpa: Default::default(), + bridge_moonbase_parachain: Default::default(), + bridge_pangoro_messages: Default::default(), + pangoro_fee_market: Default::default(), } }, Vec::new(), @@ -358,5 +364,11 @@ fn testnet_genesis( ) }, }, + + // S2S stuff. + bridge_moonbase_grandpa: Default::default(), + bridge_moonbase_parachain: Default::default(), + bridge_pangoro_messages: Default::default(), + pangoro_fee_market: Default::default(), } } diff --git a/node/src/chain_spec/pangoro.rs b/node/src/chain_spec/pangoro.rs index 02e034cb6..482b78956 100644 --- a/node/src/chain_spec/pangoro.rs +++ b/node/src/chain_spec/pangoro.rs @@ -241,6 +241,12 @@ pub fn genesis_config() -> ChainSpec { ) }, }, + + // S2S stuff. + bridge_rococo_grandpa: Default::default(), + bridge_rococo_parachain: Default::default(), + bridge_pangolin_messages: Default::default(), + pangolin_fee_market: Default::default(), } }, Vec::new(), @@ -358,5 +364,11 @@ fn testnet_genesis( ) }, }, + + // S2S stuff. + bridge_rococo_grandpa: Default::default(), + bridge_rococo_parachain: Default::default(), + bridge_pangolin_messages: Default::default(), + pangolin_fee_market: Default::default(), } } diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index ec3a5cf67..7ba4ef52b 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -26,6 +26,7 @@ pub mod xcm_configs; pub use bp_darwinia_core as bp_crab; pub use bp_darwinia_core as bp_darwinia; pub use bp_darwinia_core as bp_pangolin; +pub use bp_darwinia_core as bp_pangoro; #[cfg(feature = "test")] pub mod test; diff --git a/runtime/pangolin/src/bridges_message/mod.rs b/runtime/pangolin/src/bridges_message/mod.rs new file mode 100644 index 000000000..65ea8ae43 --- /dev/null +++ b/runtime/pangolin/src/bridges_message/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub mod pangoro; +pub use pangoro as bm_pangoro; diff --git a/runtime/pangolin/src/bridges_message/pangoro.rs b/runtime/pangolin/src/bridges_message/pangoro.rs new file mode 100644 index 000000000..bb96b0a42 --- /dev/null +++ b/runtime/pangolin/src/bridges_message/pangoro.rs @@ -0,0 +1,182 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +// crates.io +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +// paritytech +use frame_support::{weights::Weight, RuntimeDebug}; +use sp_runtime::{FixedPointNumber, FixedU128}; +// darwinia +use crate::*; +use bp_messages::{source_chain::*, target_chain::*, *}; +use bp_polkadot_core::parachains::ParaId; +use bp_runtime::*; +use bridge_runtime_common::{ + lanes::*, + messages::{source::*, target::*, *}, +}; +use darwinia_common_runtime::*; + +/// Message delivery proof for Pangolin -> Pangoro messages. +pub type ToPangoroMessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof; +/// Message proof for Pangoro -> Pangolin messages. +pub type FromPangoroMessagesProof = FromBridgedChainMessagesProof; + +/// Message payload for Pangolin -> Pangoro messages. +pub type ToPangoroMessagePayload = FromThisChainMessagePayload; +/// Message payload for Pangoro -> Pangolin messages. +pub type FromPangoroMessagePayload = FromBridgedChainMessagePayload; + +/// Message verifier for Pangolin -> Pangoro messages. +pub type ToPangoroMessageVerifier = + FromThisChainMessageVerifier; + +/// Encoded Pangoro Call as it comes from Pangoro. +pub type FromPangoroEncodedCall = FromBridgedChainEncodedMessageCall; + +/// Call-dispatch based message dispatch for Pangoro -> Pangolin messages. +pub type FromPangoroMessageDispatch = FromBridgedChainMessageDispatch< + WithPangoroMessageBridge, + Runtime, + Balances, + WithPangoroDispatch, +>; + +pub const INITIAL_PANGORO_TO_PANGOLIN_CONVERSION_RATE: FixedU128 = + FixedU128::from_inner(FixedU128::DIV); + +frame_support::parameter_types! { + /// Pangolin to Pangoro conversion rate. Initially we treate both tokens as equal. + pub storage PangoroToPangolinConversionRate: FixedU128 = INITIAL_PANGORO_TO_PANGOLIN_CONVERSION_RATE; +} + +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub enum PangolinToPangoroParameter { + /// The conversion formula we use is: `PangoroTokens = PangolinTokens * + /// conversion_rate`. + PangoroToPangolinConversionRate(FixedU128), +} +impl Parameter for PangolinToPangoroParameter { + fn save(&self) { + match *self { + PangolinToPangoroParameter::PangoroToPangolinConversionRate(ref conversion_rate) => + PangoroToPangolinConversionRate::set(conversion_rate), + } + } +} + +pub type ToPangoroMaximalOutboundPayloadSize = + bridge_runtime_common::messages::source::FromThisChainMaximalOutboundPayloadSize< + WithPangoroMessageBridge, + >; + +/// Pangoro <-> Pangolin message bridge. +#[derive(Clone, Copy, RuntimeDebug)] +pub struct WithPangoroMessageBridge; +impl MessageBridge for WithPangoroMessageBridge { + type BridgedChain = Pangoro; + type ThisChain = Pangolin; + + const BRIDGED_CHAIN_ID: bp_runtime::ChainId = PANGORO_CHAIN_ID; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = + bridge_runtime_common::pallets::WITH_PANGOLIN_MESSAGES_PALLET_NAME; + const RELAYER_FEE_PERCENT: u32 = 10; + const THIS_CHAIN_ID: bp_runtime::ChainId = PANGOLIN_CHAIN_ID; +} + +#[derive(Clone, Copy, RuntimeDebug)] +pub struct Pangolin; +impl ChainWithMessages for Pangolin { + type AccountId = bp_pangolin::AccountId; + type Balance = bp_pangolin::Balance; + type Hash = bp_pangolin::Hash; + type Signature = bp_pangolin::Signature; + type Signer = bp_pangolin::AccountPublic; +} +impl ThisChainWithMessages for Pangolin { + type RuntimeCall = RuntimeCall; + type RuntimeOrigin = RuntimeOrigin; + + fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { + *lane == PANGORO_PANGOLIN_LANE + } + + fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { + MessageNonce::MAX + } +} + +#[derive(Clone, Copy, RuntimeDebug)] +pub struct Pangoro; +impl ChainWithMessages for Pangoro { + type AccountId = bp_pangoro::AccountId; + type Balance = bp_pangoro::Balance; + type Hash = bp_pangoro::Hash; + type Signature = bp_pangoro::Signature; + type Signer = bp_pangoro::AccountPublic; +} +impl BridgedChainWithMessages for Pangoro { + fn maximal_extrinsic_size() -> u32 { + bp_pangoro::DarwiniaLike::max_extrinsic_size() + } + + fn verify_dispatch_weight(_message_payload: &[u8], payload_weight: &Weight) -> bool { + let upper_limit = target::maximal_incoming_message_dispatch_weight( + bp_pangoro::DarwiniaLike::max_extrinsic_weight(), + ); + payload_weight.all_lte(upper_limit) + } +} +impl TargetHeaderChain::AccountId> + for Pangoro +{ + type Error = &'static str; + type MessagesDeliveryProof = ToPangoroMessagesDeliveryProof; + + fn verify_message(payload: &ToPangoroMessagePayload) -> Result<(), Self::Error> { + source::verify_chain_message::(payload) + } + + fn verify_messages_delivery_proof( + proof: Self::MessagesDeliveryProof, + ) -> Result<(LaneId, InboundLaneData), Self::Error> { + source::verify_messages_delivery_proof_from_parachain::< + WithPangoroMessageBridge, + bp_pangoro::Header, + Runtime, + WithMoonbaseParachainsInstance, + >(ParaId(2105), proof) + } +} +impl SourceHeaderChain<::Balance> for Pangoro { + type Error = &'static str; + type MessagesProof = FromPangoroMessagesProof; + + fn verify_messages_proof( + proof: Self::MessagesProof, + messages_count: u32, + ) -> Result::Balance>>, Self::Error> { + target::verify_messages_proof_from_parachain::< + WithPangoroMessageBridge, + bp_pangoro::Header, + Runtime, + WithMoonbaseParachainsInstance, + >(ParaId(2105), proof, messages_count) + } +} diff --git a/runtime/pangolin/src/lib.rs b/runtime/pangolin/src/lib.rs index d03cc8ff2..9a59921c6 100644 --- a/runtime/pangolin/src/lib.rs +++ b/runtime/pangolin/src/lib.rs @@ -27,6 +27,9 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod pallets; pub use pallets::*; +mod bridges_message; +pub use bridges_message::*; + mod migration; mod weights; @@ -52,6 +55,7 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + BridgeRejectObsoleteHeadersAndMessages, ); /// Unchecked extrinsic type as expected by this runtime. @@ -154,6 +158,13 @@ frame_support::construct_runtime! { Ethereum: pallet_ethereum = 36, Evm: pallet_evm = 37, MessageTransact: darwinia_message_transact = 38, + + // Pangolin <> Pangoro + BridgeMoonbaseGrandpa: pallet_bridge_grandpa:: = 39, + BridgeMoonbaseParachain: pallet_bridge_parachains:: = 40, + BridgePangoroMessages: pallet_bridge_messages:: = 41, + BridgePangoroDispatch: pallet_bridge_dispatch:: = 42, + PangoroFeeMarket: pallet_fee_market:: = 43 } } @@ -168,6 +179,16 @@ frame_benchmarking::define_benchmarks! { impl_self_contained_call!(); +bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { + RuntimeCall, AccountId, + // Grandpa + BridgeMoonbaseGrandpa, + // Messages + BridgePangoroMessages, + // Parachain + BridgeMoonbaseParachain +} + sp_api::impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { diff --git a/runtime/pangolin/src/pallets/bridge_dispatch.rs b/runtime/pangolin/src/pallets/bridge_dispatch.rs new file mode 100644 index 000000000..367da5504 --- /dev/null +++ b/runtime/pangolin/src/pallets/bridge_dispatch.rs @@ -0,0 +1,109 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_bridge_dispatch::Instance1 as WithPangoroDispatch; + +// darwinia +use crate::*; + +pub struct CallValidator; +impl bp_message_dispatch::CallValidate for CallValidator { + fn check_receiving_before_dispatch( + relayer_account: &AccountId, + call: &RuntimeCall, + ) -> Result<(), &'static str> { + match call { + RuntimeCall::MessageTransact(darwinia_message_transact::Call::message_transact { + transaction: tx, + }) => { + let total_payment = + darwinia_message_transact::total_payment::((&**tx).into()); + let relayer = + pallet_evm::Pallet::::account_basic(&sp_core::H160(relayer_account.0)) + .0; + + frame_support::ensure!(relayer.balance >= total_payment, "Insufficient balance"); + Ok(()) + }, + _ => Ok(()), + } + } + + fn call_validate( + relayer_account: &AccountId, + origin: &RuntimeOrigin, + call: &RuntimeCall, + ) -> Result<(), sp_runtime::transaction_validity::TransactionValidityError> { + match call { + RuntimeCall::MessageTransact(darwinia_message_transact::Call::message_transact { + transaction: tx, + }) => match origin.caller { + OriginCaller::MessageTransact( + darwinia_message_transact::LcmpEthOrigin::MessageTransact(id), + ) => { + let total_payment = + darwinia_message_transact::total_payment::((&**tx).into()); + pallet_balances::Pallet::::transfer( + frame_system::RawOrigin::Signed(*relayer_account).into(), + id.into(), + total_payment.as_u128(), + ) + .map_err(|_| { + sp_runtime::transaction_validity::TransactionValidityError::Invalid( + sp_runtime::transaction_validity::InvalidTransaction::Payment, + ) + })?; + + Ok(()) + }, + _ => Err(sp_runtime::transaction_validity::TransactionValidityError::Invalid( + sp_runtime::transaction_validity::InvalidTransaction::BadSigner, + )), + }, + _ => Ok(()), + } + } +} + +pub struct IntoDispatchOrigin; +impl bp_message_dispatch::IntoDispatchOrigin + for IntoDispatchOrigin +{ + fn into_dispatch_origin(id: &AccountId, call: &RuntimeCall) -> RuntimeOrigin { + match call { + RuntimeCall::MessageTransact(darwinia_message_transact::Call::message_transact { + .. + }) => darwinia_message_transact::LcmpEthOrigin::MessageTransact(sp_core::H160(id.0)) + .into(), + _ => frame_system::RawOrigin::Signed(*id).into(), + } + } +} + +impl pallet_bridge_dispatch::Config for Runtime { + type AccountIdConverter = bp_pangolin::AccountIdConverter; + type BridgeMessageId = (bp_messages::LaneId, bp_messages::MessageNonce); + type CallValidator = CallValidator; + type EncodedCall = bm_pangoro::FromPangoroEncodedCall; + type IntoDispatchOrigin = IntoDispatchOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type SourceChainAccountId = bp_pangoro::AccountId; + type TargetChainAccountPublic = bp_pangolin::AccountPublic; + type TargetChainSignature = bp_pangolin::Signature; +} diff --git a/runtime/pangolin/src/pallets/bridge_grandpa.rs b/runtime/pangolin/src/pallets/bridge_grandpa.rs new file mode 100644 index 000000000..368bf79ba --- /dev/null +++ b/runtime/pangolin/src/pallets/bridge_grandpa.rs @@ -0,0 +1,33 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_bridge_grandpa::Instance1 as WithMoonbaseGrandpa; + +// pangoro +use crate::*; + +pub type MoonbaseHeadersToKeep = ConstU32<500>; + +impl pallet_bridge_grandpa::Config for Runtime { + type BridgedChain = bp_pangoro::DarwiniaLike; + type HeadersToKeep = MoonbaseHeadersToKeep; + type MaxBridgedAuthorities = ConstU32<100_000>; + type MaxBridgedHeaderSize = ConstU32<65536>; + type MaxRequests = ConstU32<50>; + type WeightInfo = (); +} diff --git a/runtime/pangolin/src/pallets/bridge_messages.rs b/runtime/pangolin/src/pallets/bridge_messages.rs new file mode 100644 index 000000000..40139c904 --- /dev/null +++ b/runtime/pangolin/src/pallets/bridge_messages.rs @@ -0,0 +1,68 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +use pallet_bridge_messages::Instance1 as WithPangoroMessages; + +// darwinia +use crate::*; + +impl bp_messages::source_chain::SenderOrigin for RuntimeOrigin { + fn linked_account(&self) -> Option { + match self.caller { + OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) => + Some(*submitter), + _ => None, + } + } +} + +frame_support::parameter_types! { + pub const BridgedChainId: bp_runtime::ChainId = bp_runtime::PANGORO_CHAIN_ID; + pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = + bp_pangoro::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; + pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = + bp_pangoro::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + pub RootAccountForPayments: Option = None; +} + +impl pallet_bridge_messages::Config for Runtime { + type AccountIdConverter = bp_pangolin::AccountIdConverter; + type BridgedChainId = BridgedChainId; + type InboundMessageFee = bp_pangoro::Balance; + type InboundPayload = bm_pangoro::FromPangoroMessagePayload; + type InboundRelayer = bp_pangoro::AccountId; + type LaneMessageVerifier = bm_pangoro::ToPangoroMessageVerifier; + type MaxMessagesToPruneAtOnce = ConstU64<8>; + type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; + type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; + type MaximalOutboundPayloadSize = bm_pangoro::ToPangoroMaximalOutboundPayloadSize; + type MessageDeliveryAndDispatchPayment = + pallet_fee_market::s2s::FeeMarketPayment; + type MessageDispatch = bm_pangoro::FromPangoroMessageDispatch; + type OnDeliveryConfirmed = + pallet_fee_market::s2s::FeeMarketMessageConfirmedHandler; + type OnMessageAccepted = + pallet_fee_market::s2s::FeeMarketMessageAcceptedHandler; + type OutboundMessageFee = bp_pangolin::Balance; + type OutboundPayload = bm_pangoro::ToPangoroMessagePayload; + type Parameter = bm_pangoro::PangolinToPangoroParameter; + type RuntimeEvent = RuntimeEvent; + type SourceHeaderChain = bm_pangoro::Pangoro; + type TargetHeaderChain = bm_pangoro::Pangoro; + type WeightInfo = (); +} diff --git a/runtime/pangolin/src/pallets/bridge_parachains.rs b/runtime/pangolin/src/pallets/bridge_parachains.rs new file mode 100644 index 000000000..cd723c4f9 --- /dev/null +++ b/runtime/pangolin/src/pallets/bridge_parachains.rs @@ -0,0 +1,36 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_bridge_parachains::Instance1 as WithMoonbaseParachainsInstance; + +// darwinia +use crate::*; + +frame_support::parameter_types! { + pub const ParasPalletName: &'static str = bp_polkadot_core::parachains::PARAS_PALLET_NAME; +} + +impl pallet_bridge_parachains::Config for Runtime { + type BridgesGrandpaPalletInstance = WithMoonbaseGrandpa; + type HeadsToKeep = MoonbaseHeadersToKeep; + type MaxParaHeadSize = ConstU32<1024>; + type ParasPalletName = ParasPalletName; + type RuntimeEvent = RuntimeEvent; + type TrackedParachains = frame_support::traits::Everything; + type WeightInfo = (); +} diff --git a/runtime/pangolin/src/pallets/fee_market.rs b/runtime/pangolin/src/pallets/fee_market.rs new file mode 100644 index 000000000..93e5b2686 --- /dev/null +++ b/runtime/pangolin/src/pallets/fee_market.rs @@ -0,0 +1,74 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_fee_market::Instance1 as WithPangoroFeeMarket; + +// darwinia +use crate::*; + +pub struct FeeMarketSlasher; + +impl, I: 'static> pallet_fee_market::Slasher + for FeeMarketSlasher +{ + fn calc_amount( + locked_collateral: pallet_fee_market::BalanceOf, + timeout: T::BlockNumber, + ) -> pallet_fee_market::BalanceOf { + // substrate + use sp_runtime::traits::UniqueSaturatedInto; + + let slash_each_block = 2 * UNIT; + let slash_value = + sp_runtime::traits::UniqueSaturatedInto::::unique_saturated_into(timeout) + .saturating_mul( + sp_runtime::traits::UniqueSaturatedInto::::unique_saturated_into( + slash_each_block, + ), + ) + .unique_saturated_into(); + + core::cmp::min(locked_collateral, slash_value) + } +} + +frame_support::parameter_types! { + pub const TreasuryPalletId: frame_support::PalletId = frame_support::PalletId(*b"da/trsry"); + pub const FeeMarketLockId: frame_support::traits::LockIdentifier = *b"da/feecr"; + + pub const DutyRelayersRewardRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(60); + pub const MessageRelayersRewardRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(80); + pub const ConfirmRelayersRewardRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(20); + pub const AssignedRelayerSlashRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(20); +} + +impl pallet_fee_market::Config for Runtime { + type AssignedRelayerSlashRatio = AssignedRelayerSlashRatio; + type CollateralPerOrder = ConstU128<{ 50 * UNIT }>; + type ConfirmRelayersRewardRatio = ConfirmRelayersRewardRatio; + type Currency = Balances; + type DutyRelayersRewardRatio = DutyRelayersRewardRatio; + type LockId = FeeMarketLockId; + type MessageRelayersRewardRatio = MessageRelayersRewardRatio; + type MinimumRelayFee = ConstU128<{ 15 * UNIT }>; + type RuntimeEvent = RuntimeEvent; + type Slasher = FeeMarketSlasher; + type Slot = ConstU32<600>; + type TreasuryPalletId = TreasuryPalletId; + type WeightInfo = (); +} diff --git a/runtime/pangolin/src/pallets/mod.rs b/runtime/pangolin/src/pallets/mod.rs index c07ec8c74..2ac24d6da 100644 --- a/runtime/pangolin/src/pallets/mod.rs +++ b/runtime/pangolin/src/pallets/mod.rs @@ -109,3 +109,19 @@ mod evm; pub use evm::*; mod message_transact; + +// S2S stuff. +mod bridge_dispatch; +pub use bridge_dispatch::*; + +mod bridge_grandpa; +pub use bridge_grandpa::*; + +mod bridge_messages; +pub use bridge_messages::*; + +mod bridge_parachains; +pub use bridge_parachains::*; + +mod fee_market; +pub use fee_market::*; diff --git a/runtime/pangoro/src/bridges_message/mod.rs b/runtime/pangoro/src/bridges_message/mod.rs new file mode 100644 index 000000000..4ff85dab9 --- /dev/null +++ b/runtime/pangoro/src/bridges_message/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub mod pangolin; +pub use pangolin as bm_pangolin; diff --git a/runtime/pangoro/src/bridges_message/pangolin.rs b/runtime/pangoro/src/bridges_message/pangolin.rs new file mode 100644 index 000000000..12f5cf2e4 --- /dev/null +++ b/runtime/pangoro/src/bridges_message/pangolin.rs @@ -0,0 +1,182 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +// crates.io +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +// paritytech +use frame_support::{weights::Weight, RuntimeDebug}; +use sp_runtime::{FixedPointNumber, FixedU128}; +// darwinia +use crate::*; +use bp_messages::{source_chain::*, target_chain::*, *}; +use bp_polkadot_core::parachains::ParaId; +use bp_runtime::*; +use bridge_runtime_common::{ + lanes::*, + messages::{source::*, target::*, *}, +}; +use darwinia_common_runtime::*; + +/// Message delivery proof for Pangoro -> Pangolin messages. +pub type ToPangolinMessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof; +/// Message proof for Pangolin -> Pangoro messages. +pub type FromPangolinMessagesProof = FromBridgedChainMessagesProof; + +/// Message payload for Pangoro -> Pangolin messages. +pub type ToPangolinMessagePayload = FromThisChainMessagePayload; +/// Message payload for Pangolin -> Pangoro messages. +pub type FromPangolinMessagePayload = FromBridgedChainMessagePayload; + +/// Message verifier for Pangoro -> Pangolin messages. +pub type ToPangolinMessageVerifier = + FromThisChainMessageVerifier; + +/// Encoded Pangolin Call as it comes from Pangolin. +pub type FromPangolinEncodedCall = FromBridgedChainEncodedMessageCall; + +/// Call-dispatch based message dispatch for Pangolin -> Pangoro messages. +pub type FromPangolinMessageDispatch = FromBridgedChainMessageDispatch< + WithPangolinMessageBridge, + Runtime, + Balances, + WithPangolinDispatch, +>; + +pub const INITIAL_PANGOLIN_TO_PANGORO_CONVERSION_RATE: FixedU128 = + FixedU128::from_inner(FixedU128::DIV); + +frame_support::parameter_types! { + /// Pangoro to Pangolin conversion rate. Initially we treate both tokens as equal. + pub storage PangolinToPangoroConversionRate: FixedU128 = INITIAL_PANGOLIN_TO_PANGORO_CONVERSION_RATE; +} + +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub enum PangoroToPangolinParameter { + /// The conversion formula we use is: `PangolinTokens = PangoroTokens * + /// conversion_rate`. + PangolinToPangoroConversionRate(FixedU128), +} +impl Parameter for PangoroToPangolinParameter { + fn save(&self) { + match *self { + PangoroToPangolinParameter::PangolinToPangoroConversionRate(ref conversion_rate) => + PangolinToPangoroConversionRate::set(conversion_rate), + } + } +} + +pub type ToPangolinMaximalOutboundPayloadSize = + bridge_runtime_common::messages::source::FromThisChainMaximalOutboundPayloadSize< + WithPangolinMessageBridge, + >; + +/// Pangolin <-> Pangoro message bridge. +#[derive(Clone, Copy, RuntimeDebug)] +pub struct WithPangolinMessageBridge; +impl MessageBridge for WithPangolinMessageBridge { + type BridgedChain = Pangolin; + type ThisChain = Pangoro; + + const BRIDGED_CHAIN_ID: bp_runtime::ChainId = PANGOLIN_CHAIN_ID; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = + bridge_runtime_common::pallets::WITH_PANGORO_MESSAGES_PALLET_NAME; + const RELAYER_FEE_PERCENT: u32 = 10; + const THIS_CHAIN_ID: bp_runtime::ChainId = PANGORO_CHAIN_ID; +} + +#[derive(Clone, Copy, RuntimeDebug)] +pub struct Pangoro; +impl ChainWithMessages for Pangoro { + type AccountId = bp_pangoro::AccountId; + type Balance = bp_pangoro::Balance; + type Hash = bp_pangoro::Hash; + type Signature = bp_pangoro::Signature; + type Signer = bp_pangoro::AccountPublic; +} +impl ThisChainWithMessages for Pangoro { + type RuntimeCall = RuntimeCall; + type RuntimeOrigin = RuntimeOrigin; + + fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { + *lane == PANGORO_PANGOLIN_LANE + } + + fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { + MessageNonce::MAX + } +} + +#[derive(Clone, Copy, RuntimeDebug)] +pub struct Pangolin; +impl ChainWithMessages for Pangolin { + type AccountId = bp_pangolin::AccountId; + type Balance = bp_pangolin::Balance; + type Hash = bp_pangolin::Hash; + type Signature = bp_pangolin::Signature; + type Signer = bp_pangolin::AccountPublic; +} +impl BridgedChainWithMessages for Pangolin { + fn maximal_extrinsic_size() -> u32 { + bp_pangolin::DarwiniaLike::max_extrinsic_size() + } + + fn verify_dispatch_weight(_message_payload: &[u8], payload_weight: &Weight) -> bool { + let upper_limit = target::maximal_incoming_message_dispatch_weight( + bp_pangolin::DarwiniaLike::max_extrinsic_weight(), + ); + payload_weight.all_lte(upper_limit) + } +} +impl TargetHeaderChain::AccountId> + for Pangolin +{ + type Error = &'static str; + type MessagesDeliveryProof = ToPangolinMessagesDeliveryProof; + + fn verify_message(payload: &ToPangolinMessagePayload) -> Result<(), Self::Error> { + source::verify_chain_message::(payload) + } + + fn verify_messages_delivery_proof( + proof: Self::MessagesDeliveryProof, + ) -> Result<(LaneId, InboundLaneData), Self::Error> { + source::verify_messages_delivery_proof_from_parachain::< + WithPangolinMessageBridge, + bp_pangolin::Header, + Runtime, + WithRococoParachainsInstance, + >(ParaId(2105), proof) + } +} +impl SourceHeaderChain<::Balance> for Pangolin { + type Error = &'static str; + type MessagesProof = FromPangolinMessagesProof; + + fn verify_messages_proof( + proof: Self::MessagesProof, + messages_count: u32, + ) -> Result::Balance>>, Self::Error> { + target::verify_messages_proof_from_parachain::< + WithPangolinMessageBridge, + bp_pangolin::Header, + Runtime, + WithRococoParachainsInstance, + >(ParaId(2105), proof, messages_count) + } +} diff --git a/runtime/pangoro/src/lib.rs b/runtime/pangoro/src/lib.rs index 1b1559f68..b8615abba 100644 --- a/runtime/pangoro/src/lib.rs +++ b/runtime/pangoro/src/lib.rs @@ -27,6 +27,9 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod pallets; pub use pallets::*; +mod bridges_message; +pub use bridges_message::*; + mod migration; mod weights; @@ -52,6 +55,7 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + BridgeRejectObsoleteHeadersAndMessages, ); /// Unchecked extrinsic type as expected by this runtime. @@ -154,6 +158,13 @@ frame_support::construct_runtime! { Ethereum: pallet_ethereum = 36, Evm: pallet_evm = 37, MessageTransact: darwinia_message_transact = 38, + + // Pangoro <> Pangolin + BridgeRococoGrandpa: pallet_bridge_grandpa:: = 39, + BridgeRococoParachain: pallet_bridge_parachains:: = 40, + BridgePangolinMessages: pallet_bridge_messages:: = 41, + BridgePangolinDispatch: pallet_bridge_dispatch:: = 42, + PangolinFeeMarket: pallet_fee_market:: = 43 } } @@ -168,6 +179,16 @@ frame_benchmarking::define_benchmarks! { impl_self_contained_call!(); +bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { + RuntimeCall, AccountId, + // Grandpa + BridgeRococoGrandpa, + // Messages + BridgePangolinMessages, + // Parachain + BridgeRococoParachain +} + sp_api::impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { diff --git a/runtime/pangoro/src/pallets/bridge_dispatch.rs b/runtime/pangoro/src/pallets/bridge_dispatch.rs new file mode 100644 index 000000000..8b990a1cc --- /dev/null +++ b/runtime/pangoro/src/pallets/bridge_dispatch.rs @@ -0,0 +1,109 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_bridge_dispatch::Instance1 as WithPangolinDispatch; + +// darwinia +use crate::*; + +pub struct CallValidator; +impl bp_message_dispatch::CallValidate for CallValidator { + fn check_receiving_before_dispatch( + relayer_account: &AccountId, + call: &RuntimeCall, + ) -> Result<(), &'static str> { + match call { + RuntimeCall::MessageTransact(darwinia_message_transact::Call::message_transact { + transaction: tx, + }) => { + let total_payment = + darwinia_message_transact::total_payment::((&**tx).into()); + let relayer = + pallet_evm::Pallet::::account_basic(&sp_core::H160(relayer_account.0)) + .0; + + frame_support::ensure!(relayer.balance >= total_payment, "Insufficient balance"); + Ok(()) + }, + _ => Ok(()), + } + } + + fn call_validate( + relayer_account: &AccountId, + origin: &RuntimeOrigin, + call: &RuntimeCall, + ) -> Result<(), sp_runtime::transaction_validity::TransactionValidityError> { + match call { + RuntimeCall::MessageTransact(darwinia_message_transact::Call::message_transact { + transaction: tx, + }) => match origin.caller { + OriginCaller::MessageTransact( + darwinia_message_transact::LcmpEthOrigin::MessageTransact(id), + ) => { + let total_payment = + darwinia_message_transact::total_payment::((&**tx).into()); + pallet_balances::Pallet::::transfer( + frame_system::RawOrigin::Signed(*relayer_account).into(), + id.into(), + total_payment.as_u128(), + ) + .map_err(|_| { + sp_runtime::transaction_validity::TransactionValidityError::Invalid( + sp_runtime::transaction_validity::InvalidTransaction::Payment, + ) + })?; + + Ok(()) + }, + _ => Err(sp_runtime::transaction_validity::TransactionValidityError::Invalid( + sp_runtime::transaction_validity::InvalidTransaction::BadSigner, + )), + }, + _ => Ok(()), + } + } +} + +pub struct IntoDispatchOrigin; +impl bp_message_dispatch::IntoDispatchOrigin + for IntoDispatchOrigin +{ + fn into_dispatch_origin(id: &AccountId, call: &RuntimeCall) -> RuntimeOrigin { + match call { + RuntimeCall::MessageTransact(darwinia_message_transact::Call::message_transact { + .. + }) => darwinia_message_transact::LcmpEthOrigin::MessageTransact(sp_core::H160(id.0)) + .into(), + _ => frame_system::RawOrigin::Signed(*id).into(), + } + } +} + +impl pallet_bridge_dispatch::Config for Runtime { + type AccountIdConverter = bp_pangoro::AccountIdConverter; + type BridgeMessageId = (bp_messages::LaneId, bp_messages::MessageNonce); + type CallValidator = CallValidator; + type EncodedCall = bm_pangolin::FromPangolinEncodedCall; + type IntoDispatchOrigin = IntoDispatchOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type SourceChainAccountId = bp_pangolin::AccountId; + type TargetChainAccountPublic = bp_pangoro::AccountPublic; + type TargetChainSignature = bp_pangoro::Signature; +} diff --git a/runtime/pangoro/src/pallets/bridge_grandpa.rs b/runtime/pangoro/src/pallets/bridge_grandpa.rs new file mode 100644 index 000000000..635aa7efb --- /dev/null +++ b/runtime/pangoro/src/pallets/bridge_grandpa.rs @@ -0,0 +1,33 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_bridge_grandpa::Instance1 as WithRococoGrandpa; + +// darwinia +use crate::*; + +pub type RococoHeadersToKeep = ConstU32<500>; + +impl pallet_bridge_grandpa::Config for Runtime { + type BridgedChain = bp_pangolin::DarwiniaLike; + type HeadersToKeep = RococoHeadersToKeep; + type MaxBridgedAuthorities = ConstU32<100_000>; + type MaxBridgedHeaderSize = ConstU32<65536>; + type MaxRequests = ConstU32<50>; + type WeightInfo = (); +} diff --git a/runtime/pangoro/src/pallets/bridge_messages.rs b/runtime/pangoro/src/pallets/bridge_messages.rs new file mode 100644 index 000000000..0a664dabf --- /dev/null +++ b/runtime/pangoro/src/pallets/bridge_messages.rs @@ -0,0 +1,68 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +use pallet_bridge_messages::Instance1 as WithPangolinMessages; + +// darwinia +use crate::*; + +impl bp_messages::source_chain::SenderOrigin for RuntimeOrigin { + fn linked_account(&self) -> Option { + match self.caller { + OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) => + Some(*submitter), + _ => None, + } + } +} + +frame_support::parameter_types! { + pub const BridgedChainId: bp_runtime::ChainId = bp_runtime::PANGOLIN_CHAIN_ID; + pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = + bp_pangoro::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; + pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = + bp_pangoro::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + pub RootAccountForPayments: Option = None; +} + +impl pallet_bridge_messages::Config for Runtime { + type AccountIdConverter = bp_pangoro::AccountIdConverter; + type BridgedChainId = BridgedChainId; + type InboundMessageFee = bp_pangolin::Balance; + type InboundPayload = bm_pangolin::FromPangolinMessagePayload; + type InboundRelayer = bp_pangolin::AccountId; + type LaneMessageVerifier = bm_pangolin::ToPangolinMessageVerifier; + type MaxMessagesToPruneAtOnce = ConstU64<8>; + type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; + type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; + type MaximalOutboundPayloadSize = bm_pangolin::ToPangolinMaximalOutboundPayloadSize; + type MessageDeliveryAndDispatchPayment = + pallet_fee_market::s2s::FeeMarketPayment; + type MessageDispatch = bm_pangolin::FromPangolinMessageDispatch; + type OnDeliveryConfirmed = + pallet_fee_market::s2s::FeeMarketMessageConfirmedHandler; + type OnMessageAccepted = + pallet_fee_market::s2s::FeeMarketMessageAcceptedHandler; + type OutboundMessageFee = bp_pangoro::Balance; + type OutboundPayload = bm_pangolin::ToPangolinMessagePayload; + type Parameter = bm_pangolin::PangoroToPangolinParameter; + type RuntimeEvent = RuntimeEvent; + type SourceHeaderChain = bm_pangolin::Pangolin; + type TargetHeaderChain = bm_pangolin::Pangolin; + type WeightInfo = (); +} diff --git a/runtime/pangoro/src/pallets/bridge_parachains.rs b/runtime/pangoro/src/pallets/bridge_parachains.rs new file mode 100644 index 000000000..191d8ad97 --- /dev/null +++ b/runtime/pangoro/src/pallets/bridge_parachains.rs @@ -0,0 +1,36 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_bridge_parachains::Instance1 as WithRococoParachainsInstance; + +// darwinia +use crate::*; + +frame_support::parameter_types! { + pub const ParasPalletName: &'static str = bp_polkadot_core::parachains::PARAS_PALLET_NAME; +} + +impl pallet_bridge_parachains::Config for Runtime { + type BridgesGrandpaPalletInstance = WithRococoGrandpa; + type HeadsToKeep = RococoHeadersToKeep; + type MaxParaHeadSize = ConstU32<1024>; + type ParasPalletName = ParasPalletName; + type RuntimeEvent = RuntimeEvent; + type TrackedParachains = frame_support::traits::Everything; + type WeightInfo = (); +} diff --git a/runtime/pangoro/src/pallets/fee_market.rs b/runtime/pangoro/src/pallets/fee_market.rs new file mode 100644 index 000000000..c9a1ba34b --- /dev/null +++ b/runtime/pangoro/src/pallets/fee_market.rs @@ -0,0 +1,73 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2023 Darwinia Network +// SPDX-License-Identifier: GPL-3.0 +// +// Darwinia 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. +// +// Darwinia 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 Darwinia. If not, see . + +pub use pallet_fee_market::Instance1 as WithPangolinFeeMarket; + +// darwinia +use crate::*; + +pub struct FeeMarketSlasher; +impl, I: 'static> pallet_fee_market::Slasher + for FeeMarketSlasher +{ + fn calc_amount( + locked_collateral: pallet_fee_market::BalanceOf, + timeout: T::BlockNumber, + ) -> pallet_fee_market::BalanceOf { + // substrate + use sp_runtime::traits::UniqueSaturatedInto; + + let slash_each_block = 2 * UNIT; + let slash_value = + sp_runtime::traits::UniqueSaturatedInto::::unique_saturated_into(timeout) + .saturating_mul( + sp_runtime::traits::UniqueSaturatedInto::::unique_saturated_into( + slash_each_block, + ), + ) + .unique_saturated_into(); + + core::cmp::min(locked_collateral, slash_value) + } +} + +frame_support::parameter_types! { + pub const TreasuryPalletId: frame_support::PalletId = frame_support::PalletId(*b"da/trsry"); + pub const FeeMarketLockId: frame_support::traits::LockIdentifier = *b"da/feecr"; + + pub const DutyRelayersRewardRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(60); + pub const MessageRelayersRewardRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(80); + pub const ConfirmRelayersRewardRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(20); + pub const AssignedRelayerSlashRatio: sp_runtime::Permill = sp_runtime::Permill::from_percent(20); +} + +impl pallet_fee_market::Config for Runtime { + type AssignedRelayerSlashRatio = AssignedRelayerSlashRatio; + type CollateralPerOrder = ConstU128<{ 50 * UNIT }>; + type ConfirmRelayersRewardRatio = ConfirmRelayersRewardRatio; + type Currency = Balances; + type DutyRelayersRewardRatio = DutyRelayersRewardRatio; + type LockId = FeeMarketLockId; + type MessageRelayersRewardRatio = MessageRelayersRewardRatio; + type MinimumRelayFee = ConstU128<{ 15 * UNIT }>; + type RuntimeEvent = RuntimeEvent; + type Slasher = FeeMarketSlasher; + type Slot = ConstU32<600>; + type TreasuryPalletId = TreasuryPalletId; + type WeightInfo = (); +} diff --git a/runtime/pangoro/src/pallets/mod.rs b/runtime/pangoro/src/pallets/mod.rs index c07ec8c74..2ac24d6da 100644 --- a/runtime/pangoro/src/pallets/mod.rs +++ b/runtime/pangoro/src/pallets/mod.rs @@ -109,3 +109,19 @@ mod evm; pub use evm::*; mod message_transact; + +// S2S stuff. +mod bridge_dispatch; +pub use bridge_dispatch::*; + +mod bridge_grandpa; +pub use bridge_grandpa::*; + +mod bridge_messages; +pub use bridge_messages::*; + +mod bridge_parachains; +pub use bridge_parachains::*; + +mod fee_market; +pub use fee_market::*;