diff --git a/Cargo.lock b/Cargo.lock index d925435e138c4..33d34db349ec1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3738,6 +3738,7 @@ name = "srml-executive" version = "2.0.0" dependencies = [ "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "node-runtime 2.0.0", "parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index 190fff168c770..65c0f20182e5e 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -199,7 +199,7 @@ mod tests { use super::*; use runtime_io::blake2_256; use crate::codec::{Encode, Decode}; - use crate::traits::SignedExtension; + use crate::traits::{SignedExtension, BlockNumberToHash, Lookup, CurrentHeight}; use serde::{Serialize, Deserialize}; struct TestContext; @@ -237,6 +237,8 @@ mod tests { struct TestExtra; impl SignedExtension for TestExtra { type AccountId = u64; + type AdditionalSigned = (); + fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } } type Ex = UncheckedExtrinsic; @@ -254,8 +256,7 @@ mod tests { let ux = Ex::new_signed( vec![0u8; 0], TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (TEST_ACCOUNT, vec![0u8; 0], Era::immortal(), 0u64).encode()), - Era::immortal(), + TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), TestExtra ); let encoded = ux.encode(); @@ -267,9 +268,8 @@ mod tests { let ux = Ex::new_signed( vec![0u8; 0], TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (TEST_ACCOUNT, vec![0u8; 257], Era::immortal(), 0u64) + TestSig(TEST_ACCOUNT, (vec![0u8; 257], TestExtra) .using_encoded(blake2_256)[..].to_owned()), - Era::immortal(), TestExtra ); let encoded = ux.encode(); @@ -289,7 +289,6 @@ mod tests { vec![0u8; 0], TEST_ACCOUNT, TestSig(TEST_ACCOUNT, vec![0u8; 0]), - Era::immortal(), TestExtra ); assert!(ux.is_signed().unwrap_or(false)); @@ -297,12 +296,11 @@ mod tests { } #[test] - fn immortal_signed_check_should_work() { + fn signed_check_should_work() { let ux = Ex::new_signed( vec![0u8; 0], TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], Era::immortal(), 0u64, TestExtra).encode()), - Era::immortal(), + TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), TestExtra ); assert!(ux.is_signed().unwrap_or(false)); @@ -312,63 +310,6 @@ mod tests { ); } - #[test] - fn mortal_signed_check_should_work() { - let ux = Ex::new_signed( - vec![0u8; 0], - TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], Era::mortal(32, 42), 42u64, TestExtra).encode()), - Era::mortal(32, 42), - TestExtra - ); - assert!(ux.is_signed().unwrap_or(false)); - assert_eq!( - >::check(ux, &TestContext), - Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }) - ); - } - - #[test] - fn later_mortal_signed_check_should_work() { - let ux = Ex::new_signed( - vec![0u8; 0], - TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], Era::mortal(32, 11), 11u64, TestExtra).encode()), - Era::mortal(32, 11), - TestExtra - ); - assert!(ux.is_signed().unwrap_or(false)); - assert_eq!( - >::check(ux, &TestContext), - Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] })); - } - - #[test] - fn too_late_mortal_signed_check_should_fail() { - let ux = Ex::new_signed( - vec![0u8; 0], - TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (TEST_ACCOUNT, vec![0u8; 0], Era::mortal(32, 10), 10u64).encode()), - Era::mortal(32, 10), - TestExtra - ); - assert!(ux.is_signed().unwrap_or(false)); - assert_eq!(>::check(ux, &TestContext), Err(crate::BAD_SIGNATURE)); - } - - #[test] - fn too_early_mortal_signed_check_should_fail() { - let ux = Ex::new_signed( - vec![0u8; 0], - TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (TEST_ACCOUNT, vec![0u8; 0], Era::mortal(32, 43), 43u64).encode()), - Era::mortal(32, 43), - TestExtra - ); - assert!(ux.is_signed().unwrap_or(false)); - assert_eq!(>::check(ux, &TestContext), Err(crate::BAD_SIGNATURE)); - } - #[test] fn encoding_matches_vec() { let ex = Ex::new_unsigned(vec![0u8; 0]); diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 98b3ceb0ef15d..1afe65fa274b2 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -848,58 +848,74 @@ pub trait SignedExtension: ) -> Result<(), DispatchError> { Self::validate_unsigned(weight).map(|_| ()) } } -impl< - AccountId, - A: SignedExtension, - B: SignedExtension, -> SignedExtension for (A, B) { - type AccountId = AccountId; - type AdditionalSigned = (A::AdditionalSigned, B::AdditionalSigned); - - fn additional_signed(&self) -> Result { - Ok((self.0.additional_signed()?, self.1.additional_signed()?)) - } +macro_rules! tuple_impl_indexed { + ($first:ident, $($rest:ident,)+ ; $first_index:tt, $($rest_index:tt,)+) => { + tuple_impl_indexed!([$first] [$($rest)+] ; [$first_index,] [$($rest_index,)+]); + }; + ([$($direct:ident)+] ; [$($index:tt,)+]) => { + impl< + AccountId, + $($direct: SignedExtension),+ + > SignedExtension for ($($direct),+,) { + type AccountId = AccountId; + type AdditionalSigned = ($($direct::AdditionalSigned,)+); + fn additional_signed(&self) -> Result { + Ok(( $(self.$index.additional_signed()?,)+ )) + } + fn validate( + &self, + who: &Self::AccountId, + weight: crate::weights::Weight, + ) -> Result { + let aggregator = vec![$(<$direct as SignedExtension>::validate(&self.$index, who, weight)?),+]; + Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a))) + } + fn pre_dispatch( + self, + who: &Self::AccountId, + weight: crate::weights::Weight, + ) -> Result<(), DispatchError> { + $(self.$index.pre_dispatch(who, weight)?;)+ + Ok(()) + } + fn validate_unsigned( + weight: crate::weights::Weight, + ) -> Result { + let aggregator = vec![$($direct::validate_unsigned(weight)?),+]; + Ok(aggregator.into_iter().fold(ValidTransaction::default(), |acc, a| acc.combine_with(a))) + } + fn pre_dispatch_unsigned( + weight: crate::weights::Weight, + ) -> Result<(), DispatchError> { + $($direct::pre_dispatch_unsigned(weight)?;)+ + Ok(()) + } + } - fn validate( - &self, - who: &Self::AccountId, - weight: crate::weights::Weight, - ) -> Result { - let a = self.0.validate(who, weight)?; - let b = self.1.validate(who, weight)?; - Ok(a.combine_with(b)) - } - fn pre_dispatch( - self, - who: &Self::AccountId, - weight: crate::weights::Weight, - ) -> Result<(), DispatchError> { - self.0.pre_dispatch(who, weight)?; - self.1.pre_dispatch(who, weight)?; - Ok(()) - } - fn validate_unsigned( - weight: crate::weights::Weight, - ) -> Result { - let a = A::validate_unsigned(weight)?; - let b = B::validate_unsigned(weight)?; - Ok(a.combine_with(b)) - } - fn pre_dispatch_unsigned( - weight: crate::weights::Weight, - ) -> Result<(), DispatchError> { - A::pre_dispatch_unsigned(weight)?; - B::pre_dispatch_unsigned(weight)?; - Ok(()) - } + }; + ([$($direct:ident)+] [] ; [$($index:tt,)+] []) => { + tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); + }; + ( + [$($direct:ident)+] [$first:ident $($rest:ident)*] + ; + [$($index:tt,)+] [$first_index:tt, $($rest_index:tt,)*] + ) => { + tuple_impl_indexed!([$($direct)+] ; [$($index,)+]); + tuple_impl_indexed!([$($direct)+ $first] [$($rest)*] ; [$($index,)+ $first_index,] [$($rest_index,)*]); + }; } -/// To be used only for testing. +// TODO: merge this into `tuple_impl` once codec supports `trait Codec` for longer tuple lengths. +#[allow(non_snake_case)] +tuple_impl_indexed!(A, B, C, D, E, F, G, H, I, J, ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,); + +/// Only for base bone testing when you don't care about signed extensions at all.\ #[cfg(feature = "std")] impl SignedExtension for () { type AccountId = u64; type AdditionalSigned = (); - fn additional_signed(&self) -> result::Result<(), &'static str> { Ok(()) } + fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } } /// An "executable" piece of information, used by the standard Substrate Executive in order to diff --git a/core/sr-primitives/src/transaction_validity.rs b/core/sr-primitives/src/transaction_validity.rs index 66e66c0042db9..a6cc43c5a365d 100644 --- a/core/sr-primitives/src/transaction_validity.rs +++ b/core/sr-primitives/src/transaction_validity.rs @@ -103,7 +103,7 @@ impl ValidTransaction { /// the logic *And* of the propagate flags. pub fn combine_with(mut self, mut other: ValidTransaction) -> Self { ValidTransaction { - priority: self.priority + other.priority, + priority: self.priority.saturating_add(other.priority), requires: { self.requires.append(&mut other.requires); self.requires }, provides: { self.provides.append(&mut other.provides); self.provides }, longevity: self.longevity.min(other.longevity), diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 1dcc65d00b5e4..3a6eb1886fc34 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -17,7 +17,7 @@ use primitives::bytes; use primitives::{ed25519, sr25519, OpaqueMetadata}; use runtime_primitives::{ ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, - traits::{self, NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify} + traits::{self, NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify}, weights::Weight, }; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, @@ -113,6 +113,7 @@ pub fn native_version() -> NativeVersion { parameter_types! { pub const BlockHashCount: BlockNumber = 250; + pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; } impl system::Trait for Runtime { @@ -136,6 +137,8 @@ impl system::Trait for Runtime { type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; + /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. + type MaximumBlockWeight = MaximumBlockWeight; } impl aura::Trait for Runtime { @@ -228,7 +231,7 @@ pub type Block = generic::Block; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. -pub type SignedExtra = (system::CheckNonce, balances::TakeFees); +pub type SignedExtra = (system::CheckNonce, system::CheckWeight, balances::TakeFees); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 05257d2a53341..97466d2b6dce5 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -73,6 +73,7 @@ mod tests { use primitives::{H256, Blake2Hasher}; use support::{impl_outer_origin, assert_ok, parameter_types}; use runtime_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use runtime_primitives::weights::Weight; impl_outer_origin! { pub enum Origin for Test {} @@ -85,6 +86,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -97,6 +99,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Test { type Event = (); diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index ed45d4cf9545a..6f2ef00ad74a6 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -51,6 +51,17 @@ pub struct FactoryState { type Number = <::Header as HeaderT>::Number; +impl FactoryState { + fn build_extra(index: node_primitives::Index, phase: u64) -> node_runtime::SignedExtra { + ( + system::CheckEra::from(Era::mortal(256, phase)), + system::CheckNonce::from(index), + system::CheckWeight::from(), + balances::TakeFees::from(0) + ) + } +} + impl RuntimeAdapter for FactoryState { type AccountId = node_primitives::AccountId; type Balance = node_primitives::Balance; @@ -127,19 +138,16 @@ impl RuntimeAdapter for FactoryState { ) -> ::Extrinsic { let index = self.extract_index(&sender, prior_block_hash); let phase = self.extract_phase(*prior_block_hash); - let era = system::CheckEra::from(Era::mortal(256, phase)); - let check_nonce = system::CheckNonce::from(index); - let take_fees = balances::TakeFees::from(0); sign::(CheckedExtrinsic { - signed: Some((sender.clone(), (era, (check_nonce, take_fees)))), + signed: Some((sender.clone(), Self::build_extra(index, phase))), function: Call::Balances( BalancesCall::transfer( indices::address::Address::Id(destination.clone().into()), (*amount).into() ) ) - }, key, (prior_block_hash.clone(), ((), ()))) + }, key, (prior_block_hash.clone(), (), (), ())) } fn inherent_extrinsics(&self) -> InherentData { diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index ce054f9f798a2..6302a6a4815e5 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -357,12 +357,14 @@ mod tests { let signer = charlie.clone(); let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - let era = Era::immortal(); + + let check_era = system::CheckEra::from(Era::Immortal); let check_nonce = system::CheckNonce::from(index); + let check_weight = system::CheckWeight::from(); let take_fees = balances::TakeFees::from(0); - let extra = (check_nonce, take_fees); + let extra = (check_era, check_nonce, check_weight, take_fees); - let raw_payload = (function, era, genesis_hash, extra.clone()); + let raw_payload = (function, extra.clone(), genesis_hash); let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { signer.sign(&blake2_256(payload)[..]) } else { @@ -372,7 +374,6 @@ mod tests { raw_payload.0, from.into(), signature.into(), - era, extra, ).encode(); let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index f09853ca10e1e..e0617ff9d1324 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -81,8 +81,10 @@ mod tests { type TestExternalities = CoreTestExternalities; // TODO: fix for being charged based on weight now. - fn transfer_fee(bytes: Balance) -> Balance { - >::get() + >::get() * bytes + fn transfer_fee(extrinsic: &E) -> Balance { + >::get() + + >::get() * + (extrinsic.encode().len() as Balance) } fn creation_fee() -> Balance { @@ -116,8 +118,7 @@ mod tests { fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { match xt.signed { Some((signed, extra)) => { - let era = Era::mortal(256, 0); - let payload = (xt.function, era, GENESIS_HASH, extra.clone()); + let payload = (xt.function, extra.clone(), GENESIS_HASH); let key = AccountKeyring::from_public(&signed).unwrap(); let signature = payload.using_encoded(|b| { if b.len() > 256 { @@ -127,7 +128,7 @@ mod tests { } }).into(); UncheckedExtrinsic { - signature: Some((indices::address::Address::Id(signed), signature, era, extra)), + signature: Some((indices::address::Address::Id(signed), signature, extra)), function: payload.0, } } @@ -139,7 +140,12 @@ mod tests { } fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { - (system::CheckNonce::from(nonce), balances::TakeFees::from(extra_fee)) + ( + system::CheckEra::from(Era::mortal(256, 0)), + system::CheckNonce::from(nonce), + system::CheckWeight::from(), + balances::TakeFees::from(extra_fee) + ) } fn xt() -> UncheckedExtrinsic { @@ -260,7 +266,7 @@ mod tests { assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt()) - creation_fee()); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -296,7 +302,7 @@ mod tests { assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt()) - creation_fee()); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -491,7 +497,6 @@ mod tests { // session change => consensus authorities change => authorities change digest item appears let digest = Header::decode(&mut &block2.0[..]).unwrap().digest; assert_eq!(digest.logs().len(), 0); -// assert!(digest.logs()[0].as_consensus().is_some()); (block1, block2) } @@ -529,7 +534,7 @@ mod tests { ).0.unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt()) - creation_fee()); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); let events = vec![ EventRecord { @@ -566,8 +571,8 @@ mod tests { runtime_io::with_externalities(&mut t, || { // TODO TODO: this needs investigating: why are we deducting creation fee twice here? and why bob also pays it? - assert_eq!(Balances::total_balance(&alice()), 32 * DOLLARS - 2 * transfer_fee(169) - 2 * creation_fee()); - assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 32 * DOLLARS - 2 * transfer_fee(&xt()) - 2 * creation_fee()); + assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - transfer_fee(&xt()) - creation_fee()); let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), @@ -622,15 +627,15 @@ mod tests { WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1.0).unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt()) - creation_fee()); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); }); WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2.0).unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 32 * DOLLARS - 2 * transfer_fee(169) - 2 * creation_fee()); - assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - 1 * transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 32 * DOLLARS - 2 * transfer_fee(&xt()) - 2 * creation_fee()); + assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - 1 * transfer_fee(&xt()) - creation_fee()); }); } @@ -876,7 +881,7 @@ mod tests { assert_eq!(r, Ok(ApplyOutcome::Success)); runtime_io::with_externalities(&mut t, || { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(169) - creation_fee()); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt()) - creation_fee()); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index f6c6707e03cfd..a8130dee0ea17 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -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, Convert, }; @@ -111,6 +112,7 @@ pub const DAYS: Moment = HOURS * 24; parameter_types! { pub const BlockHashCount: BlockNumber = 250; + pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; } impl system::Trait for Runtime { @@ -124,6 +126,7 @@ impl system::Trait for Runtime { type Header = generic::Header; type Event = Event; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl aura::Trait for Runtime { @@ -436,7 +439,12 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. -pub type SignedExtra = (system::CheckEra, (system::CheckNonce, balances::TakeFees)); +pub type SignedExtra = ( + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + balances::TakeFees +); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index 19159bf60fba3..1e4c06700abe1 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -257,6 +257,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -269,6 +270,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Test { type Event = (); diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index fad511baba331..ba6a66cdace68 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -37,6 +37,7 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { @@ -50,6 +51,7 @@ impl system::Trait for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl timestamp::Trait for Test { diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 08a0279284871..42fa0630a4855 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -337,6 +337,7 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { @@ -350,6 +351,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Test { diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 9266b44a4ee42..004ea41a035e9 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -747,6 +747,7 @@ impl, I: Instance> system::Trait for ElevatedTrait { type Header = T::Header; type Event = (); type BlockHashCount = T::BlockHashCount; + type MaximumBlockWeight = T::MaximumBlockWeight; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; @@ -1156,7 +1157,6 @@ use primitives::weights::Weight; impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { type AccountId = T::AccountId; - type AdditionalSigned = (); fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index 26f4439f4608d..274f093386823 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -67,6 +67,7 @@ impl Get for TransactionByteFee { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Runtime { type Origin = Origin; @@ -79,6 +80,7 @@ impl system::Trait for Runtime { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Runtime { type Balance = u64; diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 10e6f94693682..c5e36ed6571f2 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -658,3 +658,20 @@ fn extra_balance_should_transfer() { } ); } + +#[test] +fn signed_extension_take_fees_work() { + with_externalities( + &mut ExtBuilder::default() + .existential_deposit(10) + .transaction_fees(10, 1) + .monied(true) + .build(), + || { + assert!(TakeFees::::from(0).validate(&1, 10).is_ok()); + assert_eq!(Balances::free_balance(&1), 100 - 20); + assert!(TakeFees::::from(5 /* tipped */).validate(&1, 10).is_ok()); + assert_eq!(Balances::free_balance(&1), 100 - 20 - 25); + } + ); +} diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 23b156c718e7f..a8303501d46ea 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -402,6 +402,7 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -414,6 +415,7 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Test { type Origin = Origin; diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index b195a74bf429b..c3c6a595a3442 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -96,6 +96,7 @@ impl Get for BlockGasLimit { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -108,6 +109,7 @@ impl system::Trait for Test { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const BalancesTransactionBaseFee: u64 = 0; diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index 8a52f9ec004a9..1baeb6fdfd34b 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -98,6 +98,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -110,6 +111,7 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index d13feb4db531d..5c49f9519013d 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -998,6 +998,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -1010,6 +1011,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/srml/elections/src/lib.rs b/srml/elections/src/lib.rs index 77597591775d7..324c1a78fbf1e 100644 --- a/srml/elections/src/lib.rs +++ b/srml/elections/src/lib.rs @@ -1108,6 +1108,7 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -1120,6 +1121,7 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 20ee1c6ba114f..b2bb0a0af47e4 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -525,6 +525,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -537,6 +538,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index 512b9086c9cbb..fa08a1017b94f 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -91,8 +91,6 @@ use primitives::weights::Weighable; mod internal { use primitives::traits::DispatchError; - pub const MAX_TRANSACTIONS_WEIGHT: u32 = 4 * 1024 * 1024; - pub enum ApplyError { BadSignature(&'static str), Stale, @@ -283,17 +281,10 @@ where >::note_extrinsic(encoded); } - // Check the weight of the block if that extrinsic is applied. - let weight = xt.weight(encoded_len); - - // TODO: Consider placing into a transaction extension. - if >::all_extrinsics_weight() + weight > internal::MAX_TRANSACTIONS_WEIGHT { - return Err(internal::ApplyError::FullBlock); - } - // AUDIT: Under no circumstances may this function panic from here onwards. // Decode parameters and dispatch + let weight = xt.weight(encoded_len); let r = Applyable::dispatch(xt, weight) .map_err(internal::ApplyError::from)?; @@ -366,10 +357,11 @@ mod tests { use balances::Call; use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; + use primitives::generic::Era; use primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}; use primitives::testing::{Digest, Header, Block}; use srml_support::{impl_outer_event, impl_outer_origin, parameter_types}; - use srml_support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}; + use srml_support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason, Get}; use system; use hex_literal::hex; @@ -389,6 +381,7 @@ mod tests { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Runtime { type Origin = Origin; @@ -401,6 +394,7 @@ mod tests { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const ExistentialDeposit: u64 = 0; @@ -435,12 +429,22 @@ mod tests { } } - type SignedExtra = (system::CheckNonce, balances::TakeFees); + type SignedExtra = ( + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + balances::TakeFees + ); type TestXt = primitives::testing::TestXt, SignedExtra>; type Executive = super::Executive, system::ChainContext, Runtime, ()>; fn extra(nonce: u64, fee: u64) -> SignedExtra { - (system::CheckNonce::from(nonce), balances::TakeFees::from(fee)) + ( + system::CheckEra::from(Era::Immortal), + system::CheckNonce::from(nonce), + system::CheckWeight::from(), + balances::TakeFees::from(fee) + ) } #[test] @@ -551,7 +555,7 @@ mod tests { let xt = primitives::testing::TestXt(Some(1), Call::transfer(33, 69), extra(0, 0)); let xt2 = primitives::testing::TestXt(Some(1), Call::transfer(33, 69), extra(1, 0)); let encoded = xt2.encode(); - let len = if should_fail { (internal::MAX_TRANSACTIONS_WEIGHT - 1) as usize } else { encoded.len() }; + let len = if should_fail { ( ::MaximumBlockWeight::get() - 1) as usize } else { encoded.len() }; let encoded_len = encoded.len() as u32; with_externalities(&mut t, || { Executive::initialize_block(&Header::new( @@ -583,14 +587,16 @@ mod tests { } #[test] - fn default_block_weight() { - let xt = primitives::testing::TestXt(None, Call::set_balance(33, 69, 69), extra(0, 0)); + fn default_block_weight_is_stored() { + let xt = primitives::testing::TestXt(Some(1), Call::transfer(33, 0), extra(0, 0)); + let x1 = primitives::testing::TestXt(Some(1), Call::transfer(33, 0), extra(1, 0)); + let x2 = primitives::testing::TestXt(Some(1), Call::transfer(33, 0), extra(2, 0)); let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(); with_externalities(&mut t, || { Executive::apply_extrinsic(xt.clone()).unwrap(); - Executive::apply_extrinsic(xt.clone()).unwrap(); - Executive::apply_extrinsic(xt.clone()).unwrap(); + Executive::apply_extrinsic(x1.clone()).unwrap(); + Executive::apply_extrinsic(x2.clone()).unwrap(); assert_eq!( >::all_extrinsics_weight(), 3 * (0 /*base*/ + len /*len*/ * 1 /*byte*/) diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index f9ccc36346222..2e17d9688f1c9 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -299,6 +299,7 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -311,6 +312,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const WindowSize: u64 = 11; diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index 733b2deaf1493..1420d65eb5576 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -43,6 +43,7 @@ impl Trait for Test { } parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -55,6 +56,7 @@ impl system::Trait for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } mod grandpa { diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index 53e8f314c94bb..938aec2bc3311 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -66,6 +66,7 @@ impl ResolveHint for TestResolveHint { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Runtime { type Origin = Origin; @@ -78,6 +79,7 @@ impl system::Trait for Runtime { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Runtime { type AccountIndex = u64; diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index adb37720519a8..e6228e21042ed 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -109,6 +109,7 @@ pub fn set_next_validators(next: Vec) { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -121,6 +122,7 @@ impl system::Trait for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl timestamp::Trait for Test { type Moment = u64; diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index abad1752a6ec6..b767f446df1e8 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -87,6 +87,7 @@ impl_outer_origin!{ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -99,6 +100,7 @@ impl system::Trait for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const TransferFee: u64 = 0; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 684dc24ae7339..be7a3ec492252 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -76,6 +76,7 @@ use serde::Serialize; use rstd::prelude::*; #[cfg(any(feature = "std", test))] use rstd::map; +use rstd::marker::PhantomData; use primitives::{ generic::{self, Era}, weights::Weight, traits::{ self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, @@ -190,6 +191,9 @@ pub trait Trait: 'static + Eq + Clone { /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount: Get; + + /// The maximum weight of a block. + type MaximumBlockWeight: Get; } pub type DigestOf = generic::Digest<::Hash>; @@ -725,17 +729,15 @@ impl Module { } /// To be called immediately after an extrinsic has been applied. - pub fn note_applied_extrinsic(r: &Result<(), &'static str>, encoded_len: u32) { + pub fn note_applied_extrinsic(r: &Result<(), &'static str>, _encoded_len: u32) { Self::deposit_event(match r { Ok(_) => Event::ExtrinsicSuccess, Err(_) => Event::ExtrinsicFailed, }.into()); let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; - let total_length = encoded_len.saturating_add(Self::all_extrinsics_weight()); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); - AllExtrinsicsWeight::put(&total_length); } /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block @@ -753,6 +755,61 @@ impl Module { } } +/// Weight limit check and increment. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckWeight(PhantomData); + +impl CheckWeight { + fn internal_check_weight(weight: Weight) -> Result<(), DispatchError> { + let current_weight = Module::::all_extrinsics_weight(); + let next_weight = current_weight.saturating_add(weight); + if next_weight > T::MaximumBlockWeight::get() { + return Err(DispatchError::Payment) + } + AllExtrinsicsWeight::put(next_weight); + Ok(()) + } +} + +impl SignedExtension for CheckWeight { + type AccountId = T::AccountId; + type AdditionalSigned = (); + + fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + + fn pre_dispatch( + self, + _who: &Self::AccountId, + weight: Weight, + ) -> Result<(), DispatchError> { + Self::internal_check_weight(weight) + } + + fn validate( + &self, + _who: &Self::AccountId, + _weight: Weight, + ) -> Result { + // TODO: check for a maximum size and weight here as well. + // write priority based on tx weight type + tip. + Ok(ValidTransaction::default()) + } +} + +#[cfg(feature = "std")] +impl CheckWeight { + pub fn from() -> Self { + Self(PhantomData) + } +} + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for CheckWeight { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + write!(f, "CheckWeight") + } +} + /// Nonce check and increment to give replay protection for transactions. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckNonce(#[codec(compact)] T::Index); @@ -775,7 +832,9 @@ impl rstd::fmt::Debug for CheckNonce { impl SignedExtension for CheckNonce { type AccountId = T::AccountId; type AdditionalSigned = (); - fn additional_signed(&self) -> Result<(), &'static str> { Ok(()) } + + fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) } + fn pre_dispatch( self, who: &Self::AccountId, @@ -819,7 +878,6 @@ impl SignedExtension for CheckNonce { } } - /// Nonce check and increment to give replay protection for transactions. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckEra((Era, rstd::marker::PhantomData)); @@ -850,7 +908,6 @@ impl SignedExtension for CheckEra { } } - pub struct ChainContext(::rstd::marker::PhantomData); impl Default for ChainContext { fn default() -> Self { @@ -898,6 +955,7 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 10; + pub const MaximumBlockWeight: Weight = 1024; } impl Trait for Test { @@ -911,6 +969,7 @@ mod tests { type Header = Header; type Event = u16; type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl From for u16 { @@ -1061,4 +1120,52 @@ mod tests { } }) } + + #[test] + fn signed_ext_check_nonce_works() { + with_externalities(&mut new_test_ext(), || { + >::insert(1, 1); + // stale + assert!(CheckNonce::(0).validate(&1, 0).is_err()); + assert!(CheckNonce::(0).pre_dispatch(&1, 0).is_err()); + // correct + assert!(CheckNonce::(1).validate(&1, 0).is_ok()); + assert!(CheckNonce::(1).pre_dispatch(&1, 0).is_ok()); + // future + assert!(CheckNonce::(5).validate(&1, 0).is_ok()); + assert!(CheckNonce::(5).pre_dispatch(&1, 0).is_err()); + }) + } + + #[test] + fn signed_ext_check_weight_works() { + with_externalities(&mut new_test_ext(), || { + // small + AllExtrinsicsWeight::put(512); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, 100).is_ok()); + // almost + AllExtrinsicsWeight::put(512); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, 512).is_ok()); + // big + AllExtrinsicsWeight::put(512); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, 513).is_err()); + + }) + } + + #[test] + fn signed_ext_check_era_should_work() { + with_externalities(&mut new_test_ext(), || { + // future + assert_eq!( + CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), + "transaction birth block ancient" + ); + + // correct + System::set_block_number(13); + >::insert(12, H256::repeat_byte(1)); + assert!(CheckEra::::from(Era::mortal(4, 12)).additional_signed().is_ok()); + }) + } } diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 7bffac0db9007..a1c0b2f69fcaa 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -343,6 +343,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -355,6 +356,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } impl Trait for Test { type Moment = u64; diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 7c4d7b10f21cf..aa49190d5abb2 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -370,6 +370,7 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; } impl system::Trait for Test { type Origin = Origin; @@ -382,6 +383,7 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/subkey/src/main.rs b/subkey/src/main.rs index dfd923e993149..6a74391b00815 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -87,7 +87,12 @@ fn execute(matches: clap::ArgMatches) where <::Pair as Pair>::Public: Sized + AsRef<[u8]> + Ss58Codec + AsRef<<::Pair as Pair>::Public>, { let extra = |i: Index, f: Balance| { - (system::CheckNonce::::from(i), balances::TakeFees::::from(f)) + ( + system::CheckEra::::from(Era::Immortal), + system::CheckNonce::::from(i), + system::CheckWeight::::from(), + balances::TakeFees::::from(f), + ) }; let password = matches.value_of("password"); match matches.subcommand() { @@ -155,9 +160,7 @@ fn execute(matches: clap::ArgMatches) where println!("Using a genesis hash of {}", HexDisplay::from(&genesis_hash.as_ref())); - let era = Era::immortal(); - - let raw_payload = (function, era, genesis_hash, extra(index, 0)); + let raw_payload = (function, extra(index, 0), genesis_hash); let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 { signer.sign(&blake2_256(payload)[..]) } else { @@ -168,7 +171,6 @@ fn execute(matches: clap::ArgMatches) where raw_payload.0, signer.public().into(), signature.into(), - era, extra(index, 0), ); println!("0x{}", hex::encode(&extrinsic.encode())); @@ -209,7 +211,6 @@ fn execute(matches: clap::ArgMatches) where raw_payload.0, signer.public().into(), signature.into(), - era, extra(index, 0), );