mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 23:21:02 +00:00
pay dispatch fee at target chain (#911)
* pay dispatch fee at target chain
* refund unspent dispatch weight to messages relayer
* test that transfer actually happens
* pay-at-target-cchain benchmarks + fix previous benchmarks (invalid signature)
* include/exclude pay-dispatch-fee weight from delivery_and_dispatch_fee/delivery tx cost
* remvoe some redundant traces
* enum DispatchFeePayment {}
* typo
* update docs
* (revert removal of valid check)
* Update modules/messages/src/benchmarking.rs
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
* Update modules/messages/src/benchmarking.rs
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
* Update modules/messages/src/benchmarking.rs
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
* Update modules/messages/src/benchmarking.rs
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
Co-authored-by: Tomasz Drwięga <tomasz@parity.io>
This commit is contained in:
committed by
Bastian Köcher
parent
613803a15d
commit
20b7f341e1
@@ -862,6 +862,7 @@ impl_runtime_apis! {
|
||||
}
|
||||
|
||||
use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge};
|
||||
use bp_runtime::messages::DispatchFeePayment;
|
||||
use bridge_runtime_common::messages;
|
||||
use pallet_bridge_messages::benchmarking::{
|
||||
Pallet as MessagesBench,
|
||||
@@ -905,6 +906,7 @@ impl_runtime_apis! {
|
||||
weight: params.size as _,
|
||||
origin: dispatch_origin,
|
||||
call: message_payload,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
};
|
||||
(message, pallet_bridge_messages::benchmarking::MESSAGE_FEE.into())
|
||||
}
|
||||
@@ -921,7 +923,7 @@ impl_runtime_apis! {
|
||||
use codec::Encode;
|
||||
use frame_support::weights::GetDispatchInfo;
|
||||
use pallet_bridge_messages::storage_keys;
|
||||
use sp_runtime::traits::Header;
|
||||
use sp_runtime::traits::{Header, IdentifyAccount};
|
||||
|
||||
let remark = match params.size {
|
||||
MessagesProofSize::Minimal(ref size) => vec![0u8; *size as _],
|
||||
@@ -934,12 +936,19 @@ impl_runtime_apis! {
|
||||
let (rialto_raw_public, rialto_raw_signature) = ed25519_sign(
|
||||
&call,
|
||||
&millau_account_id,
|
||||
VERSION.spec_version,
|
||||
bp_runtime::MILLAU_CHAIN_ID,
|
||||
bp_runtime::RIALTO_CHAIN_ID,
|
||||
);
|
||||
let rialto_public = MultiSigner::Ed25519(sp_core::ed25519::Public::from_raw(rialto_raw_public));
|
||||
let rialto_signature = MultiSignature::Ed25519(sp_core::ed25519::Signature::from_raw(
|
||||
rialto_raw_signature,
|
||||
));
|
||||
|
||||
if params.dispatch_fee_payment == DispatchFeePayment::AtTargetChain {
|
||||
Self::endow_account(&rialto_public.clone().into_account());
|
||||
}
|
||||
|
||||
let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key::<
|
||||
Runtime,
|
||||
<Millau as ChainWithMessages>::MessagesInstance,
|
||||
@@ -960,6 +969,7 @@ impl_runtime_apis! {
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let dispatch_fee_payment = params.dispatch_fee_payment.clone();
|
||||
prepare_message_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, (), _, _, _>(
|
||||
params,
|
||||
make_millau_message_key,
|
||||
@@ -978,6 +988,7 @@ impl_runtime_apis! {
|
||||
rialto_public,
|
||||
rialto_signature,
|
||||
),
|
||||
dispatch_fee_payment,
|
||||
call: call.encode(),
|
||||
}.encode(),
|
||||
)
|
||||
@@ -1010,6 +1021,18 @@ impl_runtime_apis! {
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn is_message_dispatched(nonce: bp_messages::MessageNonce) -> bool {
|
||||
frame_system::Pallet::<Runtime>::events()
|
||||
.into_iter()
|
||||
.map(|event_record| event_record.event)
|
||||
.any(|event| matches!(
|
||||
event,
|
||||
Event::pallet_bridge_dispatch(pallet_bridge_dispatch::Event::<Runtime, _>::MessageDispatched(
|
||||
_, ([0, 0, 0, 0], nonce_from_event), _,
|
||||
)) if nonce_from_event == nonce
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
add_benchmark!(
|
||||
@@ -1105,6 +1128,7 @@ mod tests {
|
||||
bp_rialto::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT,
|
||||
bp_rialto::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT,
|
||||
bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
|
||||
bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT,
|
||||
);
|
||||
|
||||
let max_incoming_message_proof_size = bp_millau::EXTRA_STORAGE_PROOF_SIZE.saturating_add(
|
||||
|
||||
@@ -58,6 +58,7 @@ pub type FromMillauEncodedCall = messages::target::FromBridgedChainEncodedMessag
|
||||
pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
|
||||
WithMillauMessageBridge,
|
||||
crate::Runtime,
|
||||
pallet_balances::Pallet<Runtime>,
|
||||
pallet_bridge_dispatch::DefaultInstance,
|
||||
>;
|
||||
|
||||
@@ -172,6 +173,7 @@ impl messages::BridgedChainWithMessages for Millau {
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
message_payload: &[u8],
|
||||
include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: Weight,
|
||||
) -> MessageTransaction<Weight> {
|
||||
let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX);
|
||||
@@ -182,6 +184,11 @@ impl messages::BridgedChainWithMessages for Millau {
|
||||
dispatch_weight: extra_bytes_in_payload
|
||||
.saturating_mul(bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT)
|
||||
.saturating_add(bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT)
|
||||
.saturating_sub(if include_pay_dispatch_fee_cost {
|
||||
0
|
||||
} else {
|
||||
bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT
|
||||
})
|
||||
.saturating_add(message_dispatch_weight),
|
||||
size: message_payload_len
|
||||
.saturating_add(bp_rialto::EXTRA_STORAGE_PROOF_SIZE)
|
||||
@@ -258,3 +265,87 @@ impl MessagesParameter for RialtoToMillauMessagesParameter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{AccountId, Call, ExistentialDeposit, Runtime, SystemCall, SystemConfig, VERSION};
|
||||
use bp_message_dispatch::CallOrigin;
|
||||
use bp_messages::{
|
||||
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
|
||||
MessageKey,
|
||||
};
|
||||
use bp_runtime::{derive_account_id, messages::DispatchFeePayment, SourceAccount};
|
||||
use bridge_runtime_common::messages::target::{FromBridgedChainEncodedMessageCall, FromBridgedChainMessagePayload};
|
||||
use frame_support::{
|
||||
traits::Currency,
|
||||
weights::{GetDispatchInfo, WeightToFeePolynomial},
|
||||
};
|
||||
use sp_runtime::traits::Convert;
|
||||
|
||||
#[test]
|
||||
fn transfer_happens_when_dispatch_fee_is_paid_at_target_chain() {
|
||||
// this test actually belongs to the `bridge-runtime-common` crate, but there we have no
|
||||
// mock runtime. Making another one there just for this test, given that both crates
|
||||
// live n single repo is an overkill
|
||||
let mut ext: sp_io::TestExternalities = SystemConfig::default().build_storage::<Runtime>().unwrap().into();
|
||||
ext.execute_with(|| {
|
||||
let bridge = MILLAU_CHAIN_ID;
|
||||
let call: Call = SystemCall::remark(vec![]).into();
|
||||
let dispatch_weight = call.get_dispatch_info().weight;
|
||||
let dispatch_fee = <Runtime as pallet_transaction_payment::Config>::WeightToFee::calc(&dispatch_weight);
|
||||
assert!(dispatch_fee > 0);
|
||||
|
||||
// create relayer account with minimal balance
|
||||
let relayer_account: AccountId = [1u8; 32].into();
|
||||
let initial_amount = ExistentialDeposit::get();
|
||||
let _ = <pallet_balances::Pallet<Runtime> as Currency<AccountId>>::deposit_creating(
|
||||
&relayer_account,
|
||||
initial_amount,
|
||||
);
|
||||
|
||||
// create dispatch account with minimal balance + dispatch fee
|
||||
let dispatch_account = derive_account_id::<<Runtime as pallet_bridge_dispatch::Config>::SourceChainAccountId>(
|
||||
bridge,
|
||||
SourceAccount::Root,
|
||||
);
|
||||
let dispatch_account =
|
||||
<Runtime as pallet_bridge_dispatch::Config>::AccountIdConverter::convert(dispatch_account);
|
||||
let _ = <pallet_balances::Pallet<Runtime> as Currency<AccountId>>::deposit_creating(
|
||||
&dispatch_account,
|
||||
initial_amount + dispatch_fee,
|
||||
);
|
||||
|
||||
// dispatch message with intention to pay dispatch fee at the target chain
|
||||
FromMillauMessageDispatch::dispatch(
|
||||
&relayer_account,
|
||||
DispatchMessage {
|
||||
key: MessageKey {
|
||||
lane_id: Default::default(),
|
||||
nonce: 0,
|
||||
},
|
||||
data: DispatchMessageData {
|
||||
payload: Ok(FromBridgedChainMessagePayload::<WithMillauMessageBridge> {
|
||||
spec_version: VERSION.spec_version,
|
||||
weight: dispatch_weight,
|
||||
origin: CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
call: FromBridgedChainEncodedMessageCall::new(call.encode()),
|
||||
}),
|
||||
fee: 1,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// ensure that fee has been transferred from dispatch to relayer account
|
||||
assert_eq!(
|
||||
<pallet_balances::Pallet<Runtime> as Currency<AccountId>>::free_balance(&relayer_account),
|
||||
initial_amount + dispatch_fee,
|
||||
);
|
||||
assert_eq!(
|
||||
<pallet_balances::Pallet<Runtime> as Currency<AccountId>>::free_balance(&dispatch_account),
|
||||
initial_amount,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user