From 976ce38e96de0a2185f6e43633eb20ebde228604 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Fri, 15 Sep 2023 20:42:55 +0900 Subject: [PATCH 1/3] Update span batch specs to allow overlapping batches --- specs/span-batches.md | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/specs/span-batches.md b/specs/span-batches.md index 3314a19aa457..26883706413e 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -63,6 +63,8 @@ Span-batches address these inefficiencies, with a new batch format version. ## Span batch format +[span-batch-format]: #span-batch-format + Note that span-batches, unlike previous singular batches, encode *a range of consecutive* L2 blocks at the same time. @@ -221,7 +223,7 @@ The assumption makes upper inequality to hold. Therefore, we decided to manage ` - If the last block references canonical L1 chain as its origin, we can ensure the all other blocks' origins are consistent with the canonical L1 chain. - Parent hash - - In V0 Batch spec, we need batch's parent hash to validate if batch's parent is consistent with current L2 safe head. + - In V0 Batch spec, we need batch's parent hash to validate if batch's parent is consistent with current L2 chain. - But in the case of Span Batch, because it contains consecutive L2 blocks in the span, we do not need to validate all blocks' parent hash except the first block. - Transactions @@ -248,14 +250,21 @@ Span-batches share the same queue with v0 batches: batches are processed in L1 i A set of modified validation rules apply to the span-batches. Rules are enforced with the [contextual definitions](./derivation.md#batch-queue) as v0-batch validation: -`batch`, `epoch`, `inclusion_block_number`, `next_timestamp`, `next_epoch`, `batch_origin` +`epoch`, `inclusion_block_number`, `next_timestamp` + +Definitions: + +- `batch` as defined in the [Span batch format section][span-batch-format]. +- `prev_l2_block` is the L2 block from the current safe chain, + whose timestamp is at `span_start.timestamp - l2_block_time` Span-batch rules, in validation order: -- `batch.start_timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process. -- `batch.start_timestamp < next_timestamp` -> `drop`: i.e. the batch must not be too old. -- `batch.parent_check != safe_l2_head.hash[:20]` -> `drop`: i.e. the checked part of the parent hash must be equal - to the L2 safe head block hash. +- `span_start.timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process. +- `span_end.timestamp < next_timestamp` -> `drop`: i.e. the batch must have at least one new block. +- If there's no `prev_l2_block` in the current safe chain -> `drop`: i.e. misaligned timestamp +- `batch.parent_check != prev_l2_block.hash[:20]` -> `drop`: + i.e. the checked part of the parent hash must be equal to the corresponding safe block. - Sequencing-window checks: - Note: The sequencing window is enforced for the *batch as a whole*: if the batch was partially invalid instead, it would drop the oldest L2 blocks, @@ -267,7 +276,7 @@ Span-batch rules, in validation order: - Rules: - `start_epoch_num + sequence_window_size < inclusion_block_number` -> `drop`: i.e. the batch must be included timely. - - `start_epoch_num > epoch.number + 1` -> `drop`: + - `start_epoch_num > prev_l2_block.l1_origin.number + 1` -> `drop`: i.e. the L1 origin cannot change by more than one L1 block per L2 block. - If `batch.l1_origin_check` does not match the canonical L1 chain at `end_epoch_num` -> `drop`: verify the batch is intended for this L1 chain. @@ -275,9 +284,8 @@ Span-batch rules, in validation order: is past `inclusion_block_number` because of the following invariant. - Invariant: the epoch-num in the batch is always less than the inclusion block number, if and only if the L1 epoch hash is correct. - - `start_epoch_num < epoch.number` -> `drop`: must have been duplicate batch, - we may be past this L1 block in the safe L2 chain. If a span-batch overlaps with older information, - it is dropped, since partially valid span-batches are not accepted. + - `start_epoch_num < prev_l2_block.l1_origin.number` -> `drop`: + epoch number cannot be older than the origin of parent block - Max Sequencer time-drift checks: - Note: The max time-drift is enforced for the *batch as a whole*, to keep the possible output variants small. - Variables: @@ -286,7 +294,7 @@ Span-batch rules, in validation order: - `next_epoch`: `block_input.origin`'s next L1 block. It may reach to the next origin outside the L1 origins of the span. - Rules: - - For each `block_input` that can be read from the span-batch: + - For each `block_input` whose timestamp is greater than `safe_head.timestamp`: - `block_input.timestamp < block_input.origin.time` -> `drop`: enforce the min L2 timestamp rule. - `block_input.timestamp > block_input.origin.time + max_sequencer_drift`: enforce the L2 timestamp drift rule, but with exceptions to preserve above min L2 timestamp invariant: @@ -305,6 +313,17 @@ Span-batch rules, in validation order: that is invalid or derived by other means exclusively: - any transaction that is empty (zero length `tx_data`) - any [deposited transactions][g-deposit-tx-type] (identified by the transaction type prefix byte in `tx_data`) +- Overlapped blocks checks: + - Note: If the span batch overlaps the current L2 safe chain, we must validate all overlapped blocks. + - Variables: + - `block_input`: an L2 block derived from the span-batch. + - `safe_block`: an L2 block from the current L2 safe chain, at same timestamp as `block_input` + - Rules: + - For each `block_input`, whose timestamp is less than `next_timestamp`: + - If there's no `safe_block` for the `block_input` -> `drop`: i.e. misaligned timestamp + - `block_input.l1_origin.number != safe_block.l1_origin.number` -> `drop` + - `block_input.transactions != safe_block.transactions` -> `drop` + - compare excluding deposit transactions Once validated, the batch-queue then emits a block-input for each of the blocks included in the span-batch. The next derivation stage is thus only aware of individual block inputs, similar to the previous V0 batch, From 753a552005f57fd873a8eef53ebc7f01f9c55a62 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 16 Oct 2023 15:53:14 +0900 Subject: [PATCH 2/3] Revert unnecessary change in spec --- specs/span-batches.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/span-batches.md b/specs/span-batches.md index 26883706413e..f0b97cd82741 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -223,7 +223,7 @@ The assumption makes upper inequality to hold. Therefore, we decided to manage ` - If the last block references canonical L1 chain as its origin, we can ensure the all other blocks' origins are consistent with the canonical L1 chain. - Parent hash - - In V0 Batch spec, we need batch's parent hash to validate if batch's parent is consistent with current L2 chain. + - In V0 Batch spec, we need batch's parent hash to validate if batch's parent is consistent with current L2 safe head. - But in the case of Span Batch, because it contains consecutive L2 blocks in the span, we do not need to validate all blocks' parent hash except the first block. - Transactions From 81cbf88ebc2797a3078a2de2ae4ed4fc21be6130 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Thu, 26 Oct 2023 15:26:26 +0900 Subject: [PATCH 3/3] Remove redundant rule --- specs/span-batches.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/span-batches.md b/specs/span-batches.md index f0b97cd82741..9505c5cc6630 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -320,7 +320,6 @@ Span-batch rules, in validation order: - `safe_block`: an L2 block from the current L2 safe chain, at same timestamp as `block_input` - Rules: - For each `block_input`, whose timestamp is less than `next_timestamp`: - - If there's no `safe_block` for the `block_input` -> `drop`: i.e. misaligned timestamp - `block_input.l1_origin.number != safe_block.l1_origin.number` -> `drop` - `block_input.transactions != safe_block.transactions` -> `drop` - compare excluding deposit transactions