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
This commit is contained in:
André Silva
2019-07-09 16:07:38 +01:00
committed by Gavin Wood
parent 459eb94c38
commit ed630e5eda
21 changed files with 149 additions and 15 deletions
@@ -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 {
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl Trait for Test {
type Event = ();
+7 -2
View File
@@ -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<BlockNumber, BlakeTwo256>;
type Event = Event;
type BlockHashCount = BlockHashCount;
}
impl aura::Trait for Runtime {
+5 -1
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl Trait for Test {
type Event = ();
+6 -1
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl timestamp::Trait for Test {
+5
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl Trait for Test {
+1
View File
@@ -746,6 +746,7 @@ impl<T: Subtrait<I>, I: Instance> system::Trait for ElevatedTrait<T, I> {
type Lookup = T::Lookup;
type Header = T::Header;
type Event = ();
type BlockHashCount = T::BlockHashCount;
}
impl<T: Subtrait<I>, I: Instance> Trait<I> for ElevatedTrait<T, I> {
type Balance = T::Balance;
+5 -1
View File
@@ -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<u64> 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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl Trait for Runtime {
type Balance = u64;
+4
View File
@@ -94,6 +94,9 @@ impl Get<u64> 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<Self::AccountId>;
type Header = Header;
type Event = MetaEvent;
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const BalancesTransactionBaseFee: u64 = 0;
+4
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const ExistentialDeposit: u64 = 0;
+4
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const ExistentialDeposit: u64 = 0;
+4
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const ExistentialDeposit: u64 = 0;
+4
View File
@@ -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<u64>;
type Header = Header;
type Event = MetaEvent;
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const ExistentialDeposit: u64 = 0;
@@ -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<u64>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const WindowSize: u64 = 11;
+5 -1
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = TestEvent;
type BlockHashCount = BlockHashCount;
}
mod grandpa {
+5 -1
View File
@@ -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<u64, u64> 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;
+5 -1
View File
@@ -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<u64>) {
#[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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl timestamp::Trait for Test {
type Moment = u64;
+4
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const TransferFee: u64 = 0;
+57 -5
View File
@@ -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<Event>;
/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
type BlockHashCount: Get<Self::BlockNumber>;
}
pub type DigestOf<T> = generic::Digest<<T as Trait>::Hash>;
@@ -570,6 +571,18 @@ impl<T: Trait> Module<T> {
let parent_hash = <ParentHash<T>>::take();
let mut digest = <Digest<T>>::take();
let extrinsics_root = <ExtrinsicsRoot<T>>::take();
// move block hash pruning window by one block
let block_hash_count = <T::BlockHashCount>::get();
if number > block_hash_count {
let to_remove = number - block_hash_count - One::one();
// keep genesis hash
if to_remove != Zero::zero() {
<BlockHash<T>>::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<Self::AccountId>;
type Header = Header;
type Event = u16;
type BlockHashCount = BlockHashCount;
}
impl From<Event> 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(),
);
}
})
}
}
+5 -1
View File
@@ -330,7 +330,7 @@ impl<T: Trait> ProvideInherent for Module<T> {
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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
impl Trait for Test {
type Moment = u64;
+4
View File
@@ -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<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
}
parameter_types! {
pub const ExistentialDeposit: u64 = 0;