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;
+}