mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
core/rawdb, triedb/pathdb: use account hash as the database key
This commit is contained in:
parent
1370ed79fb
commit
aa65b94969
9 changed files with 140 additions and 124 deletions
|
|
@ -47,8 +47,8 @@ func DeleteStateHistoryIndexMetadata(db ethdb.KeyValueWriter) {
|
||||||
|
|
||||||
// ReadAccountHistoryIndex retrieves the account history index with the provided
|
// ReadAccountHistoryIndex retrieves the account history index with the provided
|
||||||
// account address.
|
// account address.
|
||||||
func ReadAccountHistoryIndex(db ethdb.KeyValueReader, address common.Address) []byte {
|
func ReadAccountHistoryIndex(db ethdb.KeyValueReader, addressHash common.Hash) []byte {
|
||||||
data, err := db.Get(accountHistoryIndexKey(address))
|
data, err := db.Get(accountHistoryIndexKey(addressHash))
|
||||||
if err != nil || len(data) == 0 {
|
if err != nil || len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -56,24 +56,24 @@ func ReadAccountHistoryIndex(db ethdb.KeyValueReader, address common.Address) []
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteAccountHistoryIndex writes the provided account history index into database.
|
// WriteAccountHistoryIndex writes the provided account history index into database.
|
||||||
func WriteAccountHistoryIndex(db ethdb.KeyValueWriter, address common.Address, data []byte) {
|
func WriteAccountHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, data []byte) {
|
||||||
if err := db.Put(accountHistoryIndexKey(address), data); err != nil {
|
if err := db.Put(accountHistoryIndexKey(addressHash), data); err != nil {
|
||||||
log.Crit("Failed to store account history index", "err", err)
|
log.Crit("Failed to store account history index", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAccountHistoryIndex deletes the specified account history index from
|
// DeleteAccountHistoryIndex deletes the specified account history index from
|
||||||
// the database.
|
// the database.
|
||||||
func DeleteAccountHistoryIndex(db ethdb.KeyValueWriter, address common.Address) {
|
func DeleteAccountHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash) {
|
||||||
if err := db.Delete(accountHistoryIndexKey(address)); err != nil {
|
if err := db.Delete(accountHistoryIndexKey(addressHash)); err != nil {
|
||||||
log.Crit("Failed to delete account history index", "err", err)
|
log.Crit("Failed to delete account history index", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStorageHistoryIndex retrieves the storage history index with the provided
|
// ReadStorageHistoryIndex retrieves the storage history index with the provided
|
||||||
// account address and storage key hash.
|
// account address and storage key hash.
|
||||||
func ReadStorageHistoryIndex(db ethdb.KeyValueReader, address common.Address, storageHash common.Hash) []byte {
|
func ReadStorageHistoryIndex(db ethdb.KeyValueReader, addressHash common.Hash, storageHash common.Hash) []byte {
|
||||||
data, err := db.Get(storageHistoryIndexKey(address, storageHash))
|
data, err := db.Get(storageHistoryIndexKey(addressHash, storageHash))
|
||||||
if err != nil || len(data) == 0 {
|
if err != nil || len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -81,23 +81,23 @@ func ReadStorageHistoryIndex(db ethdb.KeyValueReader, address common.Address, st
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteStorageHistoryIndex writes the provided storage history index into database.
|
// WriteStorageHistoryIndex writes the provided storage history index into database.
|
||||||
func WriteStorageHistoryIndex(db ethdb.KeyValueWriter, address common.Address, storageHash common.Hash, data []byte) {
|
func WriteStorageHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash, data []byte) {
|
||||||
if err := db.Put(storageHistoryIndexKey(address, storageHash), data); err != nil {
|
if err := db.Put(storageHistoryIndexKey(addressHash, storageHash), data); err != nil {
|
||||||
log.Crit("Failed to store storage history index", "err", err)
|
log.Crit("Failed to store storage history index", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteStorageHistoryIndex deletes the specified state index from the database.
|
// DeleteStorageHistoryIndex deletes the specified state index from the database.
|
||||||
func DeleteStorageHistoryIndex(db ethdb.KeyValueWriter, address common.Address, storageHash common.Hash) {
|
func DeleteStorageHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash) {
|
||||||
if err := db.Delete(storageHistoryIndexKey(address, storageHash)); err != nil {
|
if err := db.Delete(storageHistoryIndexKey(addressHash, storageHash)); err != nil {
|
||||||
log.Crit("Failed to delete storage history index", "err", err)
|
log.Crit("Failed to delete storage history index", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAccountHistoryIndexBlock retrieves the index block with the provided
|
// ReadAccountHistoryIndexBlock retrieves the index block with the provided
|
||||||
// account address along with the block id.
|
// account address along with the block id.
|
||||||
func ReadAccountHistoryIndexBlock(db ethdb.KeyValueReader, address common.Address, blockID uint32) []byte {
|
func ReadAccountHistoryIndexBlock(db ethdb.KeyValueReader, addressHash common.Hash, blockID uint32) []byte {
|
||||||
data, err := db.Get(accountHistoryIndexBlockKey(address, blockID))
|
data, err := db.Get(accountHistoryIndexBlockKey(addressHash, blockID))
|
||||||
if err != nil || len(data) == 0 {
|
if err != nil || len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -105,23 +105,23 @@ func ReadAccountHistoryIndexBlock(db ethdb.KeyValueReader, address common.Addres
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteAccountHistoryIndexBlock writes the provided index block into database.
|
// WriteAccountHistoryIndexBlock writes the provided index block into database.
|
||||||
func WriteAccountHistoryIndexBlock(db ethdb.KeyValueWriter, address common.Address, blockID uint32, data []byte) {
|
func WriteAccountHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, blockID uint32, data []byte) {
|
||||||
if err := db.Put(accountHistoryIndexBlockKey(address, blockID), data); err != nil {
|
if err := db.Put(accountHistoryIndexBlockKey(addressHash, blockID), data); err != nil {
|
||||||
log.Crit("Failed to store account index block", "err", err)
|
log.Crit("Failed to store account index block", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAccountHistoryIndexBlock deletes the specified index block from the database.
|
// DeleteAccountHistoryIndexBlock deletes the specified index block from the database.
|
||||||
func DeleteAccountHistoryIndexBlock(db ethdb.KeyValueWriter, address common.Address, blockID uint32) {
|
func DeleteAccountHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, blockID uint32) {
|
||||||
if err := db.Delete(accountHistoryIndexBlockKey(address, blockID)); err != nil {
|
if err := db.Delete(accountHistoryIndexBlockKey(addressHash, blockID)); err != nil {
|
||||||
log.Crit("Failed to delete account index block", "err", err)
|
log.Crit("Failed to delete account index block", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStorageHistoryIndexBlock retrieves the index block with the provided state
|
// ReadStorageHistoryIndexBlock retrieves the index block with the provided state
|
||||||
// identifier along with the block id.
|
// identifier along with the block id.
|
||||||
func ReadStorageHistoryIndexBlock(db ethdb.KeyValueReader, address common.Address, storageHash common.Hash, blockID uint32) []byte {
|
func ReadStorageHistoryIndexBlock(db ethdb.KeyValueReader, addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte {
|
||||||
data, err := db.Get(storageHistoryIndexBlockKey(address, storageHash, blockID))
|
data, err := db.Get(storageHistoryIndexBlockKey(addressHash, storageHash, blockID))
|
||||||
if err != nil || len(data) == 0 {
|
if err != nil || len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -129,15 +129,15 @@ func ReadStorageHistoryIndexBlock(db ethdb.KeyValueReader, address common.Addres
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteStorageHistoryIndexBlock writes the provided index block into database.
|
// WriteStorageHistoryIndexBlock writes the provided index block into database.
|
||||||
func WriteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, address common.Address, storageHash common.Hash, id uint32, data []byte) {
|
func WriteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash, id uint32, data []byte) {
|
||||||
if err := db.Put(storageHistoryIndexBlockKey(address, storageHash, id), data); err != nil {
|
if err := db.Put(storageHistoryIndexBlockKey(addressHash, storageHash, id), data); err != nil {
|
||||||
log.Crit("Failed to store storage index block", "err", err)
|
log.Crit("Failed to store storage index block", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteStorageHistoryIndexBlock deletes the specified index block from the database.
|
// DeleteStorageHistoryIndexBlock deletes the specified index block from the database.
|
||||||
func DeleteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, address common.Address, state common.Hash, id uint32) {
|
func DeleteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash, id uint32) {
|
||||||
if err := db.Delete(storageHistoryIndexBlockKey(address, state, id)); err != nil {
|
if err := db.Delete(storageHistoryIndexBlockKey(addressHash, storageHash, id)); err != nil {
|
||||||
log.Crit("Failed to delete storage index block", "err", err)
|
log.Crit("Failed to delete storage index block", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -493,7 +493,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
|
||||||
bloomBits.Add(size)
|
bloomBits.Add(size)
|
||||||
|
|
||||||
// Path-based historic state indexes
|
// Path-based historic state indexes
|
||||||
case bytes.HasPrefix(key, StateHistoryIndexPrefix) && len(key) >= len(StateHistoryIndexPrefix)+common.AddressLength:
|
case bytes.HasPrefix(key, StateHistoryIndexPrefix) && len(key) >= len(StateHistoryIndexPrefix)+common.HashLength:
|
||||||
stateIndex.Add(size)
|
stateIndex.Add(size)
|
||||||
|
|
||||||
// Verkle trie data is detected, determine the sub-category
|
// Verkle trie data is detected, determine the sub-category
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ var (
|
||||||
stateIDPrefix = []byte("L") // stateIDPrefix + state root -> state id
|
stateIDPrefix = []byte("L") // stateIDPrefix + state root -> state id
|
||||||
|
|
||||||
// State history indexing within path-based storage scheme
|
// State history indexing within path-based storage scheme
|
||||||
StateHistoryIndexPrefix = []byte("m") // StateHistoryIndexPrefix + account address or (account address + slotHash) -> index
|
StateHistoryIndexPrefix = []byte("m") // StateHistoryIndexPrefix + account address hash or (account address hash + slotHash) -> index
|
||||||
|
|
||||||
// VerklePrefix is the database prefix for Verkle trie data, which includes:
|
// VerklePrefix is the database prefix for Verkle trie data, which includes:
|
||||||
// (a) Trie nodes
|
// (a) Trie nodes
|
||||||
|
|
@ -370,26 +370,26 @@ func filterMapBlockLVKey(number uint64) []byte {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountHistoryIndexKey = StateHistoryIndexPrefix + address
|
// accountHistoryIndexKey = StateHistoryIndexPrefix + addressHash
|
||||||
func accountHistoryIndexKey(address common.Address) []byte {
|
func accountHistoryIndexKey(addressHash common.Hash) []byte {
|
||||||
return append(StateHistoryIndexPrefix, address.Bytes()...)
|
return append(StateHistoryIndexPrefix, addressHash.Bytes()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageHistoryIndexKey = StateHistoryIndexPrefix + address + storageHash
|
// storageHistoryIndexKey = StateHistoryIndexPrefix + addressHash + storageHash
|
||||||
func storageHistoryIndexKey(address common.Address, storageHash common.Hash) []byte {
|
func storageHistoryIndexKey(addressHash common.Hash, storageHash common.Hash) []byte {
|
||||||
return append(append(StateHistoryIndexPrefix, address.Bytes()...), storageHash.Bytes()...)
|
return append(append(StateHistoryIndexPrefix, addressHash.Bytes()...), storageHash.Bytes()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountHistoryIndexBlockKey = StateHistoryIndexPrefix + address + blockID
|
// accountHistoryIndexBlockKey = StateHistoryIndexPrefix + addressHash + blockID
|
||||||
func accountHistoryIndexBlockKey(address common.Address, blockID uint32) []byte {
|
func accountHistoryIndexBlockKey(addressHash common.Hash, blockID uint32) []byte {
|
||||||
var buf [4]byte
|
var buf [4]byte
|
||||||
binary.BigEndian.PutUint32(buf[:], blockID)
|
binary.BigEndian.PutUint32(buf[:], blockID)
|
||||||
return append(append(StateHistoryIndexPrefix, address.Bytes()...), buf[:]...)
|
return append(append(StateHistoryIndexPrefix, addressHash.Bytes()...), buf[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// storageHistoryIndexBlockKey = StateHistoryIndexPrefix + address + storageHash + blockID
|
// storageHistoryIndexBlockKey = StateHistoryIndexPrefix + addressHash + storageHash + blockID
|
||||||
func storageHistoryIndexBlockKey(address common.Address, storageHash common.Hash, blockID uint32) []byte {
|
func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte {
|
||||||
var buf [4]byte
|
var buf [4]byte
|
||||||
binary.BigEndian.PutUint32(buf[:], blockID)
|
binary.BigEndian.PutUint32(buf[:], blockID)
|
||||||
return append(append(append(StateHistoryIndexPrefix, address.Bytes()...), storageHash.Bytes()...), buf[:]...)
|
return append(append(append(StateHistoryIndexPrefix, addressHash.Bytes()...), storageHash.Bytes()...), buf[:]...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,9 +80,9 @@ type indexReader struct {
|
||||||
func loadIndexData(db ethdb.KeyValueReader, state stateIdent) ([]*indexBlockDesc, error) {
|
func loadIndexData(db ethdb.KeyValueReader, state stateIdent) ([]*indexBlockDesc, error) {
|
||||||
var blob []byte
|
var blob []byte
|
||||||
if state.account {
|
if state.account {
|
||||||
blob = rawdb.ReadAccountHistoryIndex(db, state.address)
|
blob = rawdb.ReadAccountHistoryIndex(db, state.addressHash)
|
||||||
} else {
|
} else {
|
||||||
blob = rawdb.ReadStorageHistoryIndex(db, state.address, state.storageHash)
|
blob = rawdb.ReadStorageHistoryIndex(db, state.addressHash, state.storageHash)
|
||||||
}
|
}
|
||||||
if len(blob) == 0 {
|
if len(blob) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -142,9 +142,9 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) {
|
||||||
blob []byte
|
blob []byte
|
||||||
)
|
)
|
||||||
if r.state.account {
|
if r.state.account {
|
||||||
blob = rawdb.ReadAccountHistoryIndexBlock(r.db, r.state.address, desc.id)
|
blob = rawdb.ReadAccountHistoryIndexBlock(r.db, r.state.addressHash, desc.id)
|
||||||
} else {
|
} else {
|
||||||
blob = rawdb.ReadStorageHistoryIndexBlock(r.db, r.state.address, r.state.storageHash, desc.id)
|
blob = rawdb.ReadStorageHistoryIndexBlock(r.db, r.state.addressHash, r.state.storageHash, desc.id)
|
||||||
}
|
}
|
||||||
br, err = newBlockReader(blob)
|
br, err = newBlockReader(blob)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -176,9 +176,9 @@ type indexWriter struct {
|
||||||
func newIndexWriter(db ethdb.KeyValueReader, state stateIdent) (*indexWriter, error) {
|
func newIndexWriter(db ethdb.KeyValueReader, state stateIdent) (*indexWriter, error) {
|
||||||
var blob []byte
|
var blob []byte
|
||||||
if state.account {
|
if state.account {
|
||||||
blob = rawdb.ReadAccountHistoryIndex(db, state.address)
|
blob = rawdb.ReadAccountHistoryIndex(db, state.addressHash)
|
||||||
} else {
|
} else {
|
||||||
blob = rawdb.ReadStorageHistoryIndex(db, state.address, state.storageHash)
|
blob = rawdb.ReadStorageHistoryIndex(db, state.addressHash, state.storageHash)
|
||||||
}
|
}
|
||||||
if len(blob) == 0 {
|
if len(blob) == 0 {
|
||||||
desc := newIndexBlockDesc(0)
|
desc := newIndexBlockDesc(0)
|
||||||
|
|
@ -199,9 +199,9 @@ func newIndexWriter(db ethdb.KeyValueReader, state stateIdent) (*indexWriter, er
|
||||||
lastDesc = descList[len(descList)-1]
|
lastDesc = descList[len(descList)-1]
|
||||||
)
|
)
|
||||||
if state.account {
|
if state.account {
|
||||||
indexBlock = rawdb.ReadAccountHistoryIndexBlock(db, state.address, lastDesc.id)
|
indexBlock = rawdb.ReadAccountHistoryIndexBlock(db, state.addressHash, lastDesc.id)
|
||||||
} else {
|
} else {
|
||||||
indexBlock = rawdb.ReadStorageHistoryIndexBlock(db, state.address, state.storageHash, lastDesc.id)
|
indexBlock = rawdb.ReadStorageHistoryIndexBlock(db, state.addressHash, state.storageHash, lastDesc.id)
|
||||||
}
|
}
|
||||||
bw, err := newBlockWriter(indexBlock, lastDesc)
|
bw, err := newBlockWriter(indexBlock, lastDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -271,9 +271,9 @@ func (w *indexWriter) finish(batch ethdb.Batch) {
|
||||||
}
|
}
|
||||||
for _, bw := range writers {
|
for _, bw := range writers {
|
||||||
if w.state.account {
|
if w.state.account {
|
||||||
rawdb.WriteAccountHistoryIndexBlock(batch, w.state.address, bw.desc.id, bw.finish())
|
rawdb.WriteAccountHistoryIndexBlock(batch, w.state.addressHash, bw.desc.id, bw.finish())
|
||||||
} else {
|
} else {
|
||||||
rawdb.WriteStorageHistoryIndexBlock(batch, w.state.address, w.state.storageHash, bw.desc.id, bw.finish())
|
rawdb.WriteStorageHistoryIndexBlock(batch, w.state.addressHash, w.state.storageHash, bw.desc.id, bw.finish())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.frozen = nil // release all the frozen writers
|
w.frozen = nil // release all the frozen writers
|
||||||
|
|
@ -283,9 +283,9 @@ func (w *indexWriter) finish(batch ethdb.Batch) {
|
||||||
buf = append(buf, desc.encode()...)
|
buf = append(buf, desc.encode()...)
|
||||||
}
|
}
|
||||||
if w.state.account {
|
if w.state.account {
|
||||||
rawdb.WriteAccountHistoryIndex(batch, w.state.address, buf)
|
rawdb.WriteAccountHistoryIndex(batch, w.state.addressHash, buf)
|
||||||
} else {
|
} else {
|
||||||
rawdb.WriteStorageHistoryIndex(batch, w.state.address, w.state.storageHash, buf)
|
rawdb.WriteStorageHistoryIndex(batch, w.state.addressHash, w.state.storageHash, buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,9 +303,9 @@ type indexDeleter struct {
|
||||||
func newIndexDeleter(db ethdb.KeyValueReader, state stateIdent) (*indexDeleter, error) {
|
func newIndexDeleter(db ethdb.KeyValueReader, state stateIdent) (*indexDeleter, error) {
|
||||||
var blob []byte
|
var blob []byte
|
||||||
if state.account {
|
if state.account {
|
||||||
blob = rawdb.ReadAccountHistoryIndex(db, state.address)
|
blob = rawdb.ReadAccountHistoryIndex(db, state.addressHash)
|
||||||
} else {
|
} else {
|
||||||
blob = rawdb.ReadStorageHistoryIndex(db, state.address, state.storageHash)
|
blob = rawdb.ReadStorageHistoryIndex(db, state.addressHash, state.storageHash)
|
||||||
}
|
}
|
||||||
if len(blob) == 0 {
|
if len(blob) == 0 {
|
||||||
// TODO(rjl493456442) we can probably return an error here,
|
// TODO(rjl493456442) we can probably return an error here,
|
||||||
|
|
@ -328,9 +328,9 @@ func newIndexDeleter(db ethdb.KeyValueReader, state stateIdent) (*indexDeleter,
|
||||||
lastDesc = descList[len(descList)-1]
|
lastDesc = descList[len(descList)-1]
|
||||||
)
|
)
|
||||||
if state.account {
|
if state.account {
|
||||||
indexBlock = rawdb.ReadAccountHistoryIndexBlock(db, state.address, lastDesc.id)
|
indexBlock = rawdb.ReadAccountHistoryIndexBlock(db, state.addressHash, lastDesc.id)
|
||||||
} else {
|
} else {
|
||||||
indexBlock = rawdb.ReadStorageHistoryIndexBlock(db, state.address, state.storageHash, lastDesc.id)
|
indexBlock = rawdb.ReadStorageHistoryIndexBlock(db, state.addressHash, state.storageHash, lastDesc.id)
|
||||||
}
|
}
|
||||||
bw, err := newBlockWriter(indexBlock, lastDesc)
|
bw, err := newBlockWriter(indexBlock, lastDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -381,9 +381,9 @@ func (d *indexDeleter) pop(id uint64) error {
|
||||||
lastDesc = d.descList[len(d.descList)-1]
|
lastDesc = d.descList[len(d.descList)-1]
|
||||||
)
|
)
|
||||||
if d.state.account {
|
if d.state.account {
|
||||||
indexBlock = rawdb.ReadAccountHistoryIndexBlock(d.db, d.state.address, lastDesc.id)
|
indexBlock = rawdb.ReadAccountHistoryIndexBlock(d.db, d.state.addressHash, lastDesc.id)
|
||||||
} else {
|
} else {
|
||||||
indexBlock = rawdb.ReadStorageHistoryIndexBlock(d.db, d.state.address, d.state.storageHash, lastDesc.id)
|
indexBlock = rawdb.ReadStorageHistoryIndexBlock(d.db, d.state.addressHash, d.state.storageHash, lastDesc.id)
|
||||||
}
|
}
|
||||||
bw, err := newBlockWriter(indexBlock, lastDesc)
|
bw, err := newBlockWriter(indexBlock, lastDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -400,9 +400,9 @@ func (d *indexDeleter) pop(id uint64) error {
|
||||||
func (d *indexDeleter) finish(batch ethdb.Batch) {
|
func (d *indexDeleter) finish(batch ethdb.Batch) {
|
||||||
for _, id := range d.dropped {
|
for _, id := range d.dropped {
|
||||||
if d.state.account {
|
if d.state.account {
|
||||||
rawdb.DeleteAccountHistoryIndexBlock(batch, d.state.address, id)
|
rawdb.DeleteAccountHistoryIndexBlock(batch, d.state.addressHash, id)
|
||||||
} else {
|
} else {
|
||||||
rawdb.DeleteStorageHistoryIndexBlock(batch, d.state.address, d.state.storageHash, id)
|
rawdb.DeleteStorageHistoryIndexBlock(batch, d.state.addressHash, d.state.storageHash, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.dropped = nil
|
d.dropped = nil
|
||||||
|
|
@ -410,17 +410,17 @@ func (d *indexDeleter) finish(batch ethdb.Batch) {
|
||||||
// Flush the content of last block writer, regardless it's dirty or not
|
// Flush the content of last block writer, regardless it's dirty or not
|
||||||
if !d.bw.empty() {
|
if !d.bw.empty() {
|
||||||
if d.state.account {
|
if d.state.account {
|
||||||
rawdb.WriteAccountHistoryIndexBlock(batch, d.state.address, d.bw.desc.id, d.bw.finish())
|
rawdb.WriteAccountHistoryIndexBlock(batch, d.state.addressHash, d.bw.desc.id, d.bw.finish())
|
||||||
} else {
|
} else {
|
||||||
rawdb.WriteStorageHistoryIndexBlock(batch, d.state.address, d.state.storageHash, d.bw.desc.id, d.bw.finish())
|
rawdb.WriteStorageHistoryIndexBlock(batch, d.state.addressHash, d.state.storageHash, d.bw.desc.id, d.bw.finish())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Flush the index metadata into the supplied batch
|
// Flush the index metadata into the supplied batch
|
||||||
if d.empty() {
|
if d.empty() {
|
||||||
if d.state.account {
|
if d.state.account {
|
||||||
rawdb.DeleteAccountHistoryIndex(batch, d.state.address)
|
rawdb.DeleteAccountHistoryIndex(batch, d.state.addressHash)
|
||||||
} else {
|
} else {
|
||||||
rawdb.DeleteStorageHistoryIndex(batch, d.state.address, d.state.storageHash)
|
rawdb.DeleteStorageHistoryIndex(batch, d.state.addressHash, d.state.storageHash)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf := make([]byte, 0, indexBlockDescSize*len(d.descList))
|
buf := make([]byte, 0, indexBlockDescSize*len(d.descList))
|
||||||
|
|
@ -428,9 +428,9 @@ func (d *indexDeleter) finish(batch ethdb.Batch) {
|
||||||
buf = append(buf, desc.encode()...)
|
buf = append(buf, desc.encode()...)
|
||||||
}
|
}
|
||||||
if d.state.account {
|
if d.state.account {
|
||||||
rawdb.WriteAccountHistoryIndex(batch, d.state.address, buf)
|
rawdb.WriteAccountHistoryIndex(batch, d.state.addressHash, buf)
|
||||||
} else {
|
} else {
|
||||||
rawdb.WriteStorageHistoryIndex(batch, d.state.address, d.state.storageHash, buf)
|
rawdb.WriteStorageHistoryIndex(batch, d.state.addressHash, d.state.storageHash, buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIndexReaderBasic(t *testing.T) {
|
func TestIndexReaderBasic(t *testing.T) {
|
||||||
|
|
@ -32,7 +33,7 @@ func TestIndexReaderBasic(t *testing.T) {
|
||||||
1, 5, 10, 11, 20,
|
1, 5, 10, 11, 20,
|
||||||
}
|
}
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
bw, _ := newIndexWriter(db, newAccountIdent(common.Address{0xa}))
|
bw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}))
|
||||||
for i := 0; i < len(elements); i++ {
|
for i := 0; i < len(elements); i++ {
|
||||||
bw.append(elements[i])
|
bw.append(elements[i])
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +41,7 @@ func TestIndexReaderBasic(t *testing.T) {
|
||||||
bw.finish(batch)
|
bw.finish(batch)
|
||||||
batch.Write()
|
batch.Write()
|
||||||
|
|
||||||
br, err := newIndexReader(db, newAccountIdent(common.Address{0xa}))
|
br, err := newIndexReader(db, newAccountIdent(common.Hash{0xa}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to construct the index reader, %v", err)
|
t.Fatalf("Failed to construct the index reader, %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +75,7 @@ func TestIndexReaderLarge(t *testing.T) {
|
||||||
slices.Sort(elements)
|
slices.Sort(elements)
|
||||||
|
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
bw, _ := newIndexWriter(db, newAccountIdent(common.Address{0xa}))
|
bw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}))
|
||||||
for i := 0; i < len(elements); i++ {
|
for i := 0; i < len(elements); i++ {
|
||||||
bw.append(elements[i])
|
bw.append(elements[i])
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +83,7 @@ func TestIndexReaderLarge(t *testing.T) {
|
||||||
bw.finish(batch)
|
bw.finish(batch)
|
||||||
batch.Write()
|
batch.Write()
|
||||||
|
|
||||||
br, err := newIndexReader(db, newAccountIdent(common.Address{0xa}))
|
br, err := newIndexReader(db, newAccountIdent(common.Hash{0xa}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to construct the index reader, %v", err)
|
t.Fatalf("Failed to construct the index reader, %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +107,7 @@ func TestIndexReaderLarge(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyIndexReader(t *testing.T) {
|
func TestEmptyIndexReader(t *testing.T) {
|
||||||
br, err := newIndexReader(rawdb.NewMemoryDatabase(), newAccountIdent(common.Address{0xa}))
|
br, err := newIndexReader(rawdb.NewMemoryDatabase(), newAccountIdent(common.Hash{0xa}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to construct the index reader, %v", err)
|
t.Fatalf("Failed to construct the index reader, %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +122,7 @@ func TestEmptyIndexReader(t *testing.T) {
|
||||||
|
|
||||||
func TestIndexWriterBasic(t *testing.T) {
|
func TestIndexWriterBasic(t *testing.T) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
iw, _ := newIndexWriter(db, newAccountIdent(common.Address{0xa}))
|
iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}))
|
||||||
iw.append(2)
|
iw.append(2)
|
||||||
if err := iw.append(1); err == nil {
|
if err := iw.append(1); err == nil {
|
||||||
t.Fatal("out-of-order insertion is not expected")
|
t.Fatal("out-of-order insertion is not expected")
|
||||||
|
|
@ -133,7 +134,7 @@ func TestIndexWriterBasic(t *testing.T) {
|
||||||
iw.finish(batch)
|
iw.finish(batch)
|
||||||
batch.Write()
|
batch.Write()
|
||||||
|
|
||||||
iw, err := newIndexWriter(db, newAccountIdent(common.Address{0xa}))
|
iw, err := newIndexWriter(db, newAccountIdent(common.Hash{0xa}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to construct the block writer, %v", err)
|
t.Fatalf("Failed to construct the block writer, %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +148,7 @@ func TestIndexWriterBasic(t *testing.T) {
|
||||||
|
|
||||||
func TestIndexWriterDelete(t *testing.T) {
|
func TestIndexWriterDelete(t *testing.T) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
iw, _ := newIndexWriter(db, newAccountIdent(common.Address{0xa}))
|
iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}))
|
||||||
for i := 0; i < indexBlockEntriesCap*4; i++ {
|
for i := 0; i < indexBlockEntriesCap*4; i++ {
|
||||||
iw.append(uint64(i + 1))
|
iw.append(uint64(i + 1))
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +157,7 @@ func TestIndexWriterDelete(t *testing.T) {
|
||||||
batch.Write()
|
batch.Write()
|
||||||
|
|
||||||
// Delete unknown id, the request should be rejected
|
// Delete unknown id, the request should be rejected
|
||||||
id, _ := newIndexDeleter(db, newAccountIdent(common.Address{0xa}))
|
id, _ := newIndexDeleter(db, newAccountIdent(common.Hash{0xa}))
|
||||||
if err := id.pop(indexBlockEntriesCap * 5); err == nil {
|
if err := id.pop(indexBlockEntriesCap * 5); err == nil {
|
||||||
t.Fatal("Expect error to occur for unknown id")
|
t.Fatal("Expect error to occur for unknown id")
|
||||||
}
|
}
|
||||||
|
|
@ -194,23 +195,24 @@ func TestBatchIndexerWrite(t *testing.T) {
|
||||||
t.Fatal("Unexpected index position")
|
t.Fatal("Unexpected index position")
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
accounts = make(map[common.Address][]uint64)
|
accounts = make(map[common.Hash][]uint64)
|
||||||
storages = make(map[common.Address]map[common.Hash][]uint64)
|
storages = make(map[common.Hash]map[common.Hash][]uint64)
|
||||||
)
|
)
|
||||||
for i, h := range histories {
|
for i, h := range histories {
|
||||||
for _, addr := range h.accountList {
|
for _, addr := range h.accountList {
|
||||||
accounts[addr] = append(accounts[addr], uint64(i+1))
|
addrHash := crypto.Keccak256Hash(addr.Bytes())
|
||||||
|
accounts[addrHash] = append(accounts[addrHash], uint64(i+1))
|
||||||
|
|
||||||
if _, ok := storages[addr]; !ok {
|
if _, ok := storages[addrHash]; !ok {
|
||||||
storages[addr] = make(map[common.Hash][]uint64)
|
storages[addrHash] = make(map[common.Hash][]uint64)
|
||||||
}
|
}
|
||||||
for _, slot := range h.storageList[addr] {
|
for _, slot := range h.storageList[addr] {
|
||||||
storages[addr][slot] = append(storages[addr][slot], uint64(i+1))
|
storages[addrHash][slot] = append(storages[addrHash][slot], uint64(i+1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for addr, indexes := range accounts {
|
for addrHash, indexes := range accounts {
|
||||||
ir, _ := newIndexReader(db, newAccountIdent(addr))
|
ir, _ := newIndexReader(db, newAccountIdent(addrHash))
|
||||||
for i := 0; i < len(indexes)-1; i++ {
|
for i := 0; i < len(indexes)-1; i++ {
|
||||||
n, err := ir.readGreaterThan(indexes[i])
|
n, err := ir.readGreaterThan(indexes[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -228,9 +230,9 @@ func TestBatchIndexerWrite(t *testing.T) {
|
||||||
t.Fatalf("Unexpected result, want math.MaxUint64, got %d", n)
|
t.Fatalf("Unexpected result, want math.MaxUint64, got %d", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for addr, slots := range storages {
|
for addrHash, slots := range storages {
|
||||||
for slotHash, indexes := range slots {
|
for slotHash, indexes := range slots {
|
||||||
ir, _ := newIndexReader(db, newStorageIdent(addr, slotHash))
|
ir, _ := newIndexReader(db, newStorageIdent(addrHash, slotHash))
|
||||||
for i := 0; i < len(indexes)-1; i++ {
|
for i := 0; i < len(indexes)-1; i++ {
|
||||||
n, err := ir.readGreaterThan(indexes[i])
|
n, err := ir.readGreaterThan(indexes[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@ func storeIndexMetadata(db ethdb.KeyValueWriter, last uint64) {
|
||||||
// batchIndexer is a structure designed to perform batch indexing or unindexing
|
// batchIndexer is a structure designed to perform batch indexing or unindexing
|
||||||
// of state histories atomically.
|
// of state histories atomically.
|
||||||
type batchIndexer struct {
|
type batchIndexer struct {
|
||||||
accounts map[common.Address][]uint64 // History ID list, Keyed by account address
|
accounts map[common.Hash][]uint64 // History ID list, Keyed by account address
|
||||||
storages map[common.Address]map[common.Hash][]uint64 // History ID list, Keyed by account address and the hash of raw storage key
|
storages map[common.Hash]map[common.Hash][]uint64 // History ID list, Keyed by account address and the hash of raw storage key
|
||||||
counter int // The counter of processed states
|
counter int // The counter of processed states
|
||||||
delete bool // Index or unindex mode
|
delete bool // Index or unindex mode
|
||||||
lastID uint64 // The ID of latest processed history
|
lastID uint64 // The ID of latest processed history
|
||||||
|
|
@ -82,8 +82,8 @@ type batchIndexer struct {
|
||||||
// newBatchIndexer constructs the batch indexer with the supplied mode.
|
// newBatchIndexer constructs the batch indexer with the supplied mode.
|
||||||
func newBatchIndexer(db ethdb.KeyValueStore, delete bool) *batchIndexer {
|
func newBatchIndexer(db ethdb.KeyValueStore, delete bool) *batchIndexer {
|
||||||
return &batchIndexer{
|
return &batchIndexer{
|
||||||
accounts: make(map[common.Address][]uint64),
|
accounts: make(map[common.Hash][]uint64),
|
||||||
storages: make(map[common.Address]map[common.Hash][]uint64),
|
storages: make(map[common.Hash]map[common.Hash][]uint64),
|
||||||
delete: delete,
|
delete: delete,
|
||||||
db: db,
|
db: db,
|
||||||
}
|
}
|
||||||
|
|
@ -93,13 +93,14 @@ func newBatchIndexer(db ethdb.KeyValueStore, delete bool) *batchIndexer {
|
||||||
// state history, tracking the mapping between state and history IDs.
|
// state history, tracking the mapping between state and history IDs.
|
||||||
func (b *batchIndexer) process(h *history, historyID uint64) error {
|
func (b *batchIndexer) process(h *history, historyID uint64) error {
|
||||||
for _, address := range h.accountList {
|
for _, address := range h.accountList {
|
||||||
|
addrHash := crypto.Keccak256Hash(address.Bytes())
|
||||||
b.counter += 1
|
b.counter += 1
|
||||||
b.accounts[address] = append(b.accounts[address], historyID)
|
b.accounts[addrHash] = append(b.accounts[addrHash], historyID)
|
||||||
|
|
||||||
for _, slotKey := range h.storageList[address] {
|
for _, slotKey := range h.storageList[address] {
|
||||||
b.counter += 1
|
b.counter += 1
|
||||||
if _, ok := b.storages[address]; !ok {
|
if _, ok := b.storages[addrHash]; !ok {
|
||||||
b.storages[address] = make(map[common.Hash][]uint64)
|
b.storages[addrHash] = make(map[common.Hash][]uint64)
|
||||||
}
|
}
|
||||||
// The hash of the storage slot key is used as the identifier because the
|
// The hash of the storage slot key is used as the identifier because the
|
||||||
// legacy history does not include the raw storage key, therefore, the
|
// legacy history does not include the raw storage key, therefore, the
|
||||||
|
|
@ -108,7 +109,7 @@ func (b *batchIndexer) process(h *history, historyID uint64) error {
|
||||||
if h.meta.version != stateHistoryV0 {
|
if h.meta.version != stateHistoryV0 {
|
||||||
slotHash = crypto.Keccak256Hash(slotKey.Bytes())
|
slotHash = crypto.Keccak256Hash(slotKey.Bytes())
|
||||||
}
|
}
|
||||||
b.storages[address][slotHash] = append(b.storages[address][slotHash], historyID)
|
b.storages[addrHash][slotHash] = append(b.storages[addrHash][slotHash], historyID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.lastID = historyID
|
b.lastID = historyID
|
||||||
|
|
@ -125,9 +126,9 @@ func (b *batchIndexer) finish(force bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
batch := b.db.NewBatch()
|
batch := b.db.NewBatch()
|
||||||
for address, idList := range b.accounts {
|
for addrHash, idList := range b.accounts {
|
||||||
if !b.delete {
|
if !b.delete {
|
||||||
iw, err := newIndexWriter(b.db, newAccountIdent(address))
|
iw, err := newIndexWriter(b.db, newAccountIdent(addrHash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +139,7 @@ func (b *batchIndexer) finish(force bool) error {
|
||||||
}
|
}
|
||||||
iw.finish(batch)
|
iw.finish(batch)
|
||||||
} else {
|
} else {
|
||||||
id, err := newIndexDeleter(b.db, newAccountIdent(address))
|
id, err := newIndexDeleter(b.db, newAccountIdent(addrHash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -150,10 +151,10 @@ func (b *batchIndexer) finish(force bool) error {
|
||||||
id.finish(batch)
|
id.finish(batch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for address, slots := range b.storages {
|
for addrHash, slots := range b.storages {
|
||||||
for storageHash, idList := range slots {
|
for storageHash, idList := range slots {
|
||||||
if !b.delete {
|
if !b.delete {
|
||||||
iw, err := newIndexWriter(b.db, newStorageIdent(address, storageHash))
|
iw, err := newIndexWriter(b.db, newStorageIdent(addrHash, storageHash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +165,7 @@ func (b *batchIndexer) finish(force bool) error {
|
||||||
}
|
}
|
||||||
iw.finish(batch)
|
iw.finish(batch)
|
||||||
} else {
|
} else {
|
||||||
id, err := newIndexDeleter(b.db, newStorageIdent(address, storageHash))
|
id, err := newIndexDeleter(b.db, newStorageIdent(addrHash, storageHash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -191,8 +192,8 @@ func (b *batchIndexer) finish(force bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
b.counter = 0
|
b.counter = 0
|
||||||
b.accounts = make(map[common.Address][]uint64)
|
b.accounts = make(map[common.Hash][]uint64)
|
||||||
b.storages = make(map[common.Address]map[common.Hash][]uint64)
|
b.storages = make(map[common.Hash]map[common.Hash][]uint64)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,19 @@ import (
|
||||||
// either an account or a storage slot.
|
// either an account or a storage slot.
|
||||||
type stateIdent struct {
|
type stateIdent struct {
|
||||||
account bool
|
account bool
|
||||||
address common.Address
|
|
||||||
|
// The hash of the account address. This is used instead of the raw account
|
||||||
|
// address is to align the traversal order with the Merkle-Patricia-Trie.
|
||||||
|
addressHash common.Hash
|
||||||
|
|
||||||
// The hash of the storage slot key. This is used instead of the raw slot key
|
// The hash of the storage slot key. This is used instead of the raw slot key
|
||||||
// because, in legacy state histories (prior to the Cancun fork), the slot
|
// because, in legacy state histories (prior to the Cancun fork), the slot
|
||||||
// identifier is the hash of the key, and the original key (preimage) cannot
|
// identifier is the hash of the key, and the original key (preimage) cannot
|
||||||
// be recovered. To maintain backward compatibility, the key hash is used.
|
// be recovered. To maintain backward compatibility, the key hash is used.
|
||||||
//
|
//
|
||||||
|
// Meanwhile, using the storage key hash also preserve the traversal order
|
||||||
|
// with Merkle-Patricia-Trie.
|
||||||
|
//
|
||||||
// This field is null if the identifier refers to account data.
|
// This field is null if the identifier refers to account data.
|
||||||
storageHash common.Hash
|
storageHash common.Hash
|
||||||
}
|
}
|
||||||
|
|
@ -47,25 +53,25 @@ type stateIdent struct {
|
||||||
// String returns the string format state identifier.
|
// String returns the string format state identifier.
|
||||||
func (ident stateIdent) String() string {
|
func (ident stateIdent) String() string {
|
||||||
if ident.account {
|
if ident.account {
|
||||||
return ident.address.Hex()
|
return ident.addressHash.Hex()
|
||||||
}
|
}
|
||||||
return ident.address.Hex() + ident.storageHash.Hex()
|
return ident.addressHash.Hex() + ident.storageHash.Hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAccountIdent constructs a state identifier for an account.
|
// newAccountIdent constructs a state identifier for an account.
|
||||||
func newAccountIdent(address common.Address) stateIdent {
|
func newAccountIdent(addressHash common.Hash) stateIdent {
|
||||||
return stateIdent{
|
return stateIdent{
|
||||||
account: true,
|
account: true,
|
||||||
address: address,
|
addressHash: addressHash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newStorageIdent constructs a state identifier for a storage slot.
|
// newStorageIdent constructs a state identifier for a storage slot.
|
||||||
// The address denotes the address of the associated account;
|
// The address denotes the address of the associated account;
|
||||||
// the storageHash denotes the hash of the raw storage slot key;
|
// the storageHash denotes the hash of the raw storage slot key;
|
||||||
func newStorageIdent(address common.Address, storageHash common.Hash) stateIdent {
|
func newStorageIdent(addressHash common.Hash, storageHash common.Hash) stateIdent {
|
||||||
return stateIdent{
|
return stateIdent{
|
||||||
address: address,
|
addressHash: addressHash,
|
||||||
storageHash: storageHash,
|
storageHash: storageHash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,29 +79,34 @@ func newStorageIdent(address common.Address, storageHash common.Hash) stateIdent
|
||||||
// stateIdentQuery is the extension of stateIdent by adding the raw storage key.
|
// stateIdentQuery is the extension of stateIdent by adding the raw storage key.
|
||||||
type stateIdentQuery struct {
|
type stateIdentQuery struct {
|
||||||
stateIdent
|
stateIdent
|
||||||
|
|
||||||
|
address common.Address
|
||||||
storageKey common.Hash
|
storageKey common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAccountIdentQuery constructs a state identifier for an account.
|
// newAccountIdentQuery constructs a state identifier for an account.
|
||||||
func newAccountIdentQuery(address common.Address) stateIdentQuery {
|
func newAccountIdentQuery(address common.Address, addressHash common.Hash) stateIdentQuery {
|
||||||
return stateIdentQuery{
|
return stateIdentQuery{
|
||||||
stateIdent: stateIdent{
|
stateIdent: stateIdent{
|
||||||
account: true,
|
account: true,
|
||||||
address: address,
|
addressHash: addressHash,
|
||||||
},
|
},
|
||||||
|
address: address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newStorageIdentQuery constructs a state identifier for a storage slot.
|
// newStorageIdentQuery constructs a state identifier for a storage slot.
|
||||||
// The address denotes the address of the associated account;
|
// the address denotes the address of the associated account;
|
||||||
|
// the addressHash denotes the address hash of the associated account;
|
||||||
// the storageKey denotes the raw storage slot key;
|
// the storageKey denotes the raw storage slot key;
|
||||||
// the storageHash denotes the hash of the raw storage slot key;
|
// the storageHash denotes the hash of the raw storage slot key;
|
||||||
func newStorageIdentQuery(address common.Address, storageKey common.Hash, storageHash common.Hash) stateIdentQuery {
|
func newStorageIdentQuery(address common.Address, addressHash common.Hash, storageKey common.Hash, storageHash common.Hash) stateIdentQuery {
|
||||||
return stateIdentQuery{
|
return stateIdentQuery{
|
||||||
stateIdent: stateIdent{
|
stateIdent: stateIdent{
|
||||||
address: address,
|
addressHash: addressHash,
|
||||||
storageHash: storageHash,
|
storageHash: storageHash,
|
||||||
},
|
},
|
||||||
|
address: address,
|
||||||
storageKey: storageKey,
|
storageKey: storageKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func checkHistoricState(env *tester, root common.Hash, hr *historyReader) error
|
||||||
)
|
)
|
||||||
for addrHash, accountData := range accounts {
|
for addrHash, accountData := range accounts {
|
||||||
latest, _ := dl.account(addrHash, 0)
|
latest, _ := dl.account(addrHash, 0)
|
||||||
blob, err := hr.read(newAccountIdentQuery(env.accountPreimage(addrHash)), *stateID, dl.stateID(), latest)
|
blob, err := hr.read(newAccountIdentQuery(env.accountPreimage(addrHash), addrHash), *stateID, dl.stateID(), latest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ func checkHistoricState(env *tester, root common.Hash, hr *historyReader) error
|
||||||
for addrHash := range env.snapAccounts[env.roots[i]] {
|
for addrHash := range env.snapAccounts[env.roots[i]] {
|
||||||
if _, ok := accounts[addrHash]; !ok {
|
if _, ok := accounts[addrHash]; !ok {
|
||||||
latest, _ := dl.account(addrHash, 0)
|
latest, _ := dl.account(addrHash, 0)
|
||||||
blob, err := hr.read(newAccountIdentQuery(env.accountPreimage(addrHash)), *stateID, dl.stateID(), latest)
|
blob, err := hr.read(newAccountIdentQuery(env.accountPreimage(addrHash), addrHash), *stateID, dl.stateID(), latest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +78,7 @@ func checkHistoricState(env *tester, root common.Hash, hr *historyReader) error
|
||||||
for addrHash, slots := range storages {
|
for addrHash, slots := range storages {
|
||||||
for slotHash, slotData := range slots {
|
for slotHash, slotData := range slots {
|
||||||
latest, _ := dl.storage(addrHash, slotHash, 0)
|
latest, _ := dl.storage(addrHash, slotHash, 0)
|
||||||
blob, err := hr.read(newStorageIdentQuery(env.accountPreimage(addrHash), env.hashPreimage(slotHash), slotHash), *stateID, dl.stateID(), latest)
|
blob, err := hr.read(newStorageIdentQuery(env.accountPreimage(addrHash), addrHash, env.hashPreimage(slotHash), slotHash), *stateID, dl.stateID(), latest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +100,7 @@ func checkHistoricState(env *tester, root common.Hash, hr *historyReader) error
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
latest, _ := dl.storage(addrHash, slotHash, 0)
|
latest, _ := dl.storage(addrHash, slotHash, 0)
|
||||||
blob, err := hr.read(newStorageIdentQuery(env.accountPreimage(addrHash), env.hashPreimage(slotHash), slotHash), *stateID, dl.stateID(), latest)
|
blob, err := hr.read(newStorageIdentQuery(env.accountPreimage(addrHash), addrHash, env.hashPreimage(slotHash), slotHash), *stateID, dl.stateID(), latest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,11 +256,12 @@ func (r *HistoricalStateReader) AccountRLP(address common.Address) ([]byte, erro
|
||||||
// and try to define a low granularity lock if the current approach doesn't
|
// and try to define a low granularity lock if the current approach doesn't
|
||||||
// work later.
|
// work later.
|
||||||
dl := r.db.tree.bottom()
|
dl := r.db.tree.bottom()
|
||||||
latest, err := dl.account(crypto.Keccak256Hash(address.Bytes()), 0)
|
hash := crypto.Keccak256Hash(address.Bytes())
|
||||||
|
latest, err := dl.account(hash, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.reader.read(newAccountIdentQuery(address), r.id, dl.stateID(), latest)
|
return r.reader.read(newAccountIdentQuery(address, hash), r.id, dl.stateID(), latest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account directly retrieves the account associated with a particular address in
|
// Account directly retrieves the account associated with a particular address in
|
||||||
|
|
@ -305,10 +306,11 @@ func (r *HistoricalStateReader) Storage(address common.Address, key common.Hash)
|
||||||
// and try to define a low granularity lock if the current approach doesn't
|
// and try to define a low granularity lock if the current approach doesn't
|
||||||
// work later.
|
// work later.
|
||||||
dl := r.db.tree.bottom()
|
dl := r.db.tree.bottom()
|
||||||
|
addrHash := crypto.Keccak256Hash(address.Bytes())
|
||||||
keyHash := crypto.Keccak256Hash(key.Bytes())
|
keyHash := crypto.Keccak256Hash(key.Bytes())
|
||||||
latest, err := dl.storage(crypto.Keccak256Hash(address.Bytes()), keyHash, 0)
|
latest, err := dl.storage(addrHash, keyHash, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.reader.read(newStorageIdentQuery(address, key, keyHash), r.id, dl.stateID(), latest)
|
return r.reader.read(newStorageIdentQuery(address, addrHash, key, keyHash), r.id, dl.stateID(), latest)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue