Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
a72fb9a
Return FeeDetails in compute_fee_raw()
liuchengxu Dec 8, 2020
1c807af
Add payment_queryDetails rpc
liuchengxu Dec 8, 2020
7685575
Simplify serde attribute a bit
liuchengxu Dec 8, 2020
5994f88
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Dec 8, 2020
7b965bf
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Dec 9, 2020
ca58b81
Fix line width check
liuchengxu Dec 9, 2020
f319b32
Use saturating_add()
liuchengxu Dec 9, 2020
71f675d
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Dec 16, 2020
df5131b
Move transaction payment rpc types to types.rs
liuchengxu Dec 16, 2020
43ea398
Add file header
liuchengxu Dec 16, 2020
57a3c8c
Fix test
liuchengxu Dec 16, 2020
e2f76b7
Update Cargo.lock
liuchengxu Dec 16, 2020
517d38a
Nit
liuchengxu Dec 16, 2020
9d1b780
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Dec 17, 2020
a0693da
Apply the review suggestions
liuchengxu Dec 19, 2020
8c2cae8
.
liuchengxu Dec 19, 2020
00d80a2
.
liuchengxu Dec 19, 2020
a331455
Fix serde
liuchengxu Dec 19, 2020
8aa6313
Fix rust doc
liuchengxu Dec 19, 2020
422e6d1
.
liuchengxu Dec 19, 2020
1632dbf
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Dec 29, 2020
3cfc821
Update frame/transaction-payment/src/types.rs
liuchengxu Jan 1, 2021
e4556f9
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 1, 2021
7bf0be6
Merge branch 'add-fee-details-rpc' of https://github.com/liuchengxu/s…
liuchengxu Jan 1, 2021
ff6bf96
Use NumberOrHex in fee details RPC
liuchengxu Jan 1, 2021
1676d18
Address review feedback
liuchengxu Jan 1, 2021
0a54c50
Nits
liuchengxu Jan 1, 2021
98869e7
Update some docs
liuchengxu Jan 1, 2021
ae77260
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 1, 2021
ea053a3
Address review
liuchengxu Jan 4, 2021
f9365eb
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 4, 2021
b02d85d
Update frame/transaction-payment/src/types.rs
liuchengxu Jan 4, 2021
adb7a58
Happy 2021
liuchengxu Jan 4, 2021
e75131e
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 7, 2021
14c1319
Nit
liuchengxu Jan 7, 2021
05ea3b7
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 8, 2021
d6ed580
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 13, 2021
e6e945b
Address code review
liuchengxu Jan 13, 2021
db686bd
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 13, 2021
76312b4
Remove needless bound
liuchengxu Jan 14, 2021
faacef8
Merge branch 'master' of https://github.com/paritytech/substrate into…
liuchengxu Jan 14, 2021
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
Prev Previous commit
Next Next commit
Move transaction payment rpc types to types.rs
  • Loading branch information
liuchengxu committed Dec 16, 2020
commit df5131bd91f04a0dc7cfa68faceb35733aa9d587
6 changes: 1 addition & 5 deletions Cargo.lock

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

2 changes: 0 additions & 2 deletions frame/transaction-payment/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../primitives
sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" }
frame-support = { version = "2.0.0", default-features = false, path = "../support" }
frame-system = { version = "2.0.0", default-features = false, path = "../system" }
pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "./rpc/runtime-api" }
smallvec = "1.4.1"
sp-io = { version = "2.0.0", path = "../../primitives/io", default-features = false }
sp-core = { version = "2.0.0", path = "../../primitives/core", default-features = false }
Expand All @@ -37,7 +36,6 @@ std = [
"sp-runtime/std",
"frame-support/std",
"frame-system/std",
"pallet-transaction-payment-rpc-runtime-api/std",
"sp-io/std",
"sp-core/std",
]
11 changes: 2 additions & 9 deletions frame/transaction-payment/rpc/runtime-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,16 @@ readme = "README.md"
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
serde = { version = "1.0.101", optional = true, features = ["derive"] }
sp-api = { version = "2.0.0", default-features = false, path = "../../../../primitives/api" }
codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] }
sp-std = { version = "2.0.0", default-features = false, path = "../../../../primitives/std" }
sp-runtime = { version = "2.0.0", default-features = false, path = "../../../../primitives/runtime" }
frame-support = { version = "2.0.0", default-features = false, path = "../../../support" }

[dev-dependencies]
serde_json = "1.0.41"
pallet-transaction-payment = { version = "2.0.0", default-features = false, path = "../../../transaction-payment" }

[features]
default = ["std"]
std = [
"serde",
"sp-api/std",
"codec/std",
"sp-std/std",
"sp-runtime/std",
"frame-support/std",
"pallet-transaction-payment/std",
]
142 changes: 3 additions & 139 deletions frame/transaction-payment/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,107 +19,10 @@

#![cfg_attr(not(feature = "std"), no_std)]

use sp_std::prelude::*;
use frame_support::weights::{Weight, DispatchClass};
use codec::{Encode, Codec, Decode};
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
use sp_runtime::traits::{AtLeast32BitUnsigned, MaybeDisplay, MaybeFromStr};
use codec::Codec;
use sp_runtime::traits::{MaybeDisplay, MaybeFromStr};

/// 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.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
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`.
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub base_fee: Balance,
/// The length fee, the amount paid for the encoded length (in bytes) of the transaction.
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
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
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub adjusted_weight_fee: Balance,
}

impl<Balance: AtLeast32BitUnsigned + Copy> InclusionFee<Balance> {
/// Returns the total of inclusion fee.
///
/// ```ignore
/// inclusion_fee = base_fee + len_fee + adjusted_weight_fee
/// ```
pub fn total(&self) -> Balance {
self.base_fee
.saturating_add(self.len_fee)
.saturating_add(self.adjusted_weight_fee)
}
}

/// 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
/// signed transactions can have a tip.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
pub struct FeeDetails<Balance> {
pub inclusion_fee: Option<InclusionFee<Balance>>,
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub tip: Balance,
}

impl<Balance: AtLeast32BitUnsigned + Default + Copy> FeeDetails<Balance> {
/// Returns the final fee.
///
/// ```ignore
/// final_fee = inclusion_fee + tip;
/// ```
pub fn final_fee(&self) -> Balance {
self.inclusion_fee.as_ref().map(|i|i.total()).unwrap_or_default().saturating_add(self.tip)
}
}

/// Information related to a dispatchable's class, weight, and fee that can be queried from the runtime.
#[derive(Eq, PartialEq, Encode, Decode, Default)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
pub struct RuntimeDispatchInfo<Balance> {
/// Weight of this dispatch.
pub weight: Weight,
/// Class of this dispatch.
pub class: DispatchClass,
/// The inclusion fee of this dispatch. This does not include a tip or anything else that
/// depends on the signature (i.e. depends on a `SignedExtension`).
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub partial_fee: Balance,
}

#[cfg(feature = "std")]
mod serde_balance {
use serde::{Deserialize, Serializer, Deserializer};

pub fn serialize<S: Serializer, T: std::fmt::Display>(t: &T, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&t.to_string())
}

pub fn deserialize<'de, D: Deserializer<'de>, T: std::str::FromStr>(deserializer: D) -> Result<T, D::Error> {
let s = String::deserialize(deserializer)?;
s.parse::<T>().map_err(|_| serde::de::Error::custom("Parse from string failed"))
}
}
pub use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};

sp_api::decl_runtime_apis! {
pub trait TransactionPaymentApi<Balance> where
Expand All @@ -129,42 +32,3 @@ sp_api::decl_runtime_apis! {
fn query_fee_details(uxt: Block::Extrinsic, len: u32) -> FeeDetails<Balance>;
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn should_serialize_and_deserialize_properly_with_string() {
let info = RuntimeDispatchInfo {
weight: 5,
class: DispatchClass::Normal,
partial_fee: 1_000_000_u64,
};

let json_str = r#"{"weight":5,"class":"normal","partialFee":"1000000"}"#;

assert_eq!(serde_json::to_string(&info).unwrap(), json_str);
assert_eq!(serde_json::from_str::<RuntimeDispatchInfo<u64>>(json_str).unwrap(), info);

// should not panic
serde_json::to_value(&info).unwrap();
}

#[test]
fn should_serialize_and_deserialize_properly_large_value() {
let info = RuntimeDispatchInfo {
weight: 5,
class: DispatchClass::Normal,
partial_fee: u128::max_value(),
};

let json_str = r#"{"weight":5,"class":"normal","partialFee":"340282366920938463463374607431768211455"}"#;

assert_eq!(serde_json::to_string(&info).unwrap(), json_str);
assert_eq!(serde_json::from_str::<RuntimeDispatchInfo<u128>>(json_str).unwrap(), info);

// should not panic
serde_json::to_value(&info).unwrap();
}
}
4 changes: 3 additions & 1 deletion frame/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ use sp_runtime::{
DispatchInfoOf, PostDispatchInfoOf
},
};
use pallet_transaction_payment_rpc_runtime_api::{FeeDetails, InclusionFee, RuntimeDispatchInfo};

mod payment;
mod types;

pub use payment::*;
pub use types::{InclusionFee, FeeDetails, RuntimeDispatchInfo};

/// Fee multiplier.
pub type Multiplier = FixedU128;
Expand Down
140 changes: 140 additions & 0 deletions frame/transaction-payment/src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use sp_std::prelude::*;
use frame_support::weights::{Weight, DispatchClass};
use codec::{Encode, Decode};
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
use sp_runtime::traits::AtLeast32BitUnsigned;

/// 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.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
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`.
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub base_fee: Balance,
/// The length fee, the amount paid for the encoded length (in bytes) of the transaction.
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
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
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub adjusted_weight_fee: Balance,
}

impl<Balance: AtLeast32BitUnsigned + Copy> InclusionFee<Balance> {
/// Returns the total of inclusion fee.
///
/// ```ignore
/// inclusion_fee = base_fee + len_fee + adjusted_weight_fee
/// ```
pub fn total(&self) -> Balance {
self.base_fee
.saturating_add(self.len_fee)
.saturating_add(self.adjusted_weight_fee)
}
}

/// 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
/// signed transactions can have a tip.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
pub struct FeeDetails<Balance> {
pub inclusion_fee: Option<InclusionFee<Balance>>,
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub tip: Balance,
}

impl<Balance: AtLeast32BitUnsigned + Default + Copy> FeeDetails<Balance> {
/// Returns the final fee.
///
/// ```ignore
/// final_fee = inclusion_fee + tip;
/// ```
pub fn final_fee(&self) -> Balance {
self.inclusion_fee.as_ref().map(|i|i.total()).unwrap_or_default().saturating_add(self.tip)
}
}

/// Information related to a dispatchable's class, weight, and fee that can be queried from the runtime.
#[derive(Eq, PartialEq, Encode, Decode, Default)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
pub struct RuntimeDispatchInfo<Balance> {
/// Weight of this dispatch.
pub weight: Weight,
/// Class of this dispatch.
pub class: DispatchClass,
/// The inclusion fee of this dispatch. This does not include a tip or anything else that
/// depends on the signature (i.e. depends on a `SignedExtension`).
#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
pub partial_fee: Balance,
}

#[cfg(feature = "std")]
mod serde_balance {
use serde::{Deserialize, Serializer, Deserializer};

pub fn serialize<S: Serializer, T: std::fmt::Display>(t: &T, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&t.to_string())
}

pub fn deserialize<'de, D: Deserializer<'de>, T: std::str::FromStr>(deserializer: D) -> Result<T, D::Error> {
let s = String::deserialize(deserializer)?;
s.parse::<T>().map_err(|_| serde::de::Error::custom("Parse from string failed"))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn should_serialize_and_deserialize_properly_with_string() {
let info = RuntimeDispatchInfo {
weight: 5,
class: DispatchClass::Normal,
partial_fee: 1_000_000_u64,
};

let json_str = r#"{"weight":5,"class":"normal","partialFee":"1000000"}"#;

assert_eq!(serde_json::to_string(&info).unwrap(), json_str);
assert_eq!(serde_json::from_str::<RuntimeDispatchInfo<u64>>(json_str).unwrap(), info);

// should not panic
serde_json::to_value(&info).unwrap();
}

#[test]
fn should_serialize_and_deserialize_properly_large_value() {
let info = RuntimeDispatchInfo {
weight: 5,
class: DispatchClass::Normal,
partial_fee: u128::max_value(),
};

let json_str = r#"{"weight":5,"class":"normal","partialFee":"340282366920938463463374607431768211455"}"#;

assert_eq!(serde_json::to_string(&info).unwrap(), json_str);
assert_eq!(serde_json::from_str::<RuntimeDispatchInfo<u128>>(json_str).unwrap(), info);

// should not panic
serde_json::to_value(&info).unwrap();
}
}