Skip to content

Remove InputInfo from LocalCommit and compute localFundingPubKey from ChannelKeys#3102

Closed
pm47 wants to merge 5 commits intomasterfrom
remove-htlc-tx-with-remote-sig-pm
Closed

Remove InputInfo from LocalCommit and compute localFundingPubKey from ChannelKeys#3102
pm47 wants to merge 5 commits intomasterfrom
remove-htlc-tx-with-remote-sig-pm

Conversation

@pm47
Copy link
Member

@pm47 pm47 commented Jun 6, 2025

This is a work-in-progress (InteractiveTxBuilder could be improved, and tests aren't even compiling), but I'd like to get an early feedback before finishing.

My starting point was to move InputInfo out of LocalCommit and into Commitment. It seemed more logical because this is not exclusive to the local commit (indeed we use it to build remote txs).

I actually didn't move InputInfo itself, but only the localFundingPubKey and funding outpoint. It saves a little bit of space, as we get rid of the pubkeyScript). To be able to compute the InputInfo, I had to also bring the CommitmentFormat, which I guess will be needed for taproot channels.

Then I got rid of localFundingPubKey entirely by recomputing it from ChannelKeys. Since those are cached, I think performance shouldn't suffer, and it saves an additional 33B in persisted data.

t-bast and others added 5 commits June 3, 2025 18:45
When a channel was force-closed, we previously stored partially created
closing transactions for each output of the commitment transaction. In
some cases those transactions didn't include any on-chain fee (HTLC txs
with 0-fee anchors) and weren't signed. The fee is set in the publisher
actors which then sign those transactions.

This was an issue because we used those partial transactions as if they
were the final transaction that would eventually confirm: this made it
look like RBF wasn't an option to callers, and was thus easy to misuse.

We now change our data model to only store the outputs of the commit tx
that we may spend, without any actual spending transaction. We only
store spending transactions once they are confirmed, at which point they
can safely be used as closing transactions by callers such as our
balance checks.

This lets us get rid of some codec migration code related to closing
transactions, and is more future-proof because we now don't need to
encode closing transactions and can thus change their format easily.
This also reduces the size of our channel state during force-close.
We previously stored the commitment transaction and HTLC transactions
in our channel data along with the remote signatures, without our local
signatures. It is unnecessary to store those transactions, as we have
all the data we need to recompute them on-the-fly if we need to force
close.

Storing those transactions can easily use a few hundreds of kB per
channel, which adds up to the post-restart latency when channels need
to be read from the DB.

By not storing those transactions in our commitments, we also remove
the need to support encoding them, which gives us greater flexibility
to change their format in the future.

It also made it confusing in tests, where we sometimes use unsigned
transactions as if they were signed.
We actually only add `localFundingPubKey` and a few other fields, and
compute the `commitInput`. This saves 33 bytes because
`remoteFundingPubKey` is now only persisted once.
It is now computed from `fundingTxIndex` + `ChannelKeys`.
@pm47 pm47 requested a review from t-bast June 6, 2025 16:13

val commitmentsCodecWithoutFirstRemoteCommitIndex: Codec[Commitments] = (
("params" | paramsCodec) ::
("params" | paramsCodec) >>:~ { params =>
Copy link
Member Author

Choose a reason for hiding this comment

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

This is where we copy the commitmentFormat from ChannelParams to Commitment, which will be needed at some point I think.

case class WaitingForSigs(fundingParams: InteractiveTxParams,
fundingTxIndex: Long,
fundingTx: PartiallySignedSharedTransaction,
commitInput: InputInfo,
Copy link
Member Author

Choose a reason for hiding this comment

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

This is wip. I think we should add CommitmentFormat to InteractiveTxParams at some point? Which will allow us to remove this commitInput.

Copy link
Member

Choose a reason for hiding this comment

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

Agreed, this is going to be useful for migrating existing channels to taproot opportunistically using splicing, probably a good time to do it if the added codec migration isn't too painful? Otherwise this will be done when introducing codecs v5 for taproot.

@pm47 pm47 changed the base branch from master to remove-htlc-tx-with-remote-sig June 6, 2025 16:17
Copy link
Member

@t-bast t-bast left a comment

Choose a reason for hiding this comment

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

I think we should definitely make the changes you're proposing to Commitments.scala, but the codecs changes are a bit more involved than what I'd like...it may be a better idea to do this change when we introduce channel codecs v5 for taproot, where we know we have to do similar changes and will probably create a ChannelTypes4.Commitment class for the existing format, which will make the migration code easier?


def validateSeed(channelKeys: ChannelKeys): Boolean = {
active.forall { commitment =>
// TODO: the following is circular, need another method
Copy link
Member

Choose a reason for hiding this comment

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

I think we should use commitment.localFundingStatus.signedTx_opt: we'll skip the commitment we don't have it, but in most cases we will have it available. We can compare the txOut of the funding tx to what we recompute based on our seed?

case class WaitingForSigs(fundingParams: InteractiveTxParams,
fundingTxIndex: Long,
fundingTx: PartiallySignedSharedTransaction,
commitInput: InputInfo,
Copy link
Member

Choose a reason for hiding this comment

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

Agreed, this is going to be useful for migrating existing channels to taproot opportunistically using splicing, probably a good time to do it if the added codec migration isn't too painful? Otherwise this will be done when introducing codecs v5 for taproot.

@t-bast t-bast force-pushed the remove-htlc-tx-with-remote-sig branch 3 times, most recently from 7d9a628 to 84317b5 Compare June 13, 2025 08:19
Base automatically changed from remove-htlc-tx-with-remote-sig to master June 16, 2025 15:44
@t-bast
Copy link
Member

t-bast commented Jun 23, 2025

Superseded by #3118

@t-bast t-bast closed this Jun 23, 2025
@t-bast t-bast deleted the remove-htlc-tx-with-remote-sig-pm branch June 23, 2025 14:37
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