-
Notifications
You must be signed in to change notification settings - Fork 282
feat(L1 follower): adjust to recent CodecV7
and contract changes
#1120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…retrieve data from L1
…s submitted in one transaction
…single transactions
…-use-code-from-l1-follower
…1-follower-mode-update-da-codec
…atch within a set of batches
…erifier-use-code-from-l1-follower
…1-follower-mode-update-da-codec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
rollup/da_syncer/syncing_pipeline.go (1)
283-302
: Enhanced reset functionality with metadata persistenceThe reset method has been properly updated to work with the new metadata structure. It reads the current state from the database, adjusts the L1 block number based on the reset counter, and persists the changes back to the database.
Consider extracting the magic number 100 in
amount := 100 * uint64(resetCounter)
to a named constant for better readability and maintainability.+const resetBlockNumberStep = 100 func (s *SyncingPipeline) reset(resetCounter int) { - amount := 100 * uint64(resetCounter) + amount := resetBlockNumberStep * uint64(resetCounter)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
rollup/da_syncer/da/calldata_blob_source.go
(3 hunks)rollup/da_syncer/syncing_pipeline.go
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- rollup/da_syncer/da/calldata_blob_source.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (4)
rollup/da_syncer/syncing_pipeline.go (4)
82-82
: Improved state tracking with more comprehensive metadataThe change from a simple
initialL1Block
to a more structuredlastProcessedBatchMeta
provides better context and tracking of the syncing state, including batch index, L1 block number, and total L1 messages popped.
91-105
: Well-structured recovery mode with L1MessageQueueHeightFinderThe implementation correctly handles the recovery mode by using the L1MessageQueueHeightFinder to determine the L1 message queue height before the initial batch. This aligns with the PR objective of operating without InitialMessageQueueIndex by recursively carrying over the parent's total popped L1 messages.
109-122
: Robust initialization in non-recovery modeThe code properly handles the initialization in non-recovery mode by reading the existing metadata from the database or creating a default entry with appropriate values. The approach ensures continuity of operation and persistence of state across restarts.
125-126
: Updated queue initialization with metadataThe DAQueue and BatchQueue are now correctly initialized with the fields from lastProcessedBatchMeta, providing them with the necessary context about the batch processing state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (6)
rollup/da_syncer/batch_queue.go (6)
10-10
: Consider documenting import usage
The newly added imports forlog
andl1
are clear in context. However, adding a brief comment or docstring where these are used may help future maintainers locate their usage more quickly, especially given the multiple logging approaches and event definitions in the codebase.Also applies to: 12-12
38-39
: Clarify the return ofda.EntryWithBlocks
The method signature ofNextBatch
now returnsda.EntryWithBlocks
instead ofda.Entry
. Consider updating the method doc comment (line 37) to reflect the new return type and its implications.
66-67
: Add final batch check logs
After processing aFinalizeBatchType
, you check for a newly finalized batch. Logging a short message here could help operators see that finalization triggered an immediate return of a new batch.
75-76
: Loop over potentially multiple finalized batches
nextFinalizedBatch
currently returns on the first batch in the heap if it meets the finalized index condition. If multiple batches in the heap fall under that condition, you may need a loop to process them all. Confirm whether partial processing is intended.Also applies to: 82-83, 85-85
96-120
: Enhance logging inhandleRevertEvent
The revert event logic is sound. However, adding a log statement for each revert action would help diagnose unexpected revert ranges or repeated reverts. You may also want to confirm thatStartBatchIndex <= FinishBatchIndex
before looping to avoid potential no-op or invalid range errors.
134-167
: Clarify batch metadata write order
InprocessAndDeleteBatch
, the code writes the oldpreviousBatch
to disk before assigning the new batch topreviousBatch
. This design might be intentional, but it can be confusing since the new batch is the one being processed. Documenting why the old metadata is persisted just before overwriting would help avoid confusion.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sum
is excluded by!**/*.sum
📒 Files selected for processing (2)
go.mod
(1 hunks)rollup/da_syncer/batch_queue.go
(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- go.mod
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (4)
rollup/da_syncer/batch_queue.go (4)
22-24
: Validate or documentpreviousBatch
initialization
DeclaringpreviousBatch
in the struct is a good approach for maintaining state. However, ensure that callers never passnil
forlastProcessedBatch
inNewBatchQueue
, or handle that case gracefully. Otherwise, accessingBatchIndex
on anil
struct could cause a runtime panic.
58-60
: Approach revert events with caution
When a revert event is encountered, the logic delegates handling tohandleRevertEvent
. Make sure there's no concurrency gap that could cause new finalizations or commits to slip in during revert processing. If concurrency is possible, consider adding synchronization or queue pausing around this call.
122-132
: Check references when deleting the current batch
ThedeleteBatch
method cleanly removes a batch from bothbatches
andbatchesMap
. However, consider verifying that if the current peek or last accessed batch is removed, no stale references remain.
170-175
: Confirm expected workflow afterReset
TheReset
method resets the queue and updatespreviousBatch
to the provided metadata. If there's any need to re-queue items based on the new state, ensure that's handled elsewhere. Documenting theReset
workflow can prevent misunderstandings about system state post-reset.
…which would always be decoded to non-existing instead of 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
rollup/da_syncer/l1_message_queue_height_finder.go (1)
70-105
: Consider adding a timeout or maximum iteration limit to prevent potential infinite loops.The
findFinalizedBundle
method iteratively processes data entries until it finds the bundle containing the target batch. While the implementation is correct, there is no timeout or limit on the number of iterations, which could potentially lead to an infinite loop if the target batch is never found (e.g., due to data corruption or if the target batch was reverted).Consider adding a timeout or maximum iteration limit:
func (f *L1MessageQueueHeightFinder) findFinalizedBundle(targetBatch uint64, batches map[uint64]da.EntryWithBlocks) (*da.FinalizeBatch, error) { + maxIterations := 10000 // Adjust as needed + iterCount := 0 for { + if iterCount >= maxIterations { + return nil, fmt.Errorf("exceeded maximum iterations (%d) while searching for batch %d", maxIterations, targetBatch) + } + iterCount++ // Rest of the method remains unchanged } }Alternatively, you could use a context with timeout:
func (f *L1MessageQueueHeightFinder) findFinalizedBundle(targetBatch uint64, batches map[uint64]da.EntryWithBlocks) (*da.FinalizeBatch, error) { + ctx, cancel := context.WithTimeout(f.ctx, 5*time.Minute) // Adjust timeout as needed + defer cancel() for { + select { + case <-ctx.Done(): + return nil, fmt.Errorf("timeout while searching for batch %d: %w", targetBatch, ctx.Err()) + default: + } // Rest of the method remains unchanged } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sum
is excluded by!**/*.sum
📒 Files selected for processing (4)
core/rawdb/accessors_l1_message.go
(2 hunks)params/version.go
(1 hunks)rollup/da_syncer/l1_message_queue_height_finder.go
(1 hunks)rollup/da_syncer/syncing_pipeline.go
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- params/version.go
🔇 Additional comments (9)
core/rawdb/accessors_l1_message.go (2)
386-389
: Improved efficiency by using direct binary encodingGood optimization by switching from big.Int conversion to direct binary encoding for storing uint64 values. This approach:
- Reduces memory allocations
- Ensures consistent 8-byte representation
- Makes the code more straightforward
406-409
: Improved uint64 retrieval with direct binary decodingGood simplification of the data validation and conversion process. The new approach:
- Simply checks for the expected 8-byte length
- Uses direct binary decoding instead of big.Int conversion
- Maintains backward compatibility by returning nil for invalid lengths
rollup/da_syncer/syncing_pipeline.go (4)
82-107
: Well-structured recovery mode implementation with good error handling.The implementation has been updated to use a comprehensive
DAProcessedBatchMeta
structure instead of simple block numbers, which provides better tracking of the syncing state. The code properly validates inputs (checking for zero values in lines 84-89) and uses the newL1MessageQueueHeightFinder
to determine the L1 message queue height before the initial batch.The error handling is thorough, with descriptive error messages that will help with debugging if issues arise.
109-122
: Good implementation of non-recovery mode initialization.The code appropriately reads the last processed batch metadata from the database or initializes it with default values if not found. The initialization logic for the L1 block number is sensible, using the deployment block minus one when available.
The persistence handling with
rawdb.WriteDAProcessedBatchMeta
ensures data consistency between runs.
125-127
: Clean initialization of queue components with metadata.The initialization of
daQueue
andbatchQueue
now properly uses the comprehensivelastProcessedBatchMeta
instead of individual parameters, which maintains consistency in the syncing state.
283-302
: Reset logic properly handles state regression.The reset method now correctly reads the batch metadata from the database, updates the L1 block number based on the reset counter, and persists the changes. The incremental backing up strategy (using
100 * uint64(resetCounter)
) provides a good balance between responsiveness and recovery capacity.One thing to consider: if
InitialL1Block
is less thanamount
, the subtraction on line 290 could underflow. However, this should be rare in practice since the initial L1 block is typically large and reset counts are small.rollup/da_syncer/l1_message_queue_height_finder.go (3)
13-30
: Well-structured implementation of L1MessageQueueHeightFinder.The struct and its constructor are well-designed with appropriate error handling. The constructor properly initializes the calldata blob source and returns meaningful errors if initialization fails.
32-68
: Solid implementation of L1 message height calculation logic.The
TotalL1MessagesPoppedBefore
method implements a clear algorithm for finding the L1 message queue height before a target batch. The code:
- Finds the finalized bundle containing the target batch
- Fetches transaction data to get the message queue height after the bundle
- Calculates backwards to determine the height before the target batch
Error handling is thorough, with checks for missing batches and potential underflows.
107-131
: Good implementation of revert event handling with support for batch ranges.The
handleRevertEvent
method properly handles different types of revert events, including the new V7 type that supports reverting a range of batches. The error handling is thorough with descriptive error messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
Dockerfile.mockccc (2)
14-15
: Recommendation: Use COPY Instead of ADD
Static analysis (Hadolint DL3020) suggests usingCOPY
in place ofADD
when merely copying files or directories. Since there is no need for archive extraction or remote URL retrieval in this context, replacingADD . ./
withCOPY . ./
would improve clarity and adhere to best practices. Consider applying the following diff:-ADD . ./ +COPY . ./🧰 Tools
🪛 Hadolint (2.12.0)
[error] 14-14: Use COPY instead of ADD for files and folders
(DL3020)
20-21
: Clarify Commented Package Installation Command
The previously activeapt-get
command is now fully commented out. If this command is no longer needed, consider removing it altogether to clean up the Dockerfile. Otherwise, add a clarifying comment explaining why it remains commented (e.g., documentation on dependency requirements for future reference).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.dockerignore
(1 hunks)Dockerfile.mockccc
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .dockerignore
🧰 Additional context used
🪛 Hadolint (2.12.0)
Dockerfile.mockccc
[error] 14-14: Use COPY instead of ADD for files and folders
(DL3020)
🔇 Additional comments (1)
Dockerfile.mockccc (1)
10-12
: Approval of Dependency Caching Setup
The modifications setting the working directory (WORKDIR /go-ethereum
) and copying thego.mod
andgo.sum
files followed by runninggo mod download -x
are well implemented. This change improves dependency caching and build efficiency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
rollup/da_syncer/batch_queue.go (1)
26-35
:⚠️ Potential issueCheck for potential nil pointer dereference.
lastProcessedBatch.BatchIndex
is accessed without a defensive check. IflastProcessedBatch
can benil
, a panic could occur.func NewBatchQueue(DAQueue *DAQueue, db ethdb.Database, lastProcessedBatch *rawdb.DAProcessedBatchMeta) *BatchQueue { + if lastProcessedBatch == nil { + log.Crit("lastProcessedBatch cannot be nil in NewBatchQueue") + } return &BatchQueue{ ... } }
🧹 Nitpick comments (4)
rollup/da_syncer/batch_queue.go (2)
22-23
: Consider documenting the purpose ofpreviousBatch
.
A brief comment on howpreviousBatch
is used (e.g., storing the last processed batch metadata) would improve clarity.
96-123
: Consider efficiency for large revert ranges.
Looping fromStartBatchIndex
toFinishBatchIndex
might be slow if the range is large. If performance becomes critical, consider more efficient ways to handle extensive batch reverts.rollup/da_syncer/l1_message_queue_height_finder.go (2)
13-17
: Add struct-level comments for clarity.
A short description of howL1MessageQueueHeightFinder
determines the queue height would be helpful.
112-136
: Potential duplication of revert handling logic.
This revert event loop mirrorshandleRevertEvent
logic inbatch_queue.go
. Consider refactoring into a shared helper if feasible to avoid maintenance overhead.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
rollup/da_syncer/batch_queue.go
(5 hunks)rollup/da_syncer/l1_message_queue_height_finder.go
(1 hunks)rollup/l1/abi.go
(5 hunks)
🔇 Additional comments (24)
rollup/l1/abi.go (14)
27-27
: Updated ScrollChain ABI with new functionalitiesThe ABI definition has been significantly updated with new functions, events, and error types, which is consistent with the PR objective to adjust to recent
CodecV7
and contract changes.
38-41
: Improved RevertEvent type handlingGood refactoring of the RevertEvent types to support both legacy (V0-V6) and new V7 (EuclidV2) format. This change allows the system to properly handle batch reversions in both formats, with V7 introducing the ability to revert a range of batches.
47-49
: Added new method names for V7 compatibilityThe addition of
commitBatchesV7MethodName
andfinalizeBundlePostEuclidV2MethodName
properly supports the new contract functions introduced in the ScrollChain update.
110-113
: LGTM: Renamed RevertBatch event unpacked structThe RevertBatchEventV0Unpacked struct properly maintains the original structure for backward compatibility with V0-V6 events.
115-122
: Clear type differentiation for RevertBatch eventsGood approach to explicitly differentiate the V0 and V7 versions of the RevertBatch event by renaming the original to RevertBatchEventV0 and clearly documenting its applicable version range.
136-138
: Correct implementation of event type identificationThe Type() method correctly returns the newly defined RevertEventV0Type constant, ensuring proper event type identification.
148-151
: Added support for batch range reversionThe RevertBatchEventV7Unpacked struct correctly implements the new event structure that allows reverting a range of batches through start and finish indices.
153-162
: Well-structured implementation of V7 revert eventThe RevertBatchEventV7 struct implementation is well-documented and properly handles the new event format that supports reverting a range of batches, which is a key feature introduced in V7 (EuclidV2).
190-198
: LGTM: Clear accessor methods for batch rangeThe StartBatchIndex() and FinishBatchIndex() accessors provide a clear API for retrieving the range boundaries of the reverted batches, which is essential for properly handling the new V7 revert events.
295-299
: Added new batch hash fields to support V7The CommitBatchArgs struct has been updated with ParentBatchHash and LastBatchHash fields to support the new relationships between batches in CodecV7, aligning with the PR objectives.
321-333
: Well-implemented argument parsing for CommitBatchesV7The newCommitBatchArgsFromCommitBatchesV7 function correctly handles the new argument structure for V7 batch commits, extracting the necessary hash references (ParentBatchHash and LastBatchHash) needed for the updated contract interface.
343-347
: LGTM: Clean V7 commit arguments structureThe commitBatchesV7Args struct cleanly defines the parameters needed for the new commitBatches method, focusing on the batch hashes instead of the more verbose structures used in earlier versions.
349-355
: Comprehensive finalization arguments structureThe FinalizeBatchArgs struct properly captures all the parameters needed for batch finalization, including the important TotalL1MessagesPoppedOverall field that replaces the deprecated InitialMessageQueueIndex mentioned in the PR objectives.
357-364
: LGTM: Helper function for finalization argumentsThe newFinalizeBatchArgs function provides a clean interface for parsing finalization arguments from ABI-encoded values, maintaining consistent error handling with the other argument parsing functions.
rollup/da_syncer/batch_queue.go (7)
58-60
: Good error handling for revert events.
It’s good to see the revert handling logic returning the error immediately for proper upstream handling.
66-66
: Finalized batch retrieval logic seems sound.
This early return pattern is consistent with the pipeline-based approach.
75-89
: Incremental finalization logic approved.
Returning only one finalized batch at a time is a common and straightforward design for pipelines.
125-135
: Deletion mechanism looks clean.
This is a straightforward way to remove entries from both the heap and map, returning whether a deletion occurred.
137-171
: Verify the logic for persisting the “previousBatch” vs. the newly processed batch.
The code writesbq.previousBatch
to the database but then reassignsbq.previousBatch
to the freshly processed batch. Double-check that this correctly persists the state you intend, especially if the final step fails.
173-179
: Reset method implementation is straightforward.
Clearing queued batches and resetting counters aligns with re-initialization requirements.
38-39
:✅ Verification successful
Verify all callers of
NextBatch
use the new return type.
NextBatch
now returnsda.EntryWithBlocks
instead ofda.Entry
. Ensure all consumers handle this updated type.
🏁 Script executed:
#!/bin/bash # Search references to NextBatch across the repository to confirm updated usage rg -A 3 'NextBatch\s*\('Length of output: 531
All callers are correctly updated to handle the new return type from NextBatch.
Verified that the method now returnsda.EntryWithBlocks
and its usage inrollup/da_syncer/block_queue.go
is correctly adjusted (assigning the result toentryWithBlocks
, followed by appropriate error handling).
• rollup/da_syncer/batch_queue.go – Method signature updated to(da.EntryWithBlocks, error)
.
• rollup/da_syncer/block_queue.go – Caller now correctly assigns toentryWithBlocks
and handles errors.rollup/da_syncer/l1_message_queue_height_finder.go (3)
19-30
: Initialization and error handling look good.
This constructor’s approach of returning an error upon calldata source creation failure is good defensive coding.
55-58
: Double-check subtracting 1 fromargs.TotalL1MessagesPoppedOverall
.
Confirm this aligns with the intended semantics: if the value is zero, we skip, if it’s > 0, we decrement by 1.
75-110
: Consider adding timeout or break conditions.
The loop continues fetching data until a finalize event fortargetBatch
is found. If it never arrives, this may block indefinitely.
1. Purpose or design rationale of this PR
This PR is a collection of changes to adjust to recent changes in
CodecV7
and contracts.initialL1MessageQueueHash
->prevL1MessageQueueHash
andlastL1MessageQueueHash
->postL1MessageQueueHash
InitialMessageQueueIndex
from blob payload: in normal operation of the L1 follower mode we assume a sync from genesis. Therefore, we can carry over the parent's total popped L1 messages recursively.RevertEvent(startBatchIndex,endBatchIndex)
to revert a range of batchesInitialMessageQueueIndex
: implementL1MessageQueueHeightFinder
to determine the L1 message queue height for a given target batch from its finalized bundleScrollChain
ABIcommitBatches
function inl1.Reader
to be able to read calldata from new commit functions2. PR title
Your PR title must follow conventional commits (as we are doing squash merge for each PR), so it must start with one of the following types:
3. Deployment tag versioning
Has the version in
params/version.go
been updated?4. Breaking change label
Does this PR have the
breaking-change
label?Summary by CodeRabbit
New Features
L1MessageQueueHeightFinder
for calculating L1 message queue height.Improvements
Chores
.dockerignore
to exclude thetmp/
directory.Tests