diff --git a/substrate/core/sr-io/src/lib.rs b/substrate/core/sr-io/src/lib.rs index 6721cc7ecd..f340f0a99b 100644 --- a/substrate/core/sr-io/src/lib.rs +++ b/substrate/core/sr-io/src/lib.rs @@ -394,7 +394,10 @@ mod imp { } #[cfg(feature = "std")] -pub use self::imp::{StorageOverlay, ChildrenStorageOverlay, with_storage, with_externalities}; +pub use self::imp::{ + StorageOverlay, ChildrenStorageOverlay, with_storage, with_storage_and_children, + with_externalities +}; #[cfg(not(feature = "std"))] pub use self::imp::ext::*; diff --git a/substrate/core/sr-io/with_std.rs b/substrate/core/sr-io/with_std.rs index 25be27046a..9475aa0715 100644 --- a/substrate/core/sr-io/with_std.rs +++ b/substrate/core/sr-io/with_std.rs @@ -435,9 +435,32 @@ pub type ChildrenStorageOverlay = HashMap, StorageOverlay>; pub fn with_storage R>(storage: &mut StorageOverlay, f: F) -> R { let mut alt_storage = Default::default(); rstd::mem::swap(&mut alt_storage, storage); - let mut ext: BasicExternalities = alt_storage.into(); + let mut ext = BasicExternalities::new(alt_storage); let r = ext::using(&mut ext, f); - *storage = ext.into(); + *storage = ext.into_storages().0; + r +} + +/// Execute the given closure with global functions available whose functionality routes into +/// externalities that draw from and populate `storage` and `children_storage`. +/// Forwards the value that the closure returns. +pub fn with_storage_and_children R>( + storage: &mut StorageOverlay, + children_storage: &mut ChildrenStorageOverlay, + f: F +) -> R { + let mut alt_storage = Default::default(); + let mut alt_children_storage = Default::default(); + rstd::mem::swap(&mut alt_storage, storage); + rstd::mem::swap(&mut alt_children_storage, children_storage); + + let mut ext = BasicExternalities::new_with_children(alt_storage, alt_children_storage); + let r = ext::using(&mut ext, f); + + let storage_tuple = ext.into_storages(); + *storage = storage_tuple.0; + *children_storage = storage_tuple.1; + r } diff --git a/substrate/core/state-machine/src/basic.rs b/substrate/core/state-machine/src/basic.rs index e9939711f1..e922db260c 100644 --- a/substrate/core/state-machine/src/basic.rs +++ b/substrate/core/state-machine/src/basic.rs @@ -18,67 +18,64 @@ use std::collections::HashMap; use std::iter::FromIterator; +use crate::backend::{Backend, InMemory}; use hash_db::Hasher; use trie::trie_root; use primitives::offchain; -use primitives::storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES}; +use primitives::storage::well_known_keys::{HEAP_PAGES, is_child_storage_key}; use parity_codec::Encode; -use super::{ChildStorageKey, Externalities, OverlayedChanges}; +use super::{ChildStorageKey, Externalities}; use log::warn; /// Simple HashMap-based Externalities impl. +#[derive(Debug)] pub struct BasicExternalities { - inner: HashMap, Vec>, - changes: OverlayedChanges, - code: Option>, + top: HashMap, Vec>, + children: HashMap, HashMap, Vec>>, } impl BasicExternalities { /// Create a new instance of `BasicExternalities` - pub fn new(inner: HashMap, Vec>) -> Self { - Self::new_with_code(&[], inner) + pub fn new(top: HashMap, Vec>) -> Self { + Self::new_with_children(top, Default::default()) } - /// Create a new instance of `BasicExternalities` - pub fn new_with_code(code: &[u8], mut inner: HashMap, Vec>) -> Self { - let mut overlay = OverlayedChanges::default(); - super::set_changes_trie_config( - &mut overlay, - inner.get(&CHANGES_TRIE_CONFIG.to_vec()).cloned(), - false, - ).expect("changes trie configuration is correct in test env; qed"); - - inner.insert(HEAP_PAGES.to_vec(), 8u64.encode()); - + /// Create a new instance of `BasicExternalities` with children + pub fn new_with_children( + mut top: HashMap, Vec>, + children: HashMap, HashMap, Vec>>, + ) -> Self { + top.insert(HEAP_PAGES.to_vec(), 8u64.encode()); BasicExternalities { - inner, - changes: overlay, - code: Some(code.to_vec()), + top, + children, } } /// Insert key/value pub fn insert(&mut self, k: Vec, v: Vec) -> Option> { - self.inner.insert(k, v) + self.top.insert(k, v) } -} -impl ::std::fmt::Debug for BasicExternalities { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(f, "{:?}", self.inner) + /// Consume self and returns inner storages + pub fn into_storages(self) -> ( + HashMap, Vec>, + HashMap, HashMap, Vec>>, + ) { + (self.top, self.children) } } impl PartialEq for BasicExternalities { fn eq(&self, other: &BasicExternalities) -> bool { - self.inner.eq(&other.inner) + self.top.eq(&other.top) && self.children.eq(&other.children) } } impl FromIterator<(Vec, Vec)> for BasicExternalities { fn from_iter, Vec)>>(iter: I) -> Self { - let mut t = Self::new(Default::default()); - t.inner.extend(iter); + let mut t = Self::default(); + t.top.extend(iter); t } } @@ -87,69 +84,84 @@ impl Default for BasicExternalities { fn default() -> Self { Self::new(Default::default()) } } -impl From for HashMap, Vec> { - fn from(tex: BasicExternalities) -> Self { - tex.inner.into() - } -} - -impl From< HashMap, Vec> > for BasicExternalities { +impl From, Vec>> for BasicExternalities { fn from(hashmap: HashMap, Vec>) -> Self { BasicExternalities { - inner: hashmap, - changes: Default::default(), - code: None, + top: hashmap, + children: Default::default(), } } } impl Externalities for BasicExternalities where H::Out: Ord { fn storage(&self, key: &[u8]) -> Option> { - match key { - CODE => self.code.clone(), - _ => self.inner.get(key).cloned(), - } + self.top.get(key).cloned() } fn original_storage(&self, key: &[u8]) -> Option> { Externalities::::storage(self, key) } - fn child_storage(&self, _storage_key: ChildStorageKey, _key: &[u8]) -> Option> { - None + fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + self.children.get(storage_key.as_ref()).and_then(|child| child.get(key)).cloned() } fn place_storage(&mut self, key: Vec, maybe_value: Option>) { - self.changes.set_storage(key.clone(), maybe_value.clone()); - match key.as_ref() { - CODE => self.code = maybe_value, - _ => { - match maybe_value { - Some(value) => { self.inner.insert(key, value); } - None => { self.inner.remove(&key); } - } - } + if is_child_storage_key(&key) { + warn!(target: "trie", "Refuse to set child storage key via main storage"); + return; + } + + match maybe_value { + Some(value) => { self.top.insert(key, value); } + None => { self.top.remove(&key); } } } - fn place_child_storage(&mut self, _storage_key: ChildStorageKey, _key: Vec, _value: Option>) { + fn place_child_storage( + &mut self, + storage_key: ChildStorageKey, + key: Vec, + value: Option> + ) { + let child_map = self.children.entry(storage_key.into_owned()).or_default(); + if let Some(value) = value { + child_map.insert(key, value); + } else { + child_map.remove(&key); + } } - fn kill_child_storage(&mut self, _storage_key: ChildStorageKey) { } + fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + self.children.remove(storage_key.as_ref()); + } fn clear_prefix(&mut self, prefix: &[u8]) { - self.changes.clear_prefix(prefix); - self.inner.retain(|key, _| !key.starts_with(prefix)); + if is_child_storage_key(prefix) { + warn!( + target: "trie", + "Refuse to clear prefix that is part of child storage key via main storage" + ); + return; + } + + self.top.retain(|key, _| !key.starts_with(prefix)); } fn chain_id(&self) -> u64 { 42 } fn storage_root(&mut self) -> H::Out { - trie_root::(self.inner.clone()) + trie_root::(self.top.clone()) } - fn child_storage_root(&mut self, _storage_key: ChildStorageKey) -> Vec { - vec![42] + fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { + if let Some(child) = self.children.get(storage_key.as_ref()) { + let delta = child.clone().into_iter().map(|(k, v)| (k, Some(v))); + + InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 + } else { + vec![] + } } fn storage_changes_root(&mut self, _parent: H::Out) -> Result, ()> { @@ -165,7 +177,8 @@ impl Externalities for BasicExternalities where H::Out: Ord { #[cfg(test)] mod tests { use super::*; - use primitives::{Blake2Hasher, H256}; + use primitives::{Blake2Hasher, H256, map}; + use primitives::storage::well_known_keys::CODE; use hex_literal::hex; #[test] @@ -189,4 +202,33 @@ mod tests { assert_eq!(&ext.storage(CODE).unwrap(), &code); } + + #[test] + fn children_works() { + let child_storage = b":child_storage:default:test".to_vec(); + + let mut ext = BasicExternalities::new_with_children( + Default::default(), + map![ + child_storage.clone() => map![ + b"doe".to_vec() => b"reindeer".to_vec() + ] + ] + ); + + let ext = &mut ext as &mut dyn Externalities; + + let child = || ChildStorageKey::from_vec(child_storage.clone()).unwrap(); + + assert_eq!(ext.child_storage(child(), b"doe"), Some(b"reindeer".to_vec())); + + ext.set_child_storage(child(), b"dog".to_vec(), b"puppy".to_vec()); + assert_eq!(ext.child_storage(child(), b"dog"), Some(b"puppy".to_vec())); + + ext.clear_child_storage(child(), b"dog"); + assert_eq!(ext.child_storage(child(), b"dog"), None); + + ext.kill_child_storage(child()); + assert_eq!(ext.child_storage(child(), b"doe"), None); + } } diff --git a/substrate/core/state-machine/src/testing.rs b/substrate/core/state-machine/src/testing.rs index 759ffb6b96..4a0e221809 100644 --- a/substrate/core/state-machine/src/testing.rs +++ b/substrate/core/state-machine/src/testing.rs @@ -16,7 +16,7 @@ //! Test implementation for Externalities. -use std::collections::{HashMap, BTreeMap}; +use std::collections::{HashMap}; use std::iter::FromIterator; use hash_db::Hasher; use crate::backend::{InMemory, Backend}; @@ -32,6 +32,8 @@ use super::{ChildStorageKey, Externalities, OverlayedChanges}; const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime"; +type StorageTuple = (HashMap, Vec>, HashMap, HashMap, Vec>>); + /// Simple HashMap-based Externalities impl. pub struct TestExternalities { overlay: OverlayedChanges, @@ -41,28 +43,46 @@ pub struct TestExternalities { } impl TestExternalities { - /// Create a new instance of `TestExternalities`. - pub fn new(inner: HashMap, Vec>) -> Self { - Self::new_with_code(&[], inner) + /// Create a new instance of `TestExternalities` with storage. + pub fn new(storage: HashMap, Vec>) -> Self { + Self::new_with_children((storage, Default::default())) } - /// Create a new instance of `TestExternalities` - pub fn new_with_code(code: &[u8], mut inner: HashMap, Vec>) -> Self { + /// Create a new instance of `TestExternalities` with storage and children. + pub fn new_with_children(storage: StorageTuple) -> Self { + Self::new_with_code_with_children(&[], storage) + } + + /// Create a new instance of `TestExternalities` with code and storage. + pub fn new_with_code(code: &[u8], storage: HashMap, Vec>) -> Self { + Self::new_with_code_with_children(code, (storage, Default::default())) + } + + /// Create a new instance of `TestExternalities` with code, storage and children. + pub fn new_with_code_with_children(code: &[u8], mut storage: StorageTuple) -> Self { let mut overlay = OverlayedChanges::default(); + assert!(storage.0.keys().all(|key| !is_child_storage_key(key))); + assert!(storage.1.keys().all(|key| is_child_storage_key(key))); + super::set_changes_trie_config( &mut overlay, - inner.get(&CHANGES_TRIE_CONFIG.to_vec()).cloned(), + storage.0.get(&CHANGES_TRIE_CONFIG.to_vec()).cloned(), false, ).expect("changes trie configuration is correct in test env; qed"); - inner.insert(HEAP_PAGES.to_vec(), 8u64.encode()); - inner.insert(CODE.to_vec(), code.to_vec()); + storage.0.insert(HEAP_PAGES.to_vec(), 8u64.encode()); + storage.0.insert(CODE.to_vec(), code.to_vec()); + + let backend: HashMap<_, _> = storage.1.into_iter() + .map(|(keyspace, map)| (Some(keyspace), map)) + .chain(Some((None, storage.0)).into_iter()) + .collect(); TestExternalities { overlay, changes_trie_storage: ChangesTrieInMemoryStorage::new(), - backend: inner.into(), + backend: backend.into(), offchain: None, } } @@ -72,17 +92,6 @@ impl TestExternalities { self.backend = self.backend.update(vec![(None, k, Some(v))]); } - /// Iter to all pairs in key order - pub fn iter_pairs_in_order(&self) -> impl Iterator, Vec)> { - self.backend.pairs().iter() - .map(|&(ref k, ref v)| (k.to_vec(), Some(v.to_vec()))) - .chain(self.overlay.committed.top.clone().into_iter().map(|(k, v)| (k, v.value))) - .chain(self.overlay.prospective.top.clone().into_iter().map(|(k, v)| (k, v.value))) - .collect::>() - .into_iter() - .filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val))) - } - /// Set offchain externaltiies. pub fn set_offchain_externalities(&mut self, offchain: impl offchain::Externalities + 'static) { self.offchain = Some(Box::new(offchain)); @@ -92,9 +101,26 @@ impl TestExternalities { pub fn changes_trie_storage(&mut self) -> &mut ChangesTrieInMemoryStorage { &mut self.changes_trie_storage } + + /// Return a new backend with all pending value. + pub fn commit_all(&self) -> InMemory { + let top = self.overlay.committed.top.clone().into_iter() + .chain(self.overlay.prospective.top.clone().into_iter()) + .map(|(k, v)| (None, k, v.value)); + + let children = self.overlay.committed.children.clone().into_iter() + .chain(self.overlay.prospective.children.clone().into_iter()) + .flat_map(|(keyspace, map)| { + map.1.into_iter() + .map(|(k, v)| (Some(keyspace.clone()), k, v)) + .collect::>() + }); + + self.backend.update(top.chain(children).collect()) + } } -impl ::std::fmt::Debug for TestExternalities { +impl std::fmt::Debug for TestExternalities { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "overlay: {:?}\nbackend: {:?}", self.overlay, self.backend.pairs()) } @@ -104,15 +130,13 @@ impl PartialEq for TestExternalities /// This doesn't test if they are in the same state, only if they contains the /// same data at this state fn eq(&self, other: &TestExternalities) -> bool { - self.iter_pairs_in_order().eq(other.iter_pairs_in_order()) + self.commit_all().eq(&other.commit_all()) } } impl FromIterator<(Vec, Vec)> for TestExternalities { fn from_iter, Vec)>>(iter: I) -> Self { - let mut t = Self::new(Default::default()); - t.backend = t.backend.update(iter.into_iter().map(|(k, v)| (None, k, Some(v))).collect()); - t + Self::new(iter.into_iter().collect()) } } @@ -120,15 +144,15 @@ impl Default for TestExternalities { fn default() -> Self { Self::new(Default::default()) } } -impl From> for HashMap, Vec> { - fn from(tex: TestExternalities) -> Self { - tex.iter_pairs_in_order().collect() +impl From, Vec>> for TestExternalities { + fn from(hashmap: HashMap, Vec>) -> Self { + Self::from_iter(hashmap) } } -impl From< HashMap, Vec> > for TestExternalities { - fn from(hashmap: HashMap, Vec>) -> Self { - Self::from_iter(hashmap) +impl From for TestExternalities { + fn from(storage: StorageTuple) -> Self { + Self::new_with_children(storage) } } diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs index 9cf85c2357..1d6f1d1794 100644 --- a/substrate/node/executor/src/lib.rs +++ b/substrate/node/executor/src/lib.rs @@ -297,7 +297,7 @@ mod tests { } fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalities { - let mut ext = TestExternalities::new_with_code(code, GenesisConfig { + let mut ext = TestExternalities::new_with_code_with_children(code, GenesisConfig { aura: Some(Default::default()), system: Some(SystemConfig { changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { @@ -353,7 +353,7 @@ mod tests { grandpa: Some(GrandpaConfig { authorities: vec![], }), - }.build_storage().unwrap().0); + }.build_storage().unwrap()); ext.changes_trie_storage().insert(0, GENESIS_HASH.into(), Default::default()); ext } diff --git a/substrate/srml/contracts/src/tests.rs b/substrate/srml/contracts/src/tests.rs index 0d4688f9a7..b195a74bf4 100644 --- a/substrate/srml/contracts/src/tests.rs +++ b/substrate/srml/contracts/src/tests.rs @@ -260,26 +260,16 @@ impl ExtBuilder { } pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend( - balances::GenesisConfig:: { - balances: vec![], - vesting: vec![], - } - .build_storage() - .unwrap() - .0, - ); - t.extend( - GenesisConfig:: { - current_schedule: Default::default(), - gas_price: self.gas_price, - } - .build_storage() - .unwrap() - .0, - ); - runtime_io::TestExternalities::new(t) + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig:: { + balances: vec![], + vesting: vec![], + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + GenesisConfig:: { + current_schedule: Default::default(), + gas_price: self.gas_price, + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + runtime_io::TestExternalities::new_with_children(t) } } diff --git a/substrate/srml/council/src/lib.rs b/substrate/srml/council/src/lib.rs index bc66862a2a..8a52f9ec00 100644 --- a/substrate/srml/council/src/lib.rs +++ b/substrate/srml/council/src/lib.rs @@ -238,8 +238,8 @@ mod tests { } pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(balances::GenesisConfig::{ + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig::{ balances: vec![ (1, 10 * self.balance_factor), (2, 20 * self.balance_factor), @@ -249,8 +249,8 @@ mod tests { (6, 60 * self.balance_factor) ], vesting: vec![], - }.build_storage().unwrap().0); - t.extend(seats::GenesisConfig:: { + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + seats::GenesisConfig:: { active_council: if self.with_council { vec![ (1, 10), (2, 10), @@ -259,8 +259,8 @@ mod tests { desired_seats: 2, presentation_duration: 2, term_duration: 5, - }.build_storage().unwrap().0); - runtime_io::TestExternalities::new(t) + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + runtime_io::TestExternalities::new_with_children(t) } } diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs index d0c71a63d6..16a6d3b5e2 100644 --- a/substrate/srml/democracy/src/lib.rs +++ b/substrate/srml/democracy/src/lib.rs @@ -1044,13 +1044,13 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(balances::GenesisConfig::{ + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig::{ balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], vesting: vec![], - }.build_storage().unwrap().0); - t.extend(GenesisConfig::default().build_storage().unwrap().0); - runtime_io::TestExternalities::new(t) + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + GenesisConfig::default().assimilate_storage(&mut t.0, &mut t.1).unwrap(); + runtime_io::TestExternalities::new_with_children(t) } type System = system::Module; diff --git a/substrate/srml/executive/src/lib.rs b/substrate/srml/executive/src/lib.rs index 2b5ebdd88c..6ee9da3c54 100644 --- a/substrate/srml/executive/src/lib.rs +++ b/substrate/srml/executive/src/lib.rs @@ -482,13 +482,13 @@ mod tests { #[test] fn balance_transfer_dispatch_works() { - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(balances::GenesisConfig:: { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig:: { balances: vec![(1, 111)], vesting: vec![], - }.build_storage().unwrap().0); + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2, 69)); - let mut t = runtime_io::TestExternalities::::new(t); + let mut t = runtime_io::TestExternalities::::new_with_children(t); with_externalities(&mut t, || { Executive::initialize_block(&Header::new( 1, @@ -504,8 +504,8 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(balances::GenesisConfig::::default().build_storage().unwrap().0); + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig::::default().assimilate_storage(&mut t.0, &mut t.1).unwrap(); t.into() } diff --git a/substrate/srml/finality-tracker/src/lib.rs b/substrate/srml/finality-tracker/src/lib.rs index 98a8a175af..f9ccc36346 100644 --- a/substrate/srml/finality-tracker/src/lib.rs +++ b/substrate/srml/finality-tracker/src/lib.rs @@ -327,8 +327,8 @@ mod tests { #[test] fn median_works() { - let t = system::GenesisConfig::default().build_storage::().unwrap().0; - with_externalities(&mut TestExternalities::new(t), || { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + with_externalities(&mut TestExternalities::new_with_children(t), || { FinalityTracker::update_hint(Some(500)); assert_eq!(FinalityTracker::median(), 250); assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); @@ -337,8 +337,8 @@ mod tests { #[test] fn notifies_when_stalled() { - let t = system::GenesisConfig::default().build_storage::().unwrap().0; - with_externalities(&mut TestExternalities::new(t), || { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + with_externalities(&mut TestExternalities::new_with_children(t), || { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); @@ -356,8 +356,8 @@ mod tests { #[test] fn recent_notifications_prevent_stalling() { - let t = system::GenesisConfig::default().build_storage::().unwrap().0; - with_externalities(&mut TestExternalities::new(t), || { + let t = system::GenesisConfig::default().build_storage::().unwrap(); + with_externalities(&mut TestExternalities::new_with_children(t), || { let mut parent_hash = System::parent_hash(); for i in 2..106 { System::initialize(&i, &parent_hash, &Default::default(), &Default::default()); diff --git a/substrate/srml/session/src/lib.rs b/substrate/srml/session/src/lib.rs index 744e00fa10..fe7a959724 100644 --- a/substrate/srml/session/src/lib.rs +++ b/substrate/srml/session/src/lib.rs @@ -563,17 +563,16 @@ mod tests { }; fn new_test_ext() -> runtime_io::TestExternalities { - TEST_SESSION_CHANGED.with(|l| *l.borrow_mut() = false); - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(timestamp::GenesisConfig:: { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + timestamp::GenesisConfig:: { minimum_period: 5, - }.build_storage().unwrap().0); - t.extend(GenesisConfig:: { + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| l.borrow().iter().cloned().map(|i| (i, UintAuthorityId(i))).collect() ), - }.build_storage().unwrap().0); - runtime_io::TestExternalities::new(t) + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); + runtime_io::TestExternalities::new_with_children(t) } fn initialize_block(block: u64) { diff --git a/substrate/srml/timestamp/src/lib.rs b/substrate/srml/timestamp/src/lib.rs index c915f6b95d..7bffac0db9 100644 --- a/substrate/srml/timestamp/src/lib.rs +++ b/substrate/srml/timestamp/src/lib.rs @@ -364,12 +364,12 @@ mod tests { #[test] fn timestamp_works() { - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(GenesisConfig:: { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig:: { minimum_period: 5, - }.build_storage().unwrap().0); + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + with_externalities(&mut TestExternalities::new_with_children(t), || { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); assert_eq!(Timestamp::now(), 69); @@ -379,12 +379,12 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(GenesisConfig:: { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig:: { minimum_period: 5, - }.build_storage().unwrap().0); + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + with_externalities(&mut TestExternalities::new_with_children(t), || { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); let _ = Timestamp::dispatch(Call::set(70), Origin::NONE); @@ -394,12 +394,12 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { - let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; - t.extend(GenesisConfig:: { + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig:: { minimum_period: 5, - }.build_storage().unwrap().0); + }.assimilate_storage(&mut t.0, &mut t.1).unwrap(); - with_externalities(&mut TestExternalities::new(t), || { + with_externalities(&mut TestExternalities::new_with_children(t), || { Timestamp::set_timestamp(42); let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); });