Skip to content

Commit

Permalink
rpcdaemon: Split ComputeTxEnv (#12325)
Browse files Browse the repository at this point in the history
A follow up to #12316, instead of relaxing conditions on `ComputeTxEnv`
which may cause unintended edge cases, we split the function into two
smaller, well-defined functions. When tracing state sync events, we do
not care about generating TxContext so we can skip validation
surrounding it.
  • Loading branch information
shohamc1 authored Oct 18, 2024
1 parent 3126c30 commit ea2ca63
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 23 deletions.
3 changes: 1 addition & 2 deletions cmd/devnet/services/polygon/proofgenerator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,7 @@ func (rg *requestGenerator) GetTransactionReceipt(ctx context.Context, hash libc
}
defer tx.Rollback()

_, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, reader, rawdbv3.TxNums, tx, 0)

ibs, _, _, _, _, err := transactions.ComputeBlockContext(ctx, engine, block.HeaderNoCopy(), chainConfig, reader, rawdbv3.TxNums, tx, 0)
if err != nil {
return nil, err
}
Expand Down
7 changes: 6 additions & 1 deletion turbo/jsonrpc/otterscan_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,12 @@ func (api *OtterscanAPIImpl) runTracer(ctx context.Context, tx kv.Tx, hash commo
engine := api.engine()

txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, api._blockReader))
msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, api._blockReader, txNumsReader, tx, int(txIndex))
ibs, blockCtx, _, rules, signer, err := transactions.ComputeBlockContext(ctx, engine, block.HeaderNoCopy(), chainConfig, api._blockReader, txNumsReader, tx, int(txIndex))
if err != nil {
return nil, err
}

msg, txCtx, err := transactions.ComputeTxContext(ibs, engine, rules, signer, block, chainConfig, int(txIndex))
if err != nil {
return nil, err
}
Expand Down
6 changes: 4 additions & 2 deletions turbo/jsonrpc/receipts/receipts_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package receipts

import (
"context"

lru "github.com/hashicorp/golang-lru/v2"

"github.com/erigontech/erigon-lib/chain"
"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/kv"
Expand All @@ -15,7 +18,6 @@ import (
"github.com/erigontech/erigon/turbo/services"
"github.com/erigontech/erigon/turbo/snapshotsync/freezeblocks"
"github.com/erigontech/erigon/turbo/transactions"
lru "github.com/hashicorp/golang-lru/v2"
)

type Generator struct {
Expand Down Expand Up @@ -54,7 +56,7 @@ func (g *Generator) GetCachedReceipts(ctx context.Context, blockHash common.Hash

func (g *Generator) PrepareEnv(ctx context.Context, block *types.Block, cfg *chain.Config, tx kv.Tx, txIndex int) (*ReceiptEnv, error) {
txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, g.blockReader))
_, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, g.engine, block, cfg, g.blockReader, txNumsReader, tx, txIndex)
ibs, _, _, _, _, err := transactions.ComputeBlockContext(ctx, g.engine, block.HeaderNoCopy(), cfg, g.blockReader, txNumsReader, tx, txIndex)
if err != nil {
return nil, err
}
Expand Down
14 changes: 10 additions & 4 deletions turbo/jsonrpc/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,12 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp
engine := api.engine()

txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, api._blockReader))
_, blockCtx, _, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, api._blockReader, txNumsReader, tx, 0)
ibs, blockCtx, _, rules, signer, err := transactions.ComputeBlockContext(ctx, engine, block.HeaderNoCopy(), chainConfig, api._blockReader, txNumsReader, tx, 0)
if err != nil {
stream.WriteNil()
return err
}

signer := types.MakeSigner(chainConfig, block.NumberU64(), block.Time())
rules := chainConfig.Rules(block.NumberU64(), block.Time())
stream.WriteArrayStart()

txns := block.Transactions()
Expand Down Expand Up @@ -307,11 +305,12 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo
engine := api.engine()

txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, api._blockReader))
msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, api._blockReader, txNumsReader, tx, txnIndex)
ibs, blockCtx, _, rules, signer, err := transactions.ComputeBlockContext(ctx, engine, block.HeaderNoCopy(), chainConfig, api._blockReader, txNumsReader, tx, txnIndex)
if err != nil {
stream.WriteNil()
return err
}

if isBorStateSyncTxn {
return polygontracer.TraceBorStateSyncTxnDebugAPI(
ctx,
Expand All @@ -328,6 +327,13 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo
api.evmCallTimeout,
)
}

msg, txCtx, err := transactions.ComputeTxContext(ibs, engine, rules, signer, block, chainConfig, txnIndex)
if err != nil {
stream.WriteNil()
return err
}

// Trace the transaction and return
return transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream, api.evmCallTimeout)
}
Expand Down
30 changes: 16 additions & 14 deletions turbo/transactions/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ type BlockGetter interface {
GetBlock(hash libcommon.Hash, number uint64) *types.Block
}

// ComputeTxEnv returns the execution environment of a certain transaction.
func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *types.Block, cfg *chain.Config, headerReader services.HeaderReader, txNumsReader rawdbv3.TxNumsReader, dbtx kv.Tx, txIndex int) (core.Message, evmtypes.BlockContext, evmtypes.TxContext, *state.IntraBlockState, state.StateReader, error) {
reader, err := rpchelper.CreateHistoryStateReader(dbtx, txNumsReader, block.NumberU64(), txIndex, cfg.ChainName)
// ComputeBlockContext returns the execution environment of a certain block.
func ComputeBlockContext(ctx context.Context, engine consensus.EngineReader, header *types.Header, cfg *chain.Config,
headerReader services.HeaderReader, txNumsReader rawdbv3.TxNumsReader, dbtx kv.Tx,
txIndex int) (*state.IntraBlockState, evmtypes.BlockContext, state.StateReader, *chain.Rules, *types.Signer, error) {
reader, err := rpchelper.CreateHistoryStateReader(dbtx, txNumsReader, header.Number.Uint64(), txIndex, cfg.ChainName)
if err != nil {
return nil, evmtypes.BlockContext{}, evmtypes.TxContext{}, nil, nil, err
return nil, evmtypes.BlockContext{}, nil, nil, nil, err
}

// Create the parent state database
Expand All @@ -66,30 +68,30 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ
h, _ := headerReader.HeaderByNumber(ctx, dbtx, n)
return h
}
header := block.HeaderNoCopy()

blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, cfg)

if txIndex == len(block.Transactions()) {
// tx is a state sync transaction
return nil, blockContext, evmtypes.TxContext{}, statedb, nil, nil
}
rules := cfg.Rules(blockContext.BlockNumber, blockContext.Time)

// Recompute transactions up to the target index.
signer := types.MakeSigner(cfg, block.NumberU64(), block.Time())
rules := cfg.Rules(blockContext.BlockNumber, blockContext.Time)
signer := types.MakeSigner(cfg, header.Number.Uint64(), header.Time)

return statedb, blockContext, reader, rules, signer, err
}

// ComputeTxContext returns the execution environment of a certain transaction.
func ComputeTxContext(statedb *state.IntraBlockState, engine consensus.EngineReader, rules *chain.Rules, signer *types.Signer, block *types.Block, cfg *chain.Config, txIndex int) (core.Message, evmtypes.TxContext, error) {
txn := block.Transactions()[txIndex]
statedb.SetTxContext(txIndex)
msg, _ := txn.AsMessage(*signer, block.BaseFee(), rules)
if msg.FeeCap().IsZero() && engine != nil {
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
return core.SysCallContract(contract, data, cfg, statedb, header, engine, true /* constCall */)
return core.SysCallContract(contract, data, cfg, statedb, block.HeaderNoCopy(), engine, true /* constCall */)
}
msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall))
}

TxContext := core.NewEVMTxContext(msg)
return msg, blockContext, TxContext, statedb, reader, nil
return msg, TxContext, nil
}

// TraceTx configures a new tracer according to the provided configuration, and
Expand Down

0 comments on commit ea2ca63

Please sign in to comment.