diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index e437b22fc06650ef5059f9378594f865beb6a7e5..7fc26b08885216e07d1555efd9da5c38f019f323 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -23,4 +23,5 @@ std = [ "codec/std", "rstd/std", "sp-runtime/std", + "support/std", ] diff --git a/frame/transaction-payment/rpc/runtime-api/src/lib.rs b/frame/transaction-payment/rpc/runtime-api/src/lib.rs index e922ff9e283688b54e830a2d6717dcf3f8bff7a3..549f67c98ce2f48fb54d2167b4b16edd121cbea5 100644 --- a/frame/transaction-payment/rpc/runtime-api/src/lib.rs +++ b/frame/transaction-payment/rpc/runtime-api/src/lib.rs @@ -23,11 +23,11 @@ use support::weights::{Weight, DispatchClass}; use codec::{Encode, Codec, Decode}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; +use sp_runtime::traits::{UniqueSaturatedInto, SaturatedConversion}; /// Some information related to a dispatchable 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", derive(Debug))] pub struct RuntimeDispatchInfo<Balance> { /// Weight of this dispatch. pub weight: Weight, @@ -38,6 +38,41 @@ pub struct RuntimeDispatchInfo<Balance> { pub partial_fee: Balance, } +/// A capped version of `RuntimeDispatchInfo`. +/// +/// The `Balance` is capped (or expanded) to `u64` to avoid serde issues with `u128`. +#[derive(Eq, PartialEq, Encode, Decode, Default)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] +pub struct CappedDispatchInfo { + /// Weight of this dispatch. + pub weight: Weight, + /// Class of this dispatch. + pub class: DispatchClass, + /// The partial inclusion fee of this dispatch. This does not include tip or anything else which + /// is dependent on the signature (aka. depends on a `SignedExtension`). + pub partial_fee: u64, +} + +impl CappedDispatchInfo { + /// Create a new `CappedDispatchInfo` from `RuntimeDispatchInfo`. + pub fn new<Balance: UniqueSaturatedInto<u64>>( + dispatch: RuntimeDispatchInfo<Balance>, + ) -> Self { + let RuntimeDispatchInfo { + weight, + class, + partial_fee, + } = dispatch; + + Self { + weight, + class, + partial_fee: partial_fee.saturated_into(), + } + } +} + sp_api::decl_runtime_apis! { pub trait TransactionPaymentApi<Balance, Extrinsic> where Balance: Codec, @@ -59,6 +94,7 @@ mod tests { partial_fee: 1_000_000_u64, }; + let info = CappedDispatchInfo::new(info); assert_eq!( serde_json::to_string(&info).unwrap(), r#"{"weight":5,"class":"normal","partialFee":1000000}"#, diff --git a/frame/transaction-payment/rpc/src/lib.rs b/frame/transaction-payment/rpc/src/lib.rs index 35ad4a06ed2f0037decb0241cb1ab68e11d3fac4..63a6b1827b66a2617c8e7030bf801de36212726d 100644 --- a/frame/transaction-payment/rpc/src/lib.rs +++ b/frame/transaction-payment/rpc/src/lib.rs @@ -23,10 +23,10 @@ use jsonrpc_core::{Error as RpcError, ErrorCode, Result}; use jsonrpc_derive::rpc; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, ProvideRuntimeApi}, + traits::{Block as BlockT, ProvideRuntimeApi, UniqueSaturatedInto}, }; use primitives::Bytes; -use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; +use pallet_transaction_payment_rpc_runtime_api::CappedDispatchInfo; pub use pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi as TransactionPaymentRuntimeApi; pub use self::gen_client::Client as TransactionPaymentClient; @@ -37,7 +37,7 @@ pub trait TransactionPaymentApi<BlockHash, Balance> { &self, encoded_xt: Bytes, at: Option<BlockHash> - ) -> Result<RuntimeDispatchInfo<Balance>>; + ) -> Result<CappedDispatchInfo>; } /// A struct that implements the [`TransactionPaymentApi`]. @@ -78,14 +78,14 @@ where C: ProvideRuntimeApi, C: HeaderBackend<Block>, C::Api: TransactionPaymentRuntimeApi<Block, Balance, Extrinsic>, - Balance: Codec, + Balance: Codec + UniqueSaturatedInto<u64>, Extrinsic: Codec + Send + Sync + 'static, { fn query_info( &self, encoded_xt: Bytes, at: Option<<Block as BlockT>::Hash> - ) -> Result<RuntimeDispatchInfo<Balance>> { + ) -> Result<CappedDispatchInfo> { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| // If the block hash is not supplied assume the best block. @@ -103,6 +103,6 @@ where code: ErrorCode::ServerError(Error::RuntimeError.into()), message: "Unable to query dispatch info.".into(), data: Some(format!("{:?}", e).into()), - }) + }).map(CappedDispatchInfo::new) } }