@@ -148,7 +148,10 @@ func (s *stateObject) touch() {
148
148
}
149
149
}
150
150
151
- func (s * stateObject ) getTrie (db Database ) Trie {
151
+ // getTrie returns the associated storage trie. The trie will be opened
152
+ // if it's not loaded previously. An error will be returned if trie can't
153
+ // be loaded.
154
+ func (s * stateObject ) getTrie (db Database ) (Trie , error ) {
152
155
if s .trie == nil {
153
156
// Try fetching from prefetcher first
154
157
// We don't prefetch empty tries
@@ -158,15 +161,14 @@ func (s *stateObject) getTrie(db Database) Trie {
158
161
s .trie = s .db .prefetcher .trie (s .addrHash , s .data .Root )
159
162
}
160
163
if s .trie == nil {
161
- var err error
162
- s .trie , err = db .OpenStorageTrie (s .db .originalRoot , s .addrHash , s .data .Root )
164
+ tr , err := db .OpenStorageTrie (s .db .originalRoot , s .addrHash , s .data .Root )
163
165
if err != nil {
164
- s .trie , _ = db .OpenStorageTrie (s .db .originalRoot , s .addrHash , common.Hash {})
165
- s .setError (fmt .Errorf ("can't create storage trie: %v" , err ))
166
+ return nil , err
166
167
}
168
+ s .trie = tr
167
169
}
168
170
}
169
- return s .trie
171
+ return s .trie , nil
170
172
}
171
173
172
174
// GetState retrieves a value from the account storage trie.
@@ -221,7 +223,12 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
221
223
// If the snapshot is unavailable or reading from it fails, load from the database.
222
224
if s .db .snap == nil || err != nil {
223
225
start := time .Now ()
224
- enc , err = s .getTrie (db ).TryGet (key .Bytes ())
226
+ tr , err := s .getTrie (db )
227
+ if err != nil {
228
+ s .setError (err )
229
+ return common.Hash {}
230
+ }
231
+ enc , err = tr .TryGet (key .Bytes ())
225
232
if metrics .EnabledExpensive {
226
233
s .db .StorageReads += time .Since (start )
227
234
}
@@ -304,23 +311,29 @@ func (s *stateObject) finalise(prefetch bool) {
304
311
}
305
312
306
313
// updateTrie writes cached storage modifications into the object's storage trie.
307
- // It will return nil if the trie has not been loaded and no changes have been made
308
- func (s * stateObject ) updateTrie (db Database ) Trie {
314
+ // It will return nil if the trie has not been loaded and no changes have been
315
+ // made. An error will be returned if the trie can't be loaded/updated correctly.
316
+ func (s * stateObject ) updateTrie (db Database ) (Trie , error ) {
309
317
// Make sure all dirty slots are finalized into the pending storage area
310
318
s .finalise (false ) // Don't prefetch anymore, pull directly if need be
311
319
if len (s .pendingStorage ) == 0 {
312
- return s .trie
320
+ return s .trie , nil
313
321
}
314
322
// Track the amount of time wasted on updating the storage trie
315
323
if metrics .EnabledExpensive {
316
324
defer func (start time.Time ) { s .db .StorageUpdates += time .Since (start ) }(time .Now ())
317
325
}
318
326
// The snapshot storage map for the object
319
- var storage map [common.Hash ][]byte
327
+ var (
328
+ storage map [common.Hash ][]byte
329
+ hasher = s .db .hasher
330
+ )
331
+ tr , err := s .getTrie (db )
332
+ if err != nil {
333
+ s .setError (err )
334
+ return nil , err
335
+ }
320
336
// Insert all the pending updates into the trie
321
- tr := s .getTrie (db )
322
- hasher := s .db .hasher
323
-
324
337
usedStorage := make ([][]byte , 0 , len (s .pendingStorage ))
325
338
for key , value := range s .pendingStorage {
326
339
// Skip noop changes, persist actual changes
@@ -331,12 +344,18 @@ func (s *stateObject) updateTrie(db Database) Trie {
331
344
332
345
var v []byte
333
346
if (value == common.Hash {}) {
334
- s .setError (tr .TryDelete (key [:]))
347
+ if err := tr .TryDelete (key [:]); err != nil {
348
+ s .setError (err )
349
+ return nil , err
350
+ }
335
351
s .db .StorageDeleted += 1
336
352
} else {
337
353
// Encoding []byte cannot fail, ok to ignore the error.
338
354
v , _ = rlp .EncodeToBytes (common .TrimLeftZeroes (value [:]))
339
- s .setError (tr .TryUpdate (key [:], v ))
355
+ if err := tr .TryUpdate (key [:], v ); err != nil {
356
+ s .setError (err )
357
+ return nil , err
358
+ }
340
359
s .db .StorageUpdated += 1
341
360
}
342
361
// If state snapshotting is active, cache the data til commit
@@ -358,37 +377,47 @@ func (s *stateObject) updateTrie(db Database) Trie {
358
377
if len (s .pendingStorage ) > 0 {
359
378
s .pendingStorage = make (Storage )
360
379
}
361
- return tr
380
+ return tr , nil
362
381
}
363
382
364
- // UpdateRoot sets the trie root to the current root hash of
383
+ // UpdateRoot sets the trie root to the current root hash of. An error
384
+ // will be returned if trie root hash is not computed correctly.
365
385
func (s * stateObject ) updateRoot (db Database ) {
386
+ tr , err := s .updateTrie (db )
387
+ if err != nil {
388
+ s .setError (fmt .Errorf ("updateRoot (%x) error: %w" , s .address , err ))
389
+ return
390
+ }
366
391
// If nothing changed, don't bother with hashing anything
367
- if s . updateTrie ( db ) == nil {
392
+ if tr == nil {
368
393
return
369
394
}
370
395
// Track the amount of time wasted on hashing the storage trie
371
396
if metrics .EnabledExpensive {
372
397
defer func (start time.Time ) { s .db .StorageHashes += time .Since (start ) }(time .Now ())
373
398
}
374
- s .data .Root = s . trie .Hash ()
399
+ s .data .Root = tr .Hash ()
375
400
}
376
401
377
402
// commitTrie submits the storage changes into the storage trie and re-computes
378
403
// the root. Besides, all trie changes will be collected in a nodeset and returned.
379
404
func (s * stateObject ) commitTrie (db Database ) (* trie.NodeSet , error ) {
380
- // If nothing changed, don't bother with hashing anything
381
- if s . updateTrie ( db ) = = nil {
382
- return nil , nil
405
+ tr , err := s . updateTrie ( db )
406
+ if err ! = nil {
407
+ return nil , err
383
408
}
384
409
if s .dbErr != nil {
385
410
return nil , s .dbErr
386
411
}
412
+ // If nothing changed, don't bother with committing anything
413
+ if tr == nil {
414
+ return nil , nil
415
+ }
387
416
// Track the amount of time wasted on committing the storage trie
388
417
if metrics .EnabledExpensive {
389
418
defer func (start time.Time ) { s .db .StorageCommits += time .Since (start ) }(time .Now ())
390
419
}
391
- root , nodes , err := s . trie .Commit (false )
420
+ root , nodes , err := tr .Commit (false )
392
421
if err == nil {
393
422
s .data .Root = root
394
423
}
0 commit comments