AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Low 32 Bitcoin

submarine_swaps: wait for broadcast in wait_for_htlcs_and_broadcast

Public commit record

What the developer wrote

Authored by f321x

83/100 · Strong
submarine_swaps: wait for broadcast in wait_for_htlcs_and_broadcast

Wait for broadcast of the funding transaction in
`SwapManager.wait_for_htlcs_and_broadcast` before returning.
Previously it might have returned the swap funding txid before the
funding tx was broadcast.
This caused the regtest `test_swapserver_success_forward` to fail
as it expected the funding tx to be broadcast once the CLI command
returned.

See:
```
.***** test_swapserver_success_forward ******
initializing alice
funding alice
ec354953f96e0de7be4354ab156611da9e31bd85c2d25664bdb995950530c12e
initializing bob
funding bob
1df19a419b5ae5b961bae6cfaf4e7c8e772c6632d30782fab8de6992a8901e4a
mining 1 blocks
starting daemon (PID 7471)
/tmp/alice/regtest/wallets/default_wallet
true
starting daemon (PID 7502)
/tmp/bob/regtest/wallets/default_wallet
true

alice opens channel
mining 3 blocks
wait until alice sees channel open.
wait until alice sees channel open..
wait until alice sees channel open...
alice initiates forward-swap
{
"lightning_amount": "0.01967661",
"onchain_amount": "0.02",
"txid": "b0f9ba48b670ee4a1f182655fe18f3f7d5c310923b7c85ad396b24e0a2f8e0cc"
}
utxo b0f9ba48b670ee4a1f182655fe18f3f7d5c310923b7c85ad396b24e0a2f8e0cc:0 does not exist
FDaemon stopped
Daemon stopped

======================================================================
FAIL: test_swapserver_success_forward (tests.regtest.TestLightningSwapserver.test_swapserver_success_forward)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/cirrus-ci-build/tests/regtest.py", line 105, in test_swapserver_success_forward
self.run_shell(['swapserver_success_forward'])
File "/tmp/cirrus-ci-build/tests/regtest.py", line 19, in run_shell
assert process.returncode == 0
^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
```

Can be reproduced with:
```diff
diff --git a/electrum/submarine_swaps.py b/electrum/submarine_swaps.py
index f83d653f9..242aef070 100644
--- a/electrum/submarine_swaps.py
+++ b/electrum/submarine_swaps.py
@@ -1052,6 +1052,7 @@ class SwapManager(Logger):
@log_exceptions
async def broadcast_funding_tx(self, swap: SwapData, tx: Transaction) -> None:
swap.funding_txid = tx.txid()
+ await asyncio.sleep(5)
await self.network.broadcast_transaction(tx)

async def reverse_swap(
```
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
The short version

What changed, and why it matters

This commit fixes a timing bug in Electrum's submarine swap feature. Previously, when a user initiated a swap, the software could report the swap funding transaction ID back to the caller before the transaction was actually broadcast to the Bitcoin network. This meant a user or automated test might think the swap was funded and proceed, while the transaction had not yet been sent. The fix makes the code wait until the broadcast is complete before returning. There is also a small improvement in error handling when the broadcast fails.

Recommended action

Treat this as a low-severity reliability fix. It should be included in the next release because it prevents user-visible swap state inconsistency and improves error handling. No urgent security advisory is warranted based solely on the commit content, but downstream consumers relying on the swap API should be aware that prior versions could return a txid before network broadcast.

Security signals we found

01

Race condition between setting swap.funding_txid and broadcasting the funding transaction

02

Hold-invoice callback could raise unhandled TxBroadcastError, preventing retry

03

Caller could proceed on the assumption that funding tx was broadcast when it was not

04

Fix introduces explicit synchronization via asyncio.Event and timeout handling

Risk score

Why this scored 32/100

Our methodology →
Potential impact 8/30
Exploitability 4/25
Stealth signal 5/15
Affected reach 6/15
Confidence 6/10
Evidence quality 3/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.