mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
move overrides to own package
This commit is contained in:
parent
6475f5a24f
commit
1d6637e808
9 changed files with 434 additions and 366 deletions
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
@ -42,6 +43,7 @@ type Options struct {
|
||||||
Chain core.ChainContext // Chain context to access past block hashes
|
Chain core.ChainContext // Chain context to access past block hashes
|
||||||
Header *types.Header // Header defining the block context to execute in
|
Header *types.Header // Header defining the block context to execute in
|
||||||
State *state.StateDB // Pre-state on top of which to estimate the gas
|
State *state.StateDB // Pre-state on top of which to estimate the gas
|
||||||
|
BlockOverrides *override.BlockOverrides // Block overrides to apply during the estimation
|
||||||
|
|
||||||
ErrorRatio float64 // Allowed overestimation ratio for faster estimation termination
|
ErrorRatio float64 // Allowed overestimation ratio for faster estimation termination
|
||||||
}
|
}
|
||||||
|
|
@ -222,6 +224,9 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio
|
||||||
|
|
||||||
dirtyState = opts.State.Copy()
|
dirtyState = opts.State.Copy()
|
||||||
)
|
)
|
||||||
|
if opts.BlockOverrides != nil {
|
||||||
|
opts.BlockOverrides.Apply(&evmContext)
|
||||||
|
}
|
||||||
// Lower the basefee to 0 to avoid breaking EVM
|
// Lower the basefee to 0 to avoid breaking EVM
|
||||||
// invariants (basefee < feecap).
|
// invariants (basefee < feecap).
|
||||||
if msgContext.GasPrice.Sign() == 0 {
|
if msgContext.GasPrice.Sign() == 0 {
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
@ -163,8 +164,8 @@ type TraceConfig struct {
|
||||||
// field to override the state for tracing.
|
// field to override the state for tracing.
|
||||||
type TraceCallConfig struct {
|
type TraceCallConfig struct {
|
||||||
TraceConfig
|
TraceConfig
|
||||||
StateOverrides *ethapi.StateOverride
|
StateOverrides *override.StateOverride
|
||||||
BlockOverrides *ethapi.BlockOverrides
|
BlockOverrides *override.BlockOverrides
|
||||||
TxIndex *hexutil.Uint
|
TxIndex *hexutil.Uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
@ -366,7 +367,7 @@ func TestTraceCall(t *testing.T) {
|
||||||
Input: &hexutil.Bytes{0x43}, // blocknumber
|
Input: &hexutil.Bytes{0x43}, // blocknumber
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
||||||
},
|
},
|
||||||
expectErr: nil,
|
expectErr: nil,
|
||||||
expect: ` {"gas":53018,"failed":false,"returnValue":"","structLogs":[
|
expect: ` {"gas":53018,"failed":false,"returnValue":"","structLogs":[
|
||||||
|
|
@ -610,8 +611,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Value: (*hexutil.Big)(big.NewInt(1000)),
|
Value: (*hexutil.Big)(big.NewInt(1000)),
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: `{"gas":21000,"failed":false,"returnValue":""}`,
|
want: `{"gas":21000,"failed":false,"returnValue":""}`,
|
||||||
|
|
@ -652,8 +653,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
//Tracer: &tracer,
|
//Tracer: &tracer,
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: ethapi.OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")),
|
Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")),
|
||||||
StateDiff: newStates([]common.Hash{{}}, []common.Hash{common.BigToHash(big.NewInt(123))}),
|
StateDiff: newStates([]common.Hash{{}}, []common.Hash{common.BigToHash(big.NewInt(123))}),
|
||||||
},
|
},
|
||||||
|
|
@ -669,7 +670,7 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
|
Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
||||||
},
|
},
|
||||||
want: `{"gas":59537,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000001337"}`,
|
want: `{"gas":59537,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000001337"}`,
|
||||||
},
|
},
|
||||||
|
|
@ -689,7 +690,7 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
}, // blocknumber
|
}, // blocknumber
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
|
||||||
},
|
},
|
||||||
want: `{"gas":72666,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`,
|
want: `{"gas":72666,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`,
|
||||||
},
|
},
|
||||||
|
|
@ -719,8 +720,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: ethapi.OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")),
|
Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -735,8 +736,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: ethapi.OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")),
|
Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")),
|
||||||
State: newStates([]common.Hash{{}}, []common.Hash{{}}),
|
State: newStates([]common.Hash{{}}, []common.Hash{{}}),
|
||||||
},
|
},
|
||||||
|
|
@ -753,8 +754,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
storageAccount: ethapi.OverrideAccount{
|
storageAccount: override.OverrideAccount{
|
||||||
Code: newRPCBytes([]byte{
|
Code: newRPCBytes([]byte{
|
||||||
// SLOAD(3) + SLOAD(4) (which is 0x77)
|
// SLOAD(3) + SLOAD(4) (which is 0x77)
|
||||||
byte(vm.PUSH1), 0x04,
|
byte(vm.PUSH1), 0x04,
|
||||||
|
|
@ -788,8 +789,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
storageAccount: ethapi.OverrideAccount{
|
storageAccount: override.OverrideAccount{
|
||||||
Code: newRPCBytes([]byte{
|
Code: newRPCBytes([]byte{
|
||||||
// SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x00)
|
// SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x00)
|
||||||
byte(vm.PUSH1), 0x04,
|
byte(vm.PUSH1), 0x04,
|
||||||
|
|
@ -826,8 +827,8 @@ func TestTracingWithOverrides(t *testing.T) {
|
||||||
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
|
||||||
},
|
},
|
||||||
config: &TraceCallConfig{
|
config: &TraceCallConfig{
|
||||||
StateOverrides: ðapi.StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
storageAccount: ethapi.OverrideAccount{
|
storageAccount: override.OverrideAccount{
|
||||||
Code: newRPCBytes([]byte{
|
Code: newRPCBytes([]byte{
|
||||||
// SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x44)
|
// SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x44)
|
||||||
byte(vm.PUSH1), 0x04,
|
byte(vm.PUSH1), 0x04,
|
||||||
|
|
|
||||||
|
|
@ -36,19 +36,18 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasestimator"
|
"github.com/ethereum/go-ethereum/eth/gasestimator"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/holiman/uint256"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// estimateGasErrorRatio is the amount of overestimation eth_estimateGas is
|
// estimateGasErrorRatio is the amount of overestimation eth_estimateGas is
|
||||||
|
|
@ -622,171 +621,6 @@ func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rp
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OverrideAccount indicates the overriding fields of account during the execution
|
|
||||||
// of a message call.
|
|
||||||
// Note, state and stateDiff can't be specified at the same time. If state is
|
|
||||||
// set, message execution will only use the data in the given state. Otherwise
|
|
||||||
// if stateDiff is set, all diff will be applied first and then execute the call
|
|
||||||
// message.
|
|
||||||
type OverrideAccount struct {
|
|
||||||
Nonce *hexutil.Uint64 `json:"nonce"`
|
|
||||||
Code *hexutil.Bytes `json:"code"`
|
|
||||||
Balance *hexutil.Big `json:"balance"`
|
|
||||||
State map[common.Hash]common.Hash `json:"state"`
|
|
||||||
StateDiff map[common.Hash]common.Hash `json:"stateDiff"`
|
|
||||||
MovePrecompileTo *common.Address `json:"movePrecompileToAddress"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StateOverride is the collection of overridden accounts.
|
|
||||||
type StateOverride map[common.Address]OverrideAccount
|
|
||||||
|
|
||||||
func (diff *StateOverride) has(address common.Address) bool {
|
|
||||||
_, ok := (*diff)[address]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply overrides the fields of specified accounts into the given state.
|
|
||||||
func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.PrecompiledContracts) error {
|
|
||||||
if diff == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Tracks destinations of precompiles that were moved.
|
|
||||||
dirtyAddrs := make(map[common.Address]struct{})
|
|
||||||
for addr, account := range *diff {
|
|
||||||
// If a precompile was moved to this address already, it can't be overridden.
|
|
||||||
if _, ok := dirtyAddrs[addr]; ok {
|
|
||||||
return fmt.Errorf("account %s has already been overridden by a precompile", addr.Hex())
|
|
||||||
}
|
|
||||||
p, isPrecompile := precompiles[addr]
|
|
||||||
// The MoveTo feature makes it possible to move a precompile
|
|
||||||
// code to another address. If the target address is another precompile
|
|
||||||
// the code for the latter is lost for this session.
|
|
||||||
// Note the destination account is not cleared upon move.
|
|
||||||
if account.MovePrecompileTo != nil {
|
|
||||||
if !isPrecompile {
|
|
||||||
return fmt.Errorf("account %s is not a precompile", addr.Hex())
|
|
||||||
}
|
|
||||||
// Refuse to move a precompile to an address that has been
|
|
||||||
// or will be overridden.
|
|
||||||
if diff.has(*account.MovePrecompileTo) {
|
|
||||||
return fmt.Errorf("account %s is already overridden", account.MovePrecompileTo.Hex())
|
|
||||||
}
|
|
||||||
precompiles[*account.MovePrecompileTo] = p
|
|
||||||
dirtyAddrs[*account.MovePrecompileTo] = struct{}{}
|
|
||||||
}
|
|
||||||
if isPrecompile {
|
|
||||||
delete(precompiles, addr)
|
|
||||||
}
|
|
||||||
// Override account nonce.
|
|
||||||
if account.Nonce != nil {
|
|
||||||
statedb.SetNonce(addr, uint64(*account.Nonce))
|
|
||||||
}
|
|
||||||
// Override account(contract) code.
|
|
||||||
if account.Code != nil {
|
|
||||||
statedb.SetCode(addr, *account.Code)
|
|
||||||
}
|
|
||||||
// Override account balance.
|
|
||||||
if account.Balance != nil {
|
|
||||||
u256Balance, _ := uint256.FromBig((*big.Int)(account.Balance))
|
|
||||||
statedb.SetBalance(addr, u256Balance, tracing.BalanceChangeUnspecified)
|
|
||||||
}
|
|
||||||
if account.State != nil && account.StateDiff != nil {
|
|
||||||
return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
|
|
||||||
}
|
|
||||||
// Replace entire state if caller requires.
|
|
||||||
if account.State != nil {
|
|
||||||
statedb.SetStorage(addr, account.State)
|
|
||||||
}
|
|
||||||
// Apply state diff into specified accounts.
|
|
||||||
if account.StateDiff != nil {
|
|
||||||
for key, value := range account.StateDiff {
|
|
||||||
statedb.SetState(addr, key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now finalize the changes. Finalize is normally performed between transactions.
|
|
||||||
// By using finalize, the overrides are semantically behaving as
|
|
||||||
// if they were created in a transaction just before the tracing occur.
|
|
||||||
statedb.Finalise(false)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BlockOverrides is a set of header fields to override.
|
|
||||||
type BlockOverrides struct {
|
|
||||||
Number *hexutil.Big
|
|
||||||
Difficulty *hexutil.Big // No-op if we're simulating post-merge calls.
|
|
||||||
Time *hexutil.Uint64
|
|
||||||
GasLimit *hexutil.Uint64
|
|
||||||
FeeRecipient *common.Address
|
|
||||||
PrevRandao *common.Hash
|
|
||||||
BaseFeePerGas *hexutil.Big
|
|
||||||
BlobBaseFee *hexutil.Big
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply overrides the given header fields into the given block context.
|
|
||||||
func (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) {
|
|
||||||
if o == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if o.Number != nil {
|
|
||||||
blockCtx.BlockNumber = o.Number.ToInt()
|
|
||||||
}
|
|
||||||
if o.Difficulty != nil {
|
|
||||||
blockCtx.Difficulty = o.Difficulty.ToInt()
|
|
||||||
}
|
|
||||||
if o.Time != nil {
|
|
||||||
blockCtx.Time = uint64(*o.Time)
|
|
||||||
}
|
|
||||||
if o.GasLimit != nil {
|
|
||||||
blockCtx.GasLimit = uint64(*o.GasLimit)
|
|
||||||
}
|
|
||||||
if o.FeeRecipient != nil {
|
|
||||||
blockCtx.Coinbase = *o.FeeRecipient
|
|
||||||
}
|
|
||||||
if o.PrevRandao != nil {
|
|
||||||
blockCtx.Random = o.PrevRandao
|
|
||||||
}
|
|
||||||
if o.BaseFeePerGas != nil {
|
|
||||||
blockCtx.BaseFee = o.BaseFeePerGas.ToInt()
|
|
||||||
}
|
|
||||||
if o.BlobBaseFee != nil {
|
|
||||||
blockCtx.BlobBaseFee = o.BlobBaseFee.ToInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeHeader returns a new header object with the overridden
|
|
||||||
// fields.
|
|
||||||
// Note: MakeHeader ignores BlobBaseFee if set. That's because
|
|
||||||
// header has no such field.
|
|
||||||
func (o *BlockOverrides) MakeHeader(header *types.Header) *types.Header {
|
|
||||||
if o == nil {
|
|
||||||
return header
|
|
||||||
}
|
|
||||||
h := types.CopyHeader(header)
|
|
||||||
if o.Number != nil {
|
|
||||||
h.Number = o.Number.ToInt()
|
|
||||||
}
|
|
||||||
if o.Difficulty != nil {
|
|
||||||
h.Difficulty = o.Difficulty.ToInt()
|
|
||||||
}
|
|
||||||
if o.Time != nil {
|
|
||||||
h.Time = uint64(*o.Time)
|
|
||||||
}
|
|
||||||
if o.GasLimit != nil {
|
|
||||||
h.GasLimit = uint64(*o.GasLimit)
|
|
||||||
}
|
|
||||||
if o.FeeRecipient != nil {
|
|
||||||
h.Coinbase = *o.FeeRecipient
|
|
||||||
}
|
|
||||||
if o.PrevRandao != nil {
|
|
||||||
h.MixDigest = *o.PrevRandao
|
|
||||||
}
|
|
||||||
if o.BaseFeePerGas != nil {
|
|
||||||
h.BaseFee = o.BaseFeePerGas.ToInt()
|
|
||||||
}
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChainContextBackend provides methods required to implement ChainContext.
|
// ChainContextBackend provides methods required to implement ChainContext.
|
||||||
type ChainContextBackend interface {
|
type ChainContextBackend interface {
|
||||||
Engine() consensus.Engine
|
Engine() consensus.Engine
|
||||||
|
|
@ -819,7 +653,7 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||||
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
|
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
|
||||||
if blockOverrides != nil {
|
if blockOverrides != nil {
|
||||||
blockOverrides.Apply(&blockCtx)
|
blockOverrides.Apply(&blockCtx)
|
||||||
|
|
@ -898,7 +732,7 @@ func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, ti
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||||
|
|
||||||
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||||
|
|
@ -914,7 +748,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
|
||||||
//
|
//
|
||||||
// Note, this function doesn't make and changes in the state/blockchain and is
|
// Note, this function doesn't make and changes in the state/blockchain and is
|
||||||
// useful to execute and retrieve values.
|
// useful to execute and retrieve values.
|
||||||
func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) {
|
func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *override.StateOverride, blockOverrides *override.BlockOverrides) (hexutil.Bytes, error) {
|
||||||
if blockNrOrHash == nil {
|
if blockNrOrHash == nil {
|
||||||
latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
|
latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
|
||||||
blockNrOrHash = &latest
|
blockNrOrHash = &latest
|
||||||
|
|
@ -973,7 +807,7 @@ func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrO
|
||||||
// successfully at block `blockNrOrHash`. It returns error if the transaction would revert, or if
|
// successfully at block `blockNrOrHash`. It returns error if the transaction would revert, or if
|
||||||
// there are unexpected failures. The gas limit is capped by both `args.Gas` (if non-nil &
|
// there are unexpected failures. The gas limit is capped by both `args.Gas` (if non-nil &
|
||||||
// non-zero) and `gasCap` (if non-zero).
|
// non-zero) and `gasCap` (if non-zero).
|
||||||
func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, gasCap uint64) (hexutil.Uint64, error) {
|
func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, gasCap uint64) (hexutil.Uint64, error) {
|
||||||
// Retrieve the base state and mutate it with any overrides
|
// Retrieve the base state and mutate it with any overrides
|
||||||
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||||
if state == nil || err != nil {
|
if state == nil || err != nil {
|
||||||
|
|
@ -981,10 +815,6 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||||
}
|
}
|
||||||
chainContext := NewChainContext(ctx, b)
|
chainContext := NewChainContext(ctx, b)
|
||||||
blockCtx := core.NewEVMBlockContext(header, chainContext, nil)
|
blockCtx := core.NewEVMBlockContext(header, chainContext, nil)
|
||||||
if blockOverrides != nil {
|
|
||||||
blockOverrides.Apply(&blockCtx)
|
|
||||||
}
|
|
||||||
|
|
||||||
rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time)
|
rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time)
|
||||||
precompiles := maps.Clone(vm.ActivePrecompiledContracts(rules))
|
precompiles := maps.Clone(vm.ActivePrecompiledContracts(rules))
|
||||||
if err := overrides.Apply(state, precompiles); err != nil {
|
if err := overrides.Apply(state, precompiles); err != nil {
|
||||||
|
|
@ -994,7 +824,8 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||||
opts := &gasestimator.Options{
|
opts := &gasestimator.Options{
|
||||||
Config: b.ChainConfig(),
|
Config: b.ChainConfig(),
|
||||||
Chain: chainContext,
|
Chain: chainContext,
|
||||||
Header: blockOverrides.MakeHeader(header),
|
Header: header,
|
||||||
|
BlockOverrides: blockOverrides,
|
||||||
State: state,
|
State: state,
|
||||||
ErrorRatio: estimateGasErrorRatio,
|
ErrorRatio: estimateGasErrorRatio,
|
||||||
}
|
}
|
||||||
|
|
@ -1025,7 +856,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||||
// value is capped by both `args.Gas` (if non-nil & non-zero) and the backend's RPCGasCap
|
// value is capped by both `args.Gas` (if non-nil & non-zero) and the backend's RPCGasCap
|
||||||
// configuration (if non-zero).
|
// configuration (if non-zero).
|
||||||
// Note: Required blob gas is not computed in this method.
|
// Note: Required blob gas is not computed in this method.
|
||||||
func (api *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Uint64, error) {
|
func (api *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *override.StateOverride, blockOverrides *override.BlockOverrides) (hexutil.Uint64, error) {
|
||||||
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
|
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
|
||||||
if blockNrOrHash != nil {
|
if blockNrOrHash != nil {
|
||||||
bNrOrHash = *blockNrOrHash
|
bNrOrHash = *blockNrOrHash
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -35,6 +34,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
|
@ -57,7 +57,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/internal/blocktest"
|
"github.com/ethereum/go-ethereum/internal/blocktest"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
@ -666,8 +665,8 @@ func TestEstimateGas(t *testing.T) {
|
||||||
var testSuite = []struct {
|
var testSuite = []struct {
|
||||||
blockNumber rpc.BlockNumber
|
blockNumber rpc.BlockNumber
|
||||||
call TransactionArgs
|
call TransactionArgs
|
||||||
overrides StateOverride
|
overrides override.StateOverride
|
||||||
blockOverrides BlockOverrides
|
blockOverrides override.BlockOverrides
|
||||||
expectErr error
|
expectErr error
|
||||||
want uint64
|
want uint64
|
||||||
}{
|
}{
|
||||||
|
|
@ -703,8 +702,8 @@ func TestEstimateGas(t *testing.T) {
|
||||||
{
|
{
|
||||||
blockNumber: rpc.LatestBlockNumber,
|
blockNumber: rpc.LatestBlockNumber,
|
||||||
call: TransactionArgs{},
|
call: TransactionArgs{},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
|
||||||
},
|
},
|
||||||
expectErr: nil,
|
expectErr: nil,
|
||||||
want: 53000,
|
want: 53000,
|
||||||
|
|
@ -716,8 +715,8 @@ func TestEstimateGas(t *testing.T) {
|
||||||
To: &randomAccounts[1].addr,
|
To: &randomAccounts[1].addr,
|
||||||
Value: (*hexutil.Big)(big.NewInt(1000)),
|
Value: (*hexutil.Big)(big.NewInt(1000)),
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
|
||||||
},
|
},
|
||||||
expectErr: core.ErrInsufficientFunds,
|
expectErr: core.ErrInsufficientFunds,
|
||||||
},
|
},
|
||||||
|
|
@ -813,12 +812,12 @@ func TestEstimateGas(t *testing.T) {
|
||||||
To: &accounts[1].addr,
|
To: &accounts[1].addr,
|
||||||
Data: hex2Bytes("0x3592d016"), //estimate
|
Data: hex2Bytes("0x3592d016"), //estimate
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
accounts[1].addr: OverrideAccount{
|
accounts[1].addr: override.OverrideAccount{
|
||||||
Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"),
|
Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
blockOverrides: BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
|
blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
|
||||||
expectErr: newRevertError(packRevert("block 11")),
|
expectErr: newRevertError(packRevert("block 11")),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -883,9 +882,9 @@ func TestCall(t *testing.T) {
|
||||||
var testSuite = []struct {
|
var testSuite = []struct {
|
||||||
name string
|
name string
|
||||||
blockNumber rpc.BlockNumber
|
blockNumber rpc.BlockNumber
|
||||||
overrides StateOverride
|
overrides override.StateOverride
|
||||||
call TransactionArgs
|
call TransactionArgs
|
||||||
blockOverrides BlockOverrides
|
blockOverrides override.BlockOverrides
|
||||||
expectErr error
|
expectErr error
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
|
|
@ -945,8 +944,8 @@ func TestCall(t *testing.T) {
|
||||||
To: &randomAccounts[1].addr,
|
To: &randomAccounts[1].addr,
|
||||||
Value: (*hexutil.Big)(big.NewInt(1000)),
|
Value: (*hexutil.Big)(big.NewInt(1000)),
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
|
||||||
},
|
},
|
||||||
want: "0x",
|
want: "0x",
|
||||||
},
|
},
|
||||||
|
|
@ -985,8 +984,8 @@ func TestCall(t *testing.T) {
|
||||||
To: &randomAccounts[2].addr,
|
To: &randomAccounts[2].addr,
|
||||||
Data: hex2Bytes("8381f58a"), // call number()
|
Data: hex2Bytes("8381f58a"), // call number()
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
randomAccounts[2].addr: OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
Code: hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033"),
|
Code: hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033"),
|
||||||
StateDiff: map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))},
|
StateDiff: map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))},
|
||||||
},
|
},
|
||||||
|
|
@ -1033,12 +1032,12 @@ func TestCall(t *testing.T) {
|
||||||
To: &accounts[2].addr,
|
To: &accounts[2].addr,
|
||||||
Data: hex2Bytes("0x28b5e32b"), //call
|
Data: hex2Bytes("0x28b5e32b"), //call
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
accounts[2].addr: OverrideAccount{
|
accounts[2].addr: override.OverrideAccount{
|
||||||
Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"),
|
Code: hex2Bytes("608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806328b5e32b146100385780633592d0161461004b575b5f5ffd5b4360405190815260200160405180910390f35b610053610055565b005b61005e4361009d565b60405160200161006e91906101a5565b60408051601f198184030181529082905262461bcd60e51b8252610094916004016101cd565b60405180910390fd5b6060815f036100c35750506040805180820190915260018152600360fc1b602082015290565b815f5b81156100ec57806100d681610216565b91506100e59050600a83610242565b91506100c6565b5f8167ffffffffffffffff81111561010657610106610255565b6040519080825280601f01601f191660200182016040528015610130576020820181803683370190505b508593509050815b831561019c57610149600a85610269565b61015490603061027c565b60f81b8261016183610295565b92508281518110610174576101746102aa565b60200101906001600160f81b03191690815f1a905350610195600a85610242565b9350610138565b50949350505050565b650313637b1b5960d51b81525f82518060208501600685015e5f920160060191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161022757610227610202565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f826102505761025061022e565b500490565b634e487b7160e01b5f52604160045260245ffd5b5f826102775761027761022e565b500690565b8082018082111561028f5761028f610202565b92915050565b5f816102a3576102a3610202565b505f190190565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220a253cad1e2e3523b8c053c1d0cd1e39d7f3bafcedd73440a244872701f05dab264736f6c634300081c0033"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
blockOverrides: BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
|
blockOverrides: override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
|
||||||
want: "0x000000000000000000000000000000000000000000000000000000000000000b",
|
want: "0x000000000000000000000000000000000000000000000000000000000000000b",
|
||||||
},
|
},
|
||||||
// Clear storage trie
|
// Clear storage trie
|
||||||
|
|
@ -1061,8 +1060,8 @@ func TestCall(t *testing.T) {
|
||||||
// }
|
// }
|
||||||
Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"),
|
Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"),
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
dad: OverrideAccount{
|
dad: override.OverrideAccount{
|
||||||
State: map[common.Hash]common.Hash{},
|
State: map[common.Hash]common.Hash{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -1089,7 +1088,7 @@ func TestCall(t *testing.T) {
|
||||||
BlobHashes: []common.Hash{{0x01, 0x22}},
|
BlobHashes: []common.Hash{{0x01, 0x22}},
|
||||||
BlobFeeCap: (*hexutil.Big)(big.NewInt(1)),
|
BlobFeeCap: (*hexutil.Big)(big.NewInt(1)),
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
randomAccounts[2].addr: {
|
randomAccounts[2].addr: {
|
||||||
Code: hex2Bytes("60004960005260206000f3"),
|
Code: hex2Bytes("60004960005260206000f3"),
|
||||||
},
|
},
|
||||||
|
|
@ -1115,8 +1114,8 @@ func TestCall(t *testing.T) {
|
||||||
// }
|
// }
|
||||||
Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"),
|
Input: hex2Bytes("610dad6000813103600f57600080fd5b6000548060005260206000f3"),
|
||||||
},
|
},
|
||||||
overrides: StateOverride{
|
overrides: override.StateOverride{
|
||||||
dad: OverrideAccount{
|
dad: override.OverrideAccount{
|
||||||
State: map[common.Hash]common.Hash{},
|
State: map[common.Hash]common.Hash{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -1270,8 +1269,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "simple",
|
name: "simple",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))},
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
From: &randomAccounts[0].addr,
|
From: &randomAccounts[0].addr,
|
||||||
|
|
@ -1313,8 +1312,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "simple-multi-block",
|
name: "simple-multi-block",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))},
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{
|
Calls: []TransactionArgs{
|
||||||
{
|
{
|
||||||
|
|
@ -1328,8 +1327,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[3].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
|
randomAccounts[3].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{
|
Calls: []TransactionArgs{
|
||||||
{
|
{
|
||||||
|
|
@ -1387,8 +1386,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "evm-error",
|
name: "evm-error",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: OverrideAccount{Code: hex2Bytes("f3")},
|
randomAccounts[2].addr: override.OverrideAccount{Code: hex2Bytes("f3")},
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
From: &randomAccounts[0].addr,
|
From: &randomAccounts[0].addr,
|
||||||
|
|
@ -1414,7 +1413,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "block-overrides",
|
name: "block-overrides",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
Number: (*hexutil.Big)(big.NewInt(11)),
|
Number: (*hexutil.Big)(big.NewInt(11)),
|
||||||
FeeRecipient: &cac,
|
FeeRecipient: &cac,
|
||||||
},
|
},
|
||||||
|
|
@ -1429,7 +1428,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
Number: (*hexutil.Big)(big.NewInt(12)),
|
Number: (*hexutil.Big)(big.NewInt(12)),
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
|
|
@ -1472,7 +1471,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "block-number-order",
|
name: "block-number-order",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
Number: (*hexutil.Big)(big.NewInt(12)),
|
Number: (*hexutil.Big)(big.NewInt(12)),
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
|
|
@ -1484,7 +1483,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}, {
|
}, {
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
Number: (*hexutil.Big)(big.NewInt(11)),
|
Number: (*hexutil.Big)(big.NewInt(11)),
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
|
|
@ -1504,8 +1503,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "storage-contract",
|
name: "storage-contract",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"),
|
Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -1546,8 +1545,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "logs",
|
name: "logs",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
// Yul code:
|
// Yul code:
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
// code {
|
// code {
|
||||||
|
|
@ -1588,8 +1587,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "ecrecover-override",
|
name: "ecrecover-override",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
// Yul code that returns ecrecover(0, 0, 0, 0).
|
// Yul code that returns ecrecover(0, 0, 0, 0).
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
// code {
|
// code {
|
||||||
|
|
@ -1616,7 +1615,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
// }
|
// }
|
||||||
Code: hex2Bytes("6040516000815260006020820152600060408201526000606082015260208160808360015afa60008103603157600080fd5b601482f3"),
|
Code: hex2Bytes("6040516000815260006020820152600060408201526000606082015260208160808360015afa60008103603157600080fd5b601482f3"),
|
||||||
},
|
},
|
||||||
common.BytesToAddress([]byte{0x01}): OverrideAccount{
|
common.BytesToAddress([]byte{0x01}): override.OverrideAccount{
|
||||||
// Yul code that returns the address of the caller.
|
// Yul code that returns the address of the caller.
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
// code {
|
// code {
|
||||||
|
|
@ -1653,8 +1652,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "precompile-move",
|
name: "precompile-move",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
sha256Address: OverrideAccount{
|
sha256Address: override.OverrideAccount{
|
||||||
// Yul code that returns the calldata.
|
// Yul code that returns the calldata.
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
// code {
|
// code {
|
||||||
|
|
@ -1708,8 +1707,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "transfer-logs",
|
name: "transfer-logs",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{
|
randomAccounts[0].addr: override.OverrideAccount{
|
||||||
Balance: newRPCBalance(big.NewInt(100)),
|
Balance: newRPCBalance(big.NewInt(100)),
|
||||||
// Yul code that transfers 100 wei to address passed in calldata:
|
// Yul code that transfers 100 wei to address passed in calldata:
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
|
|
@ -1851,8 +1850,8 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "validation-checks-from-contract",
|
name: "validation-checks-from-contract",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: OverrideAccount{
|
randomAccounts[2].addr: override.OverrideAccount{
|
||||||
Balance: newRPCBalance(big.NewInt(2098640803896784)),
|
Balance: newRPCBalance(big.NewInt(2098640803896784)),
|
||||||
Code: hex2Bytes("00"),
|
Code: hex2Bytes("00"),
|
||||||
Nonce: newUint64(1),
|
Nonce: newUint64(1),
|
||||||
|
|
@ -1886,11 +1885,11 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "validation-checks-success",
|
name: "validation-checks-success",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)),
|
BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)),
|
||||||
},
|
},
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(10000000))},
|
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(big.NewInt(10000000))},
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
From: &randomAccounts[0].addr,
|
From: &randomAccounts[0].addr,
|
||||||
|
|
@ -1919,7 +1918,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "clear-storage",
|
name: "clear-storage",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: {
|
randomAccounts[2].addr: {
|
||||||
Code: newBytes(genesis.Alloc[bab].Code),
|
Code: newBytes(genesis.Alloc[bab].Code),
|
||||||
StateDiff: map[common.Hash]common.Hash{
|
StateDiff: map[common.Hash]common.Hash{
|
||||||
|
|
@ -1941,7 +1940,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
To: &bab,
|
To: &bab,
|
||||||
}},
|
}},
|
||||||
}, {
|
}, {
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: {
|
randomAccounts[2].addr: {
|
||||||
State: map[common.Hash]common.Hash{
|
State: map[common.Hash]common.Hash{
|
||||||
common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(5)),
|
common.BigToHash(big.NewInt(1)): common.BigToHash(big.NewInt(5)),
|
||||||
|
|
@ -1988,10 +1987,10 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "blockhash-opcode",
|
name: "blockhash-opcode",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
Number: (*hexutil.Big)(big.NewInt(12)),
|
Number: (*hexutil.Big)(big.NewInt(12)),
|
||||||
},
|
},
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: {
|
randomAccounts[2].addr: {
|
||||||
Code: hex2Bytes("600035804060008103601057600080fd5b5050"),
|
Code: hex2Bytes("600035804060008103601057600080fd5b5050"),
|
||||||
},
|
},
|
||||||
|
|
@ -2013,7 +2012,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
Input: uint256ToBytes(uint256.NewInt(10)),
|
Input: uint256ToBytes(uint256.NewInt(10)),
|
||||||
}},
|
}},
|
||||||
}, {
|
}, {
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
Number: (*hexutil.Big)(big.NewInt(16)),
|
Number: (*hexutil.Big)(big.NewInt(16)),
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
|
|
@ -2103,7 +2102,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "basefee-non-validation",
|
name: "basefee-non-validation",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: {
|
randomAccounts[2].addr: {
|
||||||
// Yul code:
|
// Yul code:
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
|
|
@ -2138,7 +2137,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
BlockOverrides: &BlockOverrides{
|
BlockOverrides: &override.BlockOverrides{
|
||||||
BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)),
|
BaseFeePerGas: (*hexutil.Big)(big.NewInt(1)),
|
||||||
},
|
},
|
||||||
Calls: []TransactionArgs{{
|
Calls: []TransactionArgs{{
|
||||||
|
|
@ -2211,7 +2210,7 @@ func TestSimulateV1(t *testing.T) {
|
||||||
name: "basefee-validation-mode",
|
name: "basefee-validation-mode",
|
||||||
tag: latest,
|
tag: latest,
|
||||||
blocks: []simBlock{{
|
blocks: []simBlock{{
|
||||||
StateOverrides: &StateOverride{
|
StateOverrides: &override.StateOverride{
|
||||||
randomAccounts[2].addr: {
|
randomAccounts[2].addr: {
|
||||||
// Yul code:
|
// Yul code:
|
||||||
// object "Test" {
|
// object "Test" {
|
||||||
|
|
@ -3384,97 +3383,6 @@ func TestRPCGetBlockReceipts(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type precompileContract struct{}
|
|
||||||
|
|
||||||
func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 }
|
|
||||||
|
|
||||||
func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil }
|
|
||||||
|
|
||||||
func TestStateOverrideMovePrecompile(t *testing.T) {
|
|
||||||
db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
|
|
||||||
statedb, err := state.New(common.Hash{}, db)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to create statedb: %v", err)
|
|
||||||
}
|
|
||||||
precompiles := map[common.Address]vm.PrecompiledContract{
|
|
||||||
common.BytesToAddress([]byte{0x1}): &precompileContract{},
|
|
||||||
common.BytesToAddress([]byte{0x2}): &precompileContract{},
|
|
||||||
}
|
|
||||||
bytes2Addr := func(b []byte) *common.Address {
|
|
||||||
a := common.BytesToAddress(b)
|
|
||||||
return &a
|
|
||||||
}
|
|
||||||
var testSuite = []struct {
|
|
||||||
overrides StateOverride
|
|
||||||
expectedPrecompiles map[common.Address]struct{}
|
|
||||||
fail bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
overrides: StateOverride{
|
|
||||||
common.BytesToAddress([]byte{0x1}): {
|
|
||||||
Code: hex2Bytes("0xff"),
|
|
||||||
MovePrecompileTo: bytes2Addr([]byte{0x2}),
|
|
||||||
},
|
|
||||||
common.BytesToAddress([]byte{0x2}): {
|
|
||||||
Code: hex2Bytes("0x00"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 0x2 has already been touched by the moveTo.
|
|
||||||
fail: true,
|
|
||||||
}, {
|
|
||||||
overrides: StateOverride{
|
|
||||||
common.BytesToAddress([]byte{0x1}): {
|
|
||||||
Code: hex2Bytes("0xff"),
|
|
||||||
MovePrecompileTo: bytes2Addr([]byte{0xff}),
|
|
||||||
},
|
|
||||||
common.BytesToAddress([]byte{0x3}): {
|
|
||||||
Code: hex2Bytes("0x00"),
|
|
||||||
MovePrecompileTo: bytes2Addr([]byte{0xfe}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 0x3 is not a precompile.
|
|
||||||
fail: true,
|
|
||||||
}, {
|
|
||||||
overrides: StateOverride{
|
|
||||||
common.BytesToAddress([]byte{0x1}): {
|
|
||||||
Code: hex2Bytes("0xff"),
|
|
||||||
MovePrecompileTo: bytes2Addr([]byte{0xff}),
|
|
||||||
},
|
|
||||||
common.BytesToAddress([]byte{0x2}): {
|
|
||||||
Code: hex2Bytes("0x00"),
|
|
||||||
MovePrecompileTo: bytes2Addr([]byte{0xfe}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedPrecompiles: map[common.Address]struct{}{common.BytesToAddress([]byte{0xfe}): {}, common.BytesToAddress([]byte{0xff}): {}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, tt := range testSuite {
|
|
||||||
cpy := maps.Clone(precompiles)
|
|
||||||
// Apply overrides
|
|
||||||
err := tt.overrides.Apply(statedb, cpy)
|
|
||||||
if tt.fail {
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("test %d: want error, have nothing", i)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("test %d: want no error, have %v", i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Precompile keys
|
|
||||||
if len(cpy) != len(tt.expectedPrecompiles) {
|
|
||||||
t.Errorf("test %d: precompile mismatch, want %d, have %d", i, len(tt.expectedPrecompiles), len(cpy))
|
|
||||||
}
|
|
||||||
for k := range tt.expectedPrecompiles {
|
|
||||||
if _, ok := cpy[k]; !ok {
|
|
||||||
t.Errorf("test %d: precompile not found: %s", i, k.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc string, file string) {
|
func testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc string, file string) {
|
||||||
data, err := json.MarshalIndent(result, "", " ")
|
data, err := json.MarshalIndent(result, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
195
internal/ethapi/override/override.go
Normal file
195
internal/ethapi/override/override.go
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
// Copyright 2024 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package override
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OverrideAccount indicates the overriding fields of account during the execution
|
||||||
|
// of a message call.
|
||||||
|
// Note, state and stateDiff can't be specified at the same time. If state is
|
||||||
|
// set, message execution will only use the data in the given state. Otherwise
|
||||||
|
// if stateDiff is set, all diff will be applied first and then execute the call
|
||||||
|
// message.
|
||||||
|
type OverrideAccount struct {
|
||||||
|
Nonce *hexutil.Uint64 `json:"nonce"`
|
||||||
|
Code *hexutil.Bytes `json:"code"`
|
||||||
|
Balance *hexutil.Big `json:"balance"`
|
||||||
|
State map[common.Hash]common.Hash `json:"state"`
|
||||||
|
StateDiff map[common.Hash]common.Hash `json:"stateDiff"`
|
||||||
|
MovePrecompileTo *common.Address `json:"movePrecompileToAddress"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateOverride is the collection of overridden accounts.
|
||||||
|
type StateOverride map[common.Address]OverrideAccount
|
||||||
|
|
||||||
|
func (diff *StateOverride) has(address common.Address) bool {
|
||||||
|
_, ok := (*diff)[address]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply overrides the fields of specified accounts into the given state.
|
||||||
|
func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.PrecompiledContracts) error {
|
||||||
|
if diff == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Tracks destinations of precompiles that were moved.
|
||||||
|
dirtyAddrs := make(map[common.Address]struct{})
|
||||||
|
for addr, account := range *diff {
|
||||||
|
// If a precompile was moved to this address already, it can't be overridden.
|
||||||
|
if _, ok := dirtyAddrs[addr]; ok {
|
||||||
|
return fmt.Errorf("account %s has already been overridden by a precompile", addr.Hex())
|
||||||
|
}
|
||||||
|
p, isPrecompile := precompiles[addr]
|
||||||
|
// The MoveTo feature makes it possible to move a precompile
|
||||||
|
// code to another address. If the target address is another precompile
|
||||||
|
// the code for the latter is lost for this session.
|
||||||
|
// Note the destination account is not cleared upon move.
|
||||||
|
if account.MovePrecompileTo != nil {
|
||||||
|
if !isPrecompile {
|
||||||
|
return fmt.Errorf("account %s is not a precompile", addr.Hex())
|
||||||
|
}
|
||||||
|
// Refuse to move a precompile to an address that has been
|
||||||
|
// or will be overridden.
|
||||||
|
if diff.has(*account.MovePrecompileTo) {
|
||||||
|
return fmt.Errorf("account %s is already overridden", account.MovePrecompileTo.Hex())
|
||||||
|
}
|
||||||
|
precompiles[*account.MovePrecompileTo] = p
|
||||||
|
dirtyAddrs[*account.MovePrecompileTo] = struct{}{}
|
||||||
|
}
|
||||||
|
if isPrecompile {
|
||||||
|
delete(precompiles, addr)
|
||||||
|
}
|
||||||
|
// Override account nonce.
|
||||||
|
if account.Nonce != nil {
|
||||||
|
statedb.SetNonce(addr, uint64(*account.Nonce))
|
||||||
|
}
|
||||||
|
// Override account(contract) code.
|
||||||
|
if account.Code != nil {
|
||||||
|
statedb.SetCode(addr, *account.Code)
|
||||||
|
}
|
||||||
|
// Override account balance.
|
||||||
|
if account.Balance != nil {
|
||||||
|
u256Balance, _ := uint256.FromBig((*big.Int)(account.Balance))
|
||||||
|
statedb.SetBalance(addr, u256Balance, tracing.BalanceChangeUnspecified)
|
||||||
|
}
|
||||||
|
if account.State != nil && account.StateDiff != nil {
|
||||||
|
return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
|
||||||
|
}
|
||||||
|
// Replace entire state if caller requires.
|
||||||
|
if account.State != nil {
|
||||||
|
statedb.SetStorage(addr, account.State)
|
||||||
|
}
|
||||||
|
// Apply state diff into specified accounts.
|
||||||
|
if account.StateDiff != nil {
|
||||||
|
for key, value := range account.StateDiff {
|
||||||
|
statedb.SetState(addr, key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now finalize the changes. Finalize is normally performed between transactions.
|
||||||
|
// By using finalize, the overrides are semantically behaving as
|
||||||
|
// if they were created in a transaction just before the tracing occur.
|
||||||
|
statedb.Finalise(false)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockOverrides is a set of header fields to override.
|
||||||
|
type BlockOverrides struct {
|
||||||
|
Number *hexutil.Big
|
||||||
|
Difficulty *hexutil.Big // No-op if we're simulating post-merge calls.
|
||||||
|
Time *hexutil.Uint64
|
||||||
|
GasLimit *hexutil.Uint64
|
||||||
|
FeeRecipient *common.Address
|
||||||
|
PrevRandao *common.Hash
|
||||||
|
BaseFeePerGas *hexutil.Big
|
||||||
|
BlobBaseFee *hexutil.Big
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply overrides the given header fields into the given block context.
|
||||||
|
func (o *BlockOverrides) Apply(blockCtx *vm.BlockContext) {
|
||||||
|
if o == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if o.Number != nil {
|
||||||
|
blockCtx.BlockNumber = o.Number.ToInt()
|
||||||
|
}
|
||||||
|
if o.Difficulty != nil {
|
||||||
|
blockCtx.Difficulty = o.Difficulty.ToInt()
|
||||||
|
}
|
||||||
|
if o.Time != nil {
|
||||||
|
blockCtx.Time = uint64(*o.Time)
|
||||||
|
}
|
||||||
|
if o.GasLimit != nil {
|
||||||
|
blockCtx.GasLimit = uint64(*o.GasLimit)
|
||||||
|
}
|
||||||
|
if o.FeeRecipient != nil {
|
||||||
|
blockCtx.Coinbase = *o.FeeRecipient
|
||||||
|
}
|
||||||
|
if o.PrevRandao != nil {
|
||||||
|
blockCtx.Random = o.PrevRandao
|
||||||
|
}
|
||||||
|
if o.BaseFeePerGas != nil {
|
||||||
|
blockCtx.BaseFee = o.BaseFeePerGas.ToInt()
|
||||||
|
}
|
||||||
|
if o.BlobBaseFee != nil {
|
||||||
|
blockCtx.BlobBaseFee = o.BlobBaseFee.ToInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeHeader returns a new header object with the overridden
|
||||||
|
// fields.
|
||||||
|
// Note: MakeHeader ignores BlobBaseFee if set. That's because
|
||||||
|
// header has no such field.
|
||||||
|
func (o *BlockOverrides) MakeHeader(header *types.Header) *types.Header {
|
||||||
|
if o == nil {
|
||||||
|
return header
|
||||||
|
}
|
||||||
|
h := types.CopyHeader(header)
|
||||||
|
if o.Number != nil {
|
||||||
|
h.Number = o.Number.ToInt()
|
||||||
|
}
|
||||||
|
if o.Difficulty != nil {
|
||||||
|
h.Difficulty = o.Difficulty.ToInt()
|
||||||
|
}
|
||||||
|
if o.Time != nil {
|
||||||
|
h.Time = uint64(*o.Time)
|
||||||
|
}
|
||||||
|
if o.GasLimit != nil {
|
||||||
|
h.GasLimit = uint64(*o.GasLimit)
|
||||||
|
}
|
||||||
|
if o.FeeRecipient != nil {
|
||||||
|
h.Coinbase = *o.FeeRecipient
|
||||||
|
}
|
||||||
|
if o.PrevRandao != nil {
|
||||||
|
h.MixDigest = *o.PrevRandao
|
||||||
|
}
|
||||||
|
if o.BaseFeePerGas != nil {
|
||||||
|
h.BaseFee = o.BaseFeePerGas.ToInt()
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
125
internal/ethapi/override/override_test.go
Normal file
125
internal/ethapi/override/override_test.go
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Copyright 2024 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package override
|
||||||
|
|
||||||
|
import (
|
||||||
|
"maps"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
)
|
||||||
|
|
||||||
|
type precompileContract struct{}
|
||||||
|
|
||||||
|
func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 }
|
||||||
|
|
||||||
|
func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil }
|
||||||
|
|
||||||
|
func TestStateOverrideMovePrecompile(t *testing.T) {
|
||||||
|
db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
|
||||||
|
statedb, err := state.New(common.Hash{}, db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create statedb: %v", err)
|
||||||
|
}
|
||||||
|
precompiles := map[common.Address]vm.PrecompiledContract{
|
||||||
|
common.BytesToAddress([]byte{0x1}): &precompileContract{},
|
||||||
|
common.BytesToAddress([]byte{0x2}): &precompileContract{},
|
||||||
|
}
|
||||||
|
bytes2Addr := func(b []byte) *common.Address {
|
||||||
|
a := common.BytesToAddress(b)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
var testSuite = []struct {
|
||||||
|
overrides StateOverride
|
||||||
|
expectedPrecompiles map[common.Address]struct{}
|
||||||
|
fail bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
overrides: StateOverride{
|
||||||
|
common.BytesToAddress([]byte{0x1}): {
|
||||||
|
Code: hex2Bytes("0xff"),
|
||||||
|
MovePrecompileTo: bytes2Addr([]byte{0x2}),
|
||||||
|
},
|
||||||
|
common.BytesToAddress([]byte{0x2}): {
|
||||||
|
Code: hex2Bytes("0x00"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 0x2 has already been touched by the moveTo.
|
||||||
|
fail: true,
|
||||||
|
}, {
|
||||||
|
overrides: StateOverride{
|
||||||
|
common.BytesToAddress([]byte{0x1}): {
|
||||||
|
Code: hex2Bytes("0xff"),
|
||||||
|
MovePrecompileTo: bytes2Addr([]byte{0xff}),
|
||||||
|
},
|
||||||
|
common.BytesToAddress([]byte{0x3}): {
|
||||||
|
Code: hex2Bytes("0x00"),
|
||||||
|
MovePrecompileTo: bytes2Addr([]byte{0xfe}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 0x3 is not a precompile.
|
||||||
|
fail: true,
|
||||||
|
}, {
|
||||||
|
overrides: StateOverride{
|
||||||
|
common.BytesToAddress([]byte{0x1}): {
|
||||||
|
Code: hex2Bytes("0xff"),
|
||||||
|
MovePrecompileTo: bytes2Addr([]byte{0xff}),
|
||||||
|
},
|
||||||
|
common.BytesToAddress([]byte{0x2}): {
|
||||||
|
Code: hex2Bytes("0x00"),
|
||||||
|
MovePrecompileTo: bytes2Addr([]byte{0xfe}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPrecompiles: map[common.Address]struct{}{common.BytesToAddress([]byte{0xfe}): {}, common.BytesToAddress([]byte{0xff}): {}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range testSuite {
|
||||||
|
cpy := maps.Clone(precompiles)
|
||||||
|
// Apply overrides
|
||||||
|
err := tt.overrides.Apply(statedb, cpy)
|
||||||
|
if tt.fail {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("test %d: want error, have nothing", i)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("test %d: want no error, have %v", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Precompile keys
|
||||||
|
if len(cpy) != len(tt.expectedPrecompiles) {
|
||||||
|
t.Errorf("test %d: precompile mismatch, want %d, have %d", i, len(tt.expectedPrecompiles), len(cpy))
|
||||||
|
}
|
||||||
|
for k := range tt.expectedPrecompiles {
|
||||||
|
if _, ok := cpy[k]; !ok {
|
||||||
|
t.Errorf("test %d: precompile not found: %s", i, k.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hex2Bytes(str string) *hexutil.Bytes {
|
||||||
|
rpcBytes := hexutil.Bytes(common.FromHex(str))
|
||||||
|
return &rpcBytes
|
||||||
|
}
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
|
@ -50,8 +51,8 @@ const (
|
||||||
|
|
||||||
// simBlock is a batch of calls to be simulated sequentially.
|
// simBlock is a batch of calls to be simulated sequentially.
|
||||||
type simBlock struct {
|
type simBlock struct {
|
||||||
BlockOverrides *BlockOverrides
|
BlockOverrides *override.BlockOverrides
|
||||||
StateOverrides *StateOverride
|
StateOverrides *override.StateOverride
|
||||||
Calls []TransactionArgs
|
Calls []TransactionArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,7 +306,7 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) {
|
||||||
)
|
)
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
if block.BlockOverrides == nil {
|
if block.BlockOverrides == nil {
|
||||||
block.BlockOverrides = new(BlockOverrides)
|
block.BlockOverrides = new(override.BlockOverrides)
|
||||||
}
|
}
|
||||||
if block.BlockOverrides.Number == nil {
|
if block.BlockOverrides.Number == nil {
|
||||||
n := new(big.Int).Add(prevNumber, big.NewInt(1))
|
n := new(big.Int).Add(prevNumber, big.NewInt(1))
|
||||||
|
|
@ -325,7 +326,7 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) {
|
||||||
for i := uint64(0); i < gap.Uint64(); i++ {
|
for i := uint64(0); i < gap.Uint64(); i++ {
|
||||||
n := new(big.Int).Add(prevNumber, big.NewInt(int64(i+1)))
|
n := new(big.Int).Add(prevNumber, big.NewInt(int64(i+1)))
|
||||||
t := prevTimestamp + timestampIncrement
|
t := prevTimestamp + timestampIncrement
|
||||||
b := simBlock{BlockOverrides: &BlockOverrides{Number: (*hexutil.Big)(n), Time: (*hexutil.Uint64)(&t)}}
|
b := simBlock{BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(n), Time: (*hexutil.Uint64)(&t)}}
|
||||||
prevTimestamp = t
|
prevTimestamp = t
|
||||||
res = append(res, b)
|
res = append(res, b)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
|
|
||||||
"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/internal/ethapi/override"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSimulateSanitizeBlockOrder(t *testing.T) {
|
func TestSimulateSanitizeBlockOrder(t *testing.T) {
|
||||||
|
|
@ -45,37 +46,37 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) {
|
||||||
{
|
{
|
||||||
baseNumber: 10,
|
baseNumber: 10,
|
||||||
baseTimestamp: 50,
|
baseTimestamp: 50,
|
||||||
blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(70)}}, {}},
|
blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(70)}}, {}},
|
||||||
expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 70}, {number: 14, timestamp: 71}},
|
expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 70}, {number: 14, timestamp: 71}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
baseNumber: 10,
|
baseNumber: 10,
|
||||||
baseTimestamp: 50,
|
baseTimestamp: 50,
|
||||||
blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(11)}}, {BlockOverrides: &BlockOverrides{Number: newInt(14)}}, {}},
|
blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(14)}}, {}},
|
||||||
expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}, {number: 14, timestamp: 54}, {number: 15, timestamp: 55}},
|
expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}, {number: 14, timestamp: 54}, {number: 15, timestamp: 55}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
baseNumber: 10,
|
baseNumber: 10,
|
||||||
baseTimestamp: 50,
|
baseTimestamp: 50,
|
||||||
blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13)}}, {BlockOverrides: &BlockOverrides{Number: newInt(12)}}},
|
blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(12)}}},
|
||||||
err: "block numbers must be in order: 12 <= 13",
|
err: "block numbers must be in order: 12 <= 13",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
baseNumber: 10,
|
baseNumber: 10,
|
||||||
baseTimestamp: 50,
|
baseTimestamp: 50,
|
||||||
blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(52)}}},
|
blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(52)}}},
|
||||||
err: "block timestamps must be in order: 52 <= 52",
|
err: "block timestamps must be in order: 52 <= 52",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
baseNumber: 10,
|
baseNumber: 10,
|
||||||
baseTimestamp: 50,
|
baseTimestamp: 50,
|
||||||
blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &BlockOverrides{Number: newInt(12), Time: newUint64(55)}}},
|
blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(12), Time: newUint64(55)}}},
|
||||||
err: "block timestamps must be in order: 55 <= 60",
|
err: "block timestamps must be in order: 55 <= 60",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
baseNumber: 10,
|
baseNumber: 10,
|
||||||
baseTimestamp: 50,
|
baseTimestamp: 50,
|
||||||
blocks: []simBlock{{BlockOverrides: &BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &BlockOverrides{Number: newInt(13), Time: newUint64(61)}}},
|
blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(61)}}},
|
||||||
err: "block timestamps must be in order: 61 <= 61",
|
err: "block timestamps must be in order: 61 <= 61",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue