Bridge: auto-refund does not run when BLS signing expires (EXPIRED) #1352
Summary
When an outbound RequestBridgeMint BLS request reaches terminal EXPIRED (threshold not met), the chain emits inference.bls.EventThresholdSigningFailed but does not auto-refund bridge escrow. GNK stays locked until the user calls cancel-bridge-operation with the plaintext request_id from bridge_mint_requested.
Reproduced twice on gonka-testnet-4 (manual test case #18). Unit tests pass in isolation; live integration fails.
Full evidence: docs/bridge-auto-refund-on-expired-bug.md (in working tree).
Expected
finalizeFailedThresholdSigningRequest → BlsHooks.AfterThresholdSigningFailed → ProcessAutoRefundForFailedBridgeOperation → escrow refund + bridge_operation_auto_refunded + BLS → CANCELLED.
Actual (run B @ block 36114)
| Check | Result |
|---|---|
| Mint height | 36114 |
| BLS id | KDTcSiJ3Jrv45kvMOivlDDznH4MT3bKLB1QYQKRpEuA= |
| Terminal block | 36144 — EventThresholdSigningFailed |
bridge_operation_auto_refunded |
Absent |
| Escrow while EXPIRED | 29B ngonka (+1 GNK locked) |
| BLS status | EXPIRED (not CANCELLED) |
Manual cancel tx 9AA0F016… (plaintext req_36114_…) |
Success → escrow 28B |
Earlier run A (mint 8E610948… @ 35726): same pattern — EXPIRED, no auto-refund, manual cancel worked.
Code path
x/bls/keeper/threshold_signing.go:finalizeFailedThresholdSigningRequest/maybeCloseRetryAfterFailedPostProcessx/inference/module/bls_hooks.go:AfterThresholdSigningFailedx/inference/keeper/bridge_pending_refund.go:ProcessAutoRefundForFailedBridgeOperation
Silent (false, nil) if hooks empty or pending not found — no retry queue for failure hooks.
Test gap
TestProcessAutoRefundForFailedBridgeOperation_Mint calls refund logic directly and sets pending after expiry — does not wire BlsHooks on BLS keeper through ProcessThresholdSigningDeadlines.
Workaround
cancel-bridge-operation --request-id <plaintext req_<height>_…> — not BLS base64 id.
Suggested fixes
- Integration test: mint → expire with wired
BlsHooks→ assert auto-refund. - Verify
InvokeSetBlsHookson deployed testnet/mainnet binaries. - Log when failure hook returns
(false, nil). - Optional: failure-hook retry queue (like completed post-process).
Severity
Medium — funds stuck in escrow without user action; manual cancel required (easy to get wrong request_id format). Reduced from High because the expired signature situation will happen during incidents, not normal operation.
💬 Comments (2)
at the moment all filfox servers are down
when they come back, i will need to take back and restore the environment to continue with testing. The data above will be gone. But we can simulate again on request
🔄 Auto-synced from Issue #1352 every hour.
Testnet evidence retrieval (
gonka-testnet-4)Run on seed host
702111:Environment
1. Chain height + BLS params
Result
2. Mint block — events + save plaintext
request_idThe result will be
3. Verify
keccak256(plaintext)matches BLSrequest_idResult
4. BLS signing request state
Result - it is Cancelled because i cancelled manually the EXPIRED BLS tx and refunded manually as a test.
5. Failure block —
EventThresholdSigningFailed, no auto-refundResult
6. Escrow + minter balances
Result - the 1 GNK returned after i manually cancelled
7. Manual cancel tx (recovery)
Result - proof of manual cancel and refund
8. Node logs (hook errors)
Result - None in the logs.
9. Pending refund map (export)
Result - Nothing - the refund was not listed in pending...
Run A (earlier attempt @ 35726)
Notes
cancel-bridge-operation --request-idmust be the plaintextreq_<height>_…frombridge_mint_requested(/tmp/bridge_req_id.txt), not the BLS base64 id (KDTcSiJ3…=).finalize_block_events, nottxs_results.--page-limit(not--limit) forquery bls signing-history.