mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
all: Add an error return value to NewEVM
This commit is contained in:
parent
f0233948d2
commit
3ac4b5f6b7
16 changed files with 135 additions and 48 deletions
|
|
@ -304,7 +304,10 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
|
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
|
||||||
// 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.NewEVM(evmContext, statedb, b.config, vm.Config{})
|
vmenv, err := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, false, err
|
||||||
|
}
|
||||||
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
|
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
|
|
||||||
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,10 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
||||||
context := NewEVMContext(msg, header, bc, author)
|
context := NewEVMContext(msg, header, bc, author)
|
||||||
// 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.NewEVM(context, statedb, config, cfg)
|
vmenv, err := vm.NewEVM(context, statedb, config, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
// Apply the transaction to the current state (included in the env)
|
// Apply the transaction to the current state (included in the env)
|
||||||
_, gas, failed, err := ApplyMessage(vmenv, msg, gp)
|
_, gas, failed, err := ApplyMessage(vmenv, msg, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ type EVM struct {
|
||||||
|
|
||||||
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
|
||||||
// only ever be used *once*.
|
// only ever be used *once*.
|
||||||
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
|
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) (*EVM, error) {
|
||||||
evm := &EVM{
|
evm := &EVM{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
|
|
@ -160,7 +160,7 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
|
||||||
evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
|
evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
|
||||||
evm.interpreter = evm.interpreters[0]
|
evm.interpreter = evm.interpreters[0]
|
||||||
|
|
||||||
return evm
|
return evm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel cancels any running EVM operation. This may be called concurrently and
|
// Cancel cancels any running EVM operation. This may be called concurrently and
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,12 @@ type twoOperandTest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) {
|
func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) {
|
||||||
|
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating the EVM object: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
pc = uint64(0)
|
pc = uint64(0)
|
||||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||||
|
|
@ -74,8 +78,11 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestByteOp(t *testing.T) {
|
func TestByteOp(t *testing.T) {
|
||||||
|
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating the EVM object: %v", err)
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||||
)
|
)
|
||||||
|
|
@ -209,8 +216,11 @@ func TestSLT(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func opBenchmark(bench *testing.B, op func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) {
|
func opBenchmark(bench *testing.B, op func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) {
|
||||||
|
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
bench.Fatalf("error creating the EVM object: %v", err)
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||||
)
|
)
|
||||||
|
|
@ -444,8 +454,11 @@ func BenchmarkOpIsZero(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOpMstore(t *testing.T) {
|
func TestOpMstore(t *testing.T) {
|
||||||
|
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating the EVM object: %v", err)
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||||
|
|
@ -470,8 +483,11 @@ func TestOpMstore(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkOpMstore(bench *testing.B) {
|
func BenchmarkOpMstore(bench *testing.B) {
|
||||||
|
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
bench.Fatalf("error creating the EVM object: %v", err)
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||||
|
|
@ -493,8 +509,11 @@ func BenchmarkOpMstore(bench *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkOpSHA3(bench *testing.B) {
|
func BenchmarkOpSHA3(bench *testing.B) {
|
||||||
|
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
bench.Fatalf("error creating the EVM object: %v", err)
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
|
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,12 @@ type dummyStatedb struct {
|
||||||
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
||||||
|
|
||||||
func TestStoreCapture(t *testing.T) {
|
func TestStoreCapture(t *testing.T) {
|
||||||
|
env, err := NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create an EVM: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
env = NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{})
|
|
||||||
logger = NewStructLogger(nil)
|
logger = NewStructLogger(nil)
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewEnv(cfg *Config) *vm.EVM {
|
func NewEnv(cfg *Config) (*vm.EVM, error) {
|
||||||
context := vm.Context{
|
context := vm.Context{
|
||||||
CanTransfer: core.CanTransfer,
|
CanTransfer: core.CanTransfer,
|
||||||
Transfer: core.Transfer,
|
Transfer: core.Transfer,
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,12 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
address = common.BytesToAddress([]byte("contract"))
|
address = common.BytesToAddress([]byte("contract"))
|
||||||
vmenv = NewEnv(cfg)
|
|
||||||
sender = vm.AccountRef(cfg.Origin)
|
sender = vm.AccountRef(cfg.Origin)
|
||||||
)
|
)
|
||||||
|
vmenv, err := NewEnv(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
cfg.State.CreateAccount(address)
|
cfg.State.CreateAccount(address)
|
||||||
// set the receiver's (the executing contract) code for execution.
|
// set the receiver's (the executing contract) code for execution.
|
||||||
cfg.State.SetCode(address, code)
|
cfg.State.SetCode(address, code)
|
||||||
|
|
@ -131,10 +134,13 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
|
||||||
}
|
}
|
||||||
var (
|
|
||||||
vmenv = NewEnv(cfg)
|
sender := vm.AccountRef(cfg.Origin)
|
||||||
sender = vm.AccountRef(cfg.Origin)
|
|
||||||
)
|
vmenv, err := NewEnv(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, common.Address{}, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
// Call the code with the given configuration.
|
// Call the code with the given configuration.
|
||||||
code, address, leftOverGas, err := vmenv.Create(
|
code, address, leftOverGas, err := vmenv.Create(
|
||||||
|
|
@ -154,7 +160,10 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) {
|
func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
vmenv := NewEnv(cfg)
|
vmenv, err := NewEnv(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
sender := cfg.State.GetOrNewStateObject(cfg.Origin)
|
sender := cfg.State.GetOrNewStateObject(cfg.Origin)
|
||||||
// Call the code with the given configuration.
|
// Call the code with the given configuration.
|
||||||
|
|
|
||||||
|
|
@ -125,12 +125,14 @@ func (b *EthAPIBackend) GetTd(blockHash common.Hash) *big.Int {
|
||||||
return b.eth.blockchain.GetTdByHash(blockHash)
|
return b.eth.blockchain.GetTdByHash(blockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEVM creates a new EVM object
|
||||||
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
||||||
state.SetBalance(msg.From(), math.MaxBig256)
|
state.SetBalance(msg.From(), math.MaxBig256)
|
||||||
vmError := func() error { return nil }
|
vmError := func() error { return nil }
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
|
context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
|
||||||
return vm.NewEVM(context, state, b.eth.chainConfig, *b.eth.blockchain.GetVMConfig()), vmError, nil
|
evm, err := vm.NewEVM(context, state, b.eth.chainConfig, *b.eth.blockchain.GetVMConfig())
|
||||||
|
return evm, vmError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,10 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
||||||
msg, _ := tx.AsMessage(signer)
|
msg, _ := tx.AsMessage(signer)
|
||||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||||
|
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{})
|
vmenv, err := vm.NewEVM(vmctx, statedb, api.config, vm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
break
|
break
|
||||||
|
|
@ -595,7 +598,10 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Execute the transaction and flush any traces to disk
|
// Execute the transaction and flush any traces to disk
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, api.config, vmConf)
|
vmenv, err := vm.NewEVM(vmctx, statedb, api.config, vmConf)
|
||||||
|
if err != nil {
|
||||||
|
return dumps, err
|
||||||
|
}
|
||||||
_, _, _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
|
_, _, _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
|
||||||
if writer != nil {
|
if writer != nil {
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
|
|
@ -756,7 +762,10 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
||||||
tracer = vm.NewStructLogger(config.LogConfig)
|
tracer = vm.NewStructLogger(config.LogConfig)
|
||||||
}
|
}
|
||||||
// Run the transaction with tracing enabled.
|
// Run the transaction with tracing enabled.
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
vmenv, err := vm.NewEVM(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("EVM creation failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
|
ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -806,7 +815,10 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
|
||||||
return msg, context, statedb, nil
|
return msg, context, statedb, nil
|
||||||
}
|
}
|
||||||
// Not yet the searched for transaction, execute on top of the current state
|
// Not yet the searched for transaction, execute on top of the current state
|
||||||
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{})
|
vmenv, err := vm.NewEVM(context, statedb, api.config, vm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, vm.Context{}, nil, fmt.Errorf("EVM creation failed: %v", err)
|
||||||
|
}
|
||||||
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||||
return nil, vm.Context{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
return nil, vm.Context{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,15 @@ type dummyStatedb struct {
|
||||||
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
||||||
|
|
||||||
func runTrace(tracer *Tracer) (json.RawMessage, error) {
|
func runTrace(tracer *Tracer) (json.RawMessage, error) {
|
||||||
env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
env, err := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000)
|
contract := vm.NewContract(account{}, account{}, big.NewInt(0), 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.Interpreter().Run(contract, []byte{}, false)
|
_, err = env.Interpreter().Run(contract, []byte{}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +136,10 @@ func TestHaltBetweenSteps(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
env, err := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating EVM object: %v", err)
|
||||||
|
}
|
||||||
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0)
|
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0)
|
||||||
|
|
||||||
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil)
|
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil)
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,10 @@ func TestPrestateTracerCreate2(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
evm, err := vm.NewEVM(context, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create EVM: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
msg, err := tx.AsMessage(signer)
|
msg, err := tx.AsMessage(signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -247,7 +250,10 @@ func TestCallTracer(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
evm, err := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create EVM: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
msg, err := tx.AsMessage(signer)
|
msg, err := tx.AsMessage(signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,12 @@ func (b *LesApiBackend) GetTd(hash common.Hash) *big.Int {
|
||||||
return b.eth.blockchain.GetTdByHash(hash)
|
return b.eth.blockchain.GetTdByHash(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEVM creates a new EVM object
|
||||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
|
||||||
state.SetBalance(msg.From(), math.MaxBig256)
|
state.SetBalance(msg.From(), math.MaxBig256)
|
||||||
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
|
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
|
||||||
return vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{}), state.Error, nil
|
vm, err := vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{})
|
||||||
|
return vm, state.Error, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,13 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte
|
type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) ([]byte, error)
|
||||||
|
|
||||||
func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) }
|
func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) }
|
||||||
|
|
||||||
func TestOdrGetBlockLes2(t *testing.T) { testOdr(t, 2, 1, odrGetBlock) }
|
func TestOdrGetBlockLes2(t *testing.T) { testOdr(t, 2, 1, odrGetBlock) }
|
||||||
|
|
||||||
func odrGetBlock(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrGetBlock(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) ([]byte, error) {
|
||||||
var block *types.Block
|
var block *types.Block
|
||||||
if bc != nil {
|
if bc != nil {
|
||||||
block = bc.GetBlockByHash(bhash)
|
block = bc.GetBlockByHash(bhash)
|
||||||
|
|
@ -50,17 +50,17 @@ func odrGetBlock(ctx context.Context, db ethdb.Database, config *params.ChainCon
|
||||||
block, _ = lc.GetBlockByHash(ctx, bhash)
|
block, _ = lc.GetBlockByHash(ctx, bhash)
|
||||||
}
|
}
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
rlp, _ := rlp.EncodeToBytes(block)
|
rlp, _ := rlp.EncodeToBytes(block)
|
||||||
return rlp
|
return rlp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, 1, odrGetReceipts) }
|
func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, 1, odrGetReceipts) }
|
||||||
|
|
||||||
func TestOdrGetReceiptsLes2(t *testing.T) { testOdr(t, 2, 1, odrGetReceipts) }
|
func TestOdrGetReceiptsLes2(t *testing.T) { testOdr(t, 2, 1, odrGetReceipts) }
|
||||||
|
|
||||||
func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) ([]byte, error) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
if bc != nil {
|
if bc != nil {
|
||||||
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
|
||||||
|
|
@ -72,17 +72,17 @@ func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.Chain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if receipts == nil {
|
if receipts == nil {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
rlp, _ := rlp.EncodeToBytes(receipts)
|
rlp, _ := rlp.EncodeToBytes(receipts)
|
||||||
return rlp
|
return rlp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, 1, odrAccounts) }
|
func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, 1, odrAccounts) }
|
||||||
|
|
||||||
func TestOdrAccountsLes2(t *testing.T) { testOdr(t, 2, 1, odrAccounts) }
|
func TestOdrAccountsLes2(t *testing.T) { testOdr(t, 2, 1, odrAccounts) }
|
||||||
|
|
||||||
func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) ([]byte, error) {
|
||||||
dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678")
|
dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678")
|
||||||
acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr}
|
acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr}
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainCon
|
||||||
res = append(res, rlp...)
|
res = append(res, rlp...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOdrContractCallLes1(t *testing.T) { testOdr(t, 1, 2, odrContractCall) }
|
func TestOdrContractCallLes1(t *testing.T) { testOdr(t, 1, 2, odrContractCall) }
|
||||||
|
|
@ -118,7 +118,7 @@ type callmsg struct {
|
||||||
|
|
||||||
func (callmsg) CheckNonce() bool { return false }
|
func (callmsg) CheckNonce() bool { return false }
|
||||||
|
|
||||||
func odrContractCall(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
func odrContractCall(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) ([]byte, error) {
|
||||||
data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000")
|
data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000")
|
||||||
|
|
||||||
var res []byte
|
var res []byte
|
||||||
|
|
@ -135,7 +135,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, bc, nil)
|
context := core.NewEVMContext(msg, header, bc, nil)
|
||||||
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
vmenv, err := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
//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(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
|
|
@ -148,7 +151,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
state.SetBalance(testBankAddress, math.MaxBig256)
|
state.SetBalance(testBankAddress, math.MaxBig256)
|
||||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false)}
|
||||||
context := core.NewEVMContext(msg, header, lc, nil)
|
context := core.NewEVMContext(msg, header, lc, nil)
|
||||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
vmenv, err := vm.NewEVM(context, state, config, vm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
if state.Error() == nil {
|
if state.Error() == nil {
|
||||||
|
|
@ -156,7 +162,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// testOdr tests odr requests whose validation guaranteed by block headers.
|
// testOdr tests odr requests whose validation guaranteed by block headers.
|
||||||
|
|
@ -169,11 +175,17 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
||||||
test := func(expFail uint64) {
|
test := func(expFail uint64) {
|
||||||
for i := uint64(0); i <= server.pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
for i := uint64(0); i <= server.pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
||||||
bhash := rawdb.ReadCanonicalHash(server.db, i)
|
bhash := rawdb.ReadCanonicalHash(server.db, i)
|
||||||
b1 := fn(light.NoOdr, server.db, server.pm.chainConfig, server.pm.blockchain.(*core.BlockChain), nil, bhash)
|
b1, err := fn(light.NoOdr, server.db, server.pm.chainConfig, server.pm.blockchain.(*core.BlockChain), nil, bhash)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error executing test function: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
b2 := fn(ctx, client.db, client.pm.chainConfig, nil, client.pm.blockchain.(*light.LightChain), bhash)
|
b2, err := fn(ctx, client.db, client.pm.chainConfig, nil, client.pm.blockchain.(*light.LightChain), bhash)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error executing test function: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
eq := bytes.Equal(b1, b2)
|
eq := bytes.Equal(b1, b2)
|
||||||
exp := i < expFail
|
exp := i < expFail
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,10 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
st.SetBalance(testBankAddress, math.MaxBig256)
|
||||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false)}
|
||||||
context := core.NewEVMContext(msg, header, chain, nil)
|
context := core.NewEVMContext(msg, header, chain, nil)
|
||||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
vmenv, err := vm.NewEVM(context, st, config, vm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,10 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
||||||
}
|
}
|
||||||
context := core.NewEVMContext(msg, block.Header(), nil, &t.json.Env.Coinbase)
|
context := core.NewEVMContext(msg, block.Header(), nil, &t.json.Env.Coinbase)
|
||||||
context.GetHash = vmTestBlockHash
|
context.GetHash = vmTestBlockHash
|
||||||
evm := vm.NewEVM(context, statedb, config, vmconfig)
|
evm, err := vm.NewEVM(context, statedb, config, vmconfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
gaspool := new(core.GasPool)
|
gaspool := new(core.GasPool)
|
||||||
gaspool.AddGas(block.GasLimit())
|
gaspool.AddGas(block.GasLimit())
|
||||||
|
|
|
||||||
|
|
@ -115,12 +115,15 @@ func (t *VMTest) Run(vmconfig vm.Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) {
|
func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) {
|
||||||
evm := t.newEVM(statedb, vmconfig)
|
evm, err := t.newEVM(statedb, vmconfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
e := t.json.Exec
|
e := t.json.Exec
|
||||||
return evm.Call(vm.AccountRef(e.Caller), e.Address, e.Data, e.GasLimit, e.Value)
|
return evm.Call(vm.AccountRef(e.Caller), e.Address, e.Data, e.GasLimit, e.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM {
|
func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) (*vm.EVM, error) {
|
||||||
initialCall := true
|
initialCall := true
|
||||||
canTransfer := func(db vm.StateDB, address common.Address, amount *big.Int) bool {
|
canTransfer := func(db vm.StateDB, address common.Address, amount *big.Int) bool {
|
||||||
if initialCall {
|
if initialCall {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue