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 /core/vm/runtime | |
parent | 7f79d249a64ee72b185ffa9a9ed78f137b7938de (diff) | |
download | go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.gz go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.bz2 go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.lz go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.xz go-tangerine-3fc7c978277051391f8ea7831559e9f4f83c3166.tar.zst go-tangerine-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 'core/vm/runtime')
-rw-r--r-- | core/vm/runtime/env.go | 98 | ||||
-rw-r--r-- | core/vm/runtime/runtime.go | 29 |
2 files changed, 41 insertions, 86 deletions
diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index f1a2b60d3..3cf0dd024 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -23,92 +23,22 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" ) -// Env is a basic runtime environment required for running the EVM. -type Env struct { - chainConfig *params.ChainConfig - depth int - state *state.StateDB - - origin common.Address - coinbase common.Address - - number *big.Int - time *big.Int - difficulty *big.Int - gasLimit *big.Int - - getHashFn func(uint64) common.Hash - - evm *vm.EVM -} - -// NewEnv returns a new vm.Environment -func NewEnv(cfg *Config, state *state.StateDB) vm.Environment { - env := &Env{ - chainConfig: cfg.ChainConfig, - state: state, - origin: cfg.Origin, - coinbase: cfg.Coinbase, - number: cfg.BlockNumber, - time: cfg.Time, - difficulty: cfg.Difficulty, - gasLimit: cfg.GasLimit, +func NewEnv(cfg *Config, state *state.StateDB) *vm.Environment { + 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: new(big.Int), } - env.evm = vm.New(env, vm.Config{ - Debug: cfg.Debug, - EnableJit: !cfg.DisableJit, - ForceJit: !cfg.DisableJit, - }) - - return env -} - -func (self *Env) ChainConfig() *params.ChainConfig { return self.chainConfig } -func (self *Env) Vm() vm.Vm { return self.evm } -func (self *Env) Origin() common.Address { return self.origin } -func (self *Env) BlockNumber() *big.Int { return self.number } -func (self *Env) Coinbase() common.Address { return self.coinbase } -func (self *Env) Time() *big.Int { return self.time } -func (self *Env) Difficulty() *big.Int { return self.difficulty } -func (self *Env) Db() vm.Database { return self.state } -func (self *Env) GasLimit() *big.Int { return self.gasLimit } -func (self *Env) VmType() vm.Type { return vm.StdVmTy } -func (self *Env) GetHash(n uint64) common.Hash { - return self.getHashFn(n) -} -func (self *Env) AddLog(log *vm.Log) { - self.state.AddLog(log) -} -func (self *Env) Depth() int { return self.depth } -func (self *Env) SetDepth(i int) { self.depth = i } -func (self *Env) CanTransfer(from common.Address, balance *big.Int) bool { - return self.state.GetBalance(from).Cmp(balance) >= 0 -} -func (self *Env) SnapshotDatabase() int { - return self.state.Snapshot() -} -func (self *Env) RevertToSnapshot(snapshot int) { - self.state.RevertToSnapshot(snapshot) -} - -func (self *Env) Transfer(from, to vm.Account, amount *big.Int) { - core.Transfer(from, to, amount) -} - -func (self *Env) Call(caller vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - return core.Call(self, caller, addr, data, gas, price, value) -} -func (self *Env) 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 *Env) DelegateCall(me vm.ContractRef, addr common.Address, data []byte, gas, price *big.Int) ([]byte, error) { - return core.DelegateCall(self, me, addr, data, gas, price) -} -func (self *Env) Create(caller vm.ContractRef, data []byte, gas, price, value *big.Int) ([]byte, common.Address, error) { - return core.Create(self, caller, data, gas, price, value) + return vm.NewEnvironment(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig) } diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index d51b435f8..3e99ed689 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" @@ -49,6 +50,7 @@ type Config struct { Value *big.Int DisableJit bool // "disable" so it's enabled by default Debug bool + EVMConfig vm.Config State *state.StateDB GetHashFn func(n uint64) common.Hash @@ -123,13 +125,37 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { receiver.Address(), input, cfg.GasLimit, - cfg.GasPrice, 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, error) { + if cfg == nil { + cfg = new(Config) + } + setDefaults(cfg) + + if cfg.State == nil { + db, _ := ethdb.NewMemDatabase() + cfg.State, _ = state.New(common.Hash{}, db) + } + var ( + vmenv = NewEnv(cfg, cfg.State) + sender = cfg.State.CreateAccount(cfg.Origin) + ) + + // Call the code with the given configuration. + return vmenv.Create( + sender, + input, + cfg.GasLimit, + cfg.Value, + ) +} + // Call executes the code given by the contract's address. It will return the // EVM's return value or an error if it failed. // @@ -147,7 +173,6 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, error) { address, input, cfg.GasLimit, - cfg.GasPrice, cfg.Value, ) |