Skip to content

Improve logging of pathfinding behavior #2011

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

Closed
wants to merge 28 commits into from

Conversation

Sharmalm
Copy link
Contributor

@Sharmalm Sharmalm commented Feb 5, 2023

This pull request is for issue #1646.Please review my PR. :)

@codecov-commenter
Copy link

codecov-commenter commented Feb 5, 2023

Codecov Report

Patch coverage has no change and project coverage change: -0.02 ⚠️

Comparison is base (12d799e) 91.15% compared to head (4364e18) 91.13%.

❗ Current head 4364e18 differs from pull request most recent head 34d21dc. Consider uploading reports for the commit 34d21dc to get more accurate results

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2011      +/-   ##
==========================================
- Coverage   91.15%   91.13%   -0.02%     
==========================================
  Files         101      101              
  Lines       48868    48769      -99     
  Branches    48868    48769      -99     
==========================================
- Hits        44544    44445      -99     
  Misses       4324     4324              
Impacted Files Coverage Δ
lightning/src/routing/router.rs 94.69% <ø> (-0.11%) ⬇️

... and 24 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@Sharmalm Sharmalm marked this pull request as ready for review February 5, 2023 17:47
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.

Thank you for having a go at this! Here are some initial comments.

@@ -1270,6 +1270,12 @@ where L::Target: Logger {
// around again with a higher amount.
if !contributes_sufficient_value || exceeds_max_path_length ||
exceeds_cltv_delta_limit || payment_failed_on_this_channel {
if let Some(first_hops) = first_hops { // for only first hop it will log feedback
for hop in first_hops {
let _channel_id = hop.channel_id;
Copy link
Contributor

Choose a reason for hiding this comment

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

You probably want to log via the short_channel_id rather than the channel_id to maintain uniformity with other logging outputs.

for hop in first_hops {
let _channel_id = hop.channel_id;
}
log_trace!(logger, "first Hop is excluded because unfulfilling condition");
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nice to know a) what hop was excluded and b) why exactly it was excluded. To this end it might make sense to break up the ORed bools above into individual else if statements.

@@ -1270,6 +1270,12 @@ where L::Target: Logger {
// around again with a higher amount.
if !contributes_sufficient_value || exceeds_max_path_length ||
exceeds_cltv_delta_limit || payment_failed_on_this_channel {
if let Some(first_hops) = first_hops { // for only first hop it will log feedback
for hop in first_hops {
Copy link
Contributor

Choose a reason for hiding this comment

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

With this you're logging every single first hop, independently of whether it was excluded or not. You rather should just log the current candidate if it matches one of the first hops.

Copy link
Contributor Author

@Sharmalm Sharmalm Feb 8, 2023

Choose a reason for hiding this comment

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

where to find find current candidate in this code :)

Copy link
Contributor

Choose a reason for hiding this comment

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

where to find find current candidate in this code :)

$candidate

@@ -1270,6 +1270,12 @@ where L::Target: Logger {
// around again with a higher amount.
if !contributes_sufficient_value || exceeds_max_path_length ||
exceeds_cltv_delta_limit || payment_failed_on_this_channel {
if let Some(first_hops) = first_hops { // for only first hop it will log feedback
Copy link
Contributor

Choose a reason for hiding this comment

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

If you'd use first_hop_targets rather than first_hops, there would be no need for this unwrapping.

Copy link
Contributor Author

@Sharmalm Sharmalm Feb 8, 2023

Choose a reason for hiding this comment

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

@tnull But first_hop_targets doesn't have short_channel_id field.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes it does. It is a HashMap from PublicKey to ChannelDetails and the latter has short_channel_id.

@Sharmalm
Copy link
Contributor Author

Sharmalm commented Feb 6, 2023

OK

@TheBlueMatt
Copy link
Collaborator

Looks like CI is failing due to a unknown-item error.

@Sharmalm
Copy link
Contributor Author

Sharmalm commented Feb 11, 2023

Looks like CI is failing due to a unknown-item error.

But it build's successfully on my device

Screenshot from 2023-02-09 23-44-28

@Sharmalm
Copy link
Contributor Author

Hey, how can I fix the CI error even though it builds successfully on my device?

@Sharmalm Sharmalm requested a review from tnull February 13, 2023 06:18
let our_node_id = NodeId::from_pubkey(&our_node_pubkey);
let target = first_hop_targets.get(&NodeId::from_pubkey(&our_node_pubkey)).unwrap();
let empty_vec: Vec<&ChannelDetails> = Vec::new();
let target = match first_hop_targets.get(&NodeId::from_pubkey(&our_node_pubkey)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you're looking for

Suggested change
let target = match first_hop_targets.get(&NodeId::from_pubkey(&our_node_pubkey)) {
if let Some(targets) = first_hop_targets.get(&NodeId::from_pubkey(&our_node_pubkey)) {

and then can just move the for inside? An alternative would be to use .unwrap_or(Vec::new()) or similar.

if short_channel_id == short_channel_id_target {
log_trace!(logger, "first Hop of node id {our_node_id} is excluded due to a failed requirement.");
if short_channel_id == short_channel_id_target { // short_channel_id is hop id of candidate.
if !contributes_sufficient_value {
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 think we should replicate checking on the individual bools here, rather we can just break the big if above, no? Likely we also want to create the is_first_hop bool before that so that we can reuse it in all variants.

@@ -1243,6 +1243,25 @@ where L::Target: Logger {
// around again with a higher amount.
if !contributes_sufficient_value || exceeds_max_path_length ||
exceeds_cltv_delta_limit || payment_failed_on_this_channel {
let mut is_first_hop = true;
if let Some(target) = first_hop_targets.get(&NodeId::from_pubkey(&our_node_pubkey)){
Copy link
Collaborator

Choose a reason for hiding this comment

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

Have you tested this somehow? I don't think our node key can ever be in first_hop_targets. Maybe try writing a test for exactly one of the cases here and see if you can get it to hit one of your new logs.

Copy link
Contributor Author

@Sharmalm Sharmalm Feb 16, 2023

Choose a reason for hiding this comment

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

.entry(NodeId::from_pubkey(&chan.counterparty.node_id))

@TheBlueMatt , NodeId is the Key of the Hashmap first_hop_targets here ,right?.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have you tested this somehow? I don't think our node key can ever be in first_hop_targets. Maybe try writing a test for exactly one of the cases here and see if you can get it to hit one of your new logs.

Hey @TheBlueMatt , I don't know how to use test. How should I approach writing tests :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Start by looking at how the existing tests work and select one that does something similar and copy/modify it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK

Copy link
Contributor Author

@Sharmalm Sharmalm Feb 20, 2023

Choose a reason for hiding this comment

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

Start by looking at how the existing tests work and select one that does something similar and copy/modify it.

Please help me with test functions. I can't find any similar test functions of logging.

let mut is_first_hop = true;
// if let Some(target) = first_hop_targets.get(&NodeId::from_pubkey(&our_node_pubkey)) {
for (key ,value) in &first_hop_targets {
if (key == &NodeId::from_pubkey(&our_node_pubkey)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You're still comparing a first_hop_targets key to our_node_id which will never succeed, thus all of this is dead code. You need to use something else here.

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.

Nice! Glad you got test coverage working.

@@ -1296,6 +1296,25 @@ where L::Target: Logger {
// around again with a higher amount.
if !contributes_sufficient_value || exceeds_max_path_length ||
exceeds_cltv_delta_limit || payment_failed_on_this_channel {

let mut is_first_hop = true;
for (key , _channel) in &first_hop_targets {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need to loop here, you can just do first_hop_targets.get(&$dest_node_id) with an if let Some... or match. That should also let you drop the is_first_hop variable.

if key == &$dest_node_id {
if is_first_hop && !contributes_sufficient_value {
log_trace!(logger, "First Hop {} is excluded due to insufficient value", short_channel_id);

Copy link
Collaborator

Choose a reason for hiding this comment

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

You can drop the blank lines here, and note that some lines have whitespace at the end, which would be nice to remove. Finally, note that some lines are indented by spaces followed by tabs, which should be replaced by all tabs. All of these issues will be highlighted by doing git show or git diff-tree -U3 locally, depending on your terminal config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks

log_trace!(logger, "First Hop {} is excluded beacause it was failed previously" , short_channel_id);
}
is_first_hop = false;
} // commit
Copy link
Collaborator

Choose a reason for hiding this comment

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

What does // commit mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, it means nothing. I write // commit in the line where I update the code.

// Retrieve the log message from TestLogger
let lines = logger.lines.lock().unwrap();
let mut log_output = String::new();
for ((module, file), line) in &*lines {
Copy link
Collaborator

@TheBlueMatt TheBlueMatt Mar 20, 2023

Choose a reason for hiding this comment

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

You don't have to iterate over the lines here, you can just do logger.assert_log_contains("routing:;router", "First Hop 3 is excluded due to insufficient value", 1);

@Sharmalm
Copy link
Contributor Author

Sharmalm commented Mar 21, 2023

Nice! Glad you got test coverage working.

Hey , But this test has been failing.

@TheBlueMatt
Copy link
Collaborator

Hey , But this test has been failing.

Ah, I didn't try to run it. So if you want to get some first-hops rejected, you should probably at least have Some first_hops at all - your current get_route call passes a None for first_hops, so your code definitely wont run :). Try adding a first hop that fails to be used that connects from a random public key (which you use as the sender) to somewhere in the network graph being used.

@Sharmalm
Copy link
Contributor Author

Hey , But this test has been failing.

Ah, I didn't try to run it. So if you want to get some first-hops rejected, you should probably at least have Some first_hops at all - your current get_route call passes a None for first_hops, so your code definitely wont run :). Try adding a first hop that fails to be used that connects from a random public key (which you use as the sender) to somewhere in the network graph being used.

It means I have to make a first_hops that can't route the payment in the test function ,and then test it right?

@TheBlueMatt
Copy link
Collaborator

Right, your new logging is all about first_hops, so you definitely need to have some to hit the new code :)

@TheBlueMatt
Copy link
Collaborator

Any desire to pick this back up?

@Sharmalm
Copy link
Contributor Author

apologies for break on my PR , i have been busy in university exam and internship. I will resume working on it in some time :)

@tnull
Copy link
Contributor

tnull commented Jul 24, 2023

Closing this as it has been superseded by #2436.

@tnull tnull closed this Jul 24, 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.

4 participants