Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Transaction payment runtime api: query call info and fee details #11819

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,23 @@ impl_runtime_apis! {
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, Call>
for Runtime
{
fn query_call_info(
call: Call,
len: u32,
) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
TransactionPayment::query_call_info(call, len)
}
fn query_call_fee_details(
call: Call,
len: u32,
) -> pallet_transaction_payment::FeeDetails<Balance> {
TransactionPayment::query_call_fee_details(call, len)
}
}

#[cfg(feature = "runtime-benchmarks")]
impl frame_benchmarking::Benchmark<Block> for Runtime {
fn benchmark_metadata(extra: bool) -> (
Expand Down
11 changes: 11 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,17 @@ impl_runtime_apis! {
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, Call>
for Runtime
{
fn query_call_info(call: Call, len: u32) -> RuntimeDispatchInfo<Balance> {
TransactionPayment::query_call_info(call, len)
}
fn query_call_fee_details(call: Call, len: u32) -> FeeDetails<Balance> {
TransactionPayment::query_call_fee_details(call, len)
}
}

impl pallet_mmr::primitives::MmrApi<
Block,
mmr::Hash,
Expand Down
12 changes: 12 additions & 0 deletions frame/transaction-payment/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,16 @@ sp_api::decl_runtime_apis! {
fn query_info(uxt: Block::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance>;
fn query_fee_details(uxt: Block::Extrinsic, len: u32) -> FeeDetails<Balance>;
}

pub trait TransactionPaymentCallApi<Balance, Call>
where
Balance: Codec + MaybeDisplay,
Call: Codec,
muharem marked this conversation as resolved.
Show resolved Hide resolved
{
/// Query information of a dispatch class, weight, and fee of a given encoded `Call`.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed panic, since the implementation itself is not supposed to panic, only upstream state_call

fn query_call_info(call: Call, len: u32) -> RuntimeDispatchInfo<Balance>;

/// Query fee details of a given encoded `Call`.
fn query_call_fee_details(call: Call, len: u32) -> FeeDetails<Balance>;
}
}
63 changes: 63 additions & 0 deletions frame/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,32 @@ where
}
}

/// Query information of a dispatch class, weight, and fee of a given encoded `Call`.
muharem marked this conversation as resolved.
Show resolved Hide resolved
pub fn query_call_info(call: T::Call, len: u32) -> RuntimeDispatchInfo<BalanceOf<T>>
where
T::Call: Dispatchable<Info = DispatchInfo> + GetDispatchInfo,
{
let dispatch_info = <T::Call as GetDispatchInfo>::get_dispatch_info(&call);
let DispatchInfo { weight, class, .. } = dispatch_info;

RuntimeDispatchInfo {
weight,
class,
partial_fee: Self::compute_fee(len, &dispatch_info, 0u32.into()),
}
}

/// Query fee details of a given encoded `Call`.
muharem marked this conversation as resolved.
Show resolved Hide resolved
pub fn query_call_fee_details(call: T::Call, len: u32) -> FeeDetails<BalanceOf<T>>
where
T::Call: Dispatchable<Info = DispatchInfo> + GetDispatchInfo,
{
let dispatch_info = <T::Call as GetDispatchInfo>::get_dispatch_info(&call);
let tip = 0u32.into();

Self::compute_fee_details(len, &dispatch_info, tip)
}

/// Compute the final fee value for a particular transaction.
pub fn compute_fee(len: u32, info: &DispatchInfoOf<T::Call>, tip: BalanceOf<T>) -> BalanceOf<T>
where
Expand Down Expand Up @@ -1206,6 +1232,43 @@ mod tests {
});
}

#[test]
fn query_call_info_and_fee_details_works() {
let call = Call::Balances(BalancesCall::transfer { dest: 2, value: 69 });
let info = call.get_dispatch_info();
let encoded_call = call.encode();
let len = encoded_call.len() as u32;

ExtBuilder::default().base_weight(5).weight_fee(2).build().execute_with(|| {
// all fees should be x1.5
<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));

assert_eq!(
TransactionPayment::query_call_info(call.clone(), len),
RuntimeDispatchInfo {
weight: info.weight,
class: info.class,
partial_fee: 5 * 2 /* base * weight_fee */
+ len as u64 /* len * 1 */
+ info.weight.min(BlockWeights::get().max_block) as u64 * 2 * 3 / 2 /* weight */
},
);

assert_eq!(
TransactionPayment::query_call_fee_details(call, len),
FeeDetails {
inclusion_fee: Some(InclusionFee {
base_fee: 5 * 2, /* base * weight_fee */
len_fee: len as u64, /* len * 1 */
adjusted_weight_fee: info.weight.min(BlockWeights::get().max_block) as u64 *
2 * 3 / 2 /* weight * weight_fee * multipler */
}),
tip: 0,
},
);
});
}

#[test]
fn compute_fee_works_without_multiplier() {
ExtBuilder::default()
Expand Down