core, all: split vm.Context into BlockContext and TxContext (#21672)
* all: core: split vm.Config into BlockConfig and TxConfig * core: core/vm: reset EVM between tx in block instead of creating new * core/vm: added docs
This commit is contained in:
parent
6f4cccf8d2
commit
2045a2bba3
|
@ -542,10 +542,11 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
|||
// Execute the call.
|
||||
msg := callMsg{call}
|
||||
|
||||
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil)
|
||||
// Create a new environment which holds all relevant information
|
||||
// about the transaction and calling mechanisms.
|
||||
vmEnv := vm.NewEVM(evmContext, stateDB, b.config, vm.Config{})
|
||||
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{})
|
||||
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
|
||||
return core.NewStateTransition(vmEnv, msg, gasPool).TransitionDb()
|
||||
|
|
|
@ -110,7 +110,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
txIndex = 0
|
||||
)
|
||||
gaspool.AddGas(pre.Env.GasLimit)
|
||||
vmContext := vm.Context{
|
||||
vmContext := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
Transfer: core.Transfer,
|
||||
Coinbase: pre.Env.Coinbase,
|
||||
|
@ -119,7 +119,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
Difficulty: pre.Env.Difficulty,
|
||||
GasLimit: pre.Env.GasLimit,
|
||||
GetHash: getHash,
|
||||
// GasPrice and Origin needs to be set per transaction
|
||||
}
|
||||
// If DAO is supported/enabled, we need to handle it here. In geth 'proper', it's
|
||||
// done in StateProcessor.Process(block, ...), right before transactions are applied.
|
||||
|
@ -143,10 +142,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
vmConfig.Tracer = tracer
|
||||
vmConfig.Debug = (tracer != nil)
|
||||
statedb.Prepare(tx.Hash(), blockHash, txIndex)
|
||||
vmContext.GasPrice = msg.GasPrice()
|
||||
vmContext.Origin = msg.From()
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
|
||||
evm := vm.NewEVM(vmContext, statedb, chainConfig, vmConfig)
|
||||
evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig)
|
||||
if chainConfig.IsYoloV2(vmContext.BlockNumber) {
|
||||
statedb.AddAddressToAccessList(msg.From())
|
||||
if dst := msg.To(); dst != nil {
|
||||
|
@ -185,7 +183,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
receipt.GasUsed = msgResult.UsedGas
|
||||
// if the transaction created a contract, store the creation address in the receipt.
|
||||
if msg.To() == nil {
|
||||
receipt.ContractAddress = crypto.CreateAddress(evm.Context.Origin, tx.Nonce())
|
||||
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
|
||||
}
|
||||
// Set the receipt logs and create a bloom for filtering
|
||||
receipt.Logs = statedb.GetLogs(tx.Hash())
|
||||
|
|
|
@ -671,12 +671,13 @@ func (api *RetestethAPI) AccountRange(ctx context.Context,
|
|||
}
|
||||
// Recompute transactions up to the target index.
|
||||
signer := types.MakeSigner(api.blockchain.Config(), block.Number())
|
||||
context := core.NewEVMBlockContext(block.Header(), api.blockchain, nil)
|
||||
for idx, tx := range block.Transactions() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := tx.AsMessage(signer)
|
||||
context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
// Not yet the searched for transaction, execute on top of the current state
|
||||
vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{})
|
||||
vmenv := vm.NewEVM(context, txContext, statedb, api.blockchain.Config(), vm.Config{})
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||
return AccountRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
}
|
||||
|
@ -781,12 +782,13 @@ func (api *RetestethAPI) StorageRangeAt(ctx context.Context,
|
|||
}
|
||||
// Recompute transactions up to the target index.
|
||||
signer := types.MakeSigner(api.blockchain.Config(), block.Number())
|
||||
context := core.NewEVMBlockContext(block.Header(), api.blockchain, nil)
|
||||
for idx, tx := range block.Transactions() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := tx.AsMessage(signer)
|
||||
context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
// Not yet the searched for transaction, execute on top of the current state
|
||||
vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{})
|
||||
vmenv := vm.NewEVM(context, txContext, statedb, api.blockchain.Config(), vm.Config{})
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||
return StorageRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
}
|
||||
|
|
16
core/evm.go
16
core/evm.go
|
@ -35,8 +35,8 @@ type ChainContext interface {
|
|||
GetHeader(common.Hash, uint64) *types.Header
|
||||
}
|
||||
|
||||
// NewEVMContext creates a new context for use in the EVM.
|
||||
func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context {
|
||||
// NewEVMBlockContext creates a new context for use in the EVM.
|
||||
func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext {
|
||||
// If we don't have an explicit author (i.e. not mining), extract from the header
|
||||
var beneficiary common.Address
|
||||
if author == nil {
|
||||
|
@ -44,17 +44,23 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author
|
|||
} else {
|
||||
beneficiary = *author
|
||||
}
|
||||
return vm.Context{
|
||||
return vm.BlockContext{
|
||||
CanTransfer: CanTransfer,
|
||||
Transfer: Transfer,
|
||||
GetHash: GetHashFn(header, chain),
|
||||
Origin: msg.From(),
|
||||
Coinbase: beneficiary,
|
||||
BlockNumber: new(big.Int).Set(header.Number),
|
||||
Time: new(big.Int).SetUint64(header.Time),
|
||||
Difficulty: new(big.Int).Set(header.Difficulty),
|
||||
GasLimit: header.GasLimit,
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice()),
|
||||
}
|
||||
}
|
||||
|
||||
// NewEVMTxContext creates a new transaction context for a single transaction.
|
||||
func NewEVMTxContext(msg Message) vm.TxContext {
|
||||
return vm.TxContext{
|
||||
Origin: msg.From(),
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,9 @@ func precacheTransaction(config *params.ChainConfig, bc ChainContext, author *co
|
|||
return err
|
||||
}
|
||||
// Create the EVM and execute the transaction
|
||||
context := NewEVMContext(msg, header, bc, author)
|
||||
vm := vm.NewEVM(context, statedb, config, cfg)
|
||||
context := NewEVMBlockContext(header, bc, author)
|
||||
txContext := NewEVMTxContext(msg)
|
||||
vm := vm.NewEVM(context, txContext, statedb, config, cfg)
|
||||
|
||||
_, err = ApplyMessage(vm, msg, gaspool)
|
||||
return err
|
||||
|
|
|
@ -65,10 +65,16 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
blockContext := NewEVMBlockContext(header, p.bc, nil)
|
||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
||||
// Iterate over and process the individual transactions
|
||||
for i, tx := range block.Transactions() {
|
||||
msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number))
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
||||
receipt, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
|
||||
receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, header, tx, usedGas, vmenv)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
@ -81,34 +87,25 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
return receipts, allLogs, *usedGas, nil
|
||||
}
|
||||
|
||||
// ApplyTransaction attempts to apply a transaction to the given state database
|
||||
// and uses the input parameters for its environment. It returns the receipt
|
||||
// for the transaction, gas used and an error if the transaction failed,
|
||||
// indicating the block was invalid.
|
||||
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
||||
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
|
||||
// Create a new context to be used in the EVM environment
|
||||
context := NewEVMContext(msg, header, bc, author)
|
||||
// Create a new environment which holds all relevant information
|
||||
// about the transaction and calling mechanisms.
|
||||
vmenv := vm.NewEVM(context, statedb, config, cfg)
|
||||
|
||||
txContext := NewEVMTxContext(msg)
|
||||
// Add addresses to access list if applicable
|
||||
if config.IsYoloV2(header.Number) {
|
||||
statedb.AddAddressToAccessList(msg.From())
|
||||
if dst := msg.To(); dst != nil {
|
||||
statedb.AddAddressToAccessList(*dst)
|
||||
// If it's a create-tx, the destination will be added inside evm.create
|
||||
}
|
||||
for _, addr := range vmenv.ActivePrecompiles() {
|
||||
for _, addr := range evm.ActivePrecompiles() {
|
||||
statedb.AddAddressToAccessList(addr)
|
||||
}
|
||||
}
|
||||
|
||||
// Update the evm with the new transaction context.
|
||||
evm.Reset(txContext, statedb)
|
||||
// Apply the transaction to the current state (included in the env)
|
||||
result, err := ApplyMessage(vmenv, msg, gp)
|
||||
result, err := ApplyMessage(evm, msg, gp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -128,7 +125,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
receipt.GasUsed = result.UsedGas
|
||||
// if the transaction created a contract, store the creation address in the receipt.
|
||||
if msg.To() == nil {
|
||||
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
|
||||
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
|
||||
}
|
||||
// Set the receipt logs and create a bloom for filtering
|
||||
receipt.Logs = statedb.GetLogs(tx.Hash())
|
||||
|
@ -139,3 +136,18 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
|
||||
return receipt, err
|
||||
}
|
||||
|
||||
// ApplyTransaction attempts to apply a transaction to the given state database
|
||||
// and uses the input parameters for its environment. It returns the receipt
|
||||
// for the transaction, gas used and an error if the transaction failed,
|
||||
// indicating the block was invalid.
|
||||
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
||||
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create a new context to be used in the EVM environment
|
||||
blockContext := NewEVMBlockContext(header, bc, author)
|
||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
|
||||
return applyTransaction(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv)
|
||||
}
|
||||
|
|
|
@ -230,8 +230,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
}
|
||||
msg := st.msg
|
||||
sender := vm.AccountRef(msg.From())
|
||||
homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
|
||||
istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.BlockNumber)
|
||||
homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
|
||||
istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.Context.BlockNumber)
|
||||
contractCreation := msg.To() == nil
|
||||
|
||||
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
||||
|
@ -245,7 +245,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
st.gas -= gas
|
||||
|
||||
// Check clause 6
|
||||
if msg.Value().Sign() > 0 && !st.evm.CanTransfer(st.state, msg.From(), msg.Value()) {
|
||||
if msg.Value().Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
|
||||
return nil, ErrInsufficientFundsForTransfer
|
||||
}
|
||||
var (
|
||||
|
@ -260,7 +260,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
|
||||
}
|
||||
st.refundGas()
|
||||
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
|
||||
st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
|
||||
|
||||
return &ExecutionResult{
|
||||
UsedGas: st.gasUsed(),
|
||||
|
|
|
@ -91,9 +91,9 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
|
|||
return nil, errors.New("no compatible interpreter")
|
||||
}
|
||||
|
||||
// Context provides the EVM with auxiliary information. Once provided
|
||||
// BlockContext provides the EVM with auxiliary information. Once provided
|
||||
// it shouldn't be modified.
|
||||
type Context struct {
|
||||
type BlockContext struct {
|
||||
// CanTransfer returns whether the account contains
|
||||
// sufficient ether to transfer the value
|
||||
CanTransfer CanTransferFunc
|
||||
|
@ -102,10 +102,6 @@ type Context struct {
|
|||
// GetHash returns the hash corresponding to n
|
||||
GetHash GetHashFunc
|
||||
|
||||
// Message information
|
||||
Origin common.Address // Provides information for ORIGIN
|
||||
GasPrice *big.Int // Provides information for GASPRICE
|
||||
|
||||
// Block information
|
||||
Coinbase common.Address // Provides information for COINBASE
|
||||
GasLimit uint64 // Provides information for GASLIMIT
|
||||
|
@ -114,6 +110,14 @@ type Context struct {
|
|||
Difficulty *big.Int // Provides information for DIFFICULTY
|
||||
}
|
||||
|
||||
// TxContext provides the EVM with information about a transaction.
|
||||
// All fields can change between transactions.
|
||||
type TxContext struct {
|
||||
// Message information
|
||||
Origin common.Address // Provides information for ORIGIN
|
||||
GasPrice *big.Int // Provides information for GASPRICE
|
||||
}
|
||||
|
||||
// EVM is the Ethereum Virtual Machine base object and provides
|
||||
// the necessary tools to run a contract on the given state with
|
||||
// the provided context. It should be noted that any error
|
||||
|
@ -125,7 +129,8 @@ type Context struct {
|
|||
// The EVM should never be reused and is not thread safe.
|
||||
type EVM struct {
|
||||
// Context provides auxiliary blockchain related information
|
||||
Context
|
||||
Context BlockContext
|
||||
TxContext
|
||||
// StateDB gives access to the underlying state
|
||||
StateDB StateDB
|
||||
// Depth is the current call stack
|
||||
|
@ -153,17 +158,18 @@ type EVM struct {
|
|||
|
||||
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
||||
// only ever be used *once*.
|
||||
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
|
||||
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
|
||||
evm := &EVM{
|
||||
Context: ctx,
|
||||
Context: blockCtx,
|
||||
TxContext: txCtx,
|
||||
StateDB: statedb,
|
||||
vmConfig: vmConfig,
|
||||
chainConfig: chainConfig,
|
||||
chainRules: chainConfig.Rules(ctx.BlockNumber),
|
||||
chainRules: chainConfig.Rules(blockCtx.BlockNumber),
|
||||
interpreters: make([]Interpreter, 0, 1),
|
||||
}
|
||||
|
||||
if chainConfig.IsEWASM(ctx.BlockNumber) {
|
||||
if chainConfig.IsEWASM(blockCtx.BlockNumber) {
|
||||
// to be implemented by EVM-C and Wagon PRs.
|
||||
// if vmConfig.EWASMInterpreter != "" {
|
||||
// extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":")
|
||||
|
@ -187,6 +193,13 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
|
|||
return evm
|
||||
}
|
||||
|
||||
// Reset resets the EVM with a new transaction context.Reset
|
||||
// This is not threadsafe and should only be done very cautiously.
|
||||
func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) {
|
||||
evm.TxContext = txCtx
|
||||
evm.StateDB = statedb
|
||||
}
|
||||
|
||||
// Cancel cancels any running EVM operation. This may be called concurrently and
|
||||
// it's safe to be called multiple times.
|
||||
func (evm *EVM) Cancel() {
|
||||
|
@ -233,7 +246,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
}
|
||||
evm.StateDB.CreateAccount(addr)
|
||||
}
|
||||
evm.Transfer(evm.StateDB, caller.Address(), addr, value)
|
||||
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
|
||||
|
||||
// Capture the tracer start/end events in debug mode
|
||||
if evm.vmConfig.Debug && evm.depth == 0 {
|
||||
|
@ -426,7 +439,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, common.Address{}, gas, ErrDepth
|
||||
}
|
||||
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||
return nil, common.Address{}, gas, ErrInsufficientBalance
|
||||
}
|
||||
nonce := evm.StateDB.GetNonce(caller.Address())
|
||||
|
@ -447,7 +460,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
if evm.chainRules.IsEIP158 {
|
||||
evm.StateDB.SetNonce(address, 1)
|
||||
}
|
||||
evm.Transfer(evm.StateDB, caller.Address(), address, value)
|
||||
evm.Context.Transfer(evm.StateDB, caller.Address(), address, value)
|
||||
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
|
|
|
@ -87,11 +87,11 @@ func TestEIP2200(t *testing.T) {
|
|||
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
||||
statedb.Finalise(true) // Push the state into the "original" slot
|
||||
|
||||
vmctx := Context{
|
||||
vmctx := BlockContext{
|
||||
CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true },
|
||||
Transfer: func(StateDB, common.Address, common.Address, *big.Int) {},
|
||||
}
|
||||
vmenv := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
|
||||
vmenv := NewEVM(vmctx, TxContext{}, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
|
||||
|
||||
_, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(big.Int))
|
||||
if err != tt.failure {
|
||||
|
|
|
@ -438,14 +438,14 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx)
|
|||
return nil, nil
|
||||
}
|
||||
var upper, lower uint64
|
||||
upper = interpreter.evm.BlockNumber.Uint64()
|
||||
upper = interpreter.evm.Context.BlockNumber.Uint64()
|
||||
if upper < 257 {
|
||||
lower = 0
|
||||
} else {
|
||||
lower = upper - 256
|
||||
}
|
||||
if num64 >= lower && num64 < upper {
|
||||
num.SetBytes(interpreter.evm.GetHash(num64).Bytes())
|
||||
num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes())
|
||||
} else {
|
||||
num.Clear()
|
||||
}
|
||||
|
@ -453,30 +453,30 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx)
|
|||
}
|
||||
|
||||
func opCoinbase(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Coinbase.Bytes()))
|
||||
callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opTimestamp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.Time)
|
||||
v, _ := uint256.FromBig(interpreter.evm.Context.Time)
|
||||
callContext.stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opNumber(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.BlockNumber)
|
||||
v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber)
|
||||
callContext.stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opDifficulty(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.Difficulty)
|
||||
v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty)
|
||||
callContext.stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(interpreter.evm.GasLimit))
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -842,7 +842,7 @@ func makeLog(size int) executionFunc {
|
|||
Data: d,
|
||||
// This is a non-consensus field, but assigned here because
|
||||
// core/state doesn't know the current block number.
|
||||
BlockNumber: interpreter.evm.BlockNumber.Uint64(),
|
||||
BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(),
|
||||
})
|
||||
|
||||
return nil, nil
|
||||
|
|
|
@ -92,7 +92,7 @@ func init() {
|
|||
func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
|
||||
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack = newstack()
|
||||
rstack = newReturnStack()
|
||||
pc = uint64(0)
|
||||
|
@ -192,7 +192,7 @@ func TestSAR(t *testing.T) {
|
|||
|
||||
func TestAddMod(t *testing.T) {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack = newstack()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
pc = uint64(0)
|
||||
|
@ -231,7 +231,7 @@ func TestAddMod(t *testing.T) {
|
|||
// getResult is a convenience function to generate the expected values
|
||||
func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack, rstack = newstack(), newReturnStack()
|
||||
pc = uint64(0)
|
||||
interpreter = env.interpreter.(*EVMInterpreter)
|
||||
|
@ -281,7 +281,7 @@ func TestJsonTestcases(t *testing.T) {
|
|||
|
||||
func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack, rstack = newstack(), newReturnStack()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
)
|
||||
|
@ -515,7 +515,7 @@ func BenchmarkOpIsZero(b *testing.B) {
|
|||
|
||||
func TestOpMstore(t *testing.T) {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack, rstack = newstack(), newReturnStack()
|
||||
mem = NewMemory()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
|
@ -539,7 +539,7 @@ func TestOpMstore(t *testing.T) {
|
|||
|
||||
func BenchmarkOpMstore(bench *testing.B) {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack, rstack = newstack(), newReturnStack()
|
||||
mem = NewMemory()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
|
@ -560,7 +560,7 @@ func BenchmarkOpMstore(bench *testing.B) {
|
|||
|
||||
func BenchmarkOpSHA3(bench *testing.B) {
|
||||
var (
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack, rstack = newstack(), newReturnStack()
|
||||
mem = NewMemory()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
|
|
|
@ -51,7 +51,7 @@ func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
|||
|
||||
func TestStoreCapture(t *testing.T) {
|
||||
var (
|
||||
env = NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{})
|
||||
env = NewEVM(BlockContext{}, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{})
|
||||
logger = NewStructLogger(nil)
|
||||
mem = NewMemory()
|
||||
stack = newstack()
|
||||
|
|
|
@ -22,18 +22,20 @@ import (
|
|||
)
|
||||
|
||||
func NewEnv(cfg *Config) *vm.EVM {
|
||||
context := vm.Context{
|
||||
txContext := vm.TxContext{
|
||||
Origin: cfg.Origin,
|
||||
GasPrice: cfg.GasPrice,
|
||||
}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
Transfer: core.Transfer,
|
||||
GetHash: cfg.GetHashFn,
|
||||
Origin: cfg.Origin,
|
||||
Coinbase: cfg.Coinbase,
|
||||
BlockNumber: cfg.BlockNumber,
|
||||
Time: cfg.Time,
|
||||
Difficulty: cfg.Difficulty,
|
||||
GasLimit: cfg.GasLimit,
|
||||
GasPrice: cfg.GasPrice,
|
||||
}
|
||||
|
||||
return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
|
||||
return vm.NewEVM(blockContext, txContext, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
vmenv = NewEnv(cfg)
|
||||
sender = vm.AccountRef(cfg.Origin)
|
||||
)
|
||||
if cfg.ChainConfig.IsYoloV2(vmenv.BlockNumber) {
|
||||
if cfg.ChainConfig.IsYoloV2(vmenv.Context.BlockNumber) {
|
||||
cfg.State.AddAddressToAccessList(cfg.Origin)
|
||||
cfg.State.AddAddressToAccessList(address)
|
||||
for _, addr := range vmenv.ActivePrecompiles() {
|
||||
|
@ -150,7 +150,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
vmenv = NewEnv(cfg)
|
||||
sender = vm.AccountRef(cfg.Origin)
|
||||
)
|
||||
if cfg.ChainConfig.IsYoloV2(vmenv.BlockNumber) {
|
||||
if cfg.ChainConfig.IsYoloV2(vmenv.Context.BlockNumber) {
|
||||
cfg.State.AddAddressToAccessList(cfg.Origin)
|
||||
for _, addr := range vmenv.ActivePrecompiles() {
|
||||
cfg.State.AddAddressToAccessList(addr)
|
||||
|
@ -178,7 +178,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
|
|||
vmenv := NewEnv(cfg)
|
||||
|
||||
sender := cfg.State.GetOrNewStateObject(cfg.Origin)
|
||||
if cfg.ChainConfig.IsYoloV2(vmenv.BlockNumber) {
|
||||
if cfg.ChainConfig.IsYoloV2(vmenv.Context.BlockNumber) {
|
||||
cfg.State.AddAddressToAccessList(cfg.Origin)
|
||||
cfg.State.AddAddressToAccessList(address)
|
||||
for _, addr := range vmenv.ActivePrecompiles() {
|
||||
|
|
|
@ -194,8 +194,9 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
||||
vmError := func() error { return nil }
|
||||
|
||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
|
||||
return vm.NewEVM(context, state, b.eth.blockchain.Config(), *b.eth.blockchain.GetVMConfig()), vmError, nil
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
|
||||
return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *b.eth.blockchain.GetVMConfig()), vmError, nil
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
||||
|
|
|
@ -203,13 +203,11 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
|
|||
// Fetch and execute the next block trace tasks
|
||||
for task := range tasks {
|
||||
signer := types.MakeSigner(api.eth.blockchain.Config(), task.block.Number())
|
||||
|
||||
blockCtx := core.NewEVMBlockContext(task.block.Header(), api.eth.blockchain, nil)
|
||||
// Trace all the transactions contained within
|
||||
for i, tx := range task.block.Transactions() {
|
||||
msg, _ := tx.AsMessage(signer)
|
||||
vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain, nil)
|
||||
|
||||
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
|
||||
res, err := api.traceTx(ctx, msg, blockCtx, task.statedb, config)
|
||||
if err != nil {
|
||||
task.results[i] = &txTraceResult{Error: err.Error()}
|
||||
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
|
||||
|
@ -473,17 +471,15 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
|||
if threads > len(txs) {
|
||||
threads = len(txs)
|
||||
}
|
||||
blockCtx := core.NewEVMBlockContext(block.Header(), api.eth.blockchain, nil)
|
||||
for th := 0; th < threads; th++ {
|
||||
pend.Add(1)
|
||||
go func() {
|
||||
defer pend.Done()
|
||||
|
||||
// Fetch and execute the next transaction trace tasks
|
||||
for task := range jobs {
|
||||
msg, _ := txs[task.index].AsMessage(signer)
|
||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||
|
||||
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
|
||||
res, err := api.traceTx(ctx, msg, blockCtx, task.statedb, config)
|
||||
if err != nil {
|
||||
results[task.index] = &txTraceResult{Error: err.Error()}
|
||||
continue
|
||||
|
@ -500,9 +496,9 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
|||
|
||||
// Generate the next state snapshot fast without tracing
|
||||
msg, _ := tx.AsMessage(signer)
|
||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
|
||||
vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vm.Config{})
|
||||
vmenv := vm.NewEVM(blockCtx, txContext, statedb, api.eth.blockchain.Config(), vm.Config{})
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
||||
failed = err
|
||||
break
|
||||
|
@ -565,6 +561,7 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
|
|||
signer = types.MakeSigner(api.eth.blockchain.Config(), block.Number())
|
||||
dumps []string
|
||||
chainConfig = api.eth.blockchain.Config()
|
||||
vmctx = core.NewEVMBlockContext(block.Header(), api.eth.blockchain, nil)
|
||||
canon = true
|
||||
)
|
||||
// Check if there are any overrides: the caller may wish to enable a future
|
||||
|
@ -587,13 +584,12 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
|
|||
for i, tx := range block.Transactions() {
|
||||
// Prepare the trasaction for un-traced execution
|
||||
var (
|
||||
msg, _ = tx.AsMessage(signer)
|
||||
vmctx = core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||
|
||||
vmConf vm.Config
|
||||
dump *os.File
|
||||
writer *bufio.Writer
|
||||
err error
|
||||
msg, _ = tx.AsMessage(signer)
|
||||
txContext = core.NewEVMTxContext(msg)
|
||||
vmConf vm.Config
|
||||
dump *os.File
|
||||
writer *bufio.Writer
|
||||
err error
|
||||
)
|
||||
// If the transaction needs tracing, swap out the configs
|
||||
if tx.Hash() == txHash || txHash == (common.Hash{}) {
|
||||
|
@ -617,7 +613,7 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
|
|||
}
|
||||
}
|
||||
// Execute the transaction and flush any traces to disk
|
||||
vmenv := vm.NewEVM(vmctx, statedb, chainConfig, vmConf)
|
||||
vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf)
|
||||
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
|
||||
if writer != nil {
|
||||
writer.Flush()
|
||||
|
@ -776,18 +772,19 @@ func (api *PrivateDebugAPI) TraceCall(ctx context.Context, args ethapi.CallArgs,
|
|||
|
||||
// Execute the trace
|
||||
msg := args.ToMessage(api.eth.APIBackend.RPCGasCap())
|
||||
vmctx := core.NewEVMContext(msg, header, api.eth.blockchain, nil)
|
||||
vmctx := core.NewEVMBlockContext(header, api.eth.blockchain, nil)
|
||||
return api.traceTx(ctx, msg, vmctx, statedb, config)
|
||||
}
|
||||
|
||||
// traceTx configures a new tracer according to the provided configuration, and
|
||||
// executes the given message in the provided environment. The return value will
|
||||
// be tracer dependent.
|
||||
func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx vm.Context, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
|
||||
func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
|
||||
// Assemble the structured logger or the JavaScript tracer
|
||||
var (
|
||||
tracer vm.Tracer
|
||||
err error
|
||||
tracer vm.Tracer
|
||||
err error
|
||||
txContext = core.NewEVMTxContext(message)
|
||||
)
|
||||
switch {
|
||||
case config != nil && config.Tracer != nil:
|
||||
|
@ -817,7 +814,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
|||
tracer = vm.NewStructLogger(config.LogConfig)
|
||||
}
|
||||
// Run the transaction with tracing enabled.
|
||||
vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vm.Config{Debug: true, Tracer: tracer})
|
||||
vmenv := vm.NewEVM(vmctx, txContext, statedb, api.eth.blockchain.Config(), vm.Config{Debug: true, Tracer: tracer})
|
||||
|
||||
result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
|
||||
if err != nil {
|
||||
|
@ -847,19 +844,19 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
|||
}
|
||||
|
||||
// computeTxEnv returns the execution environment of a certain transaction.
|
||||
func (api *PrivateDebugAPI) computeTxEnv(block *types.Block, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, error) {
|
||||
func (api *PrivateDebugAPI) computeTxEnv(block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
|
||||
// Create the parent state database
|
||||
parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||
if parent == nil {
|
||||
return nil, vm.Context{}, nil, fmt.Errorf("parent %#x not found", block.ParentHash())
|
||||
return nil, vm.BlockContext{}, nil, fmt.Errorf("parent %#x not found", block.ParentHash())
|
||||
}
|
||||
statedb, err := api.computeStateDB(parent, reexec)
|
||||
if err != nil {
|
||||
return nil, vm.Context{}, nil, err
|
||||
return nil, vm.BlockContext{}, nil, err
|
||||
}
|
||||
|
||||
if txIndex == 0 && len(block.Transactions()) == 0 {
|
||||
return nil, vm.Context{}, statedb, nil
|
||||
return nil, vm.BlockContext{}, statedb, nil
|
||||
}
|
||||
|
||||
// Recompute transactions up to the target index.
|
||||
|
@ -868,18 +865,19 @@ func (api *PrivateDebugAPI) computeTxEnv(block *types.Block, txIndex int, reexec
|
|||
for idx, tx := range block.Transactions() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := tx.AsMessage(signer)
|
||||
context := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), api.eth.blockchain, nil)
|
||||
if idx == txIndex {
|
||||
return msg, context, statedb, nil
|
||||
}
|
||||
// Not yet the searched for transaction, execute on top of the current state
|
||||
vmenv := vm.NewEVM(context, statedb, api.eth.blockchain.Config(), vm.Config{})
|
||||
vmenv := vm.NewEVM(context, txContext, statedb, api.eth.blockchain.Config(), vm.Config{})
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||
return nil, vm.Context{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
}
|
||||
// Ensure any modifications are committed to the state
|
||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
|
||||
}
|
||||
return nil, vm.Context{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||
return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||
}
|
||||
|
|
|
@ -545,7 +545,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
|
|||
if jst.err == nil {
|
||||
// Initialize the context if it wasn't done yet
|
||||
if !jst.inited {
|
||||
jst.ctx["block"] = env.BlockNumber.Uint64()
|
||||
jst.ctx["block"] = env.Context.BlockNumber.Uint64()
|
||||
jst.inited = true
|
||||
}
|
||||
// If tracing was interrupted, set the error and stop
|
||||
|
|
|
@ -51,7 +51,7 @@ type dummyStatedb struct {
|
|||
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
||||
|
||||
func runTrace(tracer *Tracer) (json.RawMessage, error) {
|
||||
env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
|
||||
contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000)
|
||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
|
||||
|
@ -166,7 +166,7 @@ func TestHaltBetweenSteps(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0)
|
||||
|
||||
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, nil, nil, contract, 0, nil)
|
||||
|
|
|
@ -143,16 +143,18 @@ func TestPrestateTracerCreate2(t *testing.T) {
|
|||
result: 0x60f3f640a8508fC6a86d45DF051962668E1e8AC7
|
||||
*/
|
||||
origin, _ := signer.Sender(tx)
|
||||
context := vm.Context{
|
||||
txContext := vm.TxContext{
|
||||
Origin: origin,
|
||||
GasPrice: big.NewInt(1),
|
||||
}
|
||||
context := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
Transfer: core.Transfer,
|
||||
Origin: origin,
|
||||
Coinbase: common.Address{},
|
||||
BlockNumber: new(big.Int).SetUint64(8000000),
|
||||
Time: new(big.Int).SetUint64(5),
|
||||
Difficulty: big.NewInt(0x30000),
|
||||
GasLimit: uint64(6000000),
|
||||
GasPrice: big.NewInt(1),
|
||||
}
|
||||
alloc := core.GenesisAlloc{}
|
||||
|
||||
|
@ -175,7 +177,7 @@ func TestPrestateTracerCreate2(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed to create call tracer: %v", err)
|
||||
}
|
||||
evm := vm.NewEVM(context, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
evm := vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
|
||||
msg, err := tx.AsMessage(signer)
|
||||
if err != nil {
|
||||
|
@ -230,17 +232,18 @@ func TestCallTracer(t *testing.T) {
|
|||
}
|
||||
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
|
||||
origin, _ := signer.Sender(tx)
|
||||
|
||||
context := vm.Context{
|
||||
txContext := vm.TxContext{
|
||||
Origin: origin,
|
||||
GasPrice: tx.GasPrice(),
|
||||
}
|
||||
context := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
Transfer: core.Transfer,
|
||||
Origin: origin,
|
||||
Coinbase: test.Context.Miner,
|
||||
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
|
||||
Time: new(big.Int).SetUint64(uint64(test.Context.Time)),
|
||||
Difficulty: (*big.Int)(test.Context.Difficulty),
|
||||
GasLimit: uint64(test.Context.GasLimit),
|
||||
GasPrice: tx.GasPrice(),
|
||||
}
|
||||
_, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false)
|
||||
|
||||
|
@ -249,7 +252,7 @@ func TestCallTracer(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed to create call tracer: %v", err)
|
||||
}
|
||||
evm := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
||||
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
||||
|
||||
msg, err := tx.AsMessage(signer)
|
||||
if err != nil {
|
||||
|
|
|
@ -171,8 +171,9 @@ func (b *LesApiBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
}
|
||||
|
||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
||||
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
|
||||
return vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{}), state.Error, nil
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(header, b.eth.blockchain, nil)
|
||||
return vm.NewEVM(context, txContext, state, b.eth.chainConfig, vm.Config{}), state.Error, nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||
|
|
|
@ -130,8 +130,9 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||
|
||||
context := core.NewEVMContext(msg, header, bc, nil)
|
||||
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||
context := core.NewEVMBlockContext(header, bc, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
vmenv := vm.NewEVM(context, txContext, statedb, config, vm.Config{})
|
||||
|
||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
|
@ -143,8 +144,9 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
state := light.NewState(ctx, header, lc.Odr())
|
||||
state.SetBalance(bankAddr, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||
context := core.NewEVMContext(msg, header, lc, nil)
|
||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
||||
context := core.NewEVMBlockContext(header, lc, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
result, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
if state.Error() == nil {
|
||||
|
|
|
@ -195,8 +195,9 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
// Perform read-only call.
|
||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
|
||||
context := core.NewEVMContext(msg, header, chain, nil)
|
||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(header, chain, nil)
|
||||
vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
result, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
res = append(res, result.Return()...)
|
||||
|
|
|
@ -182,9 +182,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||
if err != nil {
|
||||
return nil, nil, common.Hash{}, err
|
||||
}
|
||||
context := core.NewEVMContext(msg, block.Header(), nil, &t.json.Env.Coinbase)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
|
||||
context.GetHash = vmTestBlockHash
|
||||
evm := vm.NewEVM(context, statedb, config, vmconfig)
|
||||
evm := vm.NewEVM(context, txContext, statedb, config, vmconfig)
|
||||
|
||||
if config.IsYoloV2(context.BlockNumber) {
|
||||
statedb.AddAddressToAccessList(msg.From())
|
||||
|
|
|
@ -138,20 +138,22 @@ func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM {
|
|||
return core.CanTransfer(db, address, amount)
|
||||
}
|
||||
transfer := func(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {}
|
||||
context := vm.Context{
|
||||
txContext := vm.TxContext{
|
||||
Origin: t.json.Exec.Origin,
|
||||
GasPrice: t.json.Exec.GasPrice,
|
||||
}
|
||||
context := vm.BlockContext{
|
||||
CanTransfer: canTransfer,
|
||||
Transfer: transfer,
|
||||
GetHash: vmTestBlockHash,
|
||||
Origin: t.json.Exec.Origin,
|
||||
Coinbase: t.json.Env.Coinbase,
|
||||
BlockNumber: new(big.Int).SetUint64(t.json.Env.Number),
|
||||
Time: new(big.Int).SetUint64(t.json.Env.Timestamp),
|
||||
GasLimit: t.json.Env.GasLimit,
|
||||
Difficulty: t.json.Env.Difficulty,
|
||||
GasPrice: t.json.Exec.GasPrice,
|
||||
}
|
||||
vmconfig.NoRecursion = true
|
||||
return vm.NewEVM(context, statedb, params.MainnetChainConfig, vmconfig)
|
||||
return vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vmconfig)
|
||||
}
|
||||
|
||||
func vmTestBlockHash(n uint64) common.Hash {
|
||||
|
|
Loading…
Reference in New Issue