| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2014 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-31 14:45:03 +01:00
										 |  |  | package trie | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2014-11-18 19:52:45 +01:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2014-05-26 00:09:38 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-11-18 19:52:45 +01:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2014-11-15 20:21:55 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-03-19 10:57:02 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | type Db map[string][]byte | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func (self Db) Get(k []byte) ([]byte, error) { return self[string(k)], nil } | 
					
						
							| 
									
										
										
										
											2015-06-21 17:08:47 +02:00
										 |  |  | func (self Db) Put(k, v []byte) error        { self[string(k)] = v; return nil } | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | // Used for testing | 
					
						
							|  |  |  | func NewEmpty() *Trie { | 
					
						
							|  |  |  | 	return New(nil, make(Db)) | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 12:15:58 +01:00
										 |  |  | func NewEmptySecure() *SecureTrie { | 
					
						
							|  |  |  | 	return NewSecure(nil, make(Db)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestEmptyTrie(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							|  |  |  | 	res := trie.Hash() | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	exp := crypto.Sha3(common.Encode("")) | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	if !bytes.Equal(res, exp) { | 
					
						
							|  |  |  | 		t.Errorf("expected %x got %x", exp, res) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-19 10:57:02 +01:00
										 |  |  | func TestNull(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	key := make([]byte, 32) | 
					
						
							|  |  |  | 	value := common.FromHex("0x823140710bf13990e4500136726d8b55") | 
					
						
							|  |  |  | 	trie.Update(key, value) | 
					
						
							|  |  |  | 	value = trie.Get(key) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestInsert(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.UpdateString("doe", "reindeer") | 
					
						
							|  |  |  | 	trie.UpdateString("dog", "puppy") | 
					
						
							|  |  |  | 	trie.UpdateString("dogglesworth", "cat") | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	exp := common.Hex2Bytes("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3") | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	root := trie.Hash() | 
					
						
							|  |  |  | 	if !bytes.Equal(root, exp) { | 
					
						
							|  |  |  | 		t.Errorf("exp %x got %x", exp, root) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-20 14:40:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie = NewEmpty() | 
					
						
							|  |  |  | 	trie.UpdateString("A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") | 
					
						
							| 
									
										
										
										
											2014-02-20 14:40:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	exp = common.Hex2Bytes("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab") | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	root = trie.Hash() | 
					
						
							|  |  |  | 	if !bytes.Equal(root, exp) { | 
					
						
							|  |  |  | 		t.Errorf("exp %x got %x", exp, root) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-20 14:40:00 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-24 12:11:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestGet(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-02-25 10:50:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.UpdateString("doe", "reindeer") | 
					
						
							|  |  |  | 	trie.UpdateString("dog", "puppy") | 
					
						
							|  |  |  | 	trie.UpdateString("dogglesworth", "cat") | 
					
						
							| 
									
										
										
										
											2014-05-26 00:09:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	res := trie.GetString("dog") | 
					
						
							|  |  |  | 	if !bytes.Equal(res, []byte("puppy")) { | 
					
						
							|  |  |  | 		t.Errorf("expected puppy got %x", res) | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	unknown := trie.GetString("unknown") | 
					
						
							|  |  |  | 	if unknown != nil { | 
					
						
							|  |  |  | 		t.Errorf("expected nil got %x", unknown) | 
					
						
							| 
									
										
										
										
											2014-06-17 18:05:46 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestDelete(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							|  |  |  | 		{"shaman", "horse"}, | 
					
						
							|  |  |  | 		{"doge", "coin"}, | 
					
						
							|  |  |  | 		{"ether", ""}, | 
					
						
							|  |  |  | 		{"dog", "puppy"}, | 
					
						
							|  |  |  | 		{"shaman", ""}, | 
					
						
							| 
									
										
										
										
											2014-06-17 18:05:46 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	for _, val := range vals { | 
					
						
							|  |  |  | 		if val.v != "" { | 
					
						
							|  |  |  | 			trie.UpdateString(val.k, val.v) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			trie.DeleteString(val.k) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	hash := trie.Hash() | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	exp := common.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84") | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	if !bytes.Equal(hash, exp) { | 
					
						
							|  |  |  | 		t.Errorf("expected %x got %x", exp, hash) | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-27 01:08:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestEmptyValues(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							|  |  |  | 		{"shaman", "horse"}, | 
					
						
							|  |  |  | 		{"doge", "coin"}, | 
					
						
							|  |  |  | 		{"ether", ""}, | 
					
						
							|  |  |  | 		{"dog", "puppy"}, | 
					
						
							|  |  |  | 		{"shaman", ""}, | 
					
						
							| 
									
										
										
										
											2014-06-30 13:08:00 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	for _, val := range vals { | 
					
						
							|  |  |  | 		trie.UpdateString(val.k, val.v) | 
					
						
							| 
									
										
										
										
											2014-07-01 09:55:20 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	hash := trie.Hash() | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	exp := common.Hex2Bytes("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84") | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	if !bytes.Equal(hash, exp) { | 
					
						
							|  |  |  | 		t.Errorf("expected %x got %x", exp, hash) | 
					
						
							| 
									
										
										
										
											2014-06-17 18:05:46 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-01 09:55:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestReplication(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							|  |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							|  |  |  | 		{"shaman", "horse"}, | 
					
						
							|  |  |  | 		{"doge", "coin"}, | 
					
						
							|  |  |  | 		{"ether", ""}, | 
					
						
							|  |  |  | 		{"dog", "puppy"}, | 
					
						
							|  |  |  | 		{"shaman", ""}, | 
					
						
							|  |  |  | 		{"somethingveryoddindeedthis is", "myothernodedata"}, | 
					
						
							| 
									
										
										
										
											2014-06-17 18:05:46 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	for _, val := range vals { | 
					
						
							|  |  |  | 		trie.UpdateString(val.k, val.v) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	trie.Commit() | 
					
						
							| 
									
										
										
										
											2014-06-18 13:48:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-01 15:38:32 +02:00
										 |  |  | 	trie2 := New(trie.Root(), trie.cache.backend) | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	if string(trie2.GetString("horse")) != "stallion" { | 
					
						
							|  |  |  | 		t.Error("expected to have horse => stallion") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-15 15:29:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	hash := trie2.Hash() | 
					
						
							|  |  |  | 	exp := trie.Hash() | 
					
						
							|  |  |  | 	if !bytes.Equal(hash, exp) { | 
					
						
							|  |  |  | 		t.Errorf("root failure. expected %x got %x", exp, hash) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-17 11:21:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 17:00:06 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestReset(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							|  |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							| 
									
										
										
										
											2014-10-10 17:00:06 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	for _, val := range vals { | 
					
						
							|  |  |  | 		trie.UpdateString(val.k, val.v) | 
					
						
							| 
									
										
										
										
											2014-10-10 17:00:06 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.Commit() | 
					
						
							| 
									
										
										
										
											2014-10-10 17:00:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	before := common.CopyBytes(trie.roothash) | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.UpdateString("should", "revert") | 
					
						
							|  |  |  | 	trie.Hash() | 
					
						
							|  |  |  | 	// Should have no effect | 
					
						
							|  |  |  | 	trie.Hash() | 
					
						
							|  |  |  | 	trie.Hash() | 
					
						
							|  |  |  | 	// ### | 
					
						
							| 
									
										
										
										
											2014-10-10 17:00:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.Reset() | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	after := common.CopyBytes(trie.roothash) | 
					
						
							| 
									
										
										
										
											2014-11-14 15:19:50 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	if !bytes.Equal(before, after) { | 
					
						
							|  |  |  | 		t.Errorf("expected roots to be equal. %x - %x", before, after) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-12 01:36:36 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | func TestParanoia(t *testing.T) { | 
					
						
							|  |  |  | 	t.Skip() | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							|  |  |  | 		{"shaman", "horse"}, | 
					
						
							|  |  |  | 		{"doge", "coin"}, | 
					
						
							|  |  |  | 		{"ether", ""}, | 
					
						
							|  |  |  | 		{"dog", "puppy"}, | 
					
						
							|  |  |  | 		{"shaman", ""}, | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 		{"somethingveryoddindeedthis is", "myothernodedata"}, | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for _, val := range vals { | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 		trie.UpdateString(val.k, val.v) | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.Commit() | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	ok, t2 := ParanoiaCheck(trie, trie.cache.backend) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Errorf("trie paranoia check failed %x %x", trie.roothash, t2.roothash) | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | // Not an actual test | 
					
						
							|  |  |  | func TestOutput(t *testing.T) { | 
					
						
							|  |  |  | 	t.Skip() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	base := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							|  |  |  | 	for i := 0; i < 50; i++ { | 
					
						
							|  |  |  | 		trie.UpdateString(fmt.Sprintf("%s%d", base, i), "valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Println("############################## FULL ################################") | 
					
						
							|  |  |  | 	fmt.Println(trie.root) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	trie.Commit() | 
					
						
							|  |  |  | 	fmt.Println("############################## SMALL ################################") | 
					
						
							|  |  |  | 	trie2 := New(trie.roothash, trie.cache.backend) | 
					
						
							|  |  |  | 	trie2.GetString(base + "20") | 
					
						
							|  |  |  | 	fmt.Println(trie2.root) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | func BenchmarkGets(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							|  |  |  | 		{"shaman", "horse"}, | 
					
						
							|  |  |  | 		{"doge", "coin"}, | 
					
						
							|  |  |  | 		{"ether", ""}, | 
					
						
							|  |  |  | 		{"dog", "puppy"}, | 
					
						
							|  |  |  | 		{"shaman", ""}, | 
					
						
							|  |  |  | 		{"somethingveryoddindeedthis is", "myothernodedata"}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, val := range vals { | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 		trie.UpdateString(val.k, val.v) | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 		trie.Get([]byte("horse")) | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkUpdate(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie := NewEmpty() | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 		trie.UpdateString(fmt.Sprintf("aaaaaaaaa%d", i), "value") | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	trie.Hash() | 
					
						
							| 
									
										
										
										
											2014-11-18 12:03:09 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-07 17:03:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | type kv struct { | 
					
						
							|  |  |  | 	k, v []byte | 
					
						
							|  |  |  | 	t    bool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestLargeData(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmpty() | 
					
						
							|  |  |  | 	vals := make(map[string]*kv) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 17:46:00 +01:00
										 |  |  | 	for i := byte(0); i < 255; i++ { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 		value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} | 
					
						
							|  |  |  | 		value2 := &kv{common.LeftPadBytes([]byte{10, i}, 32), []byte{i}, false} | 
					
						
							| 
									
										
										
										
											2015-02-07 17:03:22 +01:00
										 |  |  | 		trie.Update(value.k, value.v) | 
					
						
							|  |  |  | 		trie.Update(value2.k, value2.v) | 
					
						
							|  |  |  | 		vals[string(value.k)] = value | 
					
						
							|  |  |  | 		vals[string(value2.k)] = value2 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	it := trie.Iterator() | 
					
						
							|  |  |  | 	for it.Next() { | 
					
						
							|  |  |  | 		vals[string(it.Key)].t = true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var untouched []*kv | 
					
						
							|  |  |  | 	for _, value := range vals { | 
					
						
							|  |  |  | 		if !value.t { | 
					
						
							|  |  |  | 			untouched = append(untouched, value) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(untouched) > 0 { | 
					
						
							|  |  |  | 		t.Errorf("Missed %d nodes", len(untouched)) | 
					
						
							|  |  |  | 		for _, value := range untouched { | 
					
						
							|  |  |  | 			t.Error(value) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-03 12:15:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestSecureDelete(t *testing.T) { | 
					
						
							|  |  |  | 	trie := NewEmptySecure() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vals := []struct{ k, v string }{ | 
					
						
							|  |  |  | 		{"do", "verb"}, | 
					
						
							|  |  |  | 		{"ether", "wookiedoo"}, | 
					
						
							|  |  |  | 		{"horse", "stallion"}, | 
					
						
							|  |  |  | 		{"shaman", "horse"}, | 
					
						
							|  |  |  | 		{"doge", "coin"}, | 
					
						
							|  |  |  | 		{"ether", ""}, | 
					
						
							|  |  |  | 		{"dog", "puppy"}, | 
					
						
							|  |  |  | 		{"shaman", ""}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, val := range vals { | 
					
						
							|  |  |  | 		if val.v != "" { | 
					
						
							|  |  |  | 			trie.UpdateString(val.k, val.v) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			trie.DeleteString(val.k) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hash := trie.Hash() | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	exp := common.Hex2Bytes("29b235a58c3c25ab83010c327d5932bcf05324b7d6b1185e650798034783ca9d") | 
					
						
							| 
									
										
										
										
											2015-03-03 12:15:58 +01:00
										 |  |  | 	if !bytes.Equal(hash, exp) { | 
					
						
							|  |  |  | 		t.Errorf("expected %x got %x", exp, hash) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |