Skip to content

Commit 44db394

Browse files
ziogaschrmeowsbits
authored andcommitted
Revert "all: remove noop vm config flags (ethereum#23111)"
This reverts commit 5441a8f. # Conflicts: # cmd/utils/flags.go # core/vm/evm.go # eth/ethconfig/gen_config.go # eth/tracers/tracer_test.go # params/config.go
1 parent b1f699f commit 44db394

File tree

16 files changed

+151
-28
lines changed

16 files changed

+151
-28
lines changed

cmd/evm/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ var (
129129
Name: "noreturndata",
130130
Usage: "disable return data output",
131131
}
132+
EVMInterpreterFlag = cli.StringFlag{
133+
Name: "vm.evm",
134+
Usage: "External EVM configuration (default = built-in interpreter)",
135+
Value: "",
136+
}
132137
)
133138

134139
var stateTransitionCommand = cli.Command{
@@ -180,6 +185,7 @@ func init() {
180185
DisableStackFlag,
181186
DisableStorageFlag,
182187
DisableReturnDataFlag,
188+
EVMInterpreterFlag,
183189
}
184190
app.Commands = []cli.Command{
185191
compileCommand,

cmd/evm/runner.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ func runCmd(ctx *cli.Context) error {
213213
Coinbase: genesisConfig.Coinbase,
214214
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
215215
EVMConfig: vm.Config{
216-
Tracer: tracer,
217-
Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name),
216+
Tracer: tracer,
217+
Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name),
218+
EVMInterpreter: ctx.GlobalString(EVMInterpreterFlag.Name),
218219
},
219220
}
220221

cmd/geth/config.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,5 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
250250
}
251251

252252
func deprecated(field string) bool {
253-
switch field {
254-
case "ethconfig.Config.EVMInterpreter":
255-
return true
256-
case "ethconfig.Config.EWASMInterpreter":
257-
return true
258-
default:
259-
return false
260-
}
253+
return false
261254
}

cmd/geth/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ var (
157157
utils.GpoPercentileFlag,
158158
utils.GpoMaxGasPriceFlag,
159159
utils.GpoIgnoreGasPriceFlag,
160+
utils.EWASMInterpreterFlag,
161+
utils.EVMInterpreterFlag,
160162
utils.MinerNotifyFullFlag,
161163
utils.ECBP1100Flag,
162164
utils.ECBP1100NoDisableFlag,

cmd/geth/usage.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ var AppHelpFlagGroups = []flags.FlagGroup{
211211
Name: "VIRTUAL MACHINE",
212212
Flags: []cli.Flag{
213213
utils.VMEnableDebugFlag,
214+
utils.EVMInterpreterFlag,
215+
utils.EWASMInterpreterFlag,
214216
},
215217
},
216218
{

cmd/utils/flags.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,16 @@ var (
805805
Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements",
806806
Value: metrics.DefaultConfig.InfluxDBTags,
807807
}
808+
EWASMInterpreterFlag = cli.StringFlag{
809+
Name: "vm.ewasm",
810+
Usage: "External ewasm configuration (default = built-in interpreter)",
811+
Value: "",
812+
}
813+
EVMInterpreterFlag = cli.StringFlag{
814+
Name: "vm.evm",
815+
Usage: "External EVM configuration (default = built-in interpreter)",
816+
Value: "",
817+
}
808818
ECBP1100Flag = cli.Uint64Flag{
809819
Name: "ecbp1100",
810820
Usage: "Configure ECBP-1100 (MESS) block activation number",
@@ -814,6 +824,7 @@ var (
814824
Name: "ecbp1100.nodisable",
815825
Usage: "Short-circuit ECBP-1100 (MESS) disable mechanisms; (yields a permanent-once-activated state, deactivating auto-shutoff mechanisms)",
816826
}
827+
817828
CatalystFlag = cli.BoolFlag{
818829
Name: "catalyst",
819830
Usage: "Catalyst mode (eth2 integration testing)",
@@ -1705,6 +1716,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17051716
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
17061717
}
17071718

1719+
if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) {
1720+
cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name)
1721+
}
1722+
1723+
if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
1724+
cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
1725+
}
17081726
if ctx.GlobalIsSet(RPCGlobalGasCapFlag.Name) {
17091727
cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCapFlag.Name)
17101728
}

consensus/misc/eip1559_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func copyConfig(original *goethereum.ChainConfig) *goethereum.ChainConfig {
4646
MuirGlacierBlock: original.MuirGlacierBlock,
4747
BerlinBlock: original.BerlinBlock,
4848
LondonBlock: original.LondonBlock,
49+
EWASMBlock: original.EWASMBlock,
4950
CatalystBlock: original.CatalystBlock,
5051
Ethash: original.Ethash,
5152
Clique: original.Clique,

core/vm/evm.go

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package vm
1818

1919
import (
20+
"errors"
2021
"math/big"
2122
"sync/atomic"
2223
"time"
@@ -59,6 +60,24 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
5960
return p, ok
6061
}
6162

63+
// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
64+
func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
65+
for _, interpreter := range evm.interpreters {
66+
if interpreter.CanRun(contract.Code) {
67+
if evm.interpreter != interpreter {
68+
// Ensure that the interpreter pointer is set back
69+
// to its current value upon return.
70+
defer func(i Interpreter) {
71+
evm.interpreter = i
72+
}(evm.interpreter)
73+
evm.interpreter = interpreter
74+
}
75+
return interpreter.Run(contract, input, readOnly)
76+
}
77+
}
78+
return nil, errors.New("no compatible interpreter")
79+
}
80+
6281
// BlockContext provides the EVM with auxiliary information. Once provided
6382
// it shouldn't be modified.
6483
type BlockContext struct {
@@ -112,7 +131,8 @@ type EVM struct {
112131
Config Config
113132
// global (to this context) ethereum virtual machine
114133
// used throughout the execution of the tx.
115-
interpreter *EVMInterpreter
134+
interpreters []Interpreter
135+
interpreter Interpreter
116136
// abort is used to abort the EVM calling operations
117137
// NOTE: must be set atomically
118138
abort int32
@@ -129,13 +149,35 @@ type EVM struct {
129149
// only ever be used *once*.
130150
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig ctypes.ChainConfigurator, config Config) *EVM {
131151
evm := &EVM{
132-
Context: blockCtx,
133-
TxContext: txCtx,
134-
StateDB: statedb,
135-
Config: config,
136-
chainConfig: chainConfig,
137-
}
138-
evm.interpreter = NewEVMInterpreter(evm, config)
152+
Context: blockCtx,
153+
TxContext: txCtx,
154+
StateDB: statedb,
155+
Config: config,
156+
chainConfig: chainConfig,
157+
interpreters: make([]Interpreter, 0, 1),
158+
}
159+
160+
if chainConfig.IsEWASM(blockCtx.BlockNumber) {
161+
// to be implemented by EVM-C and Wagon PRs.
162+
// if vmConfig.EWASMInterpreter != "" {
163+
// extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":")
164+
// path := extIntOpts[0]
165+
// options := []string{}
166+
// if len(extIntOpts) > 1 {
167+
// options = extIntOpts[1..]
168+
// }
169+
// evm.interpreters = append(evm.interpreters, NewEVMVCInterpreter(evm, vmConfig, options))
170+
// } else {
171+
// evm.interpreters = append(evm.interpreters, NewEWASMInterpreter(evm, vmConfig))
172+
// }
173+
panic("No supported ewasm interpreter yet.")
174+
}
175+
176+
// vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
177+
// as we always want to have the built-in EVM as the failover option.
178+
evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, config))
179+
evm.interpreter = evm.interpreters[0]
180+
139181
return evm
140182
}
141183

@@ -158,7 +200,7 @@ func (evm *EVM) Cancelled() bool {
158200
}
159201

160202
// Interpreter returns the current interpreter
161-
func (evm *EVM) Interpreter() *EVMInterpreter {
203+
func (evm *EVM) Interpreter() Interpreter {
162204
return evm.interpreter
163205
}
164206

@@ -216,7 +258,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
216258
// The depth-check is already done, and precompiles handled above
217259
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
218260
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
219-
ret, err = evm.interpreter.Run(contract, input, false)
261+
ret, err = run(evm, contract, input, false)
220262
gas = contract.Gas
221263
}
222264
}
@@ -268,7 +310,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
268310
// The contract is a scoped environment for this execution context only.
269311
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
270312
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
271-
ret, err = evm.interpreter.Run(contract, input, false)
313+
ret, err = run(evm, contract, input, false)
272314
gas = contract.Gas
273315
}
274316
if err != nil {
@@ -303,7 +345,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
303345
// Initialise a new contract and make initialise the delegate values
304346
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
305347
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
306-
ret, err = evm.interpreter.Run(contract, input, false)
348+
ret, err = run(evm, contract, input, false)
307349
gas = contract.Gas
308350
}
309351
if err != nil {
@@ -354,7 +396,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
354396
// When an error was returned by the EVM or when setting the creation code
355397
// above we revert to the snapshot and consume any gas remaining. Additionally
356398
// when we're in Homestead this also counts for code storage gas errors.
357-
ret, err = evm.interpreter.Run(contract, input, true)
399+
ret, err = run(evm, contract, input, true)
358400
gas = contract.Gas
359401
}
360402
if err != nil {
@@ -424,7 +466,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
424466
}
425467
start := time.Now()
426468

427-
ret, err := evm.interpreter.Run(contract, nil, false)
469+
ret, err := run(evm, contract, nil, false)
428470

429471
// Check whether the max code size has been exceeded, assign err if the case.
430472
if err == nil && evm.ChainConfig().IsEnabled(evm.chainConfig.GetEIP170Transition, evm.Context.BlockNumber) && uint64(len(ret)) > vars.MaxCodeSize {

core/vm/instructions_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
9696
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
9797
stack = newstack()
9898
pc = uint64(0)
99-
evmInterpreter = env.interpreter
99+
evmInterpreter = env.interpreter.(*EVMInterpreter)
100100
)
101101

102102
for i, test := range tests {
@@ -234,7 +234,7 @@ func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcas
234234
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
235235
stack = newstack()
236236
pc = uint64(0)
237-
interpreter = env.interpreter
237+
interpreter = env.interpreter.(*EVMInterpreter)
238238
)
239239
result := make([]TwoOperandTestcase, len(args))
240240
for i, param := range args {

core/vm/interpreter.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,34 @@ type Config struct {
3535

3636
JumpTable [256]*operation // EVM instruction table, automatically populated if unset
3737

38+
EWASMInterpreter string // External EWASM interpreter options
39+
EVMInterpreter string // External EVM interpreter options
40+
3841
ExtraEips []int // Additional EIPS that are to be enabled
3942
}
4043

44+
// Interpreter is used to run Ethereum based contracts and will utilise the
45+
// passed environment to query external sources for state information.
46+
// The Interpreter will run the byte code VM based on the passed
47+
// configuration.
48+
type Interpreter interface {
49+
// Run loops and evaluates the contract's code with the given input data and returns
50+
// the return byte-slice and an error if one occurred.
51+
Run(contract *Contract, input []byte, static bool) ([]byte, error)
52+
// CanRun tells if the contract, passed as an argument, can be
53+
// run by the current interpreter. This is meant so that the
54+
// caller can do something like:
55+
//
56+
// ```golang
57+
// for _, interpreter := range interpreters {
58+
// if interpreter.CanRun(contract.code) {
59+
// interpreter.Run(contract.code, input)
60+
// }
61+
// }
62+
// ```
63+
CanRun([]byte) bool
64+
}
65+
4166
// ScopeContext contains the things that are per-call, such as stack and memory,
4267
// but not transients like pc and gas
4368
type ScopeContext struct {
@@ -263,3 +288,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
263288
}
264289
return nil, nil
265290
}
291+
292+
// CanRun tells if the contract, passed as an argument, can be
293+
// run by the current interpreter.
294+
func (in *EVMInterpreter) CanRun(code []byte) bool {
295+
return true
296+
}

0 commit comments

Comments
 (0)