Skip to content

Commit d245210

Browse files
authored
Merge pull request #2 from Moonsong-Labs/moonbeam-moonriver
Add moonbeam <-> moonriver bridge commands
2 parents d76568e + e2d5d1a commit d245210

23 files changed

+20848
-0
lines changed

Cargo.lock

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ members = [
1919
"relay-clients/client-rococo",
2020
"relay-clients/client-westend",
2121
"relay-clients/client-moonbase",
22+
"relay-clients/client-moonbeam",
23+
"relay-clients/client-moonriver",
2224
"chains/chain-bridge-hub-polkadot",
2325
"chains/chain-bridge-hub-kusama",
2426
"chains/chain-moonbase",
27+
"chains/chain-moonriver",
28+
"chains/chain-moonbeam",
2529
"chains/chain-polkadot",
2630
"chains/chain-kusama",
2731
"substrate-relay",
@@ -84,6 +88,8 @@ bp-polkadot = { path = "./chains/chain-polkadot" }
8488
bp-polkadot-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
8589
bp-kusama = { path = "./chains/chain-kusama" }
8690
bp-moonbase = { path = "./chains/chain-moonbase" }
91+
bp-moonriver = { path = "./chains/chain-moonriver" }
92+
bp-moonbeam = { path = "./chains/chain-moonbeam" }
8793
bp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
8894
bridge-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
8995
relay-substrate-client = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
@@ -132,6 +138,8 @@ relay-polkadot-bulletin-client = { path = "./relay-clients/client-polkadot-bulle
132138
relay-rococo-client = { path = "./relay-clients/client-rococo" }
133139
relay-westend-client = { path = "./relay-clients/client-westend" }
134140
relay-moonbase-client = { path = "./relay-clients/client-moonbase" }
141+
relay-moonbeam-client = { path = "./relay-clients/client-moonbeam" }
142+
relay-moonriver-client = { path = "./relay-clients/client-moonriver" }
135143
substrate-relay-helper = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
136144
bp-test-utils = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
137145
hex-literal = "0.4"

chains/chain-moonbeam/Cargo.toml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
[package]
2+
name = "bp-moonbeam"
3+
description = "Primitives of Moonbeam parachain runtime."
4+
version = "0.6.0"
5+
authors.workspace = true
6+
edition.workspace = true
7+
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
8+
repository.workspace = true
9+
10+
[lints]
11+
workspace = true
12+
13+
[dependencies]
14+
15+
libsecp256k1 = { version = "0.7", default-features = false, features = ["hmac"] }
16+
sha3 = { version = "0.10", default-features = false }
17+
impl-serde = { version = "0.4.0", default-features = false }
18+
log = { workspace = true }
19+
codec = { workspace = true }
20+
scale-info = { workspace = true }
21+
serde = { workspace = true, features = ["derive"] }
22+
23+
# Bridge Dependencies
24+
25+
bp-bridge-hub-cumulus = { workspace = true }
26+
bp-messages = { workspace = true }
27+
bp-runtime = { workspace = true }
28+
29+
# Substrate Based Dependencies
30+
31+
frame-support = { workspace = true }
32+
sp-api = { workspace = true }
33+
sp-runtime = { workspace = true }
34+
sp-std = { workspace = true }
35+
sp-core = { workspace = true }
36+
sp-io = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master"}
37+
38+
[features]
39+
default = ["std"]
40+
std = [
41+
"bp-bridge-hub-cumulus/std",
42+
"bp-messages/std",
43+
"bp-runtime/std",
44+
"frame-support/std",
45+
"sp-api/std",
46+
"sp-runtime/std",
47+
"sp-std/std",
48+
"sp-core/std",
49+
"sp-io/std"
50+
]

chains/chain-moonbeam/src/lib.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// Copyright 2025 Moonbeam foundation
2+
// This file is part of Moonbeam.
3+
4+
// Moonbeam is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Moonbeam is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//! # Moonbeam bridge primitives
18+
19+
#![cfg_attr(not(feature = "std"), no_std)]
20+
21+
pub use bp_bridge_hub_cumulus::{
22+
BlockLength, BlockWeights, Hasher, Nonce, SignedBlock, AVERAGE_BLOCK_INTERVAL,
23+
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
24+
};
25+
use bp_messages::{ChainWithMessages, MessageNonce};
26+
27+
use bp_runtime::{
28+
decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
29+
};
30+
use frame_support::{dispatch::DispatchClass, weights::Weight};
31+
use sp_runtime::{FixedPointNumber, FixedU128, Saturating, StateVersion};
32+
33+
// TODO: Temporary, remove once moonbeam has been updated to stable2503
34+
mod temporary;
35+
pub use temporary::{
36+
AccountId, AccountInfoStorageMapKeyProvider, Balance, BlockNumber, Hash, Header, Signature,
37+
UncheckedExtrinsic,
38+
};
39+
40+
/// Moonbeam parachain.
41+
pub struct Moonbeam;
42+
43+
impl Chain for Moonbeam {
44+
const ID: ChainId = *b"mnbm";
45+
46+
type BlockNumber = BlockNumber;
47+
type Hash = Hash;
48+
type Hasher = Hasher;
49+
type Header = Header;
50+
51+
type AccountId = AccountId;
52+
type Balance = Balance;
53+
type Nonce = Nonce;
54+
type Signature = Signature;
55+
56+
const STATE_VERSION: StateVersion = StateVersion::V1;
57+
58+
fn max_extrinsic_size() -> u32 {
59+
*BlockLength::get().max.get(DispatchClass::Normal)
60+
}
61+
62+
fn max_extrinsic_weight() -> Weight {
63+
BlockWeights::get()
64+
.get(DispatchClass::Normal)
65+
.max_extrinsic
66+
.unwrap_or(Weight::MAX)
67+
}
68+
}
69+
70+
impl Parachain for Moonbeam {
71+
const PARACHAIN_ID: u32 = MOONBEAM_POLKADOT_PARACHAIN_ID;
72+
const MAX_HEADER_SIZE: u32 = 4_096;
73+
}
74+
75+
impl ChainWithMessages for Moonbeam {
76+
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
77+
WITH_MOONBEAM_POLKADOT_MESSAGES_PALLET_NAME;
78+
79+
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
80+
MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
81+
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
82+
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
83+
}
84+
85+
/// Identifier of Moonbeam parachain in the Polkadot relay chain.
86+
pub const MOONBEAM_POLKADOT_PARACHAIN_ID: u32 = 2004;
87+
88+
/// Name of the With-MoonbeamPolkadot messages pallet instance that is deployed at bridged chains.
89+
pub const WITH_MOONBEAM_POLKADOT_MESSAGES_PALLET_NAME: &str = "BridgePolkadotMessages";
90+
91+
/// Name of the With-MoonbeamPolkadot bridge-relayers pallet instance that is deployed at bridged
92+
/// chains.
93+
pub const WITH_MOONBEAM_POLKADOT_RELAYERS_PALLET_NAME: &str = "BridgeRelayers";
94+
95+
/// Bridge lane identifier.
96+
pub type LaneId = bp_messages::LegacyLaneId;
97+
98+
decl_bridge_finality_runtime_apis!(moonbeam_polkadot);
99+
decl_bridge_messages_runtime_apis!(moonbeam_polkadot, LaneId);
100+
101+
// TODO: Update values
102+
frame_support::parameter_types! {
103+
/// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Kusama
104+
/// BridgeHub.
105+
/// (initially was calculated by test `BridgeHubKusama::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`)
106+
pub const BaseXcmFeeInGlmr: u128 = 601_115_666;
107+
108+
/// Transaction fee that is paid at the Kusama BridgeHub for delivering single inbound message.
109+
/// (initially was calculated by test `BridgeHubKusama::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`)
110+
pub const BaseDeliveryFeeInGlmr: u128 = 3_142_112_953;
111+
112+
/// Transaction fee that is paid at the Kusama BridgeHub for delivering single outbound message confirmation.
113+
/// (initially was calculated by test `BridgeHubKusama::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`)
114+
pub const BaseConfirmationFeeInGlmr: u128 = 575_036_072;
115+
}
116+
117+
/// Compute the total estimated fee that needs to be paid in `GLMR` by the sender when sending
118+
/// message from Moonbeam to Moonriver.
119+
pub fn estimate_moonbeam_to_moonriver_message_fee(
120+
moonriver_base_delivery_fee_in_umovr: Balance,
121+
) -> Balance {
122+
// Sender must pay:
123+
//
124+
// 1) an approximate cost of XCM execution (`ExportMessage` and surroundings) at Moonbeam;
125+
//
126+
// 2) the approximate cost of Polkadot -> Kusama message delivery transaction on Moonriver,
127+
// converted into KSMs using 1:5 conversion rate;
128+
//
129+
// 3) the approximate cost of Polkadot -> Kusama message confirmation transaction on Moonbeam.
130+
BaseXcmFeeInGlmr::get()
131+
.saturating_add(convert_from_umovr_to_uglmr(moonriver_base_delivery_fee_in_umovr))
132+
.saturating_add(BaseConfirmationFeeInGlmr::get())
133+
}
134+
135+
/// Compute the per-byte fee that needs to be paid in `GLMRs` by the sender when sending
136+
/// message from Moonbeam to Moonriver.
137+
pub fn estimate_moonbeam_to_moonriver_byte_fee() -> Balance {
138+
// the sender pays for the same byte twice:
139+
// 1) the first part comes from the HRMP, when message travels from Moonbeam to Moonriver;
140+
// 2) the second part is the payment for bytes of the message delivery transaction, which is
141+
// "mined" at Moonriver. Hence, we need to use byte fees from that chain and convert it to
142+
// GLMRs here.
143+
144+
// TODO: move this to a constants crate per runtime
145+
// Similar to: system_parachains_constants::polkadot::fee::TRANSACTION_BYTE_FEE
146+
const MOONRIVER_TRANSACTION_BYTE_FEE: Balance = 1_000_000_000;
147+
148+
convert_from_umovr_to_uglmr(MOONRIVER_TRANSACTION_BYTE_FEE)
149+
}
150+
151+
/// Convert from `uMOVRs` to `uGLMRs`.
152+
fn convert_from_umovr_to_uglmr(price_in_umovr: Balance) -> Balance {
153+
// assuming exchange rate is 5 MOVR for 1 GLMR
154+
let ksm_to_dot_economic_rate = FixedU128::from_rational(1, 5);
155+
156+
ksm_to_dot_economic_rate
157+
.saturating_mul(FixedU128::saturating_from_integer(price_in_umovr))
158+
.into_inner() /
159+
FixedU128::DIV
160+
}

0 commit comments

Comments
 (0)