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

Commit

Permalink
Transaction payment runtime api: query call info and fee details (#11819
Browse files Browse the repository at this point in the history
)

* Transaction payment RPC calls: query call info

* transaction payment pallet - runtime api - add query_call info and fee_details

* remove unused deps

* separate call runtime api

* undo fmt for unchanged code

* system config call bounded to GetDispatchInfo, drop Call generic for query call info/fee

* impl GetDispatchInfo for Extrinsics within runtime test-utils

* introduced runtime api methods accept encoded Call instead of Call type

* replace Bytes by Vec, docs for for new api, drop len argument, drop GetDispatchInfo bound from system_Config::Call

* clean up toml and extra impl for dropped bound

* panic if Call can not be decoded

* revert to 6d0ca79

* fmt and docs

* rustfmt
  • Loading branch information
muharem authored Aug 10, 2022
1 parent ef433a8 commit edeba3f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
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 @@ -467,6 +467,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 @@ -1965,6 +1965,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,
{
/// Query information of a dispatch class, weight, and fee of a given encoded `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`.
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`.
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

0 comments on commit edeba3f

Please sign in to comment.