use tetcore_std::vec::Vec;
use codec::{Encode, Decode};
use tetsy_hash_db::{Hasher, HashDB};
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub struct StorageProof {
trie_nodes: Vec<Vec<u8>>,
}
impl StorageProof {
pub fn new(trie_nodes: Vec<Vec<u8>>) -> Self {
StorageProof { trie_nodes }
}
pub fn empty() -> Self {
StorageProof {
trie_nodes: Vec::new(),
}
}
pub fn is_empty(&self) -> bool {
self.trie_nodes.is_empty()
}
pub fn iter_nodes(self) -> StorageProofNodeIterator {
StorageProofNodeIterator::new(self)
}
pub fn into_memory_db<H: Hasher>(self) -> crate::MemoryDB<H> {
self.into()
}
pub fn merge<I>(proofs: I) -> Self where I: IntoIterator<Item=Self> {
let trie_nodes = proofs.into_iter()
.flat_map(|proof| proof.iter_nodes())
.collect::<tetcore_std::collections::btree_set::BTreeSet<_>>()
.into_iter()
.collect();
Self { trie_nodes }
}
}
pub struct StorageProofNodeIterator {
inner: <Vec<Vec<u8>> as IntoIterator>::IntoIter,
}
impl StorageProofNodeIterator {
fn new(proof: StorageProof) -> Self {
StorageProofNodeIterator {
inner: proof.trie_nodes.into_iter(),
}
}
}
impl Iterator for StorageProofNodeIterator {
type Item = Vec<u8>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<H: Hasher> From<StorageProof> for crate::MemoryDB<H> {
fn from(proof: StorageProof) -> Self {
let mut db = crate::MemoryDB::default();
for item in proof.iter_nodes() {
db.insert(crate::EMPTY_PREFIX, &item);
}
db
}
}