Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update transaction fee xpallet #561

Merged
merged 20 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions runtime/chainx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,9 @@ impl pallet_transaction_payment::Config for Runtime {
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
}

impl xpallet_transaction_fee::Config for Runtime {}
impl xpallet_transaction_fee::Config for Runtime {
type Event = Event;
}

parameter_types! {
pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS;
Expand Down Expand Up @@ -1324,7 +1326,7 @@ impl_runtime_apis! {
}
}
fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> pallet_transaction_payment::FeeDetails<Balance> {
todo!("Migrate ChainX query_fee_details")
TransactionPayment::query_fee_details(uxt, len)
}
}

Expand All @@ -1333,6 +1335,7 @@ impl_runtime_apis! {
uxt: <Block as BlockT>::Extrinsic,
len: u32,
) -> xpallet_transaction_fee::FeeDetails<Balance> {
todo!("migrate");
if let Some(extra_fee) = ChargeExtraFee::has_extra_fee(&uxt.function) {
let details = XTransactionFee::query_fee_details(uxt, len);
xpallet_transaction_fee::FeeDetails {
Expand Down
6 changes: 4 additions & 2 deletions runtime/dev/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,9 @@ impl pallet_transaction_payment::Config for Runtime {
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
}

impl xpallet_transaction_fee::Config for Runtime {}
impl xpallet_transaction_fee::Config for Runtime {
type Event = Event;
}

parameter_types! {
pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS;
Expand Down Expand Up @@ -1334,7 +1336,7 @@ impl_runtime_apis! {
}
}
fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> pallet_transaction_payment::FeeDetails<Balance> {
todo!("Migrate ChainX query_fee_details")
TransactionPayment::query_fee_details(uxt, len)
}
}

Expand Down
6 changes: 4 additions & 2 deletions runtime/malan/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,9 @@ impl pallet_transaction_payment::Config for Runtime {
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
}

impl xpallet_transaction_fee::Config for Runtime {}
impl xpallet_transaction_fee::Config for Runtime {
type Event = Event;
}

parameter_types! {
pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_BLOCKS;
Expand Down Expand Up @@ -1331,7 +1333,7 @@ impl_runtime_apis! {
}
}
fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> pallet_transaction_payment::FeeDetails<Balance> {
todo!("Migrate ChainX query_fee_details")
TransactionPayment::query_fee_details(uxt, len)
}
}

Expand Down
1 change: 1 addition & 0 deletions xpallets/transaction-fee/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sp-runtime = "3.0.0"

# Substrate pallets
pallet-transaction-payment-rpc = "3.0.0"
pallet-transaction-payment = { version = "3.0.0", default-features = false }

xp-rpc = { path = "../../../primitives/rpc" }

Expand Down
12 changes: 7 additions & 5 deletions xpallets/transaction-fee/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sp_runtime::{
use pallet_transaction_payment_rpc::Error;

use xp_rpc::RpcBalance;
use xpallet_transaction_fee_rpc_runtime_api::{FeeDetails, InclusionFee};
use xpallet_transaction_fee_rpc_runtime_api::FeeDetails;
alannotnerd marked this conversation as resolved.
Show resolved Hide resolved

pub use xpallet_transaction_fee_rpc_runtime_api::XTransactionFeeApi as XTransactionFeeRuntimeApi;

Expand Down Expand Up @@ -68,10 +68,12 @@ where

api.query_fee_details(&at, uxt, encoded_len)
.map(|fee_details| FeeDetails {
inclusion_fee: fee_details.inclusion_fee.map(|fee| InclusionFee {
base_fee: fee.base_fee.into(),
len_fee: fee.len_fee.into(),
adjusted_weight_fee: fee.adjusted_weight_fee.into(),
inclusion_fee: fee_details.inclusion_fee.map(|fee| {
pallet_transaction_payment::InclusionFee {
base_fee: fee.base_fee.into(),
len_fee: fee.len_fee.into(),
adjusted_weight_fee: fee.adjusted_weight_fee.into(),
}
alannotnerd marked this conversation as resolved.
Show resolved Hide resolved
}),
tip: fee_details.tip.into(),
extra_fee: fee_details.extra_fee.into(),
Expand Down
160 changes: 52 additions & 108 deletions xpallets/transaction-fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,47 @@ mod types;

alannotnerd marked this conversation as resolved.
Show resolved Hide resolved
use sp_std::prelude::*;

use frame_support::{
decl_event, decl_module,
traits::Get,
weights::{
DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight,
WeightToFeePolynomial,
},
};
use frame_support::weights::{DispatchInfo, GetDispatchInfo};
use sp_runtime::{
traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating},
FixedPointNumber, FixedPointOperand,
traits::{Dispatchable, Saturating},
FixedPointOperand,
};

pub use self::types::{FeeDetails, InclusionFee};
pub use self::types::FeeDetails;
pub use pallet_transaction_payment::InclusionFee;

type BalanceOf<T> = <<T as pallet_transaction_payment::Config>::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<T>>::Balance;
alannotnerd marked this conversation as resolved.
Show resolved Hide resolved

pub trait Config: pallet_transaction_payment::Config {}
pub use pallet::*;

decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::Origin {}
}
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;

decl_event!(
/// Event for the XTransactionFee Module
pub enum Event<T>
where
Balance = BalanceOf<T>,
<T as frame_system::Config>::AccountId,
{
#[pallet::pallet]
#[pallet::generate_store(pub(crate) trait Store)]
pub struct Pallet<T>(PhantomData<T>);

#[pallet::config]
pub trait Config: frame_system::Config + pallet_transaction_payment::Config {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
}

#[pallet::call]
impl<T: Config> Pallet<T> {}
alannotnerd marked this conversation as resolved.
Show resolved Hide resolved

#[pallet::event]
#[pallet::metadata(T::AccountId = "AccountId", BalanceOf<T> = "Balance")] // Optional
#[pallet::generate_deposit(pub(super) fn deposit_event)] // Optional
pub enum Event<T: Config> {
/// Transaction fee was paid to the block author and its reward pot in 1:9.
/// [author, author_fee, reward_pot, reward_pot_fee]
FeePaid(AccountId, Balance, AccountId, Balance),
FeePaid(T::AccountId, BalanceOf<T>, T::AccountId, BalanceOf<T>),
}
);
}

impl<T: Config> Module<T>
impl<T: Config> Pallet<T>
where
BalanceOf<T>: FixedPointOperand,
{
Expand All @@ -67,96 +71,36 @@ where
) -> FeeDetails<BalanceOf<T>>
where
T: Send + Sync,
BalanceOf<T>: Send + Sync,
BalanceOf<T>: Send + Sync + Default,
T::Call: Dispatchable<Info = DispatchInfo>,
{
let dispatch_info = <Extrinsic as GetDispatchInfo>::get_dispatch_info(&unchecked_extrinsic);
Self::compute_fee(len, &dispatch_info, 0u32.into())
}

pub fn compute_fee(
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)
}

/// Returns the details of the actual post dispatch fee for a particular transaction.
///
/// Identical to `compute_fee_details` with the only difference that the post dispatch corrected
/// weight is used for the weight fee calculation.
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(
let details = pallet_transaction_payment::Module::<T>::compute_fee_details(
len,
post_info.calc_actual_weight(info),
tip,
post_info.pays_fee(info),
info.class,
)
}

fn compute_fee_raw(
len: u32,
weight: Weight,
tip: BalanceOf<T>,
pays_fee: Pays,
class: DispatchClass,
) -> FeeDetails<BalanceOf<T>> {
if pays_fee == Pays::Yes {
let len = <BalanceOf<T>>::from(len);
let per_byte = T::TransactionByteFee::get();

// length fee. this is not adjusted.
let fixed_len_fee = per_byte.saturating_mul(len);

// the adjustable part of the fee.
let unadjusted_weight_fee = Self::weight_to_fee(weight);
let multiplier = pallet_transaction_payment::Module::<T>::next_fee_multiplier();
// final adjusted weight fee.
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);
let total = 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,
extra_fee: 0u32.into(),
final_fee: total,
&dispatch_info,
0u32.into(),
);

match details.inclusion_fee {
Some(fee) => {
let total = fee
.base_fee
.saturating_add(fee.len_fee)
.saturating_add(fee.adjusted_weight_fee)
.saturating_add(details.tip);
FeeDetails {
inclusion_fee: Some(fee),
tip: details.tip,
extra_fee: 0u32.into(),
final_fee: total,
}
}
} else {
FeeDetails {
None => FeeDetails {
inclusion_fee: None,
tip,
tip: details.tip,
extra_fee: 0u32.into(),
final_fee: tip,
}
final_fee: details.tip,
},
}
}

fn weight_to_fee(weight: Weight) -> BalanceOf<T> {
// cap the weight to the maximum defined in runtime, otherwise it will be the
// `Bounded` maximum of its data type, which is not desired.
let capped_weight = weight.min(T::BlockWeights::get().max_block);
T::WeightToFee::calc(&capped_weight)
}
}
31 changes: 5 additions & 26 deletions xpallets/transaction-fee/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
// Copyright 2019-2020 ChainX Project Authors. Licensed under GPL-3.0.

use codec::{Decode, Encode};
use pallet_transaction_payment::InclusionFee;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};

use sp_runtime::RuntimeDebug;

/// 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];
/// ```
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
pub struct InclusionFee<Balance> {
/// 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`.
pub base_fee: Balance,
/// The length fee, the amount paid for the encoded length (in bytes) of the transaction.
pub len_fee: Balance,
/// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on
/// the congestion of the network.
/// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight
/// accounts for the execution time of a transaction.
///
/// adjusted_weight_fee = targeted_fee_adjustment * weight_fee
pub adjusted_weight_fee: Balance,
}

/// The `final_fee` is composed of:
/// - (Optional) `inclusion_fee`: Only the `Pays::Yes` transaction can have the inclusion fee.
/// - (Optional) `tip`: If included in the transaction, the tip will be added on top. Only
Expand All @@ -42,9 +19,11 @@ pub struct InclusionFee<Balance> {
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
pub struct FeeDetails<Balance> {
/// The minimum fee for a transaction to be included in a block.
pub inclusion_fee: Option<InclusionFee<Balance>>,
/// Some calls might be charged extra fee besides the essential `inclusion_fee`.
pub extra_fee: Balance,
// Do not serialize and deserialize `tip` as we actually can not pass any tip to the RPC.
#[cfg_attr(feature = "std", serde(skip))]
pub tip: Balance,
pub extra_fee: Balance,
pub final_fee: Balance,
}