mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 04:37:57 +00:00
Extensible transactions (and tips) (#3102)
* Make extrinsics extensible. Also Remove old extrinsic types. * Rest of mockup. Add tips. * Fix some build issues * Runtiem builds :) * Substrate builds. * Fix a doc test * Compact encoding * Extract out the era logic into an extension * Weight Check signed extension. (#3115) * Weight signed extension. * Revert a bit + test for check era. * Update Cargo.toml * Update node/cli/src/factory_impl.rs * Update node/executor/src/lib.rs * Update node/executor/src/lib.rs * Don't use len for weight - use data. * Operational Transaction; second attempt (#3138) * working poc added. * some fixes. * Update doc. * Fix all tests + final logic. * more refactoring. * nits. * System block limit in bytes. * Silent the storage macro warnings. * More logic more tests. * Fix import. * Refactor names. * Fix build. * Update srml/balances/src/lib.rs * Final refactor. * Bump transaction version * Fix weight mult test. * Fix more tests and improve doc. * Bump. * Make some tests work again. * Fix subkey. * Remove todos + bump. * Ignore expensive test. * Bump.
This commit is contained in:
@@ -17,10 +17,11 @@
|
||||
//! Some configurable implementations as associated type for the substrate runtime.
|
||||
|
||||
use node_primitives::Balance;
|
||||
use runtime_primitives::weights::{Weight, WeightMultiplier, MAX_TRANSACTIONS_WEIGHT, IDEAL_TRANSACTIONS_WEIGHT};
|
||||
use runtime_primitives::weights::{Weight, WeightMultiplier};
|
||||
use runtime_primitives::traits::{Convert, Saturating};
|
||||
use runtime_primitives::Fixed64;
|
||||
use crate::Balances;
|
||||
use support::traits::Get;
|
||||
use crate::{Balances, MaximumBlockWeight};
|
||||
|
||||
/// Struct that handles the conversion of Balance -> `u64`. This is used for staking's election
|
||||
/// calculation.
|
||||
@@ -53,14 +54,19 @@ pub struct WeightMultiplierUpdateHandler;
|
||||
impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierUpdateHandler {
|
||||
fn convert(previous_state: (Weight, WeightMultiplier)) -> WeightMultiplier {
|
||||
let (block_weight, multiplier) = previous_state;
|
||||
let ideal = IDEAL_TRANSACTIONS_WEIGHT as u128;
|
||||
// CRITICAL NOTE: what the system module interprets as maximum block weight, and a portion
|
||||
// of it (1/4 usually) as ideal weight demonstrate the gap in block weights for operational
|
||||
// transactions. What this weight multiplier interprets as the maximum, is actually the
|
||||
// maximum that is available to normal transactions. Hence,
|
||||
let max_weight = <MaximumBlockWeight as Get<u32>>::get() / 4;
|
||||
let ideal_weight = (max_weight / 4) as u128;
|
||||
let block_weight = block_weight as u128;
|
||||
|
||||
// determines if the first_term is positive
|
||||
let positive = block_weight >= ideal;
|
||||
let diff_abs = block_weight.max(ideal) - block_weight.min(ideal);
|
||||
let positive = block_weight >= ideal_weight;
|
||||
let diff_abs = block_weight.max(ideal_weight) - block_weight.min(ideal_weight);
|
||||
// diff is within u32, safe.
|
||||
let diff = Fixed64::from_rational(diff_abs as i64, MAX_TRANSACTIONS_WEIGHT as u64);
|
||||
let diff = Fixed64::from_rational(diff_abs as i64, max_weight as u64);
|
||||
let diff_squared = diff.saturating_mul(diff);
|
||||
|
||||
// 0.00004 = 4/100_000 = 40_000/10^9
|
||||
@@ -94,9 +100,17 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use runtime_primitives::weights::{MAX_TRANSACTIONS_WEIGHT, IDEAL_TRANSACTIONS_WEIGHT, Weight};
|
||||
use runtime_primitives::weights::Weight;
|
||||
use runtime_primitives::Perbill;
|
||||
|
||||
fn max() -> Weight {
|
||||
<MaximumBlockWeight as Get<Weight>>::get()
|
||||
}
|
||||
|
||||
fn ideal() -> Weight {
|
||||
max() / 4 / 4
|
||||
}
|
||||
|
||||
// poc reference implementation.
|
||||
#[allow(dead_code)]
|
||||
fn weight_multiplier_update(block_weight: Weight) -> Perbill {
|
||||
@@ -104,9 +118,9 @@ mod tests {
|
||||
let v: f32 = 0.00004;
|
||||
|
||||
// maximum tx weight
|
||||
let m = MAX_TRANSACTIONS_WEIGHT as f32;
|
||||
let m = max() as f32;
|
||||
// Ideal saturation in terms of weight
|
||||
let ss = IDEAL_TRANSACTIONS_WEIGHT as f32;
|
||||
let ss = ideal() as f32;
|
||||
// Current saturation in terms of weight
|
||||
let s = block_weight;
|
||||
|
||||
@@ -124,22 +138,22 @@ mod tests {
|
||||
fn stateless_weight_mul() {
|
||||
// Light block. Fee is reduced a little.
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((1024, WeightMultiplier::default())),
|
||||
fm(-9990)
|
||||
WeightMultiplierUpdateHandler::convert((ideal() / 4, WeightMultiplier::default())),
|
||||
fm(-7500)
|
||||
);
|
||||
// a bit more. Fee is decreased less, meaning that the fee increases as the block grows.
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((1024 * 4, WeightMultiplier::default())),
|
||||
fm(-9960)
|
||||
WeightMultiplierUpdateHandler::convert((ideal() / 2, WeightMultiplier::default())),
|
||||
fm(-5000)
|
||||
);
|
||||
// ideal. Original fee.
|
||||
// ideal. Original fee. No changes.
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((IDEAL_TRANSACTIONS_WEIGHT as u32, WeightMultiplier::default())),
|
||||
WeightMultiplierUpdateHandler::convert((ideal() as u32, WeightMultiplier::default())),
|
||||
fm(0)
|
||||
);
|
||||
// // More than ideal. Fee is increased.
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert(((IDEAL_TRANSACTIONS_WEIGHT * 2) as u32, WeightMultiplier::default())),
|
||||
WeightMultiplierUpdateHandler::convert(((ideal() * 2) as u32, WeightMultiplier::default())),
|
||||
fm(10000)
|
||||
);
|
||||
}
|
||||
@@ -147,20 +161,20 @@ mod tests {
|
||||
#[test]
|
||||
fn stateful_weight_mul_grow_to_infinity() {
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((IDEAL_TRANSACTIONS_WEIGHT * 2, WeightMultiplier::default())),
|
||||
WeightMultiplierUpdateHandler::convert((ideal() * 2, WeightMultiplier::default())),
|
||||
fm(10000)
|
||||
);
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((IDEAL_TRANSACTIONS_WEIGHT * 2, fm(10000))),
|
||||
WeightMultiplierUpdateHandler::convert((ideal() * 2, fm(10000))),
|
||||
fm(20000)
|
||||
);
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((IDEAL_TRANSACTIONS_WEIGHT * 2, fm(20000))),
|
||||
WeightMultiplierUpdateHandler::convert((ideal() * 2, fm(20000))),
|
||||
fm(30000)
|
||||
);
|
||||
// ...
|
||||
assert_eq!(
|
||||
WeightMultiplierUpdateHandler::convert((IDEAL_TRANSACTIONS_WEIGHT * 2, fm(1_000_000_000))),
|
||||
WeightMultiplierUpdateHandler::convert((ideal() * 2, fm(1_000_000_000))),
|
||||
fm(1_000_000_000 + 10000)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ use client::{
|
||||
};
|
||||
use runtime_primitives::{ApplyResult, impl_opaque_keys, generic, create_runtime_str, key_types};
|
||||
use runtime_primitives::transaction_validity::TransactionValidity;
|
||||
use runtime_primitives::weights::Weight;
|
||||
use runtime_primitives::traits::{
|
||||
BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup,
|
||||
};
|
||||
@@ -74,8 +75,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
// and set impl_version to equal spec_version. If only runtime
|
||||
// implementation changes and behavior does not, then leave spec_version as
|
||||
// is and increment impl_version.
|
||||
spec_version: 116,
|
||||
impl_version: 116,
|
||||
spec_version: 117,
|
||||
impl_version: 117,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
@@ -116,6 +117,8 @@ pub const DAYS: Moment = HOURS * 24;
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: BlockNumber = 250;
|
||||
pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024;
|
||||
pub const MaximumBlockLength: u32 = 4 * 1024 * 1024;
|
||||
}
|
||||
|
||||
impl system::Trait for Runtime {
|
||||
@@ -130,6 +133,8 @@ impl system::Trait for Runtime {
|
||||
type WeightMultiplierUpdate = WeightMultiplierUpdateHandler;
|
||||
type Event = Event;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type MaximumBlockWeight = MaximumBlockWeight;
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
}
|
||||
|
||||
impl aura::Trait for Runtime {
|
||||
@@ -432,12 +437,19 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
/// BlockId type as expected by this runtime.
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
/// The SignedExtension to the basic transaction logic.
|
||||
pub type SignedExtra = (
|
||||
system::CheckEra<Runtime>,
|
||||
system::CheckNonce<Runtime>,
|
||||
system::CheckWeight<Runtime>,
|
||||
balances::TakeFees<Runtime>
|
||||
);
|
||||
/// Unchecked extrinsic type as expected by this runtime.
|
||||
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Index, Call, Signature>;
|
||||
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
|
||||
/// Extrinsic type that has already been checked.
|
||||
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Index, Call>;
|
||||
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
|
||||
/// Executive: handles dispatch to the various modules.
|
||||
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Balances, Runtime, AllModules>;
|
||||
pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl client_api::Core<Block> for Runtime {
|
||||
|
||||
Reference in New Issue
Block a user