Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/vm: add switches to select evm+ewasm interpreters #17687

Merged
merged 1 commit into from
Sep 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ var (
utils.NoCompactionFlag,
utils.GpoBlocksFlag,
utils.GpoPercentileFlag,
utils.EWASMInterpreterFlag,
utils.EVMInterpreterFlag,
configFileFlag,
}

Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ var AppHelpFlagGroups = []flagGroup{
Name: "VIRTUAL MACHINE",
Flags: []cli.Flag{
utils.VMEnableDebugFlag,
utils.EVMInterpreterFlag,
utils.EWASMInterpreterFlag,
},
},
{
Expand Down
19 changes: 19 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down
22 changes: 20 additions & 2 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Copy link
Member

@chfast chfast Sep 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but you missed 64 other places where vm.Config{} is created. I'm not even sure if the new incoming transactions are going to be executed with the selected VM.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chfast those other location correspond to tests and simulations and we want to use the native interpreter in them. Incoming transactions will be executed by the VM, if you don't believe us check it for yourself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you. I just remember I had to change this in two places. Maybe it was about tests.

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)
Expand Down
5 changes: 5 additions & 0 deletions eth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 12 additions & 3 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
)

Expand All @@ -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"`
Expand Down Expand Up @@ -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)
}
gballet marked this conversation as resolved.
Show resolved Hide resolved

// 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.
Expand Down Expand Up @@ -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
}

Expand Down