From 1a16ebc3f2f1782079701e39c646079cee0ce5cc Mon Sep 17 00:00:00 2001 From: Janko Date: Fri, 26 Aug 2022 22:14:28 +0200 Subject: [PATCH] ethclient/gethclient: this change modifies the gethclient to properly override the state for the Code property If the code property is not present in the state overrides, it should be skipped or set to null on marshal. Because of the type of the property hexutil.Bytes the empty slice marshals to 0x and the request fails. fixes #25615 --- ethclient/gethclient/gethclient.go | 12 +++- ethclient/gethclient/gethclient_test.go | 83 +++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index a86f4339f425..52bf15d53c96 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -216,16 +216,24 @@ func toOverrideMap(overrides *map[common.Address]OverrideAccount) interface{} { } type overrideAccount struct { Nonce hexutil.Uint64 `json:"nonce"` - Code hexutil.Bytes `json:"code"` + Code []byte `json:"code"` Balance *hexutil.Big `json:"balance"` State map[common.Hash]common.Hash `json:"state"` StateDiff map[common.Hash]common.Hash `json:"stateDiff"` } result := make(map[common.Address]overrideAccount) + for addr, override := range *overrides { + var code []byte + + if len(override.Code) > 0 { + // convert to hexutil.Bytes explicitly in order to marshal/unmarshal as a JSON string with 0x prefix. + code = hexutil.Bytes(override.Code) + } + result[addr] = overrideAccount{ Nonce: hexutil.Uint64(override.Nonce), - Code: override.Code, + Code: code, Balance: (*hexutil.Big)(override.Balance), State: override.State, StateDiff: override.StateDiff, diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go index a0f4eaaf5db4..e2a04290722a 100644 --- a/ethclient/gethclient/gethclient_test.go +++ b/ethclient/gethclient/gethclient_test.go @@ -19,11 +19,13 @@ package gethclient import ( "bytes" "context" + "encoding/json" "math/big" "testing" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" @@ -135,6 +137,12 @@ func TestGethClient(t *testing.T) { }, { "TestCallContract", func(t *testing.T) { testCallContract(t, client) }, + }, { + "testCodeOverride", + func(t *testing.T) { testCodeOverride(t) }, + }, { + "testNoCodeOverride", + func(t *testing.T) { testNoCodeOverride(t) }, }, } t.Parallel() @@ -327,3 +335,78 @@ func testCallContract(t *testing.T, client *rpc.Client) { t.Fatalf("unexpected error: %v", err) } } + +func testNoCodeOverride(t *testing.T) { + override := OverrideAccount{} + + mapAcc := make(map[common.Address]OverrideAccount) + mapAcc[testAddr] = override + + encoded := toOverrideMap(&mapAcc) + + type overrideAccount struct { + Nonce hexutil.Uint64 `json:"nonce"` + Code []byte `json:"code"` + Balance *hexutil.Big `json:"balance"` + State map[common.Hash]common.Hash `json:"state"` + StateDiff map[common.Hash]common.Hash `json:"stateDiff"` + } + + var accounts map[common.Address]*overrideAccount + marshalled, err := json.Marshal(encoded) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + err = json.Unmarshal(marshalled, &accounts) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + account := accounts[testAddr] + if account == nil { + t.Fatal("unexpected error") + } + + if account.Code != nil { + t.Fatal("unexpected error") + } +} + +func testCodeOverride(t *testing.T) { + override := OverrideAccount{} + override.Code = []byte{1} + + mapAcc := make(map[common.Address]OverrideAccount) + mapAcc[testAddr] = override + + encoded := toOverrideMap(&mapAcc) + + type overrideAccount struct { + Nonce hexutil.Uint64 `json:"nonce"` + Code []byte `json:"code"` + Balance *hexutil.Big `json:"balance"` + State map[common.Hash]common.Hash `json:"state"` + StateDiff map[common.Hash]common.Hash `json:"stateDiff"` + } + + var accounts map[common.Address]*overrideAccount + marshalled, err := json.Marshal(encoded) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + err = json.Unmarshal(marshalled, &accounts) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + account := accounts[testAddr] + if account == nil { + t.Fatal("unexpected error") + } + + if account.Code == nil { + t.Fatal("unexpected error") + } +}