erigon-pulse/cmd/rpcdaemon/commands/storage_range.go

46 lines
1.5 KiB
Go
Raw Normal View History

package commands
import (
"fmt"
"github.com/holiman/uint256"
libcommon "github.com/ledgerwatch/erigon-lib/common"
)
// StorageRangeResult is the result of a debug_storageRangeAt API call.
type StorageRangeResult struct {
Storage storageMap `json:"storage"`
NextKey *libcommon.Hash `json:"nextKey"` // nil if Storage includes the last key in the trie.
}
2023-01-12 02:58:21 +00:00
// storageMap a map from storage locations to StorageEntry items
type storageMap map[libcommon.Hash]StorageEntry
// StorageEntry an entry in storage of the account
type StorageEntry struct {
Key *libcommon.Hash `json:"key"`
Value libcommon.Hash `json:"value"`
}
2022-11-20 03:58:20 +00:00
type walker interface {
ForEachStorage(addr libcommon.Address, startLocation libcommon.Hash, cb func(key, seckey libcommon.Hash, value uint256.Int) bool, maxResults int) error
2022-11-20 03:58:20 +00:00
}
func storageRangeAt(stateReader walker, contractAddress libcommon.Address, start []byte, maxResult int) (StorageRangeResult, error) {
2023-01-12 02:58:21 +00:00
result := StorageRangeResult{Storage: storageMap{}}
resultCount := 0
if err := stateReader.ForEachStorage(contractAddress, libcommon.BytesToHash(start), func(key, seckey libcommon.Hash, value uint256.Int) bool {
if resultCount < maxResult {
result.Storage[seckey] = StorageEntry{Key: &key, Value: value.Bytes32()}
} else {
result.NextKey = &key
}
resultCount++
return resultCount <= maxResult
}, maxResult+1); err != nil {
2021-10-04 15:16:52 +00:00
return StorageRangeResult{}, fmt.Errorf("error walking over storage: %w", err)
}
return result, nil
}