Skip to content

Commit

Permalink
Merge branch 'omerfirmak/tx-by-tx-tracer' of github.com:scroll-tech/g…
Browse files Browse the repository at this point in the history
…o-ethereum into omerfirmak/tx-by-tx-tracer
  • Loading branch information
lispc committed Sep 6, 2024
2 parents bc10f28 + 38f3582 commit 604e8a1
Show file tree
Hide file tree
Showing 58 changed files with 3,114 additions and 635 deletions.
1 change: 1 addition & 0 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) IsL1MessageTx() bool { return false }
func (m callMsg) TxSize() common.StorageSize { return 0 }

// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ var (
utils.L1ConfirmationsFlag,
utils.L1DeploymentBlockFlag,
utils.CircuitCapacityCheckEnabledFlag,
utils.CircuitCapacityCheckWorkersFlag,
utils.RollupVerifyEnabledFlag,
utils.ShadowforkPeersFlag,
}
Expand Down Expand Up @@ -440,6 +441,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) {
// Set the gas price to the limits from the CLI and start mining
gasprice := utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
ethBackend.TxPool().SetGasPrice(gasprice)
ethBackend.TxPool().SetIsMiner(true)
// start mining
threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name)
if err := ethBackend.StartMining(threads); err != nil {
Expand Down
16 changes: 16 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"math/big"
"os"
"path/filepath"
"runtime"
godebug "runtime/debug"
"strconv"
"strings"
Expand Down Expand Up @@ -847,6 +848,12 @@ var (
Usage: "Enable circuit capacity check during block validation",
}

CircuitCapacityCheckWorkersFlag = cli.UintFlag{
Name: "ccc.numworkers",
Usage: "Set the number of workers that will be used for background CCC tasks",
Value: uint(runtime.GOMAXPROCS(0)),
}

// Rollup verify service settings
RollupVerifyEnabledFlag = cli.BoolFlag{
Name: "rollup.verify",
Expand Down Expand Up @@ -1544,6 +1551,11 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
if ctx.GlobalIsSet(LegacyMinerGasTargetFlag.Name) {
log.Warn("The generic --miner.gastarget flag is deprecated and will be removed in the future!")
}

cfg.CCCMaxWorkers = runtime.GOMAXPROCS(0)
if ctx.GlobalIsSet(CircuitCapacityCheckWorkersFlag.Name) {
cfg.CCCMaxWorkers = int(ctx.GlobalUint(CircuitCapacityCheckWorkersFlag.Name))
}
}

func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) {
Expand Down Expand Up @@ -1572,6 +1584,10 @@ func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) {
func setCircuitCapacityCheck(ctx *cli.Context, cfg *ethconfig.Config) {
if ctx.GlobalIsSet(CircuitCapacityCheckEnabledFlag.Name) {
cfg.CheckCircuitCapacity = ctx.GlobalBool(CircuitCapacityCheckEnabledFlag.Name)
cfg.CCCMaxWorkers = runtime.GOMAXPROCS(0)
if ctx.GlobalIsSet(CircuitCapacityCheckWorkersFlag.Name) {
cfg.CCCMaxWorkers = int(ctx.GlobalUint(CircuitCapacityCheckWorkersFlag.Name))
}
}
}

Expand Down
117 changes: 15 additions & 102 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,33 @@
package core

import (
"errors"
"fmt"
"sync"
"time"

"github.com/scroll-tech/go-ethereum/consensus"
"github.com/scroll-tech/go-ethereum/core/rawdb"
"github.com/scroll-tech/go-ethereum/core/state"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/ethdb"
"github.com/scroll-tech/go-ethereum/log"
"github.com/scroll-tech/go-ethereum/metrics"
"github.com/scroll-tech/go-ethereum/params"
"github.com/scroll-tech/go-ethereum/rollup/ccc"
"github.com/scroll-tech/go-ethereum/trie"
)

var (
validateL1MessagesTimer = metrics.NewRegisteredTimer("validator/l1msg", nil)
validateRowConsumptionTimer = metrics.NewRegisteredTimer("validator/rowconsumption", nil)
validateTraceTimer = metrics.NewRegisteredTimer("validator/trace", nil)
validateLockTimer = metrics.NewRegisteredTimer("validator/lock", nil)
validateCccTimer = metrics.NewRegisteredTimer("validator/ccc", nil)
validateL1MessagesTimer = metrics.NewRegisteredTimer("validator/l1msg", nil)
asyncValidatorTimer = metrics.NewRegisteredTimer("validator/async", nil)
)

// BlockValidator is responsible for validating block headers, uncles and
// processed state.
//
// BlockValidator implements Validator.
type BlockValidator struct {
config *params.ChainConfig // Chain configuration options
bc *BlockChain // Canonical block chain
engine consensus.Engine // Consensus engine used for validating

// circuit capacity checker related fields
checkCircuitCapacity bool // whether enable circuit capacity check
cMu sync.Mutex // mutex for circuit capacity checker
tracer tracerWrapper // scroll tracer wrapper
circuitCapacityChecker *ccc.Checker // circuit capacity checker instance
config *params.ChainConfig // Chain configuration options
bc *BlockChain // Canonical block chain
engine consensus.Engine // Consensus engine used for validating
asyncValidator func(*types.Block) error // Asynchronously run a validation task
}

// NewBlockValidator returns a new block validator which is safe for re-use
Expand All @@ -68,15 +56,10 @@ func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engin
return validator
}

type tracerWrapper interface {
CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error)
}

func (v *BlockValidator) SetupTracerAndCircuitCapacityChecker(tracer tracerWrapper) {
v.checkCircuitCapacity = true
v.tracer = tracer
v.circuitCapacityChecker = ccc.NewChecker(true)
log.Info("new CircuitCapacityChecker in BlockValidator", "ID", v.circuitCapacityChecker.ID)
// WithAsyncValidator sets up an async validator to be triggered on each new block
func (v *BlockValidator) WithAsyncValidator(asyncValidator func(*types.Block) error) Validator {
v.asyncValidator = asyncValidator
return v
}

// ValidateBody validates the given block's uncles and verifies the block
Expand Down Expand Up @@ -114,25 +97,13 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
if err := v.ValidateL1Messages(block); err != nil {
return err
}
if v.checkCircuitCapacity {
// if a block's RowConsumption has been stored, which means it has been processed before,
// (e.g., in miner/worker.go or in insertChain),
// we simply skip its calculation and validation
if rawdb.ReadBlockRowConsumption(v.bc.db, block.Hash()) != nil {
return nil
}
rowConsumption, err := v.validateCircuitRowConsumption(block)
if err != nil {

if v.asyncValidator != nil {
asyncStart := time.Now()
if err := v.asyncValidator(block); err != nil {
return err
}
log.Trace(
"Validator write block row consumption",
"id", v.circuitCapacityChecker.ID,
"number", block.NumberU64(),
"hash", block.Hash().String(),
"rowConsumption", rowConsumption,
)
rawdb.WriteBlockRowConsumption(v.bc.db, block.Hash(), rowConsumption)
asyncValidatorTimer.UpdateSince(asyncStart)
}
return nil
}
Expand Down Expand Up @@ -286,61 +257,3 @@ func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 {
}
return limit
}

func (v *BlockValidator) createTraceEnvAndGetBlockTrace(block *types.Block) (*types.BlockTrace, error) {
parent := v.bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
if parent == nil {
return nil, errors.New("validateCircuitRowConsumption: no parent block found")
}

statedb, err := v.bc.StateAt(parent.Root())
if err != nil {
return nil, err
}

return v.tracer.CreateTraceEnvAndGetBlockTrace(v.config, v.bc, v.engine, v.bc.db, statedb, parent, block, true)
}

func (v *BlockValidator) validateCircuitRowConsumption(block *types.Block) (*types.RowConsumption, error) {
defer func(t0 time.Time) {
validateRowConsumptionTimer.Update(time.Since(t0))
}(time.Now())

log.Trace(
"Validator apply ccc for block",
"id", v.circuitCapacityChecker.ID,
"number", block.NumberU64(),
"hash", block.Hash().String(),
"len(txs)", block.Transactions().Len(),
)

traceStartTime := time.Now()
traces, err := v.createTraceEnvAndGetBlockTrace(block)
if err != nil {
return nil, err
}
validateTraceTimer.Update(time.Since(traceStartTime))

lockStartTime := time.Now()
v.cMu.Lock()
defer v.cMu.Unlock()
validateLockTimer.Update(time.Since(lockStartTime))

cccStartTime := time.Now()
v.circuitCapacityChecker.Reset()
log.Trace("Validator reset ccc", "id", v.circuitCapacityChecker.ID)
rc, err := v.circuitCapacityChecker.ApplyBlock(traces)
validateCccTimer.Update(time.Since(cccStartTime))

log.Trace(
"Validator apply ccc for block result",
"id", v.circuitCapacityChecker.ID,
"number", block.NumberU64(),
"hash", block.Hash().String(),
"len(txs)", block.Transactions().Len(),
"rc", rc,
"err", err,
)

return rc, err
}
1 change: 1 addition & 0 deletions core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3723,6 +3723,7 @@ func TestCurieTransition(t *testing.T) {
json.Unmarshal(b, &config)
config.CurieBlock = big.NewInt(2)
config.DarwinTime = nil
config.DarwinV2Time = nil

var (
db = rawdb.NewMemoryDatabase()
Expand Down
8 changes: 5 additions & 3 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, chainConfig *p
// NewEVMTxContext creates a new transaction context for a single transaction.
func NewEVMTxContext(msg Message) vm.TxContext {
return vm.TxContext{
Origin: msg.From(),
To: msg.To(),
GasPrice: new(big.Int).Set(msg.GasPrice()),
Origin: msg.From(),
To: msg.To(),
GasPrice: new(big.Int).Set(msg.GasPrice()),
IsL1MessageTx: msg.IsL1MessageTx(),
TxSize: msg.TxSize(),
}
}

Expand Down
51 changes: 48 additions & 3 deletions core/rawdb/accessors_rollup_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ type ChunkBlockRange struct {
EndBlockNumber uint64
}

// CommittedBatchMeta holds metadata for committed batches.
type CommittedBatchMeta struct {
Version uint8
BlobVersionedHashes []common.Hash
ChunkBlockRanges []*ChunkBlockRange
}

// FinalizedBatchMeta holds metadata for finalized batches.
type FinalizedBatchMeta struct {
BatchHash common.Hash
Expand Down Expand Up @@ -53,6 +60,7 @@ func ReadRollupEventSyncedL1BlockNumber(db ethdb.Reader) *uint64 {

// WriteBatchChunkRanges writes the block ranges for each chunk within a batch to the database.
// It serializes the chunk ranges using RLP and stores them under a key derived from the batch index.
// for backward compatibility, new info is also stored in CommittedBatchMeta.
func WriteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64, chunkBlockRanges []*ChunkBlockRange) {
value, err := rlp.EncodeToBytes(chunkBlockRanges)
if err != nil {
Expand All @@ -65,6 +73,7 @@ func WriteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64, chunkBloc

// DeleteBatchChunkRanges removes the block ranges of all chunks associated with a specific batch from the database.
// Note: Only non-finalized batches can be reverted.
// for backward compatibility, new info is also stored in CommittedBatchMeta.
func DeleteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64) {
if err := db.Delete(batchChunkRangesKey(batchIndex)); err != nil {
log.Crit("failed to delete batch chunk ranges", "batch index", batchIndex, "err", err)
Expand All @@ -73,6 +82,7 @@ func DeleteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64) {

// ReadBatchChunkRanges retrieves the block ranges of all chunks associated with a specific batch from the database.
// It returns a list of ChunkBlockRange pointers, or nil if no chunk ranges are found for the given batch index.
// for backward compatibility, new info is also stored in CommittedBatchMeta.
func ReadBatchChunkRanges(db ethdb.Reader, batchIndex uint64) []*ChunkBlockRange {
data, err := db.Get(batchChunkRangesKey(batchIndex))
if err != nil && isNotFoundErr(err) {
Expand All @@ -91,13 +101,12 @@ func ReadBatchChunkRanges(db ethdb.Reader, batchIndex uint64) []*ChunkBlockRange

// WriteFinalizedBatchMeta stores the metadata of a finalized batch in the database.
func WriteFinalizedBatchMeta(db ethdb.KeyValueWriter, batchIndex uint64, finalizedBatchMeta *FinalizedBatchMeta) {
var err error
value, err := rlp.EncodeToBytes(finalizedBatchMeta)
if err != nil {
log.Crit("failed to RLP encode batch metadata", "batch index", batchIndex, "finalized batch meta", finalizedBatchMeta, "err", err)
log.Crit("failed to RLP encode finalized batch metadata", "batch index", batchIndex, "finalized batch meta", finalizedBatchMeta, "err", err)
}
if err := db.Put(batchMetaKey(batchIndex), value); err != nil {
log.Crit("failed to store batch metadata", "batch index", batchIndex, "value", value, "err", err)
log.Crit("failed to store finalized batch metadata", "batch index", batchIndex, "value", value, "err", err)
}
}

Expand Down Expand Up @@ -171,3 +180,39 @@ func ReadLastFinalizedBatchIndex(db ethdb.Reader) *uint64 {
lastFinalizedBatchIndex := number.Uint64()
return &lastFinalizedBatchIndex
}

// WriteCommittedBatchMeta stores the CommittedBatchMeta for a specific batch in the database.
func WriteCommittedBatchMeta(db ethdb.KeyValueWriter, batchIndex uint64, committedBatchMeta *CommittedBatchMeta) {
value, err := rlp.EncodeToBytes(committedBatchMeta)
if err != nil {
log.Crit("failed to RLP encode committed batch metadata", "batch index", batchIndex, "committed batch meta", committedBatchMeta, "err", err)
}
if err := db.Put(committedBatchMetaKey(batchIndex), value); err != nil {
log.Crit("failed to store committed batch metadata", "batch index", batchIndex, "value", value, "err", err)
}
}

// ReadCommittedBatchMeta fetches the CommittedBatchMeta for a specific batch from the database.
func ReadCommittedBatchMeta(db ethdb.Reader, batchIndex uint64) *CommittedBatchMeta {
data, err := db.Get(committedBatchMetaKey(batchIndex))
if err != nil && isNotFoundErr(err) {
return nil
}
if err != nil {
log.Crit("failed to read committed batch metadata from database", "batch index", batchIndex, "err", err)
}

cbm := new(CommittedBatchMeta)
if err := rlp.Decode(bytes.NewReader(data), cbm); err != nil {
log.Crit("Invalid CommittedBatchMeta RLP", "batch index", batchIndex, "data", data, "err", err)
}
return cbm
}

// DeleteCommittedBatchMeta removes the block ranges of all chunks associated with a specific batch from the database.
// Note: Only non-finalized batches can be reverted.
func DeleteCommittedBatchMeta(db ethdb.KeyValueWriter, batchIndex uint64) {
if err := db.Delete(committedBatchMetaKey(batchIndex)); err != nil {
log.Crit("failed to delete committed batch metadata", "batch index", batchIndex, "err", err)
}
}
Loading

0 comments on commit 604e8a1

Please sign in to comment.