Skip to content

Commit 4c098dd

Browse files
authored
core/vm: fold EVMInterpreter into EVM ethereum#32352 (#1838)
1 parent 10ac141 commit 4c098dd

File tree

8 files changed

+324
-351
lines changed

8 files changed

+324
-351
lines changed

core/vm/eips.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ func enable1884(jt *JumpTable) {
7070
}
7171
}
7272

73-
func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
74-
balance, _ := uint256.FromBig(interpreter.evm.StateDB.GetBalance(scope.Contract.Address()))
73+
func opSelfBalance(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
74+
balance, _ := uint256.FromBig(evm.StateDB.GetBalance(scope.Contract.Address()))
7575
scope.Stack.push(balance)
7676
return nil, nil
7777
}
@@ -89,8 +89,8 @@ func enable1344(jt *JumpTable) {
8989
}
9090

9191
// opChainID implements CHAINID opcode
92-
func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
93-
chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID)
92+
func opChainID(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
93+
chainId, _ := uint256.FromBig(evm.chainConfig.ChainID)
9494
scope.Stack.push(chainId)
9595
return nil, nil
9696
}
@@ -180,27 +180,27 @@ func enable1153(jt *JumpTable) {
180180
}
181181

182182
// opTload implements TLOAD opcode
183-
func opTload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
183+
func opTload(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
184184
loc := scope.Stack.peek()
185185
hash := common.Hash(loc.Bytes32())
186-
val := interpreter.evm.StateDB.GetTransientState(scope.Contract.Address(), hash)
186+
val := evm.StateDB.GetTransientState(scope.Contract.Address(), hash)
187187
loc.SetBytes(val.Bytes())
188188
return nil, nil
189189
}
190190

191191
// opTstore implements TSTORE opcode
192-
func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
193-
if interpreter.readOnly {
192+
func opTstore(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
193+
if evm.readOnly {
194194
return nil, ErrWriteProtection
195195
}
196196
loc := scope.Stack.pop()
197197
val := scope.Stack.pop()
198-
interpreter.evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32())
198+
evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32())
199199
return nil, nil
200200
}
201201

202202
// opBaseFee implements BASEFEE opcode
203-
func opBaseFee(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
203+
func opBaseFee(pc *uint64, evm *EVM, callContext *ScopeContext) ([]byte, error) {
204204
baseFee, _ := uint256.FromBig(common.BaseFee)
205205
callContext.Stack.push(baseFee)
206206
return nil, nil
@@ -218,7 +218,7 @@ func enable3855(jt *JumpTable) {
218218
}
219219

220220
// opPush0 implements the PUSH0 opcode
221-
func opPush0(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) {
221+
func opPush0(pc *uint64, evm *EVM, callContext *ScopeContext) ([]byte, error) {
222222
callContext.Stack.push(new(uint256.Int))
223223
return nil, nil
224224
}
@@ -244,7 +244,7 @@ func enable5656(jt *JumpTable) {
244244
}
245245

246246
// opMcopy implements the MCOPY opcode (https://eips.ethereum.org/EIPS/eip-5656)
247-
func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
247+
func opMcopy(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
248248
var (
249249
dst = scope.Stack.pop()
250250
src = scope.Stack.pop()
@@ -257,7 +257,7 @@ func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
257257
}
258258

259259
// opBlobHash implements the BLOBHASH opcode
260-
func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
260+
func opBlobHash(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
261261
index := scope.Stack.peek()
262262
// xdc chain have no blob hash, so len(interpreter.evm.TxContext.BlobHashes) is always 0
263263
// and index.LtUint64(uint64(len(interpreter.evm.TxContext.BlobHashes))) is always false
@@ -272,7 +272,7 @@ func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
272272
}
273273

274274
// opBlobBaseFee implements BLOBBASEFEE opcode
275-
func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
275+
func opBlobBaseFee(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
276276
blobBaseFee := new(uint256.Int)
277277
scope.Stack.push(blobBaseFee)
278278
return nil, nil

core/vm/evm.go

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/XinFinOrg/XDPoSChain/core/tracing"
2727
"github.com/XinFinOrg/XDPoSChain/core/types"
2828
"github.com/XinFinOrg/XDPoSChain/crypto"
29+
"github.com/XinFinOrg/XDPoSChain/log"
2930
"github.com/XinFinOrg/XDPoSChain/params"
3031
"github.com/holiman/uint256"
3132
)
@@ -92,6 +93,9 @@ type EVM struct {
9293

9394
tradingStateDB *tradingstate.TradingStateDB
9495

96+
// table holds the opcode specific handlers
97+
table *JumpTable
98+
9599
// Depth is the current call stack
96100
depth int
97101

@@ -102,17 +106,23 @@ type EVM struct {
102106
// virtual machine configuration options used to initialise the
103107
// evm.
104108
Config Config
105-
// global (to this context) ethereum virtual machine
106-
// used throughout the execution of the tx.
107-
interpreter *EVMInterpreter
109+
108110
// abort is used to abort the EVM calling operations
109111
abort atomic.Bool
112+
110113
// callGasTemp holds the gas available for the current call. This is needed because the
111114
// available gas is calculated in gasCall* according to the 63/64 rule and later
112115
// applied in opCall*.
113116
callGasTemp uint64
117+
114118
// precompiles holds the precompiled contracts for the current epoch
115119
precompiles map[common.Address]PrecompiledContract
120+
121+
hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes
122+
hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes
123+
124+
readOnly bool // Whether to throw on stateful modifications
125+
returnData []byte // Last CALL's return data for subsequent reuse
116126
}
117127

118128
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
@@ -126,9 +136,56 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, tradingStat
126136
Config: config,
127137
chainConfig: chainConfig,
128138
chainRules: chainConfig.Rules(blockCtx.BlockNumber),
139+
hasher: crypto.NewKeccakState(),
129140
}
130141
evm.precompiles = activePrecompiledContracts(evm.chainRules)
131-
evm.interpreter = NewEVMInterpreter(evm)
142+
143+
switch {
144+
// TODO(daniel): define pragueInstructionSet
145+
// case evm.chainRules.IsPrague:
146+
// evm.table = &pragueInstructionSet
147+
case evm.chainRules.IsCancun:
148+
evm.table = &cancunInstructionSet
149+
case evm.chainRules.IsEIP1559:
150+
evm.table = &eip1559InstructionSet
151+
case evm.chainRules.IsShanghai:
152+
evm.table = &shanghaiInstructionSet
153+
case evm.chainRules.IsMerge:
154+
evm.table = &mergeInstructionSet
155+
case evm.chainRules.IsLondon:
156+
evm.table = &londonInstructionSet
157+
case evm.chainRules.IsBerlin:
158+
evm.table = &berlinInstructionSet
159+
case evm.chainRules.IsIstanbul:
160+
evm.table = &istanbulInstructionSet
161+
case evm.chainRules.IsConstantinople:
162+
evm.table = &constantinopleInstructionSet
163+
case evm.chainRules.IsByzantium:
164+
evm.table = &byzantiumInstructionSet
165+
case evm.chainRules.IsEIP158:
166+
evm.table = &spuriousDragonInstructionSet
167+
case evm.chainRules.IsEIP150:
168+
evm.table = &tangerineWhistleInstructionSet
169+
case evm.chainRules.IsHomestead:
170+
evm.table = &homesteadInstructionSet
171+
default:
172+
evm.table = &frontierInstructionSet
173+
}
174+
if len(evm.Config.ExtraEips) > 0 {
175+
// Deep-copy jumptable to prevent modification of opcodes in other tables
176+
evm.table = copyJumpTable(evm.table)
177+
}
178+
extraEips := make([]int, 0, len(evm.Config.ExtraEips))
179+
for _, eip := range evm.Config.ExtraEips {
180+
if err := EnableEIP(eip, evm.table); err != nil {
181+
// Disable it, so caller can check if it's activated or not
182+
log.Error("EIP activation failed", "eip", eip, "error", err)
183+
} else {
184+
extraEips = append(extraEips, eip)
185+
}
186+
}
187+
evm.Config.ExtraEips = extraEips[0:len(extraEips):len(extraEips)]
188+
132189
return evm
133190
}
134191

@@ -157,11 +214,6 @@ func (evm *EVM) Cancelled() bool {
157214
return evm.abort.Load()
158215
}
159216

160-
// Interpreter returns the current interpreter
161-
func (evm *EVM) Interpreter() *EVMInterpreter {
162-
return evm.interpreter
163-
}
164-
165217
// Call executes the contract associated with the addr with the given input as
166218
// parameters. It also handles any necessary value transfer required and takes
167219
// the necessary steps to create accounts and reverses the state in case of an
@@ -208,7 +260,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
208260
// The depth-check is already done, and precompiles handled above
209261
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
210262
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
211-
ret, err = evm.interpreter.Run(contract, input, false)
263+
ret, err = evm.Run(contract, input, false)
212264
gas = contract.Gas
213265
}
214266
}
@@ -268,7 +320,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
268320
// The contract is a scoped environment for this execution context only.
269321
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
270322
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
271-
ret, err = evm.interpreter.Run(contract, input, false)
323+
ret, err = evm.Run(contract, input, false)
272324
gas = contract.Gas
273325
}
274326
if err != nil {
@@ -315,7 +367,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
315367
// Initialise a new contract and make initialise the delegate values
316368
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
317369
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
318-
ret, err = evm.interpreter.Run(contract, input, false)
370+
ret, err = evm.Run(contract, input, false)
319371
gas = contract.Gas
320372
}
321373
if err != nil {
@@ -376,7 +428,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
376428
// above we revert to the snapshot and consume any gas remaining. Additionally
377429
// when we're in Homestead this also counts for code storage gas errors.
378430
readOnly := evm.ChainConfig().IsTIPXDCXCancellationFee(evm.Context.BlockNumber)
379-
ret, err = evm.interpreter.Run(contract, input, readOnly)
431+
ret, err = evm.Run(contract, input, readOnly)
380432
gas = contract.Gas
381433
}
382434
if err != nil {
@@ -458,7 +510,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
458510
contract := NewContract(caller, AccountRef(address), value, gas)
459511
contract.SetCodeOptionalHash(&address, codeAndHash)
460512

461-
ret, err = evm.interpreter.Run(contract, nil, false)
513+
ret, err = evm.Run(contract, nil, false)
462514

463515
// Check whether the max code size has been exceeded, assign err if the case.
464516
if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {

0 commit comments

Comments
 (0)