mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 03:10:48 +00:00
add: add batch storage RPC methods
This commit is contained in:
parent
bbb1ab8d16
commit
d2f83bd4da
1 changed files with 55 additions and 0 deletions
|
|
@ -1928,6 +1928,61 @@ func NewDebugAPI(b Backend) *DebugAPI {
|
|||
return &DebugAPI{b: b}
|
||||
}
|
||||
|
||||
// BatchGetStorageAt returns multiple storage slots for a single account at the given block.
|
||||
// Params: address, [hexKey...], blockNrOrHash
|
||||
// Returns values in the same order as input keys.
|
||||
func (api *DebugAPI) BatchGetStorageAt(ctx context.Context, address common.Address, hexKeys []string, blockNrOrHash rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) {
|
||||
state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Preallocate results
|
||||
res := make([]hexutil.Bytes, len(hexKeys))
|
||||
for i, k := range hexKeys {
|
||||
key, _, err := decodeHash(k)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to decode storage key at index %d: %w", i, err)
|
||||
}
|
||||
v := state.GetState(address, key)
|
||||
vv := make([]byte, len(v))
|
||||
copy(vv, v[:])
|
||||
res[i] = vv
|
||||
}
|
||||
if err := state.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// BatchGetStorage returns multiple storage slots for multiple accounts at the given block.
|
||||
// Params: {address: [hexKey, ...], ...}, blockNrOrHash
|
||||
// Returns a map {address: [value,...]} preserving the order within each key list.
|
||||
func (api *DebugAPI) BatchGetStorage(ctx context.Context, req map[common.Address][]string, blockNrOrHash rpc.BlockNumberOrHash) (map[common.Address][]hexutil.Bytes, error) {
|
||||
state, _, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make(map[common.Address][]hexutil.Bytes, len(req))
|
||||
for addr, keys := range req {
|
||||
vals := make([]hexutil.Bytes, len(keys))
|
||||
for i, k := range keys {
|
||||
key, _, err := decodeHash(k)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to decode storage key for %s at index %d: %w", addr.Hex(), i, err)
|
||||
}
|
||||
v := state.GetState(addr, key)
|
||||
vv := make([]byte, len(v))
|
||||
copy(vv, v[:])
|
||||
vals[i] = vv
|
||||
}
|
||||
out[addr] = vals
|
||||
}
|
||||
if err := state.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetRawHeader retrieves the RLP encoding for a single header.
|
||||
func (api *DebugAPI) GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) {
|
||||
var hash common.Hash
|
||||
|
|
|
|||
Loading…
Reference in a new issue