Skip to content

Commit 91eec12

Browse files
authored
cmd, core, eth, trie: get rid of trie cache generations (ethereum#19262)
* cmd, core, eth, trie: get rid of trie cache generations * core, trie: get rid of remainder of cache gen boilerplate
1 parent e270a75 commit 91eec12

21 files changed

+100
-332
lines changed

cmd/geth/chaincmd.go

-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"github.com/ethereum/go-ethereum/eth/downloader"
3636
"github.com/ethereum/go-ethereum/event"
3737
"github.com/ethereum/go-ethereum/log"
38-
"github.com/ethereum/go-ethereum/trie"
3938
"gopkg.in/urfave/cli.v1"
4039
)
4140

@@ -261,9 +260,6 @@ func importChain(ctx *cli.Context) error {
261260
}
262261
fmt.Println(ioStats)
263262

264-
fmt.Printf("Trie cache misses: %d\n", trie.CacheMisses())
265-
fmt.Printf("Trie cache unloads: %d\n\n", trie.CacheUnloads())
266-
267263
// Print the memory statistics used by the importing
268264
mem := new(runtime.MemStats)
269265
runtime.ReadMemStats(mem)

cmd/geth/main.go

-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ var (
102102
utils.CacheDatabaseFlag,
103103
utils.CacheTrieFlag,
104104
utils.CacheGCFlag,
105-
utils.TrieCacheGenFlag,
106105
utils.ListenPortFlag,
107106
utils.MaxPeersFlag,
108107
utils.MaxPendingPeersFlag,

cmd/geth/usage.go

-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ var AppHelpFlagGroups = []flagGroup{
139139
utils.CacheDatabaseFlag,
140140
utils.CacheTrieFlag,
141141
utils.CacheGCFlag,
142-
utils.TrieCacheGenFlag,
143142
},
144143
},
145144
{

cmd/utils/flags.go

-10
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import (
3737
"github.com/ethereum/go-ethereum/consensus/clique"
3838
"github.com/ethereum/go-ethereum/consensus/ethash"
3939
"github.com/ethereum/go-ethereum/core"
40-
"github.com/ethereum/go-ethereum/core/state"
4140
"github.com/ethereum/go-ethereum/core/vm"
4241
"github.com/ethereum/go-ethereum/crypto"
4342
"github.com/ethereum/go-ethereum/dashboard"
@@ -350,11 +349,6 @@ var (
350349
Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)",
351350
Value: 25,
352351
}
353-
TrieCacheGenFlag = cli.IntFlag{
354-
Name: "trie-cache-gens",
355-
Usage: "Number of trie node generations to keep in memory",
356-
Value: int(state.MaxTrieCacheGen),
357-
}
358352
// Miner settings
359353
MiningEnabledFlag = cli.BoolFlag{
360354
Name: "mine",
@@ -1432,10 +1426,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
14321426
cfg.MinerGasPrice = big.NewInt(1)
14331427
}
14341428
}
1435-
// TODO(fjl): move trie cache generations into config
1436-
if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
1437-
state.MaxTrieCacheGen = uint16(gen)
1438-
}
14391429
}
14401430

14411431
// SetDashboardConfig applies dashboard related command line flags to the config.

core/blockchain.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
342342
if block == nil {
343343
return fmt.Errorf("non existent block [%x…]", hash[:4])
344344
}
345-
if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB(), 0); err != nil {
345+
if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil {
346346
return err
347347
}
348348
// If all checks out, manually set the head block

core/state/database.go

+44-65
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,14 @@ package state
1818

1919
import (
2020
"fmt"
21-
"sync"
2221

2322
"github.com/ethereum/go-ethereum/common"
2423
"github.com/ethereum/go-ethereum/ethdb"
2524
"github.com/ethereum/go-ethereum/trie"
2625
lru "github.com/hashicorp/golang-lru"
2726
)
2827

29-
// Trie cache generation limit after which to evict trie nodes from memory.
30-
var MaxTrieCacheGen = uint16(120)
31-
3228
const (
33-
// Number of past tries to keep. This value is chosen such that
34-
// reasonable chain reorg depths will hit an existing trie.
35-
maxPastTries = 12
36-
3729
// Number of codehash->size associations to keep.
3830
codeSizeCacheSize = 100000
3931
)
@@ -59,28 +51,61 @@ type Database interface {
5951
TrieDB() *trie.Database
6052
}
6153

62-
// Trie is a Ethereum Merkle Trie.
54+
// Trie is a Ethereum Merkle Patricia trie.
6355
type Trie interface {
56+
// GetKey returns the sha3 preimage of a hashed key that was previously used
57+
// to store a value.
58+
//
59+
// TODO(fjl): remove this when SecureTrie is removed
60+
GetKey([]byte) []byte
61+
62+
// TryGet returns the value for key stored in the trie. The value bytes must
63+
// not be modified by the caller. If a node was not found in the database, a
64+
// trie.MissingNodeError is returned.
6465
TryGet(key []byte) ([]byte, error)
66+
67+
// TryUpdate associates key with value in the trie. If value has length zero, any
68+
// existing value is deleted from the trie. The value bytes must not be modified
69+
// by the caller while they are stored in the trie. If a node was not found in the
70+
// database, a trie.MissingNodeError is returned.
6571
TryUpdate(key, value []byte) error
72+
73+
// TryDelete removes any existing value for key from the trie. If a node was not
74+
// found in the database, a trie.MissingNodeError is returned.
6675
TryDelete(key []byte) error
67-
Commit(onleaf trie.LeafCallback) (common.Hash, error)
76+
77+
// Hash returns the root hash of the trie. It does not write to the database and
78+
// can be used even if the trie doesn't have one.
6879
Hash() common.Hash
80+
81+
// Commit writes all nodes to the trie's memory database, tracking the internal
82+
// and external (for account tries) references.
83+
Commit(onleaf trie.LeafCallback) (common.Hash, error)
84+
85+
// NodeIterator returns an iterator that returns nodes of the trie. Iteration
86+
// starts at the key after the given start key.
6987
NodeIterator(startKey []byte) trie.NodeIterator
70-
GetKey([]byte) []byte // TODO(fjl): remove this when SecureTrie is removed
88+
89+
// Prove constructs a Merkle proof for key. The result contains all encoded nodes
90+
// on the path to the value at key. The value itself is also included in the last
91+
// node and can be retrieved by verifying the proof.
92+
//
93+
// If the trie does not contain a value for key, the returned proof contains all
94+
// nodes of the longest existing prefix of the key (at least the root), ending
95+
// with the node that proves the absence of the key.
7196
Prove(key []byte, fromLevel uint, proofDb ethdb.Writer) error
7297
}
7398

7499
// NewDatabase creates a backing store for state. The returned database is safe for
75-
// concurrent use and retains a few recent expanded trie nodes in memory. To keep
76-
// more historical state in memory, use the NewDatabaseWithCache constructor.
100+
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
101+
// historical state in memory, use the NewDatabaseWithCache constructor.
77102
func NewDatabase(db ethdb.Database) Database {
78103
return NewDatabaseWithCache(db, 0)
79104
}
80105

81-
// NewDatabase creates a backing store for state. The returned database is safe for
82-
// concurrent use and retains both a few recent expanded trie nodes in memory, as
83-
// well as a lot of collapsed RLP trie nodes in a large memory cache.
106+
// NewDatabaseWithCache creates a backing store for state. The returned database
107+
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
108+
// large memory cache.
84109
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
85110
csc, _ := lru.New(codeSizeCacheSize)
86111
return &cachingDB{
@@ -91,50 +116,22 @@ func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
91116

92117
type cachingDB struct {
93118
db *trie.Database
94-
mu sync.Mutex
95-
pastTries []*trie.SecureTrie
96119
codeSizeCache *lru.Cache
97120
}
98121

99-
// OpenTrie opens the main account trie.
122+
// OpenTrie opens the main account trie at a specific root hash.
100123
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
101-
db.mu.Lock()
102-
defer db.mu.Unlock()
103-
104-
for i := len(db.pastTries) - 1; i >= 0; i-- {
105-
if db.pastTries[i].Hash() == root {
106-
return cachedTrie{db.pastTries[i].Copy(), db}, nil
107-
}
108-
}
109-
tr, err := trie.NewSecure(root, db.db, MaxTrieCacheGen)
110-
if err != nil {
111-
return nil, err
112-
}
113-
return cachedTrie{tr, db}, nil
114-
}
115-
116-
func (db *cachingDB) pushTrie(t *trie.SecureTrie) {
117-
db.mu.Lock()
118-
defer db.mu.Unlock()
119-
120-
if len(db.pastTries) >= maxPastTries {
121-
copy(db.pastTries, db.pastTries[1:])
122-
db.pastTries[len(db.pastTries)-1] = t
123-
} else {
124-
db.pastTries = append(db.pastTries, t)
125-
}
124+
return trie.NewSecure(root, db.db)
126125
}
127126

128127
// OpenStorageTrie opens the storage trie of an account.
129128
func (db *cachingDB) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) {
130-
return trie.NewSecure(root, db.db, 0)
129+
return trie.NewSecure(root, db.db)
131130
}
132131

133132
// CopyTrie returns an independent copy of the given trie.
134133
func (db *cachingDB) CopyTrie(t Trie) Trie {
135134
switch t := t.(type) {
136-
case cachedTrie:
137-
return cachedTrie{t.SecureTrie.Copy(), db}
138135
case *trie.SecureTrie:
139136
return t.Copy()
140137
default:
@@ -164,21 +161,3 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro
164161
func (db *cachingDB) TrieDB() *trie.Database {
165162
return db.db
166163
}
167-
168-
// cachedTrie inserts its trie into a cachingDB on commit.
169-
type cachedTrie struct {
170-
*trie.SecureTrie
171-
db *cachingDB
172-
}
173-
174-
func (m cachedTrie) Commit(onleaf trie.LeafCallback) (common.Hash, error) {
175-
root, err := m.SecureTrie.Commit(onleaf)
176-
if err == nil {
177-
m.db.pushTrie(m.SecureTrie)
178-
}
179-
return root, err
180-
}
181-
182-
func (m cachedTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.Writer) error {
183-
return m.SecureTrie.Prove(key, fromLevel, proofDb)
184-
}

core/state/statedb.go

-1
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,5 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
662662
}
663663
return nil
664664
})
665-
log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads())
666665
return root, err
667666
}

eth/api.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,11 @@ func (api *PrivateDebugAPI) getModifiedAccounts(startBlock, endBlock *types.Bloc
446446
}
447447
triedb := api.eth.BlockChain().StateCache().TrieDB()
448448

449-
oldTrie, err := trie.NewSecure(startBlock.Root(), triedb, 0)
449+
oldTrie, err := trie.NewSecure(startBlock.Root(), triedb)
450450
if err != nil {
451451
return nil, err
452452
}
453-
newTrie, err := trie.NewSecure(endBlock.Root(), triedb, 0)
453+
newTrie, err := trie.NewSecure(endBlock.Root(), triedb)
454454
if err != nil {
455455
return nil, err
456456
}

eth/downloader/downloader_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (dl *downloadTester) CurrentFastBlock() *types.Block {
187187
func (dl *downloadTester) FastSyncCommitHead(hash common.Hash) error {
188188
// For now only check that the state trie is correct
189189
if block := dl.GetBlockByHash(hash); block != nil {
190-
_, err := trie.NewSecure(block.Root(), trie.NewDatabase(dl.stateDb), 0)
190+
_, err := trie.NewSecure(block.Root(), trie.NewDatabase(dl.stateDb))
191191
return err
192192
}
193193
return fmt.Errorf("non existent block: %x", hash[:4])

trie/database.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,11 @@ func (n *cachedNode) rlp() []byte {
154154

155155
// obj returns the decoded and expanded trie node, either directly from the cache,
156156
// or by regenerating it from the rlp encoded blob.
157-
func (n *cachedNode) obj(hash common.Hash, cachegen uint16) node {
157+
func (n *cachedNode) obj(hash common.Hash) node {
158158
if node, ok := n.node.(rawNode); ok {
159-
return mustDecodeNode(hash[:], node, cachegen)
159+
return mustDecodeNode(hash[:], node)
160160
}
161-
return expandNode(hash[:], n.node, cachegen)
161+
return expandNode(hash[:], n.node)
162162
}
163163

164164
// childs returns all the tracked children of this node, both the implicit ones
@@ -223,16 +223,15 @@ func simplifyNode(n node) node {
223223

224224
// expandNode traverses the node hierarchy of a collapsed storage node and converts
225225
// all fields and keys into expanded memory form.
226-
func expandNode(hash hashNode, n node, cachegen uint16) node {
226+
func expandNode(hash hashNode, n node) node {
227227
switch n := n.(type) {
228228
case *rawShortNode:
229229
// Short nodes need key and child expansion
230230
return &shortNode{
231231
Key: compactToHex(n.Key),
232-
Val: expandNode(nil, n.Val, cachegen),
232+
Val: expandNode(nil, n.Val),
233233
flags: nodeFlag{
234234
hash: hash,
235-
gen: cachegen,
236235
},
237236
}
238237

@@ -241,12 +240,11 @@ func expandNode(hash hashNode, n node, cachegen uint16) node {
241240
node := &fullNode{
242241
flags: nodeFlag{
243242
hash: hash,
244-
gen: cachegen,
245243
},
246244
}
247245
for i := 0; i < len(node.Children); i++ {
248246
if n[i] != nil {
249-
node.Children[i] = expandNode(nil, n[i], cachegen)
247+
node.Children[i] = expandNode(nil, n[i])
250248
}
251249
}
252250
return node
@@ -349,13 +347,13 @@ func (db *Database) insertPreimage(hash common.Hash, preimage []byte) {
349347

350348
// node retrieves a cached trie node from memory, or returns nil if none can be
351349
// found in the memory cache.
352-
func (db *Database) node(hash common.Hash, cachegen uint16) node {
350+
func (db *Database) node(hash common.Hash) node {
353351
// Retrieve the node from the clean cache if available
354352
if db.cleans != nil {
355353
if enc, err := db.cleans.Get(string(hash[:])); err == nil && enc != nil {
356354
memcacheCleanHitMeter.Mark(1)
357355
memcacheCleanReadMeter.Mark(int64(len(enc)))
358-
return mustDecodeNode(hash[:], enc, cachegen)
356+
return mustDecodeNode(hash[:], enc)
359357
}
360358
}
361359
// Retrieve the node from the dirty cache if available
@@ -364,7 +362,7 @@ func (db *Database) node(hash common.Hash, cachegen uint16) node {
364362
db.lock.RUnlock()
365363

366364
if dirty != nil {
367-
return dirty.obj(hash, cachegen)
365+
return dirty.obj(hash)
368366
}
369367
// Content unavailable in memory, attempt to retrieve from disk
370368
enc, err := db.diskdb.Get(hash[:])
@@ -376,7 +374,7 @@ func (db *Database) node(hash common.Hash, cachegen uint16) node {
376374
memcacheCleanMissMeter.Mark(1)
377375
memcacheCleanWriteMeter.Mark(int64(len(enc)))
378376
}
379-
return mustDecodeNode(hash[:], enc, cachegen)
377+
return mustDecodeNode(hash[:], enc)
380378
}
381379

382380
// Node retrieves an encoded cached trie node from memory. If it cannot be found

0 commit comments

Comments
 (0)