@@ -18,22 +18,14 @@ package state
18
18
19
19
import (
20
20
"fmt"
21
- "sync"
22
21
23
22
"github.com/ethereum/go-ethereum/common"
24
23
"github.com/ethereum/go-ethereum/ethdb"
25
24
"github.com/ethereum/go-ethereum/trie"
26
25
lru "github.com/hashicorp/golang-lru"
27
26
)
28
27
29
- // Trie cache generation limit after which to evict trie nodes from memory.
30
- var MaxTrieCacheGen = uint16 (120 )
31
-
32
28
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
-
37
29
// Number of codehash->size associations to keep.
38
30
codeSizeCacheSize = 100000
39
31
)
@@ -59,28 +51,61 @@ type Database interface {
59
51
TrieDB () * trie.Database
60
52
}
61
53
62
- // Trie is a Ethereum Merkle Trie .
54
+ // Trie is a Ethereum Merkle Patricia trie .
63
55
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.
64
65
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.
65
71
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.
66
75
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.
68
79
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.
69
87
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.
71
96
Prove (key []byte , fromLevel uint , proofDb ethdb.Writer ) error
72
97
}
73
98
74
99
// 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.
77
102
func NewDatabase (db ethdb.Database ) Database {
78
103
return NewDatabaseWithCache (db , 0 )
79
104
}
80
105
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.
84
109
func NewDatabaseWithCache (db ethdb.Database , cache int ) Database {
85
110
csc , _ := lru .New (codeSizeCacheSize )
86
111
return & cachingDB {
@@ -91,50 +116,22 @@ func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
91
116
92
117
type cachingDB struct {
93
118
db * trie.Database
94
- mu sync.Mutex
95
- pastTries []* trie.SecureTrie
96
119
codeSizeCache * lru.Cache
97
120
}
98
121
99
- // OpenTrie opens the main account trie.
122
+ // OpenTrie opens the main account trie at a specific root hash .
100
123
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 )
126
125
}
127
126
128
127
// OpenStorageTrie opens the storage trie of an account.
129
128
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 )
131
130
}
132
131
133
132
// CopyTrie returns an independent copy of the given trie.
134
133
func (db * cachingDB ) CopyTrie (t Trie ) Trie {
135
134
switch t := t .(type ) {
136
- case cachedTrie :
137
- return cachedTrie {t .SecureTrie .Copy (), db }
138
135
case * trie.SecureTrie :
139
136
return t .Copy ()
140
137
default :
@@ -164,21 +161,3 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro
164
161
func (db * cachingDB ) TrieDB () * trie.Database {
165
162
return db .db
166
163
}
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
- }
0 commit comments