Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit 2d6356a

Browse files
Integrate fee-market to FromThisChainMessageVerifier (#189)
* Run ignored crate * Fix tests * Add features * Fix compile
1 parent 4c0f658 commit 2d6356a

4 files changed

Lines changed: 36 additions & 208 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
- bp-pangolin-parachain
2424
- bp-rococo
2525
- bp-darwinia-core
26+
- bridge-runtime-common
2627
steps:
2728
- uses: actions/checkout@v2
2829
- name: Check ${{ matrix.package }}

Cargo.lock

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

bin/runtime-common/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ bp-runtime = { path = "../../primitives/runtime", default-features = false }
2222
pallet-bridge-dispatch = { path = "../../modules/dispatch", default-features = false }
2323
pallet-bridge-grandpa = { path = "../../modules/grandpa", default-features = false }
2424
pallet-bridge-messages = { path = "../../modules/messages", default-features = false }
25+
pallet-fee-market = { path = "../../modules/fee-market", default-features = false }
2526

2627
# Substrate dependencies
2728

@@ -50,6 +51,7 @@ std = [
5051
"pallet-bridge-dispatch/std",
5152
"pallet-bridge-grandpa/std",
5253
"pallet-bridge-messages/std",
54+
"pallet-fee-market/std",
5355
"pallet-transaction-payment/std",
5456
"scale-info/std",
5557
"sp-api/std",

bin/runtime-common/src/messages.rs

Lines changed: 32 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ pub mod source {
269269
/// dispatch origin;
270270
/// - check that the sender has paid enough funds for both message delivery and dispatch.
271271
#[derive(RuntimeDebug)]
272-
pub struct FromThisChainMessageVerifier<B>(PhantomData<B>);
272+
pub struct FromThisChainMessageVerifier<B, F, I>(PhantomData<(B, F, I)>);
273273

274274
/// The error message returned from LaneMessageVerifier when outbound lane is disabled.
275275
pub const MESSAGE_REJECTED_BY_OUTBOUND_LANE: &str =
@@ -282,23 +282,27 @@ pub mod source {
282282
/// The error message returned from LaneMessageVerifier when the message fee is too low.
283283
pub const TOO_LOW_FEE: &str = "Provided fee is below minimal threshold required by the lane.";
284284

285-
impl<B>
285+
impl<B, F, I>
286286
LaneMessageVerifier<
287287
OriginOf<ThisChain<B>>,
288288
AccountIdOf<ThisChain<B>>,
289289
FromThisChainMessagePayload<B>,
290290
BalanceOf<ThisChain<B>>,
291-
> for FromThisChainMessageVerifier<B>
291+
> for FromThisChainMessageVerifier<B, F, I>
292292
where
293293
B: MessageBridge,
294+
F: pallet_fee_market::Config<I>,
295+
I: 'static,
294296
// matches requirements from the `frame_system::Config::Origin`
295297
OriginOf<ThisChain<B>>: Clone
296298
+ Into<Result<frame_system::RawOrigin<AccountIdOf<ThisChain<B>>>, OriginOf<ThisChain<B>>>>,
297299
AccountIdOf<ThisChain<B>>: PartialEq + Clone,
300+
pallet_fee_market::BalanceOf<F, I>: From<BalanceOf<ThisChain<B>>>,
298301
{
299302
type Error = &'static str;
300303

301304
#[allow(clippy::single_match)]
305+
#[cfg(not(feature = "runtime-benchmarks"))]
302306
fn verify_message(
303307
submitter: &OriginOf<ThisChain<B>>,
304308
delivery_and_dispatch_fee: &BalanceOf<ThisChain<B>>,
@@ -338,19 +342,35 @@ pub mod source {
338342
// is valid, or not.
339343
};
340344

341-
let minimal_fee_in_this_tokens = estimate_message_dispatch_and_delivery_fee::<B>(
342-
payload,
343-
B::RELAYER_FEE_PERCENT,
344-
None,
345-
)?;
345+
// Do the delivery_and_dispatch_fee. We assume that the delivery and dispatch fee always
346+
// greater than the fee market provided fee.
347+
if let Some(market_fee) = pallet_fee_market::Pallet::<F, I>::market_fee() {
348+
let message_fee: pallet_fee_market::BalanceOf<F, I> =
349+
(*delivery_and_dispatch_fee).into();
346350

347-
// compare with actual fee paid
348-
if *delivery_and_dispatch_fee < minimal_fee_in_this_tokens {
349-
return Err(TOO_LOW_FEE);
351+
// compare with actual fee paid
352+
if message_fee < market_fee {
353+
return Err(TOO_LOW_FEE);
354+
}
355+
} else {
356+
const NO_MARKET_FEE: &str = "The fee market are not ready for accepting messages.";
357+
358+
return Err(NO_MARKET_FEE);
350359
}
351360

352361
Ok(())
353362
}
363+
364+
#[cfg(feature = "runtime-benchmarks")]
365+
fn verify_message(
366+
_submitter: &OriginOf<ThisChain<B>>,
367+
_delivery_and_dispatch_fee: &BalanceOf<ThisChain<B>>,
368+
_lane: &LaneId,
369+
_lane_outbound_data: &OutboundLaneData,
370+
_payload: &FromThisChainMessagePayload<B>,
371+
) -> Result<(), Self::Error> {
372+
Ok(())
373+
}
354374
}
355375

356376
/// Return maximal message size of This -> Bridged chain message.
@@ -813,15 +833,14 @@ pub mod target {
813833
#[cfg(test)]
814834
mod tests {
815835
use super::*;
836+
use bp_runtime::messages::DispatchFeePayment;
816837
use codec::{Decode, Encode};
817838
use frame_support::weights::Weight;
818839
use std::ops::RangeInclusive;
819840

820841
const DELIVERY_TRANSACTION_WEIGHT: Weight = 100;
821-
const DELIVERY_CONFIRMATION_TRANSACTION_WEIGHT: Weight = 100;
822842
const THIS_CHAIN_WEIGHT_TO_BALANCE_RATE: Weight = 2;
823843
const BRIDGED_CHAIN_WEIGHT_TO_BALANCE_RATE: Weight = 4;
824-
const BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE: u32 = 6;
825844
const BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT: Weight = 2048;
826845
const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024;
827846

@@ -1107,10 +1126,6 @@ mod tests {
11071126
}
11081127
}
11091128

1110-
fn test_lane_outbound_data() -> OutboundLaneData {
1111-
OutboundLaneData::default()
1112-
}
1113-
11141129
#[test]
11151130
fn message_from_bridged_chain_is_decoded() {
11161131
// the message is encoded on the bridged chain
@@ -1148,180 +1163,6 @@ mod tests {
11481163
const TEST_LANE_ID: &LaneId = b"test";
11491164
const MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE: MessageNonce = 32;
11501165

1151-
fn regular_outbound_message_payload() -> source::FromThisChainMessagePayload<OnThisChainBridge>
1152-
{
1153-
source::FromThisChainMessagePayload::<OnThisChainBridge> {
1154-
spec_version: 1,
1155-
weight: 100,
1156-
origin: bp_message_dispatch::CallOrigin::SourceRoot,
1157-
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
1158-
call: vec![42],
1159-
}
1160-
}
1161-
1162-
#[test]
1163-
fn message_fee_is_checked_by_verifier() {
1164-
const EXPECTED_MINIMAL_FEE: u32 = 5500;
1165-
1166-
// payload of the This -> Bridged chain message
1167-
let payload = regular_outbound_message_payload();
1168-
1169-
// let's check if estimation matching hardcoded value
1170-
assert_eq!(
1171-
source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
1172-
&payload,
1173-
OnThisChainBridge::RELAYER_FEE_PERCENT,
1174-
None,
1175-
),
1176-
Ok(ThisChainBalance(EXPECTED_MINIMAL_FEE)),
1177-
);
1178-
1179-
// let's check if estimation is less than hardcoded, if dispatch is paid at target chain
1180-
let mut payload_with_pay_on_target = regular_outbound_message_payload();
1181-
payload_with_pay_on_target.dispatch_fee_payment = DispatchFeePayment::AtTargetChain;
1182-
let fee_at_source =
1183-
source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
1184-
&payload_with_pay_on_target,
1185-
OnThisChainBridge::RELAYER_FEE_PERCENT,
1186-
None,
1187-
)
1188-
.expect(
1189-
"estimate_message_dispatch_and_delivery_fee failed for pay-at-target-chain message",
1190-
);
1191-
assert!(
1192-
fee_at_source < EXPECTED_MINIMAL_FEE.into(),
1193-
"Computed fee {:?} without prepaid dispatch must be less than the fee with prepaid dispatch {}",
1194-
fee_at_source,
1195-
EXPECTED_MINIMAL_FEE,
1196-
);
1197-
1198-
// and now check that the verifier checks the fee
1199-
assert_eq!(
1200-
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1201-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
1202-
&ThisChainBalance(1),
1203-
TEST_LANE_ID,
1204-
&test_lane_outbound_data(),
1205-
&payload,
1206-
),
1207-
Err(source::TOO_LOW_FEE)
1208-
);
1209-
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1210-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
1211-
&ThisChainBalance(1_000_000),
1212-
TEST_LANE_ID,
1213-
&test_lane_outbound_data(),
1214-
&payload,
1215-
)
1216-
.is_ok(),);
1217-
}
1218-
1219-
#[test]
1220-
fn should_disallow_root_calls_from_regular_accounts() {
1221-
// payload of the This -> Bridged chain message
1222-
let payload = source::FromThisChainMessagePayload::<OnThisChainBridge> {
1223-
spec_version: 1,
1224-
weight: 100,
1225-
origin: bp_message_dispatch::CallOrigin::SourceRoot,
1226-
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
1227-
call: vec![42],
1228-
};
1229-
1230-
// and now check that the verifier checks the fee
1231-
assert_eq!(
1232-
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1233-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Signed(ThisChainAccountId(0)))),
1234-
&ThisChainBalance(1_000_000),
1235-
TEST_LANE_ID,
1236-
&test_lane_outbound_data(),
1237-
&payload,
1238-
),
1239-
Err(source::BAD_ORIGIN)
1240-
);
1241-
assert_eq!(
1242-
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1243-
&ThisChainOrigin(Ok(frame_system::RawOrigin::None)),
1244-
&ThisChainBalance(1_000_000),
1245-
TEST_LANE_ID,
1246-
&test_lane_outbound_data(),
1247-
&payload,
1248-
),
1249-
Err(source::BAD_ORIGIN)
1250-
);
1251-
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1252-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
1253-
&ThisChainBalance(1_000_000),
1254-
TEST_LANE_ID,
1255-
&test_lane_outbound_data(),
1256-
&payload,
1257-
)
1258-
.is_ok(),);
1259-
}
1260-
1261-
#[test]
1262-
fn should_verify_source_and_target_origin_matching() {
1263-
// payload of the This -> Bridged chain message
1264-
let payload = source::FromThisChainMessagePayload::<OnThisChainBridge> {
1265-
spec_version: 1,
1266-
weight: 100,
1267-
origin: bp_message_dispatch::CallOrigin::SourceAccount(ThisChainAccountId(1)),
1268-
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
1269-
call: vec![42],
1270-
};
1271-
1272-
// and now check that the verifier checks the fee
1273-
assert_eq!(
1274-
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1275-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Signed(ThisChainAccountId(0)))),
1276-
&ThisChainBalance(1_000_000),
1277-
TEST_LANE_ID,
1278-
&test_lane_outbound_data(),
1279-
&payload,
1280-
),
1281-
Err(source::BAD_ORIGIN)
1282-
);
1283-
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1284-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Signed(ThisChainAccountId(1)))),
1285-
&ThisChainBalance(1_000_000),
1286-
TEST_LANE_ID,
1287-
&test_lane_outbound_data(),
1288-
&payload,
1289-
)
1290-
.is_ok(),);
1291-
}
1292-
1293-
#[test]
1294-
fn message_is_rejected_when_sent_using_disabled_lane() {
1295-
assert_eq!(
1296-
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1297-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
1298-
&ThisChainBalance(1_000_000),
1299-
b"dsbl",
1300-
&test_lane_outbound_data(),
1301-
&regular_outbound_message_payload(),
1302-
),
1303-
Err(source::MESSAGE_REJECTED_BY_OUTBOUND_LANE)
1304-
);
1305-
}
1306-
1307-
#[test]
1308-
fn message_is_rejected_when_there_are_too_many_pending_messages_at_outbound_lane() {
1309-
assert_eq!(
1310-
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
1311-
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
1312-
&ThisChainBalance(1_000_000),
1313-
TEST_LANE_ID,
1314-
&OutboundLaneData {
1315-
latest_received_nonce: 100,
1316-
latest_generated_nonce: 100 + MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE + 1,
1317-
..Default::default()
1318-
},
1319-
&regular_outbound_message_payload(),
1320-
),
1321-
Err(source::TOO_MANY_PENDING_MESSAGES)
1322-
);
1323-
}
1324-
13251166
#[test]
13261167
fn verify_chain_message_rejects_message_with_too_small_declared_weight() {
13271168
assert!(source::verify_chain_message::<OnThisChainBridge>(
@@ -1650,21 +1491,4 @@ mod tests {
16501491
100 + 50 * 10 + 777,
16511492
);
16521493
}
1653-
1654-
#[test]
1655-
fn conversion_rate_override_works() {
1656-
let payload = regular_outbound_message_payload();
1657-
let regular_fee = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
1658-
&payload,
1659-
OnThisChainBridge::RELAYER_FEE_PERCENT,
1660-
None,
1661-
);
1662-
let overrided_fee = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
1663-
&payload,
1664-
OnThisChainBridge::RELAYER_FEE_PERCENT,
1665-
Some(FixedU128::from_float((BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE * 2) as f64)),
1666-
);
1667-
1668-
assert!(regular_fee < overrided_fee);
1669-
}
16701494
}

0 commit comments

Comments
 (0)