From ed630e5edaf0aecc7fcbeddf245e722c91f4df96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 9 Jul 2019 16:07:38 +0100 Subject: [PATCH] srml: system: prune block hash mapping (#3062) * srml: system: prune block number to hash mapping * srml: system: add test for block hash mapping pruning * node: bump runtime version * srml: system: wrap long line * srml: system: use parameter type for block hash count * srml: system: prune block hash mapping before storage root calculation * srml: system: keep the genesis hash in block number map --- substrate/node-template/runtime/src/lib.rs | 6 ++ .../node-template/runtime/src/template.rs | 6 +- substrate/node/runtime/src/lib.rs | 9 ++- substrate/srml/assets/src/lib.rs | 6 +- substrate/srml/aura/src/mock.rs | 7 ++- substrate/srml/authorship/src/lib.rs | 5 ++ substrate/srml/balances/src/lib.rs | 1 + substrate/srml/balances/src/mock.rs | 6 +- substrate/srml/contracts/src/tests.rs | 4 ++ substrate/srml/council/src/lib.rs | 4 ++ substrate/srml/democracy/src/lib.rs | 4 ++ substrate/srml/example/src/lib.rs | 4 ++ substrate/srml/executive/src/lib.rs | 4 ++ substrate/srml/finality-tracker/src/lib.rs | 4 ++ substrate/srml/grandpa/src/mock.rs | 6 +- substrate/srml/indices/src/mock.rs | 6 +- substrate/srml/session/src/mock.rs | 6 +- substrate/srml/staking/src/mock.rs | 4 ++ substrate/srml/system/src/lib.rs | 62 +++++++++++++++++-- substrate/srml/timestamp/src/lib.rs | 6 +- substrate/srml/treasury/src/lib.rs | 4 ++ 21 files changed, 149 insertions(+), 15 deletions(-) diff --git a/substrate/node-template/runtime/src/lib.rs b/substrate/node-template/runtime/src/lib.rs index 7f593893fc..5cf774a5e9 100644 --- a/substrate/node-template/runtime/src/lib.rs +++ b/substrate/node-template/runtime/src/lib.rs @@ -111,6 +111,10 @@ pub fn native_version() -> NativeVersion { } } +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; +} + impl system::Trait for Runtime { /// The identifier used to distinguish between accounts. type AccountId = AccountId; @@ -130,6 +134,8 @@ impl system::Trait for Runtime { type Event = Event; /// The ubiquitous origin type. type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; } impl aura::Trait for Runtime { diff --git a/substrate/node-template/runtime/src/template.rs b/substrate/node-template/runtime/src/template.rs index 3d53c08300..05257d2a53 100644 --- a/substrate/node-template/runtime/src/template.rs +++ b/substrate/node-template/runtime/src/template.rs @@ -71,7 +71,7 @@ mod tests { use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; - use support::{impl_outer_origin, assert_ok}; + use support::{impl_outer_origin, assert_ok, parameter_types}; use runtime_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { @@ -83,6 +83,9 @@ mod tests { // configuration traits of modules we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -93,6 +96,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl Trait for Test { type Event = (); diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 3ea064cac0..4382227de4 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -71,8 +71,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: 106, - impl_version: 106, + spec_version: 107, + impl_version: 107, apis: RUNTIME_API_VERSIONS, }; @@ -111,6 +111,10 @@ pub const MINUTES: Moment = 60 / SECS_PER_BLOCK; pub const HOURS: Moment = MINUTES * 60; pub const DAYS: Moment = HOURS * 24; +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; +} + impl system::Trait for Runtime { type Origin = Origin; type Index = Index; @@ -121,6 +125,7 @@ impl system::Trait for Runtime { type Lookup = Indices; type Header = generic::Header; type Event = Event; + type BlockHashCount = BlockHashCount; } impl aura::Trait for Runtime { diff --git a/substrate/srml/assets/src/lib.rs b/substrate/srml/assets/src/lib.rs index b0306f4446..19159bf60f 100644 --- a/substrate/srml/assets/src/lib.rs +++ b/substrate/srml/assets/src/lib.rs @@ -240,7 +240,7 @@ mod tests { use super::*; use runtime_io::with_externalities; - use srml_support::{impl_outer_origin, assert_ok, assert_noop}; + use srml_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; use substrate_primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. @@ -255,6 +255,9 @@ mod tests { // configuration traits of modules we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -265,6 +268,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl Trait for Test { type Event = (); diff --git a/substrate/srml/aura/src/mock.rs b/substrate/srml/aura/src/mock.rs index 181a09febb..7482388cd1 100644 --- a/substrate/srml/aura/src/mock.rs +++ b/substrate/srml/aura/src/mock.rs @@ -23,7 +23,7 @@ use primitives::{ traits::IdentityLookup, testing::{UINT_DUMMY_KEY, Header, UintAuthorityId}, }; -use srml_support::impl_outer_origin; +use srml_support::{impl_outer_origin, parameter_types}; use runtime_io; use substrate_primitives::{H256, Blake2Hasher}; use crate::{Trait, Module, GenesisConfig}; @@ -36,6 +36,10 @@ impl_outer_origin!{ #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -46,6 +50,7 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl timestamp::Trait for Test { diff --git a/substrate/srml/authorship/src/lib.rs b/substrate/srml/authorship/src/lib.rs index 127ff88dbb..08a0279284 100644 --- a/substrate/srml/authorship/src/lib.rs +++ b/substrate/srml/authorship/src/lib.rs @@ -335,6 +335,10 @@ mod tests { #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } + impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -345,6 +349,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl Trait for Test { diff --git a/substrate/srml/balances/src/lib.rs b/substrate/srml/balances/src/lib.rs index 40d4552f90..84e023ee5b 100644 --- a/substrate/srml/balances/src/lib.rs +++ b/substrate/srml/balances/src/lib.rs @@ -746,6 +746,7 @@ impl, I: Instance> system::Trait for ElevatedTrait { type Lookup = T::Lookup; type Header = T::Header; type Event = (); + type BlockHashCount = T::BlockHashCount; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; diff --git a/substrate/srml/balances/src/mock.rs b/substrate/srml/balances/src/mock.rs index 1c749d9e35..26f4439f46 100644 --- a/substrate/srml/balances/src/mock.rs +++ b/substrate/srml/balances/src/mock.rs @@ -21,7 +21,7 @@ use primitives::{traits::{IdentityLookup}, testing::Header}; use substrate_primitives::{H256, Blake2Hasher}; use runtime_io; -use srml_support::{impl_outer_origin, traits::Get}; +use srml_support::{impl_outer_origin, parameter_types, traits::Get}; use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait}; @@ -65,6 +65,9 @@ impl Get for TransactionByteFee { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} impl system::Trait for Runtime { type Origin = Origin; type Index = u64; @@ -75,6 +78,7 @@ impl system::Trait for Runtime { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl Trait for Runtime { type Balance = u64; diff --git a/substrate/srml/contracts/src/tests.rs b/substrate/srml/contracts/src/tests.rs index 3308a8cac6..0d4688f9a7 100644 --- a/substrate/srml/contracts/src/tests.rs +++ b/substrate/srml/contracts/src/tests.rs @@ -94,6 +94,9 @@ impl Get for BlockGasLimit { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -104,6 +107,7 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = MetaEvent; + type BlockHashCount = BlockHashCount; } parameter_types! { pub const BalancesTransactionBaseFee: u64 = 0; diff --git a/substrate/srml/council/src/lib.rs b/substrate/srml/council/src/lib.rs index 496b940cf9..bc66862a2a 100644 --- a/substrate/srml/council/src/lib.rs +++ b/substrate/srml/council/src/lib.rs @@ -96,6 +96,9 @@ mod tests { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -106,6 +109,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = Event; + type BlockHashCount = BlockHashCount; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs index c159b4fdd8..d0c71a63d6 100644 --- a/substrate/srml/democracy/src/lib.rs +++ b/substrate/srml/democracy/src/lib.rs @@ -971,6 +971,9 @@ mod tests { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -981,6 +984,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/substrate/srml/example/src/lib.rs b/substrate/srml/example/src/lib.rs index 87f04ecfc5..20ee1c6ba1 100644 --- a/substrate/srml/example/src/lib.rs +++ b/substrate/srml/example/src/lib.rs @@ -523,6 +523,9 @@ mod tests { // configuration traits of modules we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -533,6 +536,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/substrate/srml/executive/src/lib.rs b/substrate/srml/executive/src/lib.rs index 2e2453cd03..2b5ebdd88c 100644 --- a/substrate/srml/executive/src/lib.rs +++ b/substrate/srml/executive/src/lib.rs @@ -416,6 +416,9 @@ mod tests { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Eq, PartialEq)] pub struct Runtime; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Runtime { type Origin = Origin; type Index = u64; @@ -426,6 +429,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = MetaEvent; + type BlockHashCount = BlockHashCount; } parameter_types! { pub const ExistentialDeposit: u64 = 0; diff --git a/substrate/srml/finality-tracker/src/lib.rs b/substrate/srml/finality-tracker/src/lib.rs index 983cef856b..98a8a175af 100644 --- a/substrate/srml/finality-tracker/src/lib.rs +++ b/substrate/srml/finality-tracker/src/lib.rs @@ -297,6 +297,9 @@ mod tests { } } + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -307,6 +310,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } parameter_types! { pub const WindowSize: u64 = 11; diff --git a/substrate/srml/grandpa/src/mock.rs b/substrate/srml/grandpa/src/mock.rs index 08847b0929..733b2deaf1 100644 --- a/substrate/srml/grandpa/src/mock.rs +++ b/substrate/srml/grandpa/src/mock.rs @@ -20,7 +20,7 @@ use primitives::{DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; use runtime_io; -use srml_support::{impl_outer_origin, impl_outer_event}; +use srml_support::{impl_outer_origin, impl_outer_event, parameter_types}; use substrate_primitives::{H256, Blake2Hasher}; use parity_codec::{Encode, Decode}; use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog}; @@ -41,6 +41,9 @@ impl Trait for Test { type Event = TestEvent; } +parameter_types! { + pub const BlockHashCount: u64 = 250; +} impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -51,6 +54,7 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = TestEvent; + type BlockHashCount = BlockHashCount; } mod grandpa { diff --git a/substrate/srml/indices/src/mock.rs b/substrate/srml/indices/src/mock.rs index 93726502d2..53e8f314c9 100644 --- a/substrate/srml/indices/src/mock.rs +++ b/substrate/srml/indices/src/mock.rs @@ -22,7 +22,7 @@ use std::collections::HashSet; use ref_thread_local::{ref_thread_local, RefThreadLocal}; use primitives::testing::Header; use substrate_primitives::{H256, Blake2Hasher}; -use srml_support::impl_outer_origin; +use srml_support::{impl_outer_origin, parameter_types}; use {runtime_io, system}; use crate::{GenesisConfig, Module, Trait, IsDeadAccount, OnNewAccount, ResolveHint}; @@ -64,6 +64,9 @@ impl ResolveHint for TestResolveHint { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} impl system::Trait for Runtime { type Origin = Origin; type Index = u64; @@ -74,6 +77,7 @@ impl system::Trait for Runtime { type Lookup = Indices; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl Trait for Runtime { type AccountIndex = u64; diff --git a/substrate/srml/session/src/mock.rs b/substrate/srml/session/src/mock.rs index 171098fc97..68fa95524a 100644 --- a/substrate/srml/session/src/mock.rs +++ b/substrate/srml/session/src/mock.rs @@ -18,7 +18,7 @@ use super::*; use std::cell::RefCell; -use srml_support::impl_outer_origin; +use srml_support::{impl_outer_origin, parameter_types}; use substrate_primitives::H256; use primitives::{ traits::{BlakeTwo256, IdentityLookup, ConvertInto}, @@ -107,6 +107,9 @@ pub fn set_next_validators(next: Vec) { #[derive(Clone, Eq, PartialEq)] pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -117,6 +120,7 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl timestamp::Trait for Test { type Moment = u64; diff --git a/substrate/srml/staking/src/mock.rs b/substrate/srml/staking/src/mock.rs index 02a05168c6..c86d647646 100644 --- a/substrate/srml/staking/src/mock.rs +++ b/substrate/srml/staking/src/mock.rs @@ -86,6 +86,9 @@ impl_outer_origin!{ // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -96,6 +99,7 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } parameter_types! { pub const TransferFee: u64 = 0; diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs index f51ee1dbfc..a55cb9be86 100644 --- a/substrate/srml/system/src/lib.rs +++ b/substrate/srml/system/src/lib.rs @@ -79,17 +79,15 @@ use rstd::map; use primitives::{generic, traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, CurrentHeight, BlockNumberToHash, MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, Lookup, + Zero, }}; -#[cfg(any(feature = "std", test))] -use primitives::traits::Zero; use substrate_primitives::storage::well_known_keys; use srml_support::{ storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue, - StorageMap, Parameter, for_each_tuple, traits::Contains, + StorageMap, Parameter, for_each_tuple, traits::{Contains, Get}, }; use safe_mix::TripletMix; use parity_codec::{Encode, Decode}; -use crate::{self as system}; #[cfg(any(feature = "std", test))] use runtime_io::{twox_128, TestExternalities, Blake2Hasher}; @@ -184,6 +182,9 @@ pub trait Trait: 'static + Eq + Clone { /// The aggregated event type of the runtime. type Event: Parameter + Member + From; + + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount: Get; } pub type DigestOf = generic::Digest<::Hash>; @@ -570,6 +571,18 @@ impl Module { let parent_hash = >::take(); let mut digest = >::take(); let extrinsics_root = >::take(); + + // move block hash pruning window by one block + let block_hash_count = ::get(); + if number > block_hash_count { + let to_remove = number - block_hash_count - One::one(); + + // keep genesis hash + if to_remove != Zero::zero() { + >::remove(to_remove); + } + } + let storage_root = T::Hashing::storage_root(); let storage_changes_root = T::Hashing::storage_changes_root(parent_hash); @@ -771,7 +784,7 @@ mod tests { use runtime_io::with_externalities; use substrate_primitives::H256; use primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use srml_support::impl_outer_origin; + use srml_support::{impl_outer_origin, parameter_types}; impl_outer_origin!{ pub enum Origin for Test where system = super {} @@ -779,6 +792,11 @@ mod tests { #[derive(Clone, Eq, PartialEq)] pub struct Test; + + parameter_types! { + pub const BlockHashCount: u64 = 10; + } + impl Trait for Test { type Origin = Origin; type Index = u64; @@ -789,6 +807,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = u16; + type BlockHashCount = BlockHashCount; } impl From for u16 { @@ -906,4 +925,37 @@ mod tests { ); }); } + + #[test] + fn prunes_block_hash_mappings() { + with_externalities(&mut new_test_ext(), || { + // simulate import of 15 blocks + for n in 1..=15 { + System::initialize( + &n, + &[n as u8 - 1; 32].into(), + &[0u8; 32].into(), + &Default::default(), + ); + + System::finalize(); + } + + // first 5 block hashes are pruned + for n in 0..5 { + assert_eq!( + System::block_hash(n), + H256::zero(), + ); + } + + // the remaining 10 are kept + for n in 5..15 { + assert_eq!( + System::block_hash(n), + [n as u8; 32].into(), + ); + } + }) + } } diff --git a/substrate/srml/timestamp/src/lib.rs b/substrate/srml/timestamp/src/lib.rs index 7757eade15..c915f6b95d 100644 --- a/substrate/srml/timestamp/src/lib.rs +++ b/substrate/srml/timestamp/src/lib.rs @@ -330,7 +330,7 @@ impl ProvideInherent for Module { mod tests { use super::*; - use srml_support::{impl_outer_origin, assert_ok}; + use srml_support::{impl_outer_origin, assert_ok, parameter_types}; use runtime_io::{with_externalities, TestExternalities}; use substrate_primitives::H256; use runtime_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -341,6 +341,9 @@ mod tests { #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -351,6 +354,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } impl Trait for Test { type Moment = u64; diff --git a/substrate/srml/treasury/src/lib.rs b/substrate/srml/treasury/src/lib.rs index 182882e58f..7c4d7b10f2 100644 --- a/substrate/srml/treasury/src/lib.rs +++ b/substrate/srml/treasury/src/lib.rs @@ -368,6 +368,9 @@ mod tests { #[derive(Clone, Eq, PartialEq)] pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + } impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -378,6 +381,7 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; } parameter_types! { pub const ExistentialDeposit: u64 = 0;