new state api state_getKeys to expose storage keys (#1380)

This commit is contained in:
Xiliang Chen
2019-01-12 00:51:19 +13:00
committed by Gav Wood
parent bf51b8a5ad
commit 0e569e6bf2
7 changed files with 56 additions and 0 deletions
@@ -86,6 +86,9 @@ pub trait Backend<H: Hasher> {
/// Get all key/value pairs into a Vec.
fn pairs(&self) -> Vec<(Vec<u8>, Vec<u8>)>;
/// Get all keys with given prefix
fn keys(&self, prefix: &Vec<u8>) -> Vec<Vec<u8>>;
/// Try convert into trie backend.
fn try_into_trie_backend(self) -> Option<TrieBackend<Self::TrieBackendStorage, H>>;
}
@@ -283,6 +286,10 @@ impl<H: Hasher> Backend<H> for InMemory<H> where H::Out: HeapSizeOf {
self.inner.get(&None).into_iter().flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.clone()))).collect()
}
fn keys(&self, prefix: &Vec<u8>) -> Vec<Vec<u8>> {
self.inner.get(&None).into_iter().flat_map(|map| map.keys().filter(|k| k.starts_with(prefix)).cloned()).collect()
}
fn try_into_trie_backend(self) -> Option<TrieBackend<Self::TrieBackendStorage, H>> {
let mut mdb = MemoryDB::default(); // TODO: should be more correct and use ::new()
let mut root = None;
@@ -146,6 +146,10 @@ impl<'a, S, H> Backend<H> for ProvingBackend<'a, S, H>
self.backend.pairs()
}
fn keys(&self, prefix: &Vec<u8>) -> Vec<Vec<u8>> {
self.backend.keys(prefix)
}
fn storage_root<I>(&self, delta: I) -> (H::Out, MemoryDB<H>)
where I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
{
@@ -105,6 +105,26 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
}
}
fn keys(&self, prefix: &Vec<u8>) -> Vec<Vec<u8>> {
let mut read_overlay = MemoryDB::default(); // TODO: use new for correctness
let eph = Ephemeral::new(self.essence.backend_storage(), &mut read_overlay);
let collect_all = || -> Result<_, Box<TrieError<H::Out>>> {
let trie = TrieDB::<H>::new(&eph, self.essence.root())?;
let mut v = Vec::new();
for x in trie.iter()? {
let (key, _) = x?;
if key.starts_with(prefix) {
v.push(key.to_vec());
}
}
Ok(v)
};
collect_all().map_err(|e| debug!(target: "trie", "Error extracting trie keys: {}", e)).unwrap_or_default()
}
fn storage_root<I>(&self, delta: I) -> (H::Out, MemoryDB<H>)
where I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
{