Skip to content

Commit

Permalink
feat: add counter based ccc (#1040)
Browse files Browse the repository at this point in the history
* add rollup/ccc/logger.go

* update Cargo.toml & Cargo.lock

* update miner/miner.go

* update miner/miner_test.go

* update eth/backend.go

* update `Message` type

* update interfaces.go

* update core/rawdb/accessors_row_consumption.go

* update evm.go

* update accounts/abi/bind/backends/simulated.go

* fix rollup/ccc/logger.go

* update core/state_processor.go

* update rollup/ccc/async_checker_test.go

* update rollup/ccc/async_checker.go

* scroll_worker: var

* scroll_worker: work

* scroll_worker: reorgTrigger

* scroll_worker: worker

* scroll_worker: newWorker

* scroll_worker: rm getCCC

* scroll_worker: checkHeadRowConsumption

* scroll_worker: mainLoop

* scroll_worker: updateSnapshot

* scroll_worker: newWork

* scroll_worker: handlePipelineResult

* scroll_worker: tryCommitNewWork

* scroll_worker: handleForks

* scroll_worker: processTxPool

* scroll_worker: processTxnSlice

* scroll_worker: processReorgedTxns

* scroll_worker: processTxns

* scroll_worker: processTxn

* scroll_worker: commit

* scroll_worker: onTxFailing

* scroll_worker: skipTransaction

* scroll_worker: forceTestErr, scheduleCCCError, skip, onBlockFailingCCC, handleReorg, isCanonical

* scroll_worker: fix 1

* scroll_worker: fix 2

* scroll_worker: fix 3

* scroll_worker: fix 4

* scroll_worker: fix 5

* scroll_worker: fix 6

* scroll_worker: fix 7

* fix: disable headCCCCheck for follower nodes

* feat: double check ancestor RowConsumption before committing

* feat: add miner idle metric

* fix: nil-check curRc

* fix: skip ccc.ErrUnknown txns immediately

* fix: increase keccak usage safety buffer

* fix: ignore RC check if force committing

* fix: properly handle wrapped retryable errors
  • Loading branch information
0xmountaintop authored Sep 17, 2024
1 parent a6c6543 commit e0ba374
Show file tree
Hide file tree
Showing 28 changed files with 1,562 additions and 366 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 @@ -706,6 +706,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
AccessList: call.AccessList,
SkipAccountChecks: true,
IsL1MessageTx: false,
TxSize: 0,
}

// Create a new environment which holds all relevant information
Expand Down
4 changes: 4 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,10 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
if ctx.IsSet(MinerMaxAccountsNumFlag.Name) {
cfg.MaxAccountsNum = ctx.Int(MinerMaxAccountsNumFlag.Name)
}
cfg.CCCMaxWorkers = runtime.GOMAXPROCS(0)
if ctx.IsSet(CircuitCapacityCheckWorkersFlag.Name) {
cfg.CCCMaxWorkers = int(ctx.Uint(CircuitCapacityCheckWorkersFlag.Name))
}
}

func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {
Expand Down
5 changes: 4 additions & 1 deletion core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, chainConfig *p
func NewEVMTxContext(msg *Message) vm.TxContext {
return vm.TxContext{
Origin: msg.From,
To: msg.To,
GasPrice: new(big.Int).Set(msg.GasPrice),
BlobHashes: msg.BlobHashes,

To: msg.To,
IsL1MessageTx: msg.IsL1MessageTx,
TxSize: msg.TxSize,
}
}

Expand Down
5 changes: 5 additions & 0 deletions core/rawdb/accessors_row_consumption.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ func WriteBlockRowConsumption(db ethdb.KeyValueWriter, l2BlockHash common.Hash,
}
}

// DeleteBlockRowConsumption deletes a RowConsumption of the block from the database
func DeleteBlockRowConsumption(db ethdb.KeyValueWriter, l2BlockHash common.Hash) error {
return db.Delete(rowConsumptionKey(l2BlockHash))
}

// ReadBlockRowConsumption retrieves the RowConsumption corresponding to the block hash.
func ReadBlockRowConsumption(db ethdb.Reader, l2BlockHash common.Hash) *types.RowConsumption {
data := ReadBlockRowConsumptionRLP(db, l2BlockHash)
Expand Down
5 changes: 5 additions & 0 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
// Apply the transaction to the current state (included in the env).
applyMessageStartTime := time.Now()
result, err := ApplyMessage(evm, msg, gp, l1DataFee)
if evm.Config.Tracer.IsDebug() {
if erroringTracer, ok := evm.Config.Tracer.(interface{ Error() error }); ok {
err = errors.Join(err, erroringTracer.Error())
}
}
applyMessageTimer.Update(time.Since(applyMessageStartTime))
if err != nil {
return nil, err
Expand Down
3 changes: 3 additions & 0 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ type Message struct {

// scroll-related fields
IsL1MessageTx bool
TxSize uint64
}

func (m *Message) GetFrom() common.Address { return m.From }
Expand All @@ -168,6 +169,7 @@ func (m *Message) GetNonce() uint64 { return m.Nonce }
func (m *Message) GetData() []byte { return m.Data }
func (m *Message) GetAccessList() types.AccessList { return m.AccessList }
func (m *Message) GetIsL1MessageTx() bool { return m.IsL1MessageTx }
func (m *Message) GetTxSize() uint64 { return m.TxSize }

// TransactionToMessage converts a transaction into a Message.
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
Expand All @@ -185,6 +187,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
BlobHashes: tx.BlobHashes(),
BlobGasFeeCap: tx.BlobGasFeeCap(),
IsL1MessageTx: tx.IsL1MessageTx(),
TxSize: tx.Size(),
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
Expand Down
13 changes: 8 additions & 5 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import (
"math/big"
"sync/atomic"

"github.com/holiman/uint256"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/crypto"
"github.com/scroll-tech/go-ethereum/params"
"github.com/holiman/uint256"
)

type (
Expand Down Expand Up @@ -85,10 +85,13 @@ type BlockContext struct {
// All fields can change between transactions.
type TxContext struct {
// Message information
Origin common.Address // Provides information for ORIGIN
To *common.Address // Provides information for TO in trace
GasPrice *big.Int // Provides information for GASPRICE
BlobHashes []common.Hash // Provides information for BLOBHASH
Origin common.Address // Provides information for ORIGIN
GasPrice *big.Int // Provides information for GASPRICE
BlobHashes []common.Hash // Provides information for BLOBHASH

To *common.Address // Provides information for TO in trace
IsL1MessageTx bool // Provides information for trace
TxSize uint64 // Provides information for trace
}

// EVM is the Ethereum Virtual Machine base object and provides
Expand Down
2 changes: 2 additions & 0 deletions core/vm/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ type EVMLogger interface {
CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
CaptureStateAfter(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error)
// Helper function
IsDebug() bool
}
2 changes: 1 addition & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client sync_service.EthCl
return nil, err
}
if config.CheckCircuitCapacity {
eth.asyncChecker = ccc.NewAsyncChecker(eth.blockchain, config.CCCMaxWorkers, true)
eth.asyncChecker = ccc.NewAsyncChecker(eth.blockchain, config.CCCMaxWorkers, false)
eth.asyncChecker.WithOnFailingBlock(func(b *types.Block, err error) {
log.Warn("block failed CCC check, it will be reorged by the sequencer", "hash", b.Hash(), "err", err)
})
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/js/goja.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ func (t *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Ad
}
}

func (t *jsTracer) IsDebug() bool {
return false
}

// CaptureExit is called when EVM exits a scope, even if the scope didn't
// execute any code.
func (t *jsTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/logger/access_list_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,7 @@ func (a *AccessListTracer) AccessList() types.AccessList {
func (a *AccessListTracer) Equal(other *AccessListTracer) bool {
return a.list.equal(other.list)
}

func (a *AccessListTracer) IsDebug() bool {
return false
}
2 changes: 2 additions & 0 deletions eth/tracers/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ func (l *StructLogger) UpdatedStorages() map[common.Address]Storage {
// CreatedAccount return the account data in case it is a create tx
func (l *StructLogger) CreatedAccount() *types.AccountWrapper { return l.createdAccount }

func (l *StructLogger) IsDebug() bool { return l.cfg.Debug }

// WriteTrace writes a formatted trace to the given writer
func WriteTrace(writer io.Writer, logs []StructLog) {
for _, log := range logs {
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/logger/logger_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,7 @@ func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}
func (l *JSONLogger) CaptureTxStart(gasLimit uint64) {}

func (l *JSONLogger) CaptureTxEnd(restGas uint64) {}

func (l *JSONLogger) IsDebug() bool {
return l.cfg.Debug
}
4 changes: 4 additions & 0 deletions eth/tracers/native/4byte.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to comm
t.store(input[0:4], len(input)-4)
}

func (t *fourByteTracer) IsDebug() bool {
return false
}

// GetResult returns the json-encoded nested list of call traces, and any
// error arising from the encoding or forceful termination (via `Stop`).
func (t *fourByteTracer) GetResult() (json.RawMessage, error) {
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/native/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ func (t *CallTracer) CaptureTxEnd(restGas uint64) {
}
}

func (t *CallTracer) IsDebug() bool {
return false
}

// GetResult returns the json-encoded nested list of call traces, and any
// error arising from the encoding or forceful termination (via `Stop`).
func (t *CallTracer) GetResult() (json.RawMessage, error) {
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/native/call_flat.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ func (t *flatCallTracer) CaptureTxEnd(restGas uint64) {
t.tracer.CaptureTxEnd(restGas)
}

func (t *flatCallTracer) IsDebug() bool {
return false
}

// GetResult returns an empty json object.
func (t *flatCallTracer) GetResult() (json.RawMessage, error) {
if len(t.tracer.callstack) < 1 {
Expand Down
4 changes: 4 additions & 0 deletions eth/tracers/native/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ func (t *MuxTracer) CaptureTxEnd(restGas uint64) {
}
}

func (t *MuxTracer) IsDebug() bool {
return false
}

// GetResult returns an empty json object.
func (t *MuxTracer) GetResult() (json.RawMessage, error) {
resObject := make(map[string]json.RawMessage)
Expand Down
2 changes: 2 additions & 0 deletions eth/tracers/native/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func (*noopTracer) CaptureTxStart(gasLimit uint64) {}

func (*noopTracer) CaptureTxEnd(restGas uint64) {}

func (*noopTracer) IsDebug() bool { return false }

// GetResult returns an empty json object.
func (t *noopTracer) GetResult() (json.RawMessage, error) {
return json.RawMessage(`{}`), nil
Expand Down
1 change: 1 addition & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ type CallMsg struct {

// scroll-related:
// not need to have a `IsL1MessageTx` field, should always be false
// not need to have a `TxSize` field, not known at the moment
}

// A ContractCaller provides contract calls, essentially transactions that are executed by
Expand Down
1 change: 1 addition & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type Config struct {

StoreSkippedTxTraces bool // Whether store the wrapped traces when storing a skipped tx
MaxAccountsNum int // Maximum number of accounts that miner will fetch the pending transactions of when building a new block
CCCMaxWorkers int // Maximum number of workers to use for async CCC tasks
}

// DefaultConfig contains default settings for miner.
Expand Down
1 change: 1 addition & 0 deletions miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux, func(skipMiner bool)) {
config := Config{
Etherbase: common.HexToAddress("123456789"),
MaxAccountsNum: math.MaxInt,
CCCMaxWorkers: 2,
}
// Create chainConfig
chainDB := rawdb.NewMemoryDatabase()
Expand Down
Loading

0 comments on commit e0ba374

Please sign in to comment.