mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 21:26:42 +00:00
core,triedb: read partial block index
Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
c53bde7e17
commit
95dbdb3b1d
2 changed files with 34 additions and 35 deletions
|
|
@ -188,24 +188,30 @@ func ReadStateAccountIndex(db ethdb.AncientReaderOp, id uint64) []byte {
|
||||||
// data in the concatenated storage data table. Compute the position of state
|
// data in the concatenated storage data table. Compute the position of state
|
||||||
// history in freezer by minus one since the id of first state history starts
|
// history in freezer by minus one since the id of first state history starts
|
||||||
// from one (zero for initial state).
|
// from one (zero for initial state).
|
||||||
func ReadStateStorageIndex(db ethdb.AncientReaderOp, id uint64) []byte {
|
func ReadStateStorageIndex(db ethdb.AncientReaderOp, id uint64, offset, length int) ([]byte, error) {
|
||||||
blob, err := db.Ancient(stateHistoryStorageIndex, id-1)
|
blob, err := db.AncientBytes(stateHistoryStorageIndex, id-1, uint64(offset), uint64(length))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, err
|
||||||
}
|
}
|
||||||
return blob
|
if len(blob) != length {
|
||||||
|
return blob, errors.New("state storage index data length mismatch")
|
||||||
|
}
|
||||||
|
return blob, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStateAccountHistory retrieves the concatenated account data blob for the
|
// ReadStateAccountHistory retrieves the concatenated account data blob for the
|
||||||
// specified state history. Offsets and lengths are resolved via the account
|
// specified state history. Offsets and lengths are resolved via the account
|
||||||
// index. Compute the position of state history in freezer by minus one since
|
// index. Compute the position of state history in freezer by minus one since
|
||||||
// the id of first state history starts from one (zero for initial state).
|
// the id of first state history starts from one (zero for initial state).
|
||||||
func ReadStateAccountHistory(db ethdb.AncientReaderOp, id uint64) []byte {
|
func ReadStateAccountHistory(db ethdb.AncientReaderOp, id uint64, offset, length int) ([]byte, error) {
|
||||||
blob, err := db.Ancient(stateHistoryAccountData, id-1)
|
blob, err := db.AncientBytes(stateHistoryAccountData, id-1, uint64(offset), uint64(length))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, err
|
||||||
}
|
}
|
||||||
return blob
|
if len(blob) != length {
|
||||||
|
return blob, errors.New("state account history data length mismatch")
|
||||||
|
}
|
||||||
|
return blob, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStateStorageHistory retrieves the concatenated storage slot data blob for
|
// ReadStateStorageHistory retrieves the concatenated storage slot data blob for
|
||||||
|
|
@ -213,12 +219,15 @@ func ReadStateAccountHistory(db ethdb.AncientReaderOp, id uint64) []byte {
|
||||||
// storage indexes. Compute the position of state history in freezer by minus
|
// storage indexes. Compute the position of state history in freezer by minus
|
||||||
// one since the id of first state history starts from one (zero for initial
|
// one since the id of first state history starts from one (zero for initial
|
||||||
// state).
|
// state).
|
||||||
func ReadStateStorageHistory(db ethdb.AncientReaderOp, id uint64) []byte {
|
func ReadStateStorageHistory(db ethdb.AncientReaderOp, id uint64, offset, length int) ([]byte, error) {
|
||||||
blob, err := db.Ancient(stateHistoryStorageData, id-1)
|
blob, err := db.AncientBytes(stateHistoryStorageData, id-1, uint64(offset), uint64(length))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, err
|
||||||
}
|
}
|
||||||
return blob
|
if len(blob) != length {
|
||||||
|
return blob, errors.New("state storage history data length mismatch")
|
||||||
|
}
|
||||||
|
return blob, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStateHistory retrieves the state history from database with provided id.
|
// ReadStateHistory retrieves the state history from database with provided id.
|
||||||
|
|
|
||||||
|
|
@ -144,25 +144,17 @@ func (r *historyReader) readAccountMetadata(address common.Address, historyID ui
|
||||||
// readStorageMetadata resolves the storage slot metadata within the specified
|
// readStorageMetadata resolves the storage slot metadata within the specified
|
||||||
// state history.
|
// state history.
|
||||||
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
|
data, err := rawdb.ReadStateStorageIndex(r.freezer, historyID, slotIndexSize*slotOffset, slotIndexSize*slotNumber)
|
||||||
blob := rawdb.ReadStateStorageIndex(r.freezer, historyID)
|
if err != nil {
|
||||||
if len(blob) == 0 {
|
return nil, fmt.Errorf("storage indices is truncated, historyID: %d, size: %d, offset: %d, length: %d", historyID, len(data), slotOffset, slotNumber)
|
||||||
return nil, fmt.Errorf("storage index is truncated, historyID: %d", historyID)
|
|
||||||
}
|
}
|
||||||
if len(blob)%slotIndexSize != 0 {
|
|
||||||
return nil, fmt.Errorf("storage indices is corrupted, historyID: %d, size: %d", historyID, len(blob))
|
|
||||||
}
|
|
||||||
if slotIndexSize*(slotOffset+slotNumber) > len(blob) {
|
|
||||||
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)]
|
|
||||||
|
|
||||||
// TODO(rj493456442) get rid of the metadata resolution
|
// TODO(rj493456442) get rid of the metadata resolution
|
||||||
var (
|
var (
|
||||||
m meta
|
m meta
|
||||||
target common.Hash
|
target common.Hash
|
||||||
)
|
)
|
||||||
blob = rawdb.ReadStateHistoryMeta(r.freezer, historyID)
|
blob := rawdb.ReadStateHistoryMeta(r.freezer, historyID)
|
||||||
if err := m.decode(blob); err != nil {
|
if err := m.decode(blob); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -172,17 +164,17 @@ func (r *historyReader) readStorageMetadata(storageKey common.Hash, storageHash
|
||||||
target = storageKey
|
target = storageKey
|
||||||
}
|
}
|
||||||
pos := sort.Search(slotNumber, func(i int) bool {
|
pos := sort.Search(slotNumber, func(i int) bool {
|
||||||
slotID := subSlice[slotIndexSize*i : slotIndexSize*i+common.HashLength]
|
slotID := data[slotIndexSize*i : slotIndexSize*i+common.HashLength]
|
||||||
return bytes.Compare(slotID, target.Bytes()) >= 0
|
return bytes.Compare(slotID, target.Bytes()) >= 0
|
||||||
})
|
})
|
||||||
if pos == slotNumber {
|
if pos == slotNumber {
|
||||||
return nil, fmt.Errorf("storage metadata is not found, slot key: %#x, historyID: %d", storageKey, historyID)
|
return nil, fmt.Errorf("storage metadata is not found, slot key: %#x, historyID: %d", storageKey, historyID)
|
||||||
}
|
}
|
||||||
offset := slotIndexSize * pos
|
offset := slotIndexSize * pos
|
||||||
if target != common.BytesToHash(subSlice[offset:offset+common.HashLength]) {
|
if target != common.BytesToHash(data[offset:offset+common.HashLength]) {
|
||||||
return nil, fmt.Errorf("storage metadata is not found, slot key: %#x, historyID: %d", storageKey, historyID)
|
return nil, fmt.Errorf("storage metadata is not found, slot key: %#x, historyID: %d", storageKey, historyID)
|
||||||
}
|
}
|
||||||
return subSlice[offset : slotIndexSize*(pos+1)], nil
|
return data[offset : slotIndexSize*(pos+1)], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// readAccount retrieves the account data from the specified state history.
|
// readAccount retrieves the account data from the specified state history.
|
||||||
|
|
@ -194,12 +186,11 @@ func (r *historyReader) readAccount(address common.Address, historyID uint64) ([
|
||||||
length := int(metadata[common.AddressLength]) // one byte for account data length
|
length := int(metadata[common.AddressLength]) // one byte for account data length
|
||||||
offset := int(binary.BigEndian.Uint32(metadata[common.AddressLength+1 : common.AddressLength+5])) // four bytes for the account data offset
|
offset := int(binary.BigEndian.Uint32(metadata[common.AddressLength+1 : common.AddressLength+5])) // four bytes for the account data offset
|
||||||
|
|
||||||
// TODO(rj493456442) optimize it with partial read
|
data, err := rawdb.ReadStateAccountHistory(r.freezer, historyID, offset, length)
|
||||||
data := rawdb.ReadStateAccountHistory(r.freezer, historyID)
|
if err != nil {
|
||||||
if len(data) < length+offset {
|
|
||||||
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 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, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// readStorage retrieves the storage slot data from the specified state history.
|
// readStorage retrieves the storage slot data from the specified state history.
|
||||||
|
|
@ -222,12 +213,11 @@ func (r *historyReader) readStorage(address common.Address, storageKey common.Ha
|
||||||
length := int(slotMetadata[common.HashLength]) // one byte for slot data length
|
length := int(slotMetadata[common.HashLength]) // one byte for slot data length
|
||||||
offset := int(binary.BigEndian.Uint32(slotMetadata[common.HashLength+1 : common.HashLength+5])) // four bytes for slot data offset
|
offset := int(binary.BigEndian.Uint32(slotMetadata[common.HashLength+1 : common.HashLength+5])) // four bytes for slot data offset
|
||||||
|
|
||||||
// TODO(rj493456442) optimize it with partial read
|
data, err := rawdb.ReadStateStorageHistory(r.freezer, historyID, offset, length)
|
||||||
data := rawdb.ReadStateStorageHistory(r.freezer, historyID)
|
if err != nil {
|
||||||
if len(data) < offset+length {
|
|
||||||
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 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, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// read retrieves the state element data associated with the stateID.
|
// read retrieves the state element data associated with the stateID.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue