|
| 1 | +<pre> |
| 2 | + BEP: 543 |
| 3 | + Title: opBNB Shorter Block Interval |
| 4 | + Status: Draft |
| 5 | + Type: Standards |
| 6 | + Created: 2025-03-14 |
| 7 | + Description: To shorten opBNB block interval from 1 second to 500 milliseconds. |
| 8 | +</pre> |
| 9 | + |
| 10 | +# BEP-543: opBNB Short Block Interval |
| 11 | +- [BEP-543: Shorten opBNB block interval from 1 second to 500 milliseconds](#bep-opbnb-short-block-interval) |
| 12 | + - [1. Summary](#1-summary) |
| 13 | + - [2. Abstract](#2-abstract) |
| 14 | + - [3. Motivation](#3-motivation) |
| 15 | + - [4. Specification](#4-specification) |
| 16 | + - [4.1 Millisecond Representation in opBNB Block Header](#41-millisecond-representation-in-opbnb-block-header) |
| 17 | + - [4.2 Timestamp of RawSpanBatch](#42-timestamp-of-rawspanbatch) |
| 18 | + - [4.3 Parameter Changes](#43-parameter-changes) |
| 19 | + - [5. Rational](#5-rational) |
| 20 | + - [5.1 SeqWindowSize and MaxSequencerDrift](#51-seqwindowsize-and-maxsequencerdrift) |
| 21 | + - [5.2 ChannelTimeout and MaxChannelDuration](#52-channeltimeout-and-maxchannelduration) |
| 22 | + - [5.3 op-proposer propose interval](#53-op-proposer-propose-interval) |
| 23 | + - [5.4 op-batcher commit Blob data](#54-op-batcher-commit-blob-data) |
| 24 | + - [6. Backward Compatibility](#6-backward-compatibility) |
| 25 | + - [6.1 DApp Developers And Users](#61-dapp-developers-and-users) |
| 26 | + - [7. License](#7-license) |
| 27 | + |
| 28 | +## 1. Summary |
| 29 | +Shorten the block interval from 1 second to 500 milliseconds to adapt BSC shorter block interval change and also enable faster transaction confirmation, improving user experience. |
| 30 | + |
| 31 | +## 2. Abstract |
| 32 | +BSC has started to shorten block intervals [(BEP-524)](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md) to sub-seconds. As the L2 of BSC, opBNB needs to adapt to the change. As design opBNB’s block interval should be less than BSC’s. |
| 33 | +Lower block time intervals can provide quicker transaction confirmation and better user experience. |
| 34 | +This BEP is mainly to reduce the opBNB block time from 1 second to 500 milliseconds. |
| 35 | + |
| 36 | +## 3. Motivation |
| 37 | +After BSC network moves to the 750 milliseconds block time interval, opBNB will never be able to sync to the latest cross-chain messages and stop producing blocks. |
| 38 | +It is required that opBNB reduces the block time interval to adapt. And besides this, reducing block time intervals will make opBNB more competitive and better meet users’ expectations. |
| 39 | + |
| 40 | +## 4. Specification |
| 41 | + |
| 42 | +### 4.1 Millisecond Representation in opBNB Block Header |
| 43 | +Referencing [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md), the millisecond time for opBNB is also stored in the `Header.MixDigest`. This field is populated by the value from the `Header.MixDigest` of the BSC. Consequently, |
| 44 | +the last two bytes of opBNB's `Header.MixDigest` are utilized to store the BSC millisecond time. To prevent any potential conflicts, opBNB has reserved the first two bytes specifically for its own millisecond time. |
| 45 | +After the hard fork, all modules of opBNB will switch from second-level timestamps to millisecond-level timestamps, and a flag will be set in the `Header.MixDigest` field to indicate that it has started storing milliseconds. |
| 46 | +This careful structuring ensures compatibility while optimizing both chains' functionality. |
| 47 | +The opBNB BlockTime is calculated by op-node and distributed to op-geth through `PayloadAttributes`. Therefore, the millisecond timestamp will be written into `PayloadAttributes` and then copied to the opBNB Block Header. |
| 48 | + |
| 49 | +```Go |
| 50 | +// SetMillisecondTimestamp is used to set millisecond timestamp. |
| 51 | +// [32]byte PrevRandao |
| 52 | +// [0][1] represent l2 millisecond's mill part. |
| 53 | +func (pa *PayloadAttributes) SetMillisecondTimestamp(ts uint64, updateMilliSecond bool) { |
| 54 | + pa.Timestamp = hexutil.Uint64(ts / 1000) |
| 55 | + if updateMilliSecond { |
| 56 | + milliPartBytes := uint256.NewInt(ts % 1000).Bytes32() |
| 57 | + pa.PrevRandao[0] = milliPartBytes[30] |
| 58 | + pa.PrevRandao[1] = milliPartBytes[31] |
| 59 | + |
| 60 | + // It is just a marker byte to ensure that the whole is not empty; |
| 61 | + // op-geth relies on non-empty to determine that the passed in millisecond timestamp. |
| 62 | + pa.PrevRandao[2] = 1 |
| 63 | + } |
| 64 | +} |
| 65 | + |
| 66 | +// millisecondes returns milliseconds of header |
| 67 | +unc (h *Header) millisecondes() uint64 { |
| 68 | + if h.MixDigest == (common.Hash{}) { |
| 69 | + return 0 |
| 70 | + } |
| 71 | + return uint256.NewInt(0).SetBytes2(h.MixDigest[:2]).Uint64() |
| 72 | +} |
| 73 | + |
| 74 | +// MilliTimestamp returns timestamp in milliseconds |
| 75 | +func (h *Header) MilliTimestamp() uint64 { |
| 76 | + return h.Time*1000 + h.millisecondes() |
| 77 | +} |
| 78 | + |
| 79 | +// SecondsTimestamp returns timestamp in seconds |
| 80 | +func (h *Header) SecondsTimestamp() uint64 { |
| 81 | + return h.Time |
| 82 | +} |
| 83 | + |
| 84 | +// NextMilliTimestamp returns next block's timestamp in milliseconds |
| 85 | +func (h *Header) NextMilliTimestamp() uint64 { |
| 86 | + if h.MixDigest == (common.Hash{}) { |
| 87 | + return h.Time*1000 + 1000 |
| 88 | + } |
| 89 | + return h.MilliTimestamp() + 500 |
| 90 | +} |
| 91 | + |
| 92 | +// NextSecondsTimestamp returns next block's timestamp in seconds |
| 93 | +func (h *Header) NextSecondsTimestamp() uint64 { |
| 94 | + return h.NextMilliTimestamp() / 1000 |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +To ensure forward compatibility, millisecond timestamps can be identified by checking `h.MixDigest == (common.Hash{})`; if not enabled, the timestamps will continue to be in second-level format. |
| 99 | + |
| 100 | +* `MilliTimestamp` returns the millisecond-level block timestamp to enable opBNB to support sub-second block production. |
| 101 | +* `NextMilliTimestamp` may be called when verifying the time relationship between parent and child blocks. |
| 102 | +* `NextSecondsTimestamp` and `SecondsTimestamp` will be called when checking for forks, as forks still use second-level timestamps. |
| 103 | + |
| 104 | + |
| 105 | +### 4.2 Timestamp of RawSpanBatch |
| 106 | +`RawSpanBatch` serves as a streamlined storage format for L2Block on opBNB and does not have reserved unused fields for storing millisecond timestamps. The timestamps within `RawSpanBatch` |
| 107 | + are converted from second-level timestamps to millisecond timestamps after the hard fork. |
| 108 | + |
| 109 | +### 4.3 Parameter Changes |
| 110 | +A multitude of system parameters are configured based on the assumption that the default block interval is 1 second. Consequently, when the block interval is altered, these parameters must be adjusted accordingly: |
| 111 | + |
| 112 | + |
| 113 | +|parameter |type | origin(1s) | new(500ms)| |
| 114 | +|--------|--------|--------|--------| |
| 115 | +|L1EpochPollInterval |op-node parameter |3s |1.5s/750ms | |
| 116 | +|BlockTime |op-node parameter |1s |500ms | |
| 117 | +|MaxSequencerDrift |op-node parameter |1800 |3600/7200 | |
| 118 | +|SeqWindowSize |op-node parameter |14400 |28800/57600 | |
| 119 | +|ChannelTimeout |op-node parameter |1200 |2400/4800 | |
| 120 | +|MaxChannelDuration |op-batcher parameter |32 |64/128 | |
| 121 | +|TargetNumFrames |op-batcher parameter |6 |3/2 | |
| 122 | + |
| 123 | +The items in the list that depend on BSC's block time will have two new values, primarily relying on the timing of the BSC hard forks for [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md) and [BEP-524](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md). |
| 124 | + |
| 125 | +The BlockTime configuration, which was previously specified in seconds, will transition to a millisecond-based unit. For instance, if it was originally set to 1 to represent 1 second, |
| 126 | +it must now be adjusted to 1000 post-upgrade to preserve the same functionality. Additionally, it is advisable to avoid configuring block times shorter than 100 milliseconds. |
| 127 | + |
| 128 | +## 5. Rational |
| 129 | +### 5.1 SeqWindowSize and MaxSequencerDrift |
| 130 | +SeqWindowSize and MaxSequencerDrift are measured in block numbers. |
| 131 | +SeqWindowSize origin value 14400 means that if opBNB fails and does not recover within 14400 * 3s (BSC BlockTime) = 24 hours, opBNB will be permanently irrecoverable. |
| 132 | +MaxSequencerDrift origin value 1800 means that after BSC stops producing blocks, opBNB can still produce blocks, but if it exceeds 1800 * 1s (opBNB BlockTime) = 30 minutes, it will stop producing blocks. |
| 133 | +Therefore, although both are measured in block numbers, they indeed reflect a measurement of time. With the forks of BSC and opBNB, the time for handling exceptional situations cannot be shortened, |
| 134 | +so these parameters need to be adjusted proportionally. |
| 135 | + |
| 136 | +### 5.2 ChannelTimeout and MaxChannelDuration |
| 137 | +ChannelTimeout and MaxChannelDuration are both measured in BSC block numbers, representing the timeout periods for uploading and downloading L2 blocks in the channel. As the BSC BlockTime shortens, |
| 138 | +the configuration for storing the same amount of data in the pipeline needs to be increased proportionally. |
| 139 | + |
| 140 | +### 5.3 op-Proposer propose interval |
| 141 | +The interval for op-proposer to propose the state root remains 3600(30min), instead of 7200(1h), primarily considering the following three points: |
| 142 | +* The recovery time after a sequencer restart remains the same or even becomes faster. |
| 143 | +* Compatibility for users obtaining withdrawal proofs based on the Block Number (the most recent Block Number divisible by 3600). |
| 144 | +* The waiting time for users to prove a withdrawal initiated in opBNB has been reduced from 1 hour to 30 minutes. |
| 145 | + |
| 146 | +### 5.4 op-Batcher submit Blob data |
| 147 | +As [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md) describes, the block handles 1 blob per second, blob maximum is 2. Op-batcher will adjust the configuration item TargetNumFrames accordingly. |
| 148 | + |
| 149 | +## 6. Backward Compatibility |
| 150 | +### 6.1 DApp Developers And Users |
| 151 | +The impact on DApp developers and users is similar to that of [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md), primarily affecting **Timing Based on Block Numbers** and **Indexing Based on block.timestamp**. A common solution is to use the block hash instead. |
| 152 | + |
| 153 | +## 7. License |
| 154 | +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
0 commit comments