mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-20 20:55:41 +00:00
Create sp-weights crate to store weight primitives (#12219)
* Create sp-weights crate to store weight primitives * Fix templates * Fix templates * Fixes * Fixes * cargo fmt * Fixes * Fixes * Use deprecated type alias instead of deprecated unit types * Use deprecated subtraits instead of deprecated hollow new traits * Fixes * Allow deprecation in macro expansion * Add missing where clause during call macro expansion * cargo fmt * Fixes * cargo fmt * Fixes * Fixes * Fixes * Fixes * Move FRAME-specific weight files back to frame_support * Fixes * Update frame/support/src/dispatch.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/support/src/dispatch.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/support/src/dispatch.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Add missing header * Rewrite module docs * Fixes * Fixes * Fixes * Fixes * cargo fmt Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Generated
+18
@@ -2293,6 +2293,7 @@ dependencies = [
|
|||||||
"sp-state-machine",
|
"sp-state-machine",
|
||||||
"sp-std",
|
"sp-std",
|
||||||
"sp-tracing",
|
"sp-tracing",
|
||||||
|
"sp-weights",
|
||||||
"tt-call",
|
"tt-call",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2390,6 +2391,7 @@ dependencies = [
|
|||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
"sp-std",
|
"sp-std",
|
||||||
"sp-version",
|
"sp-version",
|
||||||
|
"sp-weights",
|
||||||
"substrate-test-runtime-client",
|
"substrate-test-runtime-client",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -10010,6 +10012,7 @@ dependencies = [
|
|||||||
"sp-state-machine",
|
"sp-state-machine",
|
||||||
"sp-std",
|
"sp-std",
|
||||||
"sp-tracing",
|
"sp-tracing",
|
||||||
|
"sp-weights",
|
||||||
"substrate-test-runtime-client",
|
"substrate-test-runtime-client",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
@@ -10315,6 +10318,21 @@ dependencies = [
|
|||||||
"wasmtime",
|
"wasmtime",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sp-weights"
|
||||||
|
version = "4.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"impl-trait-for-tuples",
|
||||||
|
"parity-scale-codec",
|
||||||
|
"scale-info",
|
||||||
|
"serde",
|
||||||
|
"smallvec",
|
||||||
|
"sp-arithmetic",
|
||||||
|
"sp-core",
|
||||||
|
"sp-debug-derive",
|
||||||
|
"sp-std",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ members = [
|
|||||||
"primitives/version",
|
"primitives/version",
|
||||||
"primitives/version/proc-macro",
|
"primitives/version/proc-macro",
|
||||||
"primitives/wasm-interface",
|
"primitives/wasm-interface",
|
||||||
|
"primitives/weights",
|
||||||
"test-utils/client",
|
"test-utils/client",
|
||||||
"test-utils/derive",
|
"test-utils/derive",
|
||||||
"test-utils/runtime",
|
"test-utils/runtime",
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
|
|
||||||
use codec::{Decode, Encode, Joiner};
|
use codec::{Decode, Encode, Joiner};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo},
|
||||||
traits::Currency,
|
traits::Currency,
|
||||||
weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::{self, AccountInfo, EventRecord, Phase};
|
use frame_system::{self, AccountInfo, EventRecord, Phase};
|
||||||
use sp_core::{storage::well_known_keys, traits::Externalities};
|
use sp_core::{storage::well_known_keys, traits::Externalities};
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
|
|
||||||
use codec::{Encode, Joiner};
|
use codec::{Encode, Joiner};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::GetDispatchInfo,
|
||||||
traits::Currency,
|
traits::Currency,
|
||||||
weights::{constants::ExtrinsicBaseWeight, GetDispatchInfo, IdentityFee, WeightToFee},
|
weights::{constants::ExtrinsicBaseWeight, IdentityFee, WeightToFee},
|
||||||
};
|
};
|
||||||
use kitchensink_runtime::{
|
use kitchensink_runtime::{
|
||||||
constants::{currency::*, time::SLOT_DURATION},
|
constants::{currency::*, time::SLOT_DURATION},
|
||||||
|
|||||||
@@ -129,7 +129,10 @@ mod multiplier_tests {
|
|||||||
AdjustmentVariable, MinimumMultiplier, Runtime, RuntimeBlockWeights as BlockWeights,
|
AdjustmentVariable, MinimumMultiplier, Runtime, RuntimeBlockWeights as BlockWeights,
|
||||||
System, TargetBlockFullness, TransactionPayment,
|
System, TargetBlockFullness, TransactionPayment,
|
||||||
};
|
};
|
||||||
use frame_support::weights::{DispatchClass, Weight, WeightToFee};
|
use frame_support::{
|
||||||
|
dispatch::DispatchClass,
|
||||||
|
weights::{Weight, WeightToFee},
|
||||||
|
};
|
||||||
|
|
||||||
fn max_normal() -> Weight {
|
fn max_normal() -> Weight {
|
||||||
BlockWeights::get()
|
BlockWeights::get()
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ use frame_election_provider_support::{
|
|||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
construct_runtime,
|
construct_runtime,
|
||||||
|
dispatch::DispatchClass,
|
||||||
pallet_prelude::Get,
|
pallet_prelude::Get,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
traits::{
|
traits::{
|
||||||
@@ -37,7 +38,7 @@ use frame_support::{
|
|||||||
},
|
},
|
||||||
weights::{
|
weights::{
|
||||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
|
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
|
||||||
ConstantMultiplier, DispatchClass, IdentityFee, Weight,
|
ConstantMultiplier, IdentityFee, Weight,
|
||||||
},
|
},
|
||||||
PalletId, RuntimeDebug,
|
PalletId, RuntimeDebug,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,13 +23,13 @@
|
|||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchResultWithPostInfo,
|
dispatch::{DispatchResultWithPostInfo, Pays},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{
|
traits::{
|
||||||
ConstU32, DisabledValidators, FindAuthor, Get, KeyOwnerProofSystem, OnTimestampSet,
|
ConstU32, DisabledValidators, FindAuthor, Get, KeyOwnerProofSystem, OnTimestampSet,
|
||||||
OneSessionHandler,
|
OneSessionHandler,
|
||||||
},
|
},
|
||||||
weights::{Pays, Weight},
|
weights::Weight,
|
||||||
BoundedVec, WeakBoundedVec,
|
BoundedVec, WeakBoundedVec,
|
||||||
};
|
};
|
||||||
use sp_application_crypto::ByteArray;
|
use sp_application_crypto::ByteArray;
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
use super::{Call, *};
|
use super::{Call, *};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_err, assert_noop, assert_ok,
|
assert_err, assert_noop, assert_ok,
|
||||||
|
dispatch::{GetDispatchInfo, Pays},
|
||||||
traits::{Currency, EstimateNextSessionRotation, OnFinalize},
|
traits::{Currency, EstimateNextSessionRotation, OnFinalize},
|
||||||
weights::{GetDispatchInfo, Pays},
|
|
||||||
};
|
};
|
||||||
use mock::*;
|
use mock::*;
|
||||||
use pallet_session::ShouldEndSession;
|
use pallet_session::ShouldEndSession;
|
||||||
|
|||||||
@@ -21,9 +21,10 @@
|
|||||||
|
|
||||||
use crate::{self as pallet_balances, decl_tests, Config, Pallet};
|
use crate::{self as pallet_balances, decl_tests, Config, Pallet};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::DispatchInfo,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
traits::{ConstU32, ConstU64, ConstU8},
|
traits::{ConstU32, ConstU64, ConstU8},
|
||||||
weights::{DispatchInfo, IdentityFee, Weight},
|
weights::{IdentityFee, Weight},
|
||||||
};
|
};
|
||||||
use pallet_transaction_payment::CurrencyAdapter;
|
use pallet_transaction_payment::CurrencyAdapter;
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
|
|||||||
@@ -21,9 +21,10 @@
|
|||||||
|
|
||||||
use crate::{self as pallet_balances, decl_tests, Config, Pallet};
|
use crate::{self as pallet_balances, decl_tests, Config, Pallet};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::DispatchInfo,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
traits::{ConstU32, ConstU64, ConstU8, StorageMapShim},
|
traits::{ConstU32, ConstU64, ConstU8, StorageMapShim},
|
||||||
weights::{DispatchInfo, IdentityFee, Weight},
|
weights::{IdentityFee, Weight},
|
||||||
};
|
};
|
||||||
use pallet_transaction_payment::CurrencyAdapter;
|
use pallet_transaction_payment::CurrencyAdapter;
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
|
|||||||
@@ -49,12 +49,15 @@ use sp_std::{marker::PhantomData, prelude::*, result};
|
|||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
codec::{Decode, Encode, MaxEncodedLen},
|
codec::{Decode, Encode, MaxEncodedLen},
|
||||||
dispatch::{DispatchError, DispatchResultWithPostInfo, Dispatchable, PostDispatchInfo},
|
dispatch::{
|
||||||
|
DispatchError, DispatchResultWithPostInfo, Dispatchable, GetDispatchInfo, Pays,
|
||||||
|
PostDispatchInfo,
|
||||||
|
},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{
|
traits::{
|
||||||
Backing, ChangeMembers, EnsureOrigin, Get, GetBacking, InitializeMembers, StorageVersion,
|
Backing, ChangeMembers, EnsureOrigin, Get, GetBacking, InitializeMembers, StorageVersion,
|
||||||
},
|
},
|
||||||
weights::{GetDispatchInfo, Pays, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -18,9 +18,10 @@
|
|||||||
use super::{Event as CollectiveEvent, *};
|
use super::{Event as CollectiveEvent, *};
|
||||||
use crate as pallet_collective;
|
use crate as pallet_collective;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_noop, assert_ok, parameter_types,
|
assert_noop, assert_ok,
|
||||||
|
dispatch::Pays,
|
||||||
|
parameter_types,
|
||||||
traits::{ConstU32, ConstU64, GenesisBuild, StorageVersion},
|
traits::{ConstU32, ConstU64, GenesisBuild, StorageVersion},
|
||||||
weights::Pays,
|
|
||||||
Hashable,
|
Hashable,
|
||||||
};
|
};
|
||||||
use frame_system::{EventRecord, Phase};
|
use frame_system::{EventRecord, Phase};
|
||||||
|
|||||||
@@ -107,10 +107,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use codec::{Encode, HasCompact};
|
use codec::{Encode, HasCompact};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::Dispatchable,
|
dispatch::{DispatchClass, Dispatchable, GetDispatchInfo, Pays, PostDispatchInfo},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{ConstU32, Contains, Currency, Get, Randomness, ReservableCurrency, Time},
|
traits::{ConstU32, Contains, Currency, Get, Randomness, ReservableCurrency, Time},
|
||||||
weights::{DispatchClass, GetDispatchInfo, Pays, PostDispatchInfo, Weight},
|
weights::Weight,
|
||||||
BoundedVec,
|
BoundedVec,
|
||||||
};
|
};
|
||||||
use frame_system::{limits::BlockWeights, Pallet as System};
|
use frame_system::{limits::BlockWeights, Pallet as System};
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ use assert_matches::assert_matches;
|
|||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_err, assert_err_ignore_postinfo, assert_noop, assert_ok,
|
assert_err, assert_err_ignore_postinfo, assert_noop, assert_ok,
|
||||||
dispatch::DispatchErrorWithPostInfo,
|
dispatch::{DispatchClass, DispatchErrorWithPostInfo, PostDispatchInfo},
|
||||||
parameter_types,
|
parameter_types,
|
||||||
storage::child,
|
storage::child,
|
||||||
traits::{
|
traits::{
|
||||||
BalanceStatus, ConstU32, ConstU64, Contains, Currency, Get, OnIdle, OnInitialize,
|
BalanceStatus, ConstU32, ConstU64, Contains, Currency, Get, OnIdle, OnInitialize,
|
||||||
ReservableCurrency,
|
ReservableCurrency,
|
||||||
},
|
},
|
||||||
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, PostDispatchInfo, Weight},
|
weights::{constants::WEIGHT_PER_SECOND, Weight},
|
||||||
};
|
};
|
||||||
use frame_system::{self as system, EventRecord, Phase};
|
use frame_system::{self as system, EventRecord, Phase};
|
||||||
use pretty_assertions::{assert_eq, assert_ne};
|
use pretty_assertions::{assert_eq, assert_ne};
|
||||||
|
|||||||
@@ -2314,7 +2314,7 @@ pub mod env {
|
|||||||
call_ptr: u32,
|
call_ptr: u32,
|
||||||
call_len: u32,
|
call_len: u32,
|
||||||
) -> Result<ReturnCode, TrapReason> {
|
) -> Result<ReturnCode, TrapReason> {
|
||||||
use frame_support::{dispatch::GetDispatchInfo, weights::extract_actual_weight};
|
use frame_support::dispatch::{extract_actual_weight, GetDispatchInfo};
|
||||||
ctx.charge_gas(RuntimeCosts::CopyFromContract(call_len))?;
|
ctx.charge_gas(RuntimeCosts::CopyFromContract(call_len))?;
|
||||||
let call: <E::T as Config>::RuntimeCall =
|
let call: <E::T as Config>::RuntimeCall =
|
||||||
ctx.read_sandbox_memory_as_unbounded(call_ptr, call_len)?;
|
ctx.read_sandbox_memory_as_unbounded(call_ptr, call_len)?;
|
||||||
|
|||||||
@@ -234,9 +234,10 @@ use frame_election_provider_support::{
|
|||||||
ElectionDataProvider, ElectionProvider, InstantElectionProvider, NposSolution,
|
ElectionDataProvider, ElectionProvider, InstantElectionProvider, NposSolution,
|
||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::DispatchClass,
|
||||||
ensure,
|
ensure,
|
||||||
traits::{Currency, Get, OnUnbalanced, ReservableCurrency},
|
traits::{Currency, Get, OnUnbalanced, ReservableCurrency},
|
||||||
weights::{DispatchClass, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::{ensure_none, offchain::SendTransactionTypes};
|
use frame_system::{ensure_none, offchain::SendTransactionTypes};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Debug, ElectionDataProvider, ElectionProvider, InstantElectionProvider, NposSolver, WeightInfo,
|
Debug, ElectionDataProvider, ElectionProvider, InstantElectionProvider, NposSolver, WeightInfo,
|
||||||
};
|
};
|
||||||
use frame_support::{traits::Get, weights::DispatchClass};
|
use frame_support::{dispatch::DispatchClass, traits::Get};
|
||||||
use sp_npos_elections::*;
|
use sp_npos_elections::*;
|
||||||
use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData, prelude::*};
|
use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData, prelude::*};
|
||||||
|
|
||||||
|
|||||||
@@ -273,9 +273,9 @@
|
|||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchResult,
|
dispatch::{ClassifyDispatch, DispatchClass, DispatchResult, Pays, PaysFee, WeighData},
|
||||||
traits::IsSubType,
|
traits::IsSubType,
|
||||||
weights::{ClassifyDispatch, DispatchClass, Pays, PaysFee, WeighData, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::ensure_signed;
|
use frame_system::ensure_signed;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_ok, parameter_types,
|
assert_ok,
|
||||||
|
dispatch::{DispatchInfo, GetDispatchInfo},
|
||||||
|
parameter_types,
|
||||||
traits::{ConstU64, OnInitialize},
|
traits::{ConstU64, OnInitialize},
|
||||||
weights::{DispatchInfo, GetDispatchInfo},
|
|
||||||
};
|
};
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
// The testing primitives are very useful for avoiding having to work with signatures
|
// The testing primitives are very useful for avoiding having to work with signatures
|
||||||
|
|||||||
@@ -118,12 +118,12 @@
|
|||||||
|
|
||||||
use codec::{Codec, Encode};
|
use codec::{Codec, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::PostDispatchInfo,
|
dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
|
||||||
traits::{
|
traits::{
|
||||||
EnsureInherentsAreFirst, ExecuteBlock, OffchainWorker, OnFinalize, OnIdle, OnInitialize,
|
EnsureInherentsAreFirst, ExecuteBlock, OffchainWorker, OnFinalize, OnIdle, OnInitialize,
|
||||||
OnRuntimeUpgrade,
|
OnRuntimeUpgrade,
|
||||||
},
|
},
|
||||||
weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
generic::Digest,
|
generic::Digest,
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ use fg_primitives::{
|
|||||||
GRANDPA_ENGINE_ID,
|
GRANDPA_ENGINE_ID,
|
||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchResultWithPostInfo,
|
dispatch::{DispatchResultWithPostInfo, Pays},
|
||||||
pallet_prelude::Get,
|
pallet_prelude::Get,
|
||||||
storage,
|
storage,
|
||||||
traits::{KeyOwnerProofSystem, OneSessionHandler},
|
traits::{KeyOwnerProofSystem, OneSessionHandler},
|
||||||
weights::{Pays, Weight},
|
weights::Weight,
|
||||||
WeakBoundedVec,
|
WeakBoundedVec,
|
||||||
};
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ use codec::Encode;
|
|||||||
use fg_primitives::ScheduledChange;
|
use fg_primitives::ScheduledChange;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_err, assert_noop, assert_ok,
|
assert_err, assert_noop, assert_ok,
|
||||||
|
dispatch::{GetDispatchInfo, Pays},
|
||||||
traits::{Currency, OnFinalize, OneSessionHandler},
|
traits::{Currency, OnFinalize, OneSessionHandler},
|
||||||
weights::{GetDispatchInfo, Pays},
|
|
||||||
};
|
};
|
||||||
use frame_system::{EventRecord, Phase};
|
use frame_system::{EventRecord, Phase};
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
|
|||||||
@@ -53,11 +53,12 @@ pub mod weights;
|
|||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::{
|
dispatch::{
|
||||||
DispatchErrorWithPostInfo, DispatchResult, DispatchResultWithPostInfo, PostDispatchInfo,
|
DispatchErrorWithPostInfo, DispatchResult, DispatchResultWithPostInfo, GetDispatchInfo,
|
||||||
|
PostDispatchInfo,
|
||||||
},
|
},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{Currency, Get, ReservableCurrency, WrapperKeepOpaque},
|
traits::{Currency, Get, ReservableCurrency, WrapperKeepOpaque},
|
||||||
weights::{GetDispatchInfo, Weight},
|
weights::Weight,
|
||||||
RuntimeDebug,
|
RuntimeDebug,
|
||||||
};
|
};
|
||||||
use frame_system::{self as system, RawOrigin};
|
use frame_system::{self as system, RawOrigin};
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ use sp_std::prelude::*;
|
|||||||
|
|
||||||
use codec::{Decode, Encode, MaxEncodedLen};
|
use codec::{Decode, Encode, MaxEncodedLen};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::Pays,
|
||||||
ensure,
|
ensure,
|
||||||
pallet_prelude::Get,
|
pallet_prelude::Get,
|
||||||
traits::{Currency, PreimageProvider, PreimageRecipient, ReservableCurrency},
|
traits::{Currency, PreimageProvider, PreimageRecipient, ReservableCurrency},
|
||||||
weights::Pays,
|
|
||||||
BoundedVec,
|
BoundedVec,
|
||||||
};
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
|
|||||||
@@ -35,10 +35,9 @@ pub mod weights;
|
|||||||
|
|
||||||
use codec::{Decode, Encode, MaxEncodedLen};
|
use codec::{Decode, Encode, MaxEncodedLen};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchError,
|
dispatch::{DispatchError, GetDispatchInfo},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{Currency, Get, InstanceFilter, IsSubType, IsType, OriginTrait, ReservableCurrency},
|
traits::{Currency, Get, InstanceFilter, IsSubType, IsType, OriginTrait, ReservableCurrency},
|
||||||
weights::GetDispatchInfo,
|
|
||||||
RuntimeDebug,
|
RuntimeDebug,
|
||||||
};
|
};
|
||||||
use frame_system::{self as system};
|
use frame_system::{self as system};
|
||||||
|
|||||||
@@ -52,10 +52,9 @@ use sp_std::{marker::PhantomData, prelude::*};
|
|||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
codec::{Decode, Encode, MaxEncodedLen},
|
codec::{Decode, Encode, MaxEncodedLen},
|
||||||
dispatch::{DispatchError, DispatchResultWithPostInfo},
|
dispatch::{DispatchError, DispatchResultWithPostInfo, PostDispatchInfo},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{EnsureOrigin, PollStatus, Polling, VoteTally},
|
traits::{EnsureOrigin, PollStatus, Polling, VoteTally},
|
||||||
weights::PostDispatchInfo,
|
|
||||||
CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
|
CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -160,9 +160,8 @@ use sp_runtime::traits::{CheckedAdd, CheckedMul, Dispatchable, SaturatedConversi
|
|||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::PostDispatchInfo,
|
dispatch::{GetDispatchInfo, PostDispatchInfo},
|
||||||
traits::{BalanceStatus, Currency, ReservableCurrency},
|
traits::{BalanceStatus, Currency, ReservableCurrency},
|
||||||
weights::GetDispatchInfo,
|
|
||||||
BoundedVec, RuntimeDebug,
|
BoundedVec, RuntimeDebug,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ pub mod weights;
|
|||||||
|
|
||||||
use codec::{Codec, Decode, Encode};
|
use codec::{Codec, Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::{DispatchError, DispatchResult, Dispatchable, Parameter},
|
dispatch::{DispatchError, DispatchResult, Dispatchable, GetDispatchInfo, Parameter},
|
||||||
traits::{
|
traits::{
|
||||||
schedule::{self, DispatchTime, MaybeHashed},
|
schedule::{self, DispatchTime, MaybeHashed},
|
||||||
EnsureOrigin, Get, IsType, OriginTrait, PalletInfoAccess, PrivilegeCmp, StorageVersion,
|
EnsureOrigin, Get, IsType, OriginTrait, PalletInfoAccess, PrivilegeCmp, StorageVersion,
|
||||||
},
|
},
|
||||||
weights::{GetDispatchInfo, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::{self as system, ensure_signed};
|
use frame_system::{self as system, ensure_signed};
|
||||||
pub use pallet::*;
|
pub use pallet::*;
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ use frame_election_provider_support::{
|
|||||||
Supports, VoteWeight, VoterOf,
|
Supports, VoteWeight, VoterOf,
|
||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::WithPostDispatchInfo,
|
||||||
pallet_prelude::*,
|
pallet_prelude::*,
|
||||||
traits::{
|
traits::{
|
||||||
Currency, CurrencyToVote, Defensive, EstimateNextNewSession, Get, Imbalance,
|
Currency, CurrencyToVote, Defensive, EstimateNextNewSession, Get, Imbalance,
|
||||||
LockableCurrency, OnUnbalanced, UnixTime, WithdrawReasons,
|
LockableCurrency, OnUnbalanced, UnixTime, WithdrawReasons,
|
||||||
},
|
},
|
||||||
weights::{Weight, WithPostDispatchInfo},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
|
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
|
||||||
use pallet_session::historical;
|
use pallet_session::historical;
|
||||||
|
|||||||
@@ -21,10 +21,9 @@ use super::{ConfigOp, Event, MaxUnlockingChunks, *};
|
|||||||
use frame_election_provider_support::{ElectionProvider, SortedListProvider, Support};
|
use frame_election_provider_support::{ElectionProvider, SortedListProvider, Support};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_noop, assert_ok, assert_storage_noop, bounded_vec,
|
assert_noop, assert_ok, assert_storage_noop, bounded_vec,
|
||||||
dispatch::WithPostDispatchInfo,
|
dispatch::{extract_actual_weight, GetDispatchInfo, WithPostDispatchInfo},
|
||||||
pallet_prelude::*,
|
pallet_prelude::*,
|
||||||
traits::{Currency, Get, ReservableCurrency},
|
traits::{Currency, Get, ReservableCurrency},
|
||||||
weights::{extract_actual_weight, GetDispatchInfo},
|
|
||||||
};
|
};
|
||||||
use mock::*;
|
use mock::*;
|
||||||
use pallet_balances::Error as BalancesError;
|
use pallet_balances::Error as BalancesError;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
use sp_runtime::{traits::StaticLookup, DispatchResult};
|
use sp_runtime::{traits::StaticLookup, DispatchResult};
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
use frame_support::{traits::UnfilteredDispatchable, weights::GetDispatchInfo};
|
use frame_support::{dispatch::GetDispatchInfo, traits::UnfilteredDispatchable};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod mock;
|
mod mock;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ sp-core = { version = "6.0.0", default-features = false, path = "../../primitive
|
|||||||
sp-arithmetic = { version = "5.0.0", default-features = false, path = "../../primitives/arithmetic" }
|
sp-arithmetic = { version = "5.0.0", default-features = false, path = "../../primitives/arithmetic" }
|
||||||
sp-inherents = { version = "4.0.0-dev", default-features = false, path = "../../primitives/inherents" }
|
sp-inherents = { version = "4.0.0-dev", default-features = false, path = "../../primitives/inherents" }
|
||||||
sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../primitives/staking" }
|
sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../primitives/staking" }
|
||||||
|
sp-weights = { version = "4.0.0", default-features = false, path = "../../primitives/weights" }
|
||||||
tt-call = "1.0.8"
|
tt-call = "1.0.8"
|
||||||
frame-support-procedural = { version = "4.0.0-dev", default-features = false, path = "./procedural" }
|
frame-support-procedural = { version = "4.0.0-dev", default-features = false, path = "./procedural" }
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
@@ -62,6 +63,7 @@ std = [
|
|||||||
"sp-inherents/std",
|
"sp-inherents/std",
|
||||||
"sp-staking/std",
|
"sp-staking/std",
|
||||||
"sp-state-machine",
|
"sp-state-machine",
|
||||||
|
"sp-weights/std",
|
||||||
"frame-support-procedural/std",
|
"frame-support-procedural/std",
|
||||||
"log/std",
|
"log/std",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -123,6 +123,9 @@ pub fn expand_outer_dispatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Deprecated, but will warn when used
|
||||||
|
#[allow(deprecated)]
|
||||||
|
impl #scrate::weights::GetDispatchInfo for RuntimeCall {}
|
||||||
impl #scrate::dispatch::GetCallMetadata for RuntimeCall {
|
impl #scrate::dispatch::GetCallMetadata for RuntimeCall {
|
||||||
fn get_call_metadata(&self) -> #scrate::dispatch::CallMetadata {
|
fn get_call_metadata(&self) -> #scrate::dispatch::CallMetadata {
|
||||||
use #scrate::dispatch::GetCallName;
|
use #scrate::dispatch::GetCallName;
|
||||||
@@ -161,8 +164,8 @@ pub fn expand_outer_dispatch(
|
|||||||
impl #scrate::dispatch::Dispatchable for RuntimeCall {
|
impl #scrate::dispatch::Dispatchable for RuntimeCall {
|
||||||
type Origin = Origin;
|
type Origin = Origin;
|
||||||
type Config = RuntimeCall;
|
type Config = RuntimeCall;
|
||||||
type Info = #scrate::weights::DispatchInfo;
|
type Info = #scrate::dispatch::DispatchInfo;
|
||||||
type PostInfo = #scrate::weights::PostDispatchInfo;
|
type PostInfo = #scrate::dispatch::PostDispatchInfo;
|
||||||
fn dispatch(self, origin: Origin) -> #scrate::dispatch::DispatchResultWithPostInfo {
|
fn dispatch(self, origin: Origin) -> #scrate::dispatch::DispatchResultWithPostInfo {
|
||||||
if !<Self::Origin as #scrate::traits::OriginTrait>::filter_call(&origin, &self) {
|
if !<Self::Origin as #scrate::traits::OriginTrait>::filter_call(&origin, &self) {
|
||||||
return #scrate::sp_std::result::Result::Err(
|
return #scrate::sp_std::result::Result::Err(
|
||||||
|
|||||||
@@ -255,6 +255,10 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated, but will warn when used
|
||||||
|
#[allow(deprecated)]
|
||||||
|
impl<#type_impl_gen> #frame_support::weights::GetDispatchInfo for #call_ident<#type_use_gen> #where_clause {}
|
||||||
|
|
||||||
impl<#type_impl_gen> #frame_support::dispatch::GetCallName for #call_ident<#type_use_gen>
|
impl<#type_impl_gen> #frame_support::dispatch::GetCallName for #call_ident<#type_use_gen>
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,18 +31,22 @@ pub use crate::{
|
|||||||
traits::{
|
traits::{
|
||||||
CallMetadata, GetCallMetadata, GetCallName, GetStorageVersion, UnfilteredDispatchable,
|
CallMetadata, GetCallMetadata, GetCallName, GetStorageVersion, UnfilteredDispatchable,
|
||||||
},
|
},
|
||||||
weights::{
|
|
||||||
ClassifyDispatch, DispatchInfo, GetDispatchInfo, PaysFee, PostDispatchInfo,
|
|
||||||
TransactionPriority, WeighData, Weight, WithPostDispatchInfo,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
pub use sp_runtime::{traits::Dispatchable, DispatchError, RuntimeDebug};
|
#[cfg(feature = "std")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sp_runtime::{
|
||||||
|
generic::{CheckedExtrinsic, UncheckedExtrinsic},
|
||||||
|
traits::SignedExtension,
|
||||||
|
};
|
||||||
|
pub use sp_runtime::{
|
||||||
|
traits::Dispatchable, transaction_validity::TransactionPriority, DispatchError, RuntimeDebug,
|
||||||
|
};
|
||||||
|
pub use sp_weights::Weight;
|
||||||
|
|
||||||
/// The return type of a `Dispatchable` in frame. When returned explicitly from
|
/// The return type of a `Dispatchable` in frame. When returned explicitly from
|
||||||
/// a dispatchable function it allows overriding the default `PostDispatchInfo`
|
/// a dispatchable function it allows overriding the default `PostDispatchInfo`
|
||||||
/// returned from a dispatch.
|
/// returned from a dispatch.
|
||||||
pub type DispatchResultWithPostInfo =
|
pub type DispatchResultWithPostInfo = sp_runtime::DispatchResultWithInfo<PostDispatchInfo>;
|
||||||
sp_runtime::DispatchResultWithInfo<crate::weights::PostDispatchInfo>;
|
|
||||||
|
|
||||||
/// Unaugmented version of `DispatchResultWithPostInfo` that can be returned from
|
/// Unaugmented version of `DispatchResultWithPostInfo` that can be returned from
|
||||||
/// dispatchable functions and is automatically converted to the augmented type. Should be
|
/// dispatchable functions and is automatically converted to the augmented type. Should be
|
||||||
@@ -51,8 +55,7 @@ pub type DispatchResultWithPostInfo =
|
|||||||
pub type DispatchResult = Result<(), sp_runtime::DispatchError>;
|
pub type DispatchResult = Result<(), sp_runtime::DispatchError>;
|
||||||
|
|
||||||
/// The error type contained in a `DispatchResultWithPostInfo`.
|
/// The error type contained in a `DispatchResultWithPostInfo`.
|
||||||
pub type DispatchErrorWithPostInfo =
|
pub type DispatchErrorWithPostInfo = sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>;
|
||||||
sp_runtime::DispatchErrorWithPostInfo<crate::weights::PostDispatchInfo>;
|
|
||||||
|
|
||||||
/// Serializable version of pallet dispatchable.
|
/// Serializable version of pallet dispatchable.
|
||||||
pub trait Callable<T> {
|
pub trait Callable<T> {
|
||||||
@@ -91,6 +94,552 @@ impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
|||||||
pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
|
pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
|
||||||
impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
|
impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
|
||||||
|
|
||||||
|
/// Means of classifying a dispatchable function.
|
||||||
|
pub trait ClassifyDispatch<T> {
|
||||||
|
/// Classify the dispatch function based on input data `target` of type `T`. When implementing
|
||||||
|
/// this for a dispatchable, `T` will be a tuple of all arguments given to the function (except
|
||||||
|
/// origin).
|
||||||
|
fn classify_dispatch(&self, target: T) -> DispatchClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indicates if dispatch function should pay fees or not.
|
||||||
|
///
|
||||||
|
/// If set to `Pays::No`, the block resource limits are applied, yet no fee is deducted.
|
||||||
|
pub trait PaysFee<T> {
|
||||||
|
fn pays_fee(&self, _target: T) -> Pays;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Explicit enum to denote if a transaction pays fee or not.
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode, TypeInfo)]
|
||||||
|
pub enum Pays {
|
||||||
|
/// Transactor will pay related fees.
|
||||||
|
Yes,
|
||||||
|
/// Transactor will NOT pay related fees.
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Pays {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Pays> for PostDispatchInfo {
|
||||||
|
fn from(pays_fee: Pays) -> Self {
|
||||||
|
Self { actual_weight: None, pays_fee }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A generalized group of dispatch types.
|
||||||
|
///
|
||||||
|
/// NOTE whenever upgrading the enum make sure to also update
|
||||||
|
/// [DispatchClass::all] and [DispatchClass::non_mandatory] helper functions.
|
||||||
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)]
|
||||||
|
pub enum DispatchClass {
|
||||||
|
/// A normal dispatch.
|
||||||
|
Normal,
|
||||||
|
/// An operational dispatch.
|
||||||
|
Operational,
|
||||||
|
/// A mandatory dispatch. These kinds of dispatch are always included regardless of their
|
||||||
|
/// weight, therefore it is critical that they are separately validated to ensure that a
|
||||||
|
/// malicious validator cannot craft a valid but impossibly heavy block. Usually this just
|
||||||
|
/// means ensuring that the extrinsic can only be included once and that it is always very
|
||||||
|
/// light.
|
||||||
|
///
|
||||||
|
/// Do *NOT* use it for extrinsics that can be heavy.
|
||||||
|
///
|
||||||
|
/// The only real use case for this is inherent extrinsics that are required to execute in a
|
||||||
|
/// block for the block to be valid, and it solves the issue in the case that the block
|
||||||
|
/// initialization is sufficiently heavy to mean that those inherents do not fit into the
|
||||||
|
/// block. Essentially, we assume that in these exceptional circumstances, it is better to
|
||||||
|
/// allow an overweight block to be created than to not allow any block at all to be created.
|
||||||
|
Mandatory,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DispatchClass {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DispatchClass {
|
||||||
|
/// Returns an array containing all dispatch classes.
|
||||||
|
pub fn all() -> &'static [DispatchClass] {
|
||||||
|
&[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an array of all dispatch classes except `Mandatory`.
|
||||||
|
pub fn non_mandatory() -> &'static [DispatchClass] {
|
||||||
|
&[DispatchClass::Normal, DispatchClass::Operational]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait that represents one or many values of given type.
|
||||||
|
///
|
||||||
|
/// Useful to accept as parameter type to let the caller pass either a single value directly
|
||||||
|
/// or an iterator.
|
||||||
|
pub trait OneOrMany<T> {
|
||||||
|
/// The iterator type.
|
||||||
|
type Iter: Iterator<Item = T>;
|
||||||
|
/// Convert this item into an iterator.
|
||||||
|
fn into_iter(self) -> Self::Iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OneOrMany<DispatchClass> for DispatchClass {
|
||||||
|
type Iter = sp_std::iter::Once<DispatchClass>;
|
||||||
|
fn into_iter(self) -> Self::Iter {
|
||||||
|
sp_std::iter::once(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> OneOrMany<DispatchClass> for &'a [DispatchClass] {
|
||||||
|
type Iter = sp_std::iter::Cloned<sp_std::slice::Iter<'a, DispatchClass>>;
|
||||||
|
fn into_iter(self) -> Self::Iter {
|
||||||
|
self.iter().cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A bundle of static information collected from the `#[pallet::weight]` attributes.
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
||||||
|
pub struct DispatchInfo {
|
||||||
|
/// Weight of this transaction.
|
||||||
|
pub weight: Weight,
|
||||||
|
/// Class of this transaction.
|
||||||
|
pub class: DispatchClass,
|
||||||
|
/// Does this transaction pay fees.
|
||||||
|
pub pays_fee: Pays,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `Dispatchable` function (aka transaction) that can carry some static information along with
|
||||||
|
/// it, using the `#[pallet::weight]` attribute.
|
||||||
|
pub trait GetDispatchInfo {
|
||||||
|
/// Return a `DispatchInfo`, containing relevant information of this dispatch.
|
||||||
|
///
|
||||||
|
/// This is done independently of its encoded size.
|
||||||
|
fn get_dispatch_info(&self) -> DispatchInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetDispatchInfo for () {
|
||||||
|
fn get_dispatch_info(&self) -> DispatchInfo {
|
||||||
|
DispatchInfo::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract the actual weight from a dispatch result if any or fall back to the default weight.
|
||||||
|
pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Weight {
|
||||||
|
match result {
|
||||||
|
Ok(post_info) => post_info,
|
||||||
|
Err(err) => &err.post_info,
|
||||||
|
}
|
||||||
|
.calc_actual_weight(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract the actual pays_fee from a dispatch result if any or fall back to the default weight.
|
||||||
|
pub fn extract_actual_pays_fee(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Pays {
|
||||||
|
match result {
|
||||||
|
Ok(post_info) => post_info,
|
||||||
|
Err(err) => &err.post_info,
|
||||||
|
}
|
||||||
|
.pays_fee(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Weight information that is only available post dispatch.
|
||||||
|
/// NOTE: This can only be used to reduce the weight or fee, not increase it.
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
||||||
|
pub struct PostDispatchInfo {
|
||||||
|
/// Actual weight consumed by a call or `None` which stands for the worst case static weight.
|
||||||
|
pub actual_weight: Option<Weight>,
|
||||||
|
/// Whether this transaction should pay fees when all is said and done.
|
||||||
|
pub pays_fee: Pays,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PostDispatchInfo {
|
||||||
|
/// Calculate how much (if any) weight was not used by the `Dispatchable`.
|
||||||
|
pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
|
||||||
|
info.weight - self.calc_actual_weight(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculate how much weight was actually spent by the `Dispatchable`.
|
||||||
|
pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
|
||||||
|
if let Some(actual_weight) = self.actual_weight {
|
||||||
|
actual_weight.min(info.weight)
|
||||||
|
} else {
|
||||||
|
info.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine if user should actually pay fees at the end of the dispatch.
|
||||||
|
pub fn pays_fee(&self, info: &DispatchInfo) -> Pays {
|
||||||
|
// If they originally were not paying fees, or the post dispatch info
|
||||||
|
// says they should not pay fees, then they don't pay fees.
|
||||||
|
// This is because the pre dispatch information must contain the
|
||||||
|
// worst case for weight and fees paid.
|
||||||
|
if info.pays_fee == Pays::No || self.pays_fee == Pays::No {
|
||||||
|
Pays::No
|
||||||
|
} else {
|
||||||
|
// Otherwise they pay.
|
||||||
|
Pays::Yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<()> for PostDispatchInfo {
|
||||||
|
fn from(_: ()) -> Self {
|
||||||
|
Self { actual_weight: None, pays_fee: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_runtime::traits::Printable for PostDispatchInfo {
|
||||||
|
fn print(&self) {
|
||||||
|
"actual_weight=".print();
|
||||||
|
match self.actual_weight {
|
||||||
|
Some(weight) => weight.print(),
|
||||||
|
None => "max-weight".print(),
|
||||||
|
};
|
||||||
|
"pays_fee=".print();
|
||||||
|
match self.pays_fee {
|
||||||
|
Pays::Yes => "Yes".print(),
|
||||||
|
Pays::No => "No".print(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Allows easy conversion from `DispatchError` to `DispatchErrorWithPostInfo` for dispatchables
|
||||||
|
/// that want to return a custom a posterior weight on error.
|
||||||
|
pub trait WithPostDispatchInfo {
|
||||||
|
/// Call this on your modules custom errors type in order to return a custom weight on error.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// let who = ensure_signed(origin).map_err(|e| e.with_weight(Weight::from_ref_time(100)))?;
|
||||||
|
/// ensure!(who == me, Error::<T>::NotMe.with_weight(200_000));
|
||||||
|
/// ```
|
||||||
|
fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WithPostDispatchInfo for T
|
||||||
|
where
|
||||||
|
T: Into<DispatchError>,
|
||||||
|
{
|
||||||
|
fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo {
|
||||||
|
DispatchErrorWithPostInfo {
|
||||||
|
post_info: PostDispatchInfo {
|
||||||
|
actual_weight: Some(actual_weight),
|
||||||
|
pays_fee: Default::default(),
|
||||||
|
},
|
||||||
|
error: self.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation for unchecked extrinsic.
|
||||||
|
impl<Address, Call, Signature, Extra> GetDispatchInfo
|
||||||
|
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||||
|
where
|
||||||
|
Call: GetDispatchInfo,
|
||||||
|
Extra: SignedExtension,
|
||||||
|
{
|
||||||
|
fn get_dispatch_info(&self) -> DispatchInfo {
|
||||||
|
self.function.get_dispatch_info()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation for checked extrinsic.
|
||||||
|
impl<AccountId, Call, Extra> GetDispatchInfo for CheckedExtrinsic<AccountId, Call, Extra>
|
||||||
|
where
|
||||||
|
Call: GetDispatchInfo,
|
||||||
|
{
|
||||||
|
fn get_dispatch_info(&self) -> DispatchInfo {
|
||||||
|
self.function.get_dispatch_info()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation for test extrinsic.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<Call: Encode, Extra: Encode> GetDispatchInfo for sp_runtime::testing::TestXt<Call, Extra> {
|
||||||
|
fn get_dispatch_info(&self) -> DispatchInfo {
|
||||||
|
// for testing: weight == size.
|
||||||
|
DispatchInfo {
|
||||||
|
weight: Weight::from_ref_time(self.encode().len() as _),
|
||||||
|
pays_fee: Pays::Yes,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A struct holding value for each `DispatchClass`.
|
||||||
|
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
|
||||||
|
pub struct PerDispatchClass<T> {
|
||||||
|
/// Value for `Normal` extrinsics.
|
||||||
|
normal: T,
|
||||||
|
/// Value for `Operational` extrinsics.
|
||||||
|
operational: T,
|
||||||
|
/// Value for `Mandatory` extrinsics.
|
||||||
|
mandatory: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PerDispatchClass<T> {
|
||||||
|
/// Create new `PerDispatchClass` with the same value for every class.
|
||||||
|
pub fn new(val: impl Fn(DispatchClass) -> T) -> Self {
|
||||||
|
Self {
|
||||||
|
normal: val(DispatchClass::Normal),
|
||||||
|
operational: val(DispatchClass::Operational),
|
||||||
|
mandatory: val(DispatchClass::Mandatory),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to current value of given class.
|
||||||
|
pub fn get_mut(&mut self, class: DispatchClass) -> &mut T {
|
||||||
|
match class {
|
||||||
|
DispatchClass::Operational => &mut self.operational,
|
||||||
|
DispatchClass::Normal => &mut self.normal,
|
||||||
|
DispatchClass::Mandatory => &mut self.mandatory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get current value for given class.
|
||||||
|
pub fn get(&self, class: DispatchClass) -> &T {
|
||||||
|
match class {
|
||||||
|
DispatchClass::Normal => &self.normal,
|
||||||
|
DispatchClass::Operational => &self.operational,
|
||||||
|
DispatchClass::Mandatory => &self.mandatory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> PerDispatchClass<T> {
|
||||||
|
/// Set the value of given class.
|
||||||
|
pub fn set(&mut self, new: T, class: impl OneOrMany<DispatchClass>) {
|
||||||
|
for class in class.into_iter() {
|
||||||
|
*self.get_mut(class) = new.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PerDispatchClass<Weight> {
|
||||||
|
/// Returns the total weight consumed by all extrinsics in the block.
|
||||||
|
pub fn total(&self) -> Weight {
|
||||||
|
let mut sum = Weight::zero();
|
||||||
|
for class in DispatchClass::all() {
|
||||||
|
sum = sum.saturating_add(*self.get(*class));
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`.
|
||||||
|
pub fn add(&mut self, weight: Weight, class: DispatchClass) {
|
||||||
|
let value = self.get_mut(class);
|
||||||
|
*value = value.saturating_add(weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would
|
||||||
|
/// occur.
|
||||||
|
pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> {
|
||||||
|
let value = self.get_mut(class);
|
||||||
|
*value = value.checked_add(&weight).ok_or(())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of
|
||||||
|
/// `Weight`.
|
||||||
|
pub fn sub(&mut self, weight: Weight, class: DispatchClass) {
|
||||||
|
let value = self.get_mut(class);
|
||||||
|
*value = value.saturating_sub(weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Means of weighing some particular kind of data (`T`).
|
||||||
|
pub trait WeighData<T> {
|
||||||
|
/// Weigh the data `T` given by `target`. When implementing this for a dispatchable, `T` will be
|
||||||
|
/// a tuple of all arguments given to the function (except origin).
|
||||||
|
fn weigh_data(&self, target: T) -> Weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for Weight {
|
||||||
|
fn weigh_data(&self, _: T) -> Weight {
|
||||||
|
return *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for (Weight, DispatchClass, Pays) {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
self.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for (Weight, DispatchClass) {
|
||||||
|
fn weigh_data(&self, args: T) -> Weight {
|
||||||
|
return self.0.weigh_data(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for (Weight, DispatchClass, Pays) {
|
||||||
|
fn weigh_data(&self, args: T) -> Weight {
|
||||||
|
return self.0.weigh_data(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for (Weight, DispatchClass) {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for (Weight, DispatchClass) {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
Pays::Yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for (Weight, Pays) {
|
||||||
|
fn weigh_data(&self, args: T) -> Weight {
|
||||||
|
return self.0.weigh_data(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for (Weight, Pays) {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
DispatchClass::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for (Weight, Pays) {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Option<Weight>, Pays)> for PostDispatchInfo {
|
||||||
|
fn from(post_weight_info: (Option<Weight>, Pays)) -> Self {
|
||||||
|
let (actual_weight, pays_fee) = post_weight_info;
|
||||||
|
Self { actual_weight, pays_fee }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Option<Weight>> for PostDispatchInfo {
|
||||||
|
fn from(actual_weight: Option<Weight>) -> Self {
|
||||||
|
Self { actual_weight, pays_fee: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for Weight {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
DispatchClass::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for Weight {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
Pays::Yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for (Weight, DispatchClass, Pays) {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Eventually remove these
|
||||||
|
|
||||||
|
impl From<Option<u64>> for PostDispatchInfo {
|
||||||
|
fn from(maybe_actual_computation: Option<u64>) -> Self {
|
||||||
|
let actual_weight = match maybe_actual_computation {
|
||||||
|
Some(actual_computation) => Some(Weight::zero().set_ref_time(actual_computation)),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
Self { actual_weight, pays_fee: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Option<u64>, Pays)> for PostDispatchInfo {
|
||||||
|
fn from(post_weight_info: (Option<u64>, Pays)) -> Self {
|
||||||
|
let (maybe_actual_time, pays_fee) = post_weight_info;
|
||||||
|
let actual_weight = match maybe_actual_time {
|
||||||
|
Some(actual_time) => Some(Weight::zero().set_ref_time(actual_time)),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
Self { actual_weight, pays_fee }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for u64 {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
DispatchClass::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for u64 {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
Pays::Yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for u64 {
|
||||||
|
fn weigh_data(&self, _: T) -> Weight {
|
||||||
|
return Weight::zero().set_ref_time(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for (u64, DispatchClass, Pays) {
|
||||||
|
fn weigh_data(&self, args: T) -> Weight {
|
||||||
|
return self.0.weigh_data(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for (u64, DispatchClass, Pays) {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for (u64, DispatchClass, Pays) {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
self.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for (u64, DispatchClass) {
|
||||||
|
fn weigh_data(&self, args: T) -> Weight {
|
||||||
|
return self.0.weigh_data(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for (u64, DispatchClass) {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for (u64, DispatchClass) {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
Pays::Yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeighData<T> for (u64, Pays) {
|
||||||
|
fn weigh_data(&self, args: T) -> Weight {
|
||||||
|
return self.0.weigh_data(args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ClassifyDispatch<T> for (u64, Pays) {
|
||||||
|
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
||||||
|
DispatchClass::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaysFee<T> for (u64, Pays) {
|
||||||
|
fn pays_fee(&self, _: T) -> Pays {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// END TODO
|
||||||
|
|
||||||
/// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic.
|
/// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic.
|
||||||
///
|
///
|
||||||
/// ## Declaration
|
/// ## Declaration
|
||||||
@@ -2629,13 +3178,14 @@ macro_rules! __check_reserved_fn_name {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
dispatch::{DispatchClass, DispatchInfo, Pays},
|
||||||
metadata::*,
|
metadata::*,
|
||||||
traits::{
|
traits::{
|
||||||
CrateVersion, Get, GetCallName, IntegrityTest, OnFinalize, OnIdle, OnInitialize,
|
CrateVersion, Get, GetCallName, IntegrityTest, OnFinalize, OnIdle, OnInitialize,
|
||||||
OnRuntimeUpgrade, PalletInfo,
|
OnRuntimeUpgrade, PalletInfo,
|
||||||
},
|
},
|
||||||
weights::{DispatchClass, DispatchInfo, Pays, RuntimeDbWeight},
|
|
||||||
};
|
};
|
||||||
|
use sp_weights::RuntimeDbWeight;
|
||||||
|
|
||||||
pub trait Config: system::Config + Sized
|
pub trait Config: system::Config + Sized
|
||||||
where
|
where
|
||||||
@@ -2940,3 +3490,187 @@ mod tests {
|
|||||||
Call::<TraitImpl>::new_call_variant_aux_0();
|
Call::<TraitImpl>::new_call_variant_aux_0();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
// Do not complain about unused `dispatch` and `dispatch_aux`.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
mod weight_tests {
|
||||||
|
use super::*;
|
||||||
|
use sp_core::{parameter_types, Get};
|
||||||
|
use sp_weights::RuntimeDbWeight;
|
||||||
|
|
||||||
|
pub trait Config: 'static {
|
||||||
|
type Origin;
|
||||||
|
type Balance;
|
||||||
|
type BlockNumber;
|
||||||
|
type DbWeight: Get<RuntimeDbWeight>;
|
||||||
|
type PalletInfo: crate::traits::PalletInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TraitImpl {}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
||||||
|
read: 100,
|
||||||
|
write: 1000,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config for TraitImpl {
|
||||||
|
type Origin = u32;
|
||||||
|
type BlockNumber = u32;
|
||||||
|
type Balance = u32;
|
||||||
|
type DbWeight = DbWeight;
|
||||||
|
type PalletInfo = crate::tests::PanicPalletInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
decl_module! {
|
||||||
|
pub struct Module<T: Config> for enum Call where origin: T::Origin, system=self {
|
||||||
|
// no arguments, fixed weight
|
||||||
|
#[weight = 1000]
|
||||||
|
fn f00(_origin) { unimplemented!(); }
|
||||||
|
|
||||||
|
#[weight = (1000, DispatchClass::Mandatory)]
|
||||||
|
fn f01(_origin) { unimplemented!(); }
|
||||||
|
|
||||||
|
#[weight = (1000, Pays::No)]
|
||||||
|
fn f02(_origin) { unimplemented!(); }
|
||||||
|
|
||||||
|
#[weight = (1000, DispatchClass::Operational, Pays::No)]
|
||||||
|
fn f03(_origin) { unimplemented!(); }
|
||||||
|
|
||||||
|
// weight = a x 10 + b
|
||||||
|
#[weight = ((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes)]
|
||||||
|
fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); }
|
||||||
|
|
||||||
|
#[weight = (0, DispatchClass::Operational, Pays::Yes)]
|
||||||
|
fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); }
|
||||||
|
|
||||||
|
#[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + Weight::from_ref_time(10_000)]
|
||||||
|
fn f20(_origin) { unimplemented!(); }
|
||||||
|
|
||||||
|
#[weight = T::DbWeight::get().reads_writes(6, 5) + Weight::from_ref_time(40_000)]
|
||||||
|
fn f21(_origin) { unimplemented!(); }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn weights_are_correct() {
|
||||||
|
// #[weight = 1000]
|
||||||
|
let info = Call::<TraitImpl>::f00 {}.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
||||||
|
assert_eq!(info.class, DispatchClass::Normal);
|
||||||
|
assert_eq!(info.pays_fee, Pays::Yes);
|
||||||
|
|
||||||
|
// #[weight = (1000, DispatchClass::Mandatory)]
|
||||||
|
let info = Call::<TraitImpl>::f01 {}.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
||||||
|
assert_eq!(info.class, DispatchClass::Mandatory);
|
||||||
|
assert_eq!(info.pays_fee, Pays::Yes);
|
||||||
|
|
||||||
|
// #[weight = (1000, Pays::No)]
|
||||||
|
let info = Call::<TraitImpl>::f02 {}.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
||||||
|
assert_eq!(info.class, DispatchClass::Normal);
|
||||||
|
assert_eq!(info.pays_fee, Pays::No);
|
||||||
|
|
||||||
|
// #[weight = (1000, DispatchClass::Operational, Pays::No)]
|
||||||
|
let info = Call::<TraitImpl>::f03 {}.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
||||||
|
assert_eq!(info.class, DispatchClass::Operational);
|
||||||
|
assert_eq!(info.pays_fee, Pays::No);
|
||||||
|
|
||||||
|
// #[weight = ((_a * 10 + _eb * 1) as Weight, DispatchClass::Normal, Pays::Yes)]
|
||||||
|
let info = Call::<TraitImpl>::f11 { _a: 13, _eb: 20 }.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(150)); // 13*10 + 20
|
||||||
|
assert_eq!(info.class, DispatchClass::Normal);
|
||||||
|
assert_eq!(info.pays_fee, Pays::Yes);
|
||||||
|
|
||||||
|
// #[weight = (0, DispatchClass::Operational, Pays::Yes)]
|
||||||
|
let info = Call::<TraitImpl>::f12 { _a: 10, _eb: 20 }.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(0));
|
||||||
|
assert_eq!(info.class, DispatchClass::Operational);
|
||||||
|
assert_eq!(info.pays_fee, Pays::Yes);
|
||||||
|
|
||||||
|
// #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000]
|
||||||
|
let info = Call::<TraitImpl>::f20 {}.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(12300)); // 100*3 + 1000*2 + 10_1000
|
||||||
|
assert_eq!(info.class, DispatchClass::Normal);
|
||||||
|
assert_eq!(info.pays_fee, Pays::Yes);
|
||||||
|
|
||||||
|
// #[weight = T::DbWeight::get().reads_writes(6, 5) + 40_000]
|
||||||
|
let info = Call::<TraitImpl>::f21 {}.get_dispatch_info();
|
||||||
|
assert_eq!(info.weight, Weight::from_ref_time(45600)); // 100*6 + 1000*5 + 40_1000
|
||||||
|
assert_eq!(info.class, DispatchClass::Normal);
|
||||||
|
assert_eq!(info.pays_fee, Pays::Yes);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_actual_weight_works() {
|
||||||
|
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
|
||||||
|
assert_eq!(extract_actual_weight(&Ok(Some(7).into()), &pre), Weight::from_ref_time(7));
|
||||||
|
assert_eq!(
|
||||||
|
extract_actual_weight(&Ok(Some(1000).into()), &pre),
|
||||||
|
Weight::from_ref_time(1000)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
extract_actual_weight(
|
||||||
|
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(9))),
|
||||||
|
&pre
|
||||||
|
),
|
||||||
|
Weight::from_ref_time(9)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_actual_weight_caps_at_pre_weight() {
|
||||||
|
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
|
||||||
|
assert_eq!(
|
||||||
|
extract_actual_weight(&Ok(Some(1250).into()), &pre),
|
||||||
|
Weight::from_ref_time(1000)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
extract_actual_weight(
|
||||||
|
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(1300))),
|
||||||
|
&pre
|
||||||
|
),
|
||||||
|
Weight::from_ref_time(1000),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_actual_pays_fee_works() {
|
||||||
|
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok(Some(7).into()), &pre), Pays::Yes);
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok(Some(1000).into()), &pre), Pays::Yes);
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::Yes).into()), &pre), Pays::Yes);
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::No).into()), &pre), Pays::No);
|
||||||
|
assert_eq!(
|
||||||
|
extract_actual_pays_fee(
|
||||||
|
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(9))),
|
||||||
|
&pre
|
||||||
|
),
|
||||||
|
Pays::Yes
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
extract_actual_pays_fee(
|
||||||
|
&Err(DispatchErrorWithPostInfo {
|
||||||
|
post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::No },
|
||||||
|
error: DispatchError::BadOrigin,
|
||||||
|
}),
|
||||||
|
&pre
|
||||||
|
),
|
||||||
|
Pays::No
|
||||||
|
);
|
||||||
|
|
||||||
|
let pre = DispatchInfo {
|
||||||
|
weight: Weight::from_ref_time(1000),
|
||||||
|
pays_fee: Pays::No,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok(Some(7).into()), &pre), Pays::No);
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok(Some(1000).into()), &pre), Pays::No);
|
||||||
|
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::Yes).into()), &pre), Pays::No);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1376,7 +1376,10 @@ pub mod pallet_prelude {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use crate::traits::GenesisBuild;
|
pub use crate::traits::GenesisBuild;
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
dispatch::{DispatchError, DispatchResult, DispatchResultWithPostInfo, Parameter},
|
dispatch::{
|
||||||
|
DispatchClass, DispatchError, DispatchResult, DispatchResultWithPostInfo, Parameter,
|
||||||
|
Pays,
|
||||||
|
},
|
||||||
ensure,
|
ensure,
|
||||||
inherent::{InherentData, InherentIdentifier, ProvideInherent},
|
inherent::{InherentData, InherentIdentifier, ProvideInherent},
|
||||||
storage,
|
storage,
|
||||||
@@ -1391,7 +1394,6 @@ pub mod pallet_prelude {
|
|||||||
ConstU32, EnsureOrigin, Get, GetDefault, GetStorageVersion, Hooks, IsType,
|
ConstU32, EnsureOrigin, Get, GetDefault, GetStorageVersion, Hooks, IsType,
|
||||||
PalletInfoAccess, StorageInfoTrait, StorageVersion, TypedGet,
|
PalletInfoAccess, StorageInfoTrait, StorageVersion, TypedGet,
|
||||||
},
|
},
|
||||||
weights::{DispatchClass, Pays, Weight},
|
|
||||||
Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity,
|
Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity,
|
||||||
PartialEqNoBound, RuntimeDebug, RuntimeDebugNoBound, Twox128, Twox256, Twox64Concat,
|
PartialEqNoBound, RuntimeDebug, RuntimeDebugNoBound, Twox128, Twox256, Twox64Concat,
|
||||||
};
|
};
|
||||||
@@ -1407,6 +1409,7 @@ pub mod pallet_prelude {
|
|||||||
MAX_MODULE_ERROR_ENCODED_SIZE,
|
MAX_MODULE_ERROR_ENCODED_SIZE,
|
||||||
};
|
};
|
||||||
pub use sp_std::marker::PhantomData;
|
pub use sp_std::marker::PhantomData;
|
||||||
|
pub use sp_weights::Weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `pallet` attribute macro allows to define a pallet to be used in `construct_runtime!`.
|
/// `pallet` attribute macro allows to define a pallet to be used in `construct_runtime!`.
|
||||||
|
|||||||
@@ -711,13 +711,13 @@ pub trait EstimateCallFee<Call, Balance> {
|
|||||||
///
|
///
|
||||||
/// The dispatch info and the length is deduced from the call. The post info can optionally be
|
/// The dispatch info and the length is deduced from the call. The post info can optionally be
|
||||||
/// provided.
|
/// provided.
|
||||||
fn estimate_call_fee(call: &Call, post_info: crate::weights::PostDispatchInfo) -> Balance;
|
fn estimate_call_fee(call: &Call, post_info: crate::dispatch::PostDispatchInfo) -> Balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Useful for building mocks.
|
// Useful for building mocks.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
|
impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
|
||||||
fn estimate_call_fee(_: &Call, _: crate::weights::PostDispatchInfo) -> Balance {
|
fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
|
||||||
T.into()
|
T.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,102 +15,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//! # Primitives for transaction weighting.
|
//! Re-exports `sp-weights` public API, and contains benchmarked weight constants specific to
|
||||||
//!
|
//! FRAME.
|
||||||
//! Every dispatchable function is responsible for providing `#[weight = $x]` attribute. In this
|
|
||||||
//! snipped, `$x` can be any user provided struct that implements the following traits:
|
|
||||||
//!
|
|
||||||
//! - [`WeighData`]: the weight amount.
|
|
||||||
//! - [`ClassifyDispatch`]: class of the dispatch.
|
|
||||||
//! - [`PaysFee`]: whether this weight should be translated to fee and deducted upon dispatch.
|
|
||||||
//!
|
|
||||||
//! Substrate then bundles the output information of the three traits into [`DispatchInfo`] struct
|
|
||||||
//! and provides it by implementing the [`GetDispatchInfo`] for all `Call` both inner and outer call
|
|
||||||
//! types.
|
|
||||||
//!
|
|
||||||
//! Substrate provides two pre-defined ways to annotate weight:
|
|
||||||
//!
|
|
||||||
//! ### 1. Fixed values
|
|
||||||
//!
|
|
||||||
//! This can only be used when all 3 traits can be resolved statically. You have 3 degrees of
|
|
||||||
//! configuration:
|
|
||||||
//!
|
|
||||||
//! 1. Define only weight, **in which case `ClassifyDispatch` will be `Normal` and `PaysFee` will be
|
|
||||||
//! `Yes`**.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use frame_system::Config;
|
|
||||||
//! frame_support::decl_module! {
|
|
||||||
//! pub struct Module<T: Config> for enum Call where origin: T::Origin {
|
|
||||||
//! #[weight = 1000]
|
|
||||||
//! fn dispatching(origin) { unimplemented!() }
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! # fn main() {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! 2.1 Define weight and class, **in which case `PaysFee` would be `Yes`**.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use frame_system::Config;
|
|
||||||
//! # use frame_support::weights::DispatchClass;
|
|
||||||
//! frame_support::decl_module! {
|
|
||||||
//! pub struct Module<T: Config> for enum Call where origin: T::Origin {
|
|
||||||
//! #[weight = (1000, DispatchClass::Operational)]
|
|
||||||
//! fn dispatching(origin) { unimplemented!() }
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! # fn main() {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! 2.2 Define weight and `PaysFee`, **in which case `ClassifyDispatch` would be `Normal`**.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use frame_system::Config;
|
|
||||||
//! # use frame_support::weights::Pays;
|
|
||||||
//! frame_support::decl_module! {
|
|
||||||
//! pub struct Module<T: Config> for enum Call where origin: T::Origin {
|
|
||||||
//! #[weight = (1000, Pays::No)]
|
|
||||||
//! fn dispatching(origin) { unimplemented!() }
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! # fn main() {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! 3. Define all 3 parameters.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use frame_system::Config;
|
|
||||||
//! # use frame_support::weights::{DispatchClass, Pays};
|
|
||||||
//! frame_support::decl_module! {
|
|
||||||
//! pub struct Module<T: Config> for enum Call where origin: T::Origin {
|
|
||||||
//! #[weight = (1000, DispatchClass::Operational, Pays::No)]
|
|
||||||
//! fn dispatching(origin) { unimplemented!() }
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! # fn main() {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! ### 2. Define weights as a function of input arguments.
|
|
||||||
//!
|
|
||||||
//! The arguments of the dispatch are available in the weight expressions as a borrowed value.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use frame_system::Config;
|
|
||||||
//! # use frame_support::weights::{DispatchClass, Pays};
|
|
||||||
//! frame_support::decl_module! {
|
|
||||||
//! pub struct Module<T: Config> for enum Call where origin: T::Origin {
|
|
||||||
//! #[weight = (
|
|
||||||
//! *a as u64 + *b,
|
|
||||||
//! DispatchClass::Operational,
|
|
||||||
//! if *a > 1000 { Pays::Yes } else { Pays::No }
|
|
||||||
//! )]
|
|
||||||
//! fn dispatching(origin, a: u32, b: u64) { unimplemented!() }
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! # fn main() {}
|
|
||||||
//! ```
|
|
||||||
//! FRAME assumes a weight of `1_000_000_000_000` equals 1 second of compute on a standard machine.
|
|
||||||
//!
|
//!
|
||||||
//! Latest machine specification used to benchmark are:
|
//! Latest machine specification used to benchmark are:
|
||||||
//! - Digital Ocean: ubuntu-s-2vcpu-4gb-ams3-01
|
//! - Digital Ocean: ubuntu-s-2vcpu-4gb-ams3-01
|
||||||
@@ -123,41 +29,14 @@ mod block_weights;
|
|||||||
mod extrinsic_weights;
|
mod extrinsic_weights;
|
||||||
mod paritydb_weights;
|
mod paritydb_weights;
|
||||||
mod rocksdb_weights;
|
mod rocksdb_weights;
|
||||||
mod weight_v2;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::dispatch;
|
||||||
dispatch::{DispatchError, DispatchErrorWithPostInfo, DispatchResultWithPostInfo},
|
pub use sp_weights::*;
|
||||||
traits::Get,
|
|
||||||
};
|
|
||||||
use codec::{Decode, Encode, MaxEncodedLen};
|
|
||||||
use scale_info::TypeInfo;
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use sp_arithmetic::{
|
|
||||||
traits::{BaseArithmetic, Saturating, Unsigned},
|
|
||||||
Perbill,
|
|
||||||
};
|
|
||||||
use sp_runtime::{
|
|
||||||
generic::{CheckedExtrinsic, UncheckedExtrinsic},
|
|
||||||
traits::{SaturatedConversion, SignedExtension},
|
|
||||||
RuntimeDebug,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Re-export priority as type
|
|
||||||
pub use sp_runtime::transaction_validity::TransactionPriority;
|
|
||||||
|
|
||||||
pub use weight_v2::*;
|
|
||||||
|
|
||||||
/// These constants are specific to FRAME, and the current implementation of its various components.
|
/// These constants are specific to FRAME, and the current implementation of its various components.
|
||||||
/// For example: FRAME System, FRAME Executive, our FRAME support libraries, etc...
|
/// For example: FRAME System, FRAME Executive, our FRAME support libraries, etc...
|
||||||
pub mod constants {
|
pub mod constants {
|
||||||
use super::Weight;
|
pub use sp_weights::constants::*;
|
||||||
|
|
||||||
pub const WEIGHT_PER_SECOND: Weight = Weight::from_ref_time(1_000_000_000_000);
|
|
||||||
pub const WEIGHT_PER_MILLIS: Weight = Weight::from_ref_time(1_000_000_000);
|
|
||||||
pub const WEIGHT_PER_MICROS: Weight = Weight::from_ref_time(1_000_000);
|
|
||||||
pub const WEIGHT_PER_NANOS: Weight = Weight::from_ref_time(1_000);
|
|
||||||
|
|
||||||
// Expose the Block and Extrinsic base weights.
|
// Expose the Block and Extrinsic base weights.
|
||||||
pub use super::{block_weights::BlockExecutionWeight, extrinsic_weights::ExtrinsicBaseWeight};
|
pub use super::{block_weights::BlockExecutionWeight, extrinsic_weights::ExtrinsicBaseWeight};
|
||||||
@@ -168,786 +47,69 @@ pub mod constants {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Means of weighing some particular kind of data (`T`).
|
#[deprecated = "Function has moved to `frame_support::dispatch`"]
|
||||||
pub trait WeighData<T> {
|
pub fn extract_actual_pays_fee(
|
||||||
/// Weigh the data `T` given by `target`. When implementing this for a dispatchable, `T` will be
|
res: &dispatch::DispatchResultWithPostInfo,
|
||||||
/// a tuple of all arguments given to the function (except origin).
|
info: &dispatch::DispatchInfo,
|
||||||
fn weigh_data(&self, target: T) -> Weight;
|
) -> dispatch::Pays {
|
||||||
|
dispatch::extract_actual_pays_fee(res, info)
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Function has moved to `frame_support::dispatch`"]
|
||||||
/// Means of classifying a dispatchable function.
|
pub fn extract_actual_weight(
|
||||||
pub trait ClassifyDispatch<T> {
|
res: &dispatch::DispatchResultWithPostInfo,
|
||||||
/// Classify the dispatch function based on input data `target` of type `T`. When implementing
|
info: &dispatch::DispatchInfo,
|
||||||
/// this for a dispatchable, `T` will be a tuple of all arguments given to the function (except
|
) -> Weight {
|
||||||
/// origin).
|
dispatch::extract_actual_weight(res, info)
|
||||||
fn classify_dispatch(&self, target: T) -> DispatchClass;
|
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Trait has moved to `frame_support::dispatch`"]
|
||||||
/// Indicates if dispatch function should pay fees or not.
|
pub trait ClassifyDispatch<T>: dispatch::ClassifyDispatch<T> {
|
||||||
/// If set to `Pays::No`, the block resource limits are applied, yet no fee is deducted.
|
fn classify_dispatch(&self, target: T) -> dispatch::DispatchClass {
|
||||||
pub trait PaysFee<T> {
|
<Self as dispatch::ClassifyDispatch<T>>::classify_dispatch(self, target)
|
||||||
fn pays_fee(&self, _target: T) -> Pays;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Explicit enum to denote if a transaction pays fee or not.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode, TypeInfo)]
|
|
||||||
pub enum Pays {
|
|
||||||
/// Transactor will pay related fees.
|
|
||||||
Yes,
|
|
||||||
/// Transactor will NOT pay related fees.
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Pays {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Yes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Enum has moved to `frame_support::dispatch`"]
|
||||||
impl From<Pays> for PostDispatchInfo {
|
pub type DispatchClass = dispatch::DispatchClass;
|
||||||
fn from(pays_fee: Pays) -> Self {
|
#[deprecated = "Struct has moved to `frame_support::dispatch`"]
|
||||||
Self { actual_weight: None, pays_fee }
|
pub type DispatchInfo = dispatch::DispatchInfo;
|
||||||
|
#[deprecated = "Trait has moved to `frame_support::dispatch`"]
|
||||||
|
pub trait GetDispatchInfo: dispatch::GetDispatchInfo {
|
||||||
|
fn get_dispatch_info(&self) -> dispatch::DispatchInfo {
|
||||||
|
<Self as dispatch::GetDispatchInfo>::get_dispatch_info(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Trait has moved to `frame_support::dispatch`"]
|
||||||
/// A generalized group of dispatch types.
|
pub trait OneOrMany<T>: dispatch::OneOrMany<T> {
|
||||||
///
|
fn into_iter(self) -> Self::Iter
|
||||||
/// NOTE whenever upgrading the enum make sure to also update
|
where
|
||||||
/// [DispatchClass::all] and [DispatchClass::non_mandatory] helper functions.
|
Self: Sized,
|
||||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
{
|
||||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
<Self as dispatch::OneOrMany<T>>::into_iter(self)
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)]
|
|
||||||
pub enum DispatchClass {
|
|
||||||
/// A normal dispatch.
|
|
||||||
Normal,
|
|
||||||
/// An operational dispatch.
|
|
||||||
Operational,
|
|
||||||
/// A mandatory dispatch. These kinds of dispatch are always included regardless of their
|
|
||||||
/// weight, therefore it is critical that they are separately validated to ensure that a
|
|
||||||
/// malicious validator cannot craft a valid but impossibly heavy block. Usually this just
|
|
||||||
/// means ensuring that the extrinsic can only be included once and that it is always very
|
|
||||||
/// light.
|
|
||||||
///
|
|
||||||
/// Do *NOT* use it for extrinsics that can be heavy.
|
|
||||||
///
|
|
||||||
/// The only real use case for this is inherent extrinsics that are required to execute in a
|
|
||||||
/// block for the block to be valid, and it solves the issue in the case that the block
|
|
||||||
/// initialization is sufficiently heavy to mean that those inherents do not fit into the
|
|
||||||
/// block. Essentially, we assume that in these exceptional circumstances, it is better to
|
|
||||||
/// allow an overweight block to be created than to not allow any block at all to be created.
|
|
||||||
Mandatory,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for DispatchClass {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Normal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Enum has moved to `frame_support::dispatch`"]
|
||||||
impl DispatchClass {
|
pub type Pays = dispatch::Pays;
|
||||||
/// Returns an array containing all dispatch classes.
|
#[deprecated = "Trait has moved to `frame_support::dispatch`"]
|
||||||
pub fn all() -> &'static [DispatchClass] {
|
pub trait PaysFee<T>: dispatch::PaysFee<T> {
|
||||||
&[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory]
|
fn pays_fee(&self, target: T) -> dispatch::Pays {
|
||||||
}
|
<Self as dispatch::PaysFee<T>>::pays_fee(self, target)
|
||||||
|
|
||||||
/// Returns an array of all dispatch classes except `Mandatory`.
|
|
||||||
pub fn non_mandatory() -> &'static [DispatchClass] {
|
|
||||||
&[DispatchClass::Normal, DispatchClass::Operational]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Struct has moved to `frame_support::dispatch`"]
|
||||||
/// A trait that represents one or many values of given type.
|
pub type PerDispatchClass<T> = dispatch::PerDispatchClass<T>;
|
||||||
///
|
#[deprecated = "Struct has moved to `frame_support::dispatch`"]
|
||||||
/// Useful to accept as parameter type to let the caller pass either a single value directly
|
pub type PostDispatchInfo = dispatch::PostDispatchInfo;
|
||||||
/// or an iterator.
|
#[deprecated = "Trait has moved to `frame_support::dispatch`"]
|
||||||
pub trait OneOrMany<T> {
|
pub trait WeighData<T>: dispatch::WeighData<T> {
|
||||||
/// The iterator type.
|
fn weigh_data(&self, target: T) -> Weight {
|
||||||
type Iter: Iterator<Item = T>;
|
<Self as dispatch::WeighData<T>>::weigh_data(self, target)
|
||||||
/// Convert this item into an iterator.
|
|
||||||
fn into_iter(self) -> Self::Iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OneOrMany<DispatchClass> for DispatchClass {
|
|
||||||
type Iter = sp_std::iter::Once<DispatchClass>;
|
|
||||||
fn into_iter(self) -> Self::Iter {
|
|
||||||
sp_std::iter::once(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[deprecated = "Trait has moved to `frame_support::dispatch`"]
|
||||||
impl<'a> OneOrMany<DispatchClass> for &'a [DispatchClass] {
|
pub trait WithPostDispatchInfo: dispatch::WithPostDispatchInfo {
|
||||||
type Iter = sp_std::iter::Cloned<sp_std::slice::Iter<'a, DispatchClass>>;
|
fn with_weight(self, actual_weight: Weight) -> dispatch::DispatchErrorWithPostInfo
|
||||||
fn into_iter(self) -> Self::Iter {
|
where
|
||||||
self.iter().cloned()
|
Self: Sized,
|
||||||
}
|
{
|
||||||
}
|
<Self as dispatch::WithPostDispatchInfo>::with_weight(self, actual_weight)
|
||||||
|
|
||||||
/// A bundle of static information collected from the `#[weight = $x]` attributes.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
|
||||||
pub struct DispatchInfo {
|
|
||||||
/// Weight of this transaction.
|
|
||||||
pub weight: Weight,
|
|
||||||
/// Class of this transaction.
|
|
||||||
pub class: DispatchClass,
|
|
||||||
/// Does this transaction pay fees.
|
|
||||||
pub pays_fee: Pays,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `Dispatchable` function (aka transaction) that can carry some static information along with
|
|
||||||
/// it, using the `#[weight]` attribute.
|
|
||||||
pub trait GetDispatchInfo {
|
|
||||||
/// Return a `DispatchInfo`, containing relevant information of this dispatch.
|
|
||||||
///
|
|
||||||
/// This is done independently of its encoded size.
|
|
||||||
fn get_dispatch_info(&self) -> DispatchInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetDispatchInfo for () {
|
|
||||||
fn get_dispatch_info(&self) -> DispatchInfo {
|
|
||||||
DispatchInfo::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Weight information that is only available post dispatch.
|
|
||||||
/// NOTE: This can only be used to reduce the weight or fee, not increase it.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
|
||||||
pub struct PostDispatchInfo {
|
|
||||||
/// Actual weight consumed by a call or `None` which stands for the worst case static weight.
|
|
||||||
pub actual_weight: Option<Weight>,
|
|
||||||
/// Whether this transaction should pay fees when all is said and done.
|
|
||||||
pub pays_fee: Pays,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PostDispatchInfo {
|
|
||||||
/// Calculate how much (if any) weight was not used by the `Dispatchable`.
|
|
||||||
pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
|
|
||||||
info.weight - self.calc_actual_weight(info)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate how much weight was actually spent by the `Dispatchable`.
|
|
||||||
pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
|
|
||||||
if let Some(actual_weight) = self.actual_weight {
|
|
||||||
actual_weight.min(info.weight)
|
|
||||||
} else {
|
|
||||||
info.weight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determine if user should actually pay fees at the end of the dispatch.
|
|
||||||
pub fn pays_fee(&self, info: &DispatchInfo) -> Pays {
|
|
||||||
// If they originally were not paying fees, or the post dispatch info
|
|
||||||
// says they should not pay fees, then they don't pay fees.
|
|
||||||
// This is because the pre dispatch information must contain the
|
|
||||||
// worst case for weight and fees paid.
|
|
||||||
if info.pays_fee == Pays::No || self.pays_fee == Pays::No {
|
|
||||||
Pays::No
|
|
||||||
} else {
|
|
||||||
// Otherwise they pay.
|
|
||||||
Pays::Yes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extract the actual weight from a dispatch result if any or fall back to the default weight.
|
|
||||||
pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Weight {
|
|
||||||
match result {
|
|
||||||
Ok(post_info) => post_info,
|
|
||||||
Err(err) => &err.post_info,
|
|
||||||
}
|
|
||||||
.calc_actual_weight(info)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extract the actual pays_fee from a dispatch result if any or fall back to the default weight.
|
|
||||||
pub fn extract_actual_pays_fee(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Pays {
|
|
||||||
match result {
|
|
||||||
Ok(post_info) => post_info,
|
|
||||||
Err(err) => &err.post_info,
|
|
||||||
}
|
|
||||||
.pays_fee(info)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<()> for PostDispatchInfo {
|
|
||||||
fn from(_: ()) -> Self {
|
|
||||||
Self { actual_weight: None, pays_fee: Default::default() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sp_runtime::traits::Printable for PostDispatchInfo {
|
|
||||||
fn print(&self) {
|
|
||||||
"actual_weight=".print();
|
|
||||||
match self.actual_weight {
|
|
||||||
Some(weight) => weight.print(),
|
|
||||||
None => "max-weight".print(),
|
|
||||||
};
|
|
||||||
"pays_fee=".print();
|
|
||||||
match self.pays_fee {
|
|
||||||
Pays::Yes => "Yes".print(),
|
|
||||||
Pays::No => "No".print(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allows easy conversion from `DispatchError` to `DispatchErrorWithPostInfo` for dispatchables
|
|
||||||
/// that want to return a custom a posterior weight on error.
|
|
||||||
pub trait WithPostDispatchInfo {
|
|
||||||
/// Call this on your modules custom errors type in order to return a custom weight on error.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// let who = ensure_signed(origin).map_err(|e| e.with_weight(Weight::from_ref_time(100)))?;
|
|
||||||
/// ensure!(who == me, Error::<T>::NotMe.with_weight(200_000));
|
|
||||||
/// ```
|
|
||||||
fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WithPostDispatchInfo for T
|
|
||||||
where
|
|
||||||
T: Into<DispatchError>,
|
|
||||||
{
|
|
||||||
fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo {
|
|
||||||
DispatchErrorWithPostInfo {
|
|
||||||
post_info: PostDispatchInfo {
|
|
||||||
actual_weight: Some(actual_weight),
|
|
||||||
pays_fee: Default::default(),
|
|
||||||
},
|
|
||||||
error: self.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation for unchecked extrinsic.
|
|
||||||
impl<Address, Call, Signature, Extra> GetDispatchInfo
|
|
||||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
|
||||||
where
|
|
||||||
Call: GetDispatchInfo,
|
|
||||||
Extra: SignedExtension,
|
|
||||||
{
|
|
||||||
fn get_dispatch_info(&self) -> DispatchInfo {
|
|
||||||
self.function.get_dispatch_info()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation for checked extrinsic.
|
|
||||||
impl<AccountId, Call, Extra> GetDispatchInfo for CheckedExtrinsic<AccountId, Call, Extra>
|
|
||||||
where
|
|
||||||
Call: GetDispatchInfo,
|
|
||||||
{
|
|
||||||
fn get_dispatch_info(&self) -> DispatchInfo {
|
|
||||||
self.function.get_dispatch_info()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation for test extrinsic.
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<Call: Encode, Extra: Encode> GetDispatchInfo for sp_runtime::testing::TestXt<Call, Extra> {
|
|
||||||
fn get_dispatch_info(&self) -> DispatchInfo {
|
|
||||||
// for testing: weight == size.
|
|
||||||
DispatchInfo {
|
|
||||||
weight: Weight::from_ref_time(self.encode().len() as _),
|
|
||||||
pays_fee: Pays::Yes,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The weight of database operations that the runtime can invoke.
|
|
||||||
///
|
|
||||||
/// NOTE: This is currently only measured in computational time, and will probably
|
|
||||||
/// be updated all together once proof size is accounted for.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
|
||||||
pub struct RuntimeDbWeight {
|
|
||||||
pub read: u64,
|
|
||||||
pub write: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RuntimeDbWeight {
|
|
||||||
pub fn reads(self, r: u64) -> Weight {
|
|
||||||
Weight::from_ref_time(self.read.saturating_mul(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn writes(self, w: u64) -> Weight {
|
|
||||||
Weight::from_ref_time(self.write.saturating_mul(w))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reads_writes(self, r: u64, w: u64) -> Weight {
|
|
||||||
let read_weight = self.read.saturating_mul(r);
|
|
||||||
let write_weight = self.write.saturating_mul(w);
|
|
||||||
Weight::from_ref_time(read_weight.saturating_add(write_weight))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// One coefficient and its position in the `WeightToFee`.
|
|
||||||
///
|
|
||||||
/// One term of polynomial is calculated as:
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// coeff_integer * x^(degree) + coeff_frac * x^(degree)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The `negative` value encodes whether the term is added or substracted from the
|
|
||||||
/// overall polynomial result.
|
|
||||||
#[derive(Clone, Encode, Decode, TypeInfo)]
|
|
||||||
pub struct WeightToFeeCoefficient<Balance> {
|
|
||||||
/// The integral part of the coefficient.
|
|
||||||
pub coeff_integer: Balance,
|
|
||||||
/// The fractional part of the coefficient.
|
|
||||||
pub coeff_frac: Perbill,
|
|
||||||
/// True iff the coefficient should be interpreted as negative.
|
|
||||||
pub negative: bool,
|
|
||||||
/// Degree/exponent of the term.
|
|
||||||
pub degree: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A list of coefficients that represent one polynomial.
|
|
||||||
pub type WeightToFeeCoefficients<T> = SmallVec<[WeightToFeeCoefficient<T>; 4]>;
|
|
||||||
|
|
||||||
/// A trait that describes the weight to fee calculation.
|
|
||||||
pub trait WeightToFee {
|
|
||||||
/// The type that is returned as result from calculation.
|
|
||||||
type Balance: BaseArithmetic + From<u32> + Copy + Unsigned;
|
|
||||||
|
|
||||||
/// Calculates the fee from the passed `weight`.
|
|
||||||
fn weight_to_fee(weight: &Weight) -> Self::Balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A trait that describes the weight to fee calculation as polynomial.
|
|
||||||
///
|
|
||||||
/// An implementor should only implement the `polynomial` function.
|
|
||||||
pub trait WeightToFeePolynomial {
|
|
||||||
/// The type that is returned as result from polynomial evaluation.
|
|
||||||
type Balance: BaseArithmetic + From<u32> + Copy + Unsigned;
|
|
||||||
|
|
||||||
/// Returns a polynomial that describes the weight to fee conversion.
|
|
||||||
///
|
|
||||||
/// This is the only function that should be manually implemented. Please note
|
|
||||||
/// that all calculation is done in the probably unsigned `Balance` type. This means
|
|
||||||
/// that the order of coefficients is important as putting the negative coefficients
|
|
||||||
/// first will most likely saturate the result to zero mid evaluation.
|
|
||||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeightToFee for T
|
|
||||||
where
|
|
||||||
T: WeightToFeePolynomial,
|
|
||||||
{
|
|
||||||
type Balance = <Self as WeightToFeePolynomial>::Balance;
|
|
||||||
|
|
||||||
/// Calculates the fee from the passed `weight` according to the `polynomial`.
|
|
||||||
///
|
|
||||||
/// This should not be overridden in most circumstances. Calculation is done in the
|
|
||||||
/// `Balance` type and never overflows. All evaluation is saturating.
|
|
||||||
fn weight_to_fee(weight: &Weight) -> Self::Balance {
|
|
||||||
Self::polynomial()
|
|
||||||
.iter()
|
|
||||||
.fold(Self::Balance::saturated_from(0u32), |mut acc, args| {
|
|
||||||
let w = Self::Balance::saturated_from(weight.ref_time())
|
|
||||||
.saturating_pow(args.degree.into());
|
|
||||||
|
|
||||||
// The sum could get negative. Therefore we only sum with the accumulator.
|
|
||||||
// The Perbill Mul implementation is non overflowing.
|
|
||||||
let frac = args.coeff_frac * w;
|
|
||||||
let integer = args.coeff_integer.saturating_mul(w);
|
|
||||||
|
|
||||||
if args.negative {
|
|
||||||
acc = acc.saturating_sub(frac);
|
|
||||||
acc = acc.saturating_sub(integer);
|
|
||||||
} else {
|
|
||||||
acc = acc.saturating_add(frac);
|
|
||||||
acc = acc.saturating_add(integer);
|
|
||||||
}
|
|
||||||
|
|
||||||
acc
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementor of `WeightToFee` that maps one unit of weight to one unit of fee.
|
|
||||||
pub struct IdentityFee<T>(sp_std::marker::PhantomData<T>);
|
|
||||||
|
|
||||||
impl<T> WeightToFee for IdentityFee<T>
|
|
||||||
where
|
|
||||||
T: BaseArithmetic + From<u32> + Copy + Unsigned,
|
|
||||||
{
|
|
||||||
type Balance = T;
|
|
||||||
|
|
||||||
fn weight_to_fee(weight: &Weight) -> Self::Balance {
|
|
||||||
Self::Balance::saturated_from(weight.ref_time())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementor of [`WeightToFee`] that uses a constant multiplier.
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # use frame_support::traits::ConstU128;
|
|
||||||
/// # use frame_support::weights::ConstantMultiplier;
|
|
||||||
/// // Results in a multiplier of 10 for each unit of weight (or length)
|
|
||||||
/// type LengthToFee = ConstantMultiplier::<u128, ConstU128<10u128>>;
|
|
||||||
/// ```
|
|
||||||
pub struct ConstantMultiplier<T, M>(sp_std::marker::PhantomData<(T, M)>);
|
|
||||||
|
|
||||||
impl<T, M> WeightToFee for ConstantMultiplier<T, M>
|
|
||||||
where
|
|
||||||
T: BaseArithmetic + From<u32> + Copy + Unsigned,
|
|
||||||
M: Get<T>,
|
|
||||||
{
|
|
||||||
type Balance = T;
|
|
||||||
|
|
||||||
fn weight_to_fee(weight: &Weight) -> Self::Balance {
|
|
||||||
Self::Balance::saturated_from(weight.ref_time()).saturating_mul(M::get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A struct holding value for each `DispatchClass`.
|
|
||||||
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
|
|
||||||
pub struct PerDispatchClass<T> {
|
|
||||||
/// Value for `Normal` extrinsics.
|
|
||||||
normal: T,
|
|
||||||
/// Value for `Operational` extrinsics.
|
|
||||||
operational: T,
|
|
||||||
/// Value for `Mandatory` extrinsics.
|
|
||||||
mandatory: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PerDispatchClass<T> {
|
|
||||||
/// Create new `PerDispatchClass` with the same value for every class.
|
|
||||||
pub fn new(val: impl Fn(DispatchClass) -> T) -> Self {
|
|
||||||
Self {
|
|
||||||
normal: val(DispatchClass::Normal),
|
|
||||||
operational: val(DispatchClass::Operational),
|
|
||||||
mandatory: val(DispatchClass::Mandatory),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a mutable reference to current value of given class.
|
|
||||||
pub fn get_mut(&mut self, class: DispatchClass) -> &mut T {
|
|
||||||
match class {
|
|
||||||
DispatchClass::Operational => &mut self.operational,
|
|
||||||
DispatchClass::Normal => &mut self.normal,
|
|
||||||
DispatchClass::Mandatory => &mut self.mandatory,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get current value for given class.
|
|
||||||
pub fn get(&self, class: DispatchClass) -> &T {
|
|
||||||
match class {
|
|
||||||
DispatchClass::Normal => &self.normal,
|
|
||||||
DispatchClass::Operational => &self.operational,
|
|
||||||
DispatchClass::Mandatory => &self.mandatory,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone> PerDispatchClass<T> {
|
|
||||||
/// Set the value of given class.
|
|
||||||
pub fn set(&mut self, new: T, class: impl OneOrMany<DispatchClass>) {
|
|
||||||
for class in class.into_iter() {
|
|
||||||
*self.get_mut(class) = new.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PerDispatchClass<Weight> {
|
|
||||||
/// Returns the total weight consumed by all extrinsics in the block.
|
|
||||||
pub fn total(&self) -> Weight {
|
|
||||||
let mut sum = Weight::zero();
|
|
||||||
for class in DispatchClass::all() {
|
|
||||||
sum = sum.saturating_add(*self.get(*class));
|
|
||||||
}
|
|
||||||
sum
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`.
|
|
||||||
pub fn add(&mut self, weight: Weight, class: DispatchClass) {
|
|
||||||
let value = self.get_mut(class);
|
|
||||||
*value = value.saturating_add(weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would
|
|
||||||
/// occur.
|
|
||||||
pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> {
|
|
||||||
let value = self.get_mut(class);
|
|
||||||
*value = value.checked_add(&weight).ok_or(())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of
|
|
||||||
/// `Weight`.
|
|
||||||
pub fn sub(&mut self, weight: Weight, class: DispatchClass) {
|
|
||||||
let value = self.get_mut(class);
|
|
||||||
*value = value.saturating_sub(weight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::{decl_module, parameter_types, traits::Get};
|
|
||||||
use smallvec::smallvec;
|
|
||||||
|
|
||||||
pub trait Config: 'static {
|
|
||||||
type Origin;
|
|
||||||
type Balance;
|
|
||||||
type BlockNumber;
|
|
||||||
type DbWeight: Get<RuntimeDbWeight>;
|
|
||||||
type PalletInfo: crate::traits::PalletInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TraitImpl {}
|
|
||||||
|
|
||||||
parameter_types! {
|
|
||||||
pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
|
||||||
read: 100,
|
|
||||||
write: 1000,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config for TraitImpl {
|
|
||||||
type Origin = u32;
|
|
||||||
type BlockNumber = u32;
|
|
||||||
type Balance = u32;
|
|
||||||
type DbWeight = DbWeight;
|
|
||||||
type PalletInfo = crate::tests::PanicPalletInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
decl_module! {
|
|
||||||
pub struct Module<T: Config> for enum Call where origin: T::Origin, system=self {
|
|
||||||
// no arguments, fixed weight
|
|
||||||
#[weight = 1000]
|
|
||||||
fn f00(_origin) { unimplemented!(); }
|
|
||||||
|
|
||||||
#[weight = (1000, DispatchClass::Mandatory)]
|
|
||||||
fn f01(_origin) { unimplemented!(); }
|
|
||||||
|
|
||||||
#[weight = (1000, Pays::No)]
|
|
||||||
fn f02(_origin) { unimplemented!(); }
|
|
||||||
|
|
||||||
#[weight = (1000, DispatchClass::Operational, Pays::No)]
|
|
||||||
fn f03(_origin) { unimplemented!(); }
|
|
||||||
|
|
||||||
// weight = a x 10 + b
|
|
||||||
#[weight = ((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes)]
|
|
||||||
fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); }
|
|
||||||
|
|
||||||
#[weight = (0, DispatchClass::Operational, Pays::Yes)]
|
|
||||||
fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); }
|
|
||||||
|
|
||||||
#[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + Weight::from_ref_time(10_000)]
|
|
||||||
fn f20(_origin) { unimplemented!(); }
|
|
||||||
|
|
||||||
#[weight = T::DbWeight::get().reads_writes(6, 5) + Weight::from_ref_time(40_000)]
|
|
||||||
fn f21(_origin) { unimplemented!(); }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn weights_are_correct() {
|
|
||||||
// #[weight = 1000]
|
|
||||||
let info = Call::<TraitImpl>::f00 {}.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
|
||||||
assert_eq!(info.class, DispatchClass::Normal);
|
|
||||||
assert_eq!(info.pays_fee, Pays::Yes);
|
|
||||||
|
|
||||||
// #[weight = (1000, DispatchClass::Mandatory)]
|
|
||||||
let info = Call::<TraitImpl>::f01 {}.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
|
||||||
assert_eq!(info.class, DispatchClass::Mandatory);
|
|
||||||
assert_eq!(info.pays_fee, Pays::Yes);
|
|
||||||
|
|
||||||
// #[weight = (1000, Pays::No)]
|
|
||||||
let info = Call::<TraitImpl>::f02 {}.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
|
||||||
assert_eq!(info.class, DispatchClass::Normal);
|
|
||||||
assert_eq!(info.pays_fee, Pays::No);
|
|
||||||
|
|
||||||
// #[weight = (1000, DispatchClass::Operational, Pays::No)]
|
|
||||||
let info = Call::<TraitImpl>::f03 {}.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(1000));
|
|
||||||
assert_eq!(info.class, DispatchClass::Operational);
|
|
||||||
assert_eq!(info.pays_fee, Pays::No);
|
|
||||||
|
|
||||||
// #[weight = ((_a * 10 + _eb * 1) as Weight, DispatchClass::Normal, Pays::Yes)]
|
|
||||||
let info = Call::<TraitImpl>::f11 { _a: 13, _eb: 20 }.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(150)); // 13*10 + 20
|
|
||||||
assert_eq!(info.class, DispatchClass::Normal);
|
|
||||||
assert_eq!(info.pays_fee, Pays::Yes);
|
|
||||||
|
|
||||||
// #[weight = (0, DispatchClass::Operational, Pays::Yes)]
|
|
||||||
let info = Call::<TraitImpl>::f12 { _a: 10, _eb: 20 }.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(0));
|
|
||||||
assert_eq!(info.class, DispatchClass::Operational);
|
|
||||||
assert_eq!(info.pays_fee, Pays::Yes);
|
|
||||||
|
|
||||||
// #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000]
|
|
||||||
let info = Call::<TraitImpl>::f20 {}.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(12300)); // 100*3 + 1000*2 + 10_1000
|
|
||||||
assert_eq!(info.class, DispatchClass::Normal);
|
|
||||||
assert_eq!(info.pays_fee, Pays::Yes);
|
|
||||||
|
|
||||||
// #[weight = T::DbWeight::get().reads_writes(6, 5) + 40_000]
|
|
||||||
let info = Call::<TraitImpl>::f21 {}.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, Weight::from_ref_time(45600)); // 100*6 + 1000*5 + 40_1000
|
|
||||||
assert_eq!(info.class, DispatchClass::Normal);
|
|
||||||
assert_eq!(info.pays_fee, Pays::Yes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extract_actual_weight_works() {
|
|
||||||
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
|
|
||||||
assert_eq!(extract_actual_weight(&Ok(Some(7).into()), &pre), Weight::from_ref_time(7));
|
|
||||||
assert_eq!(
|
|
||||||
extract_actual_weight(&Ok(Some(1000).into()), &pre),
|
|
||||||
Weight::from_ref_time(1000)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
extract_actual_weight(
|
|
||||||
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(9))),
|
|
||||||
&pre
|
|
||||||
),
|
|
||||||
Weight::from_ref_time(9)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extract_actual_weight_caps_at_pre_weight() {
|
|
||||||
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
|
|
||||||
assert_eq!(
|
|
||||||
extract_actual_weight(&Ok(Some(1250).into()), &pre),
|
|
||||||
Weight::from_ref_time(1000)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
extract_actual_weight(
|
|
||||||
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(1300))),
|
|
||||||
&pre
|
|
||||||
),
|
|
||||||
Weight::from_ref_time(1000),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extract_actual_pays_fee_works() {
|
|
||||||
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok(Some(7).into()), &pre), Pays::Yes);
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok(Some(1000).into()), &pre), Pays::Yes);
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::Yes).into()), &pre), Pays::Yes);
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::No).into()), &pre), Pays::No);
|
|
||||||
assert_eq!(
|
|
||||||
extract_actual_pays_fee(
|
|
||||||
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(9))),
|
|
||||||
&pre
|
|
||||||
),
|
|
||||||
Pays::Yes
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
extract_actual_pays_fee(
|
|
||||||
&Err(DispatchErrorWithPostInfo {
|
|
||||||
post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::No },
|
|
||||||
error: DispatchError::BadOrigin,
|
|
||||||
}),
|
|
||||||
&pre
|
|
||||||
),
|
|
||||||
Pays::No
|
|
||||||
);
|
|
||||||
|
|
||||||
let pre = DispatchInfo {
|
|
||||||
weight: Weight::from_ref_time(1000),
|
|
||||||
pays_fee: Pays::No,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok(Some(7).into()), &pre), Pays::No);
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok(Some(1000).into()), &pre), Pays::No);
|
|
||||||
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::Yes).into()), &pre), Pays::No);
|
|
||||||
}
|
|
||||||
|
|
||||||
type Balance = u64;
|
|
||||||
|
|
||||||
// 0.5x^3 + 2.333x^2 + 7x - 10_000
|
|
||||||
struct Poly;
|
|
||||||
impl WeightToFeePolynomial for Poly {
|
|
||||||
type Balance = Balance;
|
|
||||||
|
|
||||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
|
||||||
smallvec![
|
|
||||||
WeightToFeeCoefficient {
|
|
||||||
coeff_integer: 0,
|
|
||||||
coeff_frac: Perbill::from_float(0.5),
|
|
||||||
negative: false,
|
|
||||||
degree: 3
|
|
||||||
},
|
|
||||||
WeightToFeeCoefficient {
|
|
||||||
coeff_integer: 2,
|
|
||||||
coeff_frac: Perbill::from_rational(1u32, 3u32),
|
|
||||||
negative: false,
|
|
||||||
degree: 2
|
|
||||||
},
|
|
||||||
WeightToFeeCoefficient {
|
|
||||||
coeff_integer: 7,
|
|
||||||
coeff_frac: Perbill::zero(),
|
|
||||||
negative: false,
|
|
||||||
degree: 1
|
|
||||||
},
|
|
||||||
WeightToFeeCoefficient {
|
|
||||||
coeff_integer: 10_000,
|
|
||||||
coeff_frac: Perbill::zero(),
|
|
||||||
negative: true,
|
|
||||||
degree: 0
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn polynomial_works() {
|
|
||||||
// 100^3/2=500000 100^2*(2+1/3)=23333 700 -10000
|
|
||||||
assert_eq!(Poly::weight_to_fee(&Weight::from_ref_time(100)), 514033);
|
|
||||||
// 10123^3/2=518677865433 10123^2*(2+1/3)=239108634 70861 -10000
|
|
||||||
assert_eq!(Poly::weight_to_fee(&Weight::from_ref_time(10_123)), 518917034928);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn polynomial_does_not_underflow() {
|
|
||||||
assert_eq!(Poly::weight_to_fee(&Weight::zero()), 0);
|
|
||||||
assert_eq!(Poly::weight_to_fee(&Weight::from_ref_time(10)), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn polynomial_does_not_overflow() {
|
|
||||||
assert_eq!(Poly::weight_to_fee(&Weight::MAX), Balance::max_value() - 10_000);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn identity_fee_works() {
|
|
||||||
assert_eq!(IdentityFee::<Balance>::weight_to_fee(&Weight::zero()), 0);
|
|
||||||
assert_eq!(IdentityFee::<Balance>::weight_to_fee(&Weight::from_ref_time(50)), 50);
|
|
||||||
assert_eq!(IdentityFee::<Balance>::weight_to_fee(&Weight::MAX), Balance::max_value());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn constant_fee_works() {
|
|
||||||
use crate::traits::ConstU128;
|
|
||||||
assert_eq!(
|
|
||||||
ConstantMultiplier::<u128, ConstU128<100u128>>::weight_to_fee(&Weight::zero()),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ConstantMultiplier::<u128, ConstU128<10u128>>::weight_to_fee(&Weight::from_ref_time(
|
|
||||||
50
|
|
||||||
)),
|
|
||||||
500
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ConstantMultiplier::<u128, ConstU128<1024u128>>::weight_to_fee(&Weight::from_ref_time(
|
|
||||||
16
|
|
||||||
)),
|
|
||||||
16384
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ConstantMultiplier::<u128, ConstU128<{ u128::MAX }>>::weight_to_fee(
|
|
||||||
&Weight::from_ref_time(2)
|
|
||||||
),
|
|
||||||
u128::MAX
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,10 +34,8 @@
|
|||||||
// --warmup=10
|
// --warmup=10
|
||||||
// --repeat=100
|
// --repeat=100
|
||||||
|
|
||||||
use frame_support::{
|
use sp_core::parameter_types;
|
||||||
parameter_types,
|
use sp_weights::{constants::WEIGHT_PER_NANOS, Weight};
|
||||||
weights::{constants::WEIGHT_PER_NANOS, Weight},
|
|
||||||
};
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// Time to execute an empty block.
|
/// Time to execute an empty block.
|
||||||
@@ -58,7 +56,7 @@ parameter_types! {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_weights {
|
mod test_weights {
|
||||||
use frame_support::weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that the weight exists and is sane.
|
/// Checks that the weight exists and is sane.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
|
|||||||
@@ -34,10 +34,8 @@
|
|||||||
// --warmup=10
|
// --warmup=10
|
||||||
// --repeat=100
|
// --repeat=100
|
||||||
|
|
||||||
use frame_support::{
|
use sp_core::parameter_types;
|
||||||
parameter_types,
|
use sp_weights::{constants::WEIGHT_PER_NANOS, Weight};
|
||||||
weights::{constants::WEIGHT_PER_NANOS, Weight},
|
|
||||||
};
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// Time to execute a NO-OP extrinsic, for example `System::remark`.
|
/// Time to execute a NO-OP extrinsic, for example `System::remark`.
|
||||||
@@ -58,7 +56,7 @@ parameter_types! {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_weights {
|
mod test_weights {
|
||||||
use frame_support::weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that the weight exists and is sane.
|
/// Checks that the weight exists and is sane.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
pub mod constants {
|
pub mod constants {
|
||||||
use frame_support::{
|
use frame_support::weights::constants;
|
||||||
parameter_types,
|
use sp_core::parameter_types;
|
||||||
weights::{constants, RuntimeDbWeight},
|
use sp_weights::RuntimeDbWeight;
|
||||||
};
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// ParityDB can be enabled with a feature flag, but is still experimental. These weights
|
/// ParityDB can be enabled with a feature flag, but is still experimental. These weights
|
||||||
@@ -33,7 +32,7 @@ pub mod constants {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db_weights {
|
mod test_db_weights {
|
||||||
use super::constants::ParityDbWeight as W;
|
use super::constants::ParityDbWeight as W;
|
||||||
use frame_support::weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that all weights exist and have sane values.
|
/// Checks that all weights exist and have sane values.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
pub mod constants {
|
pub mod constants {
|
||||||
use frame_support::{
|
use frame_support::weights::constants;
|
||||||
parameter_types,
|
use sp_core::parameter_types;
|
||||||
weights::{constants, RuntimeDbWeight},
|
use sp_weights::RuntimeDbWeight;
|
||||||
};
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// By default, Substrate uses RocksDB, so this will be the weight used throughout
|
/// By default, Substrate uses RocksDB, so this will be the weight used throughout
|
||||||
@@ -33,7 +32,7 @@ pub mod constants {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db_weights {
|
mod test_db_weights {
|
||||||
use super::constants::RocksDbWeight as W;
|
use super::constants::RocksDbWeight as W;
|
||||||
use frame_support::weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that all weights exist and have sane values.
|
/// Checks that all weights exist and have sane values.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ pub mod module3 {
|
|||||||
}
|
}
|
||||||
#[weight = 3]
|
#[weight = 3]
|
||||||
fn aux_4(_origin) -> frame_support::dispatch::DispatchResult { unreachable!() }
|
fn aux_4(_origin) -> frame_support::dispatch::DispatchResult { unreachable!() }
|
||||||
#[weight = (5, frame_support::weights::DispatchClass::Operational)]
|
#[weight = (5, frame_support::dispatch::DispatchClass::Operational)]
|
||||||
fn operational(_origin) { unreachable!() }
|
fn operational(_origin) { unreachable!() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,8 +504,8 @@ fn call_encode_is_correct_and_decode_works() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn call_weight_should_attach_to_call_enum() {
|
fn call_weight_should_attach_to_call_enum() {
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::{DispatchInfo, GetDispatchInfo},
|
dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays},
|
||||||
weights::{DispatchClass, Pays, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
// operational.
|
// operational.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ pub mod module {
|
|||||||
}
|
}
|
||||||
#[weight = 3]
|
#[weight = 3]
|
||||||
fn aux_4(_origin) -> frame_support::dispatch::DispatchResult { unreachable!() }
|
fn aux_4(_origin) -> frame_support::dispatch::DispatchResult { unreachable!() }
|
||||||
#[weight = (5, frame_support::weights::DispatchClass::Operational)]
|
#[weight = (5, frame_support::dispatch::DispatchClass::Operational)]
|
||||||
fn operational(_origin) { unreachable!() }
|
fn operational(_origin) { unreachable!() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,16 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::{Parameter, UnfilteredDispatchable},
|
dispatch::{
|
||||||
|
DispatchClass, DispatchInfo, GetDispatchInfo, Parameter, Pays, UnfilteredDispatchable,
|
||||||
|
},
|
||||||
pallet_prelude::ValueQuery,
|
pallet_prelude::ValueQuery,
|
||||||
storage::unhashed,
|
storage::unhashed,
|
||||||
traits::{
|
traits::{
|
||||||
ConstU32, GetCallName, GetStorageVersion, OnFinalize, OnGenesis, OnInitialize,
|
ConstU32, GetCallName, GetStorageVersion, OnFinalize, OnGenesis, OnInitialize,
|
||||||
OnRuntimeUpgrade, PalletError, PalletInfoAccess, StorageVersion,
|
OnRuntimeUpgrade, PalletError, PalletInfoAccess, StorageVersion,
|
||||||
},
|
},
|
||||||
weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays, RuntimeDbWeight, Weight},
|
weights::{RuntimeDbWeight, Weight},
|
||||||
};
|
};
|
||||||
use scale_info::{meta_type, TypeInfo};
|
use scale_info::{meta_type, TypeInfo};
|
||||||
use sp_io::{
|
use sp_io::{
|
||||||
|
|||||||
@@ -16,11 +16,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::UnfilteredDispatchable,
|
dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays, UnfilteredDispatchable},
|
||||||
pallet_prelude::ValueQuery,
|
pallet_prelude::ValueQuery,
|
||||||
storage::unhashed,
|
storage::unhashed,
|
||||||
traits::{ConstU32, GetCallName, OnFinalize, OnGenesis, OnInitialize, OnRuntimeUpgrade},
|
traits::{ConstU32, GetCallName, OnFinalize, OnGenesis, OnInitialize, OnRuntimeUpgrade},
|
||||||
weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays},
|
|
||||||
};
|
};
|
||||||
use sp_io::{
|
use sp_io::{
|
||||||
hashing::{blake2_128, twox_128, twox_64},
|
hashing::{blake2_128, twox_128, twox_64},
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ sp-io = { version = "6.0.0", default-features = false, path = "../../primitives/
|
|||||||
sp-runtime = { version = "6.0.0", default-features = false, path = "../../primitives/runtime" }
|
sp-runtime = { version = "6.0.0", default-features = false, path = "../../primitives/runtime" }
|
||||||
sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" }
|
sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" }
|
||||||
sp-version = { version = "5.0.0", default-features = false, path = "../../primitives/version" }
|
sp-version = { version = "5.0.0", default-features = false, path = "../../primitives/version" }
|
||||||
|
sp-weights = { version = "4.0.0", default-features = false, path = "../../primitives/weights" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3.3"
|
criterion = "0.3.3"
|
||||||
@@ -42,6 +43,7 @@ std = [
|
|||||||
"sp-runtime/std",
|
"sp-runtime/std",
|
||||||
"sp-std/std",
|
"sp-std/std",
|
||||||
"sp-version/std",
|
"sp-version/std",
|
||||||
|
"sp-weights/std",
|
||||||
]
|
]
|
||||||
runtime-benchmarks = [
|
runtime-benchmarks = [
|
||||||
"frame-support/runtime-benchmarks",
|
"frame-support/runtime-benchmarks",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use frame_benchmarking::{benchmarks, whitelisted_caller};
|
use frame_benchmarking::{benchmarks, whitelisted_caller};
|
||||||
use frame_support::{storage, traits::Get, weights::DispatchClass};
|
use frame_support::{dispatch::DispatchClass, storage, traits::Get};
|
||||||
use frame_system::{Call, Pallet as System, RawOrigin};
|
use frame_system::{Call, Pallet as System, RawOrigin};
|
||||||
use sp_core::storage::well_known_keys;
|
use sp_core::storage::well_known_keys;
|
||||||
use sp_runtime::traits::Hash;
|
use sp_runtime::traits::Hash;
|
||||||
|
|||||||
@@ -101,7 +101,10 @@ impl<T: Config + Send + Sync> SignedExtension for CheckMortality<T> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::mock::{new_test_ext, System, Test, CALL};
|
use crate::mock::{new_test_ext, System, Test, CALL};
|
||||||
use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight};
|
use frame_support::{
|
||||||
|
dispatch::{DispatchClass, DispatchInfo, Pays},
|
||||||
|
weights::Weight,
|
||||||
|
};
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::weights::DispatchInfo;
|
use frame_support::dispatch::DispatchInfo;
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{DispatchInfoOf, Dispatchable, SignedExtension},
|
traits::{DispatchInfoOf, Dispatchable, SignedExtension},
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::weights::DispatchInfo;
|
use frame_support::dispatch::DispatchInfo;
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{DispatchInfoOf, Dispatchable, One, SignedExtension},
|
traits::{DispatchInfoOf, Dispatchable, One, SignedExtension},
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
use crate::{limits::BlockWeights, Config, Pallet};
|
use crate::{limits::BlockWeights, Config, Pallet};
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo},
|
||||||
traits::Get,
|
traits::Get,
|
||||||
weights::{DispatchClass, DispatchInfo, PostDispatchInfo, Weight},
|
|
||||||
};
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
@@ -27,6 +27,7 @@ use sp_runtime::{
|
|||||||
transaction_validity::{InvalidTransaction, TransactionValidity, TransactionValidityError},
|
transaction_validity::{InvalidTransaction, TransactionValidity, TransactionValidityError},
|
||||||
DispatchResult,
|
DispatchResult,
|
||||||
};
|
};
|
||||||
|
use sp_weights::Weight;
|
||||||
|
|
||||||
/// Block resource (weight) limit check.
|
/// Block resource (weight) limit check.
|
||||||
///
|
///
|
||||||
@@ -269,10 +270,7 @@ mod tests {
|
|||||||
mock::{new_test_ext, System, Test, CALL},
|
mock::{new_test_ext, System, Test, CALL},
|
||||||
AllExtrinsicsLen, BlockWeight,
|
AllExtrinsicsLen, BlockWeight,
|
||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{assert_err, assert_ok, dispatch::Pays, weights::Weight};
|
||||||
assert_err, assert_ok,
|
|
||||||
weights::{Pays, Weight},
|
|
||||||
};
|
|
||||||
use sp_std::marker::PhantomData;
|
use sp_std::marker::PhantomData;
|
||||||
|
|
||||||
fn block_weights() -> crate::limits::BlockWeights {
|
fn block_weights() -> crate::limits::BlockWeights {
|
||||||
|
|||||||
@@ -84,20 +84,20 @@ use sp_version::RuntimeVersion;
|
|||||||
|
|
||||||
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
|
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::{DispatchResult, DispatchResultWithPostInfo},
|
dispatch::{
|
||||||
|
extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
|
||||||
|
DispatchResult, DispatchResultWithPostInfo, PerDispatchClass,
|
||||||
|
},
|
||||||
storage,
|
storage,
|
||||||
traits::{
|
traits::{
|
||||||
ConstU32, Contains, EnsureOrigin, Get, HandleLifetime, OnKilledAccount, OnNewAccount,
|
ConstU32, Contains, EnsureOrigin, Get, HandleLifetime, OnKilledAccount, OnNewAccount,
|
||||||
OriginTrait, PalletInfo, SortedMembers, StoredMap, TypedGet,
|
OriginTrait, PalletInfo, SortedMembers, StoredMap, TypedGet,
|
||||||
},
|
},
|
||||||
weights::{
|
|
||||||
extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
|
|
||||||
PerDispatchClass, RuntimeDbWeight, Weight,
|
|
||||||
},
|
|
||||||
Parameter,
|
Parameter,
|
||||||
};
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_core::storage::well_known_keys;
|
use sp_core::storage::well_known_keys;
|
||||||
|
use sp_weights::{RuntimeDbWeight, Weight};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use frame_support::traits::GenesisBuild;
|
use frame_support::traits::GenesisBuild;
|
||||||
|
|||||||
@@ -25,7 +25,10 @@
|
|||||||
//! `DispatchClass`. This module contains configuration object for both resources,
|
//! `DispatchClass`. This module contains configuration object for both resources,
|
||||||
//! which should be passed to `frame_system` configuration when runtime is being set up.
|
//! which should be passed to `frame_system` configuration when runtime is being set up.
|
||||||
|
|
||||||
use frame_support::weights::{constants, DispatchClass, OneOrMany, PerDispatchClass, Weight};
|
use frame_support::{
|
||||||
|
dispatch::{DispatchClass, OneOrMany, PerDispatchClass},
|
||||||
|
weights::{constants, Weight},
|
||||||
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{traits::Bounded, Perbill, RuntimeDebug};
|
use sp_runtime::{traits::Bounded, Perbill, RuntimeDebug};
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_noop, assert_ok,
|
assert_noop, assert_ok,
|
||||||
dispatch::PostDispatchInfo,
|
dispatch::{Pays, PostDispatchInfo, WithPostDispatchInfo},
|
||||||
weights::{Pays, WithPostDispatchInfo},
|
|
||||||
};
|
};
|
||||||
use mock::{Origin, *};
|
use mock::{Origin, *};
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ use sp_std::prelude::*;
|
|||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchResult,
|
dispatch::{DispatchInfo, DispatchResult, PostDispatchInfo},
|
||||||
traits::{
|
traits::{
|
||||||
tokens::{
|
tokens::{
|
||||||
fungibles::{Balanced, CreditOf, Inspect},
|
fungibles::{Balanced, CreditOf, Inspect},
|
||||||
@@ -47,7 +47,6 @@ use frame_support::{
|
|||||||
},
|
},
|
||||||
IsType,
|
IsType,
|
||||||
},
|
},
|
||||||
weights::{DispatchInfo, PostDispatchInfo},
|
|
||||||
DefaultNoBound,
|
DefaultNoBound,
|
||||||
};
|
};
|
||||||
use pallet_transaction_payment::OnChargeTransaction;
|
use pallet_transaction_payment::OnChargeTransaction;
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ use crate as pallet_asset_tx_payment;
|
|||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_ok,
|
assert_ok,
|
||||||
|
dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo},
|
||||||
pallet_prelude::*,
|
pallet_prelude::*,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
traits::{fungibles::Mutate, ConstU32, ConstU64, ConstU8, FindAuthor},
|
traits::{fungibles::Mutate, ConstU32, ConstU64, ConstU8, FindAuthor},
|
||||||
weights::{DispatchClass, DispatchInfo, PostDispatchInfo, Weight, WeightToFee as WeightToFeeT},
|
weights::{Weight, WeightToFee as WeightToFeeT},
|
||||||
ConsensusEngineId,
|
ConsensusEngineId,
|
||||||
};
|
};
|
||||||
use frame_system as system;
|
use frame_system as system;
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ use sp_runtime::{
|
|||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchResult,
|
dispatch::{
|
||||||
traits::{EstimateCallFee, Get},
|
DispatchClass, DispatchInfo, DispatchResult, GetDispatchInfo, Pays, PostDispatchInfo,
|
||||||
weights::{
|
|
||||||
DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight, WeightToFee,
|
|
||||||
},
|
},
|
||||||
|
traits::{EstimateCallFee, Get},
|
||||||
|
weights::{Weight, WeightToFee},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod payment;
|
mod payment;
|
||||||
@@ -849,12 +849,11 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_noop, assert_ok, parameter_types,
|
assert_noop, assert_ok,
|
||||||
|
dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
|
||||||
|
parameter_types,
|
||||||
traits::{ConstU32, ConstU64, Currency, GenesisBuild, Imbalance, OnUnbalanced},
|
traits::{ConstU32, ConstU64, Currency, GenesisBuild, Imbalance, OnUnbalanced},
|
||||||
weights::{
|
weights::{Weight, WeightToFee as WeightToFeeT},
|
||||||
DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo, Weight,
|
|
||||||
WeightToFee as WeightToFeeT,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use frame_system as system;
|
use frame_system as system;
|
||||||
use pallet_balances::Call as BalancesCall;
|
use pallet_balances::Call as BalancesCall;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sp_runtime::traits::{AtLeast32BitUnsigned, Zero};
|
use sp_runtime::traits::{AtLeast32BitUnsigned, Zero};
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
use frame_support::weights::{DispatchClass, Weight};
|
use frame_support::{dispatch::DispatchClass, weights::Weight};
|
||||||
|
|
||||||
/// The base fee and adjusted weight and length fees constitute the _inclusion fee_.
|
/// The base fee and adjusted weight and length fees constitute the _inclusion fee_.
|
||||||
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
|
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
|
||||||
|
|||||||
@@ -58,9 +58,8 @@ pub mod weights;
|
|||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::PostDispatchInfo,
|
dispatch::{extract_actual_weight, GetDispatchInfo, PostDispatchInfo},
|
||||||
traits::{IsSubType, OriginTrait, UnfilteredDispatchable},
|
traits::{IsSubType, OriginTrait, UnfilteredDispatchable},
|
||||||
weights::{extract_actual_weight, GetDispatchInfo},
|
|
||||||
};
|
};
|
||||||
use sp_core::TypeId;
|
use sp_core::TypeId;
|
||||||
use sp_io::hashing::blake2_256;
|
use sp_io::hashing::blake2_256;
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ use super::*;
|
|||||||
use crate as utility;
|
use crate as utility;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_err_ignore_postinfo, assert_noop, assert_ok,
|
assert_err_ignore_postinfo, assert_noop, assert_ok,
|
||||||
dispatch::{DispatchError, DispatchErrorWithPostInfo, Dispatchable},
|
dispatch::{DispatchError, DispatchErrorWithPostInfo, Dispatchable, Pays},
|
||||||
parameter_types, storage,
|
parameter_types, storage,
|
||||||
traits::{ConstU32, ConstU64, Contains},
|
traits::{ConstU32, ConstU64, Contains},
|
||||||
weights::{Pays, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ pub use weights::WeightInfo;
|
|||||||
|
|
||||||
use codec::{DecodeLimit, Encode, FullCodec};
|
use codec::{DecodeLimit, Encode, FullCodec};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
dispatch::{GetDispatchInfo, PostDispatchInfo},
|
||||||
ensure,
|
ensure,
|
||||||
traits::{PreimageProvider, PreimageRecipient},
|
traits::{PreimageProvider, PreimageRecipient},
|
||||||
weights::{GetDispatchInfo, PostDispatchInfo, Weight},
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::traits::{Dispatchable, Hash};
|
use sp_runtime::traits::{Dispatchable, Hash};
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ sp-arithmetic = { version = "5.0.0", default-features = false, path = "../arithm
|
|||||||
sp-core = { version = "6.0.0", default-features = false, path = "../core" }
|
sp-core = { version = "6.0.0", default-features = false, path = "../core" }
|
||||||
sp-io = { version = "6.0.0", default-features = false, path = "../io" }
|
sp-io = { version = "6.0.0", default-features = false, path = "../io" }
|
||||||
sp-std = { version = "4.0.0", default-features = false, path = "../std" }
|
sp-std = { version = "4.0.0", default-features = false, path = "../std" }
|
||||||
|
sp-weights = { version = "4.0.0", default-features = false, path = "../weights" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
|
|||||||
@@ -1820,6 +1820,12 @@ impl Printable for bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Printable for sp_weights::Weight {
|
||||||
|
fn print(&self) {
|
||||||
|
self.ref_time().print()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Printable for () {
|
impl Printable for () {
|
||||||
fn print(&self) {
|
fn print(&self) {
|
||||||
"()".print()
|
"()".print()
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
[package]
|
||||||
|
name = "sp-weights"
|
||||||
|
version = "4.0.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2021"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
homepage = "https://substrate.io"
|
||||||
|
repository = "https://github.com/paritytech/substrate/"
|
||||||
|
description = "Types and traits for interfacing between the host and the wasm runtime."
|
||||||
|
documentation = "https://docs.rs/sp-wasm-interface"
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
|
||||||
|
impl-trait-for-tuples = "0.2.2"
|
||||||
|
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
|
||||||
|
serde = { version = "1.0.136", optional = true, features = ["derive"] }
|
||||||
|
smallvec = "1.8.0"
|
||||||
|
sp-arithmetic = { version = "5.0.0", default-features = false, path = "../arithmetic" }
|
||||||
|
sp-core = { version = "6.0.0", default-features = false, path = "../core" }
|
||||||
|
sp-debug-derive = { version = "4.0.0", default-features = false, path = "../debug-derive" }
|
||||||
|
sp-std = { version = "4.0.0", default-features = false, path = "../std" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "std" ]
|
||||||
|
std = [
|
||||||
|
"codec/std",
|
||||||
|
"scale-info/std",
|
||||||
|
"serde",
|
||||||
|
"sp-arithmetic/std",
|
||||||
|
"sp-core/std",
|
||||||
|
"sp-debug-derive/std",
|
||||||
|
"sp-std/std"
|
||||||
|
]
|
||||||
|
# By default some types have documentation, `full-metadata-docs` allows to add documentation to
|
||||||
|
# more types in the metadata.
|
||||||
|
full-metadata-docs = ["scale-info/docs"]
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! # Primitives for transaction weighting.
|
||||||
|
//!
|
||||||
|
//! Latest machine specification used to benchmark are:
|
||||||
|
//! - Digital Ocean: ubuntu-s-2vcpu-4gb-ams3-01
|
||||||
|
//! - 2x Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz
|
||||||
|
//! - 4GB RAM
|
||||||
|
//! - Ubuntu 19.10 (GNU/Linux 5.3.0-18-generic x86_64)
|
||||||
|
//! - rustc 1.42.0 (b8cedc004 2020-03-09)
|
||||||
|
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
extern crate self as sp_weights;
|
||||||
|
|
||||||
|
mod weight_v2;
|
||||||
|
|
||||||
|
use codec::{Decode, Encode};
|
||||||
|
use scale_info::TypeInfo;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
use sp_arithmetic::{
|
||||||
|
traits::{BaseArithmetic, SaturatedConversion, Saturating, Unsigned},
|
||||||
|
Perbill,
|
||||||
|
};
|
||||||
|
use sp_core::Get;
|
||||||
|
use sp_debug_derive::RuntimeDebug;
|
||||||
|
|
||||||
|
pub use weight_v2::*;
|
||||||
|
|
||||||
|
pub mod constants {
|
||||||
|
use super::Weight;
|
||||||
|
|
||||||
|
pub const WEIGHT_PER_SECOND: Weight = Weight::from_ref_time(1_000_000_000_000);
|
||||||
|
pub const WEIGHT_PER_MILLIS: Weight = Weight::from_ref_time(1_000_000_000);
|
||||||
|
pub const WEIGHT_PER_MICROS: Weight = Weight::from_ref_time(1_000_000);
|
||||||
|
pub const WEIGHT_PER_NANOS: Weight = Weight::from_ref_time(1_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The weight of database operations that the runtime can invoke.
|
||||||
|
///
|
||||||
|
/// NOTE: This is currently only measured in computational time, and will probably
|
||||||
|
/// be updated all together once proof size is accounted for.
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
||||||
|
pub struct RuntimeDbWeight {
|
||||||
|
pub read: u64,
|
||||||
|
pub write: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RuntimeDbWeight {
|
||||||
|
pub fn reads(self, r: u64) -> Weight {
|
||||||
|
Weight::from_ref_time(self.read.saturating_mul(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn writes(self, w: u64) -> Weight {
|
||||||
|
Weight::from_ref_time(self.write.saturating_mul(w))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reads_writes(self, r: u64, w: u64) -> Weight {
|
||||||
|
let read_weight = self.read.saturating_mul(r);
|
||||||
|
let write_weight = self.write.saturating_mul(w);
|
||||||
|
Weight::from_ref_time(read_weight.saturating_add(write_weight))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// One coefficient and its position in the `WeightToFee`.
|
||||||
|
///
|
||||||
|
/// One term of polynomial is calculated as:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// coeff_integer * x^(degree) + coeff_frac * x^(degree)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The `negative` value encodes whether the term is added or substracted from the
|
||||||
|
/// overall polynomial result.
|
||||||
|
#[derive(Clone, Encode, Decode, TypeInfo)]
|
||||||
|
pub struct WeightToFeeCoefficient<Balance> {
|
||||||
|
/// The integral part of the coefficient.
|
||||||
|
pub coeff_integer: Balance,
|
||||||
|
/// The fractional part of the coefficient.
|
||||||
|
pub coeff_frac: Perbill,
|
||||||
|
/// True iff the coefficient should be interpreted as negative.
|
||||||
|
pub negative: bool,
|
||||||
|
/// Degree/exponent of the term.
|
||||||
|
pub degree: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A list of coefficients that represent one polynomial.
|
||||||
|
pub type WeightToFeeCoefficients<T> = SmallVec<[WeightToFeeCoefficient<T>; 4]>;
|
||||||
|
|
||||||
|
/// A trait that describes the weight to fee calculation.
|
||||||
|
pub trait WeightToFee {
|
||||||
|
/// The type that is returned as result from calculation.
|
||||||
|
type Balance: BaseArithmetic + From<u32> + Copy + Unsigned;
|
||||||
|
|
||||||
|
/// Calculates the fee from the passed `weight`.
|
||||||
|
fn weight_to_fee(weight: &Weight) -> Self::Balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait that describes the weight to fee calculation as polynomial.
|
||||||
|
///
|
||||||
|
/// An implementor should only implement the `polynomial` function.
|
||||||
|
pub trait WeightToFeePolynomial {
|
||||||
|
/// The type that is returned as result from polynomial evaluation.
|
||||||
|
type Balance: BaseArithmetic + From<u32> + Copy + Unsigned;
|
||||||
|
|
||||||
|
/// Returns a polynomial that describes the weight to fee conversion.
|
||||||
|
///
|
||||||
|
/// This is the only function that should be manually implemented. Please note
|
||||||
|
/// that all calculation is done in the probably unsigned `Balance` type. This means
|
||||||
|
/// that the order of coefficients is important as putting the negative coefficients
|
||||||
|
/// first will most likely saturate the result to zero mid evaluation.
|
||||||
|
fn polynomial() -> WeightToFeeCoefficients<Self::Balance>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WeightToFee for T
|
||||||
|
where
|
||||||
|
T: WeightToFeePolynomial,
|
||||||
|
{
|
||||||
|
type Balance = <Self as WeightToFeePolynomial>::Balance;
|
||||||
|
|
||||||
|
/// Calculates the fee from the passed `weight` according to the `polynomial`.
|
||||||
|
///
|
||||||
|
/// This should not be overridden in most circumstances. Calculation is done in the
|
||||||
|
/// `Balance` type and never overflows. All evaluation is saturating.
|
||||||
|
fn weight_to_fee(weight: &Weight) -> Self::Balance {
|
||||||
|
Self::polynomial()
|
||||||
|
.iter()
|
||||||
|
.fold(Self::Balance::saturated_from(0u32), |mut acc, args| {
|
||||||
|
let w = Self::Balance::saturated_from(weight.ref_time())
|
||||||
|
.saturating_pow(args.degree.into());
|
||||||
|
|
||||||
|
// The sum could get negative. Therefore we only sum with the accumulator.
|
||||||
|
// The Perbill Mul implementation is non overflowing.
|
||||||
|
let frac = args.coeff_frac * w;
|
||||||
|
let integer = args.coeff_integer.saturating_mul(w);
|
||||||
|
|
||||||
|
if args.negative {
|
||||||
|
acc = acc.saturating_sub(frac);
|
||||||
|
acc = acc.saturating_sub(integer);
|
||||||
|
} else {
|
||||||
|
acc = acc.saturating_add(frac);
|
||||||
|
acc = acc.saturating_add(integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementor of `WeightToFee` that maps one unit of weight to one unit of fee.
|
||||||
|
pub struct IdentityFee<T>(sp_std::marker::PhantomData<T>);
|
||||||
|
|
||||||
|
impl<T> WeightToFee for IdentityFee<T>
|
||||||
|
where
|
||||||
|
T: BaseArithmetic + From<u32> + Copy + Unsigned,
|
||||||
|
{
|
||||||
|
type Balance = T;
|
||||||
|
|
||||||
|
fn weight_to_fee(weight: &Weight) -> Self::Balance {
|
||||||
|
Self::Balance::saturated_from(weight.ref_time())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementor of [`WeightToFee`] that uses a constant multiplier.
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use sp_core::ConstU128;
|
||||||
|
/// # use sp_weights::ConstantMultiplier;
|
||||||
|
/// // Results in a multiplier of 10 for each unit of weight (or length)
|
||||||
|
/// type LengthToFee = ConstantMultiplier::<u128, ConstU128<10u128>>;
|
||||||
|
/// ```
|
||||||
|
pub struct ConstantMultiplier<T, M>(sp_std::marker::PhantomData<(T, M)>);
|
||||||
|
|
||||||
|
impl<T, M> WeightToFee for ConstantMultiplier<T, M>
|
||||||
|
where
|
||||||
|
T: BaseArithmetic + From<u32> + Copy + Unsigned,
|
||||||
|
M: Get<T>,
|
||||||
|
{
|
||||||
|
type Balance = T;
|
||||||
|
|
||||||
|
fn weight_to_fee(weight: &Weight) -> Self::Balance {
|
||||||
|
Self::Balance::saturated_from(weight.ref_time()).saturating_mul(M::get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use smallvec::smallvec;
|
||||||
|
|
||||||
|
type Balance = u64;
|
||||||
|
|
||||||
|
// 0.5x^3 + 2.333x^2 + 7x - 10_000
|
||||||
|
struct Poly;
|
||||||
|
impl WeightToFeePolynomial for Poly {
|
||||||
|
type Balance = Balance;
|
||||||
|
|
||||||
|
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||||
|
smallvec![
|
||||||
|
WeightToFeeCoefficient {
|
||||||
|
coeff_integer: 0,
|
||||||
|
coeff_frac: Perbill::from_float(0.5),
|
||||||
|
negative: false,
|
||||||
|
degree: 3
|
||||||
|
},
|
||||||
|
WeightToFeeCoefficient {
|
||||||
|
coeff_integer: 2,
|
||||||
|
coeff_frac: Perbill::from_rational(1u32, 3u32),
|
||||||
|
negative: false,
|
||||||
|
degree: 2
|
||||||
|
},
|
||||||
|
WeightToFeeCoefficient {
|
||||||
|
coeff_integer: 7,
|
||||||
|
coeff_frac: Perbill::zero(),
|
||||||
|
negative: false,
|
||||||
|
degree: 1
|
||||||
|
},
|
||||||
|
WeightToFeeCoefficient {
|
||||||
|
coeff_integer: 10_000,
|
||||||
|
coeff_frac: Perbill::zero(),
|
||||||
|
negative: true,
|
||||||
|
degree: 0
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn polynomial_works() {
|
||||||
|
// 100^3/2=500000 100^2*(2+1/3)=23333 700 -10000
|
||||||
|
assert_eq!(Poly::weight_to_fee(&Weight::from_ref_time(100)), 514033);
|
||||||
|
// 10123^3/2=518677865433 10123^2*(2+1/3)=239108634 70861 -10000
|
||||||
|
assert_eq!(Poly::weight_to_fee(&Weight::from_ref_time(10_123)), 518917034928);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn polynomial_does_not_underflow() {
|
||||||
|
assert_eq!(Poly::weight_to_fee(&Weight::zero()), 0);
|
||||||
|
assert_eq!(Poly::weight_to_fee(&Weight::from_ref_time(10)), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn polynomial_does_not_overflow() {
|
||||||
|
assert_eq!(Poly::weight_to_fee(&Weight::MAX), Balance::max_value() - 10_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn identity_fee_works() {
|
||||||
|
assert_eq!(IdentityFee::<Balance>::weight_to_fee(&Weight::zero()), 0);
|
||||||
|
assert_eq!(IdentityFee::<Balance>::weight_to_fee(&Weight::from_ref_time(50)), 50);
|
||||||
|
assert_eq!(IdentityFee::<Balance>::weight_to_fee(&Weight::MAX), Balance::max_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn constant_fee_works() {
|
||||||
|
use sp_core::ConstU128;
|
||||||
|
assert_eq!(
|
||||||
|
ConstantMultiplier::<u128, ConstU128<100u128>>::weight_to_fee(&Weight::zero()),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ConstantMultiplier::<u128, ConstU128<10u128>>::weight_to_fee(&Weight::from_ref_time(
|
||||||
|
50
|
||||||
|
)),
|
||||||
|
500
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ConstantMultiplier::<u128, ConstU128<1024u128>>::weight_to_fee(&Weight::from_ref_time(
|
||||||
|
16
|
||||||
|
)),
|
||||||
|
16384
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ConstantMultiplier::<u128, ConstU128<{ u128::MAX }>>::weight_to_fee(
|
||||||
|
&Weight::from_ref_time(2)
|
||||||
|
),
|
||||||
|
u128::MAX
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-197
@@ -17,10 +17,8 @@
|
|||||||
|
|
||||||
use codec::{CompactAs, Decode, Encode, MaxEncodedLen};
|
use codec::{CompactAs, Decode, Encode, MaxEncodedLen};
|
||||||
use core::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
|
||||||
use sp_runtime::{
|
use sp_arithmetic::traits::{Bounded, CheckedAdd, CheckedSub, Zero};
|
||||||
traits::{Bounded, CheckedAdd, CheckedSub, Zero},
|
use sp_debug_derive::RuntimeDebug;
|
||||||
RuntimeDebug,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -266,11 +264,11 @@ macro_rules! weight_mul_per_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
weight_mul_per_impl!(
|
weight_mul_per_impl!(
|
||||||
sp_runtime::Percent,
|
sp_arithmetic::Percent,
|
||||||
sp_runtime::PerU16,
|
sp_arithmetic::PerU16,
|
||||||
sp_runtime::Permill,
|
sp_arithmetic::Permill,
|
||||||
sp_runtime::Perbill,
|
sp_arithmetic::Perbill,
|
||||||
sp_runtime::Perquintill,
|
sp_arithmetic::Perquintill,
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! weight_mul_primitive_impl {
|
macro_rules! weight_mul_primitive_impl {
|
||||||
@@ -310,91 +308,6 @@ impl CheckedSub for Weight {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PaysFee<T> for (Weight, DispatchClass, Pays) {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
self.2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for (Weight, DispatchClass) {
|
|
||||||
fn weigh_data(&self, args: T) -> Weight {
|
|
||||||
return self.0.weigh_data(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for (Weight, DispatchClass, Pays) {
|
|
||||||
fn weigh_data(&self, args: T) -> Weight {
|
|
||||||
return self.0.weigh_data(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for (Weight, DispatchClass) {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for (Weight, DispatchClass) {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
Pays::Yes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for (Weight, Pays) {
|
|
||||||
fn weigh_data(&self, args: T) -> Weight {
|
|
||||||
return self.0.weigh_data(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for (Weight, Pays) {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
DispatchClass::Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for (Weight, Pays) {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(Option<Weight>, Pays)> for PostDispatchInfo {
|
|
||||||
fn from(post_weight_info: (Option<Weight>, Pays)) -> Self {
|
|
||||||
let (actual_weight, pays_fee) = post_weight_info;
|
|
||||||
Self { actual_weight, pays_fee }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Option<Weight>> for PostDispatchInfo {
|
|
||||||
fn from(actual_weight: Option<Weight>) -> Self {
|
|
||||||
Self { actual_weight, pays_fee: Default::default() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for Weight {
|
|
||||||
fn weigh_data(&self, _: T) -> Weight {
|
|
||||||
return *self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for Weight {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
DispatchClass::Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for Weight {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
Pays::Yes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for (Weight, DispatchClass, Pays) {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::fmt::Display for Weight {
|
impl core::fmt::Display for Weight {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "Weight(ref_time: {})", self.ref_time)
|
write!(f, "Weight(ref_time: {})", self.ref_time)
|
||||||
@@ -421,106 +334,3 @@ impl SubAssign for Weight {
|
|||||||
*self = Self { ref_time: self.ref_time - other.ref_time };
|
*self = Self { ref_time: self.ref_time - other.ref_time };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sp_runtime::traits::Printable for Weight {
|
|
||||||
fn print(&self) {
|
|
||||||
self.ref_time().print()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Eventually remove these
|
|
||||||
|
|
||||||
impl From<Option<u64>> for PostDispatchInfo {
|
|
||||||
fn from(maybe_actual_computation: Option<u64>) -> Self {
|
|
||||||
let actual_weight = match maybe_actual_computation {
|
|
||||||
Some(actual_computation) => Some(Weight::zero().set_ref_time(actual_computation)),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
Self { actual_weight, pays_fee: Default::default() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(Option<u64>, Pays)> for PostDispatchInfo {
|
|
||||||
fn from(post_weight_info: (Option<u64>, Pays)) -> Self {
|
|
||||||
let (maybe_actual_time, pays_fee) = post_weight_info;
|
|
||||||
let actual_weight = match maybe_actual_time {
|
|
||||||
Some(actual_time) => Some(Weight::zero().set_ref_time(actual_time)),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
Self { actual_weight, pays_fee }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for u64 {
|
|
||||||
fn weigh_data(&self, _: T) -> Weight {
|
|
||||||
return Weight::zero().set_ref_time(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for u64 {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
DispatchClass::Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for u64 {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
Pays::Yes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for (u64, DispatchClass, Pays) {
|
|
||||||
fn weigh_data(&self, args: T) -> Weight {
|
|
||||||
return self.0.weigh_data(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for (u64, DispatchClass, Pays) {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for (u64, DispatchClass, Pays) {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
self.2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for (u64, DispatchClass) {
|
|
||||||
fn weigh_data(&self, args: T) -> Weight {
|
|
||||||
return self.0.weigh_data(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for (u64, DispatchClass) {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for (u64, DispatchClass) {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
Pays::Yes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> WeighData<T> for (u64, Pays) {
|
|
||||||
fn weigh_data(&self, args: T) -> Weight {
|
|
||||||
return self.0.weigh_data(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ClassifyDispatch<T> for (u64, Pays) {
|
|
||||||
fn classify_dispatch(&self, _: T) -> DispatchClass {
|
|
||||||
DispatchClass::Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PaysFee<T> for (u64, Pays) {
|
|
||||||
fn pays_fee(&self, _: T) -> Pays {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// END TODO
|
|
||||||
@@ -13,10 +13,8 @@
|
|||||||
// {{arg}}
|
// {{arg}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
use frame_support::{
|
use sp_core::parameter_types;
|
||||||
parameter_types,
|
use sp_weights::{constants::WEIGHT_PER_NANOS, Weight};
|
||||||
weights::{constants::WEIGHT_PER_NANOS, Weight},
|
|
||||||
};
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
{{#if (eq short_name "block")}}
|
{{#if (eq short_name "block")}}
|
||||||
@@ -42,7 +40,7 @@ parameter_types! {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_weights {
|
mod test_weights {
|
||||||
use super::*;
|
use super::*;
|
||||||
use frame_support::weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that the weight exists and is sane.
|
/// Checks that the weight exists and is sane.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
|
|||||||
@@ -17,10 +17,9 @@
|
|||||||
|
|
||||||
/// Storage DB weights for the `{{runtime_name}}` runtime and `{{db_name}}`.
|
/// Storage DB weights for the `{{runtime_name}}` runtime and `{{db_name}}`.
|
||||||
pub mod constants {
|
pub mod constants {
|
||||||
use frame_support::{
|
use frame_support::weights::constants;
|
||||||
parameter_types,
|
use sp_core::parameter_types;
|
||||||
weights::{constants, RuntimeDbWeight},
|
use sp_weights::RuntimeDbWeight;
|
||||||
};
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
{{#if (eq db_name "ParityDb")}}
|
{{#if (eq db_name "ParityDb")}}
|
||||||
@@ -66,7 +65,7 @@ pub mod constants {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db_weights {
|
mod test_db_weights {
|
||||||
use super::constants::{{db_name}}Weight as W;
|
use super::constants::{{db_name}}Weight as W;
|
||||||
use frame_support::weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that all weights exist and have sane values.
|
/// Checks that all weights exist and have sane values.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
|
|||||||
Reference in New Issue
Block a user