evm: remove interpreter interface - step3 (#8842)

This commit is contained in:
Alex Sharov 2023-11-29 09:29:16 +07:00 committed by GitHub
parent a63b89334b
commit 3e8a028cbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 57 additions and 67 deletions

View File

@ -256,7 +256,7 @@ func (ot *opcodeTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,
}
pc16 := uint16(pc)
currentTxHash := ot.env.TxContext().TxHash
currentTxHash := ot.env.TxHash
currentTxDepth := opDepth - 1
ls := len(ot.stack)

View File

@ -86,7 +86,7 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G
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(evm.TxContext().Origin, tx.GetNonce())
receipt.ContractAddress = crypto.CreateAddress(evm.Origin, tx.GetNonce())
}
// Set the receipt logs and create a bloom for filtering
receipt.Logs = ibs.GetLogs(tx.Hash())

View File

@ -203,10 +203,10 @@ func (st *StateTransition) buyGas(gasBailout bool) error {
// compute blob fee for eip-4844 data blobs if any
blobGasVal := new(uint256.Int)
if st.evm.ChainRules().IsCancun {
if st.evm.Context().ExcessBlobGas == nil {
if st.evm.Context.ExcessBlobGas == nil {
return fmt.Errorf("%w: Cancun is active but ExcessBlobGas is nil", ErrInternalFailure)
}
blobGasPrice, err := misc.GetBlobGasPrice(st.evm.ChainConfig(), *st.evm.Context().ExcessBlobGas)
blobGasPrice, err := misc.GetBlobGasPrice(st.evm.ChainConfig(), *st.evm.Context.ExcessBlobGas)
if err != nil {
return err
}
@ -300,16 +300,16 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
if st.evm.ChainRules().IsLondon {
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
if !st.evm.Config().NoBaseFee || !st.gasFeeCap.IsZero() || !st.tip.IsZero() {
if err := CheckEip1559TxGasFeeCap(st.msg.From(), st.gasFeeCap, st.tip, st.evm.Context().BaseFee, st.msg.IsFree()); err != nil {
if err := CheckEip1559TxGasFeeCap(st.msg.From(), st.gasFeeCap, st.tip, st.evm.Context.BaseFee, st.msg.IsFree()); err != nil {
return err
}
}
}
if st.msg.BlobGas() > 0 && st.evm.ChainRules().IsCancun {
if st.evm.Context().ExcessBlobGas == nil {
if st.evm.Context.ExcessBlobGas == nil {
return fmt.Errorf("%w: Cancun is active but ExcessBlobGas is nil", ErrInternalFailure)
}
blobGasPrice, err := misc.GetBlobGasPrice(st.evm.ChainConfig(), *st.evm.Context().ExcessBlobGas)
blobGasPrice, err := misc.GetBlobGasPrice(st.evm.ChainConfig(), *st.evm.Context.ExcessBlobGas)
if err != nil {
return err
}
@ -317,7 +317,7 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
if blobGasPrice.Cmp(maxFeePerBlobGas) > 0 {
return fmt.Errorf("%w: address %v, maxFeePerBlobGas: %v blobGasPrice: %v, excessBlobGas: %v",
ErrMaxFeePerBlobGas,
st.msg.From().Hex(), st.msg.MaxFeePerBlobGas(), blobGasPrice, st.evm.Context().ExcessBlobGas)
st.msg.From().Hex(), st.msg.MaxFeePerBlobGas(), blobGasPrice, st.evm.Context.ExcessBlobGas)
}
}
@ -338,7 +338,7 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
// However if any consensus issue encountered, return the error directly with
// nil evm execution result.
func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*ExecutionResult, error) {
coinbase := st.evm.Context().Coinbase
coinbase := st.evm.Context.Coinbase
var input1 *uint256.Int
var input2 *uint256.Int
@ -388,7 +388,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
var bailout bool
// Gas bailout (for trace_call) should only be applied if there is not sufficient balance to perform value transfer
if gasBailout {
if !msg.Value().IsZero() && !st.evm.Context().CanTransfer(st.state, msg.From(), msg.Value()) {
if !msg.Value().IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
bailout = true
}
}
@ -429,8 +429,8 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
}
effectiveTip := st.gasPrice
if rules.IsLondon {
if st.gasFeeCap.Gt(st.evm.Context().BaseFee) {
effectiveTip = cmath.Min256(st.tip, new(uint256.Int).Sub(st.gasFeeCap, st.evm.Context().BaseFee))
if st.gasFeeCap.Gt(st.evm.Context.BaseFee) {
effectiveTip = cmath.Min256(st.tip, new(uint256.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
} else {
effectiveTip = u256.Num0
}
@ -439,9 +439,9 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
amount.Mul(amount, effectiveTip) // gasUsed * effectiveTip = how much goes to the block producer (miner, validator)
st.state.AddBalance(coinbase, amount)
if !msg.IsFree() && rules.IsLondon {
burntContractAddress := st.evm.ChainConfig().GetBurntContract(st.evm.Context().BlockNumber)
burntContractAddress := st.evm.ChainConfig().GetBurntContract(st.evm.Context.BlockNumber)
if burntContractAddress != nil {
burnAmount := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), st.evm.Context().BaseFee)
burnAmount := new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee)
st.state.AddBalance(*burntContractAddress, burnAmount)
}
}

View File

@ -217,7 +217,7 @@ func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
// opBaseFee implements BASEFEE opcode
func opBaseFee(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
baseFee := interpreter.evm.Context().BaseFee
baseFee := interpreter.evm.Context.BaseFee
callContext.Stack.Push(baseFee)
return nil, nil
}
@ -260,8 +260,8 @@ func enable4844(jt *JumpTable) {
// opBlobHash implements the BLOBHASH opcode
func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
idx := scope.Stack.Peek()
if idx.LtUint64(uint64(len(interpreter.evm.TxContext().BlobHashes))) {
hash := interpreter.evm.TxContext().BlobHashes[idx.Uint64()]
if idx.LtUint64(uint64(len(interpreter.evm.BlobHashes))) {
hash := interpreter.evm.BlobHashes[idx.Uint64()]
idx.SetBytes(hash.Bytes())
} else {
idx.Clear()
@ -308,7 +308,7 @@ func enable6780(jt *JumpTable) {
// opBlobBaseFee implements the BLOBBASEFEE opcode
func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
excessBlobGas := interpreter.evm.Context().ExcessBlobGas
excessBlobGas := interpreter.evm.Context.ExcessBlobGas
blobBaseFee, err := misc.GetBlobGasPrice(interpreter.evm.ChainConfig(), *excessBlobGas)
if err != nil {
return nil, err

View File

@ -68,8 +68,8 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
// The EVM should never be reused and is not thread safe.
type EVM struct {
// Context provides auxiliary blockchain related information
context evmtypes.BlockContext
txContext evmtypes.TxContext
Context evmtypes.BlockContext
evmtypes.TxContext
// IntraBlockState gives access to the underlying state
intraBlockState evmtypes.IntraBlockState
@ -96,8 +96,8 @@ type EVM struct {
// only ever be used *once*.
func NewEVM(blockCtx evmtypes.BlockContext, txCtx evmtypes.TxContext, state evmtypes.IntraBlockState, chainConfig *chain.Config, vmConfig Config) *EVM {
evm := &EVM{
context: blockCtx,
txContext: txCtx,
Context: blockCtx,
TxContext: txCtx,
intraBlockState: state,
config: vmConfig,
chainConfig: chainConfig,
@ -112,7 +112,7 @@ func NewEVM(blockCtx evmtypes.BlockContext, txCtx evmtypes.TxContext, state evmt
// 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 evmtypes.TxContext, ibs evmtypes.IntraBlockState) {
evm.txContext = txCtx
evm.TxContext = txCtx
evm.intraBlockState = ibs
// ensure the evm is reset to be used again
@ -120,8 +120,8 @@ func (evm *EVM) Reset(txCtx evmtypes.TxContext, ibs evmtypes.IntraBlockState) {
}
func (evm *EVM) ResetBetweenBlocks(blockCtx evmtypes.BlockContext, txCtx evmtypes.TxContext, ibs evmtypes.IntraBlockState, vmConfig Config, chainRules *chain.Rules) {
evm.context = blockCtx
evm.txContext = txCtx
evm.Context = blockCtx
evm.TxContext = txCtx
evm.intraBlockState = ibs
evm.config = vmConfig
evm.chainRules = chainRules
@ -170,7 +170,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp
}
if typ == CALL || typ == CALLCODE {
// Fail if we're trying to transfer more than the available balance
if !value.IsZero() && !evm.context.CanTransfer(evm.intraBlockState, caller.Address(), value) {
if !value.IsZero() && !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) {
if !bailout {
return nil, gas, ErrInsufficientBalance
}
@ -205,7 +205,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp
}
evm.intraBlockState.CreateAccount(addr, false)
}
evm.context.Transfer(evm.intraBlockState, caller.Address(), addr, value, bailout)
evm.Context.Transfer(evm.intraBlockState, caller.Address(), addr, value, bailout)
} else if typ == STATICCALL {
// We do an AddBalance of zero here, just in order to trigger a touch.
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
@ -352,7 +352,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
err = ErrDepth
return nil, libcommon.Address{}, gas, err
}
if !evm.context.CanTransfer(evm.intraBlockState, caller.Address(), value) {
if !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) {
err = ErrInsufficientBalance
return nil, libcommon.Address{}, gas, err
}
@ -381,7 +381,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if evm.chainRules.IsSpuriousDragon {
evm.intraBlockState.SetNonce(address, 1)
}
evm.context.Transfer(evm.intraBlockState, caller.Address(), address, value, false /* bailout */)
evm.Context.Transfer(evm.intraBlockState, caller.Address(), address, value, false /* bailout */)
// 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.
@ -476,16 +476,6 @@ func (evm *EVM) ChainRules() *chain.Rules {
return evm.chainRules
}
// Context returns the EVM's BlockContext
func (evm *EVM) Context() evmtypes.BlockContext {
return evm.context
}
// TxContext returns the EVM's TxContext
func (evm *EVM) TxContext() evmtypes.TxContext {
return evm.txContext
}
// IntraBlockState returns the EVM's IntraBlockState
func (evm *EVM) IntraBlockState() evmtypes.IntraBlockState {
return evm.intraBlockState

View File

@ -294,7 +294,7 @@ func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
}
func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
scope.Stack.Push(new(uint256.Int).SetBytes(interpreter.evm.TxContext().Origin.Bytes()))
scope.Stack.Push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
return nil, nil
}
func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
@ -459,7 +459,7 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
}
func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
scope.Stack.Push(interpreter.evm.TxContext().GasPrice)
scope.Stack.Push(interpreter.evm.GasPrice)
return nil, nil
}
@ -471,14 +471,14 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
return nil, nil
}
var upper, lower uint64
upper = interpreter.evm.Context().BlockNumber
upper = interpreter.evm.Context.BlockNumber
if upper < 257 {
lower = 0
} else {
lower = upper - 256
}
if num64 >= lower && num64 < upper {
num.SetBytes(interpreter.evm.Context().GetHash(num64).Bytes())
num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes())
} else {
num.Clear()
}
@ -486,30 +486,30 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
}
func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
scope.Stack.Push(new(uint256.Int).SetBytes(interpreter.evm.Context().Coinbase.Bytes()))
scope.Stack.Push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
return nil, nil
}
func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
v := new(uint256.Int).SetUint64(interpreter.evm.Context().Time)
v := new(uint256.Int).SetUint64(interpreter.evm.Context.Time)
scope.Stack.Push(v)
return nil, nil
}
func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
v := new(uint256.Int).SetUint64(interpreter.evm.Context().BlockNumber)
v := new(uint256.Int).SetUint64(interpreter.evm.Context.BlockNumber)
scope.Stack.Push(v)
return nil, nil
}
func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
var v *uint256.Int
if interpreter.evm.Context().PrevRanDao != nil {
if interpreter.evm.Context.PrevRanDao != nil {
// EIP-4399: Supplant DIFFICULTY opcode with PREVRANDAO
v = new(uint256.Int).SetBytes(interpreter.evm.Context().PrevRanDao.Bytes())
v = new(uint256.Int).SetBytes(interpreter.evm.Context.PrevRanDao.Bytes())
} else {
var overflow bool
v, overflow = uint256.FromBig(interpreter.evm.Context().Difficulty)
v, overflow = uint256.FromBig(interpreter.evm.Context.Difficulty)
if overflow {
return nil, fmt.Errorf("interpreter.evm.Context.Difficulty higher than 2^256-1")
}
@ -519,10 +519,10 @@ func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
}
func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
if interpreter.evm.Context().MaxGasLimit {
if interpreter.evm.Context.MaxGasLimit {
scope.Stack.Push(new(uint256.Int).SetAllOne())
} else {
scope.Stack.Push(new(uint256.Int).SetUint64(interpreter.evm.Context().GasLimit))
scope.Stack.Push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
}
return nil, nil
}
@ -575,13 +575,13 @@ func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
if usedBitmap {
if interpreter.cfg.TraceJumpDest {
log.Warn("Code Bitmap used for detecting invalid jump",
"tx", fmt.Sprintf("0x%x", interpreter.evm.TxContext().TxHash),
"block_num", interpreter.evm.Context().BlockNumber,
"tx", fmt.Sprintf("0x%x", interpreter.evm.TxHash),
"block_num", interpreter.evm.Context.BlockNumber,
)
} else {
// This is "cheaper" version because it does not require calculation of txHash for each transaction
log.Warn("Code Bitmap used for detecting invalid jump",
"block_num", interpreter.evm.Context().BlockNumber,
"block_num", interpreter.evm.Context.BlockNumber,
)
}
}
@ -598,13 +598,13 @@ func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
if usedBitmap {
if interpreter.cfg.TraceJumpDest {
log.Warn("Code Bitmap used for detecting invalid jump",
"tx", fmt.Sprintf("0x%x", interpreter.evm.TxContext().TxHash),
"block_num", interpreter.evm.Context().BlockNumber,
"tx", fmt.Sprintf("0x%x", interpreter.evm.TxHash),
"block_num", interpreter.evm.Context.BlockNumber,
)
} else {
// This is "cheaper" version because it does not require calculation of txHash for each transaction
log.Warn("Code Bitmap used for detecting invalid jump",
"block_num", interpreter.evm.Context().BlockNumber,
"block_num", interpreter.evm.Context.BlockNumber,
)
}
}
@ -928,7 +928,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.Context().BlockNumber,
BlockNumber: interpreter.evm.Context.BlockNumber,
})
return nil, nil

View File

@ -132,7 +132,7 @@ func Execute(code, input []byte, cfg *Config, bn uint64) ([]byte, *state.IntraBl
address = libcommon.BytesToAddress([]byte("contract"))
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
rules = cfg.ChainConfig.Rules(vmenv.Context().BlockNumber, vmenv.Context().Time)
rules = vmenv.ChainRules()
)
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil)
cfg.State.CreateAccount(address, true)
@ -176,7 +176,7 @@ func Create(input []byte, cfg *Config, blockNr uint64) ([]byte, libcommon.Addres
var (
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
rules = cfg.ChainConfig.Rules(vmenv.Context().BlockNumber, vmenv.Context().Time)
rules = vmenv.ChainRules()
)
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, nil, vm.ActivePrecompiles(rules), nil)
@ -202,7 +202,7 @@ func Call(address libcommon.Address, input []byte, cfg *Config) ([]byte, uint64,
sender := cfg.State.GetOrNewStateObject(cfg.Origin)
statedb := cfg.State
rules := cfg.ChainConfig.Rules(vmenv.Context().BlockNumber, vmenv.Context().Time)
rules := vmenv.ChainRules()
statedb.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil)
// Call the code with the given configuration.

View File

@ -237,16 +237,16 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommo
t.ctx["to"] = t.vm.ToValue(to.Bytes())
t.ctx["input"] = t.vm.ToValue(input)
t.ctx["gas"] = t.vm.ToValue(gas)
t.ctx["gasPrice"] = t.vm.ToValue(env.TxContext().GasPrice.ToBig())
t.ctx["gasPrice"] = t.vm.ToValue(env.GasPrice.ToBig())
valueBig, err := t.toBig(t.vm, value.ToBig().String())
if err != nil {
t.err = err
return
}
t.ctx["value"] = valueBig
t.ctx["block"] = t.vm.ToValue(env.Context().BlockNumber)
t.ctx["block"] = t.vm.ToValue(env.Context.BlockNumber)
// Update list of precompiles based on current block
rules := env.ChainConfig().Rules(env.Context().BlockNumber, env.Context().Time)
rules := env.ChainRules()
t.activePrecompiles = vm.ActivePrecompiles(rules)
}

View File

@ -83,7 +83,7 @@ func (t *fourByteTracer) store(id []byte, size int) {
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
func (t *fourByteTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) {
// Update list of precompiles based on current block
rules := env.ChainConfig().Rules(env.Context().BlockNumber, env.Context().Time)
rules := env.ChainRules()
t.activePrecompiles = vm.ActivePrecompiles(rules)
// Save the outer calldata also

View File

@ -100,7 +100,7 @@ func (t *prestateTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to li
t.lookupAccount(from)
t.lookupAccount(to)
t.lookupAccount(env.Context().Coinbase)
t.lookupAccount(env.Context.Coinbase)
// The recipient balance includes the value transferred.
toBal := new(big.Int).Sub(t.pre[to].Balance, value.ToBig())
@ -109,7 +109,7 @@ func (t *prestateTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to li
// The sender balance is after reducing: value and gasLimit.
// We need to re-add them to get the pre-tx balance.
fromBal := new(big.Int).Set(t.pre[from].Balance)
gasPrice := env.TxContext().GasPrice
gasPrice := env.GasPrice
consumedGas := new(big.Int).Mul(gasPrice.ToBig(), new(big.Int).SetUint64(t.gasLimit))
fromBal.Add(fromBal, new(big.Int).Add(value.ToBig(), consumedGas))
t.pre[from].Balance = fromBal