Interactive transaction construction for channel establishment v2 - #240
Draft
erickcestari wants to merge 6 commits into
Draft
Interactive transaction construction for channel establishment v2#240erickcestari wants to merge 6 commits into
erickcestari wants to merge 6 commits into
Conversation
Channel establishment v2 identifies a channel by SHA256(lesser-revocation-basepoint || greater-revocation-basepoint) rather than by the funding outpoint, so the id is stable across the interactive transaction negotiation. Before accept_channel2 reveals the peer's basepoint, a zeroed basepoint stands in for the non-initiator. BOLT 2 gives no test vector for either derivation, so the expected digests were computed independently and are pinned as regression vectors.
erickcestari
force-pushed
the
interactive-tx-construction
branch
from
September 9, 2026 14:39
2c34656 to
7cca921
Compare
Channel establishment v2 needs two things the bitcoin-cli wrapper could not do. tx_add_input carries the serialized previous transaction, so add get_raw_transaction. tx_signatures carries our witnesses for a transaction the peer broadcasts, so add sign_tx, which signs without broadcasting and, unlike sign_and_broadcast_tx, does not require signing to be complete: a dual-funded transaction also carries the peer's inputs, which our wallet cannot sign, and the partially signed result still holds our own witnesses. Both share a signrawtransactionwithwallet helper with sign_and_broadcast_tx, whose complete=false assertion stays as-is since a v1 funding transaction spends only our own inputs. Also tolerate an already-broadcast transaction. In v2 the peer broadcasts the funding transaction too, so it can already be in the mempool by the time we get there. Only a confirmed transaction was handled before, which left the mempool case panicking.
BOLT 2 interactive transaction construction has both peers contribute inputs and outputs to one shared transaction, each tagged with a serial_id. SharedTransaction accumulates those contributions and assembles the transaction both peers must agree on: inputs and outputs sorted by ascending serial_id, nVersion 2, and nLockTime from open_channel2. The reconstruction is checked against the BOLT 3 Appendix G dual-funding vectors, rebuilding the spec's unsigned funding transaction byte for byte from the tx_add_input and tx_add_output messages it says each peer sends. Contributions from a peer are total by construction: a prevtx that does not parse, or a prevtx_vout past the end of it, yields an unknown prevout rather than an error, since a peer is free to send nonsense and it is then the peer that must fail the negotiation. Input and output counts are capped at the BOLT limit of 252 so a mutated program cannot grow the session without bound. Also add signs_first, the BOLT 2 rule deciding who sends tx_signatures first: lowest total contributed input value, with the lexicographically lower node_id breaking a tie.
BOLT 2 splits fee responsibility for the shared transaction: the initiator pays for the common fields, and each peer pays for the inputs and outputs it contributed. SharedTransaction::local_fee_sat computes our share, which is what makes a change output's value computable before the output exists. The result is rounded up. BOLT 3 Appendix G's worked example has weight 609 at 253 sat/kw and states a fee of 155, not the 154 that truncating gives; underpaying by a single satoshi makes the peer fail the negotiation at tx_complete, which would silently kill every generated program. Witness weight is charged at 108 per input rather than Appendix G's minimum of 107, since our wallet inputs are P2WPKH and the appendix charges the maximum of the two. Overestimating is the safe direction: the peer fails the negotiation when our feerate falls short, never when it exceeds.
erickcestari
force-pushed
the
interactive-tx-construction
branch
from
September 9, 2026 14:43
7cca921 to
2a4e71a
Compare
erickcestari
marked this pull request as draft
September 10, 2026 17:10
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.
First slice of #239, split out so the dual funding work can be reviewed incrementally. This PR contains only library code in the
smitecrate: no IR, executor, or scenario changes.createrawtransaction,decoderawtransaction, andsignrawtransactionwithwalletso the wallet can sign only its own inputs of a collaboratively built funding transaction.channel_tx::interactive_tx: builds the shared funding transaction from both sides' inputs and outputs, ordered by serial id per BOLT 2, and computes the fee the initiator owes for the common fields.Depends on #222 and #221