@@ -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