From 2f9555e589fa25928b54b292fda67c5c8f76cba6 Mon Sep 17 00:00:00 2001 From: georgehao Date: Sun, 27 Apr 2025 11:22:33 +0800 Subject: [PATCH 1/5] 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 2/5] 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 3/5] 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 4/5] 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 5/5] 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)