Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
TrieDB, TrieDBMut, SecTrieDB, FatDB typechecks
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdplm committed May 30, 2018
1 parent bf01073 commit 013666f
Show file tree
Hide file tree
Showing 10 changed files with 254 additions and 267 deletions.
52 changes: 22 additions & 30 deletions util/patricia_trie/src/fatdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use ethereum_types::H256;
use keccak::keccak;
use hashdb::{HashDB, Hasher};
use super::{TrieDB, Trie, TrieDBIterator, TrieItem, TrieIterator, Query};
use rlp::{Decodable, Encodable};

/// A `Trie` implementation which hashes keys and uses a generic `HashDB` backing database.
/// Additionaly it stores inserted hash-key mappings for later retrieval.
Expand All @@ -27,43 +26,35 @@ pub struct FatDB<'db, H: Hasher + 'db> {
raw: TrieDB<'db, H>,
}

impl<'db, H: Hasher> FatDB<'db, H> {
impl<'db, H: Hasher> FatDB<'db, H> where H::Out: Decodable {
/// Create a new trie with the backing database `db` and empty `root`
/// Initialise to the state entailed by the genesis block.
/// This guarantees the trie is built correctly.
pub fn new(db: &'db HashDB<H=H>, root: &'db H256) -> super::Result<Self> {
let fatdb = FatDB {
raw: TrieDB::new(db, root)?
};

Ok(fatdb)
pub fn new(db: &'db HashDB<H=H>, root: &'db H::Out) -> super::Result<Self, H::Out> {
Ok(FatDB { raw: TrieDB::new(db, root)? })
}

/// Get the backing database.
pub fn db(&self) -> &HashDB<H=H> {
self.raw.db()
}
pub fn db(&self) -> &HashDB<H=H> { self.raw.db() }
}

impl<'db, H: Hasher> Trie for FatDB<'db, H> {
impl<'db, H: Hasher> Trie for FatDB<'db, H> where H::Out: Decodable + Encodable {
type H = H;

fn root(&self) -> &<Self::H as Hasher>::Out {
self.raw.root()
}
fn root(&self) -> &<Self::H as Hasher>::Out { self.raw.root() }

fn contains(&self, key: &[u8]) -> super::Result<bool> {
self.raw.contains(&keccak(key)) // TODO
fn contains(&self, key: &[u8]) -> super::Result<bool, <Self::H as Hasher>::Out> {
self.raw.contains(&Self::H::hash(key).as_ref())
}

fn get_with<'a, 'key, Q: Query>(&'a self, key: &'key [u8], query: Q) -> super::Result<Option<Q::Item>>
fn get_with<'a, 'key, Q: Query<Self::H>>(&'a self, key: &'key [u8], query: Q) -> super::Result<Option<Q::Item>, <Self::H as Hasher>::Out>
where 'a: 'key
{
self.raw.get_with(&keccak(key), query) // TODO
self.raw.get_with(&Self::H::hash(key).as_ref(), query)
}

fn iter<'a>(&'a self) -> super::Result<Box<TrieIterator<Item = TrieItem> + 'a>> {
FatDBIterator::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
fn iter<'a>(&'a self) -> super::Result<Box<TrieIterator<Self::H, Item = TrieItem<Self::H>> + 'a>, <Self::H as Hasher>::Out> {
FatDBIterator::<Self::H>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
}
}

Expand All @@ -73,30 +64,31 @@ pub struct FatDBIterator<'db, H: Hasher + 'db> {
trie: &'db TrieDB<'db, H>,
}

impl<'db, H: Hasher> FatDBIterator<'db, H> {
impl<'db, H: Hasher> FatDBIterator<'db, H> where H::Out: Decodable {
/// Creates new iterator.
pub fn new(trie: &'db TrieDB<H>) -> super::Result<Self> {
pub fn new(trie: &'db TrieDB<H>) -> super::Result<Self, H::Out> {
Ok(FatDBIterator {
trie_iterator: TrieDBIterator::new(trie)?,
trie: trie,
})
}
}

impl<'db, H: Hasher> TrieIterator for FatDBIterator<'db, H> {
fn seek(&mut self, key: &[u8]) -> super::Result<()> {
self.trie_iterator.seek(&keccak(key))
impl<'db, H: Hasher> TrieIterator<H> for FatDBIterator<'db, H> where H::Out: Decodable {
fn seek(&mut self, key: &[u8]) -> super::Result<(), H::Out> {
let hashed_key = H::hash(key);
self.trie_iterator.seek(&hashed_key.as_ref())
}
}

impl<'db, H: Hasher> Iterator for FatDBIterator<'db, H> {
type Item = TrieItem<'db>;
impl<'db, H: Hasher> Iterator for FatDBIterator<'db, H> where H::Out: Decodable {
type Item = TrieItem<'db, H>;

fn next(&mut self) -> Option<Self::Item> {
self.trie_iterator.next()
.map(|res|
res.map(|(hash, value)| {
let aux_hash = keccak(hash);
let aux_hash = &H::hash(&hash);
(self.trie.db().get(&aux_hash).expect("Missing fatdb hash").into_vec(), value)
})
)
Expand Down
29 changes: 12 additions & 17 deletions util/patricia_trie/src/fatdbmut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use ethereum_types::H256;
use keccak::keccak;
//use ethereum_types::H256;
//use keccak::keccak;
use hashdb::{HashDB, DBValue, Hasher};
use super::{TrieDBMut, TrieMut};

Expand All @@ -31,14 +31,14 @@ impl<'db, H: Hasher> FatDBMut<'db, H> {
/// Create a new trie with the backing database `db` and empty `root`
/// Initialise to the state entailed by the genesis block.
/// This guarantees the trie is built correctly.
pub fn new(db: &'db mut HashDB<H=H>, root: &'db mut H256) -> Self {
pub fn new(db: &'db mut HashDB<H=H>, root: &'db mut H::Out) -> Self {
FatDBMut { raw: TrieDBMut::new(db, root) }
}

/// Create a new trie with the backing database `db` and `root`.
///
/// Returns an error if root does not exist.
pub fn from_existing(db: &'db mut HashDB<H=H>, root: &'db mut H256) -> super::Result<Self> {
pub fn from_existing(db: &'db mut HashDB<H=H>, root: &'db mut H::Out) -> super::Result<Self> {
Ok(FatDBMut { raw: TrieDBMut::from_existing(db, root)? })
}

Expand All @@ -52,33 +52,27 @@ impl<'db, H: Hasher> FatDBMut<'db, H> {
self.raw.db_mut()
}

fn to_aux_key(key: &[u8]) -> H256 {
keccak(key)
} // TODO
fn to_aux_key(key: &[u8]) -> H::Out { H::hash(key) }
}

impl<'db, H: Hasher> TrieMut for FatDBMut<'db, H> {
type H = H;
fn root(&mut self) -> &<Self::H as Hasher>::Out {
self.raw.root()
}
fn root(&mut self) -> &<Self::H as Hasher>::Out { self.raw.root() }

fn is_empty(&self) -> bool {
self.raw.is_empty()
}
fn is_empty(&self) -> bool { self.raw.is_empty() }

fn contains(&self, key: &[u8]) -> super::Result<bool> {
self.raw.contains(&keccak(key))
self.raw.contains(Self::H::hash(key))
}

fn get<'a, 'key>(&'a self, key: &'key [u8]) -> super::Result<Option<DBValue>>
where 'a: 'key
{
self.raw.get(&keccak(key)) // TODO
self.raw.get(Self::H::hash(key))
}

fn insert(&mut self, key: &[u8], value: &[u8]) -> super::Result<Option<DBValue>> {
let hash = keccak(key); // TODO
let hash = Self::H::hash(key);
let out = self.raw.insert(&hash, value)?;
let db = self.raw.db_mut();

Expand All @@ -90,7 +84,8 @@ impl<'db, H: Hasher> TrieMut for FatDBMut<'db, H> {
}

fn remove(&mut self, key: &[u8]) -> super::Result<Option<DBValue>> {
let hash = keccak(key);
// let hash = keccak(key); //TODO
let hash = Self::H::hash(key);
let out = self.raw.remove(&hash)?;

// don't remove if it already exists.
Expand Down
Loading

0 comments on commit 013666f

Please sign in to comment.