Skip to content

fix: reply with the merged witnesses in external funding - #1713

Closed
LusoCryptoLabs wants to merge 1 commit into
nervosnetwork:developfrom
LusoCryptoLabs:ext-funding-witnesses
Closed

LusoCryptoLabs wants to merge 1 commit into
nervosnetwork:developfrom
LusoCryptoLabs:ext-funding-witnesses

Conversation

@LusoCryptoLabs

@LusoCryptoLabs LusoCryptoLabs commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

When the acceptor of an externally funded channel sends TxSignatures first, the initiator merges them into the submitted tx but replies with the submitted witnesses, which lack the acceptor's. The acceptor takes the reply as the whole witness set (the should_local_send_tx_signatures_first branch), so its funding_tx loses its own signatures, and the copy it broadcasts fails verification at its inputs. The initiator's copy is complete and usually reaches the pool first, so the channel still opens, but the acceptor alone cannot get a valid funding tx on chain.

  • The initiator replies with the merged witnesses.

With secp256k1 inputs on the acceptor's side, the merged set holds the acceptor's signature since #1715, now in develop, made the merge replace the placeholder the funding builder writes there.

Checked on this branch:

  • test_external_funding_acceptor_send_tx_signatures_first_keeps_its_witnesses: the acceptor funds less, so it signs first. The mock chain does not sign, so its TxSignatures is held (TestFiberMessageKind::TxSignatures, test only) and replaced with one that has a witness at its input. On develop the acceptor's funding tx is 73 bytes shorter than the initiator's; with the fix they are the same.
  • the other 27 external funding tests
  • cargo fmt, typos, cargo shear, make clippy
  • cargo test -p fnn --features rocksdb: all pass in CI after the rebase on develop

@jjyr

jjyr commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Good catch!

But can we fix this on the receiver side?

TxSignature should only contain the peer's signature. The idea is to minimize our reliance on data from the remote peer, so it should only contain the signature from one side.

@LusoCryptoLabs

Copy link
Copy Markdown
Contributor Author

You're right, and develop already does it. Since #1252, the side that sent TxSignatures first merges the reply with merge_external_funding_witnesses when the peer funded externally: the acceptor sets signed_submitted when it takes the signed tx in handle_external_funding_tx_sync.

My test was wrong. The mock chain does not sign, so the acceptor in it never held a witness of its own to keep. With the acceptor signing its own input (a mock chain middleware) and its TxSignatures reaching the initiator after the submit, develop keeps the acceptor's witness, both in the tx it stores and in the one it sends.

The -302 we saw on our node came from the placeholder check fixed in #1715. Closing this one, sorry for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants