-
Notifications
You must be signed in to change notification settings - Fork 366
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
Three-hop blinded paths #2793
base: main
Are you sure you want to change the base?
Three-hop blinded paths #2793
Conversation
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #2793 +/- ##
==========================================
- Coverage 89.84% 89.06% -0.78%
==========================================
Files 119 116 -3
Lines 97551 93294 -4257
Branches 97551 93294 -4257
==========================================
- Hits 87644 83092 -4552
- Misses 7332 7657 +325
+ Partials 2575 2545 -30 ☔ View full report in Codecov by Sentry. |
Needs rebase now that #2781 landed. |
78ddb01
to
6302480
Compare
Also need to sort the payment paths by some criteria. Earlier I figured we could use the |
6302480
to
ed86950
Compare
@coderabbitai review |
WalkthroughThe changes across the Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
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.
Review Status
Actionable comments generated: 46
Configuration used: CodeRabbit UI
Files selected for processing (20)
- lightning/src/blinded_path/payment.rs (2 hunks)
- lightning/src/ln/channelmanager.rs (5 hunks)
- lightning/src/ln/features.rs (1 hunks)
- lightning/src/ln/functional_test_utils.rs (11 hunks)
- lightning/src/ln/functional_tests.rs (1 hunks)
- lightning/src/ln/mod.rs (1 hunks)
- lightning/src/ln/offers_tests.rs (1 hunks)
- lightning/src/ln/outbound_payment.rs (11 hunks)
- lightning/src/ln/payment_tests.rs (2 hunks)
- lightning/src/ln/peer_handler.rs (2 hunks)
- lightning/src/offers/offer.rs (1 hunks)
- lightning/src/offers/refund.rs (1 hunks)
- lightning/src/onion_message/messenger.rs (9 hunks)
- lightning/src/routing/gossip.rs (2 hunks)
- lightning/src/routing/router.rs (9 hunks)
- lightning/src/routing/scoring.rs (1 hunks)
- lightning/src/sign/mod.rs (9 hunks)
- lightning/src/util/indexed_map.rs (1 hunks)
- lightning/src/util/test_utils.rs (5 hunks)
- lightning/src/util/time.rs (3 hunks)
Files skipped from review due to trivial changes (1)
- lightning/src/ln/peer_handler.rs
Additional comments: 95
lightning/src/ln/mod.rs (1)
- 82-84: The addition of the
offers_tests
module gated with#[cfg(test)]
is appropriate for including test-specific code. This ensures that the module is only compiled and included in test builds, which is a common and recommended practice.lightning/src/util/time.rs (1)
- 59-73: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [62-96]
The changes to conditionally compile the
MonotonicTime
struct,SHIFT
constant,Time
trait implementation forMonotonicTime
, and the test functionmonotonic_time_subtracts
under the "std" feature are correct. This aligns with the shift from a no-std to std environment and is a standard practice for feature-based conditional compilation.lightning/src/util/indexed_map.rs (1)
- 61-65: The addition of the
get_key_value
method to theIndexedMap
struct is a useful enhancement. It provides a standard way to retrieve both the key and value from the map, which can be particularly useful in scenarios where both are needed and avoids separate lookups.lightning/src/blinded_path/payment.rs (1)
- 110-119: The implementation of
From<DirectedChannelInfo<'a>> for PaymentRelay
is a logical addition, providing a clear conversion from channel information to payment relay parameters. This facilitates the construction of payment relays, which is an essential part of handling payments in the network.lightning/src/ln/offers_tests.rs (16)
44-55: The imports and macro definitions seem appropriate for the test module. No issues found here.
70-98: The
connect_peers
anddisconnect_peers
functions are utility functions used to manage peer connections within the tests. They appear to be correctly implemented, ensuring that both sides of the peer connection are established or disconnected.100-117: The
route_bolt12_payment
function is responsible for routing a BOLT 12 payment through a given path. It correctly monitors for added events and asserts the expected number of message events. The payment routing logic is encapsulated within thedo_pass_along_path
function, which is not shown here but assumed to be correct.119-128: The
claim_bolt12_payment
function is responsible for claiming a BOLT 12 payment. It correctly matches the expectedPaymentClaimable
event and callsclaim_payment
. The test assumes that theclaim_payment
function works as expected.131-145: The
extract_invoice_request
,extract_invoice
, andextract_invoice_error
functions are responsible for extracting different types of messages from anOnionMessage
. They correctly handle the peeled onion message and match against the expected message contents. The use of panics in the error handling is typical for test code where a failure to meet the expected conditions should stop the test immediately.180-267: The test
creates_and_pays_for_offer_using_two_hop_blinded_path
checks the payment flow for an offer using a two-hop blinded path. The test setup includes creating channels and disconnecting certain peers to ensure the correct network topology. The test then proceeds through the steps of creating an offer, paying for it, and claiming the payment. The assertions check that the correct events are generated and that the payment details are as expected. The test is well-structured and covers the intended functionality.269-346: The test
creates_and_pays_for_refund_using_two_hop_blinded_path
is similar to the previous test but for a refund. It follows the same pattern of setting up the network, creating a refund, and then routing and claiming the payment. The assertions are in place to ensure the correct behavior.349-403: The test
creates_and_pays_for_offer_using_one_hop_blinded_path
checks the payment flow for an offer using a one-hop blinded path. The test setup is simpler due to the smaller network topology. The test follows the same pattern of creating an offer, paying for it, and claiming the payment. The assertions validate the correct behavior and the use of ephemeral pubkeys.406-457: The test
creates_and_pays_for_refund_using_one_hop_blinded_path
is the refund counterpart to the previous test, with a one-hop blinded path. It follows the same structure and checks for the correct behavior with assertions.460-501: The test
pays_for_offer_without_blinded_paths
checks the behavior when paying for an offer that does not include any blinded paths. The test ensures that the payment can still be made using blinded paths as required by the spec. The assertions check that the payment is processed correctly.503-542: The test
pays_for_refund_without_blinded_paths
is similar to the previous test but for a refund. It ensures that the payment can be made without blinded paths in the refund, but still uses blinded paths for the payment itself, as per the spec.545-582: The test
fails_creating_offer_without_blinded_paths
checks that an error is returned when trying to create an offer without blinded paths, which is necessary to avoid exposing the node's id. The test correctly expects aBolt12SemanticError::MissingPaths
error.561-617: The test
fails_creating_invoice_request_without_blinded_reply_path
and the subsequent testsfails_creating_refund_without_blinded_paths
,fails_creating_invoice_request_with_duplicate_payment_id
, andfails_creating_refund_with_duplicate_payment_id
all check for error conditions when creating offers, refunds, and invoice requests. They correctly expect specific errors and assert that no recent payments are listed after the failed operations.688-751: The test
fails_sending_invoice_without_blinded_payment_paths_for_offer
checks that an error is returned when trying to send an invoice for an offer without blinded payment paths. The test setup includes disabling route blinding to simulate the error condition. The test correctly expects anInvoiceError
with aBolt12SemanticError::MissingPaths
.754-798: The test
fails_sending_invoice_without_blinded_payment_paths_for_refund
is similar to the previous test but for a refund. It also correctly expects an error when route blinding is disabled.802-892: The test
fails_paying_invoice_more_than_once
checks that an invoice cannot be paid more than once. The test setup includes creating a refund and sending two invoices for it. The test correctly expects that the second invoice will result in an error, which is simulated by sending anInvoiceError
with a "DuplicateInvoice" message.lightning/src/onion_message/messenger.rs (10)
746-749: The
set_offers_handler
function has been added to allow setting a new offers handler. This function is marked with#[cfg(test)]
, indicating it's only available for testing purposes, which is appropriate if it's intended for use in test scenarios only.128-141: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [122-138]
The example usage in the comments is very helpful for understanding how to use the
OnionMessenger
. However, it's important to ensure that the example code is kept up-to-date with the actual API to prevent confusion.
851-858: The
peel_onion_message
function is marked aspub(crate)
, which restricts its visibility to the current crate. This is good for encapsulation, but ensure that this visibility is intended and that the function does not need to be part of the public API.941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]
The
handle_onion_message
function logs at different levels (trace
,error
) based on the outcome of thepeel_onion_message
call. Ensure that the logging levels are consistent with the severity of the events being logged.Verification successful
Based on the output from the
rg
command, it is evident that the codebase uses a variety of logging levels (trace
,debug
,info
,warn
,error
) in different contexts. The use oftrace
for detailed and less critical information anderror
for serious issues is consistent with common logging practices.In the specific context of the
handle_onion_message
function, the use of different logging levels based on the outcome of thepeel_onion_message
call is likely appropriate. Thetrace
level is used for less severe events that are useful for detailed debugging, while theerror
level is reserved for significant issues that may require immediate attention.Therefore, the logging levels in the
handle_onion_message
function appear to be consistent with the severity of the events being logged, and the review comment does not seem to highlight an inconsistency with the project's logging practices.* 941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the logging levels used throughout the codebase are consistent with the severity of the events. rg --type rust 'log_(trace|debug|info|warn|error)!'Length of output: 83426
The
handle_onion_message
function does not return any value, but it performs critical operations such as forwarding onion messages or handling received messages. Ensure that any necessary actions are taken based on the outcome of these operations, such as retrying message forwarding or alerting the user in case of errors.
- 941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]
The
handle_onion_message
function uses a#[cfg(fuzzing)]
attribute, which is a conditional compilation flag for fuzz testing. Ensure that this flag is being used consistently across the codebase and that the fuzzing configuration is properly set up in the build system.Verification successful
The search results indicate that there are specific
Cargo.toml
files and shell scripts within thefuzz
directories that reference fuzzing configurations and dependencies, such ashonggfuzz
. The presence of these configurations inCargo.toml
files and the use of fuzzing-related commands inci-fuzz.sh
scripts suggest that the fuzzing configuration is indeed properly set up in the build system.Additionally, the
check-compiles.sh
script includes a command that sets thefuzzing
configuration flag when runningcargo check
, which further supports the proper setup for fuzz testing.Based on this information, it can be concluded that the
#[cfg(fuzzing)]
attribute is used consistently across the codebase and the fuzzing configuration is properly set up in the build system.* 941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the fuzzing configuration is properly set up and used consistently. rg --type rust '#\[cfg\(fuzzing\)\]'Length of output: 818
Script:
#!/bin/bash # Check for the presence of fuzzing configuration in Cargo.toml or other build scripts. rg --type toml --type sh 'fuzz'Length of output: 2305
The
handle_onion_message
function uses a lock onself.message_recipients
multiple times within the same scope. This could potentially lead to deadlocks if not handled carefully. Review the locking strategy to ensure that it is safe and efficient.Verification successful
Based on the analysis of the
messenger.rs
file, the locking strategy formessage_recipients
appears to be safe in the context of thehandle_onion_message
function. The lock is acquired once at the beginning of the function and is held until the function returns, with no nested locks or reentrant calls that could lead to deadlocks. While the use ofunwrap()
on lock acquisition could cause a panic if the lock is poisoned, this is a separate issue from deadlocks. The code uses theMutex
in a typical and straightforward manner to protect shared data.* 941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the locking strategy on self.message_recipients is safe and does not lead to deadlocks. rg --type rust 'message_recipients.lock()'Length of output: 1104
Script:
#!/bin/bash # Examine the context of each lock acquisition to understand the locking strategy better. # We will look at the surrounding code for each instance where `message_recipients.lock().unwrap()` is called. rg --type rust -C 10 'message_recipients.lock().unwrap()' lightning/src/onion_message/messenger.rsLength of output: 100
Script:
#!/bin/bash # Attempting a different approach to examine the code surrounding the lock acquisitions. # We will use the `cat` command to output the entire file and then manually locate the relevant sections. cat lightning/src/onion_message/messenger.rsLength of output: 46230
The
handle_onion_message
function has a section of code under the#[cfg(fuzzing)]
attribute. Ensure that this code is only for fuzz testing and that it does not affect the production code path.
- 941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]
The
handle_onion_message
function useslog_trace!
andlog_error!
macros for logging. Ensure that these macros are defined and used consistently throughout the codebase.Verification successful
The
log_trace!
andlog_error!
macros are used consistently throughout therust-lightning
project, as evidenced by the numerous instances across various files. This indicates that these macros are part of a common logging framework or utility used project-wide.* 941-947: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [944-1004]Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the logging macros are defined and used consistently. rg --type rust 'log_(trace|error)!'Length of output: 49369
The
handle_onion_message
function's error handling logs at different levels based on the error. Ensure that the severity of the log messages matches the severity of the errors.Verification successful
The log messages within the
handle_onion_message
function inmessenger.rs
use appropriate severity levels. Thelog_error!
macro is used for actual error conditions, whilelog_trace!
is used for informational messages that are not errors but may be relevant for detailed operational logging. The severity of the log messages matches the severity of the events they log.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the severity of log messages matches the severity of the errors. rg --type rust 'log_(trace|error)!'Length of output: 49369
lightning/src/offers/refund.rs (1)
- 300-303: The method
clear_paths
has been added to theRefundBuilder
struct. This method resets thepaths
field toNone
, effectively clearing any blinded paths that have been added. This is a useful addition for cases where the paths need to be reset during the building process.lightning/src/ln/features.rs (2)
- 923-928: The implementation of
clear_route_blinding
for types that satisfy theRouteBlinding
trait seems to be correct. However, the use of#[cfg(test)]
suggests that this function is only available for testing purposes. Ensure that this is the intended use case and that the function is not required in the non-test codebase.Verification successful
The
offers_tests
module is indeed gated by the#[cfg(test)]
attribute, indicating that it is part of the test suite. Therefore, the use ofclear_route_blinding
withinoffers_tests.rs
is consistent with its intended use case for testing purposes only, as denoted by the#[cfg(test)]
attribute in thefeatures.rs
file.* 929-929: The `unknown` function is added for types satisfying the `UnknownFeature` trait. This function is not shown in its entirety, but it appears to be a constructor for creating a `Features` instance with unknown features. It's important to ensure that this function is used correctly throughout the codebase and that it does not introduce any unexpected behavior, especially since it is not gated by `#[cfg(test)]`.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the `clear_route_blinding` function is not used outside of tests. rg --type rust --glob '!*_test.rs' 'clear_route_blinding'Length of output: 269
Script:
#!/bin/bash # Check if `offers_tests.rs` is included in a test configuration. rg --type rust 'mod offers_tests;' -- 'lightning/src/ln/mod.rs'Length of output: 81
Script:
#!/bin/bash # Check for the presence of a cfg(test) attribute above the offers_tests module declaration. rg --type rust -C 3 'mod offers_tests;' -- 'lightning/src/ln/mod.rs'Length of output: 200
Verification successful
The
Features::unknown
function is used within test cases in therefund.rs
,offer.rs
, andinvoice_request.rs
files to simulate scenarios with unknown features and to ensure that the system behaves correctly when encountering them. The usage is appropriate for the test contexts, and there is no indication ofFeatures::unknown
being used in non-test code or introducing unexpected behavior. The review comment's concern is addressed by the current usage pattern of the function.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the `unknown` function is used correctly. rg --type rust 'Features::unknown'Length of output: 1374
Script:
#!/bin/bash # Examine the context of usage of `Features::unknown` in `refund.rs` rg --type rust --context 5 'Features::unknown' lightning/src/offers/refund.rs # Examine the context of usage of `Features::unknown` in `offer.rs` rg --type rust --context 5 'Features::unknown' lightning/src/offers/offer.rs # Examine the context of usage of `Features::unknown` in `invoice_request.rs` rg --type rust --context 5 'Features::unknown' lightning/src/offers/invoice_request.rsLength of output: 4328
lightning/src/util/test_utils.rs (10)
35-38: The imports for
DefaultMessageRouter
andDefaultRouter
have been added. This change aligns with the PR's objective to enhance routing functionality with new types.107-113: The
TestRouter
struct now includes arouter
field of typeDefaultRouter
. This change seems to be part of the refactoring to use the newDefaultRouter
type. Ensure that all instances ofTestRouter
are updated to handle the new field correctly.Verification successful
The
TestRouter
struct'snew
method has been verified, and it initializes therouter
field with the necessary parameters. The calls toTestRouter::new
across various files in the codebase are consistent with this updated method signature, passing thenetwork_graph
,logger
, andscorer
as arguments. Therefore, the instances ofTestRouter
have been correctly updated to handle the newrouter
field.* 204-204: The `find_route` method in `TestRouter` now delegates to the `router` field's `find_route` method. This change is consistent with the refactoring to use `DefaultRouter`.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that all instances of TestRouter are updated to handle the new router field. rg --type rust "TestRouter::new"Length of output: 1403
Script:
#!/bin/bash # View the implementation of the TestRouter::new method to verify the initialization of the router field. rg --type rust -A 10 "impl TestRouter" lightning/src/util/test_utils.rsLength of output: 73
Script:
#!/bin/bash # Broaden the search to find the TestRouter struct and associated methods in the test_utils.rs file. rg --type rust "struct TestRouter" -A 30 lightning/src/util/test_utils.rsLength of output: 965
- 210-215: The
create_blinded_payment_paths
method inTestRouter
delegates to therouter
field's corresponding method. This is part of the refactoring and should be checked to ensure that the delegation is correctly implemented.Verification successful
The output from the
rg
command provides the information needed to verify the implementation of thecreate_blinded_payment_paths
method inTestRouter
and the type of therouter
field withinTestRouter
.From the output, we can see that
TestRouter
contains a field namedrouter
which is of typeDefaultRouter
. TheDefaultRouter
is parameterized with several types, includingArc<NetworkGraph<&'a TestLogger>>
,'a TestLogger
,'a RwLock<TestScorer>
, and()
.This confirms that the
router
field inTestRouter
is indeed of typeDefaultRouter
, and the previous context provided shows that thecreate_blinded_payment_paths
method inTestRouter
delegates to therouter
field's corresponding method.Based on the information gathered, the delegation in
create_blinded_payment_paths
withinTestRouter
is correctly implemented, as it correctly references therouter
field of typeDefaultRouter
.* 221-223: The `find_path` method in `TestRouter` now delegates to the `router` field's `find_path` method. This change is consistent with the refactoring to use `DefaultRouter`.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the delegation in create_blinded_payment_paths is correctly implemented. rg --type rust "create_blinded_payment_paths"Length of output: 897
Script:
#!/bin/bash # Verify the signature of the create_blinded_payment_paths method in DefaultRouter ast-grep --lang rust --pattern $'impl DefaultRouter { pub fn create_blinded_payment_paths<$$_>($$$) -> $_ { $$$ } }' # Verify that the router field in TestRouter is of type DefaultRouter ast-grep --lang rust --pattern $'struct TestRouter { router: DefaultRouter, $$$ }'Length of output: 213
Script:
#!/bin/bash # Adjusting the pattern to match the method signature in a more general way ast-grep --lang rust --pattern $'impl $_ { pub fn create_blinded_payment_paths<$$_>($$$) -> $_ { $$$ } }' # Adjusting the pattern to match the TestRouter struct in a more general way ast-grep --lang rust --pattern $'struct TestRouter { $$$ }'Length of output: 177
Script:
#!/bin/bash # Use ripgrep to find the TestRouter struct definition rg --type rust --context 5 "struct TestRouter" lightning/src/util/test_utils.rs # Use ripgrep to find the implementation of the create_blinded_payment_paths method within DefaultRouter context rg --type rust --context 5 "impl DefaultRouter" lightning/src/routing/router.rsLength of output: 437
- 229-232: The
create_blinded_paths
method inTestRouter
delegates to therouter
field's corresponding method. This is part of the refactoring and should be checked to ensure that the delegation is correctly implemented.Verification successful
To verify the correct implementation of the delegation in the
create_blinded_paths
method within theTestRouter
struct, we need to examine the method signatures in both theTestRouter
and theDefaultRouter
(or the type of therouter
field) to ensure they align and that the parameters are passed correctly.
The output from the scripts shows that the
create_blinded_paths
method signature inTestRouter
matches the signature inDefaultRouter
. Both methods take the same parameters: a recipient of typePublicKey
, a vector of peers of typeVec<PublicKey>
, an entropy source that implements theEntropySource
trait, and aSecp256k1
context. They both return aResult
with a vector ofBlindedPath
or an error of unit type()
.Given that the signatures match and the delegation in
TestRouter
passes the parameters directly to therouter
field'screate_blinded_paths
method, we can conclude that the delegation is correctly implemented.* 247-254: The `TestMessageRouter` struct has been added with an `inner` field of type `DefaultMessageRouter`. This addition is consistent with the PR's objective to enhance message routing functionality.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the delegation in create_blinded_paths is correctly implemented. rg --type rust "create_blinded_paths"Length of output: 1563
Script:
#!/bin/bash # Check the method signature of create_blinded_paths in TestRouter and DefaultRouter rg --type rust -A 5 "fn create_blinded_paths<" lightning/src/util/test_utils.rs rg --type rust -A 5 "fn create_blinded_paths<" lightning/src/routing/router.rsLength of output: 903
258-262: The
find_path
method inTestMessageRouter
delegates to theinner
field'sfind_path
method. This change is consistent with the introduction of theDefaultMessageRouter
.265-271: The
create_blinded_paths
method inTestMessageRouter
delegates to theinner
field's corresponding method. This is part of the refactoring and should be checked to ensure that the delegation is correctly implemented.Verification successful
The review of the
create_blinded_paths
method in bothTestRouter
andTestMessageRouter
withinlightning/src/util/test_utils.rs
confirms that the delegation to therouter
andinner
fields, respectively, is correctly implemented according to Rust's syntax and conventions. The method signatures match, and the delegation pattern is consistent with typical Rust practices.* 1434-1436: The `TestScorer` struct now implements the `Score` trait for the `c_bindings` configuration. This change should be verified to ensure that it aligns with the intended use of `TestScorer` in different build configurations.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the delegation in create_blinded_paths is correctly implemented. rg --type rust "create_blinded_paths"Length of output: 1563
Script:
#!/bin/bash # Verify the context of the delegation in create_blinded_paths within TestMessageRouter and TestRouter rg --type rust -C 10 "create_blinded_paths" lightning/src/util/test_utils.rsLength of output: 1550
lightning/src/offers/offer.rs (1)
- 342-345: The
clear_paths
method has been added to allow clearing the paths in the offer. The method is correctly usingpub(crate)
visibility, which restricts its use within the crate, a good practice for encapsulation. The method takesself
by mutable reference and returnsSelf
, allowing for method chaining. The implementation is straightforward and there are no apparent issues with logic, syntax, or performance.However, ensure that the
Offer
struct's invariants are maintained after paths are cleared, and consider if any additional actions should be taken when paths are cleared (e.g., updating related state or notifying other components).pub(crate) fn clear_paths(mut self) -> Self { self.offer.paths = None; self }lightning/src/sign/mod.rs (9)
825-826: The
InMemorySigner
struct now includes anentropy_source
field of typeRandomBytes
. This change centralizes entropy generation, which is a good practice for cryptographic applications. Ensure that all instances ofInMemorySigner
are updated to initialize this new field correctly.857-857: The
clone
method forInMemorySigner
has been updated to use the newentropy_source
field. It's important to ensure that theget_secure_random_bytes
method used here provides a fresh, secure source of entropy for each clone to prevent any cryptographic weaknesses.Verification successful
Based on the provided output, the
get_secure_random_bytes
method in theRandomBytes
struct withinlightning/src/sign/mod.rs
uses the ChaCha20 algorithm and an atomic counter to ensure that each call generates a unique and secure 32-byte value. This satisfies the requirement for providing a fresh source of entropy for each clone ofInMemorySigner
.* 891-891: The `new` method for `InMemorySigner` has been modified to initialize the `entropy_source` with a given `rand_bytes_unique_start`. It's crucial to verify that the `rand_bytes_unique_start` is securely generated and unique for each signer to maintain cryptographic security.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that get_secure_random_bytes generates unique, secure random bytes for each clone. rg --type rust "fn get_secure_random_bytes" --context 5Length of output: 8749
1067-1067: The
get_secure_random_bytes
method in theEntropySource
implementation forInMemorySigner
now delegates to theentropy_source
. This is a good encapsulation of functionality. However, it's important to review theRandomBytes::get_secure_random_bytes
method to ensure it meets the security requirements.1345-1345: The
InMemorySigner
is being initialized with anentropy_source
using bytes from anotherEntropySource
. This is a potential security risk if theEntropySource
passed in does not provide secure random bytes. It's important to ensure that the source of entropy is secure and that this pattern does not introduce any vulnerabilities.Verification successful
The
EntropySource
trait is implemented across various modules in the codebase, ensuring the generation of secure random bytes for cryptographic operations. TheRandomBytes
struct, which implementsEntropySource
, utilizes the ChaCha20 algorithm, a secure method for random number generation.Regarding the review comment, initializing an
InMemorySigner
with anentropy_source
derived from anotherEntropySource
is a pattern that relies on the security of the initial source. If the initialEntropySource
is secure, this pattern should not introduce vulnerabilities. The use of ChaCha20 in theRandomBytes
implementation suggests that the entropy source is likely secure.* 1373-1373: The `KeysManager` struct now includes an `entropy_source` field. This change is consistent with the updates to `InMemorySigner` and is a good practice for managing entropy in cryptographic systems. Ensure that all instances of `KeysManager` are updated to initialize this new field correctly.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the EntropySource passed to InMemorySigner provides secure random bytes. rg --type rust "EntropySource" --context 5Length of output: 132911
- 1442-1442: The
new
method forKeysManager
has been updated to initialize theentropy_source
withrand_bytes_unique_start
. Similar toInMemorySigner
, it's important to verify that therand_bytes_unique_start
is securely generated and unique for eachKeysManager
instance.Verification successful
The review comment is concerned with the secure generation and uniqueness of
rand_bytes_unique_start
for eachKeysManager
instance. The script output shows thatrand_bytes_unique_start
is generated using a SHA256 hash function, which includes the current time in seconds and nanoseconds, a seed, and a constant string "LDK PRNG Seed" as inputs. This approach is typically sufficient to ensure thatrand_bytes_unique_start
is both secure and unique per instance.* 1623-1623: The `get_secure_random_bytes` method in the `EntropySource` implementation for `KeysManager` now delegates to the `entropy_source`. This change is consistent with the encapsulation of entropy generation in `InMemorySigner` and should be reviewed to ensure it meets security requirements.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that rand_bytes_unique_start is securely generated and unique for each KeysManager instance. rg --type rust "rand_bytes_unique_start" --context 5Length of output: 2547
- 1877-1904: The new
RandomBytes
struct and its implementation of theEntropySource
trait using the ChaCha20 algorithm is a significant change. It's important to ensure that the ChaCha20 algorithm is correctly implemented and that theindex
is used securely to prevent any reuse of the nonce, which could lead to cryptographic vulnerabilities.lightning/src/ln/outbound_payment.rs (11)
26-26: The change to the
cfg
attribute here is consistent with the PR's objective to adjust conditional compilation for standard library features. This looks good.285-299: The modifications to the
cfg
attributes and theimpl_writeable_tlv_based_enum!
macro usage are aligned with the changes to the feature flags. Ensure that theRetry
enum is tested with both configurations (std
andnot(std)
).312-315: The conditional compilation here is correctly updated to reflect the new feature flags. However, ensure that the time comparison logic is consistent and correct in both the
std
andtest
configurations.Verification successful
To verify the consistency and correctness of the time comparison logic under both
std
andtest
configurations inlightning/src/ln/outbound_payment.rs
, we need to examine the actual usage ofduration_since
within the conditional compilation blocks. The output from the script indicates that there are relevant blocks to review. Let's proceed with examining the code surrounding these blocks.
The review comment concerning the consistency and correctness of the time comparison logic in both
std
andtest
configurations inlightning/src/ln/outbound_payment.rs
has been addressed. The logic is consistent across both configurations, using theduration_since
method. The difference in the time source (MonotonicTime
for standard andSinceEpoch
for test configurations) is intentional and a common practice to facilitate testing. The conditional compilation attributes are correctly updated to reflect the new feature flags.* 341-371: The changes to the `PaymentAttemptsUsingTime` struct and its associated `Display` implementation are consistent with the conditional compilation updates. Ensure that the `Display` implementation is tested for both `std` and `not(std)` configurations.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the time comparison logic is consistent and correct in both configurations rg --type rust "duration_since" --files-with-matches | xargs rg --type rust "#\[cfg\(all\(feature = \"std\", (not\(test\)|test)\)\)\]"Length of output: 671
Script:
#!/bin/bash # Examine the usage of `duration_since` within the conditional compilation blocks in `outbound_payment.rs` rg --type rust -C 5 "#\[cfg\(all\(feature = \"std\", not\(test\)\)\)\]" lightning/src/ln/outbound_payment.rs rg --type rust -C 5 "#\[cfg\(all\(feature = \"std\", test\)\)\]" lightning/src/ln/outbound_payment.rsLength of output: 2374
1879-1879: This hunk shows test setup code. There are no changes to the code itself, only the context in which it is shown. No action is required.
1923-1923: Similar to the previous hunk, this is test setup code without any changes. No action is required.
1962-1962: Again, this hunk shows test setup code without any changes. No action is required.
2169-2169: This hunk is also showing test setup code without any changes. No action is required.
2220-2220: This hunk is showing test setup code without any changes. No action is required.
2279-2279: This hunk is showing test setup code without any changes. No action is required.
2338-2338: This hunk is showing test setup code without any changes. No action is required.
lightning/src/routing/gossip.rs (2)
1029-1029: The access level of the
direction
function has been changed frompub(super)
topub(crate)
. This widens the visibility of the function within the crate, which could be intended for increased internal reusability. Ensure that this change aligns with the intended encapsulation and usage within the crate.1848-1848: The conditional compilation directive has been changed from
#[cfg(feature = "no-std")]
to#[cfg(not(feature = "std"))]
. This change seems to be a correction to ensure that the code is included when thestd
feature is not enabled, which is more idiomatic for Rust crates that support bothstd
andno-std
environments. Confirm that this change aligns with the project's feature management strategy.lightning/src/ln/functional_test_utils.rs (12)
22-31: The imports have been reorganized and new ones added. This is a common practice to maintain code cleanliness and ensure that all necessary modules are available for use. The added imports are related to message handling and entropy generation, which align with the new features being implemented.
48-52: Additional imports from the standard library have been added. These are foundational utilities that are often used in Rust for memory management and synchronization. Their addition suggests that the new code will involve reference counting and locking mechanisms.
394-394: A new field
message_router
of typetest_utils::TestMessageRouter
has been added to theNodeCfg
struct. This change is likely related to the new onion messaging functionality and is necessary for routing messages during tests.414-421: A new type alias
TestOnionMessenger
has been defined, which is a specialized version ofOnionMessenger
for testing purposes. It usesDedicatedEntropy
for entropy generation, which is defined later in the code. This is a good example of using type aliases to simplify complex type signatures.423-432: The
DedicatedEntropy
struct is introduced to provide a specific entropy source for theOnionMessenger
. It wraps theRandomBytes
struct, providing a dereference to the inner type. This encapsulation ensures that the entropy source can be controlled during testing.442-442: The
Node
struct has been updated with a new fieldonion_messenger
of typeTestOnionMessenger
. This addition is consistent with the new functionality for onion messaging within the test utilities.462-465: A new method
init_features
has been added to theNode
struct. This method combines the features provided by the node and the onion messenger, which is a logical step to ensure that all features are initialized correctly when establishing peer connections.635-635: The
router
field is being initialized with aTestRouter
. This is part of the setup for a node configuration and is necessary for testing the routing functionality.1090-1090: The
onion_messenger
is being set with an offers handler using theset_offers_handler
method. This is part of the node reloading process and is necessary to ensure that the onion messenger is correctly configured with the new channel manager.2915-2916: The
message_router
field is being initialized with aTestMessageRouter
. This is part of the node configuration setup and is necessary for testing the message routing functionality.2970-2982: The
onion_messenger
is being initialized with a newOnionMessenger
instance usingDedicatedEntropy
. This is part of the node setup and is necessary for testing the onion messaging functionality. TheIgnoringMessageHandler
is used, which is appropriate for tests where message handling is not the focus.2997-3014: The code here is handling the peer connection initialization between nodes. It uses the
init_features
method to get the features for each node and then callspeer_connected
on both thenode
andonion_messenger
. This is a necessary step to simulate the peer connection process in a testing environment.lightning/src/routing/scoring.rs (1)
- 254-254: The conditional compilation directive added here ensures that the implementation of
LockableScore
forRwLock<T>
is only compiled when the_test_utils
feature or tests are being run. Please confirm that this feature flag is consistent with the project's conventions for test utilities and that it is being used elsewhere in the codebase as intended.Verification successful
The search results confirm that the feature flag
_test_utils
is used consistently throughout therust-lightning
project. It is applied in various files and contexts, often in conjunction with thetest
configuration, to conditionally compile code for testing purposes. The usage of this feature flag in thescoring.rs
file is in line with the project's conventions.Based on the information gathered, the conditional compilation directive in
scoring.rs
is correctly placed and the feature flag_test_utils
is appropriately used within the project's conventions.Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that the feature flag '_test_utils' is used consistently across the project rg --type rust 'cfg\(.*_test_utils.*\)'Length of output: 2636
lightning/src/ln/payment_tests.rs (2)
45-50: The import statements have been reorganized, and new imports for
std::time
andcrate::util::time::tests::SinceEpoch
have been added. Ensure that these new imports are used within the test module, otherwise, they should be removed to avoid unused imports.2318-2318: The addition of a conditional compilation block suggests that the enclosed code is only relevant when the
std
feature is enabled. Verify that thestd
feature is indeed required for theDuration::from_secs
method and that theRetry::Timeout
parameter is correctly implemented in thesend_payment
function.lightning/src/routing/router.rs (8)
93-94: The introduction of
recipient_node_id
is a good practice for clarity and maintainability. It's important to ensure that theNodeId
type andfrom_pubkey
method are correctly implemented and thatrecipient
is always a validPublicKey
.103-116: The chaining of
filter
andfilter_map
calls is a common pattern in Rust for data transformation. However, it's important to ensure that the logic within these calls is correct and that the conditions used for filtering are appropriate for the intended functionality. The use ofunwrap_or
withu64::MAX
and0
is a sensible default but should be reviewed to ensure it aligns with the domain logic.145-228: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [139-150]
The construction of
forward_node
and the subsequentSome((forward_node, counterparty_channels))
tuple is a key part of the new logic. It's crucial to verify that the fields ofForwardNode
are being populated correctly and that thecounterparty_channels
being paired with it are the intended ones.
205-224: The construction of
two_hop_paths
and the subsequent logic to determine the final paths to return is critical. It's important to ensure that thecollect
andand_then
calls are used correctly to handle the possible outcomes and that the fallback toone_hop_for_payment
is appropriate. The use ofok_or(())
should be reviewed to ensure that it's the best way to handle errors in this context.6957-6957: The
generate_routes
test function is usingProbabilisticScorer
andProbabilisticScoringFeeParameters
. It's important to ensure that the test covers the new logic introduced in this PR and that the scoring parameters are set up correctly for the test scenarios.6978-6978: Similar to the previous comment, the
generate_routes_mpp
test function should be reviewed to ensure that it adequately tests the multi-path payment (MPP) logic with the new changes.6999-6999: The
generate_large_mpp_routes
test function should be reviewed to ensure that it is testing the generation of large MPP routes correctly and that the test is robust enough to cover the new changes.8335-8335: The
bench_utils
module is being used for benchmarking and testing. It's important to ensure that the benchmarks are updated to reflect the new logic and that they are correctly measuring the performance of the relevant parts of the code.lightning/src/ln/functional_tests.rs (1)
- 5540-5542: The addition of
message_router
to therouter
declaration and the subsequent update to thenode
declaration seem to align with the PR's objectives of enhancing privacy through the implementation of blinded paths. Ensure that theTestMessageRouter
is properly initialized and that its interactions with other components are correctly defined and tested.lightning/src/ln/channelmanager.rs (5)
7759-7767: In the conditional compilation blocks, ensure that the
create_blinded_payment_paths
function is correctly handling thestd
feature flag. The use ofmap_err
to convert errors toBolt12SemanticError::MissingPaths
is appropriate, but it's important to verify that this error type is being handled correctly wherever this function is called.9212-9222: The handling of
created_at
usingself.highest_seen_timestamp
for non-std
environments is a good fallback. However, it's crucial to ensure that thehighest_seen_timestamp
is being updated correctly elsewhere in the code to avoid potential timing issues.9231-9233: The conditional compilation for
respond_with
andrespond_with_no_std
seems to be consistent with the previous patterns. It's important to check that therespond_with_no_std
function is implemented and handles thecreated_at
parameter correctly.12473-12473: The removal of imports in this hunk suggests that there might have been code cleanup or refactoring. Since the PR instructions indicate not to flag removal of imports, this change is noted but does not require action.
12513-12513: The addition of
test_utils::TestRouter
and the configuration ofmax_dust_htlc_exposure
in the test setup is a good practice to ensure that the tests reflect the changes in the configuration. It's important to ensure that the tests cover the new code paths introduced by the PR.
lightning/src/routing/router.rs
Outdated
let three_hop_paths = counterparty_channels.clone() | ||
// Pair counterparties with their other channels | ||
.flat_map(|(forward_node, counterparty_channels)| | ||
counterparty_channels | ||
.iter() | ||
.filter_map(|scid| network_graph.channels().get_key_value(scid)) | ||
.filter_map(move |(scid, info)| info | ||
.as_directed_to(&NodeId::from_pubkey(&forward_node.node_id)) | ||
.map(|(info, source)| (source, *scid, info)) | ||
) | ||
.filter(|(source, _, _)| **source != recipient_node_id) | ||
.filter(|(source, _, _)| network_graph | ||
.node(source) | ||
.and_then(|info| info.announcement_info.as_ref()) | ||
.map(|info| info.features.supports_route_blinding()) | ||
.unwrap_or(false) | ||
) | ||
.filter(|(_, _, info)| amount_msats >= info.direction().htlc_minimum_msat) | ||
.filter(|(_, _, info)| amount_msats <= info.direction().htlc_maximum_msat) | ||
.map(move |(source, scid, info)| (source, scid, info, forward_node.clone())) | ||
) | ||
// Construct blinded paths where the counterparty's counterparty is the introduction | ||
// node: | ||
// | ||
// source --- info ---> counterparty --- counterparty_forward_node ---> recipient | ||
.map(|(introduction_node_id, scid, info, counterparty_forward_node)| { | ||
let introduction_forward_node = { | ||
let htlc_minimum_msat = info.direction().htlc_minimum_msat; | ||
let htlc_maximum_msat = info.direction().htlc_maximum_msat; | ||
let payment_relay: PaymentRelay = info.into(); | ||
let payment_constraints = PaymentConstraints { | ||
max_cltv_expiry: payment_relay.cltv_expiry_delta as u32 | ||
+ counterparty_forward_node.tlvs.payment_constraints.max_cltv_expiry, | ||
htlc_minimum_msat, | ||
}; | ||
ForwardNode { | ||
tlvs: ForwardTlvs { | ||
short_channel_id: scid, | ||
payment_relay, | ||
payment_constraints, | ||
features: BlindedHopFeatures::empty(), | ||
}, | ||
node_id: introduction_node_id.as_pubkey().unwrap(), | ||
htlc_maximum_msat, | ||
} | ||
}; | ||
BlindedPath::new_for_payment( | ||
&[introduction_forward_node, counterparty_forward_node], recipient, | ||
tlvs.clone(), u64::MAX, entropy_source, secp_ctx | ||
) | ||
}) | ||
.map(|forward_node| { | ||
.take(MAX_PAYMENT_PATHS); | ||
|
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 logic for constructing three_hop_paths
is complex and involves multiple filtering and mapping operations. It's important to ensure that the logic correctly implements the intended path construction, especially the conditions in the filter
calls. The use of clone
on counterparty_channels
should be reviewed for potential performance implications, and it may be worth considering if there's a more efficient way to achieve the same result without cloning.
- let three_hop_paths = counterparty_channels.clone()
+ let three_hop_paths = counterparty_channels.iter()
Committable suggestion
❗ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
let three_hop_paths = counterparty_channels.clone() | |
// Pair counterparties with their other channels | |
.flat_map(|(forward_node, counterparty_channels)| | |
counterparty_channels | |
.iter() | |
.filter_map(|scid| network_graph.channels().get_key_value(scid)) | |
.filter_map(move |(scid, info)| info | |
.as_directed_to(&NodeId::from_pubkey(&forward_node.node_id)) | |
.map(|(info, source)| (source, *scid, info)) | |
) | |
.filter(|(source, _, _)| **source != recipient_node_id) | |
.filter(|(source, _, _)| network_graph | |
.node(source) | |
.and_then(|info| info.announcement_info.as_ref()) | |
.map(|info| info.features.supports_route_blinding()) | |
.unwrap_or(false) | |
) | |
.filter(|(_, _, info)| amount_msats >= info.direction().htlc_minimum_msat) | |
.filter(|(_, _, info)| amount_msats <= info.direction().htlc_maximum_msat) | |
.map(move |(source, scid, info)| (source, scid, info, forward_node.clone())) | |
) | |
// Construct blinded paths where the counterparty's counterparty is the introduction | |
// node: | |
// | |
// source --- info ---> counterparty --- counterparty_forward_node ---> recipient | |
.map(|(introduction_node_id, scid, info, counterparty_forward_node)| { | |
let introduction_forward_node = { | |
let htlc_minimum_msat = info.direction().htlc_minimum_msat; | |
let htlc_maximum_msat = info.direction().htlc_maximum_msat; | |
let payment_relay: PaymentRelay = info.into(); | |
let payment_constraints = PaymentConstraints { | |
max_cltv_expiry: payment_relay.cltv_expiry_delta as u32 | |
+ counterparty_forward_node.tlvs.payment_constraints.max_cltv_expiry, | |
htlc_minimum_msat, | |
}; | |
ForwardNode { | |
tlvs: ForwardTlvs { | |
short_channel_id: scid, | |
payment_relay, | |
payment_constraints, | |
features: BlindedHopFeatures::empty(), | |
}, | |
node_id: introduction_node_id.as_pubkey().unwrap(), | |
htlc_maximum_msat, | |
} | |
}; | |
BlindedPath::new_for_payment( | |
&[introduction_forward_node, counterparty_forward_node], recipient, | |
tlvs.clone(), u64::MAX, entropy_source, secp_ctx | |
) | |
}) | |
.map(|forward_node| { | |
.take(MAX_PAYMENT_PATHS); | |
let three_hop_paths = counterparty_channels.iter() | |
// Pair counterparties with their other channels | |
.flat_map(|(forward_node, counterparty_channels)| | |
counterparty_channels | |
.iter() | |
.filter_map(|scid| network_graph.channels().get_key_value(scid)) | |
.filter_map(move |(scid, info)| info | |
.as_directed_to(&NodeId::from_pubkey(&forward_node.node_id)) | |
.map(|(info, source)| (source, *scid, info)) | |
) | |
.filter(|(source, _, _)| **source != recipient_node_id) | |
.filter(|(source, _, _)| network_graph | |
.node(source) | |
.and_then(|info| info.announcement_info.as_ref()) | |
.map(|info| info.features.supports_route_blinding()) | |
.unwrap_or(false) | |
) | |
.filter(|(_, _, info)| amount_msats >= info.direction().htlc_minimum_msat) | |
.filter(|(_, _, info)| amount_msats <= info.direction().htlc_maximum_msat) | |
.map(move |(source, scid, info)| (source, scid, info, forward_node.clone())) | |
) | |
// Construct blinded paths where the counterparty's counterparty is the introduction | |
// node: | |
// | |
// source --- info ---> counterparty --- counterparty_forward_node ---> recipient | |
.map(|(introduction_node_id, scid, info, counterparty_forward_node)| { | |
let introduction_forward_node = { | |
let htlc_minimum_msat = info.direction().htlc_minimum_msat; | |
let htlc_maximum_msat = info.direction().htlc_maximum_msat; | |
let payment_relay: PaymentRelay = info.into(); | |
let payment_constraints = PaymentConstraints { | |
max_cltv_expiry: payment_relay.cltv_expiry_delta as u32 | |
+ counterparty_forward_node.tlvs.payment_constraints.max_cltv_expiry, | |
htlc_minimum_msat, | |
}; | |
ForwardNode { | |
tlvs: ForwardTlvs { | |
short_channel_id: scid, | |
payment_relay, | |
payment_constraints, | |
features: BlindedHopFeatures::empty(), | |
}, | |
node_id: introduction_node_id.as_pubkey().unwrap(), | |
htlc_maximum_msat, | |
} | |
}; | |
BlindedPath::new_for_payment( | |
&[introduction_forward_node, counterparty_forward_node], recipient, | |
tlvs.clone(), u64::MAX, entropy_source, secp_ctx | |
) | |
}) | |
.take(MAX_PAYMENT_PATHS); |
lightning/src/routing/router.rs
Outdated
@@ -6882,7 +6944,7 @@ mod tests { | |||
(route.paths[1].hops[1].short_channel_id == 4 && route.paths[0].hops[1].short_channel_id == 13)); | |||
} | |||
|
|||
#[cfg(not(feature = "no-std"))] | |||
#[cfg(feature = "std")] |
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 random_init_seed
function is using the default HashMap
hasher for randomness. This is noted as a "(bad) RNG" in the comment, which suggests that it may not be suitable for cryptographic purposes. It's important to ensure that this RNG is only used in contexts where cryptographic strength is not required.
lightning/src/util/test_utils.rs
Outdated
pub fn new( | ||
network_graph: Arc<NetworkGraph<&'a TestLogger>>, logger: &'a TestLogger, | ||
scorer: &'a RwLock<TestScorer> | ||
) -> Self { | ||
Self { | ||
router: DefaultRouter::new(network_graph.clone(), logger, [42u8; 32], scorer, ()), | ||
network_graph, | ||
next_routes: Mutex::new(VecDeque::new()), | ||
scorer, | ||
} |
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 new
method of TestRouter
has been updated to initialize the router
field with additional parameters, including a hardcoded entropy value [42u8; 32]
. This hardcoded value should be replaced with a parameter or a constant defined elsewhere to avoid magic numbers in the code.
- router: DefaultRouter::new(network_graph.clone(), logger, [42u8; 32], scorer, ()),
+ // Assuming `DEFAULT_ENTROPY` is defined as a constant elsewhere
+ router: DefaultRouter::new(network_graph.clone(), logger, DEFAULT_ENTROPY, scorer, ()),
Committable suggestion
❗ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
pub fn new( | |
network_graph: Arc<NetworkGraph<&'a TestLogger>>, logger: &'a TestLogger, | |
scorer: &'a RwLock<TestScorer> | |
) -> Self { | |
Self { | |
router: DefaultRouter::new(network_graph.clone(), logger, [42u8; 32], scorer, ()), | |
network_graph, | |
next_routes: Mutex::new(VecDeque::new()), | |
scorer, | |
} | |
pub fn new( | |
network_graph: Arc<NetworkGraph<&'a TestLogger>>, logger: &'a TestLogger, | |
scorer: &'a RwLock<TestScorer> | |
) -> Self { | |
Self { | |
// Assuming `DEFAULT_ENTROPY` is defined as a constant elsewhere | |
router: DefaultRouter::new(network_graph.clone(), logger, DEFAULT_ENTROPY, scorer, ()), | |
network_graph, | |
next_routes: Mutex::new(VecDeque::new()), | |
scorer, | |
} |
const MIN_PEER_CHANNELS: usize = 3; | ||
|
||
let network_graph = self.network_graph.deref().read_only(); | ||
let paths = peers.iter() | ||
let peer_channels = peers.iter() | ||
.map(|pubkey| (pubkey, NodeId::from_pubkey(&pubkey))) | ||
// Limit to peers with announced channels | ||
.filter(|pubkey| | ||
.filter_map(|(pubkey, node_id)| | ||
network_graph | ||
.node(&NodeId::from_pubkey(pubkey)) | ||
.node(&node_id) | ||
.map(|info| &info.channels[..]) | ||
.map(|channels| channels.len() >= MIN_PEER_CHANNELS) | ||
.unwrap_or(false) | ||
.and_then(|channels| (channels.len() >= MIN_PEER_CHANNELS).then(|| channels)) | ||
.map(|channels| (pubkey, node_id, channels)) | ||
); | ||
|
||
let three_hop_paths = peer_channels.clone() | ||
// Pair peers with their other peers | ||
.flat_map(|(pubkey, node_id, channels)| | ||
channels | ||
.iter() | ||
.filter_map(|scid| network_graph.channels().get(scid)) | ||
.filter_map(move |info| info | ||
.as_directed_to(&node_id) | ||
.map(|(_, source)| source) | ||
) | ||
.filter(|source| **source != recipient_node_id) | ||
.filter(|source| network_graph | ||
.node(source) | ||
.and_then(|info| info.announcement_info.as_ref()) | ||
.map(|info| info.features.supports_onion_messages()) | ||
.unwrap_or(false) | ||
) | ||
.filter_map(|source| source.as_pubkey().ok()) | ||
.map(move |source_pubkey| (source_pubkey, *pubkey)) | ||
) | ||
.map(|pubkey| vec![*pubkey, recipient]) | ||
.map(|(source_pubkey, pubkey)| vec![source_pubkey, pubkey, recipient]) | ||
.map(|node_pks| BlindedPath::new_for_message(&node_pks, entropy_source, secp_ctx)) | ||
.take(MAX_PATHS) | ||
.collect::<Result<Vec<_>, _>>(); | ||
|
||
match paths { | ||
Ok(paths) if !paths.is_empty() => Ok(paths), | ||
_ => { | ||
if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) { | ||
BlindedPath::one_hop_for_message(recipient, entropy_source, secp_ctx) | ||
.map(|path| vec![path]) | ||
} else { | ||
Err(()) | ||
} | ||
}, | ||
} | ||
.take(MAX_PATHS); | ||
|
||
let two_hop_paths = peer_channels | ||
.map(|(pubkey, _, _)| vec![*pubkey, recipient]) | ||
.map(|node_pks| BlindedPath::new_for_message(&node_pks, entropy_source, secp_ctx)) | ||
.take(MAX_PATHS); | ||
|
||
three_hop_paths | ||
.collect::<Result<Vec<_>, _>>().ok() | ||
.and_then(|paths| (!paths.is_empty()).then(|| paths)) | ||
.or_else(|| two_hop_paths.collect::<Result<Vec<_>, _>>().ok()) | ||
.and_then(|paths| (!paths.is_empty()).then(|| paths)) | ||
.or_else(|| network_graph | ||
.node(&NodeId::from_pubkey(&recipient)).ok_or(()) | ||
.and_then(|_| BlindedPath::one_hop_for_message(recipient, entropy_source, secp_ctx)) | ||
.map(|path| vec![path]) | ||
.ok() | ||
) | ||
.ok_or(()) | ||
} | ||
} | ||
|
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.
Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [352-413]
The create_blinded_paths
function within the DefaultMessageRouter
struct has been modified. The logic appears to be sound, with checks for the number of channels a peer has and whether they support onion messages. However, the complexity of the nested closures and filters is quite high, which could impact maintainability. Consider refactoring for clarity.
pub(crate) fn peel_onion_message( | ||
&self, msg: &OnionMessage | ||
) -> Result<PeeledOnion<<<CMH>::Target as CustomOnionMessageHandler>::CustomMessage>, ()> { | ||
peel_onion_message( | ||
msg, &self.secp_ctx, &*self.node_signer, &*self.logger, &*self.custom_handler | ||
) | ||
} | ||
|
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 peel_onion_message
function has been added to decode one layer of an incoming OnionMessage
. The function uses a series of matches and error handling that seems appropriate. However, the error handling could be improved by returning more descriptive errors instead of a generic ()
to aid in debugging.
The peel_onion_message
function uses a lot of nested logic and has multiple points where it returns Err(())
. It would be beneficial to define a custom error type that can provide more context about the failure, which would be helpful for debugging and error handling by the callers of this function.
@@ -42,6 +40,7 @@ use crate::prelude::*; | |||
#[cfg(not(c_bindings))] | |||
use { | |||
crate::sign::KeysManager, | |||
crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}, |
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 import of IgnoringMessageHandler
is not used anywhere in the file. Unused imports can be removed to clean up the code.
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.
Are you sure? I see it used on lines 1104 and 1123?
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.
@@ -42,6 +40,7 @@ use crate::prelude::*;
#[cfg(not(c_bindings))]
use {
crate::sign::KeysManager,
+ crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager},
@jkczyz, you are correct. The IgnoringMessageHandler
is indeed used in the type aliases SimpleArcOnionMessenger
and SimpleRefOnionMessenger
on lines 1104 and 1123. Thank you for pointing that out. My initial comment was mistaken.
ed86950
to
a529010
Compare
a529010
to
707cc82
Compare
Rebased and added the filtering and sorting of three-hop blinded paths:
|
707cc82
to
f05ba31
Compare
// Limit the number of blinded paths that are computed. | ||
const MAX_PAYMENT_PATHS: usize = 3; | ||
|
||
// Ensure peers have at least three channels so that it is more difficult to infer the | ||
// recipient's node_id. | ||
const MIN_PEER_CHANNELS: usize = 3; | ||
|
||
// The minimum channel balance certainty required for using a channel in a blinded path. | ||
const MIN_CHANNEL_CERTAINTY: f64 = 0.5; |
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.
Rather than having some arbitrary "certainty" constant in the router itself, should we not just let the scorer figure out what the right certainty threshold (or even certainty concept) is? Basically have it return Option<u64 (or f64)>
and just use that to select the best path, don't apply any arbitrary limits here but make sure the docs are clear that the scorer should apply arbitrary limits itself.
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.
Hmmm... as currently written, the return value is used to compare against MIN_CHANNEL_CERTAINTY
. If the scorer applies a limit itself, it really only needs to return a bool. Or are you suggesting we combine the two new methods into one returning Some
success probability or None
? Note that certainty is only used for filtering -- so it is not used to choose the best path -- while success probability is dependent on the amount and used for both filtering and sorting.
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.
Right, I'd imagine we probably return either an option to include the probability/hop cost or we use something like u64::MAX
/f64::INF
as a magic "dont use this channel" value (like we do now with the fee cost).
f05ba31
to
b3dc11d
Compare
Rebased on #3080 but will need to adjust the strategy now. |
d839dbd
to
a0fe784
Compare
An upcoming change to the MessageRouter trait will require reusing DefaultMessageRouter::create_blinded_paths. Move the code to a utility function so facilitate this.
a0fe784
to
ecbc0eb
Compare
Using compact blinded paths isn't always necessary or desirable. For instance, reply paths are communicated via onion messages where space isn't a premium unlike in QR codes. Additionally, long-lived paths could become invalid if the channel associated with the SCID is closed. Refactor MessageRouter::create_blinded_paths into two methods: one for compact blinded paths and one for normal blinded paths.
There's no need to save space when creating reply paths since they are part of onion messages rather than in QR codes. Use normal blinded paths for these instead as they are less likely to become invalid in case of channel closure.
When an offer is short-lived, the likelihood of a channel used in a compact blinded path going away is low. Require passing the absolute expiry of an offer to ChannelManager::create_offer_builder so that it can be used to determine whether or not compact blinded path should be used. Use the same criteria for creating blinded paths for refunds as well.
When reconnecting nodes, make sure to notify OnionMessenger that the nodes are now connected.
When calling MessageRouter::create_blinded_path, ChannelManager was including disconnected peers. Filter peers such that only connected ones are included. Otherwise, the resulting BlindedPath may not work.
The docs assumed ChannelManager is parameterized by DefaultRouter, which may not be the case. Clarify the behavior is specific to using DefaultRouter.
How certain a scorer is about a channel's liquidity balance is useful in determining if the channel should be included in a blinded payment path. Channels with uncertain balances should be avoided to facilitate successful payments. Expand ScoreLookUp with a channel_balance_certainty method and use it in DefaultRouter::create_blinded_payment_paths.
How certain a scorer is about a channel's success probability is useful in determining if the channel should be included in a blinded payment path. Channels with low success probability for a given amount should be avoided to facilitate successful payments. Expand ScoreLookUp with a channel_success_probability method and use it in DefaultRouter::create_blinded_payment_paths.
ecbc0eb
to
ee88951
Compare
Work in progress split out from #2781.
Summary by CodeRabbit
New Features
Enhancements
Refactor
Bug Fixes
Documentation