Bridge Scenario A: inbound USDT stuck BRIDGE_PENDING after coordinated node halt (4-validator testnet) #1370
Summary
Manual reproduction of Scenario A (coordinated node halt with bridge + api kept running) on gonka-testnet-4 with a live Sepolia USDT inbound deposit. Result: FAIL — deposit ingested by API on all hosts, but only 1/4 validator votes landed on-chain; deposit remains BRIDGE_PENDING with no second USDT mint.
Relates to #1358.
Test environment
| Item | Value |
|---|---|
| Network | gonka-testnet-4 |
| Validators | 4 hosts on xj7-5.s.filfox.io |
| Images | api:0.2.13-post1, bridge:0.2.14, inferenced:0.2.13 |
| Sepolia bridge | 0x5941d32709048aded24A1b7E1abFCe1Cf70210FB |
| Sepolia USDT | 0x7169D38820dfd117C3FA1f22a697dBA58d90BA06 |
Hosts
| SSH port | Hostname | Validator address |
|---|---|---|
| 18222 | 702111 | gonka1uthgqf4yapkw5356uud29cjk7u4rqd52pc6j0w |
| 18223 | 702127 | gonka1qrz72h8qf9dmjaqs26jxmq2q9aymh0667gmuzv |
| 18226 | 702105 | gonka1kz8n0devnsjq9g7plw7r5nrlxl8h6t22j3nna4 |
| 18221 | 702112 | gonka1g5g4fmutlzv5t9mdhsf0ldc4rgjhmf0vakwc3w |
Sepolia deposit (test transaction)
| Field | Value |
|---|---|
| Tx hash | 0xbfc879d10c489090df4ba7a245075909564c915d228cd1252409497a0ab3266f |
| Etherscan | https://sepolia.etherscan.io/tx/0xbfc879d10c489090df4ba7a245075909564c915d228cd1252409497a0ab3266f |
| Sepolia block | 11156647 |
| Sepolia time | 2026-06-28 07:00:36 UTC |
| Receipt index | 212 |
| Receipts root | 0x09cf1eff7decf066a0e23616c408ac93f6a1dd88df2581b16b3abd41268530b0 |
| Amount | 1 USDT (1000000 base units) |
| ETH sender | 0x274563BDF552ca7cC4E0C096e594D42fE21d5a35 |
| Gonka recipient | gonka1qdwgkcxww42sxmcm9gk0trvugev2g0248upwyq |
Procedure
- User sent Sepolia USDT to bridge contract while chain was syncing.
- ~07:11 UTC — all four
nodecontainers stopped manually (dc stop node);api+bridgekept running. - During halt (~9 min): bridge handshake stalled at 11156632; Geth could not post (API unreachable while
nodedown broke API startup). - ~07:20 UTC — all
nodecontainers restarted. - Geth burst-posted blocks 11156633–11156664 to all APIs.
- Block 11156647 (deposit) processed on every host.
Voting map
| Port | Host | Validator | Processed receipt? | On-chain vote? | Result |
|---|---|---|---|---|---|
| 18221 | 702112 | gonka1g5g4f… |
Yes @ 07:20:38 | Yes | Vote recorded |
| 18222 | 702111 | gonka1uthgqf… |
Yes @ 07:20:25 | No | Broadcast failed |
| 18223 | 702127 | gonka1qrz72h… |
Yes @ 07:20:25 | No | Broadcast failed |
| 18226 | 702105 | gonka1kz8n0d… |
Yes @ 07:20:25 | No | Broadcast failed |
On-chain state (after test)
inferenced q inference bridge-transaction \
--origin-chain sepolia --block-number 11156647 --receipt-index 212
| Field | Value |
|---|---|
| Status | null (BRIDGE_PENDING) |
| Epoch | 45 |
| Validators | 1 — gonka1g5g4fmutlzv5t9mdhsf0ldc4rgjhmf0vakwc3w |
totalValidationPower |
18237 (insufficient quorum on 4-validator set) |
| Wrapped USDT balance | 1000000 (unchanged — prior deposit only; second 1 USDT not minted) |
Why three hosts failed
All three failing hosts logged Processing receipt (looks successful) then immediately:
ERROR Broadcast failed immediately subsystem=Messages code=18
rawLog="unordered tx ttl exceeds 10m0s: invalid request"
originalMsgType=/inference.inference.MsgBridgeExchange
18223 and 18226 also logged stale block time at the same instant:
07:11:32 is the last chain block time before the halt. Votes were broadcast in the first second after node restart (07:20:25) while the API still used stale block time for unordered tx TTL signing. CheckTx rejected the txs; SendTransactionAsyncNoRetry does not retry; bridge queue does not re-queue.
Why 18221 succeeded: same receipt processed 13 seconds later (07:20:38) after block time refreshed — no Broadcast failed line; vote landed on-chain.
Root cause (same as #1358)
MsgBridgeExchangeusesSendTransactionAsyncNoRetry(no halt-aware retry).- Broadcast CheckTx failures are logged but not surfaced to bridge handler.
- Geth cursor advances on HTTP 200; no replay.
- API logs
Processing receipteven when vote failed.
Attached logs
Full API + bridge log extracts for blocks 11156630–11156670 and broadcast-error context:
Gist: https://gist.github.com/maria-mitina/6dc628e81592ec99dc094624c01d4ac9
| Gist file | Contents |
|---|---|
api-18222-702111.log |
API logs — genesis host; Broadcast failed @ 07:20:25 |
api-18223-702127.log |
API logs — stale + Broadcast failed @ 07:20:25 |
api-18226-702105.log |
API logs — stale + Broadcast failed @ 07:20:25 |
api-18221-702112.log |
API logs — successful vote @ 07:20:38 (no broadcast error) |
bridge-18222-702111.log |
Bridge Geth — halt/unpause, API connectivity errors |
bridge-18223-702127.log |
Bridge Geth |
bridge-18226-702105.log |
Bridge Geth |
bridge-18221-702112.log |
Bridge Geth |
Key log excerpts
18223 @ 07:20:25 (failed):
Processing receipt ... blockNumber=11156647 receiptIndex=212
WARN node block time is stale latestBlockTime=2026-06-28T07:11:32.174Z drift=8m53.520114365s
ERROR Broadcast failed immediately ... rawLog="unordered tx ttl exceeds 10m0s: invalid request"
18221 @ 07:20:38 (succeeded):
Suggested fixes
- Use
SendTransactionAsyncWithRetryforMsgBridgeExchange, or wait for fresh block time before broadcasting after halt. - Surface
resp.Code != 0as failure to bridge handler (HTTP 500, do not advance processing). - Do not remove block from queue until vote confirmed on-chain.
- Optional: reconciliation loop for
BRIDGE_PENDINGreceipts.
Recovery
Manual bridge-exchange from validators on 18222, 18223, 18226 with receipt index 212 and receipts root above.
References
-
1358
- Prior pause test:
docs/bridge-inbound-pause-test-report.md - Scenario runbook:
docs/bridge-upgrade-scenario-a-runbook.md
💬 Comments (2)
duplicate of https://github.com/gonka-ai/gonka/issues/1358
🔄 Auto-synced from Issue #1370 every hour.
Log file direct links (gist)
Gist: https://gist.github.com/maria-mitina/6dc628e81592ec99dc094624c01d4ac9
API logs (broadcast failure window)
Bridge (Geth) logs (blocks 11156630–11156670 + halt period)
Local copy path in repo workspace:
docs/bridge-scenario-a-2026-06-28/logs/