diff --git a/substrate/native-runtime/std/src/lib.rs b/substrate/native-runtime/std/src/lib.rs index 24a6693375..be67b81bab 100644 --- a/substrate/native-runtime/std/src/lib.rs +++ b/substrate/native-runtime/std/src/lib.rs @@ -93,9 +93,9 @@ pub fn chain_id() -> u64 { } /// "Commit" all existing operations and get the resultant storage root. -pub fn commit() -> [u8; 32] { +pub fn storage_root() -> [u8; 32] { ext::with(|ext| - ext.commit() + ext.storage_root() ).unwrap_or([0u8; 32]) } diff --git a/substrate/state_machine/src/backend.rs b/substrate/state_machine/src/backend.rs index ee6b0bbe80..9f07f2d98c 100644 --- a/substrate/state_machine/src/backend.rs +++ b/substrate/state_machine/src/backend.rs @@ -40,6 +40,9 @@ pub trait Backend { /// Commit updates to the backend and get new state. fn commit(&mut self, changes: I) -> Committed where I: IntoIterator; + + /// Get all key/value pairs into a Vec. + fn pairs(&self) -> Vec<(&[u8], &[u8])>; } /// Error impossible. @@ -87,6 +90,10 @@ impl Backend for InMemory { storage_tree_root, } } + + fn pairs(&self) -> Vec<(&[u8], &[u8])> { + self.inner.storage.iter().map(|(k, v)| (&k[..], &v[..])).collect() + } } // TODO: DB-based backend diff --git a/substrate/state_machine/src/ext.rs b/substrate/state_machine/src/ext.rs index 02901c48d5..1beca17fa6 100644 --- a/substrate/state_machine/src/ext.rs +++ b/substrate/state_machine/src/ext.rs @@ -17,7 +17,7 @@ //! Conrete externalities implementation. use std::{error, fmt}; - +use triehash::trie_root; use backend::Backend; use {Externalities, ExternalitiesError, OverlayedChanges}; @@ -76,7 +76,14 @@ impl<'a, B: 'a> Externalities for Ext<'a, B> 42 } - fn commit(&self) -> [u8; 32] { - unimplemented!(); + fn storage_root(&self) -> [u8; 32] { + let mut all_pairs = self.backend.pairs(); + all_pairs.extend( + self.overlay.committed.storage.iter() + .chain(self.overlay.prospective.storage.iter()) + .map(|(k, v)| (&k[..], &v[..])) + ); + + trie_root(all_pairs.into_iter().map(|(k, v)| (k.to_vec(), v.to_vec()))).0 } } diff --git a/substrate/state_machine/src/lib.rs b/substrate/state_machine/src/lib.rs index 61b1fafd37..e1e674a419 100644 --- a/substrate/state_machine/src/lib.rs +++ b/substrate/state_machine/src/lib.rs @@ -147,7 +147,7 @@ pub trait Externalities { fn chain_id(&self) -> u64; /// Get the trie root of the current storage map. - fn commit(&self) -> [u8; 32]; + fn storage_root(&self) -> [u8; 32]; /// Get the current set of authorities from storage. fn authorities(&self) -> Result, ExternalitiesError> { diff --git a/substrate/state_machine/src/testing.rs b/substrate/state_machine/src/testing.rs index 74cfbb9dd5..1c9c4dfcf8 100644 --- a/substrate/state_machine/src/testing.rs +++ b/substrate/state_machine/src/testing.rs @@ -23,11 +23,13 @@ use triehash::trie_root; /// Simple HashMap based Externalities impl. #[derive(Debug, Default)] pub struct TestExternalities { + /// The storage. pub storage: HashMap, Vec>, } impl TestExternalities { - fn new() -> Self { + /// Create a new instance with empty storage. + pub fn new() -> Self { TestExternalities { storage: HashMap::new(), } @@ -45,7 +47,7 @@ impl Externalities for TestExternalities { fn chain_id(&self) -> u64 { 42 } - fn commit(&self) -> [u8; 32] { + fn storage_root(&self) -> [u8; 32] { trie_root(self.storage.clone()).0 } } @@ -61,6 +63,6 @@ mod tests { ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); const ROOT: [u8; 32] = hex!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"); - assert_eq!(ext.commit(), ROOT); + assert_eq!(ext.storage_root(), ROOT); } }