diff options
author | Péter Szilágyi <peterke@gmail.com> | 2019-03-14 21:25:12 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-14 21:25:12 +0800 |
commit | 91eec1251c06727581063cd7e942ba913d806971 (patch) | |
tree | e47da6be2a8b15116b773855cf06473d5b4b64ed /core | |
parent | e270a753bec7e723e7909b55543a54e26210dd8a (diff) | |
download | go-tangerine-91eec1251c06727581063cd7e942ba913d806971.tar go-tangerine-91eec1251c06727581063cd7e942ba913d806971.tar.gz go-tangerine-91eec1251c06727581063cd7e942ba913d806971.tar.bz2 go-tangerine-91eec1251c06727581063cd7e942ba913d806971.tar.lz go-tangerine-91eec1251c06727581063cd7e942ba913d806971.tar.xz go-tangerine-91eec1251c06727581063cd7e942ba913d806971.tar.zst go-tangerine-91eec1251c06727581063cd7e942ba913d806971.zip |
cmd, core, eth, trie: get rid of trie cache generations (#19262)
* cmd, core, eth, trie: get rid of trie cache generations
* core, trie: get rid of remainder of cache gen boilerplate
Diffstat (limited to 'core')
-rw-r--r-- | core/blockchain.go | 2 | ||||
-rw-r--r-- | core/state/database.go | 109 | ||||
-rw-r--r-- | core/state/statedb.go | 1 |
3 files changed, 45 insertions, 67 deletions
diff --git a/core/blockchain.go b/core/blockchain.go index d59ee99cd..c4481588f 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -342,7 +342,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { if block == nil { return fmt.Errorf("non existent block [%x…]", hash[:4]) } - if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB(), 0); err != nil { + if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil { return err } // If all checks out, manually set the head block diff --git a/core/state/database.go b/core/state/database.go index ce085747a..8798b7380 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -18,7 +18,6 @@ package state import ( "fmt" - "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" @@ -26,14 +25,7 @@ import ( lru "github.com/hashicorp/golang-lru" ) -// Trie cache generation limit after which to evict trie nodes from memory. -var MaxTrieCacheGen = uint16(120) - const ( - // Number of past tries to keep. This value is chosen such that - // reasonable chain reorg depths will hit an existing trie. - maxPastTries = 12 - // Number of codehash->size associations to keep. codeSizeCacheSize = 100000 ) @@ -59,28 +51,61 @@ type Database interface { TrieDB() *trie.Database } -// Trie is a Ethereum Merkle Trie. +// Trie is a Ethereum Merkle Patricia trie. type Trie interface { + // GetKey returns the sha3 preimage of a hashed key that was previously used + // to store a value. + // + // TODO(fjl): remove this when SecureTrie is removed + GetKey([]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 + // trie.MissingNodeError is returned. TryGet(key []byte) ([]byte, error) + + // TryUpdate associates key with value in the trie. If value has length zero, any + // existing value is deleted from the trie. The value bytes must not be modified + // by the caller while they are stored in the trie. If a node was not found in the + // database, a trie.MissingNodeError is returned. TryUpdate(key, value []byte) error + + // TryDelete removes any existing value for key from the trie. If a node was not + // found in the database, a trie.MissingNodeError is returned. TryDelete(key []byte) error - Commit(onleaf trie.LeafCallback) (common.Hash, error) + + // 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. Hash() common.Hash + + // Commit writes all nodes to the trie's memory database, tracking the internal + // and external (for account tries) references. + Commit(onleaf trie.LeafCallback) (common.Hash, error) + + // NodeIterator returns an iterator that returns nodes of the trie. Iteration + // starts at the key after the given start key. NodeIterator(startKey []byte) trie.NodeIterator - GetKey([]byte) []byte // TODO(fjl): remove this when SecureTrie is removed + + // Prove constructs a Merkle proof for key. The result contains all encoded nodes + // on the path to the value at key. The value itself is also included in the last + // node and can be retrieved by verifying the proof. + // + // If the trie does not contain a value for key, the returned proof contains all + // nodes of the longest existing prefix of the key (at least the root), ending + // with the node that proves the absence of the key. Prove(key []byte, fromLevel uint, proofDb ethdb.Writer) error } // NewDatabase creates a backing store for state. The returned database is safe for -// concurrent use and retains a few recent expanded trie nodes in memory. To keep -// more historical state in memory, use the NewDatabaseWithCache constructor. +// concurrent use, but does not retain any recent trie nodes in memory. To keep some +// historical state in memory, use the NewDatabaseWithCache constructor. func NewDatabase(db ethdb.Database) Database { return NewDatabaseWithCache(db, 0) } -// NewDatabase creates a backing store for state. The returned database is safe for -// concurrent use and retains both a few recent expanded trie nodes in memory, as -// well as a lot of collapsed RLP trie nodes in a large memory cache. +// NewDatabaseWithCache creates a backing store for state. The returned database +// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a +// large memory cache. func NewDatabaseWithCache(db ethdb.Database, cache int) Database { csc, _ := lru.New(codeSizeCacheSize) return &cachingDB{ @@ -91,50 +116,22 @@ func NewDatabaseWithCache(db ethdb.Database, cache int) Database { type cachingDB struct { db *trie.Database - mu sync.Mutex - pastTries []*trie.SecureTrie codeSizeCache *lru.Cache } -// OpenTrie opens the main account trie. +// OpenTrie opens the main account trie at a specific root hash. func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { - db.mu.Lock() - defer db.mu.Unlock() - - for i := len(db.pastTries) - 1; i >= 0; i-- { - if db.pastTries[i].Hash() == root { - return cachedTrie{db.pastTries[i].Copy(), db}, nil - } - } - tr, err := trie.NewSecure(root, db.db, MaxTrieCacheGen) - if err != nil { - return nil, err - } - return cachedTrie{tr, db}, nil -} - -func (db *cachingDB) pushTrie(t *trie.SecureTrie) { - db.mu.Lock() - defer db.mu.Unlock() - - if len(db.pastTries) >= maxPastTries { - copy(db.pastTries, db.pastTries[1:]) - db.pastTries[len(db.pastTries)-1] = t - } else { - db.pastTries = append(db.pastTries, t) - } + return trie.NewSecure(root, db.db) } // OpenStorageTrie opens the storage trie of an account. func (db *cachingDB) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) { - return trie.NewSecure(root, db.db, 0) + return trie.NewSecure(root, db.db) } // CopyTrie returns an independent copy of the given trie. func (db *cachingDB) CopyTrie(t Trie) Trie { switch t := t.(type) { - case cachedTrie: - return cachedTrie{t.SecureTrie.Copy(), db} case *trie.SecureTrie: return t.Copy() default: @@ -164,21 +161,3 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro func (db *cachingDB) TrieDB() *trie.Database { return db.db } - -// cachedTrie inserts its trie into a cachingDB on commit. -type cachedTrie struct { - *trie.SecureTrie - db *cachingDB -} - -func (m cachedTrie) Commit(onleaf trie.LeafCallback) (common.Hash, error) { - root, err := m.SecureTrie.Commit(onleaf) - if err == nil { - m.db.pushTrie(m.SecureTrie) - } - return root, err -} - -func (m cachedTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.Writer) error { - return m.SecureTrie.Prove(key, fromLevel, proofDb) -} diff --git a/core/state/statedb.go b/core/state/statedb.go index 3fc1d3271..4c00092f4 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -662,6 +662,5 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) } return nil }) - log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads()) return root, err } |