diff options
author | Jeffrey Wilcke <jeffrey@ethereum.org> | 2016-12-06 09:16:03 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2016-12-06 09:16:03 +0800 |
commit | 3fc7c978277051391f8ea7831559e9f4f83c3166 (patch) | |
tree | b11b41c1723e02adc098ddc9f4188a8bad782ed8 /cmd | |
parent | 7f79d249a64ee72b185ffa9a9ed78f137b7938de (diff) | |
download | dexon-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.gz dexon-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.zst dexon-3fc7c978277051391f8ea7831559e9f4f83c3166.zip |
core, core/vm: implemented a generic environment (#3348)
Environment is now a struct (not an interface). This
reduces a lot of tech-debt throughout the codebase where a virtual
machine environment had to be implemented in order to test or run it.
The new environment is suitable to be used en the json tests, core
consensus and light client.
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/evm/main.go | 139 |
1 files changed, 25 insertions, 114 deletions
diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 2c4329fa5..993dd7659 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -20,21 +20,18 @@ package main import ( "fmt" "io/ioutil" - "math/big" "os" - "runtime" + goruntime "runtime" "time" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/vm/runtime" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/params" "gopkg.in/urfave/cli.v1" ) @@ -129,13 +126,6 @@ func run(ctx *cli.Context) error { logger := vm.NewStructLogger(nil) - vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name)), vm.Config{ - Debug: ctx.GlobalBool(DebugFlag.Name), - ForceJit: ctx.GlobalBool(ForceJitFlag.Name), - EnableJit: !ctx.GlobalBool(DisableJitFlag.Name), - Tracer: logger, - }) - tstart := time.Now() var ( @@ -168,25 +158,30 @@ func run(ctx *cli.Context) error { if ctx.GlobalBool(CreateFlag.Name) { input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...) - ret, _, err = vmenv.Create( - sender, - input, - common.Big(ctx.GlobalString(GasFlag.Name)), - common.Big(ctx.GlobalString(PriceFlag.Name)), - common.Big(ctx.GlobalString(ValueFlag.Name)), - ) + ret, _, err = runtime.Create(input, &runtime.Config{ + Origin: sender.Address(), + State: statedb, + GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)), + GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)), + Value: common.Big(ctx.GlobalString(ValueFlag.Name)), + EVMConfig: vm.Config{ + Tracer: logger, + }, + }) } else { receiver := statedb.CreateAccount(common.StringToAddress("receiver")) - receiver.SetCode(crypto.Keccak256Hash(code), code) - ret, err = vmenv.Call( - sender, - receiver.Address(), - common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), - common.Big(ctx.GlobalString(GasFlag.Name)), - common.Big(ctx.GlobalString(PriceFlag.Name)), - common.Big(ctx.GlobalString(ValueFlag.Name)), - ) + + ret, err = runtime.Call(receiver.Address(), common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{ + Origin: sender.Address(), + State: statedb, + GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)), + GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)), + Value: common.Big(ctx.GlobalString(ValueFlag.Name)), + EVMConfig: vm.Config{ + Tracer: logger, + }, + }) } vmdone := time.Since(tstart) @@ -197,8 +192,8 @@ func run(ctx *cli.Context) error { vm.StdErrFormat(logger.StructLogs()) if ctx.GlobalBool(SysStatFlag.Name) { - var mem runtime.MemStats - runtime.ReadMemStats(&mem) + var mem goruntime.MemStats + goruntime.ReadMemStats(&mem) fmt.Printf("vm took %v\n", vmdone) fmt.Printf(`alloc: %d tot alloc: %d @@ -223,87 +218,3 @@ func main() { os.Exit(1) } } - -type VMEnv struct { - state *state.StateDB - block *types.Block - - transactor *common.Address - value *big.Int - - depth int - Gas *big.Int - time *big.Int - logs []vm.StructLog - - evm *vm.EVM -} - -func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int, cfg vm.Config) *VMEnv { - env := &VMEnv{ - state: state, - transactor: &transactor, - value: value, - time: big.NewInt(time.Now().Unix()), - } - - env.evm = vm.New(env, cfg) - return env -} - -// ruleSet implements vm.ChainConfig and will always default to the homestead rule set. -type ruleSet struct{} - -func (ruleSet) IsHomestead(*big.Int) bool { return true } -func (ruleSet) GasTable(*big.Int) params.GasTable { - return params.GasTableHomesteadGasRepriceFork -} - -func (self *VMEnv) ChainConfig() *params.ChainConfig { return params.TestChainConfig } -func (self *VMEnv) Vm() vm.Vm { return self.evm } -func (self *VMEnv) Db() vm.Database { return self.state } -func (self *VMEnv) SnapshotDatabase() int { return self.state.Snapshot() } -func (self *VMEnv) RevertToSnapshot(snap int) { self.state.RevertToSnapshot(snap) } -func (self *VMEnv) Origin() common.Address { return *self.transactor } -func (self *VMEnv) BlockNumber() *big.Int { return common.Big0 } -func (self *VMEnv) Coinbase() common.Address { return *self.transactor } -func (self *VMEnv) Time() *big.Int { return self.time } -func (self *VMEnv) Difficulty() *big.Int { return common.Big1 } -func (self *VMEnv) BlockHash() []byte { return make([]byte, 32) } -func (self *VMEnv) Value() *big.Int { return self.value } -func (self *VMEnv) GasLimit() *big.Int { return big.NewInt(1000000000) } -func (self *VMEnv) VmType() vm.Type { return vm.StdVmTy } -func (self *VMEnv) Depth() int { return 0 } -func (self *VMEnv) SetDepth(i int) { self.depth = i } -func (self *VMEnv) GetHash(n uint64) common.Hash { - if self.block.Number().Cmp(big.NewInt(int64(n))) == 0 { - return self.block.Hash() - } - return common.Hash{} -} -func (self *VMEnv) AddLog(log *vm.Log) { - self.state.AddLog(log) -} -func (self *VMEnv) CanTransfer(from common.Address, balance *big.Int) bool { - return self.state.GetBalance(from).Cmp(balance) >= 0 -} -func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) { - core.Transfer(from, to, amount) -} - -func (self *VMEnv) Call(caller vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - self.Gas = gas - return core.Call(self, caller, addr, data, gas, price, value) -} - -func (self *VMEnv) CallCode(caller vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - return core.CallCode(self, caller, addr, data, gas, price, value) -} - -func (self *VMEnv) DelegateCall(caller vm.ContractRef, addr common.Address, data []byte, gas, price *big.Int) ([]byte, error) { - return core.DelegateCall(self, caller, addr, data, gas, price) -} - -func (self *VMEnv) Create(caller vm.ContractRef, data []byte, gas, price, value *big.Int) ([]byte, common.Address, error) { - return core.Create(self, caller, data, gas, price, value) -} |