all: Add an error return value to NewEVM

This commit is contained in:
Guillaume Ballet 2019-02-27 13:10:26 +01:00
parent f0233948d2
commit 3ac4b5f6b7
16 changed files with 135 additions and 48 deletions

View file

@ -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()

View file

@ -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 {

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -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,

View file

@ -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.

View file

@ -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 {

View file

@ -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)
} }

View file

@ -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)

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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...)

View file

@ -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())

View file

@ -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 {