Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,36 @@ impl<B: TransactionBroadcaster + ?Sized> AssetLockManager<B> {
.await?
}
AssetLockStatus::Broadcast => {
// Already broadcast — just wait for proof.
// Defensive re-broadcast, then wait for proof. A lock can
// sit at `Broadcast` across app restarts long enough for
// its funding tx to be evicted from every mempool (Core's
// default `-mempoolexpiry` is two weeks), or the original
// broadcast may have reached no peers at all (SPV
// connectivity gap). Once no node holds the tx, no IS/CL
// proof can ever arrive, and the wait — now unbounded for
// the user-facing funding flows — would hang forever. A
// re-broadcast revives an evicted/undelivered tx.
//
// Best-effort: unlike the `Built` arm, this tx was already
// broadcast once (that's what `Broadcast` means), so it may
// still be in a mempool or already mined — in which case the
// network reports "already known" / "already in block
// chain". The broadcaster can't distinguish that from a real
// rejection (DAPI classifies every failure as `MaybeSent`),
// so we log and proceed to `wait_for_proof` regardless
// rather than failing the resume on a tx that is actually
// fine. If the tx really was mined, `wait_for_proof`
// resolves immediately from the SPV/persisted record.
if let Err(e) = self.broadcaster.broadcast(&tx).await {
tracing::debug!(
outpoint = %out_point,
error = %e,
"resume_asset_lock: defensive re-broadcast of a \
Broadcast-status lock returned an error (likely \
already in a mempool or mined); proceeding to wait \
for proof"
);
}
Comment on lines +288 to +297

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Nitpick: tracing::debug! may hide genuine broadcaster failures on resume

Swallowing the broadcaster error is correct (DAPI can't distinguish 'already known' / 'already in block chain' from a real rejection because everything uncertain is MaybeSent). But at debug! level, the pathological case this PR is trying to defend against — the broadcaster reaching zero peers — leaves no trace at default log levels, after which the unbounded wait_for_proof from #4006 blocks silently. Promoting to warn! (or info! with a clear 'best-effort re-broadcast reported error' phrasing) would keep the healthy case quiet (the line only fires on Err) while making the failure diagnosable from a normal log capture. Volume isn't a concern since this only runs on resume, not steady-state.

source: ['claude']

let proof = self.wait_for_proof(out_point, timeout).await?;
self.validate_or_upgrade_proof(proof, account_index, out_point)
.await?
Expand Down
Loading