Skip to content
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

Avoid storing a full FinalOnionHopData in OnionPayload::Invoice #1447

Conversation

andozw
Copy link

@andozw andozw commented Apr 23, 2022

Splits these commits from #1221 and #1445 because they should be separate.

See #1445 (review)

@codecov-commenter
Copy link

codecov-commenter commented Apr 23, 2022

Codecov Report

Merging #1447 (fc77c57) into main (9bdce47) will decrease coverage by 0.00%.
The diff coverage is 80.55%.

@@            Coverage Diff             @@
##             main    #1447      +/-   ##
==========================================
- Coverage   90.90%   90.89%   -0.01%     
==========================================
  Files          75       75              
  Lines       41616    41624       +8     
  Branches    41616    41624       +8     
==========================================
+ Hits        37829    37834       +5     
- Misses       3787     3790       +3     
Impacted Files Coverage Δ
lightning/src/ln/channelmanager.rs 84.70% <80.00%> (-0.05%) ⬇️
lightning/src/ln/inbound_payment.rs 93.49% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9bdce47...fc77c57. Read the comment docs.

Copy link
Contributor

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

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

LGTM!

log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the total value {} ran over expected value {} (or HTLCs were inconsistent)",
log_bytes!(payment_hash.0), total_value, $payment_data_total_msat);
fail_htlc!(claimable_htlc);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Gah, this is wrong and our test coverage is really lacking here. I'm working on some improved testing here but in the mean time the fail_htlc call has to stay and the htlcs.push calls need to go back in the branches instead of being unconditional.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you intend to resolve it in this PR before merging it?

Copy link
Author

Choose a reason for hiding this comment

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

@arik-so yes

Copy link
Contributor

@valentinewallace valentinewallace left a comment

Choose a reason for hiding this comment

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

Looks pretty good! Do we wanna rebase it on #1451 to get the test coverage there?

Comment on lines 173 to 181
value: u64,
onion_payload: OnionPayload,
timer_ticks: u8,
total_msat: u64,
Copy link
Contributor

Choose a reason for hiding this comment

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

Could be nice to document the difference between value and total_msat

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed; in fact, would be necessary imo

Copy link
Author

Choose a reason for hiding this comment

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

Is this close to accurate?

/// HTLCs that are to us and can be failed/claimed by the user
 struct ClaimableHTLC {
        prev_hop: HTLCPreviousHopData,
        cltv_expiry: u32,
       /// The amount (in msats) of this MPP part
        value: u64,
        onion_payload: OnionPayload,
        timer_ticks: u8,
       /// The sum total of all MPP parts
        total_msat: u64,
 }

It was not super clear to me, but I am going to walk through the code more and try to figure it out.

Copy link
Contributor

Choose a reason for hiding this comment

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

That looks good to me!

@andozw
Copy link
Author

andozw commented Apr 27, 2022

Looks pretty good! Do we wanna rebase it on #1451 to get the test coverage there?

I'll give it a go

@andozw andozw force-pushed the seana.20220422.avoid-storing-FinalOnionHopData branch from b4ba546 to d0cf6b8 Compare April 29, 2022 16:33
total_value = msgs::MAX_VALUE_MSAT;
}
if total_value >= msgs::MAX_VALUE_MSAT { break; }
},
_ => unreachable!(),
}
}
if total_value >= msgs::MAX_VALUE_MSAT || total_value > $payment_data_total_msat {
if total_value >= msgs::MAX_VALUE_MSAT || total_value > claimable_htlc.total_msat {
Copy link
Author

Choose a reason for hiding this comment

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

@TheBlueMatt - should this be || total_value > $payment_data.total_msat ? The tests pass either way. I haven't rebased against #1451 yet but it looks like that one might be ready to merge?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yea, its definitely more readable that way. That said I believe they're the same, though its a good bit of careful reading to see that, and I'm not even 100% confident of that after reading it five times.

@andozw andozw force-pushed the seana.20220422.avoid-storing-FinalOnionHopData branch from d0cf6b8 to 4da7916 Compare April 29, 2022 17:18
@andozw
Copy link
Author

andozw commented Apr 29, 2022

rebased

Copy link
Contributor

@valentinewallace valentinewallace left a comment

Choose a reason for hiding this comment

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

One comment but otherwise ACK with Matt's suggestion. Appreciate that these commits were separated out!

@@ -3465,7 +3476,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
debug_assert!(false);
return false;
}
if let OnionPayload::Invoice(ref final_hop_data) = htlcs[0].onion_payload {
if let OnionPayload::Invoice { _legacy_hop_data: ref final_hop_data } = htlcs[0].onion_payload {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a blocker, but it looks like we can get rid of this usage as well by accessing htlcs[0].total_msat instead of final_hop_data? @TheBlueMatt

Copy link
Author

Choose a reason for hiding this comment

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

done!

@andozw andozw force-pushed the seana.20220422.avoid-storing-FinalOnionHopData branch from 4da7916 to 16a6ad2 Compare April 30, 2022 16:32
Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

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

Okay, sorry for the delay on this one, LGTM modulo two trivial comments.

Invoice(msgs::FinalOnionHopData),
Invoice {
/// This is only here for backwards-compatibility in serialization, in the future it can be
/// removed, breaking clients running 0.0.104 and earlier.
Copy link
Collaborator

Choose a reason for hiding this comment

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

heh, well that's stale - should read "0.0.106", assuming this lands for 107, which it should.

(incoming_cltv_expiry, OnionPayload::Invoice(payment_data), phantom_shared_secret),
let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => {
let _legacy_hop_data = msgs::FinalOnionHopData {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: replace the explicit instantiation with just let _legacy_hop_data = payment_data.clone(), given that's what we're doing anyway.

...instead of accessing it via the `OnionPayload::Invoice` form.
This may be useful if we add MPP keysend support, but is directly
useful to allow us to drop `FinalOnionHopData` from `OnionPayload`.
@andozw andozw force-pushed the seana.20220422.avoid-storing-FinalOnionHopData branch from 16a6ad2 to 1973f1f Compare May 2, 2022 16:37
@andozw
Copy link
Author

andozw commented May 2, 2022

rebased

@andozw andozw force-pushed the seana.20220422.avoid-storing-FinalOnionHopData branch from 1973f1f to c611aff Compare May 2, 2022 16:49
@andozw
Copy link
Author

andozw commented May 2, 2022

Addressed the 2 minor fixups as an amend on the last commit since they belong there and were trivial. Should be ready for another 👀

Comment on lines 162 to 164
/// Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a
/// payment_secret which prevents path-probing attacks and can associate different HTLCs which
/// are part of the same payment.
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry should've seen this sooner, not a blocker but I think this can be removed and just say "Indicates this incoming onion payload is for the purpose of paying an invoice" or something like that

Copy link
Author

Choose a reason for hiding this comment

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

So replace Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a payment_secret which prevents path-probing attacks and can associate different HTLCs which are part of the same payment.
with:
Indicates this incoming onion payload is for the purpose of paying an invoice ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep, that sounds great.

We only use it to check the amount when processing MPP parts, but
store the full object (including new payment metadata) in it.
Because we now store the amount in the parent structure, there is
no need for it at all in the `OnionPayload`. Sadly, for
serialization compatibility, we need it to continue to exist, at
least temporarily, but we can avoid populating the new fields in
that case.
@andozw andozw force-pushed the seana.20220422.avoid-storing-FinalOnionHopData branch from c611aff to fc77c57 Compare May 2, 2022 18:41
@TheBlueMatt TheBlueMatt merged commit e3a305c into lightningdevkit:main May 2, 2022
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.

6 participants