You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unify aggsender certificate block-range adjustment under a single AdjustBlockRange flow path.
Move max-L2 limiting, finalized-root claim provability checks, certificate-size trimming, and invalid-claim posterior-unclaim validation into the same ordered pipeline.
Remove the old standalone max-L2 limiter and the CertificateBuildParams range mutator helpers, then update PP and aggchain prover flows and mocks to use the unified adjuster.
Rewrite and extend aggsender tests to cover the new adjustment flow and root-based behavior.
⚠️ Breaking Changes
🛠️ Config: None.
🔌 API/CLI: Internal aggsender flow interfaces now use AdjustBlockRange; LimitCertSize, Range, AdjustToBlock, and the standalone max-L2 limiter path were removed.
🗑️ Deprecated Features: Removed MaxL2BlockNumberLimiter and its dedicated tests.
📋 Config Updates
🧾 Diff/Config snippet: None.
✅ Testing
🤖 Automatic: go test ./aggsender/...
🖱️ Manual: Not run.
🐞 Issues
None.
🔗 Related PRs
None.
📝 Notes
Claim filtering for finalized data is now driven by L1InfoTreeRootFromWhichToProve: proposer paths select the finalized root up front, while validator paths assert that the provided root is finalized before accepting the range.
Invalid-claim/unclaim validation remains the last adjustment step so earlier truncations cannot silently invalidate the final certificate range.
This PR successfully unifies the aggsender certificate block-range adjustment logic under a single AdjustBlockRange method. The refactoring consolidates four previously separate adjustment flows (max-L2 limiting, finalized-root claim provability checks, certificate-size trimming, and invalid-claim posterior-unclaim validation) into one ordered pipeline in aggsender/flows/adjust_block_range.go.
🐛 Bug Fixes
None.
📋 Config Updates
None.
⚠️ Breaking Changes
Internal API changes: The AggsenderFlowBaser interface now exposes AdjustBlockRange with a unified BlockRangeAdjustmentOptions struct. The following methods/types were removed:
LimitCertSize method
CertificateBuildParams.Range() method
CertificateBuildParams.AdjustToBlock() method
MaxL2BlockNumberLimiter class and its dedicated tests
Flow behavior: Claim filtering based on finalized data is now driven by L1InfoTreeRootFromWhichToProve, with proposer paths selecting the finalized root upfront and validator paths asserting that the provided root is finalized.
📊 Review Summary
✅ Strengths
🟢 Excellent test coverage: The new adjust_block_range_test.go file contains 690 lines of comprehensive tests covering edge cases, error conditions, and normal flows. Tests are well-structured and use table-driven patterns.
🟢 Clear separation of concerns: The unified AdjustBlockRange method has a clean pipeline structure with well-defined steps:
adjustMaxL2BlockRange
validateRootToProveIsFinalized
adjustClaimsNotProvableAgainstRoot
limitCertSize
adjustInvalidClaimsAreNotUnclaimed
🟢 Better code organization: Removing 258 lines from flow_base.go and consolidating logic reduces cognitive load and makes the codebase easier to maintain.
🟢 Consistent error handling: Error messages are descriptive and provide context about what went wrong.
🟢 Performance optimization: The GER validation cache (gerValidationCache) prevents redundant queries for the same Global Exit Root across multiple claims.
The filter functions use capacity estimation via aggkitcommon.EstimateSliceCapacity but the logic could be more readable with a comment explaining the span/fullSpan calculation
claimHasPosteriorUnclaim modifies the usedUnclaims slice but doesn't validate that the slice length matches the unclaims length. While the current usage is safe, adding a defensive check would improve robustness.
🟡 Test clarity (aggsender/flows/adjust_block_range_test.go:382-435):
Some test names like "handles nil claim global index" could be more specific about the expected behavior (e.g., "returns false when claim has nil global index")
🔴 Issues Found
🔴 Security: Missing validation for nil GlobalIndex (aggsender/types/certificate_build_params.go:153-179):
funcclaimHasPosteriorUnclaim(...) bool {
ifclaim.GlobalIndex==nil {
returnfalse// Line 275
}
foridx, unclaim:=rangeunclaims {
ifusedUnclaims[idx] ||unclaim.GlobalIndex==nil {
continue// Line 280
}
Issue: The function returns false when claim.GlobalIndex is nil (line 275) but silently skips unclaims with nil GlobalIndex (line 280). This inconsistency could lead to unexpected behavior. The function should document why nil claims return false but nil unclaims are skipped.
Recommendation: Add a comment explaining the rationale or ensure consistent handling.
returnnil, fmt.Errorf("adjustBlockRange can't adapt the retry certificate, "+"the ToBlock %d is greater than the maxL2BlockNumber %d. Err: %w",
buildParams.ToBlock, options.MaxL2BlockNumber, ErrMaxL2BlockNumberExceededInARetryCert)
The error prefix "adjustBlockRange" is lowercase and inconsistent with Go conventions. Consider "AdjustBlockRange" or removing the prefix since the function name is already in the stack trace.
🟡 Missing edge case test: The cloneCertificateBuildParamsWithRange function correctly preserves the ExtraData field (line 358), but there's no explicit test verifying that an empty string ExtraData is preserved vs. a nil/missing field.
🟡 Code duplication: The filter functions filterBridgesInRange, filterClaimsInRange, and filterUnclaimsInRange (lines 362-408) have nearly identical logic. Consider using Go generics or a helper function to reduce duplication.
🔍 Additional Observations
CI Failure: The "Go Vulnerability Check" workflow is failing due to two vulnerabilities in dependencies:
google.golang.org/grpc@v1.79.1 (Authorization bypass) - Fixed in v1.79.3
github.com/pion/dtls/v2@v2.2.12 (AES GCM nonce issue) - No fix available yet
Note: These are dependency issues unrelated to this PR's changes. They should be addressed separately.
Migration quality: The removal of MaxL2BlockNumberLimiter (127 lines) and the old adjustment logic (258 lines from flow_base.go) is clean. All error constants were properly migrated to the new file.
Interface changes: The AggsenderFlowBaser interface is cleaner with the unified AdjustBlockRange method replacing multiple adjustment methods.
Backward compatibility: While this is a breaking change for internal APIs, external interfaces remain unchanged, which is good for API consumers.
🎯 Recommendations
Priority: 🔴 Required
Fix the nil pointer dereference risk in GetClaimsFilteringUnclaims (certificate_build_params.go:167)
Priority: 🟡 Suggested
Add doc comments to AdjustBlockRange explaining the pipeline flow and ordering
Add test case for ExtraData preservation in cloneCertificateBuildParamsWithRange
Consider refactoring the three filter functions to reduce code duplication
Document the nil handling rationale in claimHasPosteriorUnclaim
Priority: 🟢 Optional
Update dependency versions to fix the security vulnerabilities (separate PR)
Add inline comments explaining the adjustment step ordering rationale
Consider adding benchmark tests for the new unified flow to ensure no performance regression
✅ Verdict
This is a well-executed refactoring that significantly improves code organization and maintainability. The unified adjustment flow is clearer and more testable than the previous scattered approach. However, there is one critical nil pointer dereference bug that must be fixed before merging.
Once the required fix is applied, this PR will be ready to merge. The suggested improvements are non-blocking but would further enhance code quality.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔄 Changes Summary
AdjustBlockRangeflow path.CertificateBuildParamsrange mutator helpers, then update PP and aggchain prover flows and mocks to use the unified adjuster.AdjustBlockRange;LimitCertSize,Range,AdjustToBlock, and the standalone max-L2 limiter path were removed.MaxL2BlockNumberLimiterand its dedicated tests.📋 Config Updates
✅ Testing
go test ./aggsender/...🐞 Issues
🔗 Related PRs
📝 Notes
L1InfoTreeRootFromWhichToProve: proposer paths select the finalized root up front, while validator paths assert that the provided root is finalized before accepting the range.