mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
triedb/pathdb: improve error handling
This commit is contained in:
parent
297cebdd38
commit
6f29a1eb8d
1 changed files with 23 additions and 6 deletions
|
|
@ -156,7 +156,13 @@ func (r *indexReaderWithLimitTag) readGreaterThan(id uint64, lastID uint64) (uin
|
||||||
if r.limit == lastID {
|
if r.limit == lastID {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
// Refresh the index reader and give another attempt
|
// Refresh the index reader and attempt again. If the latest indexed position
|
||||||
|
// is even below the ID of the disk layer, it indicates that state histories
|
||||||
|
// are being removed. In this case, it would theoretically be better to block
|
||||||
|
// the state rollback operation synchronously until all readers are released.
|
||||||
|
// Given that it's very unlikely to occur and users try to perform historical
|
||||||
|
// state queries while reverting the states at the same time. Simply returning
|
||||||
|
// an error should be sufficient for now.
|
||||||
metadata := loadIndexMetadata(r.db)
|
metadata := loadIndexMetadata(r.db)
|
||||||
if metadata == nil || metadata.Last < lastID {
|
if metadata == nil || metadata.Last < lastID {
|
||||||
return 0, errors.New("state history hasn't been indexed yet")
|
return 0, errors.New("state history hasn't been indexed yet")
|
||||||
|
|
@ -189,8 +195,11 @@ func newHistoryReader(disk ethdb.KeyValueReader, freezer ethdb.AncientReader) *h
|
||||||
// state history.
|
// state history.
|
||||||
func (r *historyReader) readAccountMetadata(address common.Address, historyID uint64) ([]byte, error) {
|
func (r *historyReader) readAccountMetadata(address common.Address, historyID uint64) ([]byte, error) {
|
||||||
blob := rawdb.ReadStateAccountIndex(r.freezer, historyID)
|
blob := rawdb.ReadStateAccountIndex(r.freezer, historyID)
|
||||||
|
if len(blob) == 0 {
|
||||||
|
return nil, fmt.Errorf("account index is truncated, historyID: %d", historyID)
|
||||||
|
}
|
||||||
if len(blob)%accountIndexSize != 0 {
|
if len(blob)%accountIndexSize != 0 {
|
||||||
return nil, fmt.Errorf("account index is corrupted, historyID: %d", historyID)
|
return nil, fmt.Errorf("account index is corrupted, historyID: %d, size: %d", historyID, len(blob))
|
||||||
}
|
}
|
||||||
n := len(blob) / accountIndexSize
|
n := len(blob) / accountIndexSize
|
||||||
|
|
||||||
|
|
@ -213,11 +222,14 @@ func (r *historyReader) readAccountMetadata(address common.Address, historyID ui
|
||||||
func (r *historyReader) readStorageMetadata(storageKey common.Hash, storageHash common.Hash, historyID uint64, slotOffset, slotNumber int) ([]byte, error) {
|
func (r *historyReader) readStorageMetadata(storageKey common.Hash, storageHash common.Hash, historyID uint64, slotOffset, slotNumber int) ([]byte, error) {
|
||||||
// TODO(rj493456442) optimize it with partial read
|
// TODO(rj493456442) optimize it with partial read
|
||||||
blob := rawdb.ReadStateStorageIndex(r.freezer, historyID)
|
blob := rawdb.ReadStateStorageIndex(r.freezer, historyID)
|
||||||
|
if len(blob) == 0 {
|
||||||
|
return nil, fmt.Errorf("storage index is truncated, historyID: %d", historyID)
|
||||||
|
}
|
||||||
if len(blob)%slotIndexSize != 0 {
|
if len(blob)%slotIndexSize != 0 {
|
||||||
return nil, fmt.Errorf("storage indices is corrupted, historyID: %d", historyID)
|
return nil, fmt.Errorf("storage indices is corrupted, historyID: %d, size: %d", historyID, len(blob))
|
||||||
}
|
}
|
||||||
if slotIndexSize*(slotOffset+slotNumber) > len(blob) {
|
if slotIndexSize*(slotOffset+slotNumber) > len(blob) {
|
||||||
return nil, errors.New("out of slice")
|
return nil, fmt.Errorf("storage indices is truncated, historyID: %d, size: %d, offset: %d, length: %d", historyID, len(blob), slotOffset, slotNumber)
|
||||||
}
|
}
|
||||||
subSlice := blob[slotIndexSize*slotOffset : slotIndexSize*(slotOffset+slotNumber)]
|
subSlice := blob[slotIndexSize*slotOffset : slotIndexSize*(slotOffset+slotNumber)]
|
||||||
|
|
||||||
|
|
@ -261,7 +273,7 @@ func (r *historyReader) readAccount(address common.Address, historyID uint64) ([
|
||||||
// TODO(rj493456442) optimize it with partial read
|
// TODO(rj493456442) optimize it with partial read
|
||||||
data := rawdb.ReadStateAccountHistory(r.freezer, historyID)
|
data := rawdb.ReadStateAccountHistory(r.freezer, historyID)
|
||||||
if len(data) < length+offset {
|
if len(data) < length+offset {
|
||||||
return nil, fmt.Errorf("account data is truncated, address: %#x, historyID: %d", address, historyID)
|
return nil, fmt.Errorf("account data is truncated, address: %#x, historyID: %d, size: %d, offset: %d, len: %d", address, historyID, len(data), offset, length)
|
||||||
}
|
}
|
||||||
return data[offset : offset+length], nil
|
return data[offset : offset+length], nil
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +301,7 @@ func (r *historyReader) readStorage(address common.Address, storageKey common.Ha
|
||||||
// TODO(rj493456442) optimize it with partial read
|
// TODO(rj493456442) optimize it with partial read
|
||||||
data := rawdb.ReadStateStorageHistory(r.freezer, historyID)
|
data := rawdb.ReadStateStorageHistory(r.freezer, historyID)
|
||||||
if len(data) < offset+length {
|
if len(data) < offset+length {
|
||||||
return nil, errors.New("corrupted storage data")
|
return nil, fmt.Errorf("storage data is truncated, address: %#x, key: %#x, historyID: %d, size: %d, offset: %d, len: %d", address, storageKey, historyID, len(data), offset, length)
|
||||||
}
|
}
|
||||||
return data[offset : offset+length], nil
|
return data[offset : offset+length], nil
|
||||||
}
|
}
|
||||||
|
|
@ -340,6 +352,11 @@ func (r *historyReader) read(state stateIdentQuery, stateID uint64, lastID uint6
|
||||||
if historyID == math.MaxUint64 {
|
if historyID == math.MaxUint64 {
|
||||||
return latestValue, nil
|
return latestValue, nil
|
||||||
}
|
}
|
||||||
|
// Resolve data from the specified state history object. Notably, since the history
|
||||||
|
// reader operates completely asynchronously with the indexer/unindexer, it's possible
|
||||||
|
// that the associated state histories are no longer available due to a rollback.
|
||||||
|
// Such truncation should be captured by the state resolver below, rather than returning
|
||||||
|
// invalid data.
|
||||||
if state.account {
|
if state.account {
|
||||||
return r.readAccount(state.address, historyID)
|
return r.readAccount(state.address, historyID)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue