The storage runtime interface should not enforce a hash type (#4231)

* The storage runtime interface should not enforce a hash type

Currently the runtime interface enforces `H256` as hash type, but in the
future people could use whatever they want as hash type. The hash type
always needs to match between the runtime and the node, but that is
already required.

* Update primitives/externalities/src/lib.rs

Co-Authored-By: thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
Bastian Köcher
2019-11-28 01:00:29 +01:00
committed by Gavin Wood
parent 39388b826b
commit 3e26fceda4
29 changed files with 253 additions and 165 deletions
+43 -27
View File
@@ -30,6 +30,7 @@ use primitives::{
};
use trie::{trie_types::Layout, MemoryDB, default_child_trie_root};
use externalities::Extensions;
use codec::{Decode, Encode};
use std::{error, fmt, any::{Any, TypeId}};
use log::{warn, trace};
@@ -189,25 +190,25 @@ where
result
}
fn storage_hash(&self, key: &[u8]) -> Option<H256> {
fn storage_hash(&self, key: &[u8]) -> Option<Vec<u8>> {
let _guard = panic_handler::AbortGuard::force_abort();
let result = self.overlay
.storage(key)
.map(|x| x.map(|x| H::hash(x)))
.unwrap_or_else(||
self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)
);
.unwrap_or_else(|| self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL));
trace!(target: "state-trace", "{:04x}: Hash {}={:?}",
self.id,
HexDisplay::from(&key),
result,
);
result
result.map(|r| r.encode())
}
fn original_storage(&self, key: &[u8]) -> Option<Vec<u8>> {
let _guard = panic_handler::AbortGuard::force_abort();
let result = self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL);
trace!(target: "state-trace", "{:04x}: GetOriginal {}={:?}",
self.id,
HexDisplay::from(&key),
@@ -216,15 +217,16 @@ where
result
}
fn original_storage_hash(&self, key: &[u8]) -> Option<H256> {
fn original_storage_hash(&self, key: &[u8]) -> Option<Vec<u8>> {
let _guard = panic_handler::AbortGuard::force_abort();
let result = self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL);
trace!(target: "state-trace", "{:04x}: GetOriginalHash {}={:?}",
self.id,
HexDisplay::from(&key),
result,
);
result
result.map(|r| r.encode())
}
fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
@@ -246,7 +248,7 @@ where
result
}
fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<H256> {
fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
let _guard = panic_handler::AbortGuard::force_abort();
let result = self.overlay
.child_storage(storage_key.as_ref(), key)
@@ -262,7 +264,7 @@ where
result,
);
result
result.map(|r| r.encode())
}
fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
@@ -280,7 +282,11 @@ where
result
}
fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<H256> {
fn original_child_storage_hash(
&self,
storage_key: ChildStorageKey,
key: &[u8],
) -> Option<Vec<u8>> {
let _guard = panic_handler::AbortGuard::force_abort();
let result = self.backend
.child_storage_hash(storage_key.as_ref(), key)
@@ -292,7 +298,7 @@ where
HexDisplay::from(&key),
result,
);
result
result.map(|r| r.encode())
}
fn exists_storage(&self, key: &[u8]) -> bool {
@@ -415,14 +421,14 @@ where
42
}
fn storage_root(&mut self) -> H256 {
fn storage_root(&mut self) -> Vec<u8> {
let _guard = panic_handler::AbortGuard::force_abort();
if let Some((_, ref root)) = self.storage_transaction {
trace!(target: "state-trace", "{:04x}: Root (cached) {}",
self.id,
HexDisplay::from(&root.as_ref()),
);
return root.clone();
return root.encode();
}
let child_storage_keys =
@@ -447,7 +453,7 @@ where
self.id,
HexDisplay::from(&root.as_ref()),
);
root
root.encode()
}
fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec<u8> {
@@ -455,6 +461,7 @@ where
if self.storage_transaction.is_some() {
let root = self
.storage(storage_key.as_ref())
.and_then(|k| Decode::decode(&mut &k[..]).ok())
.unwrap_or(
default_child_trie_root::<Layout<H>>(storage_key.as_ref())
);
@@ -463,7 +470,7 @@ where
HexDisplay::from(&storage_key.as_ref()),
HexDisplay::from(&root.as_ref()),
);
root
root.encode()
} else {
let storage_key = storage_key.as_ref();
@@ -481,7 +488,7 @@ where
if is_empty {
self.overlay.set_storage(storage_key.into(), None);
} else {
self.overlay.set_storage(storage_key.into(), Some(root.clone()));
self.overlay.set_storage(storage_key.into(), Some(root.encode()));
}
trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}",
@@ -489,20 +496,29 @@ where
HexDisplay::from(&storage_key.as_ref()),
HexDisplay::from(&root.as_ref()),
);
root
root.encode()
}
}
fn storage_changes_root(&mut self, parent_hash: H256) -> Result<Option<H256>, ()> {
fn storage_changes_root(&mut self, parent_hash: &[u8]) -> Result<Option<Vec<u8>>, ()> {
let _guard = panic_handler::AbortGuard::force_abort();
self.changes_trie_transaction = build_changes_trie::<_, T, H, N>(
self.backend,
self.changes_trie_storage.clone(),
self.overlay,
parent_hash,
H256::decode(&mut &parent_hash[..]).map_err(|e|
trace!(
target: "state-trace",
"Failed to decode changes root parent hash: {}",
e,
)
)?,
)?;
let result = Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone()));
let result = Ok(
self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.encode())
);
trace!(target: "state-trace", "{:04x}: ChangesRoot({}) {:?}",
self.id,
HexDisplay::from(&parent_hash.as_ref()),
@@ -566,7 +582,7 @@ mod tests {
let mut overlay = prepare_overlay_with_changes();
let backend = TestBackend::default();
let mut ext = TestExt::new(&mut overlay, &backend, None, None);
assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None);
assert_eq!(ext.storage_changes_root(&H256::default().encode()).unwrap(), None);
}
#[test]
@@ -576,7 +592,7 @@ mod tests {
let storage = TestChangesTrieStorage::with_blocks(vec![(100, Default::default())]);
let backend = TestBackend::default();
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None);
assert_eq!(ext.storage_changes_root(&H256::default().encode()).unwrap(), None);
}
#[test]
@@ -586,8 +602,8 @@ mod tests {
let backend = TestBackend::default();
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
assert_eq!(
ext.storage_changes_root(Default::default()).unwrap(),
Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into()),
ext.storage_changes_root(&H256::default().encode()).unwrap(),
Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").to_vec()),
);
}
@@ -599,8 +615,8 @@ mod tests {
let backend = TestBackend::default();
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
assert_eq!(
ext.storage_changes_root(Default::default()).unwrap(),
Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into()),
ext.storage_changes_root(&H256::default().encode()).unwrap(),
Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").to_vec()),
);
}
}