mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 04:41:02 +00:00
Remove message fee + message send calls (#1642)
* remove message fee * it is compiling! * fixes + fmt * more cleanup * more cleanup * restore MessageDeliveryAndDispatchPayment since we'll need relayer rewards * started rational relayer removal * more removal * removed estimate fee subcommand * remove DispatchFeePayment * more removals * removed conversion rates && some metrics * - unneeded associated type * - OutboundMessageFee * fix benchmarks compilation * fmt * test + fix benchmarks * fix send message * clippy
This commit is contained in:
committed by
Bastian Köcher
parent
1217b2cf80
commit
8c845602cf
@@ -88,10 +88,8 @@ macro_rules! assert_bridge_messages_pallet_types(
|
||||
use static_assertions::assert_type_eq_all;
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, FromThisChainMessagePayload);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundMessageFee, BalanceOf<ThisChain<$bridge>>);
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, FromBridgedChainMessagePayload<CallOf<ThisChain<$bridge>>>);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundMessageFee, BalanceOf<BridgedChain<$bridge>>);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf<BridgedChain<$bridge>>);
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, BridgedChain<$bridge>);
|
||||
|
||||
@@ -24,26 +24,19 @@ use bp_header_chain::{HeaderChain, HeaderChainError};
|
||||
use bp_messages::{
|
||||
source_chain::LaneMessageVerifier,
|
||||
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages},
|
||||
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
||||
InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
|
||||
};
|
||||
use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Size, StorageProofChecker};
|
||||
use codec::{Decode, DecodeLimit, Encode, MaxEncodedLen};
|
||||
use codec::{Decode, DecodeLimit, Encode};
|
||||
use frame_support::{traits::Get, weights::Weight, RuntimeDebug};
|
||||
use hash_db::Hasher;
|
||||
use scale_info::TypeInfo;
|
||||
use sp_runtime::{
|
||||
traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedDiv, CheckedMul},
|
||||
FixedPointNumber, FixedPointOperand, FixedU128,
|
||||
};
|
||||
use sp_std::{convert::TryFrom, fmt::Debug, marker::PhantomData, vec::Vec};
|
||||
use sp_trie::StorageProof;
|
||||
use xcm::latest::prelude::*;
|
||||
|
||||
/// Bidirectional message bridge.
|
||||
pub trait MessageBridge {
|
||||
/// Relayer interest (in percents).
|
||||
const RELAYER_FEE_PERCENT: u32;
|
||||
|
||||
/// Identifier of this chain.
|
||||
const THIS_CHAIN_ID: ChainId;
|
||||
/// Identifier of the Bridged chain.
|
||||
@@ -59,60 +52,6 @@ pub trait MessageBridge {
|
||||
type BridgedChain: BridgedChainWithMessages;
|
||||
/// Bridged header chain.
|
||||
type BridgedHeaderChain: HeaderChain<UnderlyingChainOf<Self::BridgedChain>>;
|
||||
|
||||
/// Convert Bridged chain balance into This chain balance.
|
||||
fn bridged_balance_to_this_balance(
|
||||
bridged_balance: BalanceOf<BridgedChain<Self>>,
|
||||
bridged_to_this_conversion_rate_override: Option<FixedU128>,
|
||||
) -> BalanceOf<ThisChain<Self>>;
|
||||
}
|
||||
|
||||
/// Message related transaction parameters estimation.
|
||||
#[derive(RuntimeDebug)]
|
||||
pub struct MessageTransaction<Weight> {
|
||||
/// The estimated dispatch weight of the transaction.
|
||||
pub dispatch_weight: Weight,
|
||||
/// The estimated size of the encoded transaction.
|
||||
pub size: u32,
|
||||
}
|
||||
|
||||
/// Helper trait for estimating the size and weight of a single message delivery confirmation
|
||||
/// transaction.
|
||||
pub trait ConfirmationTransactionEstimation<Weight> {
|
||||
// Estimate size and weight of single message delivery confirmation transaction.
|
||||
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight>;
|
||||
}
|
||||
|
||||
/// Default implementation for `ConfirmationTransactionEstimation`.
|
||||
pub struct BasicConfirmationTransactionEstimation<
|
||||
AccountId: MaxEncodedLen,
|
||||
const MAX_CONFIRMATION_TX_WEIGHT: u64,
|
||||
const EXTRA_STORAGE_PROOF_SIZE: u32,
|
||||
const TX_EXTRA_BYTES: u32,
|
||||
>(PhantomData<AccountId>);
|
||||
|
||||
impl<
|
||||
AccountId: MaxEncodedLen,
|
||||
const MAX_CONFIRMATION_TX_WEIGHT: u64,
|
||||
const EXTRA_STORAGE_PROOF_SIZE: u32,
|
||||
const TX_EXTRA_BYTES: u32,
|
||||
> ConfirmationTransactionEstimation<Weight>
|
||||
for BasicConfirmationTransactionEstimation<
|
||||
AccountId,
|
||||
MAX_CONFIRMATION_TX_WEIGHT,
|
||||
EXTRA_STORAGE_PROOF_SIZE,
|
||||
TX_EXTRA_BYTES,
|
||||
>
|
||||
{
|
||||
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight> {
|
||||
let inbound_data_size = InboundLaneData::<AccountId>::encoded_size_hint_u32(1, 1);
|
||||
MessageTransaction {
|
||||
dispatch_weight: Weight::from_ref_time(MAX_CONFIRMATION_TX_WEIGHT),
|
||||
size: inbound_data_size
|
||||
.saturating_add(EXTRA_STORAGE_PROOF_SIZE)
|
||||
.saturating_add(TX_EXTRA_BYTES),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that provides the type of the underlying chain.
|
||||
@@ -127,9 +66,6 @@ pub trait ThisChainWithMessages: UnderlyingChainProvider {
|
||||
type RuntimeOrigin;
|
||||
/// Call type on the chain.
|
||||
type RuntimeCall: Encode + Decode;
|
||||
/// Helper for estimating the size and weight of a single message delivery confirmation
|
||||
/// transaction at this chain.
|
||||
type ConfirmationTransactionEstimation: ConfirmationTransactionEstimation<Weight>;
|
||||
|
||||
/// Do we accept message sent by given origin to given lane?
|
||||
fn is_message_accepted(origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool;
|
||||
@@ -138,14 +74,6 @@ pub trait ThisChainWithMessages: UnderlyingChainProvider {
|
||||
///
|
||||
/// Any messages over this limit, will be rejected.
|
||||
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce;
|
||||
|
||||
/// Estimate size and weight of single message delivery confirmation transaction at This chain.
|
||||
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight> {
|
||||
Self::ConfirmationTransactionEstimation::estimate_delivery_confirmation_transaction()
|
||||
}
|
||||
|
||||
/// Returns minimal transaction fee that must be paid for given transaction at This chain.
|
||||
fn transaction_payment(transaction: MessageTransaction<Weight>) -> BalanceOf<Self>;
|
||||
}
|
||||
|
||||
/// Bridged chain that has `pallet-bridge-messages` module.
|
||||
@@ -153,17 +81,6 @@ pub trait BridgedChainWithMessages: UnderlyingChainProvider {
|
||||
/// Returns `true` if message dispatch weight is withing expected limits. `false` means
|
||||
/// that the message is too heavy to be sent over the bridge and shall be rejected.
|
||||
fn verify_dispatch_weight(message_payload: &[u8]) -> bool;
|
||||
|
||||
/// Estimate size and weight of single message delivery transaction at the Bridged chain.
|
||||
fn estimate_delivery_transaction(
|
||||
message_payload: &[u8],
|
||||
include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: Weight,
|
||||
) -> MessageTransaction<Weight>;
|
||||
|
||||
/// Returns minimal transaction fee that must be paid for given transaction at the Bridged
|
||||
/// chain.
|
||||
fn transaction_payment(transaction: MessageTransaction<Weight>) -> BalanceOf<Self>;
|
||||
}
|
||||
|
||||
/// This chain in context of message bridge.
|
||||
@@ -188,33 +105,6 @@ pub type CallOf<C> = <C as ThisChainWithMessages>::RuntimeCall;
|
||||
/// Raw storage proof type (just raw trie nodes).
|
||||
pub type RawStorageProof = Vec<Vec<u8>>;
|
||||
|
||||
/// Compute fee of transaction at runtime where regular transaction payment pallet is being used.
|
||||
///
|
||||
/// The value of `multiplier` parameter is the expected value of
|
||||
/// `pallet_transaction_payment::NextFeeMultiplier` at the moment when transaction is submitted. If
|
||||
/// you're charging this payment in advance (and that's what happens with delivery and confirmation
|
||||
/// transaction in this crate), then there's a chance that the actual fee will be larger than what
|
||||
/// is paid in advance. So the value must be chosen carefully.
|
||||
pub fn transaction_payment<Balance: AtLeast32BitUnsigned + FixedPointOperand>(
|
||||
base_extrinsic_weight: Weight,
|
||||
per_byte_fee: Balance,
|
||||
multiplier: FixedU128,
|
||||
weight_to_fee: impl Fn(Weight) -> Balance,
|
||||
transaction: MessageTransaction<Weight>,
|
||||
) -> Balance {
|
||||
// base fee is charged for every tx
|
||||
let base_fee = weight_to_fee(base_extrinsic_weight);
|
||||
|
||||
// non-adjustable per-byte fee
|
||||
let len_fee = per_byte_fee.saturating_mul(Balance::from(transaction.size));
|
||||
|
||||
// the adjustable part of the fee
|
||||
let unadjusted_weight_fee = weight_to_fee(transaction.dispatch_weight);
|
||||
let adjusted_weight_fee = multiplier.saturating_mul_int(unadjusted_weight_fee);
|
||||
|
||||
base_fee.saturating_add(len_fee).saturating_add(adjusted_weight_fee)
|
||||
}
|
||||
|
||||
/// Sub-module that is declaring types required for processing This -> Bridged chain messages.
|
||||
pub mod source {
|
||||
use super::*;
|
||||
@@ -286,15 +176,9 @@ pub mod source {
|
||||
pub const TOO_MANY_PENDING_MESSAGES: &str = "Too many pending messages at the lane.";
|
||||
/// The error message returned from LaneMessageVerifier when call origin is mismatch.
|
||||
pub const BAD_ORIGIN: &str = "Unable to match the source origin to expected target origin.";
|
||||
/// The error message returned from LaneMessageVerifier when the message fee is too low.
|
||||
pub const TOO_LOW_FEE: &str = "Provided fee is below minimal threshold required by the lane.";
|
||||
|
||||
impl<B>
|
||||
LaneMessageVerifier<
|
||||
OriginOf<ThisChain<B>>,
|
||||
FromThisChainMessagePayload,
|
||||
BalanceOf<ThisChain<B>>,
|
||||
> for FromThisChainMessageVerifier<B>
|
||||
impl<B> LaneMessageVerifier<OriginOf<ThisChain<B>>, FromThisChainMessagePayload>
|
||||
for FromThisChainMessageVerifier<B>
|
||||
where
|
||||
B: MessageBridge,
|
||||
// matches requirements from the `frame_system::Config::Origin`
|
||||
@@ -306,10 +190,9 @@ pub mod source {
|
||||
|
||||
fn verify_message(
|
||||
submitter: &OriginOf<ThisChain<B>>,
|
||||
delivery_and_dispatch_fee: &BalanceOf<ThisChain<B>>,
|
||||
lane: &LaneId,
|
||||
lane_outbound_data: &OutboundLaneData,
|
||||
payload: &FromThisChainMessagePayload,
|
||||
_payload: &FromThisChainMessagePayload,
|
||||
) -> Result<(), Self::Error> {
|
||||
// reject message if lane is blocked
|
||||
if !ThisChain::<B>::is_message_accepted(submitter, lane) {
|
||||
@@ -325,17 +208,6 @@ pub mod source {
|
||||
return Err(TOO_MANY_PENDING_MESSAGES)
|
||||
}
|
||||
|
||||
let minimal_fee_in_this_tokens = estimate_message_dispatch_and_delivery_fee::<B>(
|
||||
payload,
|
||||
B::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
)?;
|
||||
|
||||
// compare with actual fee paid
|
||||
if *delivery_and_dispatch_fee < minimal_fee_in_this_tokens {
|
||||
return Err(TOO_LOW_FEE)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -376,52 +248,6 @@ pub mod source {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Estimate delivery and dispatch fee that must be paid for delivering a message to the Bridged
|
||||
/// chain.
|
||||
///
|
||||
/// The fee is paid in This chain Balance, but we use Bridged chain balance to avoid additional
|
||||
/// conversions. Returns `None` if overflow has happened.
|
||||
pub fn estimate_message_dispatch_and_delivery_fee<B: MessageBridge>(
|
||||
payload: &FromThisChainMessagePayload,
|
||||
relayer_fee_percent: u32,
|
||||
bridged_to_this_conversion_rate: Option<FixedU128>,
|
||||
) -> Result<BalanceOf<ThisChain<B>>, &'static str> {
|
||||
// the fee (in Bridged tokens) of all transactions that are made on the Bridged chain
|
||||
//
|
||||
// if we're going to pay dispatch fee at the target chain, then we don't include weight
|
||||
// of the message dispatch in the delivery transaction cost
|
||||
let delivery_transaction = BridgedChain::<B>::estimate_delivery_transaction(
|
||||
&payload.encode(),
|
||||
true,
|
||||
Weight::zero(),
|
||||
);
|
||||
let delivery_transaction_fee = BridgedChain::<B>::transaction_payment(delivery_transaction);
|
||||
|
||||
// the fee (in This tokens) of all transactions that are made on This chain
|
||||
let confirmation_transaction = ThisChain::<B>::estimate_delivery_confirmation_transaction();
|
||||
let confirmation_transaction_fee =
|
||||
ThisChain::<B>::transaction_payment(confirmation_transaction);
|
||||
|
||||
// minimal fee (in This tokens) is a sum of all required fees
|
||||
let minimal_fee = B::bridged_balance_to_this_balance(
|
||||
delivery_transaction_fee,
|
||||
bridged_to_this_conversion_rate,
|
||||
)
|
||||
.checked_add(&confirmation_transaction_fee);
|
||||
|
||||
// before returning, add extra fee that is paid to the relayer (relayer interest)
|
||||
minimal_fee
|
||||
.and_then(|fee|
|
||||
// having message with fee that is near the `Balance::MAX_VALUE` of the chain is
|
||||
// unlikely and should be treated as an error
|
||||
// => let's do multiplication first
|
||||
fee
|
||||
.checked_mul(&relayer_fee_percent.into())
|
||||
.and_then(|interest| interest.checked_div(&100u32.into()))
|
||||
.and_then(|interest| fee.checked_add(&interest)))
|
||||
.ok_or("Overflow when computing minimal required message delivery and dispatch fee")
|
||||
}
|
||||
|
||||
/// Verify proof of This -> Bridged chain messages delivery.
|
||||
///
|
||||
/// This function is used when Bridged chain is directly using GRANDPA finality. For Bridged
|
||||
@@ -462,7 +288,6 @@ pub mod source {
|
||||
/// Runtime message sender adapter.
|
||||
type MessageSender: bp_messages::source_chain::MessagesBridge<
|
||||
OriginOf<ThisChain<Self::MessageBridge>>,
|
||||
BalanceOf<ThisChain<Self::MessageBridge>>,
|
||||
FromThisChainMessagePayload,
|
||||
>;
|
||||
|
||||
@@ -484,7 +309,7 @@ pub mod source {
|
||||
BalanceOf<ThisChain<T::MessageBridge>>: Into<Fungibility>,
|
||||
OriginOf<ThisChain<T::MessageBridge>>: From<pallet_xcm::Origin>,
|
||||
{
|
||||
type Ticket = (BalanceOf<ThisChain<T::MessageBridge>>, FromThisChainMessagePayload);
|
||||
type Ticket = FromThisChainMessagePayload;
|
||||
|
||||
fn validate(
|
||||
dest: &mut Option<MultiLocation>,
|
||||
@@ -499,39 +324,22 @@ pub mod source {
|
||||
let route = T::build_destination();
|
||||
let msg = (route, msg.take().ok_or(SendError::MissingArgument)?).encode();
|
||||
|
||||
let fee = estimate_message_dispatch_and_delivery_fee::<T::MessageBridge>(
|
||||
&msg,
|
||||
T::MessageBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
);
|
||||
let fee = match fee {
|
||||
Ok(fee) => fee,
|
||||
Err(e) => {
|
||||
log::trace!(
|
||||
target: "runtime::bridge",
|
||||
"Failed to comupte fee for XCM message to {:?}: {:?}",
|
||||
T::MessageBridge::BRIDGED_CHAIN_ID,
|
||||
e,
|
||||
);
|
||||
*dest = Some(d);
|
||||
return Err(SendError::Transport(e))
|
||||
},
|
||||
};
|
||||
let fee_assets = MultiAssets::from((Here, fee));
|
||||
// let's just take fixed (out of thin air) fee per message in our test bridges
|
||||
// (this code won't be used in production anyway)
|
||||
let fee_assets = MultiAssets::from((Here, 1_000_000_u128));
|
||||
|
||||
Ok(((fee, msg), fee_assets))
|
||||
Ok((msg, fee_assets))
|
||||
}
|
||||
|
||||
fn deliver(ticket: Self::Ticket) -> Result<XcmHash, SendError> {
|
||||
use bp_messages::source_chain::MessagesBridge;
|
||||
|
||||
let lane = T::xcm_lane();
|
||||
let (fee, msg) = ticket;
|
||||
let msg = ticket;
|
||||
let result = T::MessageSender::send_message(
|
||||
pallet_xcm::Origin::from(MultiLocation::from(T::universal_location())).into(),
|
||||
lane,
|
||||
msg,
|
||||
fee,
|
||||
);
|
||||
result
|
||||
.map(|artifacts| {
|
||||
@@ -633,7 +441,7 @@ pub mod target {
|
||||
}
|
||||
|
||||
impl<B: MessageBridge, XcmExecutor, XcmWeigher, WeightCredit>
|
||||
MessageDispatch<AccountIdOf<ThisChain<B>>, BalanceOf<BridgedChain<B>>>
|
||||
MessageDispatch<AccountIdOf<ThisChain<B>>>
|
||||
for FromBridgedChainMessageDispatch<B, XcmExecutor, XcmWeigher, WeightCredit>
|
||||
where
|
||||
XcmExecutor: xcm::v3::ExecuteXcm<CallOf<ThisChain<B>>>,
|
||||
@@ -643,7 +451,7 @@ pub mod target {
|
||||
type DispatchPayload = FromBridgedChainMessagePayload<CallOf<ThisChain<B>>>;
|
||||
|
||||
fn dispatch_weight(
|
||||
message: &mut DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
|
||||
message: &mut DispatchMessage<Self::DispatchPayload>,
|
||||
) -> frame_support::weights::Weight {
|
||||
match message.data.payload {
|
||||
Ok(ref mut payload) => {
|
||||
@@ -673,7 +481,7 @@ pub mod target {
|
||||
|
||||
fn dispatch(
|
||||
_relayer_account: &AccountIdOf<ThisChain<B>>,
|
||||
message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
|
||||
message: DispatchMessage<Self::DispatchPayload>,
|
||||
) -> MessageDispatchResult {
|
||||
let message_id = (message.key.lane_id, message.key.nonce);
|
||||
let do_dispatch = move || -> sp_std::result::Result<Outcome, codec::Error> {
|
||||
@@ -738,7 +546,7 @@ pub mod target {
|
||||
pub fn verify_messages_proof<B: MessageBridge>(
|
||||
proof: FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>,
|
||||
messages_count: u32,
|
||||
) -> Result<ProvedMessages<Message<BalanceOf<BridgedChain<B>>>>, MessageProofError> {
|
||||
) -> Result<ProvedMessages<Message>, MessageProofError> {
|
||||
let FromBridgedChainMessagesProof {
|
||||
bridged_header_hash,
|
||||
storage_proof,
|
||||
@@ -779,11 +587,9 @@ pub mod target {
|
||||
let raw_message_data = parser
|
||||
.read_raw_message(&message_key)
|
||||
.ok_or(MessageProofError::MissingRequiredMessage)?;
|
||||
let message_data = MessageData::<BalanceOf<BridgedChain<B>>>::decode(
|
||||
&mut &raw_message_data[..],
|
||||
)
|
||||
.map_err(|_| MessageProofError::FailedToDecodeMessage)?;
|
||||
messages.push(Message { key: message_key, data: message_data });
|
||||
let payload = MessagePayload::decode(&mut &raw_message_data[..])
|
||||
.map_err(|_| MessageProofError::FailedToDecodeMessage)?;
|
||||
messages.push(Message { key: message_key, payload });
|
||||
}
|
||||
|
||||
// Now let's check if proof contains outbound lane state proof. It is optional, so
|
||||
@@ -885,11 +691,6 @@ mod tests {
|
||||
use sp_runtime::traits::{BlakeTwo256, Header as _};
|
||||
use std::cell::RefCell;
|
||||
|
||||
const DELIVERY_TRANSACTION_WEIGHT: Weight = Weight::from_ref_time(100);
|
||||
const DELIVERY_CONFIRMATION_TRANSACTION_WEIGHT: u64 = 100;
|
||||
const THIS_CHAIN_WEIGHT_TO_BALANCE_RATE: u32 = 2;
|
||||
const BRIDGED_CHAIN_WEIGHT_TO_BALANCE_RATE: u32 = 4;
|
||||
const BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE: u32 = 6;
|
||||
const BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT: usize = 5;
|
||||
const BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT: usize = 2048;
|
||||
const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024;
|
||||
@@ -900,7 +701,6 @@ mod tests {
|
||||
struct OnThisChainBridge;
|
||||
|
||||
impl MessageBridge for OnThisChainBridge {
|
||||
const RELAYER_FEE_PERCENT: u32 = 10;
|
||||
const THIS_CHAIN_ID: ChainId = *b"this";
|
||||
const BRIDGED_CHAIN_ID: ChainId = *b"brdg";
|
||||
const BRIDGED_MESSAGES_PALLET_NAME: &'static str = "";
|
||||
@@ -908,16 +708,6 @@ mod tests {
|
||||
type ThisChain = ThisChain;
|
||||
type BridgedChain = BridgedChain;
|
||||
type BridgedHeaderChain = BridgedHeaderChain;
|
||||
|
||||
fn bridged_balance_to_this_balance(
|
||||
bridged_balance: BridgedChainBalance,
|
||||
bridged_to_this_conversion_rate_override: Option<FixedU128>,
|
||||
) -> ThisChainBalance {
|
||||
let conversion_rate = bridged_to_this_conversion_rate_override
|
||||
.map(|r| r.to_float() as u32)
|
||||
.unwrap_or(BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE);
|
||||
bridged_balance as ThisChainBalance * conversion_rate as ThisChainBalance
|
||||
}
|
||||
}
|
||||
|
||||
/// Bridge that is deployed on BridgedChain and allows sending/receiving messages to/from
|
||||
@@ -926,7 +716,6 @@ mod tests {
|
||||
struct OnBridgedChainBridge;
|
||||
|
||||
impl MessageBridge for OnBridgedChainBridge {
|
||||
const RELAYER_FEE_PERCENT: u32 = 20;
|
||||
const THIS_CHAIN_ID: ChainId = *b"brdg";
|
||||
const BRIDGED_CHAIN_ID: ChainId = *b"this";
|
||||
const BRIDGED_MESSAGES_PALLET_NAME: &'static str = "";
|
||||
@@ -934,13 +723,6 @@ mod tests {
|
||||
type ThisChain = BridgedChain;
|
||||
type BridgedChain = ThisChain;
|
||||
type BridgedHeaderChain = ThisHeaderChain;
|
||||
|
||||
fn bridged_balance_to_this_balance(
|
||||
_this_balance: ThisChainBalance,
|
||||
_bridged_to_this_conversion_rate_override: Option<FixedU128>,
|
||||
) -> BridgedChainBalance {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -989,6 +771,7 @@ mod tests {
|
||||
fn max_extrinsic_size() -> u32 {
|
||||
BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE
|
||||
}
|
||||
|
||||
fn max_extrinsic_weight() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
@@ -1003,12 +786,6 @@ mod tests {
|
||||
impl ThisChainWithMessages for ThisChain {
|
||||
type RuntimeOrigin = ThisChainOrigin;
|
||||
type RuntimeCall = ThisChainCall;
|
||||
type ConfirmationTransactionEstimation = BasicConfirmationTransactionEstimation<
|
||||
ThisChainAccountId,
|
||||
{ DELIVERY_CONFIRMATION_TRANSACTION_WEIGHT },
|
||||
0,
|
||||
0,
|
||||
>;
|
||||
|
||||
fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool {
|
||||
lane == TEST_LANE_ID
|
||||
@@ -1017,31 +794,12 @@ mod tests {
|
||||
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
|
||||
MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE
|
||||
}
|
||||
|
||||
fn transaction_payment(transaction: MessageTransaction<Weight>) -> BalanceOf<Self> {
|
||||
transaction
|
||||
.dispatch_weight
|
||||
.saturating_mul(THIS_CHAIN_WEIGHT_TO_BALANCE_RATE as u64)
|
||||
.ref_time() as _
|
||||
}
|
||||
}
|
||||
|
||||
impl BridgedChainWithMessages for ThisChain {
|
||||
fn verify_dispatch_weight(_message_payload: &[u8]) -> bool {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
_message_payload: &[u8],
|
||||
_include_pay_dispatch_fee_cost: bool,
|
||||
_message_dispatch_weight: Weight,
|
||||
) -> MessageTransaction<Weight> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn transaction_payment(_transaction: MessageTransaction<Weight>) -> BalanceOf<Self> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
struct BridgedUnderlyingChain;
|
||||
@@ -1078,8 +836,6 @@ mod tests {
|
||||
impl ThisChainWithMessages for BridgedChain {
|
||||
type RuntimeOrigin = BridgedChainOrigin;
|
||||
type RuntimeCall = BridgedChainCall;
|
||||
type ConfirmationTransactionEstimation =
|
||||
BasicConfirmationTransactionEstimation<BridgedChainAccountId, 0, 0, 0>;
|
||||
|
||||
fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool {
|
||||
unreachable!()
|
||||
@@ -1088,10 +844,6 @@ mod tests {
|
||||
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn transaction_payment(_transaction: MessageTransaction<Weight>) -> BalanceOf<Self> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl BridgedChainWithMessages for BridgedChain {
|
||||
@@ -1099,24 +851,6 @@ mod tests {
|
||||
message_payload.len() >= BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT &&
|
||||
message_payload.len() <= BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT
|
||||
}
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
_message_payload: &[u8],
|
||||
_include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: Weight,
|
||||
) -> MessageTransaction<Weight> {
|
||||
MessageTransaction {
|
||||
dispatch_weight: DELIVERY_TRANSACTION_WEIGHT + message_dispatch_weight,
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn transaction_payment(transaction: MessageTransaction<Weight>) -> BalanceOf<Self> {
|
||||
transaction
|
||||
.dispatch_weight
|
||||
.saturating_mul(BRIDGED_CHAIN_WEIGHT_TO_BALANCE_RATE as u64)
|
||||
.ref_time() as _
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
@@ -1152,50 +886,11 @@ mod tests {
|
||||
vec![42]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_fee_is_checked_by_verifier() {
|
||||
const EXPECTED_MINIMAL_FEE: u32 = 2860;
|
||||
|
||||
// payload of the This -> Bridged chain message
|
||||
let payload = regular_outbound_message_payload();
|
||||
|
||||
// let's check if estimation matching hardcoded value
|
||||
assert_eq!(
|
||||
source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
),
|
||||
Ok(EXPECTED_MINIMAL_FEE),
|
||||
);
|
||||
|
||||
// and now check that the verifier checks the fee
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&1,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
),
|
||||
Err(source::TOO_LOW_FEE)
|
||||
);
|
||||
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&1_000_000,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
)
|
||||
.is_ok(),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_is_rejected_when_sent_using_disabled_lane() {
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&1_000_000,
|
||||
b"dsbl",
|
||||
&test_lane_outbound_data(),
|
||||
®ular_outbound_message_payload(),
|
||||
@@ -1209,7 +904,6 @@ mod tests {
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&1_000_000,
|
||||
TEST_LANE_ID,
|
||||
&OutboundLaneData {
|
||||
latest_received_nonce: 100,
|
||||
@@ -1267,7 +961,7 @@ mod tests {
|
||||
fn using_messages_proof<R>(
|
||||
nonces_end: MessageNonce,
|
||||
outbound_lane_data: Option<OutboundLaneData>,
|
||||
encode_message: impl Fn(MessageNonce, &MessageData<BridgedChainBalance>) -> Option<Vec<u8>>,
|
||||
encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option<Vec<u8>>,
|
||||
encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec<u8>,
|
||||
test: impl Fn(target::FromBridgedChainMessagesProof<H256>) -> R,
|
||||
) -> R {
|
||||
@@ -1366,10 +1060,9 @@ mod tests {
|
||||
|n, m| {
|
||||
let mut m = m.encode();
|
||||
if n == 5 {
|
||||
m = MessageData { fee: 0, payload: vec![0u8; 42] }.encode();
|
||||
m.truncate(2);
|
||||
m = vec![42]
|
||||
}
|
||||
Some(m.encode())
|
||||
Some(m)
|
||||
},
|
||||
encode_lane_data,
|
||||
|proof| target::verify_messages_proof::<OnThisChainBridge>(proof, 10),
|
||||
@@ -1464,7 +1157,7 @@ mod tests {
|
||||
}),
|
||||
messages: vec![Message {
|
||||
key: MessageKey { lane_id: *TEST_LANE_ID, nonce: 1 },
|
||||
data: MessageData { payload: vec![42], fee: 0 },
|
||||
payload: vec![42],
|
||||
}],
|
||||
},
|
||||
)]
|
||||
@@ -1483,53 +1176,4 @@ mod tests {
|
||||
Err(target::MessageProofError::MessagesCountMismatch),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_payment_works_with_zero_multiplier() {
|
||||
use sp_runtime::traits::Zero;
|
||||
|
||||
assert_eq!(
|
||||
transaction_payment(
|
||||
Weight::from_ref_time(100),
|
||||
10,
|
||||
FixedU128::zero(),
|
||||
|weight| weight.ref_time(),
|
||||
MessageTransaction { size: 50, dispatch_weight: Weight::from_ref_time(777) },
|
||||
),
|
||||
100 + 50 * 10,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_payment_works_with_non_zero_multiplier() {
|
||||
use sp_runtime::traits::One;
|
||||
|
||||
assert_eq!(
|
||||
transaction_payment::<u64>(
|
||||
Weight::from_ref_time(100),
|
||||
10,
|
||||
FixedU128::one(),
|
||||
|weight| weight.ref_time(),
|
||||
MessageTransaction { size: 50, dispatch_weight: Weight::from_ref_time(777) },
|
||||
),
|
||||
100 + 50 * 10 + 777,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversion_rate_override_works() {
|
||||
let payload = regular_outbound_message_payload();
|
||||
let regular_fee = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
);
|
||||
let overrided_fee = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
Some(FixedU128::from_float((BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE * 2) as f64)),
|
||||
);
|
||||
|
||||
assert!(regular_fee < overrided_fee);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn outbound_message_details<Runtime, MessagesPalletInstance>(
|
||||
lane: LaneId,
|
||||
begin: MessageNonce,
|
||||
end: MessageNonce,
|
||||
) -> Vec<OutboundMessageDetails<Runtime::OutboundMessageFee>>
|
||||
) -> Vec<OutboundMessageDetails>
|
||||
where
|
||||
Runtime: pallet_bridge_messages::Config<MessagesPalletInstance>,
|
||||
MessagesPalletInstance: 'static,
|
||||
@@ -40,10 +40,7 @@ where
|
||||
// dispatch message weight is always zero at the source chain, since we're paying for
|
||||
// dispatch at the target chain
|
||||
dispatch_weight: frame_support::weights::Weight::zero(),
|
||||
size: message_data.payload.len() as _,
|
||||
delivery_and_dispatch_fee: message_data.fee,
|
||||
// we're delivering XCM messages here, so fee is always paid at the target chain
|
||||
dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtTargetChain,
|
||||
size: message_data.len() as _,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
@@ -52,7 +49,7 @@ where
|
||||
/// Implementation of the `To*InboundLaneApi::message_details`.
|
||||
pub fn inbound_message_details<Runtime, MessagesPalletInstance>(
|
||||
lane: LaneId,
|
||||
messages: Vec<(MessagePayload, OutboundMessageDetails<Runtime::InboundMessageFee>)>,
|
||||
messages: Vec<(MessagePayload, OutboundMessageDetails)>,
|
||||
) -> Vec<InboundMessageDetails>
|
||||
where
|
||||
Runtime: pallet_bridge_messages::Config<MessagesPalletInstance>,
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
use crate::{
|
||||
messages::{
|
||||
source::{FromBridgedChainMessagesDeliveryProof, FromThisChainMessagePayload},
|
||||
target::FromBridgedChainMessagesProof,
|
||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||
AccountIdOf, BalanceOf, BridgedChain, CallOf, HashOf, MessageBridge, ThisChain,
|
||||
},
|
||||
messages_generation::{
|
||||
@@ -34,25 +33,12 @@ use bp_messages::storage_keys;
|
||||
use bp_runtime::{record_all_trie_keys, StorageProofSize};
|
||||
use codec::Encode;
|
||||
use frame_support::{dispatch::GetDispatchInfo, weights::Weight};
|
||||
use pallet_bridge_messages::benchmarking::{
|
||||
MessageDeliveryProofParams, MessageParams, MessageProofParams,
|
||||
};
|
||||
use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams};
|
||||
use sp_core::Hasher;
|
||||
use sp_runtime::traits::{Header, MaybeSerializeDeserialize, Zero};
|
||||
use sp_std::{fmt::Debug, prelude::*};
|
||||
use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, Recorder, TrieMut};
|
||||
|
||||
/// Prepare outbound message for the `send_message` call.
|
||||
pub fn prepare_outbound_message<B>(
|
||||
params: MessageParams<AccountIdOf<ThisChain<B>>>,
|
||||
) -> FromThisChainMessagePayload
|
||||
where
|
||||
B: MessageBridge,
|
||||
BalanceOf<ThisChain<B>>: From<u64>,
|
||||
{
|
||||
vec![0; params.size as usize]
|
||||
}
|
||||
|
||||
/// Prepare proof of messages for the `receive_messages_proof` call.
|
||||
///
|
||||
/// In addition to returning valid messages proof, environment is prepared to verify this message
|
||||
|
||||
@@ -31,7 +31,6 @@ use sp_runtime::transaction_validity::TransactionValidity;
|
||||
impl<
|
||||
BridgedHeaderHash,
|
||||
SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain<
|
||||
<T as Config<I>>::InboundMessageFee,
|
||||
MessagesProof = FromBridgedChainMessagesProof<BridgedHeaderHash>,
|
||||
>,
|
||||
TargetHeaderChain: bp_messages::source_chain::TargetHeaderChain<
|
||||
|
||||
@@ -18,23 +18,19 @@
|
||||
|
||||
#![cfg(any(feature = "runtime-benchmarks", test))]
|
||||
|
||||
use crate::messages::{BalanceOf, BridgedChain, HashOf, HasherOf, MessageBridge, RawStorageProof};
|
||||
use crate::messages::{BridgedChain, HashOf, HasherOf, MessageBridge, RawStorageProof};
|
||||
|
||||
use bp_messages::{
|
||||
storage_keys, LaneId, MessageData, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
|
||||
storage_keys, LaneId, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
|
||||
};
|
||||
use bp_runtime::{record_all_trie_keys, StorageProofSize};
|
||||
use codec::Encode;
|
||||
use sp_core::Hasher;
|
||||
use sp_runtime::traits::Zero;
|
||||
use sp_std::{ops::RangeInclusive, prelude::*};
|
||||
use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, Recorder, TrieMut};
|
||||
|
||||
/// Simple and correct message data encode function.
|
||||
pub(crate) fn encode_all_messages<B: Encode>(
|
||||
_: MessageNonce,
|
||||
m: &MessageData<B>,
|
||||
) -> Option<Vec<u8>> {
|
||||
pub(crate) fn encode_all_messages(_: MessageNonce, m: &MessagePayload) -> Option<Vec<u8>> {
|
||||
Some(m.encode())
|
||||
}
|
||||
|
||||
@@ -52,7 +48,7 @@ pub(crate) fn prepare_messages_storage_proof<B>(
|
||||
outbound_lane_data: Option<OutboundLaneData>,
|
||||
size: StorageProofSize,
|
||||
message_payload: MessagePayload,
|
||||
encode_message: impl Fn(MessageNonce, &MessageData<BalanceOf<BridgedChain<B>>>) -> Option<Vec<u8>>,
|
||||
encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option<Vec<u8>>,
|
||||
encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec<u8>,
|
||||
) -> (HashOf<BridgedChain<B>>, RawStorageProof)
|
||||
where
|
||||
@@ -71,12 +67,8 @@ where
|
||||
// insert messages
|
||||
for nonce in message_nonces {
|
||||
let message_key = MessageKey { lane_id: lane, nonce };
|
||||
let message_data = MessageData {
|
||||
fee: BalanceOf::<BridgedChain<B>>::zero(),
|
||||
payload: message_payload.clone(),
|
||||
};
|
||||
let message_data = match encode_message(nonce, &message_data) {
|
||||
Some(message_data) => message_data,
|
||||
let message_payload = match encode_message(nonce, &message_payload) {
|
||||
Some(message_payload) => message_payload,
|
||||
None => continue,
|
||||
};
|
||||
let storage_key = storage_keys::message_key(
|
||||
@@ -85,7 +77,7 @@ where
|
||||
message_key.nonce,
|
||||
)
|
||||
.0;
|
||||
trie.insert(&storage_key, &message_data)
|
||||
trie.insert(&storage_key, &message_payload)
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
storage_keys.push(storage_key);
|
||||
|
||||
Reference in New Issue
Block a user