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

Fix router fuzz failure #2570

Merged

Conversation

valentinewallace
Copy link
Contributor

@valentinewallace valentinewallace commented Sep 12, 2023

Fixes #2523 and another panic from fuzz input https://pastebin.com/9ZkmyzHE. See test comments for more details on the fixes.

@valentinewallace valentinewallace added this to the 0.0.117 milestone Sep 12, 2023
@TheBlueMatt
Copy link
Collaborator

LGTM, but will give this some fuzzing cycles to see if it finds anything else. Will wait to assign a second reviewer for a minute cause folks are super busy lol.

@valentinewallace
Copy link
Contributor Author

Added another fuzz fix, see latest commit.

@codecov-commenter
Copy link

codecov-commenter commented Sep 15, 2023

Codecov Report

Attention: 7 lines in your changes are missing coverage. Please review.

Comparison is base (0f87ee8) 88.97% compared to head (5e742b6) 88.98%.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2570    +/-   ##
========================================
  Coverage   88.97%   88.98%            
========================================
  Files         113      113            
  Lines       85890    86292   +402     
  Branches    85890    86292   +402     
========================================
+ Hits        76424    76784   +360     
- Misses       7239     7270    +31     
- Partials     2227     2238    +11     
Files Coverage Δ
lightning/src/routing/router.rs 93.84% <98.37%> (+0.36%) ⬆️

... and 8 files with indirect coverage changes

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

tnull
tnull previously approved these changes Sep 18, 2023
Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

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

LGTM, checked that changes fix the otherwise failing tests, and that they play together nicely with #2575 after a trivial rebase.

@valentinewallace
Copy link
Contributor Author

Thanks for taking a look! I'm gonna tack on one more fuzz fix that changes the last commit slightly.

@valentinewallace
Copy link
Contributor Author

Rewrote the last commit to generalize the solution and added another test courtesy of the fuzzer.

lightning/src/routing/router.rs Outdated Show resolved Hide resolved
lightning/src/routing/router.rs Outdated Show resolved Hide resolved
@TheBlueMatt
Copy link
Collaborator

Ugh, this is failing again - https://pastebin.com/XyrjGm3U

The fuzzer managed to hit this and it causes some invalid paths to be generated
internally.
Because my text editor loves to do that.
@valentinewallace
Copy link
Contributor Author

I fuzzed this latest branch overnight and it didn't find anything, when previously it found a crash within an hour. Also rebased to fix conflicts.

@@ -1280,6 +1284,7 @@ impl<'a> PaymentPath<'a> {

let cur_hop = &mut self.hops.get_mut(i).unwrap().0;
cur_hop.next_hops_fee_msat = total_fee_paid_msat;
cur_hop.path_penalty_msat += extra_contribution_msat;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't quite understand the extra penalization here. Wouldn't the path just be deprioritized anyways as it's higher cost?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It’s not higher cost with this solution because we don’t add the overpayment amount to the fees, just to the path contribution amount. The test fails without this as it will select an overpaying path when a path for the exact payment value is available.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, makes sense. Doesn't make update_value_and_recompute_fees much more readable though..

Maybe would be worth another comment to explain why we carve out the last hop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm tempted to try to refactor this method, it's not fun to parse..

Maybe would be worth another comment to explain why we carve out the last hop?

I kept your comment stating that we return the extra fees to account for them in the path's value contribution. Is something missing there?

Copy link
Contributor

Choose a reason for hiding this comment

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

I kept your comment stating that we return the extra fees to account for them in the path's value contribution. Is something missing there?

Could mention why we don't count the fees in this case, but probably doesn't make a big difference. Fine to leave as is.

lightning/src/routing/router.rs Show resolved Hide resolved
Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

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

So far looks good to me, I checked that rebasing #2575 works without issue if I drop the first commit there, that the LDK Node issue is still fixed, and that #2604 rebased on top of the rebase still has all tests pass. Only nit would be that I'd prefer the more general solution in 7144866, but of course we'll want to keep the tests here.

So, how should we go about landing all these? 😁

Edit: Rebased #2575 on top of this and included the requested change as part of that.

@valentinewallace
Copy link
Contributor Author

Pushed a fix for 1.48 CI:

diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs
index 17df884de..79a51b66a 100644
--- a/lightning/src/routing/router.rs
+++ b/lightning/src/routing/router.rs
@@ -7570,12 +7570,12 @@ mod tests {
                                ],
                        };
                        let mut blinded_hints = Vec::new();
-                       for htlc_min in htlc_mins {
+                       for htlc_min in htlc_mins.iter() {
                                blinded_hints.push((BlindedPayInfo {
                                        fee_base_msat: 0,
                                        fee_proportional_millionths: 0,
-                                       htlc_minimum_msat: htlc_min,
-                                       htlc_maximum_msat: htlc_min * 100,
+                                       htlc_minimum_msat: *htlc_min,
+                                       htlc_maximum_msat: *htlc_min * 100,
                                        cltv_expiry_delta: 10,
                                        features: BlindedHopFeatures::empty(),
                                }, blinded_path.clone()));

See tests, but the fuzzer found several panics from not fully ignoring these
hints.

We should support these route hints eventually, but it will involve some
reworking of the Path/BlindedTail structs.
Previously this variable was a bool, but has since been updated to be an
Option, so rename accordingly.
Previously, we would add a candidate hop to the list of potential hops even
though its available contribution wasn't sufficient to meet the next hop's
min_htlc. We'd subsequently build an invalid path using this hop and hit a
debug assertion.
See previous commit, but the bug where we would underestimate how much a first
hop candidate needed to be able to relay was also present in blinded paths.
Previously, we would add a first_hop<>network_node channel that did not have
enough contribution amount to cover the next channel's min htlc plus fees,
because we were storing the next hop as having a path_min that did not include
fees, and would add a connecting first_hop node that did not have enough
contribution amount, leading to a debug panic upon invalid path construction.
Previously, the fuzzer hit a debug panic because we wouldn't include the amount
overpaid to meet a last hop's min_htlc in the total collected paths value. We
now include this value and also penalize hops along the overpaying path to
ensure that it gets deprioritized in path selection.
@valentinewallace
Copy link
Contributor Author

Updated to make 2 tests more robust, later changes would make them spuriously succeed if the original change was reverted.

// Values are taken from the fuzz input that uncovered this panic.
let amt_msat = 7_4009_8048;
let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
let first_hop_outbound_capacity = 2_7345_2000;
Copy link
Contributor Author

@valentinewallace valentinewallace Sep 27, 2023

Choose a reason for hiding this comment

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

@TheBlueMatt this was an existing issue before routing to blinded paths was supported. ISTM the router fuzzer should've caught this previously?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yea, that's my impression too, not sure why I wasn't able to repro prior to the changes in 117.

Copy link
Contributor

@tnull tnull left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -1280,6 +1284,7 @@ impl<'a> PaymentPath<'a> {

let cur_hop = &mut self.hops.get_mut(i).unwrap().0;
cur_hop.next_hops_fee_msat = total_fee_paid_msat;
cur_hop.path_penalty_msat += extra_contribution_msat;
Copy link
Contributor

Choose a reason for hiding this comment

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

I kept your comment stating that we return the extra fees to account for them in the path's value contribution. Is something missing there?

Could mention why we don't count the fees in this case, but probably doesn't make a big difference. Fine to leave as is.

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.

LGTM. If there's any more failures we can fix them later.

@TheBlueMatt TheBlueMatt merged commit 7b4fb9d into lightningdevkit:main Sep 27, 2023
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.

Router fuzz panic on blinded paths
4 participants