aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2019-03-14 21:25:12 +0800
committerGitHub <noreply@github.com>2019-03-14 21:25:12 +0800
commit91eec1251c06727581063cd7e942ba913d806971 (patch)
treee47da6be2a8b15116b773855cf06473d5b4b64ed /core
parente270a753bec7e723e7909b55543a54e26210dd8a (diff)
downloadgo-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.go2
-rw-r--r--core/state/database.go109
-rw-r--r--core/state/statedb.go1
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
}