-
Notifications
You must be signed in to change notification settings - Fork 390
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
Replace use of HolderSignedTx with HolderCommitment #3664
base: main
Are you sure you want to change the base?
Replace use of HolderSignedTx with HolderCommitment #3664
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
@@ -3531,23 +3531,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider { | |||
return Err(ChannelError::close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_stats.num_nondust_htlcs))); | |||
} | |||
|
|||
// Up to LDK 0.0.115, HTLC information was required to be duplicated in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, did we fuck this up? Is there no way to indicate to old LDK to decline to decode the update now that its no longer actually compatible? At a minimum we need release notes but kinda annoying that we'll just silently corrupt state if a user downgrades to 0.0.115.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I think we would've needed to add an optional even TLV back then that only gets set when the sources are provided separately. Release notes will have to do for now.
lightning/src/ln/channel.rs
Outdated
if let Some(source) = source_opt.take() { | ||
nondust_htlc_sources.push(source); | ||
} else { | ||
debug_assert!(false, "Missing outbound HTLC source"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be a hard assert, right? And also probably we should change the types to avoid it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the types on what? The source still needs to be optional in case the HTLC is not offered by the holder.
PackageSolvingData::HolderHTLCOutput(htlc_output), | ||
counterparty_spendable_height, | ||
); | ||
claim_requests.push(htlc_package); | ||
} else { | ||
debug_assert!(false, "Expected transaction output index for non-dust HTLC"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, we really need to change the types on htlc info so that we don't have these checks everywhere...if we're gonna separate tracking of dust from non-dust we should use different types...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, unfortunately there are still areas where we track them both together in a single Vec, so I don't think we can get there quite yet as of this PR.
writer.write_all(&[1; 1])?; | ||
prev_holder_tx.write(writer)?; | ||
HolderSignedTx::from(prev_holder_commitment).write(writer)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bleh, can we just implement a write_as_legacy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to avoid the from
magic? Because we still need that further below to make sure the HolderCommitmentTransaction
we got from the OnchainTxHandler
maps to the HolderSignedTx
we read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In all of those cases there's no reason we need to be cloning the HTLC vecs and sources. I'd really prefer to avoid that. Plus we also panic in the conversion while trying to check if the data we read was valid, which is generally something we try to avoid.
let holder_commitment = HolderCommitment::try_from(( | ||
current_holder_commitment_tx, ¤t_holder_signed_tx, | ||
)).map_err(|_| DecodeError::InvalidValue)?; | ||
if HolderSignedTx::from(&holder_commitment) != current_holder_signed_tx { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's gonna happen here? Are we just gonna keep writing the legacy versions and converting, or should we have some upgrade path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was planning to address this in a follow-up PR that removes them from OnchainTxHandler
such that we can no longer rely on getting them from there and instead store them as a new TLV in the monitor.
👋 The first review has been submitted! Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer. |
This does seem like the kind of thing that might want an 👋 upgrade test 👋 |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3664 +/- ##
==========================================
- Coverage 89.25% 89.20% -0.06%
==========================================
Files 155 155
Lines 119959 120054 +95
Branches 119959 120054 +95
==========================================
+ Hits 107069 107090 +21
- Misses 10276 10332 +56
- Partials 2614 2632 +18 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Will need to wait for #3584 first |
2884bad
to
fdc1706
Compare
Needs rebase. |
fdc1706
to
73f82fb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't make it through everything, some initial comments.
I'm also unclear how this helps with custom commitment transactions in particular ? Thanks for clarifying here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made it through everything. Nothing out of the ordinary pops out aside from what other reviewers have raised.
I'm also unclear how this helps with custom commitment transactions in particular ? Thanks for clarifying here.
Will let @wpaulino confirm, but IIUC prior to this PR we were only storing parts of the commitment transaction, so anything additional in a custom one would be missing.
73f82fb
to
24dffdb
Compare
Correct. We were already tracking the actual commitment transaction at the |
Ok! From my side here's how I've been approaching custom transactions in channel monitor. Many details I haven't worked out yet but big picture:
Experimental API currently looks like this: /// Returns claims on a counterparty commitment transaction
fn generate_claims_from_counterparty_tx(&self,
per_commitment_point: &PublicKey,
channel_parameters: &ChannelTransactionParameters,
tx: &Transaction,
per_commitment_claimable_data: &Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
payment_preimages: &HashMap<PaymentHash, (PaymentPreimage, Vec<PaymentClaimDetails>)>,
secp_ctx: &Secp256k1<secp256k1::All>,
) -> (Vec<PackageTemplate>, CommitmentTxCounterpartyOutputInfo);
/// Returns claims on a counterparty's revoked commitment transaction
fn generate_claims_from_revoked_tx(
&self,
per_commitment_key: &SecretKey,
channel_parameters: &ChannelTransactionParameters,
tx: &Transaction,
per_commitment_claimable_data: &Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
height: u32,
secp_ctx: &Secp256k1<secp256k1::All>,
) -> (Vec<PackageTemplate>, CommitmentTxCounterpartyOutputInfo);
/// Returns claims on a holder's commitment transaction
fn generate_claims_from_holder_tx(
&self,
holder_tx: &HolderSignedTx,
conf_height: u32,
channel_parameters: &ChannelTransactionParameters,
payment_preimages: &HashMap<PaymentHash, (PaymentPreimage, Vec<PaymentClaimDetails>)>,
secp_ctx: &Secp256k1<secp256k1::All>,
) -> Vec<PackageTemplate>; What's missing:
Let me know if this syncs up with what you were thinking @wpaulino happy to chat here or elsewhere. This branch here contains this API together with an implementation that passes the test suite: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from pending discussions. Please re-request a review once those are resolved.
@tankyleo your proposal seems fine so far. The only change as a result of this PR would be to the function argument in |
Yes agreed
Sounds good |
@@ -3593,7 +3577,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider { | |||
|
|||
Ok(LatestHolderCommitmentTXInfo { | |||
commitment_tx: holder_commitment_tx, | |||
htlc_outputs: htlcs_and_sigs, | |||
htlc_outputs: dust_htlcs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename this now that its something different?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might still have the old meaning when we read. Would you rather change it now anyway or wait until we know for sure we'll only ever find dust_htlcs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mostly_dust_htlcs
? :). I mean we can certainly do it later, just seems easy for a bug to slip in because of a bad name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather defer it. I don't think a bug could happen where non-dust HTLCs are included because we still have code to support that, and the current name already assumed dust HTLCs must be included.
writer.write_all(&[1; 1])?; | ||
prev_holder_tx.write(writer)?; | ||
HolderSignedTx::from(prev_holder_commitment).write(writer)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In all of those cases there's no reason we need to be cloning the HTLC vecs and sources. I'd really prefer to avoid that. Plus we also panic in the conversion while trying to check if the data we read was valid, which is generally something we try to avoid.
24dffdb
to
41d9463
Compare
Currently, non-dust HTLCs are duplicated across the commitment transaction itself, and the full set of HTLCs (dust & non-dust) along with their `HTLCSource` considered in the commitment transaction. As of v0.0.15, we've had support for providing non-dust HTLC sources separately such that we no longer track duplicate non-dust HTLC data, but only enabled it under testing environments. This commit enables it such that it always happens. Note that we still need to support reading `ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo` updates that did not separate the non-dust HTLC sources in case they were written in an older version and they've yet to be processed.
41d9463
to
7f626c8
Compare
Had to rebase due to a conflict with #3606 and implemented |
As we move to a custom commitment transactions world, we'll no longer be able to rely on `HolderSignedTx` and should instead track the actual commitment transaction itself. This commit does so by introducing a new `HolderCommitment` struct, which we'll use as a replacement to `HolderSignedTx` to hold all relevant holder commitment data, including the `HolderCommitmentTransaction`, without data duplication. Luckily, this is a backwards and forwards compatible change due to the `OnchainTxHandler` tracking the latest `HolderCommitmentTransaction`s. In the future, we aim to remove them from the `OnchainTxHandler` entirely and begin storing them at the `ChannelMonitor` level. Aside from how the data is represented internally, there shouldn't be any functional changes within this patch.
7f626c8
to
a891a04
Compare
As we move to a custom commitment transactions world, we'll no longer be able to rely on
HolderSignedTx
and should instead track the actual commitment transaction itself. This commit does so by introducing a newHolderCommitment
struct, which we'll use as a replacement toHolderSignedTx
to hold all relevant holder commitment data, including theHolderCommitmentTransaction
, without data duplication.Luckily, this is a backwards and forwards compatible change due to the
OnchainTxHandler
tracking the latestHolderCommitmentTransaction
s. In the future, we aim to remove them from theOnchainTxHandler
entirely and begin storing them at theChannelMonitor
level.Aside from how the data is represented internally, there shouldn't be any functional changes within this patch.
Depends on #3663.