diff --git a/Cargo.lock b/Cargo.lock index 7b7e85e7c..6f9aa4c8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10264,7 +10264,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 0.1.10", "rand 0.8.5", "static_assertions", ] diff --git a/node/runtime/pangolin/src/bridges_message/mod.rs b/node/runtime/pangolin/src/bridges_message/mod.rs index 5aae77995..ea3d0b21b 100644 --- a/node/runtime/pangolin/src/bridges_message/mod.rs +++ b/node/runtime/pangolin/src/bridges_message/mod.rs @@ -20,4 +20,7 @@ pub mod pangoro; pub use pangoro as bm_pangoro; pub mod pangolin_parachain; +pub mod pangolin_parachain_alpha; + pub use pangolin_parachain as bm_pangolin_parachain; +pub use pangolin_parachain_alpha as bm_pangolin_parachain_alpha; diff --git a/node/runtime/pangolin/src/bridges_message/pangolin_parachain_alpha.rs b/node/runtime/pangolin/src/bridges_message/pangolin_parachain_alpha.rs new file mode 100644 index 000000000..7de52a9a4 --- /dev/null +++ b/node/runtime/pangolin/src/bridges_message/pangolin_parachain_alpha.rs @@ -0,0 +1,208 @@ +// This file is part of Darwinia. +// +// Copyright (C) 2018-2022 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}; +use sp_std::ops::RangeInclusive; +// --- darwinia-network --- +use crate::*; +use bp_messages::{ + source_chain::TargetHeaderChain, + target_chain::{ProvedMessages, SourceHeaderChain}, + InboundLaneData, LaneId, Message, MessageNonce, Parameter, +}; +use bp_rococo::parachains::ParaId; +use bp_runtime::{Chain, ChainId, PANGOLIN_CHAIN_ID, PANGOLIN_PARACHAIN_ALPHA_CHAIN_ID}; +use bridge_runtime_common::{ + lanes::PANGOLIN_PANGOLIN_PARACHAIN_ALPHA_LANE, + messages::{ + source::{ + self, FromBridgedChainMessagesDeliveryProof, FromThisChainMessagePayload, + FromThisChainMessageVerifier, + }, + target::{ + self, FromBridgedChainEncodedMessageCall, FromBridgedChainMessageDispatch, + FromBridgedChainMessagePayload, FromBridgedChainMessagesProof, + }, + BridgedChainWithMessages, ChainWithMessages, MessageBridge, ThisChainWithMessages, + }, +}; + +/// Message delivery proof for Pangolin -> PangolinParachainAlpha messages. +type ToPangolinParachainAlphaMessagesDeliveryProof = + FromBridgedChainMessagesDeliveryProof; +/// Message proof for PangolinParachainAlpha -> Pangolin messages. +type FromPangolinParachainAlphaMessagesProof = + FromBridgedChainMessagesProof; + +/// Message payload for Pangolin -> PangolinParachainAlpha messages. +pub type ToPangolinParachainAlphaMessagePayload = + FromThisChainMessagePayload; +/// Message payload for PangolinParachainAlpha -> Pangolin messages. +pub type FromPangolinParachainAlphaMessagePayload = + FromBridgedChainMessagePayload; + +/// Message verifier for Pangolin -> PangolinParachain messages. +pub type ToPangolinParachainAlphaMessageVerifier = FromThisChainMessageVerifier< + WithPangolinParachainAlphaMessageBridge, + Runtime, + WithPangolinParachainAlphaFeeMarket, +>; + +/// Encoded Pangolin Call as it comes from PangolinParachainAlpha +pub type FromPangolinParachainAlphaEncodedCall = FromBridgedChainEncodedMessageCall; + +/// Call-dispatch based message dispatch for PangolinParachainAlpha -> Pangolin messages. +pub type FromPangolinParachainAlphaMessageDispatch = FromBridgedChainMessageDispatch< + WithPangolinParachainAlphaMessageBridge, + Runtime, + Ring, + WithPangolinParachainAlphaDispatch, +>; + +/// Identifier of PangolinParachainAlpha registered in the moonbase relay chain. +pub const PANGOLIN_PARACHAIN_ALPHA_ID: u32 = 2105; + +pub const INITIAL_PANGOLIN_PARACHAIN_ALPHA_TO_PANGOLIN_CONVERSION_RATE: FixedU128 = + FixedU128::from_inner(FixedU128::DIV); + +frame_support::parameter_types! { + /// PangolinParachainAlpha to Pangolin conversion rate. Initially we trate both tokens as equal. + pub storage PangolinParachainAlphaToPangolinConversionRate: FixedU128 = INITIAL_PANGOLIN_PARACHAIN_ALPHA_TO_PANGOLIN_CONVERSION_RATE; +} + +#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub enum PangolinToPangolinParachainAlphaParameter { + /// The conversion formula we use is: `PangolinTokens = PangolinParachainAlphaTokens * + /// conversion_rate`. + PangolinParachainAlphaToPangolinConversionRate(FixedU128), +} +impl Parameter for PangolinToPangolinParachainAlphaParameter { + fn save(&self) { + match *self { + PangolinToPangolinParachainAlphaParameter::PangolinParachainAlphaToPangolinConversionRate( + ref conversion_rate, + ) => PangolinParachainAlphaToPangolinConversionRate::set(conversion_rate), + } + } +} + +/// Pangolin <-> PangolinParachainAlpha message bridge. +#[derive(Clone, Copy, RuntimeDebug)] +pub struct WithPangolinParachainAlphaMessageBridge; +impl MessageBridge for WithPangolinParachainAlphaMessageBridge { + type BridgedChain = PangolinParachainAlpha; + type ThisChain = Pangolin; + + const BRIDGED_CHAIN_ID: ChainId = PANGOLIN_PARACHAIN_ALPHA_CHAIN_ID; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = + bp_pangolin::WITH_PANGOLIN_MESSAGES_PALLET_NAME; + const RELAYER_FEE_PERCENT: u32 = 10; + const THIS_CHAIN_ID: ChainId = PANGOLIN_CHAIN_ID; +} + +/// Pangolin chain from message lane point of view. +#[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; + type Weight = Weight; +} +impl ThisChainWithMessages for Pangolin { + type Call = Call; + type Origin = Origin; + + fn is_message_accepted(_send_origin: &Self::Origin, lane: &LaneId) -> bool { + *lane == PANGOLIN_PANGOLIN_PARACHAIN_ALPHA_LANE + } + + fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { + MessageNonce::MAX + } +} + +#[derive(Clone, Copy, RuntimeDebug)] +pub struct PangolinParachainAlpha; +impl ChainWithMessages for PangolinParachainAlpha { + type AccountId = bp_pangolin_parachain::AccountId; + type Balance = bp_pangolin_parachain::Balance; + type Hash = bp_pangolin_parachain::Hash; + type Signature = bp_pangolin_parachain::Signature; + type Signer = bp_pangolin_parachain::AccountPublic; + type Weight = Weight; +} +impl BridgedChainWithMessages for PangolinParachainAlpha { + fn maximal_extrinsic_size() -> u32 { + bp_pangolin_parachain::PangolinParachain::max_extrinsic_size() + } + + fn message_weight_limits(_message_payload: &[u8]) -> RangeInclusive { + let upper_limit = target::maximal_incoming_message_dispatch_weight( + bp_pangolin_parachain::PangolinParachain::max_extrinsic_weight(), + ); + 0..=upper_limit + } +} +impl + TargetHeaderChain< + ToPangolinParachainAlphaMessagePayload, + ::AccountId, + > for PangolinParachainAlpha +{ + type Error = &'static str; + type MessagesDeliveryProof = ToPangolinParachainAlphaMessagesDeliveryProof; + + fn verify_message(payload: &ToPangolinParachainAlphaMessagePayload) -> 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::< + WithPangolinParachainAlphaMessageBridge, + bp_pangolin_parachain::Header, + Runtime, + WithRococoParachainsInstance, + >(ParaId(PANGOLIN_PARACHAIN_ALPHA_ID), proof) + } +} +impl SourceHeaderChain<::Balance> for PangolinParachainAlpha { + type Error = &'static str; + type MessagesProof = FromPangolinParachainAlphaMessagesProof; + + fn verify_messages_proof( + proof: Self::MessagesProof, + messages_count: u32, + ) -> Result::Balance>>, Self::Error> { + target::verify_messages_proof_from_parachain::< + WithPangolinParachainAlphaMessageBridge, + bp_pangolin_parachain::Header, + Runtime, + WithRococoParachainsInstance, + >(ParaId(PANGOLIN_PARACHAIN_ALPHA_ID), proof, messages_count) + } +} diff --git a/node/runtime/pangolin/src/lib.rs b/node/runtime/pangolin/src/lib.rs index ca2792c3a..6dd0afeb6 100644 --- a/node/runtime/pangolin/src/lib.rs +++ b/node/runtime/pangolin/src/lib.rs @@ -247,6 +247,13 @@ frame_support::construct_runtime! { PangolinParachainFeeMarket: pallet_fee_market::::{Pallet, Call, Storage, Event} = 64, TransactionPause: module_transaction_pause::{Pallet, Call, Storage, Event} = 54, + // pangolin <> pangolin parachain alpha bridge + BridgeMoonbaseRelayGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage} = 68, + BridgeMoonbaseRelayParachains: pallet_bridge_parachains::::{Pallet, Call, Storage} = 69, + BridgePangolinParachainAlphaDispatch: pallet_bridge_dispatch::::{Pallet, Event} = 70, + BridgePangolinParachainAlphaMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event} = 71, + PangolinParachainAlphaFeeMarket: pallet_fee_market::::{Pallet, Call, Storage, Event} = 72, + // Substrate2SubstrateIssuing: from_substrate_issuing::{Pallet, Call, Storage, Config, Event} = 49, ToPangolinParachainBacking: to_parachain_backing::{Pallet, Call, Storage, Config, Event} = 65, } diff --git a/node/runtime/pangolin/src/pallets/bridge_dispatch.rs b/node/runtime/pangolin/src/pallets/bridge_dispatch.rs index 8cb22fbc5..cdeb5585e 100644 --- a/node/runtime/pangolin/src/pallets/bridge_dispatch.rs +++ b/node/runtime/pangolin/src/pallets/bridge_dispatch.rs @@ -1,5 +1,6 @@ pub use pallet_bridge_dispatch::{ Instance1 as WithPangoroDispatch, Instance2 as WithPangolinParachainDispatch, + Instance3 as WithPangolinParachainAlphaDispatch, }; // --- paritytech --- @@ -125,3 +126,15 @@ impl Config for Runtime { type TargetChainAccountPublic = bp_pangolin::AccountPublic; type TargetChainSignature = bp_pangolin::Signature; } +impl Config for Runtime { + type AccountIdConverter = bp_pangolin::AccountIdConverter; + type BridgeMessageId = (LaneId, MessageNonce); + type Call = Call; + type CallValidator = CallValidator; + type EncodedCall = bm_pangolin_parachain_alpha::FromPangolinParachainAlphaEncodedCall; + type Event = Event; + type IntoDispatchOrigin = IntoDispatchOrigin; + type SourceChainAccountId = bp_pangolin_parachain::AccountId; + type TargetChainAccountPublic = bp_pangolin::AccountPublic; + type TargetChainSignature = bp_pangolin::Signature; +} diff --git a/node/runtime/pangolin/src/pallets/bridge_grandpa.rs b/node/runtime/pangolin/src/pallets/bridge_grandpa.rs index 3a3382595..9b8668cf9 100644 --- a/node/runtime/pangolin/src/pallets/bridge_grandpa.rs +++ b/node/runtime/pangolin/src/pallets/bridge_grandpa.rs @@ -1,4 +1,7 @@ -pub use pallet_bridge_grandpa::{Instance1 as WithPangoroGrandpa, Instance2 as WithRococoGrandpa}; +pub use pallet_bridge_grandpa::{ + Instance1 as WithPangoroGrandpa, Instance2 as WithRococoGrandpa, + Instance3 as WithMoonbaseRelayGrandpa, +}; // --- paritytech --- use pallet_bridge_grandpa::Config; @@ -35,3 +38,9 @@ impl Config for Runtime { type MaxRequests = MaxRequests; type WeightInfo = RococoGrandpaWeightInfo; } +impl Config for Runtime { + type BridgedChain = bp_rococo::Rococo; + type HeadersToKeep = RococoHeadersToKeep; + type MaxRequests = MaxRequests; + type WeightInfo = RococoGrandpaWeightInfo; +} diff --git a/node/runtime/pangolin/src/pallets/bridge_messages.rs b/node/runtime/pangolin/src/pallets/bridge_messages.rs index bf64bffa6..29c31c8ad 100644 --- a/node/runtime/pangolin/src/pallets/bridge_messages.rs +++ b/node/runtime/pangolin/src/pallets/bridge_messages.rs @@ -1,11 +1,14 @@ pub use pallet_bridge_messages::{ Instance1 as WithPangoroMessages, Instance2 as WithPangolinParachainMessages, + Instance3 as WithPangolinParachainAlphaMessages, }; // --- darwinia-network --- use crate::*; use bp_messages::MessageNonce; -use bp_runtime::{ChainId, PANGOLIN_PARACHAIN_CHAIN_ID, PANGORO_CHAIN_ID}; +use bp_runtime::{ + ChainId, PANGOLIN_PARACHAIN_ALPHA_CHAIN_ID, PANGOLIN_PARACHAIN_CHAIN_ID, PANGORO_CHAIN_ID, +}; use pallet_bridge_messages::Config; use pallet_fee_market::s2s::{ FeeMarketMessageAcceptedHandler, FeeMarketMessageConfirmedHandler, FeeMarketPayment, @@ -22,6 +25,7 @@ frame_support::parameter_types! { bp_pangoro::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; // Pangolin Parachain configurations. pub const PangolinParachainChainId: ChainId = PANGOLIN_PARACHAIN_CHAIN_ID; + pub const PangolinParachainAlphaChainId: ChainId = PANGOLIN_PARACHAIN_ALPHA_CHAIN_ID; pub const PangolinParachainMaxUnconfirmedMessagesAtInboundLane: MessageNonce = bp_pangolin_parachain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const PangolinParachainMaxUnrewardedRelayerEntriesAtInboundLane: MessageNonce = @@ -77,3 +81,31 @@ impl Config for Runtime { type TargetHeaderChain = bm_pangolin_parachain::PangolinParachain; type WeightInfo = (); } +impl Config for Runtime { + type AccountIdConverter = bp_pangolin::AccountIdConverter; + type BridgedChainId = PangolinParachainAlphaChainId; + type Event = Event; + type InboundMessageFee = bp_pangolin_parachain::Balance; + type InboundPayload = bm_pangolin_parachain_alpha::FromPangolinParachainAlphaMessagePayload; + type InboundRelayer = bp_pangolin_parachain::AccountId; + type LaneMessageVerifier = bm_pangolin_parachain_alpha::ToPangolinParachainAlphaMessageVerifier; + type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; + type MaxUnconfirmedMessagesAtInboundLane = PangolinParachainMaxUnconfirmedMessagesAtInboundLane; + type MaxUnrewardedRelayerEntriesAtInboundLane = + PangolinParachainMaxUnrewardedRelayerEntriesAtInboundLane; + type MessageDeliveryAndDispatchPayment = + FeeMarketPayment; + type MessageDispatch = bm_pangolin_parachain_alpha::FromPangolinParachainAlphaMessageDispatch; + type OnDeliveryConfirmed = ( + ToPangolinParachainBacking, + FeeMarketMessageConfirmedHandler, + ); + type OnMessageAccepted = + FeeMarketMessageAcceptedHandler; + type OutboundMessageFee = bp_pangolin::Balance; + type OutboundPayload = bm_pangolin_parachain_alpha::ToPangolinParachainAlphaMessagePayload; + type Parameter = bm_pangolin_parachain_alpha::PangolinToPangolinParachainAlphaParameter; + type SourceHeaderChain = bm_pangolin_parachain_alpha::PangolinParachainAlpha; + type TargetHeaderChain = bm_pangolin_parachain_alpha::PangolinParachainAlpha; + type WeightInfo = (); +} diff --git a/node/runtime/pangolin/src/pallets/bridge_parachains.rs b/node/runtime/pangolin/src/pallets/bridge_parachains.rs index 3a4a44da7..f3ffe2e37 100644 --- a/node/runtime/pangolin/src/pallets/bridge_parachains.rs +++ b/node/runtime/pangolin/src/pallets/bridge_parachains.rs @@ -1,4 +1,6 @@ -pub use pallet_bridge_parachains::Instance1 as WithRococoParachainsInstance; +pub use pallet_bridge_parachains::{ + Instance1 as WithRococoParachainsInstance, Instance2 as WithMoonbaseRelayParachainsInstance, +}; // --- darwinia-network --- use crate::*; @@ -8,3 +10,7 @@ impl Config for Runtime { type BridgesGrandpaPalletInstance = WithRococoGrandpa; type HeadsToKeep = RococoHeadersToKeep; } +impl Config for Runtime { + type BridgesGrandpaPalletInstance = WithMoonbaseRelayGrandpa; + type HeadsToKeep = RococoHeadersToKeep; +} diff --git a/node/runtime/pangolin/src/pallets/fee_market.rs b/node/runtime/pangolin/src/pallets/fee_market.rs index a2c72e310..9a8b6ce5c 100644 --- a/node/runtime/pangolin/src/pallets/fee_market.rs +++ b/node/runtime/pangolin/src/pallets/fee_market.rs @@ -1,5 +1,6 @@ pub use pallet_fee_market::{ Instance1 as WithPangoroFeeMarket, Instance2 as WithPangolinParachainFeeMarket, + Instance3 as WithPangolinParachainAlphaFeeMarket, }; // --- core --- @@ -50,6 +51,8 @@ frame_support::parameter_types! { pub const PangoroFeeMarketLockId: LockIdentifier = *b"da/feelf"; // Pangolin Parachain configurations. pub const PangolinParachainFeeMarketLockId: LockIdentifier = *b"da/feepa"; + // Pangolin Parachain Alpha configurations. + pub const PangolinParachainAlphaFeeMarketLockId: LockIdentifier = *b"da/feeph"; } impl Config for Runtime { @@ -82,3 +85,18 @@ impl Config for Runtime { type TreasuryPalletId = TreasuryPalletId; type WeightInfo = PangolinParachainWeightInfo; } +impl Config for Runtime { + type AssignedRelayerSlashRatio = AssignedRelayerSlashRatio; + type CollateralPerOrder = CollateralPerOrder; + type ConfirmRelayersRewardRatio = ConfirmRelayersRewardRatio; + type Currency = Ring; + type DutyRelayersRewardRatio = DutyRelayersRewardRatio; + type Event = Event; + type LockId = PangolinParachainAlphaFeeMarketLockId; + type MessageRelayersRewardRatio = MessageRelayersRewardRatio; + type MinimumRelayFee = MinimumRelayFee; + type Slasher = FeeMarketSlasher; + type Slot = Slot; + type TreasuryPalletId = TreasuryPalletId; + type WeightInfo = PangolinParachainWeightInfo; +}