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 5 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
18 changes: 18 additions & 0 deletions bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,24 @@ impl_runtime_apis! {
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<
Block,
Balance,
Call> for Runtime {
Copy link
Contributor

Choose a reason for hiding this comment

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

formatting is correct? 🫣

Copy link
Contributor Author

Choose a reason for hiding this comment

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

could not make rustfmt format this macro body, probably not supported rust-lang/rustfmt#3704
but this time just formatted it outside of macro body with the same indentation.

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
16 changes: 16 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,22 @@ 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)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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)
}
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<
Block,
Balance,
> for Runtime {
fn query_call_info(
opaque_call: Vec<u8>,
len: u32,
) -> RuntimeDispatchInfo<Balance> {
let call = Call::decode(&mut &*opaque_call);
TransactionPayment::query_call_info(call, len)
}

I think this is what basti wants from you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did it similar, but as suggested Basti, placed it within transaction-payment.

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
8 changes: 8 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,12 @@ 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
{
fn query_call_info(call: Call, len: u32) -> RuntimeDispatchInfo<Balance>;
fn query_call_fee_details(call: Call, len: u32) -> FeeDetails<Balance>;
}
}
70 changes: 70 additions & 0 deletions frame/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,39 @@ where
}
}

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

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

/// Query weight_to_fee of a given `Call`.
pub fn query_call_fee_details<Call: GetDispatchInfo>(
call: Call,
len: u32,
) -> FeeDetails<BalanceOf<T>>
where
T::Call: Dispatchable<Info = DispatchInfo>,
{
let dispatch_info = Call::get_dispatch_info(&call);

let tip = 0u32.into();

Self::compute_fee_details(len, &dispatch_info, tip)
muharem marked this conversation as resolved.
Show resolved Hide resolved
}

/// 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 +1239,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