Reserve funding tx inputs at build time#35
Merged
Conversation
create_funding_transaction built and signed the funding tx but never applied it back to the BDK wallet graph, so the selected UTXOs stayed selectable until the next chain or mempool sync. Two opens between syncs would build funding transactions that spend the same inputs. The network rejects the loser, but its 0-conf channel is already live, leaving an unbacked phantom channel. Apply the extracted tx with apply_unconfirmed_txs before releasing the wallet lock so its inputs are marked spent immediately, with no window for a second build to reselect them. A forced wallet sync was the obvious alternative but cannot close the hole: broadcast is async so the tx is not in any mempool when we would sync, and the rejected loser never enters a mempool at all, so a sync could never reserve its inputs. Holding the inputs at build time means a failed open now has to release them again, otherwise the UTXOs are locked out of all future coin selection. The FundingGenerationReady handler rolls back via cancel_tx on any error before logging. The regression test gives node A a single UTXO, opens one 0-conf channel, and checks that the spendable balance drops without a sync and that a second open is rejected with InsufficientFunds. Before the fix that second open silently produced a phantom channel.
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.
create_funding_transaction built and signed the funding tx but never applied it back to the BDK wallet graph, so the selected UTXOs stayed selectable until the next chain or mempool sync. Two opens between syncs would build funding transactions that spend the same inputs. The network rejects the loser, but its 0-conf channel is already live, leaving an unbacked phantom channel.
Apply the extracted tx with apply_unconfirmed_txs before releasing the wallet lock so its inputs are marked spent immediately, with no window for a second build to reselect them. A forced wallet sync was the obvious alternative but cannot close the hole: broadcast is async so the tx is not in any mempool when we would sync, and the rejected loser never enters a mempool at all, so a sync could never reserve its inputs.
Holding the inputs at build time means a failed open now has to release them again, otherwise the UTXOs are locked out of all future coin selection. The FundingGenerationReady handler rolls back via cancel_tx on any error before logging.
The regression test gives node A a single UTXO, opens one 0-conf channel, and checks that the spendable balance drops without a sync and that a second open is rejected with InsufficientFunds. Before the fix that second open silently produced a phantom channel.