mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +00:00
cmd/geth: implement debug_batchGetStorageAt RPC (Closes #32591)
This commit is contained in:
parent
a541f84fa3
commit
95a0ff03f4
2 changed files with 99 additions and 0 deletions
63
internal/ethapi/debug_api.go
Normal file
63
internal/ethapi/debug_api.go
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
package ethapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StorageBatchRequest struct {
|
||||||
|
Address common.Address `json:"address"`
|
||||||
|
Slots []common.Hash `json:"slots"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageBatchResponse map[string]string
|
||||||
|
|
||||||
|
type DebugAPI struct {
|
||||||
|
b Backend
|
||||||
|
}
|
||||||
|
|
||||||
|
type Backend interface {
|
||||||
|
BlockByNumber(ctx context.Context, number rpc.BlockNumber) (Block, error)
|
||||||
|
StateAt(root common.Hash) (StateDB, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Block interface {
|
||||||
|
Root() common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
type StateDB interface {
|
||||||
|
GetState(addr common.Address, slot common.Hash) common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *DebugAPI) BatchGetStorageAt(ctx context.Context, reqs []StorageBatchRequest, blockNr rpc.BlockNumber) (map[string]StorageBatchResponse, error) {
|
||||||
|
res := make(map[string]StorageBatchResponse)
|
||||||
|
block, err := api.b.BlockByNumber(ctx, blockNr)
|
||||||
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
|
statedb, err := api.b.StateAt(block.Root())
|
||||||
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
for _, req := range reqs {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(req StorageBatchRequest) {
|
||||||
|
defer wg.Done()
|
||||||
|
batchRes := make(StorageBatchResponse)
|
||||||
|
for _, slot := range req.Slots {
|
||||||
|
value := statedb.GetState(req.Address, slot)
|
||||||
|
batchRes[slot.Hex()] = value.Hex()
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
res[req.Address.Hex()] = batchRes
|
||||||
|
mu.Unlock()
|
||||||
|
}(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
36
internal/ethapi/debug_api_test.go
Normal file
36
internal/ethapi/debug_api_test.go
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
package ethapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dummyBackend struct{}
|
||||||
|
func (b *dummyBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (Block, error) { return &dummyBlock{}, nil }
|
||||||
|
func (b *dummyBackend) StateAt(root common.Hash) (StateDB, error) { return &dummyState{}, nil }
|
||||||
|
|
||||||
|
type dummyBlock struct{}
|
||||||
|
func (b *dummyBlock) Root() common.Hash { return common.Hash{} }
|
||||||
|
|
||||||
|
type dummyState struct{}
|
||||||
|
func (s *dummyState) GetState(addr common.Address, slot common.Hash) common.Hash {
|
||||||
|
return common.HexToHash("0x1234")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBatchGetStorageAt(t *testing.T) {
|
||||||
|
api := &DebugAPI{b: &dummyBackend{}}
|
||||||
|
reqs := []StorageBatchRequest{
|
||||||
|
{Address: common.HexToAddress("0xabc"), Slots: []common.Hash{common.HexToHash("0x0"), common.HexToHash("0x1")}},
|
||||||
|
{Address: common.HexToAddress("0xdef"), Slots: []common.Hash{common.HexToHash("0x0")}},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := api.BatchGetStorageAt(context.Background(), reqs, "latest")
|
||||||
|
if err != nil { t.Fatal(err) }
|
||||||
|
|
||||||
|
if res["0xabc"]["0x0"] != "0x0000000000000000000000000000000000001234" {
|
||||||
|
t.Errorf("unexpected value for 0xabc 0x0: %s", res["0xabc"]["0x0"])
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue