This commit is contained in:
allen 2025-10-09 12:34:01 -04:00
parent 5691d733a3
commit 4042a9ba1b
2 changed files with 68 additions and 98 deletions

View file

@ -28,7 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
@ -831,59 +831,27 @@ type SimulateOptions struct {
// SimulateBlock represents a batch of calls to be simulated. // SimulateBlock represents a batch of calls to be simulated.
type SimulateBlock struct { type SimulateBlock struct {
BlockOverrides *BlockOverrides `json:"blockOverrides,omitempty"` BlockOverrides *gethclient.BlockOverrides `json:"blockOverrides,omitempty"`
StateOverrides *StateOverride `json:"stateOverrides,omitempty"` StateOverrides *map[common.Address]gethclient.OverrideAccount `json:"stateOverrides,omitempty"`
Calls []CallArgs `json:"calls"` Calls []ethereum.CallMsg `json:"calls"`
} }
// BlockOverrides is a set of header fields to override. // MarshalJSON implements json.Marshaler for SimulateBlock.
type BlockOverrides struct { func (s SimulateBlock) MarshalJSON() ([]byte, error) {
Number *hexutil.Big `json:"number,omitempty"` type Alias struct {
Difficulty *hexutil.Big `json:"difficulty,omitempty"` BlockOverrides *gethclient.BlockOverrides `json:"blockOverrides,omitempty"`
Time *hexutil.Uint64 `json:"time,omitempty"` StateOverrides *map[common.Address]gethclient.OverrideAccount `json:"stateOverrides,omitempty"`
GasLimit *hexutil.Uint64 `json:"gasLimit,omitempty"` Calls []interface{} `json:"calls"`
FeeRecipient *common.Address `json:"feeRecipient,omitempty"`
PrevRandao *common.Hash `json:"prevRandao,omitempty"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas,omitempty"`
BlobBaseFee *hexutil.Big `json:"blobBaseFee,omitempty"`
BeaconRoot *common.Hash `json:"beaconRoot,omitempty"`
Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"`
} }
calls := make([]interface{}, len(s.Calls))
// StateOverride is the collection of overridden accounts. for i, call := range s.Calls {
type StateOverride map[common.Address]OverrideAccount calls[i] = toCallArg(call)
// OverrideAccount indicates the overriding fields of account during the execution
// of a message call.
type OverrideAccount struct {
Nonce *hexutil.Uint64 `json:"nonce,omitempty"`
Code *hexutil.Bytes `json:"code,omitempty"`
Balance *hexutil.Big `json:"balance,omitempty"`
State map[common.Hash]common.Hash `json:"state,omitempty"`
StateDiff map[common.Hash]common.Hash `json:"stateDiff,omitempty"`
MovePrecompileTo *common.Address `json:"movePrecompileToAddress,omitempty"`
} }
return json.Marshal(Alias{
// CallArgs represents the arguments to construct a transaction call. BlockOverrides: s.BlockOverrides,
type CallArgs struct { StateOverrides: s.StateOverrides,
From *common.Address `json:"from,omitempty"` Calls: calls,
To *common.Address `json:"to,omitempty"` })
Gas *hexutil.Uint64 `json:"gas,omitempty"`
GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
MaxFeePerGas *hexutil.Big `json:"maxFeePerGas,omitempty"`
MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
Value *hexutil.Big `json:"value,omitempty"`
Nonce *hexutil.Uint64 `json:"nonce,omitempty"`
Data *hexutil.Bytes `json:"data,omitempty"`
Input *hexutil.Bytes `json:"input,omitempty"`
AccessList *types.AccessList `json:"accessList,omitempty"`
ChainID *hexutil.Big `json:"chainId,omitempty"`
BlobFeeCap *hexutil.Big `json:"maxFeePerBlobGas,omitempty"`
BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
Blobs []kzg4844.Blob `json:"blobs,omitempty"`
Commitments []kzg4844.Commitment `json:"commitments,omitempty"`
Proofs []kzg4844.Proof `json:"proofs,omitempty"`
AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"`
} }
// SimulateCallResult is the result of a simulated call. // SimulateCallResult is the result of a simulated call.

View file

@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
@ -38,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
@ -777,20 +777,20 @@ func TestSimulateV1(t *testing.T) {
// Simple test: transfer ETH from one account to another // Simple test: transfer ETH from one account to another
from := testAddr from := testAddr
to := common.HexToAddress("0x0000000000000000000000000000000000000001") to := common.HexToAddress("0x0000000000000000000000000000000000000001")
value := hexutil.Big(*big.NewInt(100)) value := big.NewInt(100)
gas := hexutil.Uint64(100000) gas := uint64(100000)
maxFeePerGas := hexutil.Big(*new(big.Int).Mul(header.BaseFee, big.NewInt(2))) maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2))
opts := ethclient.SimulateOptions{ opts := ethclient.SimulateOptions{
BlockStateCalls: []ethclient.SimulateBlock{ BlockStateCalls: []ethclient.SimulateBlock{
{ {
Calls: []ethclient.CallArgs{ Calls: []ethereum.CallMsg{
{ {
From: &from, From: from,
To: &to, To: &to,
Value: &value, Value: value,
Gas: &gas, Gas: gas,
MaxFeePerGas: &maxFeePerGas, GasFeeCap: maxFeePerGas,
}, },
}, },
}, },
@ -841,26 +841,26 @@ func TestSimulateV1WithBlockOverrides(t *testing.T) {
from := testAddr from := testAddr
to := common.HexToAddress("0x0000000000000000000000000000000000000001") to := common.HexToAddress("0x0000000000000000000000000000000000000001")
value := hexutil.Big(*big.NewInt(100)) value := big.NewInt(100)
gas := hexutil.Uint64(100000) gas := uint64(100000)
maxFeePerGas := hexutil.Big(*new(big.Int).Mul(header.BaseFee, big.NewInt(2))) maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2))
// Override timestamp only // Override timestamp only
timestamp := hexutil.Uint64(1234567890) timestamp := uint64(1234567890)
opts := ethclient.SimulateOptions{ opts := ethclient.SimulateOptions{
BlockStateCalls: []ethclient.SimulateBlock{ BlockStateCalls: []ethclient.SimulateBlock{
{ {
BlockOverrides: &ethclient.BlockOverrides{ BlockOverrides: &gethclient.BlockOverrides{
Time: &timestamp, Time: timestamp,
}, },
Calls: []ethclient.CallArgs{ Calls: []ethereum.CallMsg{
{ {
From: &from, From: from,
To: &to, To: &to,
Value: &value, Value: value,
Gas: &gas, Gas: gas,
MaxFeePerGas: &maxFeePerGas, GasFeeCap: maxFeePerGas,
}, },
}, },
}, },
@ -878,7 +878,7 @@ func TestSimulateV1WithBlockOverrides(t *testing.T) {
} }
// Verify the timestamp was overridden // Verify the timestamp was overridden
if results[0].Timestamp != timestamp { if uint64(results[0].Timestamp) != timestamp {
t.Errorf("expected timestamp %d, got %d", timestamp, results[0].Timestamp) t.Errorf("expected timestamp %d, got %d", timestamp, results[0].Timestamp)
} }
} }
@ -903,30 +903,32 @@ func TestSimulateV1WithStateOverrides(t *testing.T) {
from := testAddr from := testAddr
to := common.HexToAddress("0x0000000000000000000000000000000000000001") to := common.HexToAddress("0x0000000000000000000000000000000000000001")
value := hexutil.Big(*big.NewInt(1000000000000000000)) // 1 ETH value := big.NewInt(1000000000000000000) // 1 ETH
gas := hexutil.Uint64(100000) gas := uint64(100000)
maxFeePerGas := hexutil.Big(*new(big.Int).Mul(header.BaseFee, big.NewInt(2))) maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2))
// Override the balance of the 'from' address // Override the balance of the 'from' address
balanceStr := "1000000000000000000000" balanceStr := "1000000000000000000000"
balance := new(big.Int) balance := new(big.Int)
balance.SetString(balanceStr, 10) balance.SetString(balanceStr, 10)
stateOverrides := map[common.Address]gethclient.OverrideAccount{
from: {
Balance: balance,
},
}
opts := ethclient.SimulateOptions{ opts := ethclient.SimulateOptions{
BlockStateCalls: []ethclient.SimulateBlock{ BlockStateCalls: []ethclient.SimulateBlock{
{ {
StateOverrides: &ethclient.StateOverride{ StateOverrides: &stateOverrides,
from: ethclient.OverrideAccount{ Calls: []ethereum.CallMsg{
Balance: (*hexutil.Big)(balance),
},
},
Calls: []ethclient.CallArgs{
{ {
From: &from, From: from,
To: &to, To: &to,
Value: &value, Value: value,
Gas: &gas, Gas: gas,
MaxFeePerGas: &maxFeePerGas, GasFeeCap: maxFeePerGas,
}, },
}, },
}, },
@ -968,20 +970,20 @@ func TestSimulateV1WithBlockNumberOrHash(t *testing.T) {
from := testAddr from := testAddr
to := common.HexToAddress("0x0000000000000000000000000000000000000001") to := common.HexToAddress("0x0000000000000000000000000000000000000001")
value := hexutil.Big(*big.NewInt(100)) value := big.NewInt(100)
gas := hexutil.Uint64(100000) gas := uint64(100000)
maxFeePerGas := hexutil.Big(*new(big.Int).Mul(header.BaseFee, big.NewInt(2))) maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2))
opts := ethclient.SimulateOptions{ opts := ethclient.SimulateOptions{
BlockStateCalls: []ethclient.SimulateBlock{ BlockStateCalls: []ethclient.SimulateBlock{
{ {
Calls: []ethclient.CallArgs{ Calls: []ethereum.CallMsg{
{ {
From: &from, From: from,
To: &to, To: &to,
Value: &value, Value: value,
Gas: &gas, Gas: gas,
MaxFeePerGas: &maxFeePerGas, GasFeeCap: maxFeePerGas,
}, },
}, },
}, },