aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Ballet <gballet@gmail.com>2018-09-20 15:44:35 +0800
committerPéter Szilágyi <peterke@gmail.com>2018-09-20 15:44:35 +0800
commitda29332c5f4c368ff03ec4e7132eefac48fed1ae (patch)
treefc9a9d2bd594ef22f7b9d9fca8bd410c28304f99
parent3fec73500b60c82a827b36bb03f8ae011b861e72 (diff)
downloaddexon-da29332c5f4c368ff03ec4e7132eefac48fed1ae.tar.gz
dexon-da29332c5f4c368ff03ec4e7132eefac48fed1ae.tar.zst
dexon-da29332c5f4c368ff03ec4e7132eefac48fed1ae.zip
core/vm: add switches to select evm+ewasm interpreters (#17687)
Interpreter initialization is left to the PRs implementing them. Options for external interpreters are passed after a colon in the `--vm.ewasm` and `--vm.evm` switches.
-rw-r--r--cmd/geth/main.go2
-rw-r--r--cmd/geth/usage.go2
-rw-r--r--cmd/utils/flags.go19
-rw-r--r--core/vm/evm.go22
-rw-r--r--core/vm/interpreter.go5
-rw-r--r--eth/backend.go6
-rw-r--r--eth/config.go5
-rw-r--r--params/config.go15
8 files changed, 70 insertions, 6 deletions
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 134d5a4c0..fae4b5718 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -130,6 +130,8 @@ var (
utils.NoCompactionFlag,
utils.GpoBlocksFlag,
utils.GpoPercentileFlag,
+ utils.EWASMInterpreterFlag,
+ utils.EVMInterpreterFlag,
configFileFlag,
}
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
index a674eca4f..8b0491ce3 100644
--- a/cmd/geth/usage.go
+++ b/cmd/geth/usage.go
@@ -207,6 +207,8 @@ var AppHelpFlagGroups = []flagGroup{
Name: "VIRTUAL MACHINE",
Flags: []cli.Flag{
utils.VMEnableDebugFlag,
+ utils.EVMInterpreterFlag,
+ utils.EWASMInterpreterFlag,
},
},
{
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 0fecae9aa..78fb629aa 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -610,6 +610,17 @@ var (
Usage: "InfluxDB `host` tag attached to all measurements",
Value: "localhost",
}
+
+ EWASMInterpreterFlag = cli.StringFlag{
+ Name: "vm.ewasm",
+ Usage: "External ewasm configuration (default = built-in interpreter)",
+ Value: "",
+ }
+ EVMInterpreterFlag = cli.StringFlag{
+ Name: "vm.evm",
+ Usage: "External EVM configuration (default = built-in interpreter)",
+ Value: "",
+ }
)
// MakeDataDir retrieves the currently requested data directory, terminating
@@ -1184,6 +1195,14 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
}
+ if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) {
+ cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name)
+ }
+
+ if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
+ cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
+ }
+
// Override any default configs for hard coded networks.
switch {
case ctx.GlobalBool(TestnetFlag.Name):
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 58618f811..fc040c621 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -136,10 +136,28 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
vmConfig: vmConfig,
chainConfig: chainConfig,
chainRules: chainConfig.Rules(ctx.BlockNumber),
- interpreters: make([]Interpreter, 1),
+ interpreters: make([]Interpreter, 0, 1),
}
- evm.interpreters[0] = NewEVMInterpreter(evm, vmConfig)
+ if chainConfig.IsEWASM(ctx.BlockNumber) {
+ // to be implemented by EVM-C and Wagon PRs.
+ // if vmConfig.EWASMInterpreter != "" {
+ // extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":")
+ // path := extIntOpts[0]
+ // options := []string{}
+ // if len(extIntOpts) > 1 {
+ // options = extIntOpts[1..]
+ // }
+ // evm.interpreters = append(evm.interpreters, NewEVMVCInterpreter(evm, vmConfig, options))
+ // } else {
+ // evm.interpreters = append(evm.interpreters, NewEWASMInterpreter(evm, vmConfig))
+ // }
+ panic("No supported ewasm interpreter yet.")
+ }
+
+ // vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
+ // as we always want to have the built-in EVM as the failover option.
+ evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
evm.interpreter = evm.interpreters[0]
return evm
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 0f1b07342..8e934f60e 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -39,6 +39,11 @@ type Config struct {
// may be left uninitialised and will be set to the default
// table.
JumpTable [256]operation
+
+ // Type of the EWASM interpreter
+ EWASMInterpreter string
+ // Type of the EVM interpreter
+ EVMInterpreter string
}
// Interpreter is used to run Ethereum based contracts and will utilise the
diff --git a/eth/backend.go b/eth/backend.go
index 9926225f2..7d8060d77 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -149,7 +149,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion)
}
var (
- vmConfig = vm.Config{EnablePreimageRecording: config.EnablePreimageRecording}
+ vmConfig = vm.Config{
+ EnablePreimageRecording: config.EnablePreimageRecording,
+ EWASMInterpreter: config.EWASMInterpreter,
+ EVMInterpreter: config.EVMInterpreter,
+ }
cacheConfig = &core.CacheConfig{Disabled: config.NoPruning, TrieNodeLimit: config.TrieCache, TrieTimeLimit: config.TrieTimeout}
)
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig)
diff --git a/eth/config.go b/eth/config.go
index f1a402e37..efbaafb6a 100644
--- a/eth/config.go
+++ b/eth/config.go
@@ -121,6 +121,11 @@ type Config struct {
// Miscellaneous options
DocRoot string `toml:"-"`
+
+ // Type of the EWASM interpreter ("" for detault)
+ EWASMInterpreter string
+ // Type of the EVM interpreter ("" for default)
+ EVMInterpreter string
}
type configMarshaling struct {
diff --git a/params/config.go b/params/config.go
index 629720550..c4dfa8b4b 100644
--- a/params/config.go
+++ b/params/config.go
@@ -84,16 +84,16 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
- AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
+ AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
- AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
+ AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
- TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
+ TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil}
TestRules = TestChainConfig.Rules(new(big.Int))
)
@@ -119,6 +119,7 @@ type ChainConfig struct {
ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
+ EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated)
// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"`
@@ -204,6 +205,11 @@ func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
return isForked(c.ConstantinopleBlock, num)
}
+// IsEWASM returns whether num represents a block number after the EWASM fork
+func (c *ChainConfig) IsEWASM(num *big.Int) bool {
+ return isForked(c.EWASMBlock, num)
+}
+
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
//
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
@@ -269,6 +275,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
}
+ if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
+ return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
+ }
return nil
}