Skip to content

Commit

Permalink
add eth_GetStorageAll
Browse files Browse the repository at this point in the history
  • Loading branch information
shouc committed Dec 27, 2022
1 parent b4773e8 commit f8124b4
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 9 deletions.
9 changes: 9 additions & 0 deletions core/state/snapshot/difflayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,15 @@ func (dl *diffLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
return dl.storage(accountHash, storageHash, 0)
}

func (dl *diffLayer) StorageSnapshots(accountHash common.Hash) (map[common.Hash]string, error) {
dl.lock.RLock()
res, err := dl.origin.StorageSnapshots(accountHash)

dl.lock.RUnlock()

return res, err
}

// storage is an internal version of Storage that skips the bloom filter checks
// and uses the internal maps to try and retrieve the data. It's meant to be
// used if a higher layer's bloom filter hit already.
Expand Down
17 changes: 17 additions & 0 deletions core/state/snapshot/disklayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package snapshot

import (
"bytes"
"fmt"
"sync"

"github.com/VictoriaMetrics/fastcache"
Expand Down Expand Up @@ -137,6 +138,22 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
return blob, nil
}

func (dl *diskLayer) StorageSnapshots(accountHash common.Hash) (map[common.Hash]string, error) {
dl.lock.RLock()
defer dl.lock.RUnlock()

res := make(map[common.Hash]string)

it := rawdb.IterateStorageSnapshots(dl.diskdb, accountHash)
for it.Next() {
v := it.Value()
_, content, _, _ := rlp.Split(v)
res[common.BytesToHash(it.Key()[1+len(accountHash):])] = fmt.Sprintf("%x", content)
}
it.Release()
return res, nil
}

// Storage directly retrieves the storage data associated with a particular hash,
// within a particular account.
func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, error) {
Expand Down
2 changes: 2 additions & 0 deletions core/state/snapshot/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ type Snapshot interface {
// within a particular account.
Storage(accountHash, storageHash common.Hash) ([]byte, error)

StorageSnapshots(accountHash common.Hash) (map[common.Hash]string, error)

// Parent returns the subsequent layer of a snapshot, or nil if the base was
// reached.
Parent() snapshot
Expand Down
22 changes: 22 additions & 0 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,28 @@ func (s *StateObject) GetCommittedState(db Database, key common.Hash) common.Has
return value
}

// GetCommittedState retrieves a value from the committed account storage trie.
func (s *StateObject) GetCommittedStateAll(db Database) map[common.Hash]string {
if s.db.snap != nil {
if _, destructed := s.db.snapDestructs[s.address]; destructed {
return nil
}
// enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes()))

it, err := s.db.snap.StorageSnapshots(s.addrHash)

if err != nil {
s.setError(err)
return nil
}

return it
}

return nil

}

// SetState updates a value in account storage.
func (s *StateObject) SetState(db Database, key, value common.Hash) {
// If the fake storage is set, put the temporary state update here.
Expand Down
18 changes: 13 additions & 5 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,14 @@ func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
return common.Hash{}
}

func (s *StateDB) GetStateAll(addr common.Address) map[common.Hash]string {
stateObject := s.getStateObject(addr)
if stateObject != nil {
return stateObject.GetCommittedStateAll(s.db)
}
return nil
}

// GetProof returns the Merkle proof for a given account.
func (s *StateDB) GetProof(addr common.Address) ([][]byte, error) {
return s.GetProofByHash(crypto.Keccak256Hash(addr.Bytes()))
Expand Down Expand Up @@ -779,8 +787,8 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *StateObject)
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
// a contract does the following:
//
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
//
// Carrying over the balance ensures that Ether doesn't disappear.
func (s *StateDB) CreateAccount(addr common.Address) {
Expand Down Expand Up @@ -1043,7 +1051,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
return s.StateIntermediateRoot()
}

//CorrectAccountsRoot will fix account roots in pipecommit mode
// CorrectAccountsRoot will fix account roots in pipecommit mode
func (s *StateDB) CorrectAccountsRoot(blockRoot common.Hash) {
var snapshot snapshot.Snapshot
if blockRoot == (common.Hash{}) {
Expand Down Expand Up @@ -1071,7 +1079,7 @@ func (s *StateDB) CorrectAccountsRoot(blockRoot common.Hash) {
}
}

//PopulateSnapAccountAndStorage tries to populate required accounts and storages for pipecommit
// PopulateSnapAccountAndStorage tries to populate required accounts and storages for pipecommit
func (s *StateDB) PopulateSnapAccountAndStorage() {
for addr := range s.stateObjectsPending {
if obj := s.stateObjects[addr]; !obj.deleted {
Expand All @@ -1083,7 +1091,7 @@ func (s *StateDB) PopulateSnapAccountAndStorage() {
}
}

//populateSnapStorage tries to populate required storages for pipecommit, and returns a flag to indicate whether the storage root changed or not
// populateSnapStorage tries to populate required storages for pipecommit, and returns a flag to indicate whether the storage root changed or not
func (s *StateDB) populateSnapStorage(obj *StateObject) bool {
for key, value := range obj.dirtyStorage {
obj.pendingStorage[key] = value
Expand Down
17 changes: 13 additions & 4 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,10 +737,10 @@ func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.H
}

// GetBlockByNumber returns the requested canonical block.
// * When blockNr is -1 the chain head is returned.
// * When blockNr is -2 the pending chain head is returned.
// * When fullTx is true all transactions in the block are returned, otherwise
// only the transaction hash is returned.
// - When blockNr is -1 the chain head is returned.
// - When blockNr is -2 the pending chain head is returned.
// - When fullTx is true all transactions in the block are returned, otherwise
// only the transaction hash is returned.
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
block, err := s.b.BlockByNumber(ctx, number)
if block != nil && err == nil {
Expand Down Expand Up @@ -843,6 +843,15 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
return res[:], state.Error()
}

func (s *PublicBlockChainAPI) GetStorageAll(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (map[common.Hash]string, error) {
state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
return nil, err
}
res := state.GetStateAll(address)
return res, state.Error()
}

// OverrideAccount indicates the overriding fields of account during the execution
// of a message call.
// Note, state and stateDiff can't be specified at the same time. If state is
Expand Down

0 comments on commit f8124b4

Please sign in to comment.