fix(cross2eth): reuse broadcast lock tx on ebcli retry to prevent double mint - #1320
Draft
33cn wants to merge 1 commit into
Draft
fix(cross2eth): reuse broadcast lock tx on ebcli retry to prevent double mint#132033cn wants to merge 1 commit into
33cn wants to merge 1 commit into
Conversation
…ble mint ebcli's sync lock command retries Manager.LockEthErc20Asset up to 3 times on rpc error. When the first attempt already broadcast the lock tx but failed to confirm it (transient rpc hiccup), the retry re-executed the whole approve+lock flow, locking the same asset twice and minting 2x on the chain33 side. ci_cross2eth caught this in TestETH2Chain33USDT_proxy_excess: bridge bank went 140->340 after a single lock of 100. Record broadcast-but-unconfirmed lock txs in the manager keyed by chain+owner+token+amount+receiver with a 10min TTL; on retry with the same params, wait for the recorded tx instead of re-locking. ethtxs now returns the tx hash in LockBroadcastError at the two post-broadcast error points, and WaitLockTxConfirmed distinguishes confirmed-success / confirmed-failed / still-pending so the manager can reuse, re-execute, or keep waiting accordingly. Co-Authored-By: Claude <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Context
ci_cross2eth failed on run https://github.com/33cn/plugin/actions/runs/33836471133/job/100909914007?pr=1312 (branch fix-token-duplicate-finishcreate), while the pull_request run of the same commit passed — a timing flake, not a regression from that PR.
Failure:
TestETH2Chain33USDT_proxy_excess(BSC side) — after a singleethereum lock -m 100, the bridge bank balance went 140 → 340 (expected 240). Two locks executed.Root cause
ebcli's sync
lockcommand retries the wholeManager.LockEthErc20Assetrpc up to 3 times on error (commit 857c01f). The flow is not idempotent (approve + lock txs). In the failing run the first attempt's Lock tx was broadcast/mined but the handler reported a transient error (26s wall time fits a send-stage rpc error: ~10s attempt 1 + 0.5s retry sleep + ~15s attempt 2), so the retry re-executed the lock — locking the same asset twice on ETH/BSC and minting 2x on the chain33 side.Fix
Make the sync lock idempotent across retries in the ebrelayer:
ethtxs.LockEthErc20Assetnow returnsLockBroadcastErrorcarrying the tx hash at the two post-broadcast error points (lock send error with non-nil tx, and receipt-wait failure).ethtxs.WaitLockTxConfirmedwaits for a recorded tx and distinguishes confirmed-success / confirmed-failed (ErrLockTxFailed) / still-pending (ErrLockTxPending).manager.LockEthErc20Assetrecords broadcast lock txs keyed by chain+owner+token+amount+receiver (10min TTL, swept on write). On retry with the same params it waits for the recorded tx instead of re-locking; only a definitively reverted tx is re-executed.This also protects against the rpc-reply-lost-after-success case, at the cost of an idempotency window: an identical lock request within the TTL returns the first tx hash.
Tests
Test_WaitLockTxConfirmedAndBroadcastErrorin ethtxs (simulator): wait-on-recorded-hash returns the same hash;LockBroadcastErrorcarries the hash viaerrors.As.go test ./plugin/dapp/cross2eth/ebrelayer/...all pass.🤖 Generated with Claude Code