ethclient/gethclient: fix bugs in override object encoding #25616 (#1371)

This commit is contained in:
Daniel Liu 2025-08-22 16:44:06 +08:00 committed by GitHub
parent aa88fe1d86
commit fc9c5bebe7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -19,6 +19,7 @@ package gethclient
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"math/big" "math/big"
"runtime" "runtime"
@ -119,15 +120,6 @@ func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []s
return &result, err return &result, err
} }
// OverrideAccount specifies the state of an account to be overridden.
type OverrideAccount struct {
Nonce uint64 `json:"nonce"`
Code []byte `json:"code"`
Balance *big.Int `json:"balance"`
State map[common.Hash]common.Hash `json:"state"`
StateDiff map[common.Hash]common.Hash `json:"stateDiff"`
}
// CallContract executes a message call transaction, which is directly executed in the VM // CallContract executes a message call transaction, which is directly executed in the VM
// of the node, but never mined into the blockchain. // of the node, but never mined into the blockchain.
// //
@ -142,7 +134,7 @@ func (ec *Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockN
var hex hexutil.Bytes var hex hexutil.Bytes
err := ec.c.CallContext( err := ec.c.CallContext(
ctx, &hex, "eth_call", toCallArg(msg), ctx, &hex, "eth_call", toCallArg(msg),
toBlockNumArg(blockNumber), toOverrideMap(overrides), toBlockNumArg(blockNumber), overrides,
) )
return hex, err return hex, err
} }
@ -224,26 +216,48 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
return arg return arg
} }
func toOverrideMap(overrides *map[common.Address]OverrideAccount) interface{} { // OverrideAccount specifies the state of an account to be overridden.
if overrides == nil { type OverrideAccount struct {
return nil // Nonce sets nonce of the account. Note: the nonce override will only
// be applied when it is set to a non-zero value.
Nonce uint64
// Code sets the contract code. The override will be applied
// when the code is non-nil, i.e. setting empty code is possible
// using an empty slice.
Code []byte
// Balance sets the account balance.
Balance *big.Int
// State sets the complete storage. The override will be applied
// when the given map is non-nil. Using an empty map wipes the
// entire contract storage during the call.
State map[common.Hash]common.Hash
// StateDiff allows overriding individual storage slots.
StateDiff map[common.Hash]common.Hash
} }
type overrideAccount struct {
Nonce hexutil.Uint64 `json:"nonce"` func (a OverrideAccount) MarshalJSON() ([]byte, error) {
Code hexutil.Bytes `json:"code"` type acc struct {
Balance *hexutil.Big `json:"balance"` Nonce hexutil.Uint64 `json:"nonce,omitempty"`
State map[common.Hash]common.Hash `json:"state"` Code string `json:"code,omitempty"`
StateDiff map[common.Hash]common.Hash `json:"stateDiff"` Balance *hexutil.Big `json:"balance,omitempty"`
State interface{} `json:"state,omitempty"`
StateDiff map[common.Hash]common.Hash `json:"stateDiff,omitempty"`
} }
result := make(map[common.Address]overrideAccount)
for addr, override := range *overrides { output := acc{
result[addr] = overrideAccount{ Nonce: hexutil.Uint64(a.Nonce),
Nonce: hexutil.Uint64(override.Nonce), Balance: (*hexutil.Big)(a.Balance),
Code: override.Code, StateDiff: a.StateDiff,
Balance: (*hexutil.Big)(override.Balance),
State: override.State,
StateDiff: override.StateDiff,
} }
if a.Code != nil {
output.Code = hexutil.Encode(a.Code)
} }
return &result if a.State != nil {
output.State = a.State
}
return json.Marshal(output)
} }