mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd/evm/internal/t8ntool: use transaction iterator instead of list
This commit is contained in:
parent
efcb866643
commit
463bd9f076
3 changed files with 56 additions and 17 deletions
|
|
@ -116,8 +116,8 @@ type rejectedTx struct {
|
||||||
|
|
||||||
// Apply applies a set of transactions to a pre-state
|
// Apply applies a set of transactions to a pre-state
|
||||||
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
txs types.Transactions, miningReward int64,
|
txIt txIterator, miningReward int64,
|
||||||
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, error) {
|
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error)) (*state.StateDB, *ExecutionResult, []byte, error) {
|
||||||
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
|
||||||
// required blockhashes
|
// required blockhashes
|
||||||
var hashError error
|
var hashError error
|
||||||
|
|
@ -190,7 +190,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
||||||
}
|
}
|
||||||
var blobGasUsed uint64
|
var blobGasUsed uint64
|
||||||
for i, tx := range txs {
|
|
||||||
|
for i := 0; txIt.Next(); i++ {
|
||||||
|
tx, err := txIt.Tx()
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("rejected tx", "index", i, "error", err)
|
||||||
|
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
||||||
|
continue
|
||||||
|
}
|
||||||
if tx.Type() == types.BlobTxType && vmContext.BlobBaseFee == nil {
|
if tx.Type() == types.BlobTxType && vmContext.BlobBaseFee == nil {
|
||||||
errMsg := "blob tx used but field env.ExcessBlobGas missing"
|
errMsg := "blob tx used but field env.ExcessBlobGas missing"
|
||||||
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", errMsg)
|
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", errMsg)
|
||||||
|
|
@ -208,7 +215,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
}
|
}
|
||||||
tracer, err := getTracerFn(txIndex, tx.Hash())
|
tracer, err := getTracerFn(txIndex, tx.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
vmConfig.Tracer = tracer
|
vmConfig.Tracer = tracer
|
||||||
statedb.SetTxContext(tx.Hash(), txIndex)
|
statedb.SetTxContext(tx.Hash(), txIndex)
|
||||||
|
|
@ -231,7 +238,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
}
|
}
|
||||||
includedTxs = append(includedTxs, tx)
|
includedTxs = append(includedTxs, tx)
|
||||||
if hashError != nil {
|
if hashError != nil {
|
||||||
return nil, nil, NewError(ErrorMissingBlockhash, hashError)
|
return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError)
|
||||||
}
|
}
|
||||||
gasUsed += msgResult.UsedGas
|
gasUsed += msgResult.UsedGas
|
||||||
|
|
||||||
|
|
@ -306,7 +313,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
// Commit block
|
// Commit block
|
||||||
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
|
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
|
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
|
||||||
}
|
}
|
||||||
execRs := &ExecutionResult{
|
execRs := &ExecutionResult{
|
||||||
StateRoot: root,
|
StateRoot: root,
|
||||||
|
|
@ -332,9 +339,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
// for accessing latest states.
|
// for accessing latest states.
|
||||||
statedb, err = state.New(root, statedb.Database(), nil)
|
statedb, err = state.New(root, statedb.Database(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
|
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
|
||||||
}
|
}
|
||||||
return statedb, execRs, nil
|
body, _ := rlp.EncodeToBytes(includedTxs)
|
||||||
|
return statedb, execRs, body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB {
|
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
"github.com/ethereum/go-ethereum/tests"
|
"github.com/ethereum/go-ethereum/tests"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
@ -144,7 +143,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
// Check if anything needs to be read from stdin
|
// Check if anything needs to be read from stdin
|
||||||
var (
|
var (
|
||||||
prestate Prestate
|
prestate Prestate
|
||||||
txs types.Transactions // txs to apply
|
txIt txIterator // txs to apply
|
||||||
allocStr = ctx.String(InputAllocFlag.Name)
|
allocStr = ctx.String(InputAllocFlag.Name)
|
||||||
|
|
||||||
envStr = ctx.String(InputEnvFlag.Name)
|
envStr = ctx.String(InputEnvFlag.Name)
|
||||||
|
|
@ -189,7 +188,7 @@ func Transition(ctx *cli.Context) error {
|
||||||
// Set the chain id
|
// Set the chain id
|
||||||
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
||||||
|
|
||||||
if txs, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil {
|
if txIt, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
|
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
|
||||||
|
|
@ -205,11 +204,10 @@ func Transition(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Run the test and aggregate the result
|
// Run the test and aggregate the result
|
||||||
s, result, err := prestate.Apply(vmConfig, chainConfig, txs, ctx.Int64(RewardFlag.Name), getTracer)
|
s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name), getTracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
body, _ := rlp.EncodeToBytes(txs)
|
|
||||||
// Dump the excution result
|
// Dump the excution result
|
||||||
collector := make(Alloc)
|
collector := make(Alloc)
|
||||||
s.DumpToCollector(collector, nil)
|
s.DumpToCollector(collector, nil)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// txWithKey is a helper-struct, to allow us to use the types.Transaction along with
|
// txWithKey is a helper-struct, to allow us to use the types.Transaction along with
|
||||||
|
|
@ -110,7 +111,7 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran
|
||||||
return signedTxs, nil
|
return signedTxs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (types.Transactions, error) {
|
func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (txIterator, error) {
|
||||||
var txsWithKeys []*txWithKey
|
var txsWithKeys []*txWithKey
|
||||||
var signed types.Transactions
|
var signed types.Transactions
|
||||||
if txStr != stdinSelector {
|
if txStr != stdinSelector {
|
||||||
|
|
@ -127,7 +128,7 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa
|
||||||
if err := rlp.DecodeBytes(body, &signed); err != nil {
|
if err := rlp.DecodeBytes(body, &signed); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return signed, nil
|
return newArrayIterator(signed), err
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, &txsWithKeys); err != nil {
|
if err := json.Unmarshal(data, &txsWithKeys); err != nil {
|
||||||
return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
|
return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err))
|
||||||
|
|
@ -140,12 +141,44 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa
|
||||||
if err := rlp.DecodeBytes(body, &signed); err != nil {
|
if err := rlp.DecodeBytes(body, &signed); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return signed, nil
|
return newArrayIterator(signed), nil
|
||||||
}
|
}
|
||||||
// JSON encoded transactions
|
// JSON encoded transactions
|
||||||
txsWithKeys = inputData.Txs
|
txsWithKeys = inputData.Txs
|
||||||
}
|
}
|
||||||
// We may have to sign the transactions.
|
// We may have to sign the transactions.
|
||||||
signer := types.LatestSignerForChainID(chainConfig.ChainID)
|
signer := types.LatestSignerForChainID(chainConfig.ChainID)
|
||||||
return signUnsignedTransactions(txsWithKeys, signer)
|
txs, err := signUnsignedTransactions(txsWithKeys, signer)
|
||||||
|
return newArrayIterator(txs), err
|
||||||
|
}
|
||||||
|
|
||||||
|
type txIterator interface {
|
||||||
|
// Next returns true until EOF
|
||||||
|
Next() bool
|
||||||
|
// Tx returns the next transaction, OR an error.
|
||||||
|
Tx() (*types.Transaction, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type arrayIterator struct {
|
||||||
|
idx int
|
||||||
|
txs types.Transactions
|
||||||
|
}
|
||||||
|
|
||||||
|
func newArrayIterator(transactions types.Transactions) *arrayIterator {
|
||||||
|
return &arrayIterator{0, transactions}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ait *arrayIterator) Next() bool {
|
||||||
|
if ait.idx < len(ait.txs) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ait *arrayIterator) Tx() (*types.Transaction, error) {
|
||||||
|
if ait.idx < len(ait.txs) {
|
||||||
|
ait.idx++
|
||||||
|
return ait.txs[ait.idx-1], nil
|
||||||
|
}
|
||||||
|
return nil, io.EOF
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue