core, eth, internal, les: rename VM objects

Renamed Environment to EVM and EVM to Interpreter.

The rational behind this that the Environment used to be an interface
and had multiple implementations across the code base. All of the logic
implemented in the Environment is part of the EVM. The old EVM is
actually the interpreter, which interprets the byte code. The old EVM is
part of the EVM as a whole.
This commit is contained in:
Jeffrey Wilcke 2016-12-16 17:16:29 +01:00
parent 54ab362cc1
commit 64ac1ec1d7
23 changed files with 221 additions and 221 deletions

View file

@ -229,7 +229,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain) evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain)
// Create a new environment which holds all relevant information // Create a new environment which holds all relevant information
// about the transaction and calling mechanisms. // about the transaction and calling mechanisms.
vmenv := vm.NewEnvironment(evmContext, statedb, chainConfig, vm.Config{}) vmenv := vm.NewEVM(evmContext, statedb, chainConfig, vm.Config{})
gaspool := new(core.GasPool).AddGas(common.MaxBig) gaspool := new(core.GasPool).AddGas(common.MaxBig)
ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
return ret, gasUsed, err return ret, gasUsed, err

View file

@ -99,7 +99,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, s
context := NewEVMContext(msg, header, bc) context := NewEVMContext(msg, header, bc)
// Create a new environment which holds all relevant information // Create a new environment which holds all relevant information
// about the transaction and calling mechanisms. // about the transaction and calling mechanisms.
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{}) vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
// Apply the transaction to the current state (included in the env) // Apply the transaction to the current state (included in the env)
_, gas, err := ApplyMessage(vmenv, msg, gp) _, gas, err := ApplyMessage(vmenv, msg, gp)
if err != nil { if err != nil {

View file

@ -57,7 +57,7 @@ type StateTransition struct {
data []byte data []byte
state vm.StateDB state vm.StateDB
env *vm.Environment env *vm.EVM
} }
// Message represents a message sent to a contract. // Message represents a message sent to a contract.
@ -106,7 +106,7 @@ func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
} }
// NewStateTransition initialises and returns a new state transition object. // NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(env *vm.Environment, msg Message, gp *GasPool) *StateTransition { func NewStateTransition(env *vm.EVM, msg Message, gp *GasPool) *StateTransition {
return &StateTransition{ return &StateTransition{
gp: gp, gp: gp,
env: env, env: env,
@ -127,7 +127,7 @@ func NewStateTransition(env *vm.Environment, msg Message, gp *GasPool) *StateTra
// the gas used (which includes gas refunds) and an error if it failed. An error always // the gas used (which includes gas refunds) and an error if it failed. An error always
// indicates a core error meaning that the message would always fail for that particular // indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block. // state and would never be accepted within a block.
func ApplyMessage(env *vm.Environment, msg Message, gp *GasPool) ([]byte, *big.Int, error) { func ApplyMessage(env *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, error) {
st := NewStateTransition(env, msg, gp) st := NewStateTransition(env, msg, gp)
ret, _, gasUsed, err := st.TransitionDb() ret, _, gasUsed, err := st.TransitionDb()

View file

@ -58,10 +58,10 @@ type Context struct {
Difficulty *big.Int // Provides information for DIFFICULTY Difficulty *big.Int // Provides information for DIFFICULTY
} }
// Environment provides information about external sources for the EVM // EVM provides information about external sources for the EVM
// //
// The Environment should never be reused and is not thread safe. // The EVM should never be reused and is not thread safe.
type Environment struct { type EVM struct {
// Context provides auxiliary blockchain related information // Context provides auxiliary blockchain related information
Context Context
// StateDB gives access to the underlying state // StateDB gives access to the underlying state
@ -76,7 +76,7 @@ type Environment struct {
vmConfig Config vmConfig Config
// global (to this context) ethereum virtual machine // global (to this context) ethereum virtual machine
// used throughout the execution of the tx. // used throughout the execution of the tx.
evm Vm interpreter EVMInterpreter
// abort is used to abort the EVM calling operations // abort is used to abort the EVM calling operations
// NOTE: must be set atomically // NOTE: must be set atomically
abort int32 abort int32
@ -84,27 +84,27 @@ type Environment struct {
quit chan struct{} quit chan struct{}
} }
// NewEnvironment retutrns a new EVM environment. // NewEVM retutrns a new EVM evmironment.
func NewEnvironment(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *Environment { func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
env := &Environment{ evm := &EVM{
Context: ctx, Context: ctx,
StateDB: statedb, StateDB: statedb,
vmConfig: vmConfig, vmConfig: vmConfig,
chainConfig: chainConfig, chainConfig: chainConfig,
} }
env.evm = New(env, vmConfig) evm.interpreter = NewInterpreter(evm, vmConfig)
return env return evm
} }
func (env *Environment) init() { func (evm *EVM) init() {
env.quit = make(chan struct{}) evm.quit = make(chan struct{})
go func() { go func() {
select { select {
case <-env.quit: case <-evm.quit:
return return
case <-env.Context.Done(): case <-evm.Context.Done():
atomic.StoreInt32(&env.abort, 1) atomic.StoreInt32(&evm.abort, 1)
} }
}() }()
} }
@ -112,13 +112,13 @@ func (env *Environment) init() {
// Call executes the contract associated with the addr with the given input as paramaters. It also handles any // Call executes the contract associated with the addr with the given input as paramaters. It also handles any
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in // necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
// case of an execution error or failed value transfer. // case of an execution error or failed value transfer.
func (env *Environment) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) { func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
if env.Depth == 0 { if evm.Depth == 0 {
env.init() evm.init()
defer close(env.quit) defer close(evm.quit)
} }
if env.vmConfig.NoRecursion && env.Depth > 0 { if evm.vmConfig.NoRecursion && evm.Depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, nil return nil, nil
@ -126,12 +126,12 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
// Depth check execution. Fail if we're trying to execute above the // Depth check execution. Fail if we're trying to execute above the
// limit. // limit.
if env.Depth > int(params.CallCreateDepth.Int64()) { if evm.Depth > int(params.CallCreateDepth.Int64()) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, ErrDepth return nil, ErrDepth
} }
if !env.Context.CanTransfer(env.StateDB, caller.Address(), value) { if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, ErrInsufficientBalance return nil, ErrInsufficientBalance
@ -139,35 +139,35 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
var ( var (
to Account to Account
snapshot = env.StateDB.Snapshot() snapshot = evm.StateDB.Snapshot()
) )
if !env.StateDB.Exist(addr) { if !evm.StateDB.Exist(addr) {
if PrecompiledContracts[addr] == nil && env.ChainConfig().IsEIP158(env.BlockNumber) && value.BitLen() == 0 { if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.BitLen() == 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, nil return nil, nil
} }
to = env.StateDB.CreateAccount(addr) to = evm.StateDB.CreateAccount(addr)
} else { } else {
to = env.StateDB.GetAccount(addr) to = evm.StateDB.GetAccount(addr)
} }
env.Transfer(env.StateDB, caller.Address(), to.Address(), value) evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
// initialise a new contract and set the code that is to be used by the // initialise a new contract and set the code that is to be used by the
// E The contract is a scoped environment for this execution context // E The contract is a scoped evmironment for this execution context
// only. // only.
contract := NewContract(caller, to, value, gas) contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&addr, env.StateDB.GetCodeHash(addr), env.StateDB.GetCode(addr)) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
defer contract.Finalise() defer contract.Finalise()
ret, err = env.EVM().Run(contract, input) ret, err = evm.interpreter.Run(contract, input)
// When an error was returned by the EVM or when setting the creation code // When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally // above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in homestead this also counts for code storage gas errors. // when we're in homestead this also counts for code storage gas errors.
if err != nil { if err != nil {
contract.UseGas(contract.Gas) contract.UseGas(contract.Gas)
env.StateDB.RevertToSnapshot(snapshot) evm.StateDB.RevertToSnapshot(snapshot)
} }
return ret, err return ret, err
} }
@ -177,13 +177,13 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
// case of an execution error or failed value transfer. // case of an execution error or failed value transfer.
// //
// CallCode differs from Call in the sense that it executes the given address' code with the caller as context. // CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
func (env *Environment) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) { func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
if env.Depth == 0 { if evm.Depth == 0 {
env.init() evm.init()
defer close(env.quit) defer close(evm.quit)
} }
if env.vmConfig.NoRecursion && env.Depth > 0 { if evm.vmConfig.NoRecursion && evm.Depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, nil return nil, nil
@ -191,33 +191,33 @@ func (env *Environment) CallCode(caller ContractRef, addr common.Address, input
// Depth check execution. Fail if we're trying to execute above the // Depth check execution. Fail if we're trying to execute above the
// limit. // limit.
if env.Depth > int(params.CallCreateDepth.Int64()) { if evm.Depth > int(params.CallCreateDepth.Int64()) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, ErrDepth return nil, ErrDepth
} }
if !env.CanTransfer(env.StateDB, caller.Address(), value) { if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, fmt.Errorf("insufficient funds to transfer value. Req %v, has %v", value, env.StateDB.GetBalance(caller.Address())) return nil, fmt.Errorf("insufficient funds to transfer value. Req %v, has %v", value, evm.StateDB.GetBalance(caller.Address()))
} }
var ( var (
snapshot = env.StateDB.Snapshot() snapshot = evm.StateDB.Snapshot()
to = env.StateDB.GetAccount(caller.Address()) to = evm.StateDB.GetAccount(caller.Address())
) )
// initialise a new contract and set the code that is to be used by the // initialise a new contract and set the code that is to be used by the
// E The contract is a scoped environment for this execution context // E The contract is a scoped evmironment for this execution context
// only. // only.
contract := NewContract(caller, to, value, gas) contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&addr, env.StateDB.GetCodeHash(addr), env.StateDB.GetCode(addr)) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
defer contract.Finalise() defer contract.Finalise()
ret, err = env.EVM().Run(contract, input) ret, err = evm.interpreter.Run(contract, input)
if err != nil { if err != nil {
contract.UseGas(contract.Gas) contract.UseGas(contract.Gas)
env.StateDB.RevertToSnapshot(snapshot) evm.StateDB.RevertToSnapshot(snapshot)
} }
return ret, err return ret, err
@ -228,13 +228,13 @@ func (env *Environment) CallCode(caller ContractRef, addr common.Address, input
// //
// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context // DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
// and the caller is set to the caller of the caller. // and the caller is set to the caller of the caller.
func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) { func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) {
if env.Depth == 0 { if evm.Depth == 0 {
env.init() evm.init()
defer close(env.quit) defer close(evm.quit)
} }
if env.vmConfig.NoRecursion && env.Depth > 0 { if evm.vmConfig.NoRecursion && evm.Depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, nil return nil, nil
@ -242,39 +242,39 @@ func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, in
// Depth check execution. Fail if we're trying to execute above the // Depth check execution. Fail if we're trying to execute above the
// limit. // limit.
if env.Depth > int(params.CallCreateDepth.Int64()) { if evm.Depth > int(params.CallCreateDepth.Int64()) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, ErrDepth return nil, ErrDepth
} }
var ( var (
snapshot = env.StateDB.Snapshot() snapshot = evm.StateDB.Snapshot()
to = env.StateDB.GetAccount(caller.Address()) to = evm.StateDB.GetAccount(caller.Address())
) )
// Iinitialise a new contract and make initialise the delegate values // Iinitialise a new contract and make initialise the delegate values
contract := NewContract(caller, to, caller.Value(), gas).AsDelegate() contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
contract.SetCallCode(&addr, env.StateDB.GetCodeHash(addr), env.StateDB.GetCode(addr)) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
defer contract.Finalise() defer contract.Finalise()
ret, err = env.EVM().Run(contract, input) ret, err = evm.interpreter.Run(contract, input)
if err != nil { if err != nil {
contract.UseGas(contract.Gas) contract.UseGas(contract.Gas)
env.StateDB.RevertToSnapshot(snapshot) evm.StateDB.RevertToSnapshot(snapshot)
} }
return ret, err return ret, err
} }
// Create creates a new contract using code as deployment code. // Create creates a new contract using code as deployment code.
func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) { func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) {
if env.Depth == 0 { if evm.Depth == 0 {
env.init() evm.init()
defer close(env.quit) defer close(evm.quit)
} }
if env.vmConfig.NoRecursion && env.Depth > 0 { if evm.vmConfig.NoRecursion && evm.Depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, common.Address{}, nil return nil, common.Address{}, nil
@ -282,37 +282,37 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
// Depth check execution. Fail if we're trying to execute above the // Depth check execution. Fail if we're trying to execute above the
// limit. // limit.
if env.Depth > int(params.CallCreateDepth.Int64()) { if evm.Depth > int(params.CallCreateDepth.Int64()) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, common.Address{}, ErrDepth return nil, common.Address{}, ErrDepth
} }
if !env.CanTransfer(env.StateDB, caller.Address(), value) { if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
caller.ReturnGas(gas) caller.ReturnGas(gas)
return nil, common.Address{}, ErrInsufficientBalance return nil, common.Address{}, ErrInsufficientBalance
} }
// Create a new account on the state // Create a new account on the state
nonce := env.StateDB.GetNonce(caller.Address()) nonce := evm.StateDB.GetNonce(caller.Address())
env.StateDB.SetNonce(caller.Address(), nonce+1) evm.StateDB.SetNonce(caller.Address(), nonce+1)
snapshot := env.StateDB.Snapshot() snapshot := evm.StateDB.Snapshot()
contractAddr = crypto.CreateAddress(caller.Address(), nonce) contractAddr = crypto.CreateAddress(caller.Address(), nonce)
to := env.StateDB.CreateAccount(contractAddr) to := evm.StateDB.CreateAccount(contractAddr)
if env.ChainConfig().IsEIP158(env.BlockNumber) { if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
env.StateDB.SetNonce(contractAddr, 1) evm.StateDB.SetNonce(contractAddr, 1)
} }
env.Transfer(env.StateDB, caller.Address(), to.Address(), value) evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
// initialise a new contract and set the code that is to be used by the // initialise a new contract and set the code that is to be used by the
// E The contract is a scoped environment for this execution context // E The contract is a scoped evmironment for this execution context
// only. // only.
contract := NewContract(caller, to, value, gas) contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code) contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
defer contract.Finalise() defer contract.Finalise()
ret, err = env.EVM().Run(contract, nil) ret, err = evm.interpreter.Run(contract, nil)
// check whether the max code size has been exceeded // check whether the max code size has been exceeded
maxCodeSizeExceeded := len(ret) > params.MaxCodeSize maxCodeSizeExceeded := len(ret) > params.MaxCodeSize
@ -324,7 +324,7 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
dataGas := big.NewInt(int64(len(ret))) dataGas := big.NewInt(int64(len(ret)))
dataGas.Mul(dataGas, params.CreateDataGas) dataGas.Mul(dataGas, params.CreateDataGas)
if contract.UseGas(dataGas) { if contract.UseGas(dataGas) {
env.StateDB.SetCode(contractAddr, ret) evm.StateDB.SetCode(contractAddr, ret)
} else { } else {
err = ErrCodeStoreOutOfGas err = ErrCodeStoreOutOfGas
} }
@ -334,9 +334,9 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
// above we revert to the snapshot and consume any gas remaining. Additionally // above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in homestead this also counts for code storage gas errors. // when we're in homestead this also counts for code storage gas errors.
if maxCodeSizeExceeded || if maxCodeSizeExceeded ||
(err != nil && (env.ChainConfig().IsHomestead(env.BlockNumber) || err != ErrCodeStoreOutOfGas)) { (err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
contract.UseGas(contract.Gas) contract.UseGas(contract.Gas)
env.StateDB.RevertToSnapshot(snapshot) evm.StateDB.RevertToSnapshot(snapshot)
// Nothing should be returned when an error is thrown. // Nothing should be returned when an error is thrown.
return nil, contractAddr, err return nil, contractAddr, err
@ -351,8 +351,8 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
return ret, contractAddr, err return ret, contractAddr, err
} }
// ChainConfig returns the environment's chain configuration // ChainConfig returns the evmironment's chain configuration
func (env *Environment) ChainConfig() *params.ChainConfig { return env.chainConfig } func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
// EVM returns the environments EVM // Interpreter returns the EVM interpreter
func (env *Environment) EVM() Vm { return env.evm } func (evm *EVM) Interpreter() EVMInterpreter { return evm.interpreter }

View file

@ -34,12 +34,12 @@ func memoryGasCost(mem *Memory, newMemSize *big.Int) *big.Int {
} }
func makeGenericGasFunc(op OpCode) gasFunc { func makeGenericGasFunc(op OpCode) gasFunc {
return func(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { return func(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return gasTable[op] return gasTable[op]
} }
} }
func gasCalldataCopy(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasCalldataCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := memoryGasCost(mem, memorySize) gas := memoryGasCost(mem, memorySize)
gas.Add(gas, gasTable[CALLDATACOPY]) gas.Add(gas, gasTable[CALLDATACOPY])
words := toWordSize(stack.Back(2)) words := toWordSize(stack.Back(2))
@ -47,7 +47,7 @@ func gasCalldataCopy(gt params.GasTable, env *Environment, contract *Contract, s
return gas.Add(gas, words.Mul(words, params.CopyGas)) return gas.Add(gas, words.Mul(words, params.CopyGas))
} }
func gasSStore(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasSStore(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
var ( var (
y, x = stack.Back(1), stack.Back(0) y, x = stack.Back(1), stack.Back(0)
val = env.StateDB.GetState(contract.Address(), common.BigToHash(x)) val = env.StateDB.GetState(contract.Address(), common.BigToHash(x))
@ -70,7 +70,7 @@ func gasSStore(gt params.GasTable, env *Environment, contract *Contract, stack *
} }
func makeGasLog(n uint) gasFunc { func makeGasLog(n uint) gasFunc {
return func(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { return func(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
mSize := stack.Back(1) mSize := stack.Back(1)
gas := new(big.Int).Add(memoryGasCost(mem, memorySize), params.LogGas) gas := new(big.Int).Add(memoryGasCost(mem, memorySize), params.LogGas)
@ -80,14 +80,14 @@ func makeGasLog(n uint) gasFunc {
} }
} }
func gasSha3(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasSha3(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := memoryGasCost(mem, memorySize) gas := memoryGasCost(mem, memorySize)
gas.Add(gas, gasTable[SHA3]) gas.Add(gas, gasTable[SHA3])
words := toWordSize(stack.Back(1)) words := toWordSize(stack.Back(1))
return gas.Add(gas, words.Mul(words, params.Sha3WordGas)) return gas.Add(gas, words.Mul(words, params.Sha3WordGas))
} }
func gasCodeCopy(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasCodeCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := memoryGasCost(mem, memorySize) gas := memoryGasCost(mem, memorySize)
gas.Add(gas, gasTable[CODECOPY]) gas.Add(gas, gasTable[CODECOPY])
words := toWordSize(stack.Back(2)) words := toWordSize(stack.Back(2))
@ -95,7 +95,7 @@ func gasCodeCopy(gt params.GasTable, env *Environment, contract *Contract, stack
return gas.Add(gas, words.Mul(words, params.CopyGas)) return gas.Add(gas, words.Mul(words, params.CopyGas))
} }
func gasExtCodeCopy(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasExtCodeCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := memoryGasCost(mem, memorySize) gas := memoryGasCost(mem, memorySize)
gas.Add(gas, gt.ExtcodeCopy) gas.Add(gas, gt.ExtcodeCopy)
words := toWordSize(stack.Back(3)) words := toWordSize(stack.Back(3))
@ -103,42 +103,42 @@ func gasExtCodeCopy(gt params.GasTable, env *Environment, contract *Contract, st
return gas.Add(gas, words.Mul(words, params.CopyGas)) return gas.Add(gas, words.Mul(words, params.CopyGas))
} }
func gasMLoad(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasMLoad(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return new(big.Int).Add(gasTable[MLOAD], memoryGasCost(mem, memorySize)) return new(big.Int).Add(gasTable[MLOAD], memoryGasCost(mem, memorySize))
} }
func gasMStore8(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasMStore8(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return new(big.Int).Add(gasTable[MSTORE8], memoryGasCost(mem, memorySize)) return new(big.Int).Add(gasTable[MSTORE8], memoryGasCost(mem, memorySize))
} }
func gasMStore(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasMStore(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return new(big.Int).Add(gasTable[MSTORE], memoryGasCost(mem, memorySize)) return new(big.Int).Add(gasTable[MSTORE], memoryGasCost(mem, memorySize))
} }
func gasCreate(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasCreate(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return new(big.Int).Add(gasTable[CREATE], memoryGasCost(mem, memorySize)) return new(big.Int).Add(gasTable[CREATE], memoryGasCost(mem, memorySize))
} }
func gasBalance(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasBalance(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return gt.Balance return gt.Balance
} }
func gasExtCodeSize(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasExtCodeSize(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return gt.ExtcodeSize return gt.ExtcodeSize
} }
func gasSLoad(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasSLoad(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return gt.SLoad return gt.SLoad
} }
func gasExp(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasExp(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
expByteLen := int64((stack.data[stack.len()-2].BitLen() + 7) / 8) expByteLen := int64((stack.data[stack.len()-2].BitLen() + 7) / 8)
gas := big.NewInt(expByteLen) gas := big.NewInt(expByteLen)
gas.Mul(gas, gt.ExpByte) gas.Mul(gas, gt.ExpByte)
return gas.Add(gas, gasTable[EXP]) return gas.Add(gas, gasTable[EXP])
} }
func gasCall(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasCall(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := new(big.Int).Set(gt.Calls) gas := new(big.Int).Set(gt.Calls)
transfersValue := stack.Back(2).BitLen() > 0 transfersValue := stack.Back(2).BitLen() > 0
@ -170,7 +170,7 @@ func gasCall(gt params.GasTable, env *Environment, contract *Contract, stack *St
return gas.Add(gas, cg) return gas.Add(gas, cg)
} }
func gasCallCode(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasCallCode(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := new(big.Int).Set(gt.Calls) gas := new(big.Int).Set(gt.Calls)
if stack.Back(2).BitLen() > 0 { if stack.Back(2).BitLen() > 0 {
gas.Add(gas, params.CallValueTransferGas) gas.Add(gas, params.CallValueTransferGas)
@ -189,11 +189,11 @@ func gasCallCode(gt params.GasTable, env *Environment, contract *Contract, stack
return gas.Add(gas, cg) return gas.Add(gas, cg)
} }
func gasReturn(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasReturn(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return new(big.Int).Add(gasTable[RETURN], memoryGasCost(mem, memorySize)) return new(big.Int).Add(gasTable[RETURN], memoryGasCost(mem, memorySize))
} }
func gasSuicide(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasSuicide(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := new(big.Int) gas := new(big.Int)
// EIP150 homestead gas reprice fork: // EIP150 homestead gas reprice fork:
if env.ChainConfig().IsEIP150(env.BlockNumber) { if env.ChainConfig().IsEIP150(env.BlockNumber) {
@ -219,7 +219,7 @@ func gasSuicide(gt params.GasTable, env *Environment, contract *Contract, stack
return gas return gas
} }
func gasDelegateCall(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasDelegateCall(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
gas := new(big.Int).Add(gt.Calls, memoryGasCost(mem, memorySize)) gas := new(big.Int).Add(gt.Calls, memoryGasCost(mem, memorySize))
cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1]) cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1])
@ -233,15 +233,15 @@ func gasDelegateCall(gt params.GasTable, env *Environment, contract *Contract, s
return gas.Add(gas, cg) return gas.Add(gas, cg)
} }
func gasPush(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasPush(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return GasFastestStep return GasFastestStep
} }
func gasSwap(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasSwap(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return GasFastestStep return GasFastestStep
} }
func gasDup(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int { func gasDup(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
return GasFastestStep return GasFastestStep
} }

View file

@ -26,25 +26,25 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
func opAdd(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
stack.push(U256(x.Add(x, y))) stack.push(U256(x.Add(x, y)))
return nil, nil return nil, nil
} }
func opSub(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
stack.push(U256(x.Sub(x, y))) stack.push(U256(x.Sub(x, y)))
return nil, nil return nil, nil
} }
func opMul(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
stack.push(U256(x.Mul(x, y))) stack.push(U256(x.Mul(x, y)))
return nil, nil return nil, nil
} }
func opDiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
if y.Cmp(common.Big0) != 0 { if y.Cmp(common.Big0) != 0 {
stack.push(U256(x.Div(x, y))) stack.push(U256(x.Div(x, y)))
@ -54,7 +54,7 @@ func opDiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
return nil, nil return nil, nil
} }
func opSdiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := S256(stack.pop()), S256(stack.pop()) x, y := S256(stack.pop()), S256(stack.pop())
if y.Cmp(common.Big0) == 0 { if y.Cmp(common.Big0) == 0 {
stack.push(new(big.Int)) stack.push(new(big.Int))
@ -75,7 +75,7 @@ func opSdiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
return nil, nil return nil, nil
} }
func opMod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
if y.Cmp(common.Big0) == 0 { if y.Cmp(common.Big0) == 0 {
stack.push(new(big.Int)) stack.push(new(big.Int))
@ -85,7 +85,7 @@ func opMod(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
return nil, nil return nil, nil
} }
func opSmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := S256(stack.pop()), S256(stack.pop()) x, y := S256(stack.pop()), S256(stack.pop())
if y.Cmp(common.Big0) == 0 { if y.Cmp(common.Big0) == 0 {
@ -106,13 +106,13 @@ func opSmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
return nil, nil return nil, nil
} }
func opExp(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
base, exponent := stack.pop(), stack.pop() base, exponent := stack.pop(), stack.pop()
stack.push(math.Exp(base, exponent)) stack.push(math.Exp(base, exponent))
return nil, nil return nil, nil
} }
func opSignExtend(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
back := stack.pop() back := stack.pop()
if back.Cmp(big.NewInt(31)) < 0 { if back.Cmp(big.NewInt(31)) < 0 {
bit := uint(back.Uint64()*8 + 7) bit := uint(back.Uint64()*8 + 7)
@ -130,13 +130,13 @@ func opSignExtend(pc *uint64, env *Environment, contract *Contract, memory *Memo
return nil, nil return nil, nil
} }
func opNot(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x := stack.pop() x := stack.pop()
stack.push(U256(x.Not(x))) stack.push(U256(x.Not(x)))
return nil, nil return nil, nil
} }
func opLt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
if x.Cmp(y) < 0 { if x.Cmp(y) < 0 {
stack.push(big.NewInt(1)) stack.push(big.NewInt(1))
@ -146,7 +146,7 @@ func opLt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stac
return nil, nil return nil, nil
} }
func opGt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
if x.Cmp(y) > 0 { if x.Cmp(y) > 0 {
stack.push(big.NewInt(1)) stack.push(big.NewInt(1))
@ -156,7 +156,7 @@ func opGt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stac
return nil, nil return nil, nil
} }
func opSlt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := S256(stack.pop()), S256(stack.pop()) x, y := S256(stack.pop()), S256(stack.pop())
if x.Cmp(S256(y)) < 0 { if x.Cmp(S256(y)) < 0 {
stack.push(big.NewInt(1)) stack.push(big.NewInt(1))
@ -166,7 +166,7 @@ func opSlt(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
return nil, nil return nil, nil
} }
func opSgt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := S256(stack.pop()), S256(stack.pop()) x, y := S256(stack.pop()), S256(stack.pop())
if x.Cmp(y) > 0 { if x.Cmp(y) > 0 {
stack.push(big.NewInt(1)) stack.push(big.NewInt(1))
@ -176,7 +176,7 @@ func opSgt(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
return nil, nil return nil, nil
} }
func opEq(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
if x.Cmp(y) == 0 { if x.Cmp(y) == 0 {
stack.push(big.NewInt(1)) stack.push(big.NewInt(1))
@ -186,7 +186,7 @@ func opEq(pc *uint64, env *Environment, contract *Contract, memory *Memory, stac
return nil, nil return nil, nil
} }
func opIszero(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x := stack.pop() x := stack.pop()
if x.Cmp(common.Big0) > 0 { if x.Cmp(common.Big0) > 0 {
stack.push(new(big.Int)) stack.push(new(big.Int))
@ -196,22 +196,22 @@ func opIszero(pc *uint64, env *Environment, contract *Contract, memory *Memory,
return nil, nil return nil, nil
} }
func opAnd(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
stack.push(x.And(x, y)) stack.push(x.And(x, y))
return nil, nil return nil, nil
} }
func opOr(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
stack.push(x.Or(x, y)) stack.push(x.Or(x, y))
return nil, nil return nil, nil
} }
func opXor(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop() x, y := stack.pop(), stack.pop()
stack.push(x.Xor(x, y)) stack.push(x.Xor(x, y))
return nil, nil return nil, nil
} }
func opByte(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
th, val := stack.pop(), stack.pop() th, val := stack.pop(), stack.pop()
if th.Cmp(big.NewInt(32)) < 0 { if th.Cmp(big.NewInt(32)) < 0 {
byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()])) byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
@ -221,7 +221,7 @@ func opByte(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
} }
return nil, nil return nil, nil
} }
func opAddmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y, z := stack.pop(), stack.pop(), stack.pop() x, y, z := stack.pop(), stack.pop(), stack.pop()
if z.Cmp(Zero) > 0 { if z.Cmp(Zero) > 0 {
add := x.Add(x, y) add := x.Add(x, y)
@ -232,7 +232,7 @@ func opAddmod(pc *uint64, env *Environment, contract *Contract, memory *Memory,
} }
return nil, nil return nil, nil
} }
func opMulmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y, z := stack.pop(), stack.pop(), stack.pop() x, y, z := stack.pop(), stack.pop(), stack.pop()
if z.Cmp(Zero) > 0 { if z.Cmp(Zero) > 0 {
mul := x.Mul(x, y) mul := x.Mul(x, y)
@ -244,7 +244,7 @@ func opMulmod(pc *uint64, env *Environment, contract *Contract, memory *Memory,
return nil, nil return nil, nil
} }
func opSha3(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
offset, size := stack.pop(), stack.pop() offset, size := stack.pop(), stack.pop()
hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64())) hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64()))
@ -252,12 +252,12 @@ func opSha3(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
return nil, nil return nil, nil
} }
func opAddress(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(common.Bytes2Big(contract.Address().Bytes())) stack.push(common.Bytes2Big(contract.Address().Bytes()))
return nil, nil return nil, nil
} }
func opBalance(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
addr := common.BigToAddress(stack.pop()) addr := common.BigToAddress(stack.pop())
balance := env.StateDB.GetBalance(addr) balance := env.StateDB.GetBalance(addr)
@ -265,32 +265,32 @@ func opBalance(pc *uint64, env *Environment, contract *Contract, memory *Memory,
return nil, nil return nil, nil
} }
func opOrigin(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(env.Origin.Big()) stack.push(env.Origin.Big())
return nil, nil return nil, nil
} }
func opCaller(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(contract.Caller().Big()) stack.push(contract.Caller().Big())
return nil, nil return nil, nil
} }
func opCallValue(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(new(big.Int).Set(contract.value)) stack.push(new(big.Int).Set(contract.value))
return nil, nil return nil, nil
} }
func opCalldataLoad(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32))) stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
return nil, nil return nil, nil
} }
func opCalldataSize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(big.NewInt(int64(len(contract.Input)))) stack.push(big.NewInt(int64(len(contract.Input))))
return nil, nil return nil, nil
} }
func opCalldataCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
var ( var (
mOff = stack.pop() mOff = stack.pop()
cOff = stack.pop() cOff = stack.pop()
@ -300,20 +300,20 @@ func opCalldataCopy(pc *uint64, env *Environment, contract *Contract, memory *Me
return nil, nil return nil, nil
} }
func opExtCodeSize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
addr := common.BigToAddress(stack.pop()) addr := common.BigToAddress(stack.pop())
l := big.NewInt(int64(env.StateDB.GetCodeSize(addr))) l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
stack.push(l) stack.push(l)
return nil, nil return nil, nil
} }
func opCodeSize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
l := big.NewInt(int64(len(contract.Code))) l := big.NewInt(int64(len(contract.Code)))
stack.push(l) stack.push(l)
return nil, nil return nil, nil
} }
func opCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
var ( var (
mOff = stack.pop() mOff = stack.pop()
cOff = stack.pop() cOff = stack.pop()
@ -325,7 +325,7 @@ func opCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory
return nil, nil return nil, nil
} }
func opExtCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
var ( var (
addr = common.BigToAddress(stack.pop()) addr = common.BigToAddress(stack.pop())
mOff = stack.pop() mOff = stack.pop()
@ -338,12 +338,12 @@ func opExtCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Mem
return nil, nil return nil, nil
} }
func opGasprice(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(new(big.Int).Set(env.GasPrice)) stack.push(new(big.Int).Set(env.GasPrice))
return nil, nil return nil, nil
} }
func opBlockhash(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
num := stack.pop() num := stack.pop()
n := new(big.Int).Sub(env.BlockNumber, common.Big257) n := new(big.Int).Sub(env.BlockNumber, common.Big257)
@ -355,71 +355,71 @@ func opBlockhash(pc *uint64, env *Environment, contract *Contract, memory *Memor
return nil, nil return nil, nil
} }
func opCoinbase(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(env.Coinbase.Big()) stack.push(env.Coinbase.Big())
return nil, nil return nil, nil
} }
func opTimestamp(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(U256(new(big.Int).Set(env.Time))) stack.push(U256(new(big.Int).Set(env.Time)))
return nil, nil return nil, nil
} }
func opNumber(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(U256(new(big.Int).Set(env.BlockNumber))) stack.push(U256(new(big.Int).Set(env.BlockNumber)))
return nil, nil return nil, nil
} }
func opDifficulty(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(U256(new(big.Int).Set(env.Difficulty))) stack.push(U256(new(big.Int).Set(env.Difficulty)))
return nil, nil return nil, nil
} }
func opGasLimit(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(U256(new(big.Int).Set(env.GasLimit))) stack.push(U256(new(big.Int).Set(env.GasLimit)))
return nil, nil return nil, nil
} }
func opPop(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.pop() stack.pop()
return nil, nil return nil, nil
} }
func opMload(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
offset := stack.pop() offset := stack.pop()
val := common.BigD(memory.Get(offset.Int64(), 32)) val := common.BigD(memory.Get(offset.Int64(), 32))
stack.push(val) stack.push(val)
return nil, nil return nil, nil
} }
func opMstore(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
// pop value of the stack // pop value of the stack
mStart, val := stack.pop(), stack.pop() mStart, val := stack.pop(), stack.pop()
memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256)) memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
return nil, nil return nil, nil
} }
func opMstore8(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
off, val := stack.pop().Int64(), stack.pop().Int64() off, val := stack.pop().Int64(), stack.pop().Int64()
memory.store[off] = byte(val & 0xff) memory.store[off] = byte(val & 0xff)
return nil, nil return nil, nil
} }
func opSload(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
loc := common.BigToHash(stack.pop()) loc := common.BigToHash(stack.pop())
val := env.StateDB.GetState(contract.Address(), loc).Big() val := env.StateDB.GetState(contract.Address(), loc).Big()
stack.push(val) stack.push(val)
return nil, nil return nil, nil
} }
func opSstore(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
loc := common.BigToHash(stack.pop()) loc := common.BigToHash(stack.pop())
val := stack.pop() val := stack.pop()
env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
return nil, nil return nil, nil
} }
func opJump(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
pos := stack.pop() pos := stack.pop()
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
nop := contract.GetOp(pos.Uint64()) nop := contract.GetOp(pos.Uint64())
@ -428,7 +428,7 @@ func opJump(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
*pc = pos.Uint64() *pc = pos.Uint64()
return nil, nil return nil, nil
} }
func opJumpi(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
pos, cond := stack.pop(), stack.pop() pos, cond := stack.pop(), stack.pop()
if cond.Cmp(common.BigTrue) >= 0 { if cond.Cmp(common.BigTrue) >= 0 {
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
@ -441,26 +441,26 @@ func opJumpi(pc *uint64, env *Environment, contract *Contract, memory *Memory, s
} }
return nil, nil return nil, nil
} }
func opJumpdest(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
return nil, nil return nil, nil
} }
func opPc(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(new(big.Int).SetUint64(*pc)) stack.push(new(big.Int).SetUint64(*pc))
return nil, nil return nil, nil
} }
func opMsize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(big.NewInt(int64(memory.Len()))) stack.push(big.NewInt(int64(memory.Len())))
return nil, nil return nil, nil
} }
func opGas(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.push(new(big.Int).Set(contract.Gas)) stack.push(new(big.Int).Set(contract.Gas))
return nil, nil return nil, nil
} }
func opCreate(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
var ( var (
value = stack.pop() value = stack.pop()
offset, size = stack.pop(), stack.pop() offset, size = stack.pop(), stack.pop()
@ -488,7 +488,7 @@ func opCreate(pc *uint64, env *Environment, contract *Contract, memory *Memory,
return nil, nil return nil, nil
} }
func opCall(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
gas := stack.pop() gas := stack.pop()
// pop gas and value of the stack. // pop gas and value of the stack.
addr, value := stack.pop(), stack.pop() addr, value := stack.pop(), stack.pop()
@ -520,7 +520,7 @@ func opCall(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
return nil, nil return nil, nil
} }
func opCallCode(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
gas := stack.pop() gas := stack.pop()
// pop gas and value of the stack. // pop gas and value of the stack.
addr, value := stack.pop(), stack.pop() addr, value := stack.pop(), stack.pop()
@ -552,7 +552,7 @@ func opCallCode(pc *uint64, env *Environment, contract *Contract, memory *Memory
return nil, nil return nil, nil
} }
func opDelegateCall(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
// if not homestead return an error. DELEGATECALL is not supported // if not homestead return an error. DELEGATECALL is not supported
// during pre-homestead. // during pre-homestead.
if !env.ChainConfig().IsHomestead(env.BlockNumber) { if !env.ChainConfig().IsHomestead(env.BlockNumber) {
@ -573,18 +573,18 @@ func opDelegateCall(pc *uint64, env *Environment, contract *Contract, memory *Me
return nil, nil return nil, nil
} }
func opReturn(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
offset, size := stack.pop(), stack.pop() offset, size := stack.pop(), stack.pop()
ret := memory.GetPtr(offset.Int64(), size.Int64()) ret := memory.GetPtr(offset.Int64(), size.Int64())
return ret, nil return ret, nil
} }
func opStop(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
return nil, nil return nil, nil
} }
func opSuicide(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
balance := env.StateDB.GetBalance(contract.Address()) balance := env.StateDB.GetBalance(contract.Address())
env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
@ -597,7 +597,7 @@ func opSuicide(pc *uint64, env *Environment, contract *Contract, memory *Memory,
// make log instruction function // make log instruction function
func makeLog(size int) executionFunc { func makeLog(size int) executionFunc {
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
topics := make([]common.Hash, size) topics := make([]common.Hash, size)
mStart, mSize := stack.pop(), stack.pop() mStart, mSize := stack.pop(), stack.pop()
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
@ -613,7 +613,7 @@ func makeLog(size int) executionFunc {
// make push instruction function // make push instruction function
func makePush(size uint64, bsize *big.Int) executionFunc { func makePush(size uint64, bsize *big.Int) executionFunc {
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize) byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
stack.push(common.Bytes2Big(byts)) stack.push(common.Bytes2Big(byts))
*pc += size *pc += size
@ -623,7 +623,7 @@ func makePush(size uint64, bsize *big.Int) executionFunc {
// make push instruction function // make push instruction function
func makeDup(size int64) executionFunc { func makeDup(size int64) executionFunc {
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.dup(int(size)) stack.dup(int(size))
return nil, nil return nil, nil
} }
@ -633,7 +633,7 @@ func makeDup(size int64) executionFunc {
func makeSwap(size int64) executionFunc { func makeSwap(size int64) executionFunc {
// switch n + 1 otherwise n would be swapped with n // switch n + 1 otherwise n would be swapped with n
size += 1 size += 1
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
stack.swap(int(size)) stack.swap(int(size))
return nil, nil return nil, nil
} }

View file

@ -22,8 +22,8 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
// Vm is the basic interface for an implementation of the EVM. // EVMInterpreter is the basic interface for an implementation of the EVM.
type Vm interface { type EVMInterpreter interface {
// Run should execute the given contract with the input given in in // Run should execute the given contract with the input given in in
// and return the contract execution return bytes or an error if it // and return the contract execution return bytes or an error if it
// failed. // failed.
@ -83,15 +83,15 @@ type Account interface {
Value() *big.Int Value() *big.Int
} }
// CallContext provides a basic interface for the EVM calling conventions. The EVM Environment // CallContext provides a basic interface for the EVM calling conventions. The EVM EVM
// depends on this context being implemented for doing subcalls and initialising new EVM contracts. // depends on this context being implemented for doing subcalls and initialising new EVM contracts.
type CallContext interface { type CallContext interface {
// Call another contract // Call another contract
Call(env *Environment, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
// Take another's contract code and execute within our own context // Take another's contract code and execute within our own context
CallCode(env *Environment, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
// Same as CallCode except sender and value is propagated from parent to child scope // Same as CallCode except sender and value is propagated from parent to child scope
DelegateCall(env *Environment, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error)
// Create a new contract // Create a new contract
Create(env *Environment, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
} }

View file

@ -23,8 +23,8 @@ import (
) )
type ( type (
executionFunc func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) executionFunc func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
gasFunc func(params.GasTable, *Environment, *Contract, *Stack, *Memory, *big.Int) *big.Int gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, *big.Int) *big.Int
stackValidationFunc func(*Stack) error stackValidationFunc func(*Stack) error
memorySizeFunc func(*Stack) *big.Int memorySizeFunc func(*Stack) *big.Int
) )

View file

@ -45,7 +45,7 @@ type LogConfig struct {
Limit int // maximum length of output, but zero means unlimited Limit int // maximum length of output, but zero means unlimited
} }
// StructLog is emitted to the Environment each cycle and lists information about the current internal state // StructLog is emitted to the EVM each cycle and lists information about the current internal state
// prior to the execution of the statement. // prior to the execution of the statement.
type StructLog struct { type StructLog struct {
Pc uint64 Pc uint64
@ -65,7 +65,7 @@ type StructLog struct {
// Note that reference types are actual VM data structures; make copies // Note that reference types are actual VM data structures; make copies
// if you need to retain them beyond the current call. // if you need to retain them beyond the current call.
type Tracer interface { type Tracer interface {
CaptureState(env *Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
} }
// StructLogger is an EVM state logger and implements Tracer. // StructLogger is an EVM state logger and implements Tracer.
@ -94,7 +94,7 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
// captureState logs a new structured log message and pushes it out to the environment // captureState logs a new structured log message and pushes it out to the environment
// //
// captureState also tracks SSTORE ops to track dirty values. // captureState also tracks SSTORE ops to track dirty values.
func (l *StructLogger) CaptureState(env *Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
// check if already accumulated the specified number of logs // check if already accumulated the specified number of logs
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
return ErrTraceLimitReached return ErrTraceLimitReached

View file

@ -53,7 +53,7 @@ func (d dummyStateDB) GetAccount(common.Address) Account {
func TestStoreCapture(t *testing.T) { func TestStoreCapture(t *testing.T) {
var ( var (
env = NewEnvironment(Context{Context: context.TODO()}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) env = NewEVM(Context{Context: context.TODO()}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
logger = NewStructLogger(nil) logger = NewStructLogger(nil)
mem = NewMemory() mem = NewMemory()
stack = newstack() stack = newstack()
@ -80,7 +80,7 @@ func TestStorageCapture(t *testing.T) {
var ( var (
ref = &dummyContractRef{} ref = &dummyContractRef{}
contract = NewContract(ref, ref, new(big.Int), new(big.Int)) contract = NewContract(ref, ref, new(big.Int), new(big.Int))
env = NewEnvironment(Context{Context: context.TODO()}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) env = NewEVM(Context{Context: context.TODO()}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
logger = NewStructLogger(nil) logger = NewStructLogger(nil)
mem = NewMemory() mem = NewMemory()
stack = newstack() stack = newstack()

View file

@ -26,7 +26,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
) )
func NewEnv(cfg *Config, state *state.StateDB) *vm.Environment { func NewEnv(cfg *Config, state *state.StateDB) *vm.EVM {
context := vm.Context{ context := vm.Context{
Context: context.TODO(), Context: context.TODO(),
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,
@ -42,5 +42,5 @@ func NewEnv(cfg *Config, state *state.StateDB) *vm.Environment {
GasPrice: new(big.Int), GasPrice: new(big.Int),
} }
return vm.NewEnvironment(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig) return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
} }

View file

@ -56,7 +56,7 @@ func TestDefaults(t *testing.T) {
} }
} }
func TestEnvironment(t *testing.T) { func TestEVM(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
t.Fatalf("crashed with: %v", r) t.Fatalf("crashed with: %v", r)

View file

@ -29,9 +29,9 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
// Config are the configuration options for the EVM // Config are the configuration options for the Interpreter
type Config struct { type Config struct {
// Debug enabled debugging EVM options // Debug enabled debugging Interpreter options
Debug bool Debug bool
// EnableJit enabled the JIT VM // EnableJit enabled the JIT VM
EnableJit bool EnableJit bool
@ -39,26 +39,26 @@ type Config struct {
ForceJit bool ForceJit bool
// Tracer is the op code logger // Tracer is the op code logger
Tracer Tracer Tracer Tracer
// NoRecursion disabled EVM call, callcode, // NoRecursion disabled Interpreter call, callcode,
// delegate call and create. // delegate call and create.
NoRecursion bool NoRecursion bool
// Disable gas metering // Disable gas metering
DisableGasMetering bool DisableGasMetering bool
} }
// EVM is used to run Ethereum based contracts and will utilise the // Interpreter is used to run Ethereum based contracts and will utilise the
// passed environment to query external sources for state information. // passed environment to query external sources for state information.
// The EVM will run the byte code VM or JIT VM based on the passed // The Interpreter will run the byte code VM or JIT VM based on the passed
// configuration. // configuration.
type EVM struct { type Interpreter struct {
env *Environment env *EVM
cfg Config cfg Config
gasTable params.GasTable gasTable params.GasTable
} }
// New returns a new instance of the EVM. // NewInterpreter returns a new instance of the Interpreter.
func New(env *Environment, cfg Config) *EVM { func NewInterpreter(env *EVM, cfg Config) *Interpreter {
return &EVM{ return &Interpreter{
env: env, env: env,
cfg: cfg, cfg: cfg,
gasTable: env.ChainConfig().GasTable(env.BlockNumber), gasTable: env.ChainConfig().GasTable(env.BlockNumber),
@ -66,7 +66,7 @@ func New(env *Environment, cfg Config) *EVM {
} }
// Run loops and evaluates the contract's code with the given input data // Run loops and evaluates the contract's code with the given input data
func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) { func (evm *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) {
evm.env.Depth++ evm.env.Depth++
defer func() { evm.env.Depth-- }() defer func() { evm.env.Depth-- }()
@ -112,7 +112,7 @@ func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) {
}() }()
} }
// The EVM main run loop (contextual). This loop runs until either an // The Interpreter main run loop (contextual). This loop runs until either an
// explicit STOP, RETURN or SUICIDE is executed, an error accured during // explicit STOP, RETURN or SUICIDE is executed, an error accured during
// the execution of one of the operations or until the evm.done is set by // the execution of one of the operations or until the evm.done is set by
// the parent context.Context. // the parent context.Context.

View file

@ -44,7 +44,7 @@ import (
) )
type JitVm struct { type JitVm struct {
env Environment env EVM
me ContextRef me ContextRef
callerAddr []byte callerAddr []byte
price *big.Int price *big.Int
@ -161,7 +161,7 @@ func assert(condition bool, message string) {
} }
} }
func NewJitVm(env Environment) *JitVm { func NewJitVm(env EVM) *JitVm {
return &JitVm{env: env} return &JitVm{env: env}
} }
@ -235,7 +235,7 @@ func (self *JitVm) Endl() VirtualMachine {
return self return self
} }
func (self *JitVm) Env() Environment { func (self *JitVm) Env() EVM {
return self.env return self.env
} }

View file

@ -532,7 +532,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
// Mutate the state if we haven't reached the tracing transaction yet // Mutate the state if we haven't reached the tracing transaction yet
if uint64(idx) < txIndex { if uint64(idx) < txIndex {
vmenv := vm.NewEnvironment(context, stateDb, api.config, vm.Config{}) vmenv := vm.NewEVM(context, stateDb, api.config, vm.Config{})
_, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())) _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil { if err != nil {
return nil, fmt.Errorf("mutation failed: %v", err) return nil, fmt.Errorf("mutation failed: %v", err)
@ -541,7 +541,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
continue continue
} }
vmenv := vm.NewEnvironment(context, stateDb, api.config, vm.Config{Debug: true, Tracer: tracer}) vmenv := vm.NewEVM(context, stateDb, api.config, vm.Config{Debug: true, Tracer: tracer})
ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())) ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil { if err != nil {
return nil, fmt.Errorf("tracing failed: %v", err) return nil, fmt.Errorf("tracing failed: %v", err)

View file

@ -106,14 +106,14 @@ func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(blockHash) return b.eth.blockchain.GetTdByHash(blockHash)
} }
func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.Environment, func() error, error) { func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
statedb := state.(EthApiState).state statedb := state.(EthApiState).state
from := statedb.GetOrNewStateObject(msg.From()) from := statedb.GetOrNewStateObject(msg.From())
from.SetBalance(common.MaxBig) from.SetBalance(common.MaxBig)
vmError := func() error { return nil } vmError := func() error { return nil }
context := core.NewEVMContext(msg, header, b.eth.BlockChain()) context := core.NewEVMContext(msg, header, b.eth.BlockChain())
return vm.NewEnvironment(context, statedb, b.eth.chainConfig, vm.Config{}), vmError, nil return vm.NewEVM(context, statedb, b.eth.chainConfig, vm.Config{}), vmError, nil
} }
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {

View file

@ -51,7 +51,7 @@ type Backend interface {
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
GetTd(blockHash common.Hash) *big.Int GetTd(blockHash common.Hash) *big.Int
GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (*vm.Environment, func() error, error) GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (*vm.EVM, func() error, error)
// TxPool API // TxPool API
SendTx(ctx context.Context, signedTx *types.Transaction) error SendTx(ctx context.Context, signedTx *types.Transaction) error
RemoveTx(txHash common.Hash) RemoveTx(txHash common.Hash)

View file

@ -278,7 +278,7 @@ func wrapError(context string, err error) error {
} }
// CaptureState implements the Tracer interface to trace a single step of VM execution // CaptureState implements the Tracer interface to trace a single step of VM execution
func (jst *JavascriptTracer) CaptureState(env *vm.Environment, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error {
if jst.err == nil { if jst.err == nil {
jst.memory.memory = memory jst.memory.memory = memory
jst.stack.stack = stack jst.stack.stack = stack

View file

@ -43,12 +43,12 @@ func (account) SetCode(common.Hash, []byte) {}
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
func runTrace(tracer *JavascriptTracer) (interface{}, error) { func runTrace(tracer *JavascriptTracer) (interface{}, error) {
env := vm.NewEnvironment(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
contract := vm.NewContract(account{}, account{}, big.NewInt(0), big.NewInt(10000)) contract := vm.NewContract(account{}, account{}, big.NewInt(0), big.NewInt(10000))
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
_, err := env.EVM().Run(contract, []byte{}) _, err := env.Interpreter().Run(contract, []byte{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -133,7 +133,7 @@ func TestHaltBetweenSteps(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
env := vm.NewEnvironment(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), big.NewInt(0)) contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), big.NewInt(0))
tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil) tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil)

View file

@ -88,7 +88,7 @@ func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(blockHash) return b.eth.blockchain.GetTdByHash(blockHash)
} }
func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.Environment, func() error, error) { func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
stateDb := state.(*light.LightState).Copy() stateDb := state.(*light.LightState).Copy()
addr := msg.From() addr := msg.From()
from, err := stateDb.GetOrNewStateObject(ctx, addr) from, err := stateDb.GetOrNewStateObject(ctx, addr)
@ -99,7 +99,7 @@ func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
vmstate := light.NewVMState(ctx, stateDb) vmstate := light.NewVMState(ctx, stateDb)
context := core.NewEVMContext(msg, header, b.eth.blockchain) context := core.NewEVMContext(msg, header, b.eth.blockchain)
return vm.NewEnvironment(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil return vm.NewEVM(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil
} }
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {

View file

@ -123,7 +123,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, bc) context := core.NewEVMContext(msg, header, bc)
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{}) vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
gp := new(core.GasPool).AddGas(common.MaxBig) gp := new(core.GasPool).AddGas(common.MaxBig)
@ -141,7 +141,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, lc) context := core.NewEVMContext(msg, header, lc)
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{}) vmenv := vm.NewEVM(context, vmstate, config, vm.Config{})
//vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{}) //vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
gp := new(core.GasPool).AddGas(common.MaxBig) gp := new(core.GasPool).AddGas(common.MaxBig)

View file

@ -172,7 +172,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, bc) context := core.NewEVMContext(msg, header, bc)
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{}) vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
gp := new(core.GasPool).AddGas(common.MaxBig) gp := new(core.GasPool).AddGas(common.MaxBig)
ret, _, _ := core.ApplyMessage(vmenv, msg, gp) ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
@ -188,7 +188,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)} msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, lc) context := core.NewEVMContext(msg, header, lc)
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{}) vmenv := vm.NewEVM(context, vmstate, config, vm.Config{})
gp := new(core.GasPool).AddGas(common.MaxBig) gp := new(core.GasPool).AddGas(common.MaxBig)
ret, _, _ := core.ApplyMessage(vmenv, msg, gp) ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
if vmstate.Error() == nil { if vmstate.Error() == nil {

View file

@ -150,7 +150,7 @@ type VmTest struct {
PostStateRoot string PostStateRoot string
} }
func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *state.StateDB, envValues map[string]string, tx map[string]string) (*vm.Environment, core.Message) { func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *state.StateDB, envValues map[string]string, tx map[string]string) (*vm.EVM, core.Message) {
var ( var (
data = common.FromHex(tx["data"]) data = common.FromHex(tx["data"])
gas = common.Big(tx["gasLimit"]) gas = common.Big(tx["gasLimit"])
@ -210,5 +210,5 @@ func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *st
if context.GasPrice == nil { if context.GasPrice == nil {
context.GasPrice = new(big.Int) context.GasPrice = new(big.Int)
} }
return vm.NewEnvironment(context, statedb, chainConfig, vm.Config{NoRecursion: vmTest}), msg return vm.NewEVM(context, statedb, chainConfig, vm.Config{NoRecursion: vmTest}), msg
} }