@@ -75,9 +75,11 @@ type StateObject struct {
75
75
dbErr error
76
76
77
77
// Write caches.
78
- trie * trie.SecureTrie // storage trie, which becomes non-nil on first access
79
- code Code // contract bytecode, which gets set when code is loaded
80
- storage Storage // Cached storage (flushed when updated)
78
+ trie * trie.SecureTrie // storage trie, which becomes non-nil on first access
79
+ code Code // contract bytecode, which gets set when code is loaded
80
+
81
+ cachedStorage Storage // Storage entry cache to avoid duplicate reads
82
+ dirtyStorage Storage // Storage entries that need to be flushed to disk
81
83
82
84
// Cache flags.
83
85
// When an object is marked for deletion it will be delete from the trie
@@ -105,7 +107,7 @@ func NewObject(address common.Address, data Account, onDirty func(addr common.Ad
105
107
if data .CodeHash == nil {
106
108
data .CodeHash = emptyCodeHash
107
109
}
108
- return & StateObject {address : address , data : data , storage : make (Storage ), onDirty : onDirty }
110
+ return & StateObject {address : address , data : data , cachedStorage : make ( Storage ), dirtyStorage : make (Storage ), onDirty : onDirty }
109
111
}
110
112
111
113
// EncodeRLP implements rlp.Encoder.
@@ -145,7 +147,7 @@ func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
145
147
146
148
// GetState returns a value in account storage.
147
149
func (self * StateObject ) GetState (db trie.Database , key common.Hash ) common.Hash {
148
- value , exists := self .storage [key ]
150
+ value , exists := self .cachedStorage [key ]
149
151
if exists {
150
152
return value
151
153
}
@@ -155,14 +157,16 @@ func (self *StateObject) GetState(db trie.Database, key common.Hash) common.Hash
155
157
rlp .DecodeBytes (tr .Get (key [:]), & ret )
156
158
value = common .BytesToHash (ret )
157
159
if (value != common.Hash {}) {
158
- self .storage [key ] = value
160
+ self .cachedStorage [key ] = value
159
161
}
160
162
return value
161
163
}
162
164
163
165
// SetState updates a value in account storage.
164
166
func (self * StateObject ) SetState (key , value common.Hash ) {
165
- self .storage [key ] = value
167
+ self .cachedStorage [key ] = value
168
+ self .dirtyStorage [key ] = value
169
+
166
170
if self .onDirty != nil {
167
171
self .onDirty (self .Address ())
168
172
self .onDirty = nil
@@ -172,7 +176,8 @@ func (self *StateObject) SetState(key, value common.Hash) {
172
176
// updateTrie writes cached storage modifications into the object's storage trie.
173
177
func (self * StateObject ) updateTrie (db trie.Database ) {
174
178
tr := self .getTrie (db )
175
- for key , value := range self .storage {
179
+ for key , value := range self .dirtyStorage {
180
+ delete (self .dirtyStorage , key )
176
181
if (value == common.Hash {}) {
177
182
tr .Delete (key [:])
178
183
continue
@@ -241,7 +246,8 @@ func (self *StateObject) Copy(db trie.Database, onDirty func(addr common.Address
241
246
stateObject := NewObject (self .address , self .data , onDirty )
242
247
stateObject .trie = self .trie
243
248
stateObject .code = self .code
244
- stateObject .storage = self .storage .Copy ()
249
+ stateObject .dirtyStorage = self .dirtyStorage .Copy ()
250
+ stateObject .cachedStorage = self .dirtyStorage .Copy ()
245
251
stateObject .remove = self .remove
246
252
stateObject .dirtyCode = self .dirtyCode
247
253
stateObject .deleted = self .deleted
@@ -312,15 +318,15 @@ func (self *StateObject) Value() *big.Int {
312
318
313
319
func (self * StateObject ) ForEachStorage (cb func (key , value common.Hash ) bool ) {
314
320
// When iterating over the storage check the cache first
315
- for h , value := range self .storage {
321
+ for h , value := range self .cachedStorage {
316
322
cb (h , value )
317
323
}
318
324
319
325
it := self .trie .Iterator ()
320
326
for it .Next () {
321
327
// ignore cached values
322
328
key := common .BytesToHash (self .trie .GetKey (it .Key ))
323
- if _ , ok := self .storage [key ]; ! ok {
329
+ if _ , ok := self .cachedStorage [key ]; ! ok {
324
330
cb (key , common .BytesToHash (it .Value ))
325
331
}
326
332
}
0 commit comments