-
Notifications
You must be signed in to change notification settings - Fork 284
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
initialL1Blockto a more structuredlastProcessedBatchMetaprovides 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 forlogandl1are 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 ofNextBatchnow returnsda.EntryWithBlocksinstead 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
nextFinalizedBatchcurrently 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 <= FinishBatchIndexbefore looping to avoid potential no-op or invalid range errors.
134-167: Clarify batch metadata write order
InprocessAndDeleteBatch, the code writes the oldpreviousBatchto 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.sumis 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 documentpreviousBatchinitialization
DeclaringpreviousBatchin the struct is a good approach for maintaining state. However, ensure that callers never passnilforlastProcessedBatchinNewBatchQueue, or handle that case gracefully. Otherwise, accessingBatchIndexon anilstruct 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
ThedeleteBatchmethod cleanly removes a batch from bothbatchesandbatchesMap. However, consider verifying that if the current peek or last accessed batch is removed, no stale references remain.
170-175: Confirm expected workflow afterReset
TheResetmethod resets the queue and updatespreviousBatchto the provided metadata. If there's any need to re-queue items based on the new state, ensure that's handled elsewhere. Documenting theResetworkflow 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
findFinalizedBundlemethod 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.sumis 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
DAProcessedBatchMetastructure 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 newL1MessageQueueHeightFinderto 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.WriteDAProcessedBatchMetaensures data consistency between runs.
125-127: Clean initialization of queue components with metadata.The initialization of
daQueueandbatchQueuenow properly uses the comprehensivelastProcessedBatchMetainstead 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
InitialL1Blockis 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
TotalL1MessagesPoppedBeforemethod 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
handleRevertEventmethod 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 usingCOPYin place ofADDwhen 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-getcommand 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.modandgo.sumfiles followed by runninggo mod download -xare 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.BatchIndexis accessed without a defensive check. IflastProcessedBatchcan 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 howpreviousBatchis used (e.g., storing the last processed batch metadata) would improve clarity.
96-123: Consider efficiency for large revert ranges.
Looping fromStartBatchIndextoFinishBatchIndexmight 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 howL1MessageQueueHeightFinderdetermines the queue height would be helpful.
112-136: Potential duplication of revert handling logic.
This revert event loop mirrorshandleRevertEventlogic 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
CodecV7and 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
commitBatchesV7MethodNameandfinalizeBundlePostEuclidV2MethodNameproperly 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.previousBatchto the database but then reassignsbq.previousBatchto 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:Details
✅ Verification successful
Verify all callers of
NextBatchuse the new return type.
NextBatchnow returnsda.EntryWithBlocksinstead 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.EntryWithBlocksand its usage inrollup/da_syncer/block_queue.gois 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 toentryWithBlocksand 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 fortargetBatchis 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
CodecV7and contracts.initialL1MessageQueueHash->prevL1MessageQueueHashandlastL1MessageQueueHash->postL1MessageQueueHashInitialMessageQueueIndexfrom 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: implementL1MessageQueueHeightFinderto determine the L1 message queue height for a given target batch from its finalized bundleScrollChainABIcommitBatchesfunction inl1.Readerto 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.gobeen updated?4. Breaking change label
Does this PR have the
breaking-changelabel?Summary by CodeRabbit
New Features
L1MessageQueueHeightFinderfor calculating L1 message queue height.Improvements
Chores
.dockerignoreto exclude thetmp/directory.Tests