2018-06-04 10:19:50 +02:00
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
2016-02-05 13:40:41 +01:00
// 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 <http://www.gnu.org/licenses/>.
2016-07-14 18:06:46 +02:00
//! In-memory trie representation.
2018-07-02 18:50:05 +02:00
use super ::{ Result , TrieError , TrieMut } ;
2017-01-06 16:18:45 +01:00
use super ::lookup ::Lookup ;
2018-07-02 18:50:05 +02:00
use super ::node ::Node as EncodedNode ;
use node_codec ::NodeCodec ;
2016-10-26 13:53:47 +02:00
use super ::node ::NodeKey ;
2016-07-14 18:06:46 +02:00
2017-09-06 20:47:45 +02:00
use bytes ::ToPretty ;
2018-07-02 18:50:05 +02:00
use hashdb ::{ HashDB , Hasher , DBValue } ;
2017-09-06 20:47:45 +02:00
use nibbleslice ::NibbleSlice ;
2016-07-14 18:06:46 +02:00
2018-07-02 18:50:05 +02:00
use elastic_array ::ElasticArray1024 ;
2016-07-14 18:06:46 +02:00
use std ::collections ::{ HashSet , VecDeque } ;
2018-07-02 18:50:05 +02:00
use std ::marker ::PhantomData ;
2016-07-14 18:06:46 +02:00
use std ::mem ;
use std ::ops ::Index ;
2018-07-05 17:15:03 +02:00
use heapsize ::HeapSizeOf ;
use std ::{ fmt ::Debug , hash ::Hash } ;
2016-07-14 18:06:46 +02:00
// For lookups into the Node storage buffer.
// This is deliberately non-copyable.
#[ derive(Debug) ]
struct StorageHandle ( usize ) ;
// Handles to nodes in the trie.
#[ derive(Debug) ]
2018-07-05 17:15:03 +02:00
enum NodeHandle < H > {
2016-07-14 18:06:46 +02:00
/// Loaded into memory.
InMemory ( StorageHandle ) ,
/// Either a hash or an inline node
2018-07-05 17:15:03 +02:00
Hash ( H ) ,
2016-07-14 18:06:46 +02:00
}
2018-07-05 17:15:03 +02:00
impl < H > From < StorageHandle > for NodeHandle < H > {
2016-07-14 18:06:46 +02:00
fn from ( handle : StorageHandle ) -> Self {
NodeHandle ::InMemory ( handle )
}
}
2018-07-05 17:15:03 +02:00
fn empty_children < H > ( ) -> Box < [ Option < NodeHandle < H > > ; 16 ] > {
2016-08-31 14:28:56 +02:00
Box ::new ( [
2016-07-14 18:06:46 +02:00
None , None , None , None , None , None , None , None ,
None , None , None , None , None , None , None , None ,
2016-08-31 14:28:56 +02:00
] )
2016-07-14 18:06:46 +02:00
}
/// Node types in the Trie.
#[ derive(Debug) ]
2018-07-05 17:15:03 +02:00
enum Node < H > {
2016-07-14 18:06:46 +02:00
/// Empty node.
Empty ,
/// A leaf node contains the end of a key and a value.
/// This key is encoded from a `NibbleSlice`, meaning it contains
/// a flag indicating it is a leaf.
2016-10-26 13:53:47 +02:00
Leaf ( NodeKey , DBValue ) ,
2016-07-14 18:06:46 +02:00
/// An extension contains a shared portion of a key and a child node.
/// The shared portion is encoded from a `NibbleSlice` meaning it contains
/// a flag indicating it is an extension.
/// The child node is always a branch.
2018-07-02 18:50:05 +02:00
Extension ( NodeKey , NodeHandle < H > ) ,
2016-07-14 18:06:46 +02:00
/// A branch has up to 16 children and an optional value.
2018-07-02 18:50:05 +02:00
Branch ( Box < [ Option < NodeHandle < H > > ; 16 ] > , Option < DBValue > )
2016-07-14 18:06:46 +02:00
}
2018-07-05 17:15:03 +02:00
impl < O > Node < O > where O : AsRef < [ u8 ] > + AsMut < [ u8 ] > + Default + HeapSizeOf + Debug + PartialEq + Eq + Hash + Send + Sync + Clone + Copy {
2016-07-14 18:06:46 +02:00
// load an inline node into memory or get the hash to do the lookup later.
2018-07-05 17:15:03 +02:00
fn inline_or_hash < C , H > ( node : & [ u8 ] , db : & HashDB < H > , storage : & mut NodeStorage < H ::Out > ) -> NodeHandle < H ::Out >
where C : NodeCodec < H > ,
H : Hasher < Out = O > ,
2018-07-02 18:50:05 +02:00
{
C ::try_decode_hash ( & node )
2018-03-22 03:08:48 +01:00
. map ( NodeHandle ::Hash )
. unwrap_or_else ( | | {
2018-07-05 17:15:03 +02:00
let child = Node ::from_encoded ::< C , H > ( node , db , storage ) ;
2018-03-22 03:08:48 +01:00
NodeHandle ::InMemory ( storage . alloc ( Stored ::New ( child ) ) )
} )
2016-07-14 18:06:46 +02:00
}
2018-07-02 18:50:05 +02:00
// decode a node from encoded bytes without getting its children.
2018-07-05 17:15:03 +02:00
fn from_encoded < C , H > ( data : & [ u8 ] , db : & HashDB < H > , storage : & mut NodeStorage < H ::Out > ) -> Self
where C : NodeCodec < H > ,
H : Hasher < Out = O > ,
2018-07-02 18:50:05 +02:00
{
match C ::decode ( data ) . expect ( " encoded bytes read from db; qed " ) {
EncodedNode ::Empty = > Node ::Empty ,
EncodedNode ::Leaf ( k , v ) = > Node ::Leaf ( k . encoded ( true ) , DBValue ::from_slice ( & v ) ) ,
EncodedNode ::Extension ( key , cb ) = > {
Node ::Extension (
key . encoded ( false ) ,
2018-07-05 17:15:03 +02:00
Self ::inline_or_hash ::< C , H > ( cb , db , storage ) )
2016-07-14 18:06:46 +02:00
}
2018-07-02 18:50:05 +02:00
EncodedNode ::Branch ( ref encoded_children , val ) = > {
let mut child = | i :usize | {
let raw = encoded_children [ i ] ;
if ! C ::is_empty_node ( raw ) {
2018-07-05 17:15:03 +02:00
Some ( Self ::inline_or_hash ::< C , H > ( raw , db , storage ) )
2018-03-06 19:42:24 +01:00
} else {
None
2016-07-14 18:06:46 +02:00
}
2018-03-06 19:42:24 +01:00
} ;
let children = Box ::new ( [
child ( 0 ) , child ( 1 ) , child ( 2 ) , child ( 3 ) ,
child ( 4 ) , child ( 5 ) , child ( 6 ) , child ( 7 ) ,
child ( 8 ) , child ( 9 ) , child ( 10 ) , child ( 11 ) ,
child ( 12 ) , child ( 13 ) , child ( 14 ) , child ( 15 ) ,
] ) ;
2016-07-14 18:06:46 +02:00
2017-01-06 16:18:45 +01:00
Node ::Branch ( children , val . map ( DBValue ::from_slice ) )
2016-07-14 18:06:46 +02:00
}
}
}
// TODO: parallelize
2018-07-05 17:15:03 +02:00
fn into_encoded < F , C , H > ( self , mut child_cb : F ) -> ElasticArray1024 < u8 >
2018-07-02 18:50:05 +02:00
where
C : NodeCodec < H > ,
2018-07-05 17:15:03 +02:00
F : FnMut ( NodeHandle < H ::Out > ) -> ChildReference < H ::Out > ,
H : Hasher < Out = O > ,
2016-07-14 18:06:46 +02:00
{
match self {
2018-07-02 18:50:05 +02:00
Node ::Empty = > C ::empty_node ( ) ,
Node ::Leaf ( partial , value ) = > C ::leaf_node ( & partial , & value ) ,
Node ::Extension ( partial , child ) = > C ::ext_node ( & partial , child_cb ( child ) ) ,
2016-07-14 18:06:46 +02:00
Node ::Branch ( mut children , value ) = > {
2018-07-02 18:50:05 +02:00
C ::branch_node (
// map the `NodeHandle`s from the Branch to `ChildReferences`
children . iter_mut ( )
. map ( Option ::take )
2018-07-05 17:15:03 +02:00
. map ( | maybe_child |
2018-07-02 18:50:05 +02:00
maybe_child . map ( | child | child_cb ( child ) )
) ,
value
)
2016-07-14 18:06:46 +02:00
}
}
}
}
// post-inspect action.
2018-07-05 17:15:03 +02:00
enum Action < H > {
2016-07-14 18:06:46 +02:00
// Replace a node with a new one.
2018-07-02 18:50:05 +02:00
Replace ( Node < H > ) ,
2016-07-14 18:06:46 +02:00
// Restore the original node. This trusts that the node is actually the original.
2018-07-02 18:50:05 +02:00
Restore ( Node < H > ) ,
2016-07-14 18:06:46 +02:00
// if it is a new node, just clears the storage.
Delete ,
}
// post-insert action. Same as action without delete
2018-07-05 17:15:03 +02:00
enum InsertAction < H > {
2016-07-14 18:06:46 +02:00
// Replace a node with a new one.
2018-07-02 18:50:05 +02:00
Replace ( Node < H > ) ,
2016-07-14 18:06:46 +02:00
// Restore the original node.
2018-07-02 18:50:05 +02:00
Restore ( Node < H > ) ,
2016-07-14 18:06:46 +02:00
}
2018-07-05 17:15:03 +02:00
impl < H > InsertAction < H > {
2018-07-02 18:50:05 +02:00
fn into_action ( self ) -> Action < H > {
2016-07-14 18:06:46 +02:00
match self {
InsertAction ::Replace ( n ) = > Action ::Replace ( n ) ,
InsertAction ::Restore ( n ) = > Action ::Restore ( n ) ,
}
}
// unwrap the node, disregarding replace or restore state.
2018-07-02 18:50:05 +02:00
fn unwrap_node ( self ) -> Node < H > {
2016-07-14 18:06:46 +02:00
match self {
InsertAction ::Replace ( n ) | InsertAction ::Restore ( n ) = > n ,
}
}
}
// What kind of node is stored here.
2018-07-05 17:15:03 +02:00
enum Stored < H > {
2016-07-14 18:06:46 +02:00
// A new node.
2018-07-02 18:50:05 +02:00
New ( Node < H > ) ,
2016-07-14 18:06:46 +02:00
// A cached node, loaded from the DB.
2018-07-05 17:15:03 +02:00
Cached ( Node < H > , H ) ,
2018-07-02 18:50:05 +02:00
}
/// Used to build a collection of child nodes from a collection of `NodeHandle`s
pub enum ChildReference < HO > { // `HO` is e.g. `H256`, i.e. the output of a `Hasher`
Hash ( HO ) ,
Inline ( HO , usize ) , // usize is the length of the node data we store in the `H::Out`
2016-07-14 18:06:46 +02:00
}
/// Compact and cache-friendly storage for Trie nodes.
2018-07-05 17:15:03 +02:00
struct NodeStorage < H > {
2018-07-02 18:50:05 +02:00
nodes : Vec < Stored < H > > ,
2016-07-14 18:06:46 +02:00
free_indices : VecDeque < usize > ,
}
2018-07-05 17:15:03 +02:00
impl < H > NodeStorage < H > {
2016-07-14 18:06:46 +02:00
/// Create a new storage.
fn empty ( ) -> Self {
NodeStorage {
nodes : Vec ::new ( ) ,
free_indices : VecDeque ::new ( ) ,
}
}
/// Allocate a new node in the storage.
2018-07-02 18:50:05 +02:00
fn alloc ( & mut self , stored : Stored < H > ) -> StorageHandle {
2016-07-14 18:06:46 +02:00
if let Some ( idx ) = self . free_indices . pop_front ( ) {
self . nodes [ idx ] = stored ;
StorageHandle ( idx )
} else {
self . nodes . push ( stored ) ;
StorageHandle ( self . nodes . len ( ) - 1 )
}
}
/// Remove a node from the storage, consuming the handle and returning the node.
2018-07-02 18:50:05 +02:00
fn destroy ( & mut self , handle : StorageHandle ) -> Stored < H > {
2016-07-14 18:06:46 +02:00
let idx = handle . 0 ;
self . free_indices . push_back ( idx ) ;
mem ::replace ( & mut self . nodes [ idx ] , Stored ::New ( Node ::Empty ) )
}
}
2018-07-05 17:15:03 +02:00
impl < ' a , H > Index < & ' a StorageHandle > for NodeStorage < H > {
2018-07-02 18:50:05 +02:00
type Output = Node < H > ;
2016-07-14 18:06:46 +02:00
2018-07-02 18:50:05 +02:00
fn index ( & self , handle : & ' a StorageHandle ) -> & Node < H > {
2016-07-14 18:06:46 +02:00
match self . nodes [ handle . 0 ] {
Stored ::New ( ref node ) = > node ,
Stored ::Cached ( ref node , _ ) = > node ,
}
}
}
2015-12-17 12:43:50 +01:00
2015-12-19 13:53:05 +01:00
/// A `Trie` implementation using a generic `HashDB` backing database.
2016-03-07 14:33:00 +01:00
///
2016-07-14 18:06:46 +02:00
/// Use it as a `TrieMut` trait object. You can use `db()` to get the backing database object.
/// Note that changes are not committed to the database until `commit` is called.
/// Querying the root or dropping the trie will commit automatically.
2015-12-19 13:53:05 +01:00
///
/// # Example
/// ```
2017-09-12 19:23:02 +02:00
/// extern crate patricia_trie as trie;
2018-07-02 18:50:05 +02:00
/// extern crate patricia_trie_ethereum as ethtrie;
2017-09-06 20:47:45 +02:00
/// extern crate hashdb;
2018-07-02 18:50:05 +02:00
/// extern crate keccak_hash;
/// extern crate keccak_hasher;
2017-09-06 20:47:45 +02:00
/// extern crate memorydb;
2018-01-10 13:35:18 +01:00
/// extern crate ethereum_types;
2016-09-01 13:36:32 +02:00
///
2017-11-17 17:12:12 +01:00
/// use keccak_hash::KECCAK_NULL_RLP;
2018-07-02 18:50:05 +02:00
/// use ethtrie::{TrieDBMut, trie::TrieMut};
/// use hashdb::DBValue;
/// use keccak_hasher::KeccakHasher;
2017-09-06 20:47:45 +02:00
/// use memorydb::*;
2018-01-10 13:35:18 +01:00
/// use ethereum_types::H256;
2015-12-19 13:53:05 +01:00
///
/// fn main() {
2018-07-02 18:50:05 +02:00
/// let mut memdb = MemoryDB::<KeccakHasher>::new();
2015-12-19 13:53:05 +01:00
/// let mut root = H256::new();
/// let mut t = TrieDBMut::new(&mut memdb, &mut root);
/// assert!(t.is_empty());
2017-08-30 16:20:21 +02:00
/// assert_eq!(*t.root(), KECCAK_NULL_RLP);
2016-08-03 18:35:48 +02:00
/// t.insert(b"foo", b"bar").unwrap();
/// assert!(t.contains(b"foo").unwrap());
2016-10-26 13:53:47 +02:00
/// assert_eq!(t.get(b"foo").unwrap().unwrap(), DBValue::from_slice(b"bar"));
2016-08-03 18:35:48 +02:00
/// t.remove(b"foo").unwrap();
/// assert!(!t.contains(b"foo").unwrap());
2015-12-19 13:53:05 +01:00
/// }
/// ```
2018-07-02 18:50:05 +02:00
pub struct TrieDBMut < ' a , H , C >
where
H : Hasher + ' a ,
C : NodeCodec < H >
{
2018-07-05 17:15:03 +02:00
storage : NodeStorage < H ::Out > ,
2018-07-02 18:50:05 +02:00
db : & ' a mut HashDB < H > ,
root : & ' a mut H ::Out ,
2018-07-05 17:15:03 +02:00
root_handle : NodeHandle < H ::Out > ,
2018-07-02 18:50:05 +02:00
death_row : HashSet < H ::Out > ,
2016-07-14 18:06:46 +02:00
/// The number of hash operations this trie has performed.
/// Note that none are performed until changes are committed.
2018-03-06 19:42:24 +01:00
hash_count : usize ,
2018-07-02 18:50:05 +02:00
marker : PhantomData < C > , // TODO: rpheimer: "we could have the NodeCodec trait take &self to its methods and then we don't need PhantomData. we can just store an instance of C: NodeCodec in the trie struct. If it's a ZST it won't have any additional overhead anyway"
2016-01-06 13:53:23 +01:00
}
2018-07-02 18:50:05 +02:00
impl < ' a , H , C > TrieDBMut < ' a , H , C >
where
H : Hasher ,
C : NodeCodec < H >
{
2016-07-14 18:06:46 +02:00
/// Create a new trie with backing database `db` and empty `root`.
2018-07-02 18:50:05 +02:00
pub fn new ( db : & ' a mut HashDB < H > , root : & ' a mut H ::Out ) -> Self {
* root = C ::HASHED_NULL_NODE ;
let root_handle = NodeHandle ::Hash ( C ::HASHED_NULL_NODE ) ;
2016-01-06 13:53:23 +01:00
2016-07-14 18:06:46 +02:00
TrieDBMut {
storage : NodeStorage ::empty ( ) ,
2016-03-07 14:33:00 +01:00
db : db ,
2015-12-11 03:00:39 +01:00
root : root ,
2016-07-14 18:06:46 +02:00
root_handle : root_handle ,
death_row : HashSet ::new ( ) ,
hash_count : 0 ,
2018-07-02 18:50:05 +02:00
marker : PhantomData ,
2016-07-14 18:06:46 +02:00
}
2015-12-10 15:48:25 +01:00
}
2015-11-29 15:50:33 +01:00
2016-07-14 18:06:46 +02:00
/// Create a new trie with the backing database `db` and `root.
2016-06-07 20:44:09 +02:00
/// Returns an error if `root` does not exist.
2018-07-02 18:50:05 +02:00
pub fn from_existing ( db : & ' a mut HashDB < H > , root : & ' a mut H ::Out ) -> Result < Self , H ::Out , C ::Error > {
2016-06-23 11:16:11 +02:00
if ! db . contains ( root ) {
2016-08-03 18:35:48 +02:00
return Err ( Box ::new ( TrieError ::InvalidStateRoot ( * root ) ) ) ;
2015-12-11 03:00:39 +01:00
}
2016-07-14 18:06:46 +02:00
let root_handle = NodeHandle ::Hash ( * root ) ;
Ok ( TrieDBMut {
storage : NodeStorage ::empty ( ) ,
db : db ,
root : root ,
root_handle : root_handle ,
death_row : HashSet ::new ( ) ,
hash_count : 0 ,
2018-07-02 18:50:05 +02:00
marker : PhantomData ,
2016-07-14 18:06:46 +02:00
} )
}
2015-12-07 15:00:54 +01:00
/// Get the backing database.
2018-07-02 18:50:05 +02:00
pub fn db ( & self ) -> & HashDB < H > {
2016-03-07 14:33:00 +01:00
self . db
2015-12-10 15:48:25 +01:00
}
2015-11-29 15:50:33 +01:00
2016-07-14 18:06:46 +02:00
/// Get the backing database mutably.
2018-07-02 18:50:05 +02:00
pub fn db_mut ( & mut self ) -> & mut HashDB < H > {
2016-03-07 14:33:00 +01:00
self . db
2016-01-26 15:00:22 +01:00
}
2016-07-14 18:06:46 +02:00
// cache a node by hash
2018-07-02 18:50:05 +02:00
fn cache ( & mut self , hash : H ::Out ) -> Result < StorageHandle , H ::Out , C ::Error > {
let node_encoded = self . db . get ( & hash ) . ok_or_else ( | | Box ::new ( TrieError ::IncompleteDatabase ( hash ) ) ) ? ;
2018-07-05 17:15:03 +02:00
let node = Node ::from_encoded ::< C , H > (
2018-07-02 18:50:05 +02:00
& node_encoded ,
& * self . db ,
& mut self . storage
) ;
2016-08-03 18:35:48 +02:00
Ok ( self . storage . alloc ( Stored ::Cached ( node , hash ) ) )
2015-12-03 14:56:39 +01:00
}
2016-07-14 18:06:46 +02:00
// inspect a node, choosing either to replace, restore, or delete it.
// if restored or replaced, returns the new node along with a flag of whether it was changed.
2018-07-05 17:15:03 +02:00
fn inspect < F > ( & mut self , stored : Stored < H ::Out > , inspector : F ) -> Result < Option < ( Stored < H ::Out > , bool ) > , H ::Out , C ::Error >
where F : FnOnce ( & mut Self , Node < H ::Out > ) -> Result < Action < H ::Out > , H ::Out , C ::Error > {
2016-08-03 18:35:48 +02:00
Ok ( match stored {
2016-12-27 12:53:56 +01:00
Stored ::New ( node ) = > match inspector ( self , node ) ? {
2016-07-14 18:06:46 +02:00
Action ::Restore ( node ) = > Some ( ( Stored ::New ( node ) , false ) ) ,
Action ::Replace ( node ) = > Some ( ( Stored ::New ( node ) , true ) ) ,
Action ::Delete = > None ,
} ,
2016-12-27 12:53:56 +01:00
Stored ::Cached ( node , hash ) = > match inspector ( self , node ) ? {
2016-07-14 18:06:46 +02:00
Action ::Restore ( node ) = > Some ( ( Stored ::Cached ( node , hash ) , false ) ) ,
Action ::Replace ( node ) = > {
self . death_row . insert ( hash ) ;
Some ( ( Stored ::New ( node ) , true ) )
}
Action ::Delete = > {
self . death_row . insert ( hash ) ;
None
}
} ,
2016-08-03 18:35:48 +02:00
} )
2015-12-01 19:19:16 +01:00
}
2016-07-14 18:06:46 +02:00
// walk the trie, attempting to find the key's node.
2018-07-05 17:15:03 +02:00
fn lookup < ' x , ' key > ( & ' x self , mut partial : NibbleSlice < ' key > , handle : & NodeHandle < H ::Out > ) -> Result < Option < DBValue > , H ::Out , C ::Error >
2016-08-03 18:35:48 +02:00
where ' x : ' key
{
2017-08-27 17:33:03 +02:00
let mut handle = handle ;
loop {
2017-08-29 12:31:40 +02:00
let ( mid , child ) = match * handle {
2018-07-02 18:50:05 +02:00
NodeHandle ::Hash ( ref hash ) = > return Lookup {
2017-08-29 12:31:40 +02:00
db : & * self . db ,
query : DBValue ::from_slice ,
hash : hash . clone ( ) ,
2018-07-02 18:50:05 +02:00
marker : PhantomData ::< C > ,
2017-08-29 12:31:40 +02:00
} . look_up ( partial ) ,
NodeHandle ::InMemory ( ref handle ) = > match self . storage [ handle ] {
Node ::Empty = > return Ok ( None ) ,
Node ::Leaf ( ref key , ref value ) = > {
if NibbleSlice ::from_encoded ( key ) . 0 = = partial {
return Ok ( Some ( DBValue ::from_slice ( value ) ) ) ;
} else {
return Ok ( None ) ;
2017-08-27 17:33:03 +02:00
}
2017-08-29 12:31:40 +02:00
}
Node ::Extension ( ref slice , ref child ) = > {
let slice = NibbleSlice ::from_encoded ( slice ) . 0 ;
if partial . starts_with ( & slice ) {
( slice . len ( ) , child )
} else {
return Ok ( None ) ;
2017-08-27 17:33:03 +02:00
}
2017-08-29 12:31:40 +02:00
}
Node ::Branch ( ref children , ref value ) = > {
if partial . is_empty ( ) {
return Ok ( value . as_ref ( ) . map ( | v | DBValue ::from_slice ( v ) ) ) ;
} else {
let idx = partial . at ( 0 ) ;
match children [ idx as usize ] . as_ref ( ) {
Some ( child ) = > ( 1 , child ) ,
None = > return Ok ( None ) ,
2017-08-27 17:33:03 +02:00
}
2016-08-03 18:35:48 +02:00
}
2015-12-01 19:19:16 +01:00
}
2015-12-01 18:25:47 +01:00
}
2017-08-27 17:33:03 +02:00
} ;
2017-08-29 12:31:40 +02:00
partial = partial . mid ( mid ) ;
handle = child ;
2016-07-14 18:06:46 +02:00
}
2015-12-01 18:25:47 +01:00
}
2018-07-02 18:50:05 +02:00
/// insert a key-value pair into the trie, creating new nodes if necessary.
2018-07-05 17:15:03 +02:00
fn insert_at ( & mut self , handle : NodeHandle < H ::Out > , partial : NibbleSlice , value : DBValue , old_val : & mut Option < DBValue > ) -> Result < ( StorageHandle , bool ) , H ::Out , C ::Error > {
2016-07-14 18:06:46 +02:00
let h = match handle {
NodeHandle ::InMemory ( h ) = > h ,
2016-12-27 12:53:56 +01:00
NodeHandle ::Hash ( h ) = > self . cache ( h ) ? ,
2016-07-14 18:06:46 +02:00
} ;
let stored = self . storage . destroy ( h ) ;
2016-12-27 12:53:56 +01:00
let ( new_stored , changed ) = self . inspect ( stored , move | trie , stored | {
2017-01-05 21:15:43 +01:00
trie . insert_inspector ( stored , partial , value , old_val ) . map ( | a | a . into_action ( ) )
2016-12-27 12:53:56 +01:00
} ) ? . expect ( " Insertion never deletes. " ) ;
2015-12-01 01:32:10 +01:00
2016-08-03 18:35:48 +02:00
Ok ( ( self . storage . alloc ( new_stored ) , changed ) )
2015-12-02 15:03:20 +01:00
}
2016-07-14 18:06:46 +02:00
/// the insertion inspector.
2018-07-05 17:15:03 +02:00
fn insert_inspector ( & mut self , node : Node < H ::Out > , partial : NibbleSlice , value : DBValue , old_val : & mut Option < DBValue > ) -> Result < InsertAction < H ::Out > , H ::Out , C ::Error > {
2016-07-14 18:06:46 +02:00
trace! ( target : " trie " , " augmented (partial: {:?}, value: {:?}) " , partial , value . pretty ( ) ) ;
2015-12-01 01:32:10 +01:00
2016-08-03 18:35:48 +02:00
Ok ( match node {
2016-07-14 18:06:46 +02:00
Node ::Empty = > {
trace! ( target : " trie " , " empty: COMPOSE " ) ;
InsertAction ::Replace ( Node ::Leaf ( partial . encoded ( true ) , value ) )
}
Node ::Branch ( mut children , stored_value ) = > {
trace! ( target : " trie " , " branch: ROUTE,AUGMENT " ) ;
if partial . is_empty ( ) {
let unchanged = stored_value . as_ref ( ) = = Some ( & value ) ;
let branch = Node ::Branch ( children , Some ( value ) ) ;
2017-01-05 21:15:43 +01:00
* old_val = stored_value ;
2016-07-14 18:06:46 +02:00
match unchanged {
true = > InsertAction ::Restore ( branch ) ,
false = > InsertAction ::Replace ( branch ) ,
}
} else {
let idx = partial . at ( 0 ) as usize ;
let partial = partial . mid ( 1 ) ;
if let Some ( child ) = children [ idx ] . take ( ) {
// original had something there. recurse down into it.
2017-01-05 21:15:43 +01:00
let ( new_child , changed ) = self . insert_at ( child , partial , value , old_val ) ? ;
2016-07-14 18:06:46 +02:00
children [ idx ] = Some ( new_child . into ( ) ) ;
if ! changed {
// the new node we composed didn't change. that means our branch is untouched too.
2016-08-03 18:35:48 +02:00
return Ok ( InsertAction ::Restore ( Node ::Branch ( children , stored_value ) ) ) ;
2016-07-14 18:06:46 +02:00
}
} else {
// original had nothing there. compose a leaf.
let leaf = self . storage . alloc ( Stored ::New ( Node ::Leaf ( partial . encoded ( true ) , value ) ) ) ;
children [ idx ] = Some ( leaf . into ( ) ) ;
}
2015-12-01 01:32:10 +01:00
2016-07-14 18:06:46 +02:00
InsertAction ::Replace ( Node ::Branch ( children , stored_value ) )
}
}
Node ::Leaf ( encoded , stored_value ) = > {
let existing_key = NibbleSlice ::from_encoded ( & encoded ) . 0 ;
let cp = partial . common_prefix ( & existing_key ) ;
if cp = = existing_key . len ( ) & & cp = = partial . len ( ) {
trace! ( target : " trie " , " equivalent-leaf: REPLACE " ) ;
// equivalent leaf.
2017-01-05 21:15:43 +01:00
let unchanged = stored_value = = value ;
* old_val = Some ( stored_value ) ;
match unchanged {
2016-07-14 18:06:46 +02:00
// unchanged. restore
true = > InsertAction ::Restore ( Node ::Leaf ( encoded . clone ( ) , value ) ) ,
false = > InsertAction ::Replace ( Node ::Leaf ( encoded . clone ( ) , value ) ) ,
}
} else if cp = = 0 {
trace! ( target : " trie " , " no-common-prefix, not-both-empty (exist={:?}; new={:?}): TRANSMUTE,AUGMENT " , existing_key . len ( ) , partial . len ( ) ) ;
// one of us isn't empty: transmute to branch here
let mut children = empty_children ( ) ;
let branch = if existing_key . is_empty ( ) {
// always replace since branch isn't leaf.
Node ::Branch ( children , Some ( stored_value ) )
} else {
let idx = existing_key . at ( 0 ) as usize ;
let new_leaf = Node ::Leaf ( existing_key . mid ( 1 ) . encoded ( true ) , stored_value ) ;
children [ idx ] = Some ( self . storage . alloc ( Stored ::New ( new_leaf ) ) . into ( ) ) ;
Node ::Branch ( children , None )
} ;
// always replace because whatever we get out here is not the branch we started with.
2017-01-05 21:15:43 +01:00
let branch_action = self . insert_inspector ( branch , partial , value , old_val ) ? . unwrap_node ( ) ;
2016-08-03 18:35:48 +02:00
InsertAction ::Replace ( branch_action )
2016-07-14 18:06:46 +02:00
} else if cp = = existing_key . len ( ) {
trace! ( target : " trie " , " complete-prefix (cp={:?}): AUGMENT-AT-END " , cp ) ;
// fully-shared prefix for an extension.
// make a stub branch and an extension.
let branch = Node ::Branch ( empty_children ( ) , Some ( stored_value ) ) ;
// augment the new branch.
2017-01-05 21:15:43 +01:00
let branch = self . insert_inspector ( branch , partial . mid ( cp ) , value , old_val ) ? . unwrap_node ( ) ;
2016-07-14 18:06:46 +02:00
// always replace since we took a leaf and made an extension.
let branch_handle = self . storage . alloc ( Stored ::New ( branch ) ) . into ( ) ;
InsertAction ::Replace ( Node ::Extension ( existing_key . encoded ( false ) , branch_handle ) )
} else {
trace! ( target : " trie " , " partially-shared-prefix (exist={:?}; new={:?}; cp={:?}): AUGMENT-AT-END " , existing_key . len ( ) , partial . len ( ) , cp ) ;
// partially-shared prefix for an extension.
// start by making a leaf.
let low = Node ::Leaf ( existing_key . mid ( cp ) . encoded ( true ) , stored_value ) ;
2017-01-05 21:15:43 +01:00
2016-07-14 18:06:46 +02:00
// augment it. this will result in the Leaf -> cp == 0 routine,
// which creates a branch.
2017-01-05 21:15:43 +01:00
let augmented_low = self . insert_inspector ( low , partial . mid ( cp ) , value , old_val ) ? . unwrap_node ( ) ;
2016-07-14 18:06:46 +02:00
// make an extension using it. this is a replacement.
InsertAction ::Replace ( Node ::Extension (
existing_key . encoded_leftmost ( cp , false ) ,
self . storage . alloc ( Stored ::New ( augmented_low ) ) . into ( )
) )
}
}
Node ::Extension ( encoded , child_branch ) = > {
let existing_key = NibbleSlice ::from_encoded ( & encoded ) . 0 ;
let cp = partial . common_prefix ( & existing_key ) ;
if cp = = 0 {
trace! ( target : " trie " , " no-common-prefix, not-both-empty (exist={:?}; new={:?}): TRANSMUTE,AUGMENT " , existing_key . len ( ) , partial . len ( ) ) ;
// partial isn't empty: make a branch here
// extensions may not have empty partial keys.
assert! ( ! existing_key . is_empty ( ) ) ;
let idx = existing_key . at ( 0 ) as usize ;
let mut children = empty_children ( ) ;
children [ idx ] = if existing_key . len ( ) = = 1 {
// direct extension, just replace.
Some ( child_branch )
} else {
// more work required after branching.
let ext = Node ::Extension ( existing_key . mid ( 1 ) . encoded ( false ) , child_branch ) ;
Some ( self . storage . alloc ( Stored ::New ( ext ) ) . into ( ) )
} ;
// continue inserting.
2017-01-05 21:15:43 +01:00
let branch_action = self . insert_inspector ( Node ::Branch ( children , None ) , partial , value , old_val ) ? . unwrap_node ( ) ;
2016-08-03 18:35:48 +02:00
InsertAction ::Replace ( branch_action )
2016-07-14 18:06:46 +02:00
} else if cp = = existing_key . len ( ) {
trace! ( target : " trie " , " complete-prefix (cp={:?}): AUGMENT-AT-END " , cp ) ;
// fully-shared prefix.
// insert into the child node.
2017-01-05 21:15:43 +01:00
let ( new_child , changed ) = self . insert_at ( child_branch , partial . mid ( cp ) , value , old_val ) ? ;
2016-07-14 18:06:46 +02:00
let new_ext = Node ::Extension ( existing_key . encoded ( false ) , new_child . into ( ) ) ;
// if the child branch wasn't changed, meaning this extension remains the same.
match changed {
true = > InsertAction ::Replace ( new_ext ) ,
false = > InsertAction ::Restore ( new_ext ) ,
}
} else {
trace! ( target : " trie " , " partially-shared-prefix (exist={:?}; new={:?}; cp={:?}): AUGMENT-AT-END " , existing_key . len ( ) , partial . len ( ) , cp ) ;
// partially-shared.
let low = Node ::Extension ( existing_key . mid ( cp ) . encoded ( false ) , child_branch ) ;
// augment the extension. this will take the cp == 0 path, creating a branch.
2017-01-05 21:15:43 +01:00
let augmented_low = self . insert_inspector ( low , partial . mid ( cp ) , value , old_val ) ? . unwrap_node ( ) ;
2016-07-14 18:06:46 +02:00
// always replace, since this extension is not the one we started with.
// this is known because the partial key is only the common prefix.
InsertAction ::Replace ( Node ::Extension (
existing_key . encoded_leftmost ( cp , false ) ,
self . storage . alloc ( Stored ::New ( augmented_low ) ) . into ( )
) )
}
}
2016-08-03 18:35:48 +02:00
} )
2015-12-01 20:24:47 +01:00
}
2016-07-14 18:06:46 +02:00
/// Remove a node from the trie based on key.
2018-07-05 17:15:03 +02:00
fn remove_at ( & mut self , handle : NodeHandle < H ::Out > , partial : NibbleSlice , old_val : & mut Option < DBValue > ) -> Result < Option < ( StorageHandle , bool ) > , H ::Out , C ::Error > {
2016-07-14 18:06:46 +02:00
let stored = match handle {
NodeHandle ::InMemory ( h ) = > self . storage . destroy ( h ) ,
NodeHandle ::Hash ( h ) = > {
2016-12-27 12:53:56 +01:00
let handle = self . cache ( h ) ? ;
2016-07-14 18:06:46 +02:00
self . storage . destroy ( handle )
}
} ;
2015-12-01 01:12:06 +01:00
2017-01-05 21:15:43 +01:00
let opt = self . inspect ( stored , move | trie , node | trie . remove_inspector ( node , partial , old_val ) ) ? ;
2016-08-03 18:35:48 +02:00
Ok ( opt . map ( | ( new , changed ) | ( self . storage . alloc ( new ) , changed ) ) )
2015-11-30 02:57:02 +01:00
}
2015-12-01 01:12:06 +01:00
2016-07-14 18:06:46 +02:00
/// the removal inspector
2018-07-05 17:15:03 +02:00
fn remove_inspector ( & mut self , node : Node < H ::Out > , partial : NibbleSlice , old_val : & mut Option < DBValue > ) -> Result < Action < H ::Out > , H ::Out , C ::Error > {
2016-08-03 18:35:48 +02:00
Ok ( match ( node , partial . is_empty ( ) ) {
2016-07-14 18:06:46 +02:00
( Node ::Empty , _ ) = > Action ::Delete ,
( Node ::Branch ( c , None ) , true ) = > Action ::Restore ( Node ::Branch ( c , None ) ) ,
2017-01-05 21:15:43 +01:00
( Node ::Branch ( children , Some ( val ) ) , true ) = > {
* old_val = Some ( val ) ;
2016-07-14 18:06:46 +02:00
// always replace since we took the value out.
2016-12-27 12:53:56 +01:00
Action ::Replace ( self . fix ( Node ::Branch ( children , None ) ) ? )
2016-07-14 18:06:46 +02:00
}
( Node ::Branch ( mut children , value ) , false ) = > {
let idx = partial . at ( 0 ) as usize ;
if let Some ( child ) = children [ idx ] . take ( ) {
trace! ( target : " trie " , " removing value out of branch child, partial={:?} " , partial ) ;
2017-01-05 21:15:43 +01:00
match self . remove_at ( child , partial . mid ( 1 ) , old_val ) ? {
2016-07-14 18:06:46 +02:00
Some ( ( new , changed ) ) = > {
children [ idx ] = Some ( new . into ( ) ) ;
let branch = Node ::Branch ( children , value ) ;
match changed {
// child was changed, so we were too.
true = > Action ::Replace ( branch ) ,
// unchanged, so we are too.
false = > Action ::Restore ( branch ) ,
}
}
None = > {
// the child we took was deleted.
// the node may need fixing.
trace! ( target : " trie " , " branch child deleted, partial={:?} " , partial ) ;
2016-12-27 12:53:56 +01:00
Action ::Replace ( self . fix ( Node ::Branch ( children , value ) ) ? )
2015-12-07 15:00:54 +01:00
}
}
2016-07-14 18:06:46 +02:00
} else {
// no change needed.
Action ::Restore ( Node ::Branch ( children , value ) )
2015-12-07 15:00:54 +01:00
}
2016-07-14 18:06:46 +02:00
}
( Node ::Leaf ( encoded , value ) , _ ) = > {
if NibbleSlice ::from_encoded ( & encoded ) . 0 = = partial {
// this is the node we were looking for. Let's delete it.
2017-01-05 21:15:43 +01:00
* old_val = Some ( value ) ;
2016-07-14 18:06:46 +02:00
Action ::Delete
} else {
// leaf the node alone.
trace! ( target : " trie " , " restoring leaf wrong partial, partial={:?}, existing={:?} " , partial , NibbleSlice ::from_encoded ( & encoded ) . 0 ) ;
Action ::Restore ( Node ::Leaf ( encoded , value ) )
2015-12-01 02:23:53 +01:00
}
2016-07-14 18:06:46 +02:00
}
( Node ::Extension ( encoded , child_branch ) , _ ) = > {
let ( cp , existing_len ) = {
let existing_key = NibbleSlice ::from_encoded ( & encoded ) . 0 ;
( existing_key . common_prefix ( & partial ) , existing_key . len ( ) )
} ;
if cp = = existing_len {
// try to remove from the child branch.
trace! ( target : " trie " , " removing from extension child, partial={:?} " , partial ) ;
2017-01-05 21:15:43 +01:00
match self . remove_at ( child_branch , partial . mid ( cp ) , old_val ) ? {
2016-07-14 18:06:46 +02:00
Some ( ( new_child , changed ) ) = > {
let new_child = new_child . into ( ) ;
// if the child branch was unchanged, then the extension is too.
// otherwise, this extension may need fixing.
match changed {
2016-12-27 12:53:56 +01:00
true = > Action ::Replace ( self . fix ( Node ::Extension ( encoded , new_child ) ) ? ) ,
2016-07-14 18:06:46 +02:00
false = > Action ::Restore ( Node ::Extension ( encoded , new_child ) ) ,
}
}
None = > {
// the whole branch got deleted.
// that means that this extension is useless.
Action ::Delete
}
2015-12-02 22:59:00 +01:00
}
2016-07-14 18:06:46 +02:00
} else {
// partway through an extension -- nothing to do here.
Action ::Restore ( Node ::Extension ( encoded , child_branch ) )
2015-12-02 22:59:00 +01:00
}
}
2016-08-03 18:35:48 +02:00
} )
2015-12-02 22:59:00 +01:00
}
2016-07-14 18:06:46 +02:00
/// Given a node which may be in an _invalid state_, fix it such that it is then in a valid
2015-12-02 22:59:00 +01:00
/// state.
///
/// _invalid state_ means:
/// - Branch node where there is only a single entry;
/// - Extension node followed by anything other than a Branch node.
2018-07-05 17:15:03 +02:00
fn fix ( & mut self , node : Node < H ::Out > ) -> Result < Node < H ::Out > , H ::Out , C ::Error > {
2016-07-14 18:06:46 +02:00
match node {
Node ::Branch ( mut children , value ) = > {
2015-12-02 22:59:00 +01:00
// if only a single value, transmute to leaf/extension and feed through fixed.
2015-12-03 00:32:58 +01:00
#[ derive(Debug) ]
enum UsedIndex {
None ,
2015-12-03 00:50:14 +01:00
One ( u8 ) ,
2015-12-03 00:32:58 +01:00
Many ,
} ;
let mut used_index = UsedIndex ::None ;
2015-12-02 22:59:00 +01:00
for i in 0 .. 16 {
2016-07-14 18:06:46 +02:00
match ( children [ i ] . is_none ( ) , & used_index ) {
2015-12-03 00:50:14 +01:00
( false , & UsedIndex ::None ) = > used_index = UsedIndex ::One ( i as u8 ) ,
2016-07-14 18:06:46 +02:00
( false , & UsedIndex ::One ( _ ) ) = > {
used_index = UsedIndex ::Many ;
break ;
}
_ = > continue ,
2015-12-02 22:59:00 +01:00
}
}
2016-07-14 18:06:46 +02:00
match ( used_index , value ) {
2015-12-03 00:32:58 +01:00
( UsedIndex ::None , None ) = > panic! ( " Branch with no subvalues. Something went wrong. " ) ,
2016-07-14 18:06:46 +02:00
( UsedIndex ::One ( a ) , None ) = > {
// only one onward node. make an extension.
let new_partial = NibbleSlice ::new_offset ( & [ a ] , 1 ) . encoded ( false ) ;
2016-10-25 22:34:52 +02:00
let child = children [ a as usize ] . take ( ) . expect ( " used_index only set if occupied; qed " ) ;
let new_node = Node ::Extension ( new_partial , child ) ;
2016-07-14 18:06:46 +02:00
self . fix ( new_node )
}
( UsedIndex ::None , Some ( value ) ) = > {
// make a leaf.
trace! ( target : " trie " , " fixing: branch -> leaf " ) ;
2016-08-03 18:35:48 +02:00
Ok ( Node ::Leaf ( NibbleSlice ::new ( & [ ] ) . encoded ( true ) , value ) )
2016-07-14 18:06:46 +02:00
}
( _ , value ) = > {
// all is well.
trace! ( target : " trie " , " fixing: restoring branch " ) ;
2016-08-03 18:35:48 +02:00
Ok ( Node ::Branch ( children , value ) )
2015-12-02 22:59:00 +01:00
}
}
2016-07-14 18:06:46 +02:00
}
Node ::Extension ( partial , child ) = > {
let stored = match child {
NodeHandle ::InMemory ( h ) = > self . storage . destroy ( h ) ,
NodeHandle ::Hash ( h ) = > {
2016-12-27 12:53:56 +01:00
let handle = self . cache ( h ) ? ;
2016-07-14 18:06:46 +02:00
self . storage . destroy ( handle )
}
} ;
let ( child_node , maybe_hash ) = match stored {
Stored ::New ( node ) = > ( node , None ) ,
Stored ::Cached ( node , hash ) = > ( node , Some ( hash ) )
} ;
match child_node {
Node ::Extension ( sub_partial , sub_child ) = > {
// combine with node below.
if let Some ( hash ) = maybe_hash {
// delete the cached child since we are going to replace it.
self . death_row . insert ( hash ) ;
}
let partial = NibbleSlice ::from_encoded ( & partial ) . 0 ;
let sub_partial = NibbleSlice ::from_encoded ( & sub_partial ) . 0 ;
let new_partial = NibbleSlice ::new_composed ( & partial , & sub_partial ) ;
trace! ( target : " trie " , " fixing: extension combination. new_partial={:?} " , new_partial ) ;
self . fix ( Node ::Extension ( new_partial . encoded ( false ) , sub_child ) )
}
Node ::Leaf ( sub_partial , value ) = > {
// combine with node below.
if let Some ( hash ) = maybe_hash {
// delete the cached child since we are going to replace it.
self . death_row . insert ( hash ) ;
}
let partial = NibbleSlice ::from_encoded ( & partial ) . 0 ;
let sub_partial = NibbleSlice ::from_encoded ( & sub_partial ) . 0 ;
let new_partial = NibbleSlice ::new_composed ( & partial , & sub_partial ) ;
trace! ( target : " trie " , " fixing: extension -> leaf. new_partial={:?} " , new_partial ) ;
2016-08-03 18:35:48 +02:00
Ok ( Node ::Leaf ( new_partial . encoded ( true ) , value ) )
2016-07-14 18:06:46 +02:00
}
child_node = > {
trace! ( target : " trie " , " fixing: restoring extension " ) ;
// reallocate the child node.
let stored = if let Some ( hash ) = maybe_hash {
Stored ::Cached ( child_node , hash )
} else {
Stored ::New ( child_node )
} ;
2016-08-03 18:35:48 +02:00
Ok ( Node ::Extension ( partial , self . storage . alloc ( stored ) . into ( ) ) )
2016-07-14 18:06:46 +02:00
}
2015-12-02 22:59:00 +01:00
}
2016-07-14 18:06:46 +02:00
}
2016-08-03 18:35:48 +02:00
other = > Ok ( other ) , // only ext and branch need fixing.
2015-12-02 22:59:00 +01:00
}
}
2015-12-02 15:03:20 +01:00
2016-07-14 18:06:46 +02:00
/// Commit the in-memory changes to disk, freeing their storage and
/// updating the state root.
pub fn commit ( & mut self ) {
trace! ( target : " trie " , " Committing trie changes to db. " ) ;
2016-08-31 14:28:56 +02:00
// always kill all the nodes on death row.
2016-07-14 18:06:46 +02:00
trace! ( target : " trie " , " {:?} nodes to remove from db " , self . death_row . len ( ) ) ;
for hash in self . death_row . drain ( ) {
self . db . remove ( & hash ) ;
}
2016-08-31 14:28:56 +02:00
let handle = match self . root_handle ( ) {
NodeHandle ::Hash ( _ ) = > return , // no changes necessary.
NodeHandle ::InMemory ( h ) = > h ,
} ;
2016-07-14 18:06:46 +02:00
match self . storage . destroy ( handle ) {
Stored ::New ( node ) = > {
2018-07-05 17:15:03 +02:00
let encoded_root = node . into_encoded ::< _ , C , H > ( | child | self . commit_child ( child ) ) ;
2018-07-02 18:50:05 +02:00
* self . root = self . db . insert ( & encoded_root [ .. ] ) ;
2016-07-14 18:06:46 +02:00
self . hash_count + = 1 ;
2018-07-02 18:50:05 +02:00
trace! ( target : " trie " , " encoded root node: {:?} " , ( & encoded_root [ .. ] ) . pretty ( ) ) ;
2016-07-14 18:06:46 +02:00
self . root_handle = NodeHandle ::Hash ( * self . root ) ;
}
Stored ::Cached ( node , hash ) = > {
// probably won't happen, but update the root and move on.
* self . root = hash ;
self . root_handle = NodeHandle ::InMemory ( self . storage . alloc ( Stored ::Cached ( node , hash ) ) ) ;
}
}
2015-12-02 22:59:00 +01:00
}
2015-12-02 15:03:20 +01:00
2018-07-02 18:50:05 +02:00
/// Commit a node by hashing it and writing it to the db. Returns a
/// `ChildReference` which in most cases carries a normal hash but for the
/// case where we can fit the actual data in the `Hasher`s output type, we
/// store the data inline. This function is used as the callback to the
/// `into_encoded` method of `Node`.
2018-07-05 17:15:03 +02:00
fn commit_child ( & mut self , handle : NodeHandle < H ::Out > ) -> ChildReference < H ::Out > {
2016-07-14 18:06:46 +02:00
match handle {
2018-07-02 18:50:05 +02:00
NodeHandle ::Hash ( hash ) = > ChildReference ::Hash ( hash ) ,
NodeHandle ::InMemory ( storage_handle ) = > {
match self . storage . destroy ( storage_handle ) {
Stored ::Cached ( _ , hash ) = > ChildReference ::Hash ( hash ) ,
Stored ::New ( node ) = > {
2018-07-05 17:15:03 +02:00
let encoded = node . into_encoded ::< _ , C , H > ( | node_handle | self . commit_child ( node_handle ) ) ;
2018-07-02 18:50:05 +02:00
if encoded . len ( ) > = H ::LENGTH {
let hash = self . db . insert ( & encoded [ .. ] ) ;
self . hash_count + = 1 ;
ChildReference ::Hash ( hash )
} else {
// it's a small value, so we cram it into a `H::Out` and tag with length
let mut h = H ::Out ::default ( ) ;
let len = encoded . len ( ) ;
h . as_mut ( ) [ .. len ] . copy_from_slice ( & encoded [ .. len ] ) ;
ChildReference ::Inline ( h , len )
}
2016-07-14 18:06:46 +02:00
}
2015-12-02 22:59:00 +01:00
}
2016-07-14 18:06:46 +02:00
}
2018-07-02 18:50:05 +02:00
}
2016-07-14 18:06:46 +02:00
}
// a hack to get the root node's handle
2018-07-05 17:15:03 +02:00
fn root_handle ( & self ) -> NodeHandle < H ::Out > {
2016-07-14 18:06:46 +02:00
match self . root_handle {
NodeHandle ::Hash ( h ) = > NodeHandle ::Hash ( h ) ,
NodeHandle ::InMemory ( StorageHandle ( x ) ) = > NodeHandle ::InMemory ( StorageHandle ( x ) ) ,
2015-12-02 22:59:00 +01:00
}
2015-12-02 15:03:20 +01:00
}
2015-11-29 15:50:33 +01:00
}
2018-07-02 18:50:05 +02:00
impl < ' a , H , C > TrieMut < H , C > for TrieDBMut < ' a , H , C >
2018-07-05 17:15:03 +02:00
where
2018-07-02 18:50:05 +02:00
H : Hasher ,
C : NodeCodec < H >
{
fn root ( & mut self ) -> & H ::Out {
2016-07-14 18:06:46 +02:00
self . commit ( ) ;
2016-07-26 20:31:25 +02:00
self . root
2016-07-14 18:06:46 +02:00
}
2015-11-29 18:45:41 +01:00
2016-07-14 18:06:46 +02:00
fn is_empty ( & self ) -> bool {
match self . root_handle {
2018-07-02 18:50:05 +02:00
NodeHandle ::Hash ( h ) = > h = = C ::HASHED_NULL_NODE ,
2016-07-14 18:06:46 +02:00
NodeHandle ::InMemory ( ref h ) = > match self . storage [ h ] {
Node ::Empty = > true ,
_ = > false ,
}
}
}
2018-07-02 18:50:05 +02:00
fn get < ' x , ' key > ( & ' x self , key : & ' key [ u8 ] ) -> Result < Option < DBValue > , H ::Out , C ::Error >
where ' x : ' key
{
2016-07-14 18:06:46 +02:00
self . lookup ( NibbleSlice ::new ( key ) , & self . root_handle )
2015-11-29 18:45:41 +01:00
}
2018-07-02 18:50:05 +02:00
fn insert ( & mut self , key : & [ u8 ] , value : & [ u8 ] ) -> Result < Option < DBValue > , H ::Out , C ::Error > {
2017-01-05 21:15:43 +01:00
if value . is_empty ( ) { return self . remove ( key ) }
let mut old_val = None ;
2016-07-14 18:06:46 +02:00
2016-08-31 14:28:56 +02:00
trace! ( target : " trie " , " insert: key={:?}, value={:?} " , key . pretty ( ) , value . pretty ( ) ) ;
2016-07-14 18:06:46 +02:00
let root_handle = self . root_handle ( ) ;
2017-01-05 21:15:43 +01:00
let ( new_handle , changed ) = self . insert_at (
root_handle ,
NibbleSlice ::new ( key ) ,
DBValue ::from_slice ( value ) ,
& mut old_val ,
) ? ;
2016-08-31 14:28:56 +02:00
trace! ( target : " trie " , " insert: altered trie={} " , changed ) ;
2016-07-14 18:06:46 +02:00
self . root_handle = NodeHandle ::InMemory ( new_handle ) ;
2016-08-03 18:35:48 +02:00
2017-01-05 21:15:43 +01:00
Ok ( old_val )
2015-11-29 18:45:41 +01:00
}
2018-07-02 18:50:05 +02:00
fn remove ( & mut self , key : & [ u8 ] ) -> Result < Option < DBValue > , H ::Out , C ::Error > {
2016-08-31 14:28:56 +02:00
trace! ( target : " trie " , " remove: key={:?} " , key . pretty ( ) ) ;
2016-07-14 18:06:46 +02:00
let root_handle = self . root_handle ( ) ;
let key = NibbleSlice ::new ( key ) ;
2017-01-05 21:15:43 +01:00
let mut old_val = None ;
match self . remove_at ( root_handle , key , & mut old_val ) ? {
2016-08-31 14:28:56 +02:00
Some ( ( handle , changed ) ) = > {
trace! ( target : " trie " , " remove: altered trie={} " , changed ) ;
2016-07-14 18:06:46 +02:00
self . root_handle = NodeHandle ::InMemory ( handle ) ;
}
None = > {
2016-08-31 14:28:56 +02:00
trace! ( target : " trie " , " remove: obliterated trie " ) ;
2018-07-02 18:50:05 +02:00
self . root_handle = NodeHandle ::Hash ( C ::HASHED_NULL_NODE ) ;
* self . root = C ::HASHED_NULL_NODE ;
2016-07-14 18:06:46 +02:00
}
2017-01-05 21:15:43 +01:00
}
2016-08-03 18:35:48 +02:00
2017-01-05 21:15:43 +01:00
Ok ( old_val )
2015-12-07 15:00:54 +01:00
}
}
2018-07-02 18:50:05 +02:00
impl < ' a , H , C > Drop for TrieDBMut < ' a , H , C >
where
H : Hasher ,
C : NodeCodec < H >
{
2016-07-14 18:06:46 +02:00
fn drop ( & mut self ) {
self . commit ( ) ;
2015-11-29 18:45:41 +01:00
}
2015-11-29 15:50:33 +01:00
}
2015-12-01 03:35:55 +01:00
#[ cfg(test) ]
mod tests {
2016-02-27 15:49:44 +01:00
use bytes ::ToPretty ;
2018-07-02 18:50:05 +02:00
use hashdb ::{ DBValue , Hasher , HashDB } ;
use keccak_hasher ::KeccakHasher ;
use memorydb ::MemoryDB ;
use rlp ::{ Decodable , Encodable } ;
use triehash ::trie_root ;
2018-02-19 12:03:54 +01:00
use standardmap ::* ;
2018-07-02 18:50:05 +02:00
use ethtrie ::{ TrieDBMut , RlpCodec , trie ::{ TrieMut , NodeCodec } } ;
use env_logger ;
use ethereum_types ::H256 ;
2015-12-03 18:42:51 +01:00
2018-07-02 18:50:05 +02:00
fn populate_trie < ' db , H , C > ( db : & ' db mut HashDB < KeccakHasher > , root : & ' db mut H256 , v : & [ ( Vec < u8 > , Vec < u8 > ) ] ) -> TrieDBMut < ' db >
where H : Hasher , H ::Out : Decodable + Encodable , C : NodeCodec < H >
{
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( db , root ) ;
2015-12-03 18:42:51 +01:00
for i in 0 .. v . len ( ) {
let key : & [ u8 ] = & v [ i ] . 0 ;
let val : & [ u8 ] = & v [ i ] . 1 ;
2016-08-03 18:35:48 +02:00
t . insert ( key , val ) . unwrap ( ) ;
2015-12-03 18:42:51 +01:00
}
t
}
2016-01-19 13:47:30 +01:00
fn unpopulate_trie < ' db > ( t : & mut TrieDBMut < ' db > , v : & [ ( Vec < u8 > , Vec < u8 > ) ] ) {
for i in v {
2015-12-03 18:42:51 +01:00
let key : & [ u8 ] = & i . 0 ;
2016-08-03 18:35:48 +02:00
t . remove ( key ) . unwrap ( ) ;
2015-12-03 18:42:51 +01:00
}
}
2015-12-01 01:44:18 +01:00
2015-12-02 22:59:00 +01:00
#[ test ]
fn playpen ( ) {
2018-07-02 18:50:05 +02:00
env_logger ::init ( ) ;
2016-02-27 15:49:44 +01:00
let mut seed = H256 ::new ( ) ;
2016-07-14 18:06:46 +02:00
for test_i in 0 .. 10 {
2015-12-04 18:05:59 +01:00
if test_i % 50 = = 0 {
debug! ( " {:?} of 10000 stress tests done " , test_i ) ;
}
2016-02-27 15:49:44 +01:00
let x = StandardMap {
2017-06-28 16:41:08 +02:00
alphabet : Alphabet ::Custom ( b " @QWERTYUIOPASDFGHJKLZXCVBNM[/]^_ " . to_vec ( ) ) ,
2016-02-27 15:49:44 +01:00
min_key : 5 ,
journal_key : 0 ,
value_mode : ValueMode ::Index ,
count : 100 ,
} . make_with ( & mut seed ) ;
2015-12-02 22:59:00 +01:00
2015-12-03 18:42:51 +01:00
let real = trie_root ( x . clone ( ) ) ;
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2018-07-02 18:50:05 +02:00
let mut memtrie = populate_trie ::< _ , RlpCodec > ( & mut memdb , & mut root , & x ) ;
2016-07-14 18:06:46 +02:00
memtrie . commit ( ) ;
if * memtrie . root ( ) ! = real {
2015-12-03 18:42:51 +01:00
println! ( " TRIE MISMATCH " ) ;
println! ( " " ) ;
println! ( " {:?} vs {:?} " , memtrie . root ( ) , real ) ;
2016-01-19 13:47:30 +01:00
for i in & x {
2015-12-03 18:42:51 +01:00
println! ( " {:?} -> {:?} " , i . 0. pretty ( ) , i . 1. pretty ( ) ) ;
}
}
assert_eq! ( * memtrie . root ( ) , real ) ;
unpopulate_trie ( & mut memtrie , & x ) ;
2016-07-14 18:06:46 +02:00
memtrie . commit ( ) ;
2018-07-02 18:50:05 +02:00
if * memtrie . root ( ) ! = RlpCodec ::HASHED_NULL_NODE {
2016-01-15 04:02:24 +01:00
println! ( " - TRIE MISMATCH " ) ;
2015-12-03 18:42:51 +01:00
println! ( " " ) ;
println! ( " {:?} vs {:?} " , memtrie . root ( ) , real ) ;
2016-01-19 13:47:30 +01:00
for i in & x {
2015-12-03 18:42:51 +01:00
println! ( " {:?} -> {:?} " , i . 0. pretty ( ) , i . 1. pretty ( ) ) ;
}
}
2018-07-02 18:50:05 +02:00
assert_eq! ( * memtrie . root ( ) , RlpCodec ::HASHED_NULL_NODE ) ;
2015-12-02 22:59:00 +01:00
}
}
#[ test ]
fn init ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2016-07-14 18:06:46 +02:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2018-07-02 18:50:05 +02:00
assert_eq! ( * t . root ( ) , RlpCodec ::HASHED_NULL_NODE ) ;
2015-12-02 22:59:00 +01:00
}
#[ test ]
fn insert_on_empty ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [ ( vec! [ 0x01 u8 , 0x23 ] , vec! [ 0x01 u8 , 0x23 ] ) ] ) ) ;
}
#[ test ]
fn remove_to_empty ( ) {
2015-12-03 18:42:51 +01:00
let big_value = b " 00000000000000000000000000000000 " ;
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t1 = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2017-06-28 16:41:08 +02:00
t1 . insert ( & [ 0x01 , 0x23 ] , big_value ) . unwrap ( ) ;
t1 . insert ( & [ 0x01 , 0x34 ] , big_value ) . unwrap ( ) ;
2018-07-02 18:50:05 +02:00
let mut memdb2 = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root2 = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t2 = TrieDBMut ::new ( & mut memdb2 , & mut root2 ) ;
2018-07-02 18:50:05 +02:00
2017-06-28 16:41:08 +02:00
t2 . insert ( & [ 0x01 ] , big_value ) . unwrap ( ) ;
t2 . insert ( & [ 0x01 , 0x23 ] , big_value ) . unwrap ( ) ;
t2 . insert ( & [ 0x01 , 0x34 ] , big_value ) . unwrap ( ) ;
2016-08-03 18:35:48 +02:00
t2 . remove ( & [ 0x01 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
}
#[ test ]
fn insert_replace_root ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x23 u8 , 0x45 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [ ( vec! [ 0x01 u8 , 0x23 ] , vec! [ 0x23 u8 , 0x45 ] ) ] ) ) ;
}
#[ test ]
fn insert_make_branch_root ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0x11 u8 , 0x23 ] , & [ 0x11 u8 , 0x23 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
( vec! [ 0x01 u8 , 0x23 ] , vec! [ 0x01 u8 , 0x23 ] ) ,
( vec! [ 0x11 u8 , 0x23 ] , vec! [ 0x11 u8 , 0x23 ] )
] ) ) ;
}
#[ test ]
fn insert_into_branch_root ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0xf1 u8 , 0x23 ] , & [ 0xf1 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0x81 u8 , 0x23 ] , & [ 0x81 u8 , 0x23 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
( vec! [ 0x01 u8 , 0x23 ] , vec! [ 0x01 u8 , 0x23 ] ) ,
( vec! [ 0x81 u8 , 0x23 ] , vec! [ 0x81 u8 , 0x23 ] ) ,
( vec! [ 0xf1 u8 , 0x23 ] , vec! [ 0xf1 u8 , 0x23 ] ) ,
] ) ) ;
}
#[ test ]
fn insert_value_into_branch_root ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ ] , & [ 0x0 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
( vec! [ ] , vec! [ 0x0 ] ) ,
( vec! [ 0x01 u8 , 0x23 ] , vec! [ 0x01 u8 , 0x23 ] ) ,
] ) ) ;
}
#[ test ]
fn insert_split_leaf ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0x01 u8 , 0x34 ] , & [ 0x01 u8 , 0x34 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
( vec! [ 0x01 u8 , 0x23 ] , vec! [ 0x01 u8 , 0x23 ] ) ,
( vec! [ 0x01 u8 , 0x34 ] , vec! [ 0x01 u8 , 0x34 ] ) ,
] ) ) ;
}
#[ test ]
fn insert_split_extenstion ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 , 0x23 , 0x45 ] , & [ 0x01 ] ) . unwrap ( ) ;
t . insert ( & [ 0x01 , 0xf3 , 0x45 ] , & [ 0x02 ] ) . unwrap ( ) ;
t . insert ( & [ 0x01 , 0xf3 , 0xf5 ] , & [ 0x03 ] ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
( vec! [ 0x01 , 0x23 , 0x45 ] , vec! [ 0x01 ] ) ,
( vec! [ 0x01 , 0xf3 , 0x45 ] , vec! [ 0x02 ] ) ,
( vec! [ 0x01 , 0xf3 , 0xf5 ] , vec! [ 0x03 ] ) ,
] ) ) ;
}
#[ test ]
fn insert_big_value ( ) {
let big_value0 = b " 00000000000000000000000000000000 " ;
let big_value1 = b " 11111111111111111111111111111111 " ;
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , big_value0 ) . unwrap ( ) ;
t . insert ( & [ 0x11 u8 , 0x23 ] , big_value1 ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
2017-06-28 16:41:08 +02:00
( vec! [ 0x01 u8 , 0x23 ] , big_value0 . to_vec ( ) ) ,
( vec! [ 0x11 u8 , 0x23 ] , big_value1 . to_vec ( ) )
2015-12-02 22:59:00 +01:00
] ) ) ;
}
#[ test ]
fn insert_duplicate_value ( ) {
let big_value = b " 00000000000000000000000000000000 " ;
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , big_value ) . unwrap ( ) ;
t . insert ( & [ 0x11 u8 , 0x23 ] , big_value ) . unwrap ( ) ;
2015-12-02 22:59:00 +01:00
assert_eq! ( * t . root ( ) , trie_root ( vec! [
2017-06-28 16:41:08 +02:00
( vec! [ 0x01 u8 , 0x23 ] , big_value . to_vec ( ) ) ,
( vec! [ 0x11 u8 , 0x23 ] , big_value . to_vec ( ) )
2015-12-02 22:59:00 +01:00
] ) ) ;
}
2015-12-01 16:39:44 +01:00
#[ test ]
fn test_at_empty ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2018-07-02 18:50:05 +02:00
assert_eq! ( t . get ( & [ 0x5 ] ) . unwrap ( ) , None ) ;
2015-12-01 16:39:44 +01:00
}
#[ test ]
fn test_at_one ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
2016-10-26 13:53:47 +02:00
assert_eq! ( t . get ( & [ 0x1 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0x1 u8 , 0x23 ] ) ) ;
2016-07-14 18:06:46 +02:00
t . commit ( ) ;
2016-10-26 13:53:47 +02:00
assert_eq! ( t . get ( & [ 0x1 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0x1 u8 , 0x23 ] ) ) ;
2015-12-01 16:39:44 +01:00
}
2015-12-01 17:03:54 +01:00
#[ test ]
fn test_at_three ( ) {
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut memdb , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0xf1 u8 , 0x23 ] , & [ 0xf1 u8 , 0x23 ] ) . unwrap ( ) ;
t . insert ( & [ 0x81 u8 , 0x23 ] , & [ 0x81 u8 , 0x23 ] ) . unwrap ( ) ;
2016-10-26 13:53:47 +02:00
assert_eq! ( t . get ( & [ 0x01 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0x01 u8 , 0x23 ] ) ) ;
assert_eq! ( t . get ( & [ 0xf1 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0xf1 u8 , 0x23 ] ) ) ;
assert_eq! ( t . get ( & [ 0x81 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0x81 u8 , 0x23 ] ) ) ;
2018-07-02 18:50:05 +02:00
assert_eq! ( t . get ( & [ 0x82 , 0x23 ] ) . unwrap ( ) , None ) ;
2016-07-14 18:06:46 +02:00
t . commit ( ) ;
2016-10-26 13:53:47 +02:00
assert_eq! ( t . get ( & [ 0x01 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0x01 u8 , 0x23 ] ) ) ;
assert_eq! ( t . get ( & [ 0xf1 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0xf1 u8 , 0x23 ] ) ) ;
assert_eq! ( t . get ( & [ 0x81 , 0x23 ] ) . unwrap ( ) . unwrap ( ) , DBValue ::from_slice ( & [ 0x81 u8 , 0x23 ] ) ) ;
2018-07-02 18:50:05 +02:00
assert_eq! ( t . get ( & [ 0x82 , 0x23 ] ) . unwrap ( ) , None ) ;
2015-12-01 18:25:47 +01:00
}
2015-12-02 02:37:26 +01:00
#[ test ]
fn stress ( ) {
2016-02-27 15:49:44 +01:00
let mut seed = H256 ::new ( ) ;
2015-12-19 13:53:05 +01:00
for _ in 0 .. 50 {
2016-02-27 15:49:44 +01:00
let x = StandardMap {
2017-06-28 16:41:08 +02:00
alphabet : Alphabet ::Custom ( b " @QWERTYUIOPASDFGHJKLZXCVBNM[/]^_ " . to_vec ( ) ) ,
2016-02-27 15:49:44 +01:00
min_key : 5 ,
journal_key : 0 ,
value_mode : ValueMode ::Index ,
count : 4 ,
} . make_with ( & mut seed ) ;
2015-12-02 02:37:26 +01:00
let real = trie_root ( x . clone ( ) ) ;
2018-07-02 18:50:05 +02:00
let mut memdb = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
2018-07-02 18:50:05 +02:00
let mut memtrie = populate_trie ::< _ , RlpCodec > ( & mut memdb , & mut root , & x ) ;
2015-12-02 15:03:20 +01:00
let mut y = x . clone ( ) ;
y . sort_by ( | ref a , ref b | a . 0. cmp ( & b . 0 ) ) ;
2018-07-02 18:50:05 +02:00
let mut memdb2 = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root2 = H256 ::new ( ) ;
2018-07-02 18:50:05 +02:00
let mut memtrie_sorted = populate_trie ::< _ , RlpCodec > ( & mut memdb2 , & mut root2 , & y ) ;
2015-12-02 15:03:20 +01:00
if * memtrie . root ( ) ! = real | | * memtrie_sorted . root ( ) ! = real {
println! ( " TRIE MISMATCH " ) ;
println! ( " " ) ;
println! ( " ORIGINAL... {:?} " , memtrie . root ( ) ) ;
2016-01-19 13:47:30 +01:00
for i in & x {
2015-12-02 15:03:20 +01:00
println! ( " {:?} -> {:?} " , i . 0. pretty ( ) , i . 1. pretty ( ) ) ;
}
println! ( " SORTED... {:?} " , memtrie_sorted . root ( ) ) ;
2016-01-19 13:47:30 +01:00
for i in & y {
2015-12-02 15:03:20 +01:00
println! ( " {:?} -> {:?} " , i . 0. pretty ( ) , i . 1. pretty ( ) ) ;
}
}
assert_eq! ( * memtrie . root ( ) , real ) ;
assert_eq! ( * memtrie_sorted . root ( ) , real ) ;
2015-12-02 02:37:26 +01:00
}
}
2015-12-11 03:00:39 +01:00
#[ test ]
fn test_trie_existing ( ) {
2018-07-02 18:50:05 +02:00
let mut db = MemoryDB ::< KeccakHasher > ::new ( ) ;
2015-12-11 03:00:39 +01:00
let mut root = H256 ::new ( ) ;
{
2015-12-17 12:43:50 +01:00
let mut t = TrieDBMut ::new ( & mut db , & mut root ) ;
2016-08-03 18:35:48 +02:00
t . insert ( & [ 0x01 u8 , 0x23 ] , & [ 0x01 u8 , 0x23 ] ) . unwrap ( ) ;
2015-12-11 03:00:39 +01:00
}
{
2018-07-02 18:50:05 +02:00
let _ = TrieDBMut ::from_existing ( & mut db , & mut root ) ;
2015-12-11 03:00:39 +01:00
}
}
2016-07-14 18:06:46 +02:00
#[ test ]
fn insert_empty ( ) {
let mut seed = H256 ::new ( ) ;
let x = StandardMap {
2017-06-28 16:41:08 +02:00
alphabet : Alphabet ::Custom ( b " @QWERTYUIOPASDFGHJKLZXCVBNM[/]^_ " . to_vec ( ) ) ,
2016-07-14 18:06:46 +02:00
min_key : 5 ,
journal_key : 0 ,
value_mode : ValueMode ::Index ,
count : 4 ,
} . make_with ( & mut seed ) ;
2018-07-02 18:50:05 +02:00
let mut db = MemoryDB ::< KeccakHasher > ::new ( ) ;
2016-07-14 18:06:46 +02:00
let mut root = H256 ::new ( ) ;
let mut t = TrieDBMut ::new ( & mut db , & mut root ) ;
for & ( ref key , ref value ) in & x {
2016-08-03 18:35:48 +02:00
t . insert ( key , value ) . unwrap ( ) ;
2016-07-14 18:06:46 +02:00
}
assert_eq! ( * t . root ( ) , trie_root ( x . clone ( ) ) ) ;
for & ( ref key , _ ) in & x {
2016-08-03 18:35:48 +02:00
t . insert ( key , & [ ] ) . unwrap ( ) ;
2016-07-14 18:06:46 +02:00
}
assert! ( t . is_empty ( ) ) ;
2018-07-02 18:50:05 +02:00
assert_eq! ( * t . root ( ) , RlpCodec ::HASHED_NULL_NODE ) ;
2016-07-14 18:06:46 +02:00
}
2017-01-05 21:15:43 +01:00
#[ test ]
fn return_old_values ( ) {
let mut seed = H256 ::new ( ) ;
let x = StandardMap {
2017-06-28 16:41:08 +02:00
alphabet : Alphabet ::Custom ( b " @QWERTYUIOPASDFGHJKLZXCVBNM[/]^_ " . to_vec ( ) ) ,
2017-01-05 21:15:43 +01:00
min_key : 5 ,
journal_key : 0 ,
value_mode : ValueMode ::Index ,
count : 4 ,
} . make_with ( & mut seed ) ;
2018-07-02 18:50:05 +02:00
let mut db = MemoryDB ::< KeccakHasher > ::new ( ) ;
2017-01-05 21:15:43 +01:00
let mut root = H256 ::new ( ) ;
let mut t = TrieDBMut ::new ( & mut db , & mut root ) ;
for & ( ref key , ref value ) in & x {
assert! ( t . insert ( key , value ) . unwrap ( ) . is_none ( ) ) ;
assert_eq! ( t . insert ( key , value ) . unwrap ( ) , Some ( DBValue ::from_slice ( value ) ) ) ;
}
for ( key , value ) in x {
assert_eq! ( t . remove ( & key ) . unwrap ( ) , Some ( DBValue ::from_slice ( & value ) ) ) ;
assert! ( t . remove ( & key ) . unwrap ( ) . is_none ( ) ) ;
}
}
2016-07-19 09:25:51 +02:00
}