-
Notifications
You must be signed in to change notification settings - Fork 418
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
👋 Thanks for assigning @tankyleo as a reviewer! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3983 +/- ##
==========================================
- Coverage 88.94% 88.83% -0.11%
==========================================
Files 174 175 +1
Lines 124575 127997 +3422
Branches 124575 127997 +3422
==========================================
+ Hits 110797 113706 +2909
- Misses 11278 11721 +443
- Partials 2500 2570 +70
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
} | ||
{ | ||
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 :)
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.
@a-mpch Let's also do this here ? let expected_error_data = amt_msat.to_be_bytes();
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 ! |
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 |
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.
Another round of review thank you !
Also proofread the commit message, there are a few mistakes in there :)
We add a `check_trampoline_constraints` similar to `check_blinded_path_constraints` that compares the Trampoline onion's amount and CLTV values to the limitations imposed by the outer onion. We also add the expected errors by the spec: `TemporaryTrampolineFailure`, `TrampolineFeeOrExpiryInsufficient` and `UnknownNextTrampoline` to be used when encountering errors during forwarding or constraint validation. Finally, we add and modify the following tests: - Modified the unblinded receive to validate when receiving amount less than expected - Modified test with wrong CLTV parameters that now fails with new enforcement of CLTV limits - Add unblinded receive test that forces trampoline onion's CLTV to be greater than the outer onion packet Note that there are some TODOs to be fixed in following commits as we need the full trampoline forwarding feature to effectively test all cases. Co-authored-by: Arik Sosman <[email protected]>
3515844
to
5c6f023
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.
Just two last questions, then a couple of drive-by nits again thank you for all the work.
@@ -306,6 +349,15 @@ pub(super) fn create_recv_pending_htlc_info( | |||
} | |||
})?; | |||
let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat }; | |||
check_trampoline_onion_constraints(outer_hop_data, cltv_expiry_height, sender_intended_htlc_amt_msat).map_err(|e| { |
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 understand that we don't have test coverage for the forwarding code paths, but here we don't have test coverage - should we be adding a test for blinded trampoline receives ?
/// We have been unable to forward a payment to the next Trampoline node but may be able to | ||
/// do it later. | ||
TemporaryTrampolineFailure, | ||
/// The amount or CLTV expiry were insufficient to route the payment to the next Trampoline. | ||
TrampolineFeeOrExpiryInsufficient, | ||
/// The specified next Trampoline node cannot be reached from our node. | ||
UnknownNextTrampoline, |
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 would have expected these to be used in this PR since the commit message says
We also add the expected errors by the spec: `TemporaryTrampolineFailure`,
`TrampolineFeeOrExpiryInsufficient` and `UnknownNextTrampoline` to be used
when encountering errors during forwarding or constraint validation.
But as far as I see they are not used anywhere yet, can you help me understand ? thank you again !
// Creates custom onion packet where the final trampoline hop uses unblinded receive format | ||
// (not natively supported) to validate payment amount verification. | ||
// - When underpay=false: Payment succeeds with correct amount | ||
// - When underpay=true: Payment fails due to amount mismatch (sends 2x expected amount) |
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.
The blurb is great thank you ! If we send 2x the expected amount, shouldn't the boolean variable name be overpay
?
TrampolineHop { | ||
pubkey: carol_node_id, | ||
node_features: Features::empty(), | ||
fee_msat: 0, // no trampoline fee becuase we are receiving. |
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
|
||
// Get the original inner session private key that the ChannelManager generated so we can | ||
// re-use it for the outer session private key. This way HMAC validation in attributable | ||
// errors do not makes the test fail. |
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: does not make the test fail.
}, | ||
], | ||
hops: carol_blinded_hops, | ||
blinding_point: carol_blinding_point, | ||
// This will be ignored becase we force the cltv_expiry of the trampoline hop. |
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: because
let outer_session_priv = secret_from_hex("e52c20461ed7acd46c4e7b591a37610519179482887bd73bf3b94617f8f03677"); | ||
// Get the original inner session private key that the ChannelManager generated so we can | ||
// re-use it for the outer session private key. This way HMAC validation in attributable | ||
// errors do not makes the test fail. |
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: does not make the test fail.
let err = InboundHTLCErr { | ||
reason: LocalHTLCFailureReason::FinalIncorrectCLTVExpiry, | ||
err_data: outer_hop_data.outgoing_cltv_value.to_be_bytes().to_vec(), | ||
msg: "Trampoline onion's CLTV values exceeded the outer onion's", |
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: use singular value
let err = InboundHTLCErr { | ||
reason: LocalHTLCFailureReason::FinalIncorrectHTLCAmount, | ||
err_data: outgoing_amount.to_be_bytes().to_vec(), | ||
msg: "Trampoline onion's amt values exceeded the outer onion's", |
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: same here let's use singular value
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.