Add payment_queryFeeDetails RPC (#7692)

* Return FeeDetails in compute_fee_raw()

* Add payment_queryDetails rpc

* Simplify serde attribute a bit

* Fix line width check

* Use saturating_add()

* Move transaction payment rpc types to types.rs

* Add file header

* Fix test

* Update Cargo.lock

* Nit

* Apply the review suggestions

* .

* .

* Fix serde

* Fix rust doc

* .

* Update frame/transaction-payment/src/types.rs

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>

* Use NumberOrHex in fee details RPC

* Address review feedback

* Nits

* Update some docs

* Address review

* Update frame/transaction-payment/src/types.rs

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>

* Happy 2021

* Nit

* Address code review

* Remove needless bound

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
Liu-Cheng Xu
2021-01-14 19:43:53 +08:00
committed by GitHub
parent f7fccb3122
commit 65569620c2
11 changed files with 322 additions and 137 deletions
+66 -35
View File
@@ -19,11 +19,25 @@
//!
//! This module provides the basic logic needed to pay the absolute minimum amount needed for a
//! transaction to be included. This includes:
//! - _base fee_: This is the minimum amount a user pays for a transaction. It is declared
//! as a base _weight_ in the runtime and converted to a fee using `WeightToFee`.
//! - _weight fee_: A fee proportional to amount of weight a transaction consumes.
//! - _length fee_: A fee proportional to the encoded length of the transaction.
//! - _tip_: An optional tip. Tip increases the priority of the transaction, giving it a higher
//! chance to be included by the transaction queue.
//!
//! The base fee and adjusted weight and length fees constitute the _inclusion fee_, which is
//! the minimum fee for a transaction to be included in a block.
//!
//! The formula of final fee:
//! ```ignore
//! inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee];
//! final_fee = inclusion_fee + tip;
//! ```
//!
//! - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on
//! the congestion of the network.
//!
//! Additionally, this module allows one to configure:
//! - The mapping between one unit of weight to one unit of fee via [`Config::WeightToFee`].
//! - A means of updating the fee for the next block, via defining a multiplier, based on the
@@ -54,10 +68,12 @@ use sp_runtime::{
DispatchInfoOf, PostDispatchInfoOf,
},
};
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
mod payment;
mod types;
pub use payment::*;
pub use types::{InclusionFee, FeeDetails, RuntimeDispatchInfo};
/// Fee multiplier.
pub type Multiplier = FixedU128;
@@ -329,27 +345,19 @@ impl<T: Config> Module<T> where
RuntimeDispatchInfo { weight, class, partial_fee }
}
/// Query the detailed fee of a given `call`.
pub fn query_fee_details<Extrinsic: GetDispatchInfo>(
unchecked_extrinsic: Extrinsic,
len: u32,
) -> FeeDetails<BalanceOf<T>>
where
T::Call: Dispatchable<Info=DispatchInfo>,
{
let dispatch_info = <Extrinsic as GetDispatchInfo>::get_dispatch_info(&unchecked_extrinsic);
Self::compute_fee_details(len, &dispatch_info, 0u32.into())
}
/// Compute the final fee value for a particular transaction.
///
/// The final fee is composed of:
/// - `base_fee`: This is the minimum amount a user pays for a transaction. It is declared
/// as a base _weight_ in the runtime and converted to a fee using `WeightToFee`.
/// - `len_fee`: The length fee, the amount paid for the encoded length (in bytes) of the
/// transaction.
/// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight
/// accounts for the execution time of a transaction.
/// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on
/// the congestion of the network.
/// - (Optional) `tip`: If included in the transaction, the tip will be added on top. Only
/// signed transactions can have a tip.
///
/// The base fee and adjusted weight and length fees constitute the _inclusion fee,_ which is
/// the minimum fee for a transaction to be included in a block.
///
/// ```ignore
/// inclusion_fee = base_fee + len_fee + [targeted_fee_adjustment * weight_fee];
/// final_fee = inclusion_fee + tip;
/// ```
pub fn compute_fee(
len: u32,
info: &DispatchInfoOf<T::Call>,
@@ -357,13 +365,18 @@ impl<T: Config> Module<T> where
) -> BalanceOf<T> where
T::Call: Dispatchable<Info=DispatchInfo>,
{
Self::compute_fee_raw(
len,
info.weight,
tip,
info.pays_fee,
info.class,
)
Self::compute_fee_details(len, info, tip).final_fee()
}
/// Compute the fee details for a particular transaction.
pub fn compute_fee_details(
len: u32,
info: &DispatchInfoOf<T::Call>,
tip: BalanceOf<T>,
) -> FeeDetails<BalanceOf<T>> where
T::Call: Dispatchable<Info=DispatchInfo>,
{
Self::compute_fee_raw(len, info.weight, tip, info.pays_fee, info.class)
}
/// Compute the actual post dispatch fee for a particular transaction.
@@ -377,6 +390,18 @@ impl<T: Config> Module<T> where
tip: BalanceOf<T>,
) -> BalanceOf<T> where
T::Call: Dispatchable<Info=DispatchInfo,PostInfo=PostDispatchInfo>,
{
Self::compute_actual_fee_details(len, info, post_info, tip).final_fee()
}
/// Compute the actual post dispatch fee details for a particular transaction.
pub fn compute_actual_fee_details(
len: u32,
info: &DispatchInfoOf<T::Call>,
post_info: &PostDispatchInfoOf<T::Call>,
tip: BalanceOf<T>,
) -> FeeDetails<BalanceOf<T>> where
T::Call: Dispatchable<Info=DispatchInfo,PostInfo=PostDispatchInfo>,
{
Self::compute_fee_raw(
len,
@@ -393,7 +418,7 @@ impl<T: Config> Module<T> where
tip: BalanceOf<T>,
pays_fee: Pays,
class: DispatchClass,
) -> BalanceOf<T> {
) -> FeeDetails<BalanceOf<T>> {
if pays_fee == Pays::Yes {
let len = <BalanceOf<T>>::from(len);
let per_byte = T::TransactionByteFee::get();
@@ -408,12 +433,19 @@ impl<T: Config> Module<T> where
let adjusted_weight_fee = multiplier.saturating_mul_int(unadjusted_weight_fee);
let base_fee = Self::weight_to_fee(T::BlockWeights::get().get(class).base_extrinsic);
base_fee
.saturating_add(fixed_len_fee)
.saturating_add(adjusted_weight_fee)
.saturating_add(tip)
FeeDetails {
inclusion_fee: Some(InclusionFee {
base_fee,
len_fee: fixed_len_fee,
adjusted_weight_fee
}),
tip
}
} else {
tip
FeeDetails {
inclusion_fee: None,
tip
}
}
}
@@ -578,7 +610,6 @@ mod tests {
traits::Currency,
};
use pallet_balances::Call as BalancesCall;
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
use sp_core::H256;
use sp_runtime::{
testing::{Header, TestXt},