mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 10:31:04 +00:00
Extensible transactions (and tips) (#3102)
* Make extrinsics extensible. Also Remove old extrinsic types. * Rest of mockup. Add tips. * Fix some build issues * Runtiem builds :) * Substrate builds. * Fix a doc test * Compact encoding * Extract out the era logic into an extension * Weight Check signed extension. (#3115) * Weight signed extension. * Revert a bit + test for check era. * Update Cargo.toml * Update node/cli/src/factory_impl.rs * Update node/executor/src/lib.rs * Update node/executor/src/lib.rs * Don't use len for weight - use data. * Operational Transaction; second attempt (#3138) * working poc added. * some fixes. * Update doc. * Fix all tests + final logic. * more refactoring. * nits. * System block limit in bytes. * Silent the storage macro warnings. * More logic more tests. * Fix import. * Refactor names. * Fix build. * Update srml/balances/src/lib.rs * Final refactor. * Bump transaction version * Fix weight mult test. * Fix more tests and improve doc. * Bump. * Make some tests work again. * Fix subkey. * Remove todos + bump. * Ignore expensive test. * Bump.
This commit is contained in:
@@ -25,25 +25,18 @@ pub use srml_metadata::{
|
||||
FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata,
|
||||
ModuleConstantMetadata, DefaultByte, DefaultByteGetter,
|
||||
};
|
||||
pub use sr_primitives::weights::{TransactionWeight, Weighable, Weight};
|
||||
pub use sr_primitives::weights::{SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData,
|
||||
ClassifyDispatch,
|
||||
TransactionPriority
|
||||
};
|
||||
pub use sr_primitives::traits::{Dispatchable, DispatchResult};
|
||||
|
||||
/// A type that cannot be instantiated.
|
||||
pub enum Never {}
|
||||
|
||||
/// Result of a module function call; either nothing (functions are only called for "side effects")
|
||||
/// or an error message.
|
||||
pub type Result = result::Result<(), &'static str>;
|
||||
|
||||
/// A lazy call (module function and argument values) that can be executed via its `dispatch`
|
||||
/// method.
|
||||
pub trait Dispatchable {
|
||||
/// Every function call from your runtime has an origin, which specifies where the extrinsic was
|
||||
/// generated from. In the case of a signed extrinsic (transaction), the origin contains an
|
||||
/// identifier for the caller. The origin can be empty in the case of an inherent extrinsic.
|
||||
type Origin;
|
||||
type Trait;
|
||||
fn dispatch(self, origin: Self::Origin) -> Result;
|
||||
}
|
||||
pub type Result = DispatchResult;
|
||||
|
||||
/// Serializable version of Dispatchable.
|
||||
/// This value can be used as a "function" in an extrinsic.
|
||||
@@ -593,7 +586,7 @@ macro_rules! decl_module {
|
||||
{ $( $constants )* }
|
||||
[ $( $dispatchables )* ]
|
||||
$(#[doc = $doc_attr])*
|
||||
#[weight = $crate::dispatch::TransactionWeight::default()]
|
||||
#[weight = $crate::dispatch::SimpleDispatchInfo::default()]
|
||||
$fn_vis fn $fn_name(
|
||||
$from $(, $(#[$codec_attr])* $param_name : $param )*
|
||||
) $( -> $result )* { $( $impl )* }
|
||||
@@ -1117,14 +1110,38 @@ macro_rules! decl_module {
|
||||
}
|
||||
|
||||
// Implement weight calculation function for Call
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Weighable
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::GetDispatchInfo
|
||||
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
|
||||
{
|
||||
fn weight(&self, _len: usize) -> $crate::dispatch::Weight {
|
||||
match self {
|
||||
$( $call_type::$fn_name(..) => $crate::dispatch::Weighable::weight(&$weight, _len), )*
|
||||
$call_type::__PhantomItem(_, _) => { unreachable!("__PhantomItem should never be used.") },
|
||||
}
|
||||
fn get_dispatch_info(&self) -> $crate::dispatch::DispatchInfo {
|
||||
$(
|
||||
if let $call_type::$fn_name($( ref $param_name ),*) = self {
|
||||
let weight = <dyn $crate::dispatch::WeighData<( $( & $param, )* )>>::weigh_data(
|
||||
&$weight,
|
||||
($( $param_name, )*)
|
||||
);
|
||||
let class = <dyn $crate::dispatch::ClassifyDispatch<( $( & $param, )* )>>::classify_dispatch(
|
||||
&$weight,
|
||||
($( $param_name, )*)
|
||||
);
|
||||
return $crate::dispatch::DispatchInfo { weight, class };
|
||||
}
|
||||
if let $call_type::__PhantomItem(_, _) = self { unreachable!("__PhantomItem should never be used.") }
|
||||
)*
|
||||
// Defensive only: this function must have already returned at this point.
|
||||
// all dispatchable function will have a weight which has the `::default`
|
||||
// implementation of `SimpleDispatchInfo`. Nonetheless, we create one if it does
|
||||
// not exist.
|
||||
let weight = <dyn $crate::dispatch::WeighData<_>>::weigh_data(
|
||||
&$crate::dispatch::SimpleDispatchInfo::default(),
|
||||
()
|
||||
);
|
||||
let class = <dyn $crate::dispatch::ClassifyDispatch<_>>::classify_dispatch(
|
||||
&$crate::dispatch::SimpleDispatchInfo::default(),
|
||||
()
|
||||
);
|
||||
$crate::dispatch::DispatchInfo { weight, class }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,10 +1286,10 @@ macro_rules! impl_outer_dispatch {
|
||||
$camelcase ( $crate::dispatch::CallableCallFor<$camelcase, $runtime> )
|
||||
,)*
|
||||
}
|
||||
impl $crate::dispatch::Weighable for $call_type {
|
||||
fn weight(&self, len: usize) -> $crate::dispatch::Weight {
|
||||
impl $crate::dispatch::GetDispatchInfo for $call_type {
|
||||
fn get_dispatch_info(&self) -> $crate::dispatch::DispatchInfo {
|
||||
match self {
|
||||
$( $call_type::$camelcase(call) => call.weight(len), )*
|
||||
$( $call_type::$camelcase(call) => call.get_dispatch_info(), )*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1579,6 +1596,7 @@ macro_rules! __check_reserved_fn_name {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::runtime_primitives::traits::{OnInitialize, OnFinalize};
|
||||
use sr_primitives::weights::{DispatchInfo, DispatchClass};
|
||||
|
||||
pub trait Trait: system::Trait + Sized where Self::AccountId: From<u32> {
|
||||
type Origin;
|
||||
@@ -1604,7 +1622,7 @@ mod tests {
|
||||
fn aux_0(_origin) -> Result { unreachable!() }
|
||||
fn aux_1(_origin, #[compact] _data: u32) -> Result { unreachable!() }
|
||||
fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() }
|
||||
#[weight = TransactionWeight::Basic(10, 100)]
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(10)]
|
||||
fn aux_3(_origin) -> Result { unreachable!() }
|
||||
fn aux_4(_origin, _data: i32) -> Result { unreachable!() }
|
||||
fn aux_5(_origin, _data: i32, #[compact] _data2: u32) -> Result { unreachable!() }
|
||||
@@ -1613,8 +1631,8 @@ mod tests {
|
||||
fn on_finalize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_finalize") } }
|
||||
fn offchain_worker() {}
|
||||
|
||||
#[weight = TransactionWeight::Max]
|
||||
fn weighted(_origin) { unreachable!() }
|
||||
#[weight = SimpleDispatchInfo::FixedOperational(5)]
|
||||
fn operational(_origin) { unreachable!() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1680,7 +1698,7 @@ mod tests {
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("weighted"),
|
||||
name: DecodeDifferent::Encode("operational"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
@@ -1755,10 +1773,19 @@ mod tests {
|
||||
#[test]
|
||||
fn weight_should_attach_to_call_enum() {
|
||||
// max weight. not dependent on input.
|
||||
assert_eq!(Call::<TraitImpl>::weighted().weight(100), 3 * 1024 * 1024);
|
||||
assert_eq!(
|
||||
Call::<TraitImpl>::operational().get_dispatch_info(),
|
||||
DispatchInfo { weight: 5, class: DispatchClass::Operational },
|
||||
);
|
||||
// default weight.
|
||||
assert_eq!(Call::<TraitImpl>::aux_0().weight(5), 5 /*tx-len*/);
|
||||
assert_eq!(
|
||||
Call::<TraitImpl>::aux_0().get_dispatch_info(),
|
||||
DispatchInfo { weight: 100, class: DispatchClass::Normal },
|
||||
);
|
||||
// custom basic
|
||||
assert_eq!(Call::<TraitImpl>::aux_3().weight(5), 10 + 100 * 5 );
|
||||
assert_eq!(
|
||||
Call::<TraitImpl>::aux_3().get_dispatch_info(),
|
||||
DispatchInfo { weight: 10, class: DispatchClass::Normal },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ use crate::codec::{Codec, Encode, Decode};
|
||||
use substrate_primitives::u32_trait::Value as U32;
|
||||
use crate::runtime_primitives::traits::{MaybeSerializeDebug, SimpleArithmetic, Saturating};
|
||||
use crate::runtime_primitives::ConsensusEngineId;
|
||||
use crate::runtime_primitives::weights::Weight;
|
||||
|
||||
use super::for_each_tuple;
|
||||
|
||||
@@ -90,19 +89,6 @@ pub enum UpdateBalanceOutcome {
|
||||
AccountKilled,
|
||||
}
|
||||
|
||||
/// Simple trait designed for hooking into a transaction payment.
|
||||
///
|
||||
/// It operates over a single generic `AccountId` type.
|
||||
pub trait MakePayment<AccountId> {
|
||||
/// Make transaction payment from `who` for an extrinsic of encoded length
|
||||
/// `encoded_len` bytes. Return `Ok` iff the payment was successful.
|
||||
fn make_payment(who: &AccountId, weight: Weight) -> Result<(), &'static str>;
|
||||
}
|
||||
|
||||
impl<T> MakePayment<T> for () {
|
||||
fn make_payment(_: &T, _: Weight) -> Result<(), &'static str> { Ok(()) }
|
||||
}
|
||||
|
||||
/// A trait for finding the author of a block header based on the `PreRuntime` digests contained
|
||||
/// within it.
|
||||
pub trait FindAuthor<Author> {
|
||||
|
||||
Reference in New Issue
Block a user