From 3e8a028cbb8e7224eb12cc04973f2ddc17da0d52 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Wed, 29 Nov 2023 09:29:16 +0700 Subject: [PATCH] evm: remove interpreter interface - step3 (#8842) --- cmd/state/commands/opcode_tracer.go | 2 +- core/state_processor.go | 2 +- core/state_transition.go | 24 +++++++++--------- core/vm/eips.go | 8 +++--- core/vm/evm.go | 32 +++++++++--------------- core/vm/instructions.go | 38 ++++++++++++++--------------- core/vm/runtime/runtime.go | 6 ++--- eth/tracers/js/goja.go | 6 ++--- eth/tracers/native/4byte.go | 2 +- eth/tracers/native/prestate.go | 4 +-- 10 files changed, 57 insertions(+), 67 deletions(-) diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go index a92f55251..c9cebb45e 100644 --- a/cmd/state/commands/opcode_tracer.go +++ b/cmd/state/commands/opcode_tracer.go @@ -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) diff --git a/core/state_processor.go b/core/state_processor.go index be097186f..c5b81a497 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -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()) diff --git a/core/state_transition.go b/core/state_transition.go index 39c4e8c39..3972dc21e 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -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) } } diff --git a/core/vm/eips.go b/core/vm/eips.go index 393d8554e..8d48f1a7b 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -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 diff --git a/core/vm/evm.go b/core/vm/evm.go index e48a1b80f..dc5dce586 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -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 diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 4caa9a691..7871e9fd8 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -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 diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 8dd670644..df2bb97b7 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -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. diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index 86c9dc0f6..466bdfdf5 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -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) } diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 608f4990b..c61617171 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -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 diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 02cb6337d..133ca8bcc 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -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