// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
//! Trie interface and implementation.
extern crate rand;
extern crate ethereum_types;
extern crate keccak_hash as keccak;
extern crate rlp;
extern crate hashdb;
extern crate ethcore_bytes as bytes;
extern crate elastic_array;
extern crate memorydb;
extern crate ethcore_logger;
#[cfg(test)]
extern crate trie_standardmap as standardmap;
#[macro_use]
extern crate log;
use std::{fmt, error};
use ethereum_types::H256;
use keccak::KECCAK_NULL_RLP;
use hashdb::{HashDB, DBValue};
pub mod node;
pub mod triedb;
pub mod triedbmut;
pub mod sectriedb;
pub mod sectriedbmut;
pub mod recorder;
mod fatdb;
mod fatdbmut;
mod lookup;
mod nibbleslice;
mod nibblevec;
pub use self::triedbmut::TrieDBMut;
pub use self::triedb::{TrieDB, TrieDBIterator};
pub use self::sectriedbmut::SecTrieDBMut;
pub use self::sectriedb::SecTrieDB;
pub use self::fatdb::{FatDB, FatDBIterator};
pub use self::fatdbmut::FatDBMut;
pub use self::recorder::Recorder;
/// Trie Errors.
///
/// These borrow the data within them to avoid excessive copying on every
/// trie operation.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum TrieError {
/// Attempted to create a trie with a state root not in the DB.
InvalidStateRoot(H256),
/// Trie item not found in the database,
IncompleteDatabase(H256),
}
impl fmt::Display for TrieError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TrieError::InvalidStateRoot(ref root) => write!(f, "Invalid state root: {}", root),
TrieError::IncompleteDatabase(ref missing) =>
write!(f, "Database missing expected key: {}", missing),
}
}
}
impl error::Error for TrieError {
fn description(&self) -> &str {
match *self {
TrieError::InvalidStateRoot(_) => "Invalid state root",
TrieError::IncompleteDatabase(_) => "Incomplete database",
}
}
}
/// Trie result type. Boxed to avoid copying around extra space for `H256`s on successful queries.
pub type Result = ::std::result::Result>;
/// Trie-Item type.
pub type TrieItem<'a> = Result<(Vec, DBValue)>;
/// Description of what kind of query will be made to the trie.
///
/// This is implemented for any &mut recorder (where the query will return
/// a DBValue), any function taking raw bytes (where no recording will be made),
/// or any tuple of (&mut Recorder, FnOnce(&[u8]))
pub trait Query {
/// Output item.
type Item;
/// Decode a byte-slice into the desired item.
fn decode(self, &[u8]) -> Self::Item;
/// Record that a node has been passed through.
fn record(&mut self, &H256, &[u8], u32) { }
}
impl<'a> Query for &'a mut Recorder {
type Item = DBValue;
fn decode(self, value: &[u8]) -> DBValue { DBValue::from_slice(value) }
fn record(&mut self, hash: &H256, data: &[u8], depth: u32) {
(&mut **self).record(hash, data, depth);
}
}
impl Query for F where F: for<'a> FnOnce(&'a [u8]) -> T {
type Item = T;
fn decode(self, value: &[u8]) -> T { (self)(value) }
}
impl<'a, F, T> Query for (&'a mut Recorder, F) where F: FnOnce(&[u8]) -> T {
type Item = T;
fn decode(self, value: &[u8]) -> T { (self.1)(value) }
fn record(&mut self, hash: &H256, data: &[u8], depth: u32) {
self.0.record(hash, data, depth)
}
}
/// A key-value datastore implemented as a database-backed modified Merkle tree.
pub trait Trie {
/// Return the root of the trie.
fn root(&self) -> &H256;
/// Is the trie empty?
fn is_empty(&self) -> bool { *self.root() == KECCAK_NULL_RLP }
/// Does the trie contain a given key?
fn contains(&self, key: &[u8]) -> Result {
self.get(key).map(|x| x.is_some())
}
/// What is the value of the given key in this trie?
fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Result