diff options
author | JM <jm@dexon.org> | 2019-01-15 23:33:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-15 23:33:28 +0800 |
commit | 020c8a477578cef3764b54f33d9ca0cf6caf7631 (patch) | |
tree | 08a669a19cc428b8c48dad180f1f32096885826b /core/vm/runtime | |
parent | bdde6109ffa6fa4d295708a2a75271186a12c761 (diff) | |
download | dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.tar dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.tar.gz dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.tar.bz2 dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.tar.lz dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.tar.xz dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.tar.zst dexon-020c8a477578cef3764b54f33d9ca0cf6caf7631.zip |
core: vm: refactor file structure (#151)
For support other vm types, this pr modified the core/vm file
structures.
Diffstat (limited to 'core/vm/runtime')
-rw-r--r-- | core/vm/runtime/doc.go | 18 | ||||
-rw-r--r-- | core/vm/runtime/env.go | 41 | ||||
-rw-r--r-- | core/vm/runtime/fuzz.go | 36 | ||||
-rw-r--r-- | core/vm/runtime/runtime.go | 170 | ||||
-rw-r--r-- | core/vm/runtime/runtime_example_test.go | 34 | ||||
-rw-r--r-- | core/vm/runtime/runtime_test.go | 205 |
6 files changed, 0 insertions, 504 deletions
diff --git a/core/vm/runtime/doc.go b/core/vm/runtime/doc.go deleted file mode 100644 index a3b464a7d..000000000 --- a/core/vm/runtime/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -// Package runtime provides a basic execution model for executing EVM code. -package runtime diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go deleted file mode 100644 index 6f241a329..000000000 --- a/core/vm/runtime/env.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package runtime - -import ( - "github.com/dexon-foundation/dexon/common" - "github.com/dexon-foundation/dexon/core" - "github.com/dexon-foundation/dexon/core/vm" -) - -func NewEnv(cfg *Config) *vm.EVM { - context := vm.Context{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: func(uint64) common.Hash { return common.Hash{} }, - - Origin: cfg.Origin, - Coinbase: cfg.Coinbase, - BlockNumber: cfg.BlockNumber, - Time: cfg.Time, - Difficulty: cfg.Difficulty, - GasLimit: cfg.GasLimit, - GasPrice: cfg.GasPrice, - } - - return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig) -} diff --git a/core/vm/runtime/fuzz.go b/core/vm/runtime/fuzz.go deleted file mode 100644 index cb9ff08b5..000000000 --- a/core/vm/runtime/fuzz.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -// +build gofuzz - -package runtime - -// Fuzz is the basic entry point for the go-fuzz tool -// -// This returns 1 for valid parsable/runable code, 0 -// for invalid opcode. -func Fuzz(input []byte) int { - _, _, err := Execute(input, input, &Config{ - GasLimit: 3000000, - }) - - // invalid opcode - if err != nil && len(err.Error()) > 6 && string(err.Error()[:7]) == "invalid" { - return 0 - } - - return 1 -} diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go deleted file mode 100644 index 5656f661a..000000000 --- a/core/vm/runtime/runtime.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package runtime - -import ( - "math" - "math/big" - "time" - - "github.com/dexon-foundation/dexon/common" - "github.com/dexon-foundation/dexon/core/state" - "github.com/dexon-foundation/dexon/core/vm" - "github.com/dexon-foundation/dexon/crypto" - "github.com/dexon-foundation/dexon/ethdb" - "github.com/dexon-foundation/dexon/params" -) - -// Config is a basic type specifying certain configuration flags for running -// the EVM. -type Config struct { - ChainConfig *params.ChainConfig - Difficulty *big.Int - Origin common.Address - Coinbase common.Address - BlockNumber *big.Int - Time *big.Int - GasLimit uint64 - GasPrice *big.Int - Value *big.Int - Debug bool - EVMConfig vm.Config - - State *state.StateDB - GetHashFn func(n uint64) common.Hash -} - -// sets defaults on the config -func setDefaults(cfg *Config) { - if cfg.ChainConfig == nil { - cfg.ChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: new(big.Int), - DAOForkBlock: new(big.Int), - DAOForkSupport: false, - EIP150Block: new(big.Int), - EIP155Block: new(big.Int), - EIP158Block: new(big.Int), - } - } - - if cfg.Difficulty == nil { - cfg.Difficulty = new(big.Int) - } - if cfg.Time == nil { - cfg.Time = big.NewInt(time.Now().Unix()) - } - if cfg.GasLimit == 0 { - cfg.GasLimit = math.MaxUint64 - } - if cfg.GasPrice == nil { - cfg.GasPrice = new(big.Int) - } - if cfg.Value == nil { - cfg.Value = new(big.Int) - } - if cfg.BlockNumber == nil { - cfg.BlockNumber = new(big.Int) - } - if cfg.GetHashFn == nil { - cfg.GetHashFn = func(n uint64) common.Hash { - return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String()))) - } - } -} - -// Execute executes the code using the input as call data during the execution. -// It returns the EVM's return value, the new state and an error if it failed. -// -// Executes sets up a in memory, temporarily, environment for the execution of -// the given code. It makes sure that it's restored to it's original state afterwards. -func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { - if cfg == nil { - cfg = new(Config) - } - setDefaults(cfg) - - if cfg.State == nil { - cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) - } - var ( - address = common.BytesToAddress([]byte("contract")) - vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) - ) - cfg.State.CreateAccount(address) - // set the receiver's (the executing contract) code for execution. - cfg.State.SetCode(address, code) - // Call the code with the given configuration. - ret, _, err := vmenv.Call( - sender, - common.BytesToAddress([]byte("contract")), - input, - cfg.GasLimit, - cfg.Value, - ) - - return ret, cfg.State, err -} - -// Create executes the code using the EVM create method -func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { - if cfg == nil { - cfg = new(Config) - } - setDefaults(cfg) - - if cfg.State == nil { - cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) - } - var ( - vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) - ) - - // Call the code with the given configuration. - code, address, leftOverGas, err := vmenv.Create( - sender, - input, - cfg.GasLimit, - cfg.Value, - ) - return code, address, leftOverGas, err -} - -// Call executes the code given by the contract's address. It will return the -// EVM's return value or an error if it failed. -// -// Call, unlike Execute, requires a config and also requires the State field to -// be set. -func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) { - setDefaults(cfg) - - vmenv := NewEnv(cfg) - - sender := cfg.State.GetOrNewStateObject(cfg.Origin) - // Call the code with the given configuration. - ret, leftOverGas, err := vmenv.Call( - sender, - address, - input, - cfg.GasLimit, - cfg.Value, - ) - - return ret, leftOverGas, err -} diff --git a/core/vm/runtime/runtime_example_test.go b/core/vm/runtime/runtime_example_test.go deleted file mode 100644 index 036cfe558..000000000 --- a/core/vm/runtime/runtime_example_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package runtime_test - -import ( - "fmt" - - "github.com/dexon-foundation/dexon/common" - "github.com/dexon-foundation/dexon/core/vm/runtime" -) - -func ExampleExecute() { - ret, _, err := runtime.Execute(common.Hex2Bytes("6060604052600a8060106000396000f360606040526008565b00"), nil, nil) - if err != nil { - fmt.Println(err) - } - fmt.Println(ret) - // Output: - // [96 96 96 64 82 96 8 86 91 0] -} diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go deleted file mode 100644 index fe03bd43f..000000000 --- a/core/vm/runtime/runtime_test.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package runtime - -import ( - "math/big" - "strings" - "testing" - - "github.com/dexon-foundation/dexon/accounts/abi" - "github.com/dexon-foundation/dexon/common" - "github.com/dexon-foundation/dexon/core/state" - "github.com/dexon-foundation/dexon/core/vm" - "github.com/dexon-foundation/dexon/ethdb" - "github.com/dexon-foundation/dexon/params" -) - -func TestDefaults(t *testing.T) { - cfg := new(Config) - setDefaults(cfg) - - if cfg.Difficulty == nil { - t.Error("expected difficulty to be non nil") - } - - if cfg.Time == nil { - t.Error("expected time to be non nil") - } - if cfg.GasLimit == 0 { - t.Error("didn't expect gaslimit to be zero") - } - if cfg.GasPrice == nil { - t.Error("expected time to be non nil") - } - if cfg.Value == nil { - t.Error("expected time to be non nil") - } - if cfg.GetHashFn == nil { - t.Error("expected time to be non nil") - } - if cfg.BlockNumber == nil { - t.Error("expected block number to be non nil") - } -} - -func TestEVM(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Fatalf("crashed with: %v", r) - } - }() - - Execute([]byte{ - byte(vm.DIFFICULTY), - byte(vm.TIMESTAMP), - byte(vm.GASLIMIT), - byte(vm.PUSH1), - byte(vm.ORIGIN), - byte(vm.BLOCKHASH), - byte(vm.COINBASE), - }, nil, nil) -} - -func TestExecute(t *testing.T) { - ret, _, err := Execute([]byte{ - byte(vm.PUSH1), 10, - byte(vm.PUSH1), 0, - byte(vm.MSTORE), - byte(vm.PUSH1), 32, - byte(vm.PUSH1), 0, - byte(vm.RETURN), - }, nil, nil) - if err != nil { - t.Fatal("didn't expect error", err) - } - - num := new(big.Int).SetBytes(ret) - if num.Cmp(big.NewInt(10)) != 0 { - t.Error("Expected 10, got", num) - } -} - -func TestCall(t *testing.T) { - state, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) - address := common.HexToAddress("0x0a") - state.SetCode(address, []byte{ - byte(vm.PUSH1), 10, - byte(vm.PUSH1), 0, - byte(vm.MSTORE), - byte(vm.PUSH1), 32, - byte(vm.PUSH1), 0, - byte(vm.RETURN), - }) - - ret, _, err := Call(address, nil, &Config{State: state}) - if err != nil { - t.Fatal("didn't expect error", err) - } - - num := new(big.Int).SetBytes(ret) - if num.Cmp(big.NewInt(10)) != 0 { - t.Error("Expected 10, got", num) - } -} - -func BenchmarkCall(b *testing.B) { - var definition = `[{"constant":true,"inputs":[],"name":"seller","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"abort","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"refund","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"buyer","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"confirmReceived","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"state","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":false,"inputs":[],"name":"confirmPurchase","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"},{"anonymous":false,"inputs":[],"name":"Aborted","type":"event"},{"anonymous":false,"inputs":[],"name":"PurchaseConfirmed","type":"event"},{"anonymous":false,"inputs":[],"name":"ItemReceived","type":"event"},{"anonymous":false,"inputs":[],"name":"Refunded","type":"event"}]` - - var code = common.Hex2Bytes("6060604052361561006c5760e060020a600035046308551a53811461007457806335a063b4146100865780633fa4f245146100a6578063590e1ae3146100af5780637150d8ae146100cf57806373fac6f0146100e1578063c19d93fb146100fe578063d696069714610112575b610131610002565b610133600154600160a060020a031681565b610131600154600160a060020a0390811633919091161461015057610002565b61014660005481565b610131600154600160a060020a039081163391909116146102d557610002565b610133600254600160a060020a031681565b610131600254600160a060020a0333811691161461023757610002565b61014660025460ff60a060020a9091041681565b61013160025460009060ff60a060020a9091041681146101cc57610002565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60025460009060a060020a900460ff16811461016b57610002565b600154600160a060020a03908116908290301631606082818181858883f150506002805460a060020a60ff02191660a160020a179055506040517f72c874aeff0b183a56e2b79c71b46e1aed4dee5e09862134b8821ba2fddbf8bf9250a150565b80546002023414806101dd57610002565b6002805460a060020a60ff021973ffffffffffffffffffffffffffffffffffffffff1990911633171660a060020a1790557fd5d55c8a68912e9a110618df8d5e2e83b8d83211c57a8ddd1203df92885dc881826060a15050565b60025460019060a060020a900460ff16811461025257610002565b60025460008054600160a060020a0390921691606082818181858883f150508354604051600160a060020a0391821694503090911631915082818181858883f150506002805460a060020a60ff02191660a160020a179055506040517fe89152acd703c9d8c7d28829d443260b411454d45394e7995815140c8cbcbcf79250a150565b60025460019060a060020a900460ff1681146102f057610002565b6002805460008054600160a060020a0390921692909102606082818181858883f150508354604051600160a060020a0391821694503090911631915082818181858883f150506002805460a060020a60ff02191660a160020a179055506040517f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf79250a15056") - - abi, err := abi.JSON(strings.NewReader(definition)) - if err != nil { - b.Fatal(err) - } - - cpurchase, err := abi.Pack("confirmPurchase") - if err != nil { - b.Fatal(err) - } - creceived, err := abi.Pack("confirmReceived") - if err != nil { - b.Fatal(err) - } - refund, err := abi.Pack("refund") - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - for j := 0; j < 400; j++ { - Execute(code, cpurchase, nil) - Execute(code, creceived, nil) - Execute(code, refund, nil) - } - } -} -func benchmarkEVM_Create(bench *testing.B, code string) { - var ( - statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) - sender = common.BytesToAddress([]byte("sender")) - receiver = common.BytesToAddress([]byte("receiver")) - ) - - statedb.CreateAccount(sender) - statedb.SetCode(receiver, common.FromHex(code)) - runtimeConfig := Config{ - Origin: sender, - State: statedb, - GasLimit: 10000000, - Difficulty: big.NewInt(0x200000), - Time: new(big.Int).SetUint64(0), - Coinbase: common.Address{}, - BlockNumber: new(big.Int).SetUint64(1), - ChainConfig: ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: new(big.Int), - ByzantiumBlock: new(big.Int), - ConstantinopleBlock: new(big.Int), - DAOForkBlock: new(big.Int), - DAOForkSupport: false, - EIP150Block: new(big.Int), - EIP155Block: new(big.Int), - EIP158Block: new(big.Int), - }, - EVMConfig: vm.Config{}, - } - // Warm up the intpools and stuff - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - Call(receiver, []byte{}, &runtimeConfig) - } - bench.StopTimer() -} - -func BenchmarkEVM_CREATE_500(bench *testing.B) { - // initcode size 500K, repeatedly calls CREATE and then modifies the mem contents - benchmarkEVM_Create(bench, "5b6207a120600080f0600152600056") -} -func BenchmarkEVM_CREATE2_500(bench *testing.B) { - // initcode size 500K, repeatedly calls CREATE2 and then modifies the mem contents - benchmarkEVM_Create(bench, "5b586207a120600080f5600152600056") -} -func BenchmarkEVM_CREATE_1200(bench *testing.B) { - // initcode size 1200K, repeatedly calls CREATE and then modifies the mem contents - benchmarkEVM_Create(bench, "5b62124f80600080f0600152600056") -} -func BenchmarkEVM_CREATE2_1200(bench *testing.B) { - // initcode size 1200K, repeatedly calls CREATE2 and then modifies the mem contents - benchmarkEVM_Create(bench, "5b5862124f80600080f5600152600056") -} |