diff --git a/trie/arc.go b/trie/arc.go index 9da012e168..229420a538 100644 --- a/trie/arc.go +++ b/trie/arc.go @@ -62,6 +62,17 @@ func newARC(c int) *arc { } } +func (a *arc) Clear() { + a.mutex.Lock() + defer a.mutex.Unlock() + a.p = 0 + a.t1 = list.New() + a.b1 = list.New() + a.t2 = list.New() + a.b2 = list.New() + a.cache = make(map[string]*entry, a.c) +} + // Put inserts a new key-value pair into the cache. // This optimizes future access to this entry (side effect). func (a *arc) Put(key hashNode, value node) bool { diff --git a/trie/encoding_test.go b/trie/encoding_test.go index 061d48d58b..2f125ef2f8 100644 --- a/trie/encoding_test.go +++ b/trie/encoding_test.go @@ -57,6 +57,12 @@ func (s *TrieEncodingSuite) TestCompactHexDecode(c *checker.C) { c.Assert(res, checker.DeepEquals, exp) } +func (s *TrieEncodingSuite) TestCompactHexEncode(c *checker.C) { + exp := []byte("verb") + res := compactHexEncode([]byte{7, 6, 6, 5, 7, 2, 6, 2, 16}) + c.Assert(res, checker.DeepEquals, exp) +} + func (s *TrieEncodingSuite) TestCompactDecode(c *checker.C) { // odd compact decode exp := []byte{1, 2, 3, 4, 5} diff --git a/trie/proof_test.go b/trie/proof_test.go index 6b5bef05c4..6738a50bcf 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" ) @@ -33,6 +34,33 @@ func TestProof(t *testing.T) { } } +func TestStoreProof(t *testing.T) { + trie, vals := randomTrie(500) + root := trie.Hash() + mdb, _ := ethdb.NewMemDatabase() + for _, kv := range vals { + proof := trie.Prove(kv.k) + if proof == nil { + t.Fatalf("missing key %x while constructing proof", kv.k) + } + val, err := VerifyProof(root, kv.k, proof) + if err != nil { + t.Fatalf("VerifyProof error for key %x: %v\nraw proof: %x", kv.k, err, proof) + } + if !bytes.Equal(val, kv.v) { + t.Fatalf("VerifyProof returned wrong value for key %x: got %x, want %x", kv.k, val, kv.v) + } + StoreProof(mdb, proof) + } + ClearGlobalCache() + mtrie, _ := New(root, mdb) + for _, kv := range vals { + if !bytes.Equal(mtrie.Get(kv.k), kv.v) { + t.Fatalf("Can't retrieve stored proof") + } + } +} + func TestOneElementProof(t *testing.T) { trie := new(Trie) updateString(trie, "k", "v") diff --git a/trie/trie.go b/trie/trie.go index 7cb17912ad..fabb7468b3 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -46,6 +46,10 @@ var ( emptyState = crypto.Sha3Hash(nil) ) +func ClearGlobalCache() { + globalCache.Clear() +} + var ErrMissingRoot = errors.New("missing root node") // OdrAccess is an interface to on-demand network access layer