internal/ethapi: fix codehash lookup in eth_getProof (#28357)

This change fixes #28355, where eth_getProof failed to return the correct codehash under certain conditions. This PR changes the logic to unconditionally look up the codehash, and also adds some more tests.
This commit is contained in:
Martin Holst Swende
2023-10-17 09:25:16 +02:00
committed by GitHub
parent a5544d35f6
commit 8b99ad4602
2 changed files with 72 additions and 70 deletions
+32 -24
View File
@@ -39,11 +39,12 @@ import (
)
var (
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
testSlot = common.HexToHash("0xdeadbeef")
testValue = crypto.Keccak256Hash(testSlot[:])
testBalance = big.NewInt(2e15)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
testContract = common.HexToAddress("0xbeef")
testSlot = common.HexToHash("0xdeadbeef")
testValue = crypto.Keccak256Hash(testSlot[:])
testBalance = big.NewInt(2e15)
)
func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
@@ -78,8 +79,9 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
func generateTestChain() (*core.Genesis, []*types.Block) {
genesis := &core.Genesis{
Config: params.AllEthashProtocolChanges,
Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}}},
Config: params.AllEthashProtocolChanges,
Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}}},
ExtraData: []byte("test genesis"),
Timestamp: 9000,
}
@@ -103,8 +105,11 @@ func TestGethClient(t *testing.T) {
test func(t *testing.T)
}{
{
"TestGetProof",
func(t *testing.T) { testGetProof(t, client) },
"TestGetProof1",
func(t *testing.T) { testGetProof(t, client, testAddr) },
}, {
"TestGetProof2",
func(t *testing.T) { testGetProof(t, client, testContract) },
}, {
"TestGetProofCanonicalizeKeys",
func(t *testing.T) { testGetProofCanonicalizeKeys(t, client) },
@@ -201,38 +206,41 @@ func testAccessList(t *testing.T, client *rpc.Client) {
}
}
func testGetProof(t *testing.T, client *rpc.Client) {
func testGetProof(t *testing.T, client *rpc.Client, addr common.Address) {
ec := New(client)
ethcl := ethclient.NewClient(client)
result, err := ec.GetProof(context.Background(), testAddr, []string{testSlot.String()}, nil)
result, err := ec.GetProof(context.Background(), addr, []string{testSlot.String()}, nil)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(result.Address[:], testAddr[:]) {
t.Fatalf("unexpected address, want: %v got: %v", testAddr, result.Address)
if result.Address != addr {
t.Fatalf("unexpected address, have: %v want: %v", result.Address, addr)
}
// test nonce
nonce, _ := ethcl.NonceAt(context.Background(), result.Address, nil)
if result.Nonce != nonce {
if nonce, _ := ethcl.NonceAt(context.Background(), addr, nil); result.Nonce != nonce {
t.Fatalf("invalid nonce, want: %v got: %v", nonce, result.Nonce)
}
// test balance
balance, _ := ethcl.BalanceAt(context.Background(), result.Address, nil)
if result.Balance.Cmp(balance) != 0 {
if balance, _ := ethcl.BalanceAt(context.Background(), addr, nil); result.Balance.Cmp(balance) != 0 {
t.Fatalf("invalid balance, want: %v got: %v", balance, result.Balance)
}
// test storage
if len(result.StorageProof) != 1 {
t.Fatalf("invalid storage proof, want 1 proof, got %v proof(s)", len(result.StorageProof))
}
proof := result.StorageProof[0]
slotValue, _ := ethcl.StorageAt(context.Background(), testAddr, testSlot, nil)
if !bytes.Equal(slotValue, proof.Value.Bytes()) {
t.Fatalf("invalid storage proof value, want: %v, got: %v", slotValue, proof.Value.Bytes())
for _, proof := range result.StorageProof {
if proof.Key != testSlot.String() {
t.Fatalf("invalid storage proof key, want: %q, got: %q", testSlot.String(), proof.Key)
}
slotValue, _ := ethcl.StorageAt(context.Background(), addr, common.HexToHash(proof.Key), nil)
if have, want := common.BigToHash(proof.Value), common.BytesToHash(slotValue); have != want {
t.Fatalf("addr %x, invalid storage proof value: have: %v, want: %v", addr, have, want)
}
}
if proof.Key != testSlot.String() {
t.Fatalf("invalid storage proof key, want: %q, got: %q", testSlot.String(), proof.Key)
// test code
code, _ := ethcl.CodeAt(context.Background(), addr, nil)
if have, want := result.CodeHash, crypto.Keccak256Hash(code); have != want {
t.Fatalf("codehash wrong, have %v want %v ", have, want)
}
}