Skip to content

[Custom Transactions] Provide Built Counterparty Commitment Transactions To ChannelMonitor #3654

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2025

Conversation

tankyleo
Copy link
Contributor

@tankyleo tankyleo commented Mar 7, 2025

Provide built counterparty commitment transactions to `ChannelMonitor`

`LatestCounterpartyCommitmentTXInfo` provides `ChannelMonitor` with the
data it needs to build counterparty commitment transactions.
`ChannelMonitor` then rebuilds commitment transactions from these pieces
of data when requested.

This commit adds a new variant to `ChannelMonitorUpdateStep` called
`LatestCounterpartyCommitmentTX`, which will provide fully built
commitment transactions to `ChannelMonitor`. When `ChannelMonitor` is
asked for counterparty commitment transactions, it will not rebuild
them, but just clone them.

As a result, this new variant eliminates any calls to the upcoming
`TxBuilder` trait in `ChannelMonitor`, which avoids adding a generic
parameter on `ChannelMonitor`. This commit also stomps any bugs that
might come from passing around disparate pieces of data to re-build
commitment transactions from scratch.

We also add a `htlc_outputs` field to the variant to include the dust
HTLCs, as well as all the HTLC sources. This means that this new variant
will store non-dust HTLCs both in the `htlc_outputs` field, and in the
`commitment_tx` field. This is ok for now as the number of HTLCs
per commitment nowadays is very low.

We add code to handle this new variant, but refrain from
immediately setting it. This will allow us to atomically switch from
`LatestCounterpartyCommitmentTXInfo` to `LatestCounterpartyCommitmentTX`
in the future while still allowing downgrades.

This was previously part of #3606

@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Mar 7, 2025

👋 I see @valentinewallace was un-assigned.
If you'd like another reviewer assignemnt, please click here.

@tankyleo tankyleo changed the title Provide built commitment transactions to ChannelMonitor Provide built counterparty commitment transactions to ChannelMonitor Mar 7, 2025
@tankyleo tankyleo force-pushed the channel-monitor-updates branch from ad98735 to 9f88056 Compare March 8, 2025 19:38
@tankyleo tankyleo changed the title Provide built counterparty commitment transactions to ChannelMonitor Provide Built Counterparty Commitment Transactions To ChannelMonitor Mar 8, 2025
@tankyleo tankyleo force-pushed the channel-monitor-updates branch 2 times, most recently from 6e70599 to 52a2eb8 Compare March 8, 2025 19:58
Copy link

codecov bot commented Mar 8, 2025

Codecov Report

Attention: Patch coverage is 82.22222% with 8 lines in your changes missing coverage. Please review.

Project coverage is 89.23%. Comparing base (4c43a5b) to head (29a8b9f).

Files with missing lines Patch % Lines
lightning/src/chain/channelmonitor.rs 81.57% 7 Missing ⚠️
lightning/src/ln/channel.rs 85.71% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3654      +/-   ##
==========================================
+ Coverage   89.18%   89.23%   +0.04%     
==========================================
  Files         155      155              
  Lines      119274   119280       +6     
  Branches   119274   119280       +6     
==========================================
+ Hits       106379   106440      +61     
+ Misses      10290    10241      -49     
+ Partials     2605     2599       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tankyleo tankyleo force-pushed the channel-monitor-updates branch from 52a2eb8 to 29a8b9f Compare March 8, 2025 20:12
@tankyleo tankyleo changed the title Provide Built Counterparty Commitment Transactions To ChannelMonitor [Custom Transactions] Provide Built Counterparty Commitment Transactions To ChannelMonitor Mar 10, 2025
@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @valentinewallace! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Copy link
Contributor

@wpaulino wpaulino left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines 3449 to 3456
let htlc_outputs = vec![];

let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
feerate_per_kw, htlc_outputs);
// Take the opportunity to populate this recently introduced field
self.initial_counterparty_commitment_tx = Some(commitment_tx.clone());
commitment_tx
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: indentation seems off here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you I addressed this below, ran the block through fmt.

Comment on lines 3508 to 3509
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs: _,
ref commitment_tx,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs: _,
ref commitment_tx,
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX {
htlc_outputs: _, ref commitment_tx,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you, addressed below.

@wpaulino wpaulino requested review from jkczyz and removed request for valentinewallace March 10, 2025 18:20
@tankyleo tankyleo force-pushed the channel-monitor-updates branch from 29a8b9f to e1b5fe0 Compare March 10, 2025 18:40
to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L,
)
where L::Target: Logger
&self, commitment_tx: CommitmentTransaction, logger: &L,
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's update the docs accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks ! Addressed below.

self.initial_counterparty_commitment_tx.clone().or_else(|| {
// This provides forward compatibility; an old monitor will not contain the full
// transaction; only enough information to rebuild it
self.initial_counterparty_commitment_info.map(
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we ever return None now? It seems before we couldn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before we could return None at this call self.initial_counterparty_commitment_info?;

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, for reason I was unaware that ? worked with Option return types.

`LatestCounterpartyCommitmentTXInfo` provides `ChannelMonitor` with the
data it needs to build counterparty commitment transactions.
`ChannelMonitor` then rebuilds commitment transactions from these pieces
of data when requested.

This commit adds a new variant to `ChannelMonitorUpdateStep` called
`LatestCounterpartyCommitmentTX`, which will provide fully built
commitment transactions to `ChannelMonitor`. When `ChannelMonitor` is
asked for counterparty commitment transactions, it will not rebuild
them, but just clone them.

As a result, this new variant eliminates any calls to the upcoming
`TxBuilder` trait in `ChannelMonitor`, which avoids adding a generic
parameter on `ChannelMonitor`. This commit also stomps any bugs that
might come from passing around disparate pieces of data to re-build
commitment transactions from scratch.

We also add a `htlc_outputs` field to the variant to include the dust
HTLCs, as well as all the HTLC sources. This means that this new variant
will store non-dust HTLCs both in the `htlc_outputs` field, and in the
`commitment_tx` field. This is ok for now as the number of HTLCs
per commitment nowadays is very low.

We add code to handle this new variant, but refrain from
immediately setting it. This will allow us to atomically switch from
`LatestCounterpartyCommitmentTXInfo` to `LatestCounterpartyCommitmentTX`
in the future while still allowing downgrades.
@tankyleo tankyleo force-pushed the channel-monitor-updates branch from e1b5fe0 to b8a03cd Compare March 10, 2025 19:16
@wpaulino wpaulino merged commit 00ee0ef into lightningdevkit:main Mar 11, 2025
23 of 27 checks passed
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
},
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs, commitment_tx } => {
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs.clone(), commitment_tx.commitment_number(), commitment_tx.per_commitment_point(), logger)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we handle having both the legacy and new version? I guess i was hoping we wouldn't have to wait a release or two for this stuff (which we have to do if we're trying to bridge versions here).

Copy link
Contributor

Choose a reason for hiding this comment

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

We could -- I think it was done that way first in #3606 but I was concerned about the extra storage cost. We're planning to use this new variant (along with a similar one for latest holder commitment) for spliced channels as a way to move to the new format sooner since you can't downgrade with a pending splice anyway.

Copy link
Contributor Author

@tankyleo tankyleo Mar 11, 2025

Choose a reason for hiding this comment

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

I think it was done that way first in #3606 but I was concerned about the extra storage cost.

Right yes we previously added another field to the legacy variant that contained the full transaction. This made most of the fields in the legacy variant redundant so we went for a new variant.

Then to alleviate the storage cost we decided against immediately setting this new variant.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yea, okay, that all makes sense, just annoying that we have to wait a release or two to ship things. Alas.

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.

5 participants