From 2fb08643cbd862a07801de09aa0aa55edc583bfa Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 24 Oct 2016 11:58:50 +0100 Subject: [PATCH] Remove NodeIterator from the storage interface --- core/state/iterator.go | 4 ++-- core/state/state_object.go | 2 +- core/state/statedb.go | 8 +++---- trie/directcache.go | 4 ---- trie/iterator.go | 8 +++---- trie/proof.go | 2 +- trie/proof_test.go | 2 +- trie/secure_trie_test.go | 2 +- trie/sync_test.go | 4 ++-- trie/trie.go | 49 +++++++++++++++++--------------------- trie/trie_test.go | 8 +++---- 11 files changed, 42 insertions(+), 51 deletions(-) diff --git a/core/state/iterator.go b/core/state/iterator.go index f48aab5583..9600c92ed5 100644 --- a/core/state/iterator.go +++ b/core/state/iterator.go @@ -76,7 +76,7 @@ func (it *NodeIterator) step() error { } // Initialize the iterator if we've just started if it.stateIt == nil { - it.stateIt = it.state.trie.NodeIterator() + it.stateIt = trie.NewNodeIterator(it.state.trie) } // If we had data nodes previously, we surely have at least state nodes if it.dataIt != nil { @@ -119,7 +119,7 @@ func (it *NodeIterator) step() error { if err != nil { return err } - it.dataIt = dataTrie.NodeIterator() + it.dataIt = trie.NewNodeIterator(dataTrie) if !it.dataIt.Next() { it.dataIt = nil } diff --git a/core/state/state_object.go b/core/state/state_object.go index 1817299493..cd60c33776 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -76,7 +76,7 @@ type StateObject struct { dbErr error // Write caches. - trie *trie.SimpleTrie // storage trie, which becomes non-nil on first access + trie *trie.Trie // storage trie, which becomes non-nil on first access storage *trie.SecureTrie // Interface to storage code Code // contract bytecode, which gets set when code is loaded diff --git a/core/state/statedb.go b/core/state/statedb.go index 2fd41e6180..eef2f38d50 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -62,9 +62,9 @@ type revision struct { // * Accounts type StateDB struct { db ethdb.Database - trie *trie.SimpleTrie + trie *trie.Trie storage *trie.SecureTrie - pastTries []*trie.SimpleTrie + pastTries []*trie.Trie codeSizeCache *lru.Cache // This map holds 'live' objects, which will get modified while processing a state transition. @@ -155,7 +155,7 @@ func (self *StateDB) Reset(root common.Hash) error { // openTrie creates a trie. It uses an existing trie if one is available // from the journal if available. -func (self *StateDB) openTrie(root common.Hash) (*trie.SimpleTrie, error) { +func (self *StateDB) openTrie(root common.Hash) (*trie.Trie, error) { for i := len(self.pastTries) - 1; i >= 0; i-- { if self.pastTries[i].Hash() == root { tr := *self.pastTries[i] @@ -165,7 +165,7 @@ func (self *StateDB) openTrie(root common.Hash) (*trie.SimpleTrie, error) { return trie.New(root, self.db, MaxTrieCacheGen) } -func (self *StateDB) pushTrie(t *trie.SimpleTrie) { +func (self *StateDB) pushTrie(t *trie.Trie) { self.lock.Lock() defer self.lock.Unlock() diff --git a/trie/directcache.go b/trie/directcache.go index 0d2a0f2410..6f87ba5ef8 100644 --- a/trie/directcache.go +++ b/trie/directcache.go @@ -70,10 +70,6 @@ func (dc *DirectCache) Iterator() *Iterator { return dc.storage.Iterator() } -func (dc *DirectCache) NodeIterator() *NodeIterator { - return dc.storage.NodeIterator() -} - func (dc *DirectCache) makeKey(key []byte) []byte { return append(dc.keyPrefix, key...) } diff --git a/trie/iterator.go b/trie/iterator.go index 750bbab12c..4b5f42890a 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -20,7 +20,7 @@ import "github.com/ethereum/go-ethereum/common" // Iterator is a key-value trie iterator that traverses a Trie. type Iterator struct { - trie *SimpleTrie + trie *Trie nodeIt *NodeIterator keyBuf []byte @@ -29,7 +29,7 @@ type Iterator struct { } // NewIterator creates a new key-value iterator. -func NewIterator(trie *SimpleTrie) *Iterator { +func NewIterator(trie *Trie) *Iterator { return &Iterator{ trie: trie, nodeIt: NewNodeIterator(trie), @@ -82,7 +82,7 @@ type nodeIteratorState struct { // NodeIterator is an iterator to traverse the trie post-order. type NodeIterator struct { - trie *SimpleTrie // Trie being iterated + trie *Trie // Trie being iterated stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state Hash common.Hash // Hash of the current node being iterated (nil if not standalone) @@ -95,7 +95,7 @@ type NodeIterator struct { } // NewNodeIterator creates an post-order trie iterator. -func NewNodeIterator(trie *SimpleTrie) *NodeIterator { +func NewNodeIterator(trie *Trie) *NodeIterator { if trie.Hash() == emptyState { return new(NodeIterator) } diff --git a/trie/proof.go b/trie/proof.go index bf796a95cd..bea5e5c098 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -37,7 +37,7 @@ import ( // contains all nodes of the longest existing prefix of the key // (at least the root node), ending with the node that proves the // absence of the key. -func (t *SimpleTrie) Prove(key []byte) []rlp.RawValue { +func (t *Trie) Prove(key []byte) []rlp.RawValue { // Collect all nodes on the path to key. key = compactHexDecode(key) nodes := []node{} diff --git a/trie/proof_test.go b/trie/proof_test.go index eddbafe00a..ce7eac5045 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -129,7 +129,7 @@ func BenchmarkVerifyProof(b *testing.B) { } } -func randomTrie(n int) (*SimpleTrie, map[string]*kv) { +func randomTrie(n int) (*Trie, map[string]*kv) { trie, _ := New(common.Hash{}, nil, 0) vals := make(map[string]*kv) for i := byte(0); i < 100; i++ { diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go index a595c2f1ea..7b8907deeb 100644 --- a/trie/secure_trie_test.go +++ b/trie/secure_trie_test.go @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" ) -func newEmptySecure() (*SimpleTrie, *SecureTrie) { +func newEmptySecure() (*Trie, *SecureTrie) { db, _ := ethdb.NewMemDatabase() tr, _ := New(common.Hash{}, db, 0) st := NewSecure(tr, db) diff --git a/trie/sync_test.go b/trie/sync_test.go index 62db45a01d..a28e81adb7 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -25,7 +25,7 @@ import ( ) // makeTestTrie create a sample test trie to test node-wise reconstruction. -func makeTestTrie() (ethdb.Database, *SimpleTrie, map[string][]byte) { +func makeTestTrie() (ethdb.Database, *Trie, map[string][]byte) { // Create an empty trie db, _ := ethdb.NewMemDatabase() trie, _ := New(common.Hash{}, db, 0) @@ -91,7 +91,7 @@ func TestEmptyTrieSync(t *testing.T) { emptyA, _ := New(common.Hash{}, nil, 0) emptyB, _ := New(emptyRoot, nil, 0) - for i, trie := range []*SimpleTrie{emptyA, emptyB} { + for i, trie := range []*Trie{emptyA, emptyB} { db, _ := ethdb.NewMemDatabase() if req := NewTrieSync(common.BytesToHash(trie.Root()), db, nil).Missing(1); len(req) != 0 { t.Errorf("test %d: content requested for empty trie: %v", i, req) diff --git a/trie/trie.go b/trie/trie.go index f9eae6053e..e186fc1d7c 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -80,7 +80,6 @@ type DatabaseWriter interface { // trie is not safe for concurrent use. type Storage interface { Iterator() *Iterator - NodeIterator() *NodeIterator Get(key []byte) []byte TryGet(key []byte) ([]byte, error) Update(key, value []byte) @@ -91,7 +90,7 @@ type Storage interface { CommitTo(db DatabaseWriter) (root common.Hash, err error) } -type SimpleTrie struct { +type Trie struct { root node db Database originalRoot common.Hash @@ -104,7 +103,7 @@ type SimpleTrie struct { } // newFlag returns the cache flag value for a newly created node. -func (t *SimpleTrie) newFlag() nodeFlag { +func (t *Trie) newFlag() nodeFlag { return nodeFlag{dirty: true, gen: t.cachegen} } @@ -117,11 +116,11 @@ func (t *SimpleTrie) newFlag() nodeFlag { // // cacheLimit is the number of 'cache generations' to keep. // A cache generations is created by a call to Commit. -func New(root common.Hash, db Database, cacheLimit uint16) (*SimpleTrie, error) { - trie := &SimpleTrie{db: db, originalRoot: root, cachelimit: cacheLimit} +func New(root common.Hash, db Database, cacheLimit uint16) (*Trie, error) { + trie := &Trie{db: db, originalRoot: root, cachelimit: cacheLimit} if (root != common.Hash{}) && root != emptyRoot { if db == nil { - panic("SimpleTrie.New: cannot use existing root without a database") + panic("Trie.New: cannot use existing root without a database") } rootnode, err := trie.resolveHash(root[:], nil, nil) if err != nil { @@ -133,17 +132,13 @@ func New(root common.Hash, db Database, cacheLimit uint16) (*SimpleTrie, error) } // Iterator returns an iterator over all mappings in the trie. -func (t *SimpleTrie) Iterator() *Iterator { +func (t *Trie) Iterator() *Iterator { return NewIterator(t) } -func (t *SimpleTrie) NodeIterator() *NodeIterator { - return NewNodeIterator(t) -} - // Get returns the value for key stored in the trie. // The value bytes must not be modified by the caller. -func (t *SimpleTrie) Get(key []byte) []byte { +func (t *Trie) Get(key []byte) []byte { res, err := t.TryGet(key) if err != nil && glog.V(logger.Error) { glog.Errorf("Unhandled trie error: %v", err) @@ -154,7 +149,7 @@ func (t *SimpleTrie) Get(key []byte) []byte { // TryGet returns the value for key stored in the trie. // The value bytes must not be modified by the caller. // If a node was not found in the database, a MissingNodeError is returned. -func (t *SimpleTrie) TryGet(key []byte) ([]byte, error) { +func (t *Trie) TryGet(key []byte) ([]byte, error) { key = compactHexDecode(key) value, newroot, didResolve, err := t.tryGet(t.root, key, 0) if err == nil && didResolve { @@ -163,7 +158,7 @@ func (t *SimpleTrie) TryGet(key []byte) ([]byte, error) { return value, err } -func (t *SimpleTrie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) { +func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) { switch n := (origNode).(type) { case nil: return nil, nil, false, nil @@ -207,7 +202,7 @@ func (t *SimpleTrie) tryGet(origNode node, key []byte, pos int) (value []byte, n // // The value bytes must not be modified by the caller while they are // stored in the trie. -func (t *SimpleTrie) Update(key, value []byte) { +func (t *Trie) Update(key, value []byte) { if err := t.TryUpdate(key, value); err != nil && glog.V(logger.Error) { glog.Errorf("Unhandled trie error: %v", err) } @@ -221,7 +216,7 @@ func (t *SimpleTrie) Update(key, value []byte) { // stored in the trie. // // If a node was not found in the database, a MissingNodeError is returned. -func (t *SimpleTrie) TryUpdate(key, value []byte) error { +func (t *Trie) TryUpdate(key, value []byte) error { k := compactHexDecode(key) if len(value) != 0 { _, n, err := t.insert(t.root, nil, k, valueNode(value)) @@ -239,7 +234,7 @@ func (t *SimpleTrie) TryUpdate(key, value []byte) error { return nil } -func (t *SimpleTrie) insert(n node, prefix, key []byte, value node) (bool, node, error) { +func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) { if len(key) == 0 { if v, ok := n.(valueNode); ok { return !bytes.Equal(v, value.(valueNode)), value, nil @@ -309,7 +304,7 @@ func (t *SimpleTrie) insert(n node, prefix, key []byte, value node) (bool, node, } // Delete removes any existing value for key from the trie. -func (t *SimpleTrie) Delete(key []byte) { +func (t *Trie) Delete(key []byte) { if err := t.TryDelete(key); err != nil && glog.V(logger.Error) { glog.Errorf("Unhandled trie error: %v", err) } @@ -317,7 +312,7 @@ func (t *SimpleTrie) Delete(key []byte) { // TryDelete removes any existing value for key from the trie. // If a node was not found in the database, a MissingNodeError is returned. -func (t *SimpleTrie) TryDelete(key []byte) error { +func (t *Trie) TryDelete(key []byte) error { k := compactHexDecode(key) _, n, err := t.delete(t.root, nil, k) if err != nil { @@ -330,7 +325,7 @@ func (t *SimpleTrie) TryDelete(key []byte) error { // delete returns the new root of the trie with key deleted. // It reduces the trie to minimal form by simplifying // nodes on the way up after deleting recursively. -func (t *SimpleTrie) delete(n node, prefix, key []byte) (bool, node, error) { +func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { switch n := n.(type) { case *shortNode: matchlen := prefixLen(key, n.Key) @@ -446,14 +441,14 @@ func concat(s1 []byte, s2 ...byte) []byte { return r } -func (t *SimpleTrie) resolve(n node, prefix, suffix []byte) (node, error) { +func (t *Trie) resolve(n node, prefix, suffix []byte) (node, error) { if n, ok := n.(hashNode); ok { return t.resolveHash(n, prefix, suffix) } return n, nil } -func (t *SimpleTrie) resolveHash(n hashNode, prefix, suffix []byte) (node, error) { +func (t *Trie) resolveHash(n hashNode, prefix, suffix []byte) (node, error) { cacheMissCounter.Inc(1) enc, err := t.db.Get(n) @@ -472,11 +467,11 @@ func (t *SimpleTrie) resolveHash(n hashNode, prefix, suffix []byte) (node, error // Root returns the root hash of the trie. // Deprecated: use Hash instead. -func (t *SimpleTrie) Root() []byte { return t.Hash().Bytes() } +func (t *Trie) Root() []byte { return t.Hash().Bytes() } // Hash returns the root hash of the trie. It does not write to the // database and can be used even if the trie doesn't have one. -func (t *SimpleTrie) Hash() common.Hash { +func (t *Trie) Hash() common.Hash { hash, cached, _ := t.hashRoot(nil) t.root = cached return common.BytesToHash(hash.(hashNode)) @@ -487,7 +482,7 @@ func (t *SimpleTrie) Hash() common.Hash { // // Committing flushes nodes from memory. // Subsequent Get calls will load nodes from the database. -func (t *SimpleTrie) Commit() (root common.Hash, err error) { +func (t *Trie) Commit() (root common.Hash, err error) { if t.db == nil { panic("Commit called on trie with nil database") } @@ -501,7 +496,7 @@ func (t *SimpleTrie) Commit() (root common.Hash, err error) { // load nodes from the trie's database. Calling code must ensure that // the changes made to db are written back to the trie's attached // database before using the trie. -func (t *SimpleTrie) CommitTo(db DatabaseWriter) (root common.Hash, err error) { +func (t *Trie) CommitTo(db DatabaseWriter) (root common.Hash, err error) { hash, cached, err := t.hashRoot(db) if err != nil { return (common.Hash{}), err @@ -511,7 +506,7 @@ func (t *SimpleTrie) CommitTo(db DatabaseWriter) (root common.Hash, err error) { return common.BytesToHash(hash.(hashNode)), nil } -func (t *SimpleTrie) hashRoot(db DatabaseWriter) (node, node, error) { +func (t *Trie) hashRoot(db DatabaseWriter) (node, node, error) { if t.root == nil { return hashNode(emptyRoot.Bytes()), nil, nil } diff --git a/trie/trie_test.go b/trie/trie_test.go index fd641d8e10..bb2861cf19 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -38,14 +38,14 @@ func init() { } // Used for testing -func newEmpty() *SimpleTrie { +func newEmpty() *Trie { db, _ := ethdb.NewMemDatabase() trie, _ := New(common.Hash{}, db, 0) return trie } func TestEmptyTrie(t *testing.T) { - var trie SimpleTrie + var trie Trie res := trie.Hash() exp := emptyRoot if res != common.Hash(exp) { @@ -54,7 +54,7 @@ func TestEmptyTrie(t *testing.T) { } func TestNull(t *testing.T) { - var trie SimpleTrie + var trie Trie key := make([]byte, 32) value := common.FromHex("0x823140710bf13990e4500136726d8b55") trie.Update(key, value) @@ -547,7 +547,7 @@ func benchGet(b *testing.B, commit bool) { } } -func benchUpdate(b *testing.B, e binary.ByteOrder) *SimpleTrie { +func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie { trie := newEmpty() k := make([]byte, 32) for i := 0; i < b.N; i++ {