-
Notifications
You must be signed in to change notification settings - Fork 417
Trampoline Forwarding: Enforce trampoline constraints #3983
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
base: main
Are you sure you want to change the base?
Trampoline Forwarding: Enforce trampoline constraints #3983
Conversation
I've assigned @tankyleo as a reviewer! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3983 +/- ##
==========================================
- Coverage 88.94% 88.76% -0.18%
==========================================
Files 174 173 -1
Lines 124575 124753 +178
Branches 124575 124753 +178
==========================================
- Hits 110797 110732 -65
- Misses 11278 11602 +324
+ Partials 2500 2419 -81
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🔔 1st Reminder Hey @tankyleo! This PR has been waiting for your review. |
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 is a more mechanical review as I am not familiar with this part of the codebase :)
👋 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. |
Also when I remove everything but the test code, the test does not fail - is that intentional ? I have not reviewed the test |
thanks @tankyleo !
Double checked the tests and yes, this happens because when receiving a trampoline it behaves exactly as receiving a non-trampoline payment. Having the same failure scenario. I added fixups for each of your comments and rebased in top of main |
4deaa3e
to
d37d6d8
Compare
.with_payment_preimage(payment_preimage) | ||
.without_claimable_event() | ||
.expect_failure(HTLCHandlingFailureType::Receive { payment_hash }); | ||
|
||
do_pass_along_path(args); |
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.
Confirmed the test fails, then passes with the added code in the PR thank you! Can you help me understand why we fail here when we remove the code from the PR ?
Without knowing much I would have expected us to fail at expect_payment_failed_conditions
further below :)
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.
My intention was to separate the big PR into smaller ones. This one seemed as a possibility to separate work but many of the code must be tested when the final feature of forwarding arrives.
That being said, in order to test the enforcement of the failed conditions, I modified the CLTV of the outer onion to something lower but acceptable (payment would be received) and maintaining the cltv_expiry of the receiving (that probably isn't clear, I'll modify it).
So in the case of no enforcement, payment is received. In case with enforcement it should fail because of the CLTV that the trampoline has is greater than the outer blinded path.
.expected_htlc_error_data(LocalHTLCFailureReason::FinalIncorrectHTLCAmount, &[0, 0, 0, 0, 0, 0, 3, 232]); | ||
expect_payment_failed_conditions(&nodes[0], payment_hash, false, payment_failed_conditions); | ||
}, | ||
TrampolineConstraintFailureScenarios::TrampolineCLTVGreaterThanOnion => { | ||
let payment_failed_conditions = PaymentFailedConditions::new() | ||
.expected_htlc_error_data(LocalHTLCFailureReason::FinalIncorrectCLTVExpiry, &[0, 0, 0, 84]); |
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.
Would be cool to document how we got these numbers, why .., 0, 3, 232
and why .., 0, 0, 84
? Someone who comes here later might have a hard time understanding these constants :)
@@ -2257,6 +2485,8 @@ fn test_trampoline_unblinded_receive() { | |||
&secp_ctx, path.into_iter(), &carol_alice_trampoline_session_priv, | |||
).unwrap(); | |||
|
|||
let trampoline_cltv_value = if failure_scenario == TrampolineConstraintFailureScenarios::TrampolineCLTVGreaterThanOnion { 52 } else { 72 }; |
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.
Similar here, why did you pick 52 and 72 for the thresholds ? Thank you!
} | ||
{ | ||
let payment_failed_conditions = PaymentFailedConditions::new() | ||
.expected_htlc_error_data(LocalHTLCFailureReason::FinalIncorrectHTLCAmount, &[0, 0, 0, 0, 0, 0, 3, 232]); |
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.
Similar question here about where the 3, 232
comes from :)
lightning/src/ln/onion_payment.rs
Outdated
fn check_trampoline_onion_constraints( | ||
outer_hop_data: &msgs::InboundTrampolineEntrypointPayload, trampoline_cltv_value: u32, | ||
trampoline_amount: u64, | ||
) -> Result<(), (LocalHTLCFailureReason, Vec<u8>)> { |
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.
Here how about we set the Err
variant to InboundHTLCErr
, and we keep the map_err
to a LocalHTLCFailureReason::InvalidOnionBlinding
reason when inside a blinded path ?
TrampolineAmountGreaterThanOnion, | ||
} | ||
|
||
fn do_test_trampoline_unblinded_receive_contraint_failure(failure_scenario: TrampolineConstraintFailureScenarios) { |
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.
nit: fix typo :)
@@ -2086,7 +2086,7 @@ fn do_test_trampoline_single_hop_receive(success: bool) { | |||
pubkey: carol_node_id, | |||
node_features: Features::empty(), | |||
fee_msat: amt_msat, | |||
cltv_expiry_delta: 24, |
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.
Why is this change needed ? Thanks for the context.
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.
To calculate the outer onion of this receiving hop we do cltv_expiry_delta
of the hop plus the current height
In this case (24 + 32 = 56)
Then when building the trampoline we do excess_final_ctlv_expiry_delta
+ current_height (39+32 = 72)
With the new constraints trampoline > outer onion. So it fails.
fee_msat: amt_msat, | ||
cltv_expiry_delta: 24, | ||
fee_msat: 0, | ||
cltv_expiry_delta: 72, |
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.
Similar here about why this is needed thank you (take a look at this comment on the original commit, 4132e78 it might be clearer)
} | ||
|
||
#[test] | ||
fn test_trampoline_enforced_constrait_cltv() { |
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.
One more typo to squash here :)
Also go ahead and squash next time you push, and expand the commit message to describe in detail what you are doing, including in the tests :) Would help me out with reviewing the code too thank you ! |
We add a `check_trampoline_contraints` similar to `check_blinded_path_constraints` that compares the Trampoline onion's amount and CLTV values to the limitations impose by outer onion. We also add the expected errors by the spec: `TemporaryTrampolineFailure`, `TrampolineFeeOrExpiryInsufficient` and `UnknownNextTrampoline` to be used in case of errors when doing forwarding or validating the constraints. Finally, we add and modified the following tests: - Modified the unblinded receive to validate when receiving amt less than the expected. - Modified test with wrong CLTV parameters that has fails with new enforcement of CTLV limits. - Add unblinded receive test that forces trampoline onion's CLTV to be greater than the the outer onion packet. Note that there are some TODO's to be fixed in following commits as we need the full trampoline forwarding feature to effectivelly test all caseos. Co-authored-by: Arik Sosman <git@arik.io>
d37d6d8
to
3515844
Compare
@tankyleo Reading the initial PR needed a lot of explanation work 😅, thanks for the detailed review! All your comments should have been addressed and rebased and squashed. note that linting CI seems to be a problem on one of the new commits after rebase |
This PR is part of 1/N PRs in order to split up #3976
This commit checks amount and CLTV of the trampoline to the outer hop. If exceeds limitations we fail the forward using a
InboundHTLCErr
with specified local reason.