mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 03:10:48 +00:00
feat: batch get storage
This commit is contained in:
parent
7b7be249cb
commit
9f9cb0f71e
3 changed files with 70 additions and 0 deletions
|
|
@ -589,6 +589,25 @@ func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Addre
|
|||
return res[:], state.Error()
|
||||
}
|
||||
|
||||
// GetStorageAtBatch returns multiple storage slots for the keys from the state at the given address,
|
||||
// block number.
|
||||
func (api *BlockChainAPI) 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
|
||||
}
|
||||
results := make([]hexutil.Bytes, len(hexKeys))
|
||||
for i, hexKey := range hexKeys {
|
||||
key, _, err := decodeStorageKey(hexKey)
|
||||
if err != nil {
|
||||
return nil, &invalidParamsError{fmt.Sprintf("index %d: %v: %q", i, err, hexKey)}
|
||||
}
|
||||
res := state.GetState(address, key)
|
||||
results[i] = res[:]
|
||||
}
|
||||
return results, state.Error()
|
||||
}
|
||||
|
||||
// GetBlockReceipts returns the block receipts for the given block hash or number or tag.
|
||||
func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -4065,3 +4065,49 @@ func TestSendRawTransactionSync_Timeout(t *testing.T) {
|
|||
t.Fatalf("expected ErrorData=%s, got %v", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchGetStorageAt(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
addr := common.HexToAddress("0xdeadbeef")
|
||||
key1 := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001")
|
||||
key2 := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000002")
|
||||
val1 := common.HexToHash("0x11")
|
||||
val2 := common.HexToHash("0x22")
|
||||
|
||||
genesis := &core.Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{
|
||||
addr: {
|
||||
Balance: big.NewInt(1000),
|
||||
Storage: map[common.Hash]common.Hash{
|
||||
key1: val1,
|
||||
key2: val2,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
backend := newTestBackend(t, 1, genesis, ethash.NewFaker(), nil)
|
||||
api := NewBlockChainAPI(backend)
|
||||
keys := []string{
|
||||
key1.Hex(),
|
||||
key2.Hex(),
|
||||
}
|
||||
bn := rpc.LatestBlockNumber
|
||||
blockNr := rpc.BlockNumberOrHash{BlockNumber: &bn}
|
||||
results, err := api.BatchGetStorageAt(context.Background(), addr, keys, blockNr)
|
||||
if err != nil {
|
||||
t.Fatalf("BatchGetStorageAt failed: %v", err)
|
||||
}
|
||||
|
||||
if len(results) != 2 {
|
||||
t.Fatalf("Expected 2 results, got %d", len(results))
|
||||
}
|
||||
if !bytes.Equal(results[0], val1.Bytes()) {
|
||||
t.Errorf("Slot 1 mismatch: have %x, want %x", results[0], val1.Bytes())
|
||||
}
|
||||
if !bytes.Equal(results[1], val2.Bytes()) {
|
||||
t.Errorf("Slot 2 mismatch: have %x, want %x", results[1], val2.Bytes())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,6 +415,11 @@ web3._extend({
|
|||
call: 'debug_storageRangeAt',
|
||||
params: 5,
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'batchGetStorageAt',
|
||||
call: 'debug_batchGetStorageAt',
|
||||
params: 3,
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'getModifiedAccountsByNumber',
|
||||
call: 'debug_getModifiedAccountsByNumber',
|
||||
|
|
|
|||
Loading…
Reference in a new issue