@@ -45,7 +45,6 @@ func (s Storage) String() (str string) {
45
45
for key , value := range s {
46
46
str += fmt .Sprintf ("%X : %X\n " , key , value )
47
47
}
48
-
49
48
return
50
49
}
51
50
@@ -54,7 +53,6 @@ func (s Storage) Copy() Storage {
54
53
for key , value := range s {
55
54
cpy [key ] = value
56
55
}
57
-
58
56
return cpy
59
57
}
60
58
@@ -73,8 +71,12 @@ type stateObject struct {
73
71
// DB error.
74
72
// State objects are used by the consensus core and VM which are
75
73
// unable to deal with database-level errors. Any error that occurs
76
- // during a database read is memoized here and will eventually be returned
77
- // by StateDB.Commit.
74
+ // during a database read is memoized here and will eventually be
75
+ // returned by StateDB.Commit. Specially, this error is used to
76
+ // represent a failed operation of:
77
+ // - storage trie read
78
+ // - contract code read
79
+ // - trie node decode
78
80
dbErr error
79
81
80
82
// Write caches.
@@ -86,7 +88,7 @@ type stateObject struct {
86
88
dirtyStorage Storage // Storage entries that have been modified in the current transaction execution
87
89
88
90
// Cache flags.
89
- // When an object is marked suicided it will be delete from the trie
91
+ // When an object is marked suicided it will be deleted from the trie
90
92
// during the "update" phase of the state transition.
91
93
dirtyCode bool // true if the code was updated
92
94
suicided bool
@@ -282,6 +284,10 @@ func (s *stateObject) finalise(prefetch bool) {
282
284
// It will return nil if the trie has not been loaded and no changes have been
283
285
// made. An error will be returned if the trie can't be loaded/updated correctly.
284
286
func (s * stateObject ) updateTrie (db Database ) (Trie , error ) {
287
+ // Short circuit if any the previous database failure is memorized.
288
+ if s .dbErr != nil {
289
+ return nil , s .dbErr
290
+ }
285
291
// Make sure all dirty slots are finalized into the pending storage area
286
292
s .finalise (false ) // Don't prefetch anymore, pull directly if need be
287
293
if len (s .pendingStorage ) == 0 {
@@ -298,7 +304,6 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) {
298
304
)
299
305
tr , err := s .getTrie (db )
300
306
if err != nil {
301
- s .setError (err )
302
307
return nil , err
303
308
}
304
309
// Insert all the pending updates into the trie
@@ -313,15 +318,13 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) {
313
318
var v []byte
314
319
if (value == common.Hash {}) {
315
320
if err := tr .TryDelete (key [:]); err != nil {
316
- s .setError (err )
317
321
return nil , err
318
322
}
319
323
s .db .StorageDeleted += 1
320
324
} else {
321
325
// Encoding []byte cannot fail, ok to ignore the error.
322
326
v , _ = rlp .EncodeToBytes (common .TrimLeftZeroes (value [:]))
323
327
if err := tr .TryUpdate (key [:], v ); err != nil {
324
- s .setError (err )
325
328
return nil , err
326
329
}
327
330
s .db .StorageUpdated += 1
@@ -348,35 +351,35 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) {
348
351
return tr , nil
349
352
}
350
353
351
- // UpdateRoot sets the trie root to the current root hash of. An error
352
- // will be returned if trie root hash is not computed correctly.
353
- func (s * stateObject ) updateRoot (db Database ) {
354
+ // updateRoot sets the trie root to the current root hash. An error
355
+ // will be returned if case any error occurs because of failed database
356
+ // reads.
357
+ func (s * stateObject ) updateRoot (db Database ) error {
354
358
tr , err := s .updateTrie (db )
355
359
if err != nil {
356
- s .setError (fmt .Errorf ("updateRoot (%x) error: %w" , s .address , err ))
357
- return
360
+ return err
358
361
}
359
362
// If nothing changed, don't bother with hashing anything
360
363
if tr == nil {
361
- return
364
+ return nil
362
365
}
363
366
// Track the amount of time wasted on hashing the storage trie
364
367
if metrics .EnabledExpensive {
365
368
defer func (start time.Time ) { s .db .StorageHashes += time .Since (start ) }(time .Now ())
366
369
}
367
370
s .data .Root = tr .Hash ()
371
+ return nil
368
372
}
369
373
370
374
// commitTrie submits the storage changes into the storage trie and re-computes
371
- // the root. Besides, all trie changes will be collected in a nodeset and returned.
375
+ // the root. Storage trie changes will be wrapped in nodeset and be returned.
376
+ // The error will be non-nil if any error occurs during trie commit operation
377
+ // or memorized in stateObject because of failed database reads.
372
378
func (s * stateObject ) commitTrie (db Database ) (* trie.NodeSet , error ) {
373
379
tr , err := s .updateTrie (db )
374
380
if err != nil {
375
381
return nil , err
376
382
}
377
- if s .dbErr != nil {
378
- return nil , s .dbErr
379
- }
380
383
// If nothing changed, don't bother with committing anything
381
384
if tr == nil {
382
385
return nil , nil
@@ -437,6 +440,7 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject {
437
440
stateObject .suicided = s .suicided
438
441
stateObject .dirtyCode = s .dirtyCode
439
442
stateObject .deleted = s .deleted
443
+ stateObject .dbErr = s .dbErr
440
444
return stateObject
441
445
}
442
446
@@ -521,10 +525,3 @@ func (s *stateObject) Balance() *big.Int {
521
525
func (s * stateObject ) Nonce () uint64 {
522
526
return s .data .Nonce
523
527
}
524
-
525
- // Value is never called, but must be present to allow stateObject to be used
526
- // as a vm.Account interface that also satisfies the vm.ContractRef
527
- // interface. Interfaces are awesome.
528
- func (s * stateObject ) Value () * big.Int {
529
- panic ("Value on stateObject should never be called" )
530
- }
0 commit comments