diff --git a/Dockerfile b/Dockerfile index ba53550302d5..339bdd11f5b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,7 @@ ADD . /go-ethereum ARG SCROLL_LIB_PATH +RUN apt update && apt install vim netcat-openbsd net-tools curl -y RUN mkdir -p $SCROLL_LIB_PATH COPY --from=zkp-builder /app/target/release/libzkp.so $SCROLL_LIB_PATH diff --git a/consensus/misc/eip1559.go b/consensus/misc/eip1559.go index f02d5fcd9514..483878fc0e4a 100644 --- a/consensus/misc/eip1559.go +++ b/consensus/misc/eip1559.go @@ -55,12 +55,12 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseF return big.NewInt(10000000) // 0.01 Gwei } l2SequencerFee := big.NewInt(1000000) // 0.001 Gwei - provingFee := big.NewInt(33700000) // 0.0337 Gwei + provingFee := big.NewInt(38200000) // 0.0382 Gwei - // L1_base_fee * 0.0034 + // L1_base_fee * 0.00017 verificationFee := parentL1BaseFee - verificationFee = new(big.Int).Mul(verificationFee, big.NewInt(34)) - verificationFee = new(big.Int).Div(verificationFee, big.NewInt(10000)) + verificationFee = new(big.Int).Mul(verificationFee, big.NewInt(17)) + verificationFee = new(big.Int).Div(verificationFee, big.NewInt(100000)) baseFee := big.NewInt(0) baseFee.Add(baseFee, l2SequencerFee) diff --git a/consensus/misc/eip1559_test.go b/consensus/misc/eip1559_test.go index 5a8c69101505..3b48c2e58107 100644 --- a/consensus/misc/eip1559_test.go +++ b/consensus/misc/eip1559_test.go @@ -112,13 +112,13 @@ func TestCalcBaseFee(t *testing.T) { parentL1BaseFee int64 expectedL2BaseFee int64 }{ - {0, 34700000}, - {1000000000, 38100000}, - {2000000000, 41500000}, - {100000000000, 374700000}, - {111111111111, 412477777}, - {2164000000000, 7392300000}, - {2931000000000, 10000000000}, // cap at max L2 base fee + {0, 39200000}, + {1000000000, 39370000}, + {2000000000, 39540000}, + {100000000000, 56200000}, + {111111111111, 58088888}, + {2164000000000, 407080000}, + {58592942000000, 10000000000}, // cap at max L2 base fee } for i, test := range tests { if have, want := CalcBaseFee(config(), nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 { diff --git a/core/state_processor_test.go b/core/state_processor_test.go index e9d6e426e11b..e565b7062b69 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -361,13 +361,13 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkDynamicCreationTx(0, 500000, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), tooBigInitCode[:]), }, - want: "could not apply tx 0 [0x8f780c3573ac61e2d7796f7b447afd0ad753623ed95bc99ef94eb083d9e0d039]: max initcode size exceeded: code size 49153 limit 49152", + want: "could not apply tx 0 [0xa31de6e26bd5ffba0ca91a2bc29fc2eaad6a6cfc5ad9ab6ffb69cac121e0125c]: max initcode size exceeded: code size 49153 limit 49152", }, { // ErrIntrinsicGas: Not enough gas to cover init code txs: []*types.Transaction{ mkDynamicCreationTx(0, 54299, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), smallInitCode[:]), }, - want: "could not apply tx 0 [0xbf812bb88c3f53402b6cf5488ac89360595e524b65582b648d1f4ef197690e89]: intrinsic gas too low: have 54299, want 54300", + want: "could not apply tx 0 [0xf36b7d68cf239f956f7c36be26688a97aaa317ea5f5230d109bb30dbc8598ccb]: intrinsic gas too low: have 54299, want 54300", }, } { block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config) diff --git a/core/tx_pool.go b/core/tx_pool.go index 5284a59eb87f..d7fc66f712aa 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -707,7 +707,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { return ErrOversizedData } // Reject transactions that cannot fit into a block even as a single transaction - if !pool.chainconfig.Scroll.IsValidBlockSize(tx.Size()) { + if !pool.chainconfig.Scroll.IsValidBlockSizeForMining(tx.Size()) { return ErrOversizedData } // Check whether the init code size has been exceeded. @@ -1378,7 +1378,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt log.Debug("runReorg", "len(txs)", len(txs)) if len(txs) > dumpReorgTxHashThreshold { for _, txs := range txs { - log.Debug("dumping runReorg tx hashes", "txHash", txs.Hash().Hex()) + log.Info("dumping runReorg tx hashes", "txHash", txs.Hash().Hex()) } } } @@ -1532,7 +1532,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans hash := tx.Hash() pool.all.Remove(hash) pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now()) - log.Trace("Removed cap-exceeding queued transaction", "hash", hash) + log.Info("Removed cap-exceeding queued transaction", "hash", hash) } queuedRateLimitMeter.Mark(int64(len(caps))) } diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 525deda66b9b..9c75a16e7f0a 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -2685,7 +2685,7 @@ func TestValidateTxBlockSize(t *testing.T) { account := crypto.PubkeyToAddress(key.PublicKey) testAddBalance(pool, account, big.NewInt(1000000000000000000)) - validTx := pricedDataTransaction(1, 2100000, big.NewInt(1), key, uint64(*pool.chainconfig.Scroll.MaxTxPayloadBytesPerBlock)-128) + validTx := pricedDataTransaction(1, 2100000, big.NewInt(1), key, uint64(float64(*pool.chainconfig.Scroll.MaxTxPayloadBytesPerBlock)*float64(0.9))) oversizedTx := pricedDataTransaction(2, 2100000, big.NewInt(1), key, uint64(*pool.chainconfig.Scroll.MaxTxPayloadBytesPerBlock)) tests := []struct { diff --git a/eth/api.go b/eth/api.go index 1ba4d6a3f1b9..74672347823c 100644 --- a/eth/api.go +++ b/eth/api.go @@ -254,6 +254,32 @@ func (api *PrivateAdminAPI) ImportChain(file string) (bool, error) { return true, nil } +// SetRollupEventSyncedL1Height sets the synced L1 height for rollup event synchronization +func (api *PrivateAdminAPI) SetRollupEventSyncedL1Height(height uint64) error { + rollupSyncService := api.eth.GetRollupSyncService() + if rollupSyncService == nil { + return errors.New("RollupSyncService is not available") + } + + log.Info("Setting rollup event synced L1 height", "height", height) + rollupSyncService.ResetStartSyncHeight(height) + + return nil +} + +// SetL1MessageSyncedL1Height sets the synced L1 height for L1 message synchronization +func (api *PrivateAdminAPI) SetL1MessageSyncedL1Height(height uint64) error { + syncService := api.eth.GetSyncService() + if syncService == nil { + return errors.New("SyncService is not available") + } + + log.Info("Setting L1 message synced L1 height", "height", height) + syncService.ResetStartSyncHeight(height) + + return nil +} + // PublicDebugAPI is the collection of Ethereum full node APIs exposed // over the public debugging endpoint. type PublicDebugAPI struct { diff --git a/eth/backend.go b/eth/backend.go index 7651c72f29c6..ae198bceefe8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -609,3 +609,15 @@ func (s *Ethereum) Stop() error { return nil } + +// GetRollupSyncService returns the RollupSyncService of the Ethereum instance. +// It returns nil if the service is not initialized. +func (e *Ethereum) GetRollupSyncService() *rollup_sync_service.RollupSyncService { + return e.rollupSyncService +} + +// GetSyncService returns the SyncService of the Ethereum instance. +// It returns nil if the service is not initialized. +func (e *Ethereum) GetSyncService() *sync_service.SyncService { + return e.syncService +} diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index c13fbb8be6d7..d43e01467ee3 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -190,6 +190,16 @@ web3._extend({ name: 'stopWS', call: 'admin_stopWS' }), + new web3._extend.Method({ + name: 'setRollupEventSyncedL1Height', + call: 'admin_setRollupEventSyncedL1Height', + params: 1 + }), + new web3._extend.Method({ + name: 'setL1MessageSyncedL1Height', + call: 'admin_setL1MessageSyncedL1Height', + params: 1 + }), ], properties: [ new web3._extend.Property({ diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 02f331bc200a..ec6337bef406 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -742,7 +742,7 @@ func (w *worker) processTxn(tx *types.Transaction) (bool, error) { return false, ErrUnexpectedL1MessageIndex } - if !tx.IsL1MessageTx() && !w.chain.Config().Scroll.IsValidBlockSize(w.current.blockSize+tx.Size()) { + if !tx.IsL1MessageTx() && !w.chain.Config().Scroll.IsValidBlockSizeForMining(w.current.blockSize+tx.Size()) { // can't fit this txn in this block, silently ignore and continue looking for more txns return false, errors.New("tx too big") } diff --git a/params/config.go b/params/config.go index 11b8ff9390c9..eb2213fdd360 100644 --- a/params/config.go +++ b/params/config.go @@ -718,6 +718,11 @@ func (s ScrollConfig) IsValidBlockSize(size common.StorageSize) bool { return s.MaxTxPayloadBytesPerBlock == nil || size <= common.StorageSize(*s.MaxTxPayloadBytesPerBlock) } +// IsValidBlockSizeForMining is similar to IsValidBlockSize, but it accounts for the confidence factor in Rust CCC +func (s ScrollConfig) IsValidBlockSizeForMining(size common.StorageSize) bool { + return s.IsValidBlockSize(size * (1.0 / 0.95)) +} + // EthashConfig is the consensus engine configs for proof-of-work based sealing. type EthashConfig struct{} diff --git a/params/version.go b/params/version.go index 47191375efc0..c523758cbe05 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 7 // Minor version component of the current release - VersionPatch = 22 // Patch version component of the current release + VersionPatch = 24 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/pipeline/pipeline.go b/rollup/pipeline/pipeline.go index 4c0abd3e53e7..12c34e2c96ff 100644 --- a/rollup/pipeline/pipeline.go +++ b/rollup/pipeline/pipeline.go @@ -272,7 +272,7 @@ func (p *Pipeline) traceAndApplyStage(txsIn <-chan *types.Transaction) (<-chan e continue } - if !tx.IsL1MessageTx() && !p.chain.Config().Scroll.IsValidBlockSize(p.blockSize+tx.Size()) { + if !tx.IsL1MessageTx() && !p.chain.Config().Scroll.IsValidBlockSizeForMining(p.blockSize+tx.Size()) { // can't fit this txn in this block, silently ignore and continue looking for more txns sendCancellable(resCh, nil, p.ctx.Done()) continue diff --git a/rollup/rollup_sync_service/rollup_sync_service.go b/rollup/rollup_sync_service/rollup_sync_service.go index 3991debcb1c6..c03d63e05c47 100644 --- a/rollup/rollup_sync_service/rollup_sync_service.go +++ b/rollup/rollup_sync_service/rollup_sync_service.go @@ -7,6 +7,7 @@ import ( "math/big" "os" "reflect" + "sync" "time" "github.com/scroll-tech/da-codec/encoding" @@ -63,6 +64,7 @@ type RollupSyncService struct { l1FinalizeBatchEventSignature common.Hash bc *core.BlockChain stack *node.Node + stateMu sync.Mutex } func NewRollupSyncService(ctx context.Context, genesisConfig *params.ChainConfig, db ethdb.Database, l1Client sync_service.EthClient, bc *core.BlockChain, stack *node.Node) (*RollupSyncService, error) { @@ -157,7 +159,23 @@ func (s *RollupSyncService) Stop() { } } +// ResetStartSyncHeight resets the RollupSyncService to a specific L1 block height +func (s *RollupSyncService) ResetStartSyncHeight(height uint64) { + if s == nil { + return + } + + s.stateMu.Lock() + defer s.stateMu.Unlock() + + s.latestProcessedBlock = height + log.Info("Reset sync service", "height", height) +} + func (s *RollupSyncService) fetchRollupEvents() { + s.stateMu.Lock() + defer s.stateMu.Unlock() + latestConfirmed, err := s.client.getLatestFinalizedBlockNumber() if err != nil { log.Warn("failed to get latest confirmed block number", "err", err) diff --git a/rollup/sync_service/sync_service.go b/rollup/sync_service/sync_service.go index 091f2d19691f..9239e210b8ed 100644 --- a/rollup/sync_service/sync_service.go +++ b/rollup/sync_service/sync_service.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "reflect" + "sync" "time" "github.com/scroll-tech/go-ethereum/core" @@ -50,6 +51,7 @@ type SyncService struct { pollInterval time.Duration latestProcessedBlock uint64 scope event.SubscriptionScope + stateMu sync.Mutex } func NewSyncService(ctx context.Context, genesisConfig *params.ChainConfig, nodeConfig *node.Config, db ethdb.Database, l1Client EthClient) (*SyncService, error) { @@ -139,6 +141,19 @@ func (s *SyncService) Stop() { } } +// ResetStartSyncHeight resets the SyncService to a specific L1 block height +func (s *SyncService) ResetStartSyncHeight(height uint64) { + if s == nil { + return + } + + s.stateMu.Lock() + defer s.stateMu.Unlock() + + s.latestProcessedBlock = height + log.Info("Reset sync service", "height", height) +} + // SubscribeNewL1MsgsEvent registers a subscription of NewL1MsgsEvent and // starts sending event to the given channel. func (s *SyncService) SubscribeNewL1MsgsEvent(ch chan<- core.NewL1MsgsEvent) event.Subscription { @@ -146,6 +161,9 @@ func (s *SyncService) SubscribeNewL1MsgsEvent(ch chan<- core.NewL1MsgsEvent) eve } func (s *SyncService) fetchMessages() { + s.stateMu.Lock() + defer s.stateMu.Unlock() + latestConfirmed, err := s.client.getLatestConfirmedBlockNumber(s.ctx) if err != nil { log.Warn("Failed to get latest confirmed block number", "err", err)