aboutsummaryrefslogtreecommitdiffstats
path: root/eth
diff options
context:
space:
mode:
authorJhih-Ming Huang <jm.huang@cobinhood.com>2019-03-27 18:49:38 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:50:26 +0800
commite715414cae9b4654b4784dfb924880a0787d1d55 (patch)
treea0772b2a0ef3be4ac03fc608a21ee0b7ccbd167a /eth
parent996310cbd484b5ff1ea76068578314d71973770f (diff)
downloaddexon-e715414cae9b4654b4784dfb924880a0787d1d55.tar.gz
dexon-e715414cae9b4654b4784dfb924880a0787d1d55.tar.zst
dexon-e715414cae9b4654b4784dfb924880a0787d1d55.zip
core: vm: refactor vm config and context
To support multiple VMs, there must be a shared execution environment for each VM, so this pull request moved some shared component to vm.Context and implemented the vm.ExecPack to hold the list of VM, list of VM configures, context and some shared resources. The adjustment includes: * Move NoRecursion, Depth, ReadOnly, RandCallIndex, IntPool and CallGasTemp to Context. * Adjust VM enumeration from byte to uint8, and the VMList from map to array. * Register VM constructor in each VM package's init function. * Initialize all VM instance in NewExecPack. * Remove EVMImplement, and modify EVM, such that EVM can do the same functions with EVMImplement.
Diffstat (limited to 'eth')
-rw-r--r--eth/api_backend.go10
-rw-r--r--eth/api_tracer.go64
-rw-r--r--eth/backend.go10
-rw-r--r--eth/handler_test.go11
-rw-r--r--eth/helper_test.go9
-rw-r--r--eth/tracers/tracer_test.go20
-rw-r--r--eth/tracers/tracers_test.go12
7 files changed, 88 insertions, 48 deletions
diff --git a/eth/api_backend.go b/eth/api_backend.go
index e50f62814..8c5b8bab3 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -27,7 +27,8 @@ import (
"github.com/dexon-foundation/dexon/core/bloombits"
"github.com/dexon-foundation/dexon/core/state"
"github.com/dexon-foundation/dexon/core/types"
- vm "github.com/dexon-foundation/dexon/core/vm/evm"
+ "github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/core/vm/evm"
"github.com/dexon-foundation/dexon/eth/gasprice"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/event"
@@ -125,12 +126,13 @@ func (b *EthAPIBackend) GetTd(blockHash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(blockHash)
}
-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) (*evm.EVM, func() error, error) {
state.SetBalance(msg.From(), math.MaxBig256)
vmError := func() error { return nil }
- context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
- return vm.NewEVM(context, state, b.eth.chainConfig, *b.eth.blockchain.GetVMConfig()), vmError, nil
+ context := core.NewVMContext(msg, header, b.eth.BlockChain(), nil)
+ pack := vm.NewExecPack(context, state, b.eth.chainConfig, b.eth.blockchain.GetVMConfig())
+ return pack.VMList[vm.EVM].(*evm.EVM), vmError, nil
}
func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
diff --git a/eth/api_tracer.go b/eth/api_tracer.go
index e05bbe0a2..10f5edeb7 100644
--- a/eth/api_tracer.go
+++ b/eth/api_tracer.go
@@ -207,7 +207,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
// Trace all the transactions contained within
for i, tx := range task.block.Transactions() {
msg, _ := tx.AsMessage(signer)
- vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain, nil)
+ vmctx := core.NewVMContext(msg, task.block.Header(), api.eth.blockchain, nil)
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
if err != nil {
@@ -290,7 +290,9 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
traced += uint64(len(txs))
}
// Generate the next state snapshot fast without tracing
- _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, evm.Config{})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, vmConfig)
if err != nil {
failed = err
break
@@ -481,7 +483,7 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
// Fetch and execute the next transaction trace tasks
for task := range jobs {
msg, _ := txs[task.index].AsMessage(signer)
- vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
+ vmctx := core.NewVMContext(msg, block.Header(), api.eth.blockchain, nil)
res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config)
if err != nil {
@@ -500,16 +502,17 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
// Generate the next state snapshot fast without tracing
msg, _ := tx.AsMessage(signer)
- vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
-
- vmenv := evm.NewEVM(vmctx, statedb, api.config, evm.Config{})
- if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
+ vmctx := core.NewVMContext(msg, block.Header(), api.eth.blockchain, nil)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ pack := vm.NewExecPack(vmctx, statedb, api.config, vmConfig)
+ if _, _, _, err := core.ApplyMessage(&pack, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
failed = err
break
}
// Finalize the state so any modifications are written to the trie
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
+ statedb.Finalise(pack.ChainConfig.IsEIP158(block.Number()))
}
close(jobs)
pend.Wait()
@@ -575,7 +578,7 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
// Prepare the trasaction for un-traced execution
var (
msg, _ = tx.AsMessage(signer)
- vmctx = core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
+ vmctx = core.NewVMContext(msg, block.Header(), api.eth.blockchain, nil)
vmConf evm.Config
dump *os.File
@@ -600,8 +603,10 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
}
}
// Execute the transaction and flush any traces to disk
- vmenv := evm.NewEVM(vmctx, statedb, api.config, vmConf)
- _, _, _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
+ vmConfigs := [vm.NUMS]interface{}{}
+ vmConfigs[vm.EVM] = vmConf
+ pack := vm.NewExecPack(vmctx, statedb, api.config, vmConfigs)
+ _, _, _, err = core.ApplyMessage(&pack, msg, new(core.GasPool).AddGas(msg.Gas()))
if dump != nil {
dump.Close()
@@ -612,7 +617,7 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
}
// Finalize the state so any modifications are written to the trie
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
+ statedb.Finalise(pack.ChainConfig.IsEIP158(block.Number()))
// If we've traced the transaction we were looking for, abort
if tx.Hash() == txHash {
@@ -668,7 +673,9 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
if block = api.eth.blockchain.GetBlockByNumber(block.NumberU64() + 1); block == nil {
return nil, fmt.Errorf("block #%d not found", block.NumberU64()+1)
}
- _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, evm.Config{})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, vmConfig)
if err != nil {
return nil, fmt.Errorf("processing block %d failed: %v", block.NumberU64(), err)
}
@@ -714,7 +721,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha
// traceTx configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment. The return value will
// be tracer dependent.
-func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx vm.Context, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
+func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx *vm.Context, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
// Assemble the structured logger or the JavaScript tracer
var (
tracer evm.Tracer
@@ -748,9 +755,11 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
tracer = evm.NewStructLogger(config.LogConfig)
}
// Run the transaction with tracing enabled.
- vmenv := evm.NewEVM(vmctx, statedb, api.config, evm.Config{Debug: true, Tracer: tracer})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{Tracer: tracer, Debug: true}
+ pack := vm.NewExecPack(vmctx, statedb, api.config, vmConfig)
- ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
+ ret, gas, failed, err := core.ApplyMessage(&pack, message, new(core.GasPool).AddGas(message.Gas()))
if err != nil {
return nil, fmt.Errorf("tracing failed: %v", err)
}
@@ -773,19 +782,19 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
}
// computeTxEnv returns the execution environment of a certain transaction.
-func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, error) {
+func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, reexec uint64) (core.Message, *vm.Context, *state.StateDB, error) {
// Create the parent state database
block := api.eth.blockchain.GetBlockByHash(blockHash)
if block == nil {
- return nil, vm.Context{}, nil, fmt.Errorf("block %#x not found", blockHash)
+ return nil, nil, nil, fmt.Errorf("block %#x not found", blockHash)
}
parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
if parent == nil {
- return nil, vm.Context{}, nil, fmt.Errorf("parent %#x not found", block.ParentHash())
+ return nil, nil, nil, fmt.Errorf("parent %#x not found", block.ParentHash())
}
statedb, err := api.computeStateDB(parent, reexec)
if err != nil {
- return nil, vm.Context{}, nil, err
+ return nil, nil, nil, err
}
// Recompute transactions up to the target index.
signer := types.MakeSigner(api.config, block.Number())
@@ -793,18 +802,21 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
for idx, tx := range block.Transactions() {
// Assemble the transaction call message and return if the requested offset
msg, _ := tx.AsMessage(signer)
- context := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
+ context := core.NewVMContext(msg, block.Header(), api.eth.blockchain, nil)
if idx == txIndex {
return msg, context, statedb, nil
}
// Not yet the searched for transaction, execute on top of the current state
- vmenv := evm.NewEVM(context, statedb, api.config, evm.Config{})
- 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)
+
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ pack := vm.NewExecPack(context, statedb, api.config, vmConfig)
+ if _, _, _, err := core.ApplyMessage(&pack, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
+ return nil, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
}
// Ensure any modifications are committed to the state
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
+ statedb.Finalise(pack.ChainConfig.IsEIP158(block.Number()))
}
- return nil, vm.Context{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, blockHash)
+ return nil, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, blockHash)
}
diff --git a/eth/backend.go b/eth/backend.go
index 815049251..09c1b0925 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -35,7 +35,8 @@ import (
"github.com/dexon-foundation/dexon/core/bloombits"
"github.com/dexon-foundation/dexon/core/rawdb"
"github.com/dexon-foundation/dexon/core/types"
- vm "github.com/dexon-foundation/dexon/core/vm/evm"
+ "github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/core/vm/evm"
"github.com/dexon-foundation/dexon/eth/downloader"
"github.com/dexon-foundation/dexon/eth/filters"
"github.com/dexon-foundation/dexon/eth/gasprice"
@@ -151,14 +152,17 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion)
}
var (
- vmConfig = vm.Config{
+ vmConfig = evm.Config{
EnablePreimageRecording: config.EnablePreimageRecording,
EWASMInterpreter: config.EWASMInterpreter,
EVMInterpreter: config.EVMInterpreter,
}
cacheConfig = &core.CacheConfig{Disabled: config.NoPruning, TrieCleanLimit: config.TrieCleanCache, TrieDirtyLimit: config.TrieDirtyCache, TrieTimeLimit: config.TrieTimeout}
)
- eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig, eth.shouldPreserve)
+
+ vmConfigs := [vm.NUMS]interface{}{}
+ vmConfigs[vm.EVM] = vmConfig
+ eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfigs, eth.shouldPreserve)
if err != nil {
return nil, err
}
diff --git a/eth/handler_test.go b/eth/handler_test.go
index 4041fbe59..a6bc31554 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -29,7 +29,8 @@ import (
"github.com/dexon-foundation/dexon/core"
"github.com/dexon-foundation/dexon/core/state"
"github.com/dexon-foundation/dexon/core/types"
- vm "github.com/dexon-foundation/dexon/core/vm/evm"
+ "github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/core/vm/evm"
"github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/eth/downloader"
"github.com/dexon-foundation/dexon/ethdb"
@@ -474,7 +475,9 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
gspec = &core.Genesis{Config: config}
genesis = gspec.MustCommit(db)
)
- blockchain, err := core.NewBlockChain(db, nil, config, pow, vm.Config{}, nil)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ blockchain, err := core.NewBlockChain(db, nil, config, pow, vmConfig, nil)
if err != nil {
t.Fatalf("failed to create new blockchain: %v", err)
}
@@ -555,7 +558,9 @@ func testBroadcastBlock(t *testing.T, totalPeers, broadcastExpected int) {
gspec = &core.Genesis{Config: config}
genesis = gspec.MustCommit(db)
)
- blockchain, err := core.NewBlockChain(db, nil, config, pow, vm.Config{}, nil)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ blockchain, err := core.NewBlockChain(db, nil, config, pow, vmConfig, nil)
if err != nil {
t.Fatalf("failed to create new blockchain: %v", err)
}
diff --git a/eth/helper_test.go b/eth/helper_test.go
index 7b2de4574..a3e928842 100644
--- a/eth/helper_test.go
+++ b/eth/helper_test.go
@@ -31,7 +31,8 @@ import (
"github.com/dexon-foundation/dexon/consensus/ethash"
"github.com/dexon-foundation/dexon/core"
"github.com/dexon-foundation/dexon/core/types"
- vm "github.com/dexon-foundation/dexon/core/vm/evm"
+ "github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/core/vm/evm"
"github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/eth/downloader"
"github.com/dexon-foundation/dexon/ethdb"
@@ -58,9 +59,11 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
Config: params.TestChainConfig,
Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}},
}
- genesis = gspec.MustCommit(db)
- blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil)
+ genesis = gspec.MustCommit(db)
)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{}
+ blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vmConfig, nil)
chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, generator)
if _, err := blockchain.InsertChain(chain); err != nil {
panic(err)
diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go
index 42343f91a..6d2c87088 100644
--- a/eth/tracers/tracer_test.go
+++ b/eth/tracers/tracer_test.go
@@ -52,12 +52,17 @@ type dummyStatedb struct {
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
func runTrace(tracer *Tracer) (json.RawMessage, error) {
- env := evm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, evm.Config{Debug: true, Tracer: tracer})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{Tracer: tracer, Debug: true}
+ vmctx := &vm.Context{BlockNumber: big.NewInt(1)}
+ pack := vm.NewExecPack(vmctx, &dummyStatedb{}, params.TestChainConfig, vmConfig)
+ e := pack.VMList[vm.EVM].(*evm.EVM)
+ interpreter := evm.NewEVMInterpreter(e, e.VMConfig())
contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000)
contract.Code = []byte{byte(evm.PUSH1), 0x1, byte(evm.PUSH1), 0x1, 0x0}
- _, err := env.Interpreter().Run(contract, []byte{}, false)
+ _, err := interpreter.Run(contract, []byte{}, false)
if err != nil {
return nil, err
}
@@ -134,13 +139,18 @@ func TestHaltBetweenSteps(t *testing.T) {
t.Fatal(err)
}
- env := evm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, evm.Config{Debug: true, Tracer: tracer})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{Tracer: tracer, Debug: true}
+ vmctx := &vm.Context{BlockNumber: big.NewInt(1)}
+ pack := vm.NewExecPack(vmctx, &dummyStatedb{}, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*evm.EVM)
+
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0)
- tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil)
+ tracer.CaptureState(evm, 0, 0, 0, 0, nil, nil, contract, 0, nil)
timeout := errors.New("stahp")
tracer.Stop(timeout)
- tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil)
+ tracer.CaptureState(evm, 0, 0, 0, 0, nil, nil, contract, 0, nil)
if _, err := tracer.GetResult(); err.Error() != timeout.Error() {
t.Errorf("Expected timeout error, got %v", err)
diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go
index 0e41a6dd3..3ee12dd7f 100644
--- a/eth/tracers/tracers_test.go
+++ b/eth/tracers/tracers_test.go
@@ -179,13 +179,15 @@ func TestPrestateTracerCreate2(t *testing.T) {
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
- evm := evm.NewEVM(context, statedb, params.MainnetChainConfig, evm.Config{Debug: true, Tracer: tracer})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{Tracer: tracer, Debug: true}
+ pack := vm.NewExecPack(&context, statedb, params.MainnetChainConfig, vmConfig)
msg, err := tx.AsMessage(signer)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
+ st := core.NewStateTransition(&pack, msg, new(core.GasPool).AddGas(tx.Gas()))
core.TestingMode = true
if _, _, _, err = st.TransitionDb(); err != nil {
t.Fatalf("failed to execute transaction: %v", err)
@@ -287,12 +289,14 @@ func TestCallTracer(t *testing.T) {
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
- evm := evm.NewEVM(context, statedb, test.Genesis.Config, evm.Config{Debug: true, Tracer: tracer})
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = evm.Config{Tracer: tracer, Debug: true}
+ pack := vm.NewExecPack(&context, statedb, test.Genesis.Config, vmConfig)
msg, err := tx.AsMessage(signer)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
+ st := core.NewStateTransition(&pack, msg, new(core.GasPool).AddGas(tx.Gas()))
if _, _, _, err = st.TransitionDb(); err != nil {
t.Fatalf("failed to execute transaction: %v", err)
}