@@ -264,12 +264,17 @@ func (s *stateObject) finalise(prefetch bool) {
264
264
}
265
265
}
266
266
267
- // updateTrie writes cached storage modifications into the object's storage trie.
268
- // It will return nil if the trie has not been loaded and no changes have been
269
- // made. An error will be returned if the trie can't be loaded/updated correctly.
267
+ // updateTrie is responsible for persisting cached storage changes into the
268
+ // object's storage trie. In case the storage trie is not yet loaded, this
269
+ // function will load the trie automatically. If any issues arise during the
270
+ // loading or updating of the trie, an error will be returned. Furthermore,
271
+ // this function will return the mutated storage trie, or nil if there is no
272
+ // storage change at all.
270
273
func (s * stateObject ) updateTrie () (Trie , error ) {
271
274
// Make sure all dirty slots are finalized into the pending storage area
272
- s .finalise (false ) // Don't prefetch anymore, pull directly if need be
275
+ s .finalise (false )
276
+
277
+ // Short circuit if nothing changed, don't bother with hashing anything
273
278
if len (s .pendingStorage ) == 0 {
274
279
return s .trie , nil
275
280
}
@@ -281,14 +286,13 @@ func (s *stateObject) updateTrie() (Trie, error) {
281
286
var (
282
287
storage map [common.Hash ][]byte
283
288
origin map [common.Hash ][]byte
284
- hasher = s .db .hasher
285
289
)
286
290
tr , err := s .getTrie ()
287
291
if err != nil {
288
292
s .db .setError (err )
289
293
return nil , err
290
294
}
291
- // Insert all the pending updates into the trie
295
+ // Insert all the pending storage updates into the trie
292
296
usedStorage := make ([][]byte , 0 , len (s .pendingStorage ))
293
297
for key , value := range s .pendingStorage {
294
298
// Skip noop changes, persist actual changes
@@ -298,19 +302,18 @@ func (s *stateObject) updateTrie() (Trie, error) {
298
302
prev := s .originStorage [key ]
299
303
s .originStorage [key ] = value
300
304
301
- // rlp-encoded value to be used by the snapshot
302
- var snapshotVal []byte
305
+ var encoded []byte // rlp-encoded value to be used by the snapshot
303
306
if (value == common.Hash {}) {
304
307
if err := tr .DeleteStorage (s .address , key [:]); err != nil {
305
308
s .db .setError (err )
306
309
return nil , err
307
310
}
308
311
s .db .StorageDeleted += 1
309
312
} else {
310
- trimmedVal := common .TrimLeftZeroes (value [:])
311
313
// Encoding []byte cannot fail, ok to ignore the error.
312
- snapshotVal , _ = rlp .EncodeToBytes (trimmedVal )
313
- if err := tr .UpdateStorage (s .address , key [:], trimmedVal ); err != nil {
314
+ trimmed := common .TrimLeftZeroes (value [:])
315
+ encoded , _ = rlp .EncodeToBytes (trimmed )
316
+ if err := tr .UpdateStorage (s .address , key [:], trimmed ); err != nil {
314
317
s .db .setError (err )
315
318
return nil , err
316
319
}
@@ -323,8 +326,8 @@ func (s *stateObject) updateTrie() (Trie, error) {
323
326
s .db .storages [s .addrHash ] = storage
324
327
}
325
328
}
326
- khash := crypto .HashData (hasher , key [:])
327
- storage [khash ] = snapshotVal // snapshotVal will be nil if it's deleted
329
+ khash := crypto .HashData (s . db . hasher , key [:])
330
+ storage [khash ] = encoded // encoded will be nil if it's deleted
328
331
329
332
// Cache the original value of mutated storage slots
330
333
if origin == nil {
@@ -349,21 +352,17 @@ func (s *stateObject) updateTrie() (Trie, error) {
349
352
if s .db .prefetcher != nil {
350
353
s .db .prefetcher .used (s .addrHash , s .data .Root , usedStorage )
351
354
}
352
- if len (s .pendingStorage ) > 0 {
353
- s .pendingStorage = make (Storage )
354
- }
355
+ s .pendingStorage = make (Storage ) // reset pending map
355
356
return tr , nil
356
357
}
357
358
358
- // UpdateRoot sets the trie root to the current root hash of. An error
359
- // will be returned if trie root hash is not computed correctly .
359
+ // updateRoot flushes all cached storage mutations to trie, recalculating the
360
+ // new storage trie root.
360
361
func (s * stateObject ) updateRoot () {
362
+ // Flush cached storage mutations into trie, short circuit if any error
363
+ // is occurred or there is not change in the trie.
361
364
tr , err := s .updateTrie ()
362
- if err != nil {
363
- return
364
- }
365
- // If nothing changed, don't bother with hashing anything
366
- if tr == nil {
365
+ if err != nil || tr == nil {
367
366
return
368
367
}
369
368
// Track the amount of time wasted on hashing the storage trie
@@ -373,22 +372,23 @@ func (s *stateObject) updateRoot() {
373
372
s .data .Root = tr .Hash ()
374
373
}
375
374
376
- // commit returns the changes made in storage trie and updates the account data.
375
+ // commit obtains a set of dirty storage trie nodes and updates the account data.
376
+ // The returned set can be nil if nothing to commit. This function assumes all
377
+ // storage mutations have already been flushed into trie by updateRoot.
377
378
func (s * stateObject ) commit () (* trienode.NodeSet , error ) {
378
- tr , err := s .updateTrie ()
379
- if err != nil {
380
- return nil , err
381
- }
382
- // If nothing changed, don't bother with committing anything
383
- if tr == nil {
379
+ // Short circuit if trie is not even loaded, don't bother with committing anything
380
+ if s .trie == nil {
384
381
s .origin = s .data .Copy ()
385
382
return nil , nil
386
383
}
387
384
// Track the amount of time wasted on committing the storage trie
388
385
if metrics .EnabledExpensive {
389
386
defer func (start time.Time ) { s .db .StorageCommits += time .Since (start ) }(time .Now ())
390
387
}
391
- root , nodes , err := tr .Commit (false )
388
+ // The trie is currently in an open state and could potentially contain
389
+ // cached mutations. Call commit to acquire a set of nodes that have been
390
+ // modified, the set can be nil if nothing to commit.
391
+ root , nodes , err := s .trie .Commit (false )
392
392
if err != nil {
393
393
return nil , err
394
394
}
@@ -536,3 +536,7 @@ func (s *stateObject) Balance() *big.Int {
536
536
func (s * stateObject ) Nonce () uint64 {
537
537
return s .data .Nonce
538
538
}
539
+
540
+ func (s * stateObject ) Root () common.Hash {
541
+ return s .data .Root
542
+ }
0 commit comments