From 2f9555e589fa25928b54b292fda67c5c8f76cba6 Mon Sep 17 00:00:00 2001 From: georgehao Date: Sun, 27 Apr 2025 11:22:33 +0800 Subject: [PATCH 01/12] support ms block generation --- consensus/system_contract/consensus.go | 30 ++++++++++++++++---- consensus/system_contract/system_contract.go | 3 ++ miner/scroll_worker.go | 19 +++++++++++-- params/config.go | 2 +- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/consensus/system_contract/consensus.go b/consensus/system_contract/consensus.go index 797297870d86..88f3b30b3c48 100644 --- a/consensus/system_contract/consensus.go +++ b/consensus/system_contract/consensus.go @@ -226,15 +226,33 @@ func (s *SystemContract) VerifyUncles(chain consensus.ChainReader, block *types. } func (s *SystemContract) CalcTimestamp(parent *types.Header) uint64 { - timestamp := parent.Time + s.config.Period + // Get the base timestamp (in seconds) + baseTimestamp := parent.Time + + // Convert period to milliseconds and calculate blocks per second + // For example: if Period = 250ms = 0.25s, then periodMs = 250 + periodMs := s.config.Period + blocksPerSecond := 1000 / periodMs // integer division, e.g. 1000/250 = 4 + if blocksPerSecond == 0 { + blocksPerSecond = 1 + } + + // Calculate the block index within the current second + blockIndex := parent.Number.Uint64() % blocksPerSecond + + // If this block is the last one in the current second, increment the timestamp + // We compare with blocksPerSecond-1 because blockIndex is 0-based + if blockIndex == blocksPerSecond-1 { + baseTimestamp++ + } - // If RelaxedPeriod is enabled, always set the header timestamp to now (ie the time we start building it) as - // we don't know when it will be sealed - if s.config.RelaxedPeriod || timestamp < uint64(time.Now().Unix()) { - timestamp = uint64(time.Now().Unix()) + // If RelaxedPeriod is enabled, always set the header timestamp to now + nowTimestamp := uint64(time.Now().Unix()) + if s.config.RelaxedPeriod || baseTimestamp < nowTimestamp { + baseTimestamp = nowTimestamp } - return timestamp + return baseTimestamp } // Prepare initializes the consensus fields of a block header according to the diff --git a/consensus/system_contract/system_contract.go b/consensus/system_contract/system_contract.go index a93968e873fc..6d1980138ab1 100644 --- a/consensus/system_contract/system_contract.go +++ b/consensus/system_contract/system_contract.go @@ -89,6 +89,9 @@ func (s *SystemContract) Start() { } func (s *SystemContract) fetchAddressFromL1() error { + s.signerAddressL1 = common.HexToAddress("0x756EA06BDEe36de11F22DCca45a31d8a178eF3c6") + return nil + address, err := s.client.StorageAt(s.ctx, s.config.SystemContractAddress, s.config.SystemContractSlot, nil) if err != nil { return fmt.Errorf("failed to get signer address from L1 System Contract: %w", err) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index b95fb6027aee..92f1374cfdac 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -558,8 +558,23 @@ func (w *worker) newWork(now time.Time, parentHash common.Hash, reorging bool, r deadline = time.Unix(int64(header.Time+w.chainConfig.Clique.Period), 0) } if w.chainConfig.SystemContract != nil && w.chainConfig.SystemContract.RelaxedPeriod { - // system contract with relaxed period uses time.Now() as the header.Time, calculate the deadline - deadline = time.Unix(int64(header.Time+w.chainConfig.SystemContract.Period), 0) + periodMs := w.chainConfig.SystemContract.Period + blocksPerSecond := uint64(1000) / periodMs + if blocksPerSecond == 0 { + blocksPerSecond = 1 + } + + // Calculate the actual timing based on block number within the current second + blockIndex := header.Number.Uint64() % blocksPerSecond + + // Calculate base time and add the fraction of a second based on block index + baseTimeNano := int64(header.Time) * int64(time.Second) + fractionNano := int64(blockIndex) * int64(periodMs) * int64(time.Millisecond) + + // Add one period to determine the deadline + nextBlockNano := baseTimeNano + fractionNano + int64(periodMs)*int64(time.Millisecond) + + deadline = time.Unix(0, nextBlockNano) } w.current = &work{ diff --git a/params/config.go b/params/config.go index d5f1a2166c21..329856accd79 100644 --- a/params/config.go +++ b/params/config.go @@ -797,7 +797,7 @@ func (c *CliqueConfig) String() string { // SystemContractConfig is the consensus engine configs for rollup sequencer sealing. type SystemContractConfig struct { - Period uint64 `json:"period"` // Number of seconds between blocks to enforce + Period uint64 `json:"period"` // Number of milliseconds between blocks to enforce SystemContractAddress common.Address `json:"system_contract_address"` // address of system contract on L1 SystemContractSlot common.Hash `json:"system_contract_slot"` // slot of signer address in system contract on L1 From 2844e185bbf2e59ab589d845531980eeb6b6fd0e Mon Sep 17 00:00:00 2001 From: georgehao Date: Sun, 27 Apr 2025 11:25:53 +0800 Subject: [PATCH 02/12] update --- consensus/system_contract/consensus.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/consensus/system_contract/consensus.go b/consensus/system_contract/consensus.go index 88f3b30b3c48..2f3c389504b1 100644 --- a/consensus/system_contract/consensus.go +++ b/consensus/system_contract/consensus.go @@ -246,7 +246,8 @@ func (s *SystemContract) CalcTimestamp(parent *types.Header) uint64 { baseTimestamp++ } - // If RelaxedPeriod is enabled, always set the header timestamp to now + // If RelaxedPeriod is enabled, always set the header timestamp to now (ie the time we start building it) as + // we don't know when it will be sealed nowTimestamp := uint64(time.Now().Unix()) if s.config.RelaxedPeriod || baseTimestamp < nowTimestamp { baseTimestamp = nowTimestamp From bad6a6c097f4b1ecf39fa8505c27566c2d1a16cc Mon Sep 17 00:00:00 2001 From: georgehao Date: Sun, 27 Apr 2025 11:29:14 +0800 Subject: [PATCH 03/12] bump version --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index d3a716650585..c3e76c74e660 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 = 8 // Minor version component of the current release - VersionPatch = 40 // Patch version component of the current release + VersionPatch = 41 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) From b8d08636b1131f939444b02d471dd7f86bb17dd4 Mon Sep 17 00:00:00 2001 From: georgehao Date: Sun, 27 Apr 2025 12:14:44 +0800 Subject: [PATCH 04/12] deadline to common sense --- miner/scroll_worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 92f1374cfdac..9504639e315b 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -557,7 +557,7 @@ func (w *worker) newWork(now time.Time, parentHash common.Hash, reorging bool, r // clique with relaxed period uses time.Now() as the header.Time, calculate the deadline deadline = time.Unix(int64(header.Time+w.chainConfig.Clique.Period), 0) } - if w.chainConfig.SystemContract != nil && w.chainConfig.SystemContract.RelaxedPeriod { + if w.chainConfig.SystemContract != nil { periodMs := w.chainConfig.SystemContract.Period blocksPerSecond := uint64(1000) / periodMs if blocksPerSecond == 0 { From e282204881656555379609356f2cf16d42ab86cf Mon Sep 17 00:00:00 2001 From: georgehao Date: Sun, 27 Apr 2025 16:52:01 +0800 Subject: [PATCH 05/12] remove unused code --- consensus/system_contract/system_contract.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/consensus/system_contract/system_contract.go b/consensus/system_contract/system_contract.go index 6d1980138ab1..a93968e873fc 100644 --- a/consensus/system_contract/system_contract.go +++ b/consensus/system_contract/system_contract.go @@ -89,9 +89,6 @@ func (s *SystemContract) Start() { } func (s *SystemContract) fetchAddressFromL1() error { - s.signerAddressL1 = common.HexToAddress("0x756EA06BDEe36de11F22DCca45a31d8a178eF3c6") - return nil - address, err := s.client.StorageAt(s.ctx, s.config.SystemContractAddress, s.config.SystemContractSlot, nil) if err != nil { return fmt.Errorf("failed to get signer address from L1 System Contract: %w", err) From 1e378fa512d8057bf1ea0870cd008339c922b144 Mon Sep 17 00:00:00 2001 From: georgehao Date: Wed, 7 May 2025 17:06:59 +0800 Subject: [PATCH 06/12] add logs --- miner/scroll_worker.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 9504639e315b..f02660d111f0 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -399,6 +399,7 @@ func (w *worker) mainLoop() { idleTimer.UpdateSince(idleStart) w.current.deadlineReached = true if len(w.current.txs) > 0 { + log.Info("hhff", "deadlineReached", w.current.deadlineReached, "len(w.current.txs)", len(w.current.txs)) _, err = w.commit() } else if w.config.AllowEmpty { log.Warn("Committing empty block", "number", w.current.header.Number) @@ -414,6 +415,7 @@ func (w *worker) mainLoop() { if w.current != nil { shouldCommit, _ := w.processTxnSlice(ev.Txs) if shouldCommit || (w.current.deadlineReached && len(w.current.txs) > 0) { + log.Info("hhff", "shouldCommit", shouldCommit, "deadlineReached", w.current.deadlineReached, "len(w.current.txs)", len(w.current.txs)) _, err = w.commit() } } From 174859430c4ab7db47b015ef9a208552aced5935 Mon Sep 17 00:00:00 2001 From: georgehao Date: Wed, 7 May 2025 17:41:09 +0800 Subject: [PATCH 07/12] update --- consensus/system_contract/system_contract.go | 3 +++ miner/scroll_worker.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/consensus/system_contract/system_contract.go b/consensus/system_contract/system_contract.go index a93968e873fc..6d1980138ab1 100644 --- a/consensus/system_contract/system_contract.go +++ b/consensus/system_contract/system_contract.go @@ -89,6 +89,9 @@ func (s *SystemContract) Start() { } func (s *SystemContract) fetchAddressFromL1() error { + s.signerAddressL1 = common.HexToAddress("0x756EA06BDEe36de11F22DCca45a31d8a178eF3c6") + return nil + address, err := s.client.StorageAt(s.ctx, s.config.SystemContractAddress, s.config.SystemContractSlot, nil) if err != nil { return fmt.Errorf("failed to get signer address from L1 System Contract: %w", err) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index f02660d111f0..34b7e0223927 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -414,7 +414,7 @@ func (w *worker) mainLoop() { // be automatically eliminated. if w.current != nil { shouldCommit, _ := w.processTxnSlice(ev.Txs) - if shouldCommit || (w.current.deadlineReached && len(w.current.txs) > 0) { + if shouldCommit && len(w.current.txs) > 0 { log.Info("hhff", "shouldCommit", shouldCommit, "deadlineReached", w.current.deadlineReached, "len(w.current.txs)", len(w.current.txs)) _, err = w.commit() } From d088aff281ecdc4616a4078d20d4b55b6f8d5cea Mon Sep 17 00:00:00 2001 From: georgehao Date: Wed, 7 May 2025 18:26:24 +0800 Subject: [PATCH 08/12] update --- miner/scroll_worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 34b7e0223927..54fa9d878444 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -414,7 +414,7 @@ func (w *worker) mainLoop() { // be automatically eliminated. if w.current != nil { shouldCommit, _ := w.processTxnSlice(ev.Txs) - if shouldCommit && len(w.current.txs) > 0 { + if shouldCommit { log.Info("hhff", "shouldCommit", shouldCommit, "deadlineReached", w.current.deadlineReached, "len(w.current.txs)", len(w.current.txs)) _, err = w.commit() } From a7e3c17f674e7b23fc9320c17f4fea17d856021b Mon Sep 17 00:00:00 2001 From: georgehao Date: Wed, 7 May 2025 19:24:29 +0800 Subject: [PATCH 09/12] update --- miner/scroll_worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 54fa9d878444..f02660d111f0 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -414,7 +414,7 @@ func (w *worker) mainLoop() { // be automatically eliminated. if w.current != nil { shouldCommit, _ := w.processTxnSlice(ev.Txs) - if shouldCommit { + if shouldCommit || (w.current.deadlineReached && len(w.current.txs) > 0) { log.Info("hhff", "shouldCommit", shouldCommit, "deadlineReached", w.current.deadlineReached, "len(w.current.txs)", len(w.current.txs)) _, err = w.commit() } From 446492a6c749bc3bd7d4371683073d6c8732a6d5 Mon Sep 17 00:00:00 2001 From: georgehao Date: Wed, 7 May 2025 21:35:11 +0800 Subject: [PATCH 10/12] add more logs --- miner/scroll_worker.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index f02660d111f0..1399e24d7cb6 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -368,6 +368,7 @@ func (w *worker) mainLoop() { // `updateSnapshot` and other functionalities. time.Sleep(5 * time.Second) } + log.Info("hhff", "retrying commit", "err", err, "retryableCommitError", retryableCommitError) if _, err = w.tryCommitNewWork(time.Now(), w.current.header.ParentHash, w.current.reorging, w.current.reorgReason); err != nil { continue } @@ -393,6 +394,7 @@ func (w *worker) mainLoop() { case chainHead := <-w.chainHeadCh: idleTimer.UpdateSince(idleStart) if w.isCanonical(chainHead.Block.Header()) { + log.Info("hhff", "chainHead", "number", chainHead.Block.Number(), "hash", chainHead.Block.Hash().Hex()) _, err = w.tryCommitNewWork(time.Now(), chainHead.Block.Hash(), false, nil) } case <-w.current.deadlineCh(): @@ -1148,6 +1150,7 @@ func (w *worker) handleReorg(trigger *reorgTrigger) error { return nil } + log.Info("hhff tryCommitNewWork", "parentHash", parentHash, "reorgReason", reorgReason) newBlockHash, err := w.tryCommitNewWork(time.Now(), parentHash, true, reorgReason) if err != nil { return err @@ -1157,6 +1160,7 @@ func (w *worker) handleReorg(trigger *reorgTrigger) error { if newBlockHash == (common.Hash{}) { // force committing the new canonical head to trigger a reorg in blockchain // otherwise we might ignore CCC errors from the new side chain since it is not canonical yet + log.Info("hhff", "newBlockHash", newBlockHash, "reorgReason", reorgReason) newBlockHash, err = w.commit() if err != nil { return err From ab1a3312975dc5bede5c072b7f1e161b7cf3740e Mon Sep 17 00:00:00 2001 From: georgehao Date: Fri, 9 May 2025 09:38:25 +0800 Subject: [PATCH 11/12] add tryCommitNewWork log --- miner/scroll_worker.go | 1 + 1 file changed, 1 insertion(+) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 1399e24d7cb6..c947cff03a69 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -630,6 +630,7 @@ func (w *worker) tryCommitNewWork(now time.Time, parent common.Hash, reorging bo } if shouldCommit { + log.Info("hhff", "tryCommitNewWork done", "shouldCommit", shouldCommit, "reorging", reorging, "reorgReason", reorgReason) // if reorging, force committing even if we are not "running" // this can happen when sequencer is instructed to shutdown while handling a reorg // we should make sure reorg is not interrupted From d50ff4ed715e36bc857c93175467c5ae0649bbff Mon Sep 17 00:00:00 2001 From: georgehao Date: Fri, 9 May 2025 10:13:04 +0800 Subject: [PATCH 12/12] add more logs --- miner/scroll_worker.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index c947cff03a69..9fe654996af7 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -613,10 +613,16 @@ func (w *worker) tryCommitNewWork(now time.Time, parent common.Hash, reorging bo if err != nil { return common.Hash{}, fmt.Errorf("failed handling forks: %w", err) } + if shouldCommit { + log.Info("hhff", "handleForks") + } // check if we are reorging if !shouldCommit && w.current.reorging { shouldCommit, err = w.processReorgedTxns(w.current.reorgReason) + if shouldCommit { + log.Info("hhff", "processReorgedTxns") + } } if err != nil { return common.Hash{}, fmt.Errorf("failed handling reorged txns: %w", err) @@ -624,6 +630,9 @@ func (w *worker) tryCommitNewWork(now time.Time, parent common.Hash, reorging bo if !shouldCommit { shouldCommit, err = w.processTxPool() + if shouldCommit { + log.Info("hhff", "processTxPool") + } } if err != nil { return common.Hash{}, fmt.Errorf("failed processing tx pool: %w", err)