feat: autoclaim L1 -> L2#1644
Conversation
# Conflicts: # multidownloader/evm_multidownloader_reorg.go # multidownloader/evm_multidownloader_reorg_test.go
…tic logs - config/config_test.go: move testify/urfave imports to end of non-stdlib group to satisfy gci two-group ordering (fixes CI lint failure) - config/default.go: set AutoClaim.L1ToL2Watchdog Enabled = true to match the assertion in TestLoadDefaultConfig (fixes unit test failure) - autoclaim/proof/preparer.go: add debug logs in selectL1InfoTreeIndex to surface whether the proof is blocked by l1InfoTree lag or gerSyncer lag - autoclaim/claimer/claimer.go: log info when proof not ready so E2E logs clearly show the pending state on each poll cycle Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rackedBlocks wipe reorgDetector.Start calls loadTrackedHeaders which replaces the in-memory trackedBlocks map entirely from DB. If l2gersync.New (which calls Subscribe internally) ran first, the subscription entry it added would be wiped by the subsequent loadTrackedHeaders call, causing every AddBlockToTrack to return "subscriber not subscribed" forever. The per-claimer l2gersync was stuck in a retry loop at the first GER injection block (block 24), never processing the GER that covered the bridge deposit, so GetFirstGERAfterL1InfoTreeIndex always returned ErrNotFound and the claim proof was never prepared. Fix: call reorgDetector.Start synchronously before l2gersync.New so that loadTrackedHeaders completes before Subscribe adds the entry. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 3 SQL injection hotspots in autoclaim/storage/storage.go were marked SAFE on SonarCloud (all use parameterized ? placeholders, not user input). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add tests across 11 files covering uncovered nil-arg error paths, option closures, getter/accessor methods, disabled-state branches, and constructor validation to push SonarCloud new_coverage above the 80% quality gate. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…overage Adds 7 targeted tests across sender and api packages to cover previously unreachable lines: default time.Now closure bodies, IsClaimed error propagation, pollResult Result() failure path, zero WaitPeriod fallback to s.pollPeriod, zero-MaxRetries target fallback to request.MaxRetries, and claimTxHash with nil Tx entry. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
joanestebanr
left a comment
There was a problem hiding this comment.
Another point is that the API for bridgeservice and for autoclaim is very similar. But there are a different that can be a bit misleading: the first page_number: bridgeservice use 1 and autoclaim use 0
…overrides, dedup) Address the unresolved review threads on PR #1644: - API design: move the public read endpoints (will/will-not-claim) into the bridge service under /bridge/v1/autoclaim/bridges, served only when the autoclaim component runs; keep admin approve/reject on the standalone [AutoClaim.API]. Shared DTOs/parsing extracted to autoclaim/apitypes. - Replace the redundant [AutoClaim] Enabled flag with DryRun (component list already gates running); DryRun prepares claims but skips submission, ending requests in a new terminal "dry-run" status. - Allow per-claimer BlockFinality / InitialBlockNum overrides for the L2 GER syncer instead of always inheriting the shared [L2GERSync] values. - Deduplicate the pre-Etrog global-index computation into bridgesync.GlobalIndexForBridge, used by both bridgeservice and autoclaim. - Harden the admin API: max-length validation on decider/decider_id/reason and an io.LimitReader body cap. Updated docs, swagger, and tests accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review comments addressedPushed API redesign (the main one). Split endpoints by audience so operators can expose request status without exposing admin controls:
Per-claimer GER config. Dedup. The pre-Etrog/global-index computation is now a single helper Admin API hardening (flagged by the bot): max-length validation on Docs, swagger, and tests updated; the resolved CodeQL/bot threads were already outdated. Bot "suggested/optional" items (errgroup startup, metrics, etc.) left for follow-ups. |
|
…-test health check The default op-pp config runs with --components=...,autoclaim. Removing the top-level [AutoClaim] Enabled = false left the L1ToL2Watchdog and allow-all claimer active by default, causing autoclaim to race with the manual claim in the post-test bridge health check and revert it. Disable the claimer (Enabled = false) in the default config so autoclaim starts but processes no bridges outside explicit test setups. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SonarCloud's scanner auto-configures for PRs by verifying the PR via GitHub API using GITHUB_TOKEN. Without an explicit pull-requests:read permission the token falls back to org-default read-only (contents only), causing the scanner to fail with "Something went wrong while trying to get the pullrequest". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…SonarCloud" This reverts commit 29fc4eb.



🔄 Changes Summary
autoclaimAggkit component for L1 -> L2 bridge claims. It discovers eligible exits froml1bridgesync, persists request/cursor/attempt state, prepares claim proofs withl1infotreesyncplus a per-claimerl2gersync, submitsclaimAsset/claimMessagetransactions throughEthTxManager, and tracks requests through confirmation or failure.allow-all,api-approve,no-message, andbasic-filter./autoclaim/v1for request listing, inspection, manual approval, and manual rejection, with generated Swagger docs.autoclaimcomponent, config loading/validation/defaults, docs, mocks, and the OP e2e environment./l1-info-tree-index: if a verified batch LER is missing from the local L2 exit tree, the lookup now avoids mixing L2 bridge-sync block numbers with L1 verified-batch block numbers and falls back to a bounded linear scan.[AutoClaim]config section and remains disabled by default.autoclaimcomponent selector and optional/autoclaim/v1API. Existing bridge service API paths are unchanged.📋 Config Updates
autoclaimcomponent and setting[AutoClaim].Enabled = true.[[AutoClaim.Claimers]]entry configures one EVM destination network with its own RPC URL, bridge address, policy, gas settings, retry settings, andEthTxManagerstorage/signing config.AutoClaim.StoragePath; each claimer also has an independentEthTxManager.StoragePathand isolated per-claimerl2gersync/ L2 reorg detector databases under the Auto Claim storage directory.✅ Testing
autoclaim/api,claimer,claimtx,config,policy,proof,runtime,sender,simulator,storage,types, andwatchdog.TestAutoClaimL1ToL2AllowAll,TestAutoClaimL1ToL2APIApprove, andTestAutoClaimL1ToL2BasicFilter.lint,test-unit, Go e2e, Docker image build, CodeQL, SonarCloud, and the configured multi/single-chain e2e workflows passing.Run govulncheckis currently failing.🐞 Issues
🔗 Related PRs
📝 Notes
origin_network:destination_network:deposit_count;origin_networkis the bridged token's origin network, not necessarily the chain where the bridge was initiated.l2gersync, which supports both legacy and sovereign L2 GER manager behavior.api-approvepolicy requires the Auto Claim API so operators can approve or reject requests inmanual-approval-requiredstatus.TestRemoveGER_NoProblematicClaims,TestRemoveGER_CategoryA,TestRemoveGER_CategoryB1,TestRemoveGER_CategoryB2, andTestGenerateInvalidGER. This is being worked on feat: migrate e2e tests from bats to go #1643GetFirstVerifiedBatchesAfterBlockwithGetLastRoot().BlockNum, which is an L2 bridge-sync block number even though the L1 info tree query expects an L1 block number. The new path only falls back ondb.ErrNotFound, keeps the original L1 verified-batch bounds, and skips missing LERs with a linear scan when binary search cannot safely continue.