add: add batch storage RPC methods

This commit is contained in:
quantumshiro 2025-09-12 01:35:30 +09:00 committed by Sina Mahmoodi
parent bbb1ab8d16
commit d2f83bd4da

View file

@ -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