-
Notifications
You must be signed in to change notification settings - Fork 97
Batching of network segments in the Session protocol #6531
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
Conversation
📝 Walkthrough<details>
<summary>📝 Walkthrough</summary>
## Walkthrough
The pull request introduces several modifications across multiple files, primarily focusing on dependency management, feature enhancements, and the introduction of new functionalities. Key changes include updates to the `Cargo.toml` files for various packages to add new dependencies and features, modifications to the session protocol to support asynchronous operations, and enhancements to session management, including the introduction of a port range configuration and optional encryption for session targets. Documentation has also been improved for clarity and correctness.
## Changes
| File | Change Summary |
|------|----------------|
| `Cargo.toml` | Updated `criterion` dependency features; added `async-std` features. |
| `README.md` | Added `HOPRD_SESSION_PORT_RANGE` environment variable; corrected typographical errors. |
| `common/network-types/Cargo.toml` | Version updated to `0.5.0`; added `testing` feature; added dependencies for `hopr-crypto-types` and `criterion`. |
| `common/network-types/benches/session.rs` | Introduced benchmarking for one-way reliable data transmission. |
| `common/network-types/src/session/errors.rs` | Updated `SessionError` enum to derive `Clone` and modified error message. |
| `common/network-types/src/session/frame.rs` | Added `MINIMUM_SIZE` and `MAXIMUM_SIZE` constants; updated `TryFrom` implementation. |
| `common/network-types/src/session/mod.rs` | Added conditional export for `utils` module. |
| `common/network-types/src/session/protocol.rs` | Enhanced message encoding with length field; updated message parsing. |
| `common/network-types/src/session/state.rs` | Removed `max_msg_per_sec`; added `allow_output_buffering`. |
| `common/network-types/src/session/utils.rs` | Introduced `FaultyNetworkConfig`, `NetworkStats`, and `FaultyNetwork` structs. |
| `common/network-types/src/types.rs` | Added `SealedHost` enum for encrypted IP handling. |
| `common/network-types/src/udp.rs` | Added `UdpStreamParallelism` enum; updated parallelism handling. |
| `common/network-types/src/utils.rs` | Changed visibility of `DuplexIO` struct to public; added `From` implementation. |
| `crypto/types/Cargo.toml` | Added `bincode` and `crypto_box` dependencies. |
| `crypto/types/src/errors.rs` | Added `SealingError` variant to `CryptoError`. |
| `crypto/types/src/lib.rs` | Added `seal` module for encryption functionality. |
| `crypto/types/src/seal.rs` | Introduced `seal_data` and `unseal_data` functions for encryption. |
| `hopr/hopr-lib/Cargo.toml` | Added `backon` and `futures-timer` dependencies. |
| `hopr/hopr-lib/src/config.rs` | Added `session` field to `HoprLibConfig`. |
| `hopr/hopr-lib/src/lib.rs` | Simplified `HoprLibProcesses` enum; enhanced error handling in `connect_to`. |
| `hoprd/hoprd/Cargo.toml` | Added `serde_with` and `smart-default` dependencies. |
| `hoprd/hoprd/src/config.rs` | Added `exit` field to `HoprdConfig`. |
| `hoprd/hoprd/src/exit.rs` | Introduced `HoprServerIpForwardingReactor` for session exit management. |
| `hoprd/hoprd/src/lib.rs` | Added `exit` module; removed `HoprServerIpForwardingReactor` struct. |
| `hoprd/hoprd/src/main.rs` | Updated import for `HoprServerIpForwardingReactor`. |
| `hoprd/rest-api/Cargo.toml` | Added `base64` dependency. |
| `hoprd/rest-api/src/lib.rs` | Added `HOPRD_SESSION_PORT_RANGE` constant and modified listener handling. |
| `hoprd/rest-api/src/session.rs` | Introduced `SessionTargetSpec` enum for session target handling. |
| `nix/rust-package.nix` | Updated test arguments for enhanced testing capabilities. |
| `tests/hopr.py` | Updated `session_client` method to include `sealed_target` parameter. |
| `transport/api/Cargo.toml` | Added `serde_with` and `smart-default` dependencies. |
| `transport/api/src/config.rs` | Introduced `SessionGlobalConfig` struct for session management. |
| `transport/api/src/constants.rs` | Removed constants related to session management. |
| `transport/api/src/helpers.rs` | Simplified `PathPlanner` and `MessageSender` structs. |
| `transport/api/src/lib.rs` | Restructured session management with new `SessionManager`. |
| `transport/session/Cargo.toml` | Updated version to `0.3.0`; added dependencies for `moka` and `hopr-async-runtime`. |
| `transport/session/src/errors.rs` | Added new error variants to `TransportSessionError`. |
| `transport/session/src/initiation.rs` | Enhanced `StartProtocol` enum handling. |
| `transport/session/src/lib.rs` | Added `manager` module for session lifecycle management. |
| `transport/session/src/manager.rs` | Introduced `SessionManager` for managing session lifecycles. |
| `transport/session/src/traits.rs` | Removed `close` method from `SendMsg` trait. |
| `transport/session/src/types.rs` | Updated session target types to use `SealedHost`. |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant Client
participant SessionManager
participant ExitNode
Client->>SessionManager: Initiate Session
SessionManager->>ExitNode: Forward Session Request
ExitNode->>SessionManager: Acknowledge Session
SessionManager->>Client: Session Established Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
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 using PR comments)
Other keywords and placeholders
Documentation and Community
|
Introduced the `allow_output_buffering` option in `SessionConfig` to control output buffering. Implemented `SessionMessageIter` to provide an iterator for `SessionMessage`, enhancing message parsing capabilities.
…session-msg-bursts
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.
Actionable comments posted: 30
🧹 Outside diff range comments (1)
common/network-types/src/session/errors.rs (1)
Line range hint
4-45
: Consider adding error variants for new Session protocol features.The PR introduces several new features that should have corresponding error types:
- Allow-list violations for Exit nodes
- Target encryption/sealing failures
- Port range configuration issues
Consider adding these error variants:
pub enum SessionError { // ... existing variants ... + #[error("target {0} is not in the allow-list")] + TargetNotAllowed(String), + + #[error("failed to seal/unseal target: {0}")] + TargetSealingError(String), + + #[error("port {0} is outside the configured range")] + PortOutOfRange(u16), }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
⛔ Files ignored due to path filters (1)
Cargo.lock
is excluded by!**/*.lock
📒 Files selected for processing (24)
README.md
(1 hunks)common/network-types/Cargo.toml
(5 hunks)common/network-types/benches/session.rs
(1 hunks)common/network-types/src/errors.rs
(1 hunks)common/network-types/src/session/errors.rs
(2 hunks)common/network-types/src/session/frame.rs
(4 hunks)common/network-types/src/session/state.rs
(32 hunks)common/network-types/src/session/utils.rs
(4 hunks)common/network-types/src/types.rs
(2 hunks)common/network-types/src/udp.rs
(13 hunks)common/primitive-types/src/bounded.rs
(3 hunks)crypto/types/src/errors.rs
(2 hunks)crypto/types/src/seal.rs
(1 hunks)hopr/hopr-lib/src/lib.rs
(10 hunks)hoprd/hoprd/example_cfg.yaml
(2 hunks)hoprd/hoprd/src/config.rs
(2 hunks)hoprd/rest-api/src/lib.rs
(3 hunks)transport/api/src/config.rs
(2 hunks)transport/api/src/helpers.rs
(5 hunks)transport/api/src/lib.rs
(16 hunks)transport/session/src/errors.rs
(1 hunks)transport/session/src/lib.rs
(2 hunks)transport/session/src/manager.rs
(1 hunks)transport/session/src/types.rs
(10 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~210-~210: Possible missing comma found.
Context: ...out any command-line argument might not work depending on the installation method us...
(AI_HYDRA_LEO_MISSING_COMMA)
🔇 Additional comments (63)
crypto/types/src/errors.rs (2)
5-5
: LGTM! Good addition of PartialEq
.
Adding PartialEq
derive is beneficial for error comparison in tests and error handling.
31-32
: 🛠️ Refactor suggestion
Consider making the sealing error transparent.
The current implementation loses the underlying error context. To preserve the error chain and provide more detailed debugging information, consider making the error type transparent by including the underlying error type.
Apply this diff:
-#[error("error during sealing/unsealing of data")]
-SealingError,
+#[error("error during sealing/unsealing of data: {0}")]
+SealingError(#[from] Box<dyn std::error::Error + Send + Sync>),
common/network-types/src/session/errors.rs (2)
4-4
: LGTM! The Clone derive is necessary.
The Clone
derive is required for SessionMessageIter
to store the last error during iteration.
27-27
: LGTM! The error message is clear and descriptive.
The updated error message "input data exceeds the maximum allowed size of segment" clearly describes the error condition and aligns well with both frame segmentation and the new batching feature.
common/network-types/Cargo.toml (4)
3-3
: Version bump from 0.4.0 to 0.5.0 is appropriate.
The version increment to 0.5.0 aligns with semantic versioning given the significant new features being added (session batching, encryption, retry strategy).
54-54
: New dependencies align with PR objectives.
The addition of:
validator
suggests input validation improvementshopr-crypto-types
aligns with the new encryption features for session targets
Also applies to: 58-58
67-67
: Benchmark configuration supports performance testing.
The addition of criterion
and the session benchmark configuration aligns with the PR's focus on performance optimization through packet batching.
#!/bin/bash
# Verify the existence of the session benchmark file
fd "session.rs" "benches"
Also applies to: 79-83
25-25
: Verify the purpose of the empty testing
feature.
The new testing
feature is currently empty. This might be intended for test-only functionality, but its purpose and usage should be clarified.
✅ Verification successful
Let me try a different search strategy to understand the purpose and usage of this feature.
Based on the search results, I can see that the testing
feature in common/network-types/Cargo.toml
is an empty feature flag that is used to enable test-specific functionality in the codebase. This is a common pattern in Rust where features are used to conditionally compile test code or expose testing utilities.
The feature is used in several places:
- In benchmarks:
common/network-types/benches/session.rs
requires this feature to be enabled - In session module:
common/network-types/src/session/mod.rs
uses it to conditionally expose testing utilities likeFaultyNetwork
andFaultyNetworkConfig
- The feature is empty (
testing = []
) indicating it's just a flag to enable test-specific code paths
This is a valid and common use of feature flags in Rust for testing purposes. The empty feature is intentional and serves its purpose of conditionally enabling test code.
The empty testing
feature is correctly implemented and used appropriately for test functionality.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for usage of the testing feature in the codebase
rg '#\[cfg\(feature = "testing"\)\]'
Length of output: 212
Script:
#!/bin/bash
# Search for any references to the testing feature in Rust files
rg -t rust 'testing' -A 2
# Also check for feature declarations in other Cargo.toml files
fd Cargo.toml --exec grep -A 2 'testing'
# Look for test modules or test-related code
rg -t rust '#\[cfg\(test\)\]' -A 2 common/network-types/
Length of output: 270941
common/primitive-types/src/bounded.rs (1)
9-14
: LGTM! Well-implemented constants with clear documentation.
The addition of MIN
and MAX
constants provides useful compile-time guarantees and improves the API's ergonomics.
transport/api/src/helpers.rs (3)
3-3
: LGTM: Appropriate imports added for new functionality.
The new imports support the transition to using OnceLock
for thread-safe initialization and improved error handling with SessionManagerError
.
Also applies to: 19-19
66-66
: LGTM: Improved trait bounds specification.
Good refactoring to move trait bounds from struct definition to impl block. This follows Rust's best practices by only applying constraints where they're actually needed.
Also applies to: 73-73
140-147
: LGTM: Improved thread safety and session management.
Good improvements:
- Moved trait bounds to impl block following Rust best practices
- Using
OnceLock
for thread-safe initialization ofprocess_packet_send
- Removed redundant
closed
field as part of session management restructuring
hoprd/hoprd/example_cfg.yaml (1)
298-303
:
Strengthen security documentation for target allow-list.
While the comment mentions that production should use the allow-list, the security implications should be more explicit:
- The default behavior (allowing all targets) could pose security risks in production
- DNS resolution behavior needs clarification:
- Does it resolve to IPv4, IPv6, or both?
- What happens if a DNS name resolves to multiple IPs?
- Are resolved IPs cached? If so, for how long?
Consider adding a warning block:
# WARNING: Leaving target_allow_list undefined allows unrestricted access to any target.
# This is NOT recommended for production deployments as it may expose internal network
# services to unauthorized access.
Let's verify if there are any other security-sensitive configurations with similar default-allow behavior:
✅ Verification successful
Let me search for more context about the target allow list implementation to better understand the security implications.
The search results provide enough context about the implementation. Let me generate the final response:
Security documentation for target allow-list is appropriate but could be enhanced
The current documentation accurately reflects the implementation in src/exit.rs
, where:
- The allow-list is implemented as
Option<HashSet<SocketAddr>>
, confirming it only accepts IP:port combinations - DNS resolution happens before the allow-list check (via
all_ips_allowed
function) - The default
None
behavior allowing all targets is explicitly documented
While the security warning could be stronger, the current documentation:
- Clearly states the default behavior
- Explicitly recommends using the allow-list in production
- Provides a concrete example of secure configuration
The DNS resolution behavior is straightforward - it resolves to SocketAddr
(which includes both IPv4/IPv6), and all resolved addresses must be in the allow-list to permit access.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for similar allow-list patterns in the codebase
rg -i "allow.*list|whitelist|permitted.*targets" --type yaml
Length of output: 407
Script:
#!/bin/bash
# Search for target allow list implementation and related code
rg -i "target.?allow.?list" -A 5 -B 5
# Also search for any validation or security checks
ast-grep --pattern 'if ($target_allow_list) { $$$ }'
Length of output: 2387
hoprd/rest-api/src/lib.rs (2)
55-56
: Verify handling of encrypted targets in existing listeners.
The change from String
to SessionTargetSpec
in ListenerJoinHandles
supports the new encrypted target field feature. However, we should ensure proper handling of existing listeners during upgrade.
Let's verify the migration handling:
#!/bin/bash
# Description: Check how existing listeners are handled during the type change
# Search for listener creation/management code
ast-grep --pattern 'fn $_(ListenerJoinHandles, $_) {
$$$
}'
# Search for any migration or upgrade handling code
rg "SessionTargetSpec::Plain|SessionTargetSpec::Sealed" -A 5
Also applies to: 71-72
18-22
:
Fix inconsistency in port range format documentation.
The documentation shows an inconsistency:
- Format specification shows "start_port:end_port"
- Example shows "9091-9099"
Additionally, the documentation could be enhanced with validation rules.
Apply this diff to improve the documentation:
pub(crate) mod env {
/// Name of the environment variable specifying automatic port range selection for Sessions.
- /// Expected format: "<start_port>:<end_port>" (e.g., "9091:9099")
+ /// Expected format: "<start_port>-<end_port>" (e.g., "9091-9099")
+ /// Validation rules:
+ /// - Both ports must be valid TCP/UDP port numbers (0-65535)
+ /// - Start port must be less than or equal to end port
pub const HOPRD_SESSION_PORT_RANGE: &str = "HOPRD_SESSION_PORT_RANGE";
}
Let's verify the actual format parsing in the codebase:
✅ Verification successful
Documentation format is correct, no changes needed
Looking at the code in session.rs
, the port range parsing logic uses the separator ":" as documented in the environment variable:
let range = range_str
.split_once(":") // Uses ":" as separator
.and_then(
|(a, b)| match u16::from_str(a).and_then(|a| Ok((a, u16::from_str(b)?))) {
Ok((a, b)) if a <= b => Some(a..=b),
_ => None,
},
)
The documentation in lib.rs
correctly specifies the format as "<start_port>:<end_port>"
which matches the actual implementation. The example "9091:9099"
is also consistent with this format.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find the code that parses HOPRD_SESSION_PORT_RANGE to confirm the expected format
# Search for references to the environment variable
rg "HOPRD_SESSION_PORT_RANGE" -A 5
# Search for port range parsing logic
ast-grep --pattern 'let $_ = $_env.var($_).map(|$_| $_)'
Length of output: 202
Script:
#!/bin/bash
# Let's try a different approach to find the port range parsing logic
# Search for files containing HOPRD_SESSION_PORT_RANGE
rg --files-with-matches "HOPRD_SESSION_PORT_RANGE"
# Search for any port range parsing patterns
rg 'split([-:]).*port' -A 3
# Look for environment variable parsing related to ports
rg 'parse.*port.*range' -i -A 3
# Search for port range validation logic
rg '(start|end)_port.*=.*parse' -A 3
Length of output: 228587
Script:
#!/bin/bash
# Let's search for port range parsing in session.rs since it was found in the previous search
cat hoprd/rest-api/src/session.rs
# Also search for any port range related code
rg -l "port.*range" hoprd/rest-api/src/
Length of output: 32664
README.md (1)
212-212
: Skip comment: Grammar issue already addressed
hoprd/hoprd/src/config.rs (1)
113-116
: Verify the integration of exit node configuration.
The exit node configuration appears to be properly integrated with appropriate validation and serialization. Let's verify the configuration integration and usage across the codebase.
✅ Verification successful
Exit node configuration is properly integrated and validated
The verification shows that the IpForwardingReactorConfig
is well-integrated:
- Properly structured with validation attributes and comprehensive documentation
- Has smart defaults for all fields (using
smart_default
derive) - Includes safety features like target allow-list and retry configuration
- Correctly used in
HoprServerIpForwardingReactor
implementation - Properly integrated into the main
HoprdConfig
with nested validation
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the integration and usage of IpForwardingReactorConfig
# Test 1: Check for configuration parsing and validation
echo "Checking configuration parsing..."
rg -p "IpForwardingReactorConfig.*parse|parse.*IpForwardingReactorConfig"
# Test 2: Check for configuration usage in exit node setup
echo "Checking exit node configuration usage..."
ast-grep --pattern 'exit: $config' -l rust
# Test 3: Check for environment variable handling
echo "Checking environment variable handling..."
rg -p "HOPR.*EXIT|EXIT.*HOPR"
# Test 4: Check for configuration documentation
echo "Checking configuration documentation..."
fd -e yaml -e md -x cat {} \; | rg -A 5 -B 5 "exit:"
Length of output: 635
Script:
#!/bin/bash
# Let's try different approaches to verify the integration
# Check for IpForwardingReactorConfig usage
echo "Checking IpForwardingReactorConfig usage..."
rg -p "IpForwardingReactorConfig"
# Check for exit node configuration initialization
echo "Checking exit node initialization..."
ast-grep --pattern 'struct $_ {
$$$
exit: IpForwardingReactorConfig,
$$$
}'
# Check for configuration loading/usage
echo "Checking configuration loading..."
rg -p "config\.exit\." -A 3 -B 3
# Check for exit node related tests
echo "Checking exit node tests..."
fd -e rs -x rg -l "test.*exit" {}
Length of output: 1464
Script:
#!/bin/bash
# Let's check the implementation details of IpForwardingReactorConfig and its usage
# Check the full implementation of IpForwardingReactorConfig
echo "Checking IpForwardingReactorConfig implementation..."
rg -p -B 5 -A 40 "struct IpForwardingReactorConfig"
# Check for exit node reactor initialization and usage
echo "Checking exit node reactor usage..."
rg -p "IpForwardingReactor" -A 3 -B 3
# Check for configuration validation implementation
echo "Checking configuration validation..."
rg -p "impl.*Validate.*IpForwardingReactorConfig" -A 10
# Check for default implementation
echo "Checking default implementation..."
rg -p "impl Default for IpForwardingReactorConfig" -A 10
Length of output: 4625
transport/api/src/lib.rs (6)
193-193
: LGTM: Session configuration field added
The addition of the session
field to HoprTransportConfig
aligns with the PR objective of making session behavior configurable.
Line range hint 202-214
: LGTM: Efficient peer ID caching and session manager integration
Good optimization to cache me_peerid
to avoid expensive conversions from OffchainPublicKey
to PeerId
. The smgr
field is properly integrated with the correct generic type.
254-262
: LGTM: Proper session manager initialization
The session manager is correctly initialized with appropriate configuration parameters and well-defined tag ranges.
Line range hint 422-447
: LGTM: Well-structured message dispatch handling
The message dispatch implementation includes comprehensive error handling and proper logging through tracing macros.
528-528
: LGTM: Proper async session creation
The session creation is correctly delegated to the session manager with proper error handling.
738-738
: LGTM: Efficient channel ownership verification
The implementation correctly uses the cached onchain keypair for address comparison.
common/network-types/src/session/frame.rs (3)
Line range hint 214-230
: LGTM! Error handling improvements.
The changes improve error handling by:
- Using more specific
SessionError
types - Adding proper size validation against
MAXIMUM_SIZE
- Providing clearer error messages
545-545
: LGTM! Clear documentation improvement.
The added documentation clearly specifies the ordering guarantee of the returned collection, which is valuable information for API users.
164-168
: 🧹 Nitpick (assertive)
Improve documentation for MAXIMUM_SIZE
constant.
The comment about "10-bits" is confusing and was previously discussed. Consider updating the comment to focus on the MTU relationship:
/// The maximum size of a segment: [`Segment::HEADER_SIZE`] + data, regardless
/// any MTU.
- /// This number is currently set, so that segment length is expressible
- /// with just 10-bits and fits typical Ethernet MTU size.
+ /// This number is set to 1500 bytes to match the typical Ethernet MTU size,
+ /// ensuring segments can be transmitted without fragmentation at the network layer.
pub const MAXIMUM_SIZE: usize = 1500;
hopr/hopr-lib/src/lib.rs (3)
Line range hint 6-15
: LGTM! Documentation improvements enhance clarity.
The documentation changes effectively communicate the library's purpose and integration points.
178-179
: LGTM! SessionsManagement consolidation improves code organization.
The consolidation of session-related variants into a single parameterized variant enhances maintainability.
1045-1047
: LGTM! Appropriate logging level adjustments.
The change to trace level for strategy tick events reduces log verbosity while maintaining important info level logs for node status.
Also applies to: 1059-1059
transport/session/src/errors.rs (2)
28-30
: Well-defined UnknownData
error variant added
The addition of the UnknownData
variant improves error handling when data is received for an unregistered session.
34-36
: Properly handling network errors with Network
variant
Including the Network(#[from] hopr_network_types::errors::NetworkTypeError)
variant allows for transparent propagation of network type errors, enhancing error management.
common/network-types/benches/session.rs (2)
1-71
: Benchmark code is well-structured and meets objectives
The benchmarking code is well-organized and effectively implements performance measurement for one-way reliable data transmission. Good job on integrating asynchronous operations and setting up the simulated network environment.
28-40
: 🛠️ Refactor suggestion
Add validation to ensure the data received matches the data sent
After reading the data from b_to_a
, adding an assertion to verify that the received data matches the sent data will ensure data integrity in the benchmark.
Apply this diff to add the validation:
let mut data_out = vec![0u8; data.len()];
b_to_a.read_exact(&mut data_out[..]).await?;
+ assert_eq!(data_out, data, "Received data does not match sent data");
Likely invalid or redundant comment.
transport/session/src/lib.rs (7)
8-8
: Approved: Addition of manager
module
The introduction of the manager
module enhances the modularity and organization of the codebase.
12-12
: Approved: Publicly exporting entities from manager
module
Re-exporting DispatchResult
, SessionManager
, and SessionManagerConfig
makes these entities accessible throughout the codebase.
14-14
: Approved: Importing SessionFeature
Importing SessionFeature
is necessary for utilizing session features in the implementation.
34-37
: Approved: Addition of RetransmissionAckOnly
and NoDelay
capabilities
Adding RetransmissionAckOnly
and NoDelay
provides more granular control over session behaviors, enhancing configurability.
77-78
: Approved: Documentation update for target
field
The added documentation for the target
field effectively explains its purpose and the use of SealedHost
for optional encryption.
52-53
: Ensure correct mapping for RetransmissionAckOnly
capability
Capability::RetransmissionAckOnly
maps to SessionFeature::AcknowledgeFrames
and SessionFeature::RetransmitFrames
. Verify that this mapping correctly represents ACK-only retransmission and that SessionFeature::RetransmitFrames
aligns with this intent.
To confirm the definition of SessionFeature::RetransmitFrames
, run:
#!/bin/bash
# Description: Retrieve the definition and usage of `SessionFeature::RetransmitFrames`.
# Expectation: Ensure it relates to ACK-only retransmission.
rg -A 3 'SessionFeature::RetransmitFrames' -t rust
45-45
: Verify if Capability::Segmentation
should include session features
Capability::Segmentation
currently returns an empty vector of SessionFeature
. Please verify whether this is intentional or if it should include specific features related to segmentation.
To check for existing SessionFeature
variants related to segmentation, run the following script:
✅ Verification successful
Let me gather more information about the SessionFeature
enum and Capability
enum to better understand their relationship.
Let me try a different approach using ripgrep to find these enum definitions.
Let me search for any documentation or comments about the Capability::Segmentation
feature.
Let me search for the frame segmentation implementation in the network-types crate since it was mentioned in the earlier context.
Based on the comprehensive code analysis, I can now provide a definitive response about the Capability::Segmentation
feature.
Capability::Segmentation
returns empty feature set by design
The empty vector for Capability::Segmentation
is intentional because:
-
Frame segmentation is a core functionality that is always enabled and doesn't require any special session features. This is evidenced by:
-
Unlike other capabilities like
Capability::Retransmission
which maps to features likeSessionFeature::RetransmitFrames
andSessionFeature::AcknowledgeFrames
, segmentation is a fundamental transport mechanism that operates independently of session features. -
The codebase shows that segmentation happens automatically when data exceeds the MTU size, regardless of any feature flags.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for SessionFeature variants related to segmentation.
# Expectation: Find SessionFeature variants containing 'Segment' or 'Segmentation'.
rg 'SessionFeature::.*Segment' -t rust
Length of output: 955
Script:
#!/bin/bash
# Search for SessionFeature enum definition
echo "=== SessionFeature enum definition ==="
ast-grep --pattern 'enum SessionFeature {
$$$
}'
echo -e "\n=== Capability enum definition ==="
# Search for Capability enum definition
ast-grep --pattern 'enum Capability {
$$$
}'
echo -e "\n=== Usage of Capability::Segmentation ==="
# Search for any usage or documentation of Capability::Segmentation
rg "Capability::Segmentation" -A 3 -B 3
Length of output: 551
Script:
#!/bin/bash
# Search for SessionFeature enum definition and its variants
echo "=== SessionFeature enum and its usage ==="
rg "enum SessionFeature" -A 10 -t rust
echo -e "\n=== Capability enum and its usage ==="
rg "enum Capability" -A 10 -t rust
echo -e "\n=== Documentation or comments about Segmentation ==="
rg "Segmentation" -B 2 -A 2 -t rust
Length of output: 67435
Script:
#!/bin/bash
# Search for documentation about Capability::Segmentation and frame segmentation
echo "=== Documentation about Capability::Segmentation ==="
rg -B 5 -A 5 "Frame segmentation" transport/
echo -e "\n=== Frame segmentation implementation ==="
rg -B 5 -A 5 "fn segment" transport/
Length of output: 1037
Script:
#!/bin/bash
# Search for frame segmentation implementation in network-types
echo "=== Frame segmentation implementation in network-types ==="
rg -B 5 -A 10 "fn segment" common/network-types/
echo -e "\n=== Frame segmentation usage ==="
rg -B 3 -A 3 "segment" common/network-types/src/session/
echo -e "\n=== SessionFeature enum definition ==="
rg -B 5 -A 10 "enum SessionFeature" common/network-types/
Length of output: 109342
crypto/types/src/seal.rs (3)
9-19
: LGTM: Correct implementation of seal_data
function
The seal_data
function correctly encrypts serializable data using the recipient's PeerId
. The use of bincode
for serialization and appropriate error handling enhances reliability.
24-34
: LGTM: Correct implementation of unseal_data
function
The unseal_data
function successfully decrypts and deserializes data encrypted with seal_data
. Error handling is properly managed, ensuring that any failures are correctly reported.
36-87
: Comprehensive test coverage for sealing and unsealing
The test module effectively covers:
- Successful sealing and unsealing operations.
- Failure when unsealing with a different private key.
- Error handling when ciphertext has been tampered with.
This thorough testing enhances confidence in the functionality.
transport/api/src/config.rs (1)
189-219
: LGTM!
The SessionGlobalConfig
struct is well-defined with appropriate defaults and validations.
common/network-types/src/session/utils.rs (4)
166-167
: Consider stronger memory ordering for atomic operations
The use of Ordering::Relaxed
for stats.bytes_sent.fetch_add
and stats.packets_sent.fetch_add
may not guarantee the necessary synchronization in a concurrent context. Using a stronger ordering like Ordering::AcqRel
can prevent potential data races when these statistics are accessed across multiple threads.
188-190
: Ensure correct byte count is returned in poll_read
Returning len
instead of item.len()
correctly reflects the actual number of bytes read into buf
, preventing mismatches and potential bugs.
158-163
: Good handling of potential send errors
Properly handling the Err
case when calling self.ingress.unbounded_send(buf.into())
improves the robustness of the code by preventing panics if the receiver has been dropped.
152-155
: Appropriate use of InvalidInput
error kind
Using std::io::ErrorKind::InvalidInput
when the buffer length exceeds C
correctly signifies that the error is due to invalid input parameters.
common/network-types/src/types.rs (3)
162-203
: Well-documented and implemented SealedHost
enum
The SealedHost
enum adds valuable functionality for handling optionally encrypted IpOrHost
instances. The documentation is thorough, and the example provided is clear and informative. This will enhance the security and flexibility of handling host information.
240-249
: Improved error specificity in TryFrom
implementation
Using NetworkTypeError::SealedTarget
as an error variant in the TryFrom<SealedHost> for IpOrHost
implementation provides clearer and more explicit error handling. This enhances the ability to precisely identify and handle cases where a sealed SealedHost
cannot be converted into an IpOrHost
.
346-352
: Consistent test implementations across runtimes
The test ip_or_host_must_resolve_ip_address
for the Tokio runtime is correctly implemented and mirrors the Async-std version. This ensures that DNS resolution functionality is properly tested in different asynchronous environments.
transport/session/src/types.rs (3)
350-352
: Pending Writes Not Flushed in poll_flush
The poll_flush
method in InnerSession
still does not flush pending writes and returns Poll::Ready(Ok(()))
immediately. This behavior can lead to data not being fully sent before the session is considered flushed.
431-432
: Potential Data Loss in poll_close
Due to Unflushed Writes
In poll_close
, setting self.closed = true
without flushing self.tx_buffer
may result in loss of pending writes.
125-127
: Ensure Proper Handling of SealedHost
in SessionTarget
The change from IpOrHost
to SealedHost
in the SessionTarget
enum variants requires updating all associated logic to handle the optional encryption. Please verify that all instances where SessionTarget::UdpStream
and SessionTarget::TcpStream
are used have been appropriately adjusted to manage SealedHost
, including necessary encryption and decryption processes.
Run the following script to identify usages of SessionTarget
that may need updates:
✅ Verification successful
Based on the search results, I can generate the final response as we have sufficient information about how SealedHost
is handled in the codebase.
SealedHost
Handling is Properly Implemented
The codebase correctly handles the SealedHost
type in both UDP and TCP variants:
- In
hoprd/hoprd/src/exit.rs
, proper unsealing is implemented using the keypair for both variants - The
manager.rs
correctly constructs the targets withSealedHost
- Test assertions in
manager.rs
properly verify the host matching
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find all usages of SessionTarget's UdpStream and TcpStream variants.
rg 'SessionTarget::(UdpStream|TcpStream)\(' -A 5
Length of output: 3661
common/network-types/src/udp.rs (5)
74-152
: Well-structured implementation of UdpStreamParallelism
The introduction of the UdpStreamParallelism
enum enhances the flexibility and configurability of the UDP stream parallelism. The implementation correctly handles different scenarios, including auto-detection of available parallelism and specific user-defined values. The methods split_evenly_with
and into_num_tasks
appropriately calculate the number of tasks, ensuring they do not exceed the available CPU parallelism.
Line range hint 280-376
: Robust socket binding with proper error handling
The refactored build
method in UdpStreamBuilder
efficiently attempts to bind sockets across all provided addresses, handling multiple receiver and sender sockets based on the configured parallelism. The code correctly applies socket options like SO_REUSEADDR
and SO_REUSEPORT
when binding multiple sockets. The error handling is thorough, logging binding failures and proceeding to the next address as necessary.
Line range hint 401-500
: Efficient and safe implementation of setup_rx_queue
The setup_rx_queue
function effectively manages incoming UDP packets with proper handling of counterparty verification and foreign data modes. The use of asynchronous loops and back-pressure through bounded channels ensures efficient processing without overwhelming the system. Error conditions are handled gracefully, and appropriate logging provides visibility into the operation.
Line range hint 509-555
: Correct handling of outgoing data in setup_tx_queue
The setup_tx_queue
function properly manages the transmission of outgoing UDP packets. It verifies the presence of a counterparty before sending data and handles errors from the egress channel appropriately. The loop exits gracefully when the transmission is complete or when errors occur, preventing unnecessary resource consumption.
571-572
: Efficient task cancellation in Drop
implementation
The Drop
implementation for ConnectedUdpStream
calls abort()
on each JoinHandle
, which is suitable in this context to immediately stop the associated tasks. Given that the tasks are solely for network I/O operations, this method effectively cleans up resources without causing significant issues. The approach aligns with the intended behavior of rapidly terminating network activities when the stream is dropped.
transport/session/src/manager.rs (2)
237-242
: 🛠️ Refactor suggestion
Replace assert!
with Proper Error Handling
Using assert!
in production code can lead to unexpected panics. Instead, consider returning a Result
with an appropriate error type to handle invalid configurations gracefully. This change improves robustness and provides clearer error messages to the users of the SessionManager
.
Apply this diff to update the constructor:
-pub fn new(me: PeerId, cfg: SessionManagerConfig) -> Self {
- assert!(
- cfg.session_tag_range.start > StartProtocolDiscriminants::COUNT as u16,
- "session tag range start should allow Start protocol messages"
- );
+pub fn new(me: PeerId, cfg: SessionManagerConfig) -> Result<Self, TransportSessionError> {
+ if cfg.session_tag_range.start <= StartProtocolDiscriminants::COUNT as u16 {
+ return Err(TransportSessionError::Manager(
+ "session tag range start should allow Start protocol messages".into(),
+ ));
+ }
Likely invalid or redundant comment.
142-168
: 🧹 Nitpick (assertive)
Prevent Potential Infinite Loop in insert_into_next_slot
While the current implementation includes a check to prevent an infinite loop, adding a maximum iteration limit can provide an extra safeguard. This ensures that the function will terminate even if the gen
function behaves unexpectedly.
Apply this diff to include a maximum iteration limit:
+ let mut iterations = 0;
loop {
+ iterations += 1;
+ if iterations > MAX_ITERATIONS {
+ return None;
+ }
let insertion_result = cache
Define a reasonable MAX_ITERATIONS
based on your use case.
Likely invalid or redundant comment.
common/network-types/src/session/state.rs (2)
171-173
: Validation added for acknowledged_frames_buffer
Good job adding the validation to ensure acknowledged_frames_buffer
has a minimum value of 1, addressing previous concerns about possible invalid configurations.
925-931
: Verify the behavior of BufWriter
with zero capacity
When NoDelay
is enabled, the buffer capacity for BufWriter
is set to zero. Setting the buffer capacity to zero may not function as intended and could lead to unexpected behavior. Please verify whether BufWriter::with_capacity(0, ...)
works correctly, or consider an alternative approach such as bypassing buffering when NoDelay
is enabled.
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.
Actionable comments posted: 15
🧹 Outside diff range comments (2)
transport/session/src/types.rs (1)
Line range hint
525-540
: Consider buffering optimization intransfer_session
.The buffer size calculation logic correctly handles both segmented and non-segmented cases. However, consider adding a debug metric to track buffer utilization for future optimization.
+ #[cfg(feature = "prometheus")] + if let Some(metrics) = hopr_metrics::get_metrics() { + metrics.observe_histogram( + "hopr_session_transfer_buffer_size", + into_session_len as f64, + &[("session_id", session.id().to_string().as_str())] + ); + }common/network-types/src/session/state.rs (1)
Line range hint
1022-1024
: Correct logging message to refer to 'socket writer' instead of 'socket reader'In the
poll_flush
method, update the logging message to "polling flush on socket writer inside session" for accuracy.Apply this diff to correct the logging message:
- "polling flush on socket reader inside session" + "polling flush on socket writer inside session"
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
⛔ Files ignored due to path filters (1)
Cargo.lock
is excluded by!**/*.lock
📒 Files selected for processing (14)
common/network-types/Cargo.toml
(5 hunks)common/network-types/benches/session.rs
(1 hunks)common/network-types/src/session/state.rs
(32 hunks)common/network-types/src/types.rs
(5 hunks)crypto/types/Cargo.toml
(1 hunks)crypto/types/src/lib.rs
(2 hunks)crypto/types/src/seal.rs
(1 hunks)tests/hopr.py
(4 hunks)tests/requirements.txt
(1 hunks)tests/test_session.py
(1 hunks)transport/api/src/lib.rs
(16 hunks)transport/session/src/errors.rs
(1 hunks)transport/session/src/lib.rs
(2 hunks)transport/session/src/types.rs
(11 hunks)
🧰 Additional context used
🪛 Ruff
tests/hopr.py
462-462: Line too long (141 > 120)
(E501)
482-482: Line too long (122 > 120)
(E501)
🔇 Additional comments (36)
tests/requirements.txt (1)
1-1
: LGTM: base58 dependency addition
The addition of base58 is appropriate for handling peer ID encoding/decoding in the test suite, particularly for the new session target encryption features.
crypto/types/Cargo.toml (1)
10-10
: LGTM! The crypto_box dependency addition aligns with PR objectives.
The addition of crypto_box
with the "seal" feature is appropriate for implementing the new encrypted target functionality in the Session protocol. The chosen version (0.9.1) is stable and compatible with the existing cryptographic dependencies.
Let's verify the compatibility with other crypto dependencies:
✅ Verification successful
Let me analyze the key findings from the search results to verify the review comment:
- The
crypto_box
dependency is added with the "seal" feature incrypto/types/Cargo.toml
- The codebase shows usage of sealed box encryption in:
crypto/types/src/seal.rs
- Implementation of sealing functionalitycommon/network-types/src/types.rs
-SealedHost
enum and related functionalitytransport/session/src/types.rs
- Usage in session typestests/hopr.py
- Tests verifying sealed box encryption
Let me verify the version compatibility with other crypto dependencies:
Based on the search results, I can verify the compatibility of the crypto_box
dependency:
-
The
crypto_box
v0.9.1 is being used with the "seal" feature, which is compatible with:curve25519-dalek
v4.1.3 (used in crypto/types and crypto/sphinx)ed25519-dalek
v2.1.1 (used in crypto/types)- Other crypto dependencies are also at compatible versions
-
The codebase shows proper integration:
crypto/types/src/seal.rs
implements sealing functionality usingcrypto_box
- The sealed box encryption is used correctly in the session protocol via
SealedHost
enum - Tests verify the sealing functionality
-
The version 0.9.1 is the latest stable release of
crypto_box
and has no known security vulnerabilities
LGTM! The crypto_box dependency and version choice are appropriate.
The dependency is well-integrated with the existing crypto stack and the version is compatible with other cryptographic dependencies in use.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify crypto dependencies compatibility
# Test: Check if there are any other files using potentially conflicting crypto implementations
# Look for any other encryption implementations that might conflict
rg -g '!target/' -g '!*.lock' -i 'crypto_box|sealed|box_seal'
# Check for any dependency conflicts in other Cargo.toml files
fd Cargo.toml --exec grep -l 'crypto_box'
Length of output: 178886
Script:
#!/bin/bash
# Check versions of related crypto dependencies
rg -g 'Cargo.toml' 'crypto|ed25519|curve25519|x25519'
Length of output: 45334
crypto/types/src/lib.rs (3)
1-2
: LGTM: Documentation is clear and follows conventions.
28-28
: LGTM: Consistent prelude re-export.
The seal
module is correctly re-exported in the prelude, maintaining consistency with other modules.
12-14
: LGTM: Module documentation is clear and aligns with PR objectives.
The new seal
module's purpose is well-documented and correctly references the OffchainKeypair
type.
Let's verify the implementation details:
✅ Verification successful
Implementation is well-tested and follows cryptographic best practices
The seal module implementation has been verified and shows:
- Proper randomized encryption using
crypto_box
with secure random number generation - Comprehensive test coverage including:
- Basic seal/unseal functionality
- Security against tampering
- Key mismatch handling
- Fixed test vectors for deterministic verification
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the seal module implementation and its usage
# Expected: Find the implementation and its tests
# Check the seal module implementation
echo "Checking seal module implementation:"
cat crypto/types/src/seal.rs || echo "seal.rs not found"
# Look for test coverage
echo -e "\nChecking test coverage:"
rg -l "mod tests" crypto/types/src/
Length of output: 3606
transport/session/src/errors.rs (1)
28-36
: LGTM! The new error variants are well-defined and follow best practices.
The new variants are:
- Clear and specific in their error cases
- Using idiomatic error propagation with
#[error(transparent)]
- Properly aligned with the session management requirements
common/network-types/Cargo.toml (4)
54-54
: LGTM! Dependencies align with PR objectives.
The new dependencies are well-justified:
validator
: Supports the new allow-list feature for session targetshopr-crypto-types
: Required for the new target field encryption featurehopr-crypto-random
: Supports cryptographic operations
Also applies to: 58-59
82-84
: LGTM! Benchmark configuration is correctly set up.
The benchmark configuration follows the standard criterion setup with harness = false
, which is required for criterion benchmarks.
25-25
: 🧹 Nitpick (assertive)
Clarify the purpose of the empty testing feature.
The new testing
feature is currently empty. Please document its intended use or remove it if not needed immediately. This will help other developers understand when to enable this feature.
✅ Verification successful
Let me gather more information about the testing feature usage.
Let me check the content of the FaultyNetwork types that are gated behind the testing feature.
The testing
feature is used to expose network fault injection utilities for testing
The empty testing
feature in Cargo.toml
is used to conditionally expose FaultyNetwork
and FaultyNetworkConfig
types from the session/utils.rs
module. These types allow simulating network faults during testing by controlling packet loss probability and network mixing. This is a valid use of a feature flag to gate testing utilities.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the testing feature is used in the codebase
# Look for #[cfg(feature = "testing")] attributes
rg -t rust '#\[cfg\(feature\s*=\s*"testing"\)\]'
Length of output: 8652
Script:
#!/bin/bash
# Check the content of the files that use the testing feature
rg -A 5 -B 5 '#\[cfg\(feature\s*=\s*"testing"\)\]' common/network-types/src/
# Also check if there are any test modules or test attributes that might be related
rg -t rust '(?:#\[test\]|mod\s+tests\s*\{)' common/network-types/src/
Length of output: 1808
Script:
#!/bin/bash
# Check the implementation of FaultyNetwork and related types
rg -A 20 'struct FaultyNetwork' common/network-types/src/session/utils.rs
# Also check if there are any docs or comments explaining the testing feature
rg -l '(?i)test' common/network-types/Cargo.toml
cat common/network-types/Cargo.toml
Length of output: 4273
3-3
: Verify if version bump follows semantic versioning.
The version bump from 0.4.0 to 0.5.0 appears justified given the significant protocol changes. However, let's verify if any breaking changes warrant this bump.
transport/session/src/lib.rs (3)
8-17
: LGTM: Module structure aligns with session management objectives.
The new manager
module and its exports (DispatchResult
, SessionManager
, SessionManagerConfig
) provide a clean interface for the enhanced session management functionality described in the PR objectives.
77-78
: LGTM: Target field encryption implementation matches requirements.
The change from IpOrHost
to SealedHost
successfully implements the PR objective of optional target field encryption, with clear documentation explaining its purpose.
39-57
: LGTM: Clean implementation with correct feature mapping.
The implementation correctly maps capabilities to their corresponding session features, particularly for the new RetransmissionAckOnly
and NoDelay
capabilities.
Let's verify the feature mappings are consistent with usage:
✅ Verification successful
Feature mappings are consistent with usage across the codebase
The verification confirms that the IntoIterator
implementation for Capability
correctly aligns with how these features are used throughout the codebase:
Retransmission
maps to all three features (AcknowledgeFrames
,RequestIncompleteFrames
,RetransmitFrames
), matching the default features innetwork-types
RetransmissionAckOnly
maps toAcknowledgeFrames
andRetransmitFrames
, which is consistent with feature checks in the state handlingNoDelay
maps to a single feature that's correctly used in frame egress logic and configuration
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for SessionFeature usage to ensure consistency
rg "SessionFeature::(AcknowledgeFrames|RequestIncompleteFrames|RetransmitFrames|NoDelay)" -A 2
Length of output: 3283
crypto/types/src/seal.rs (2)
1-6
: LGTM! Dependencies are well-organized.
The imports are appropriate for the cryptographic functionality being implemented.
22-29
: Verify secure key handling.
The implementation looks secure, but let's verify the memory handling of sensitive key material.
tests/test_session.py (1)
Line range hint 559-624
: Critical: Incomplete test implementation needs attention.
The test case has several issues that need to be addressed:
- The test contains a TODO placeholder and sleeps for 1 hour instead of implementing actual test logic
- No assertions or verifications are performed
- The hardcoded listen port (60006) could cause conflicts in parallel test runs
- The test doesn't validate the batching functionality despite using Segmentation capability
Consider implementing the test with proper assertions:
- # TODO: Placeholder for actual test
- await asyncio.sleep(3600)
+ # Use a dynamic port instead of hardcoded 60006
+ listen_port = PORT_BASE + random.randint(1, 1000)
+ listen_addr = f"127.0.0.1:{listen_port}"
+
+ src_sock_port = await src_peer.api.session_client(
+ dest_peer.peer_id,
+ path={"IntermediatePath": path},
+ protocol='udp',
+ target=wireguard_tunnel,
+ listen_on=listen_addr,
+ capabilities=['Segmentation']
+ )
+
+ # Verify session establishment
+ assert src_sock_port is not None, "Failed to open session"
+ assert len(await src_peer.api.session_list_clients('udp')) == 1
+
+ # Test batching functionality
+ # 1. Send multiple small packets that should be batched
+ # 2. Verify they are received correctly
+ # 3. Verify batching occurred using metrics or logs
+ # Add appropriate assertions here
To verify the batching functionality is working as expected, we can analyze the logs:
transport/session/src/types.rs (6)
4-4
: LGTM!
The import changes align with the PR objectives, particularly the addition of SealedHost
which supports the new encrypted target field feature.
Also applies to: 11-11
125-125
: LGTM!
The replacement of IpOrHost
with SealedHost
in SessionTarget
variants implements the optional encryption for the Session's target field, as specified in issue #6561.
Also applies to: 127-127
311-311
: LGTM!
The addition of the closed
field and its usage in poll_write
properly implements session state management, preventing writes to closed sessions.
Also applies to: 332-332, 347-350
293-295
:
Ensure proper shutdown sequence in poll_shutdown
.
The current implementation directly calls poll_close
without flushing pending writes. This could lead to data loss.
- futures::AsyncWrite::poll_close(self.as_mut(), cx)
+ match futures::AsyncWrite::poll_flush(self.as_mut(), cx) {
+ Poll::Ready(Ok(())) => futures::AsyncWrite::poll_close(self.as_mut(), cx),
+ Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
+ Poll::Pending => Poll::Pending,
+ }
Likely invalid or redundant comment.
269-280
:
Fix potential memory safety issue in poll_read
.
The use of initialize_unfilled()
is unsafe and should be replaced with unfilled_mut()
for better safety guarantees.
- let slice = buf.initialize_unfilled();
+ let slice = buf.unfilled_mut();
Likely invalid or redundant comment.
164-180
: Verify the flattening of capabilities.
The code attempts to flatten capabilities, but it's unclear if Capability
implements IntoIterator
. This could lead to compilation errors if Capability
is not iterable.
✅ Verification successful
Flattening of capabilities is correctly implemented
The code is safe as Capability
properly implements IntoIterator
with SessionFeature
as the item type. The implementation correctly handles all enum variants by returning appropriate vectors of features that are then flattened. The flattening operation in the original code will work as expected.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if Capability implements IntoIterator
ast-grep --pattern 'impl IntoIterator for Capability'
# Also check the definition of Capability
ast-grep --pattern 'enum Capability'
Length of output: 1586
transport/api/src/lib.rs (3)
Line range hint 99-123
: Consider keeping Prometheus metrics
The commented-out Prometheus metrics are valuable for monitoring session-related operations. Consider keeping these metrics to maintain observability of:
- Active sessions count
- Established/initiated sessions
- Session errors (received/sent)
#!/bin/bash
# Check if metrics are used elsewhere
rg "METRIC_ACTIVE_SESSIONS|METRIC_NUM_ESTABLISHED_SESSIONS|METRIC_NUM_INITIATED_SESSIONS|METRIC_RECEIVED_SESSION_ERRS|METRIC_SENT_SESSION_ERRS"
412-420
:
Replace expect() with proper error handling
Using expect()
could cause a panic in production. Consider proper error handling:
- .expect("failed to start session manager")
+ .map_err(|e| {
+ error!("Failed to start session manager: {}", e);
+ HoprTransportError::Api(format!("Session manager startup failed: {}", e))
+ })?
Likely invalid or redundant comment.
202-204
: 🧹 Nitpick (assertive)
Verify performance impact of PeerId conversion
The comment claims that converting OffchainPublicKey
to PeerId
is expensive. Let's verify this claim and consider if caching is truly necessary.
✅ Verification successful
Let me gather more information about the PeerId conversion to verify the performance claim.
Based on the search results, I can now provide a final response since I have sufficient information about PeerId conversion:
PeerId caching is justified for performance optimization
The caching of PeerId is indeed justified based on the following evidence:
-
The conversion from OffchainPublicKey to PeerId involves multiple steps:
- Converting the OffchainPublicKey bytes to ed25519::PublicKey
- Converting ed25519::PublicKey to libp2p PublicKey
- Generating a multihash from the public key
- Creating PeerId from the multihash
-
The implementation in
crypto/types/src/types.rs
shows this conversion chain:
impl From<OffchainPublicKey> for PeerId {
fn from(value: OffchainPublicKey) -> Self {
let k = libp2p_identity::ed25519::PublicKey::try_from_bytes(value.0.as_bytes()).unwrap();
PeerId::from_public_key(&k.into())
}
}
- The presence of benchmarks in
libp2p-identity
crate (benches/peer_id.rs
) indicates that PeerId operations are performance-sensitive enough to warrant benchmarking.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other PeerId conversions to understand the impact
ast-grep --pattern 'impl From<$_> for PeerId {'
Length of output: 2460
Script:
#!/bin/bash
# Search for PeerId conversion implementations and usages
rg -A 5 "impl.*From.*PeerId|Into.*PeerId|to_peer_id"
# Search for any benchmarks or tests related to PeerId conversion
rg -A 5 "bench.*peer_id|test.*peer_id"
Length of output: 25207
common/network-types/benches/session.rs (6)
1-7
: Imports are appropriately structured and utilized
All imported crates and modules are necessary and properly organized, contributing to the clarity and maintainability of the code.
8-9
: Compile-time feature check ensures necessary testing features
The use of compile_error!
with the #[cfg(not(feature = "testing"))]
attribute guarantees that the 'testing' feature is enabled during compilation, preventing potential build issues.
14-14
: MTU
constant is defined with clear context
The MTU
constant is set to 466
, and the comment provides context by referencing its basis in HOPR 2.2, enhancing code readability.
16-27
: setup_network
function correctly initializes session sockets
The setup_network
function effectively creates session sockets for both participants using the FaultyNetwork
. Cloning of session_cfg
is appropriate here to ensure each socket has its configuration.
29-41
: Data transmission in send_one_way
is handled correctly
The asynchronous function send_one_way
successfully writes data from Alice to Bob and performs necessary cleanup by closing the sockets. Error handling is properly managed using anyhow::Result
.
43-70
: Benchmark function is well-structured and efficient
The session_one_way_reliable_send_recv_benchmark
function sets up the benchmark group appropriately, with a reasonable sample size and specified throughput. Initialization of the Tokio runtime outside the loop optimizes performance.
common/network-types/src/types.rs (1)
163-283
: Implementation of SealedHost
is well-structured and documented
The introduction of the SealedHost
enum and its associated methods seal
and unseal
are well-implemented. The documentation is thorough, providing clear guidance on usage and examples.
common/network-types/src/session/state.rs (4)
139-150
: The addition of 'NoDelay' feature is well-implemented
The introduction of the NoDelay
feature in the SessionFeature
enum, along with its integration into the default features and configuration, is clear and logical. This enhancement effectively allows for the optional disabling of small frame buffering, aligning with the PR objectives to make session behaviors more configurable.
Line range hint 160-234
: Validation for SessionConfig
parameters enhances robustness
The added validation checks for acknowledged_frames_buffer
, backoff_base
, and rto_jitter
ensure that these configuration parameters are within valid ranges. This proactive validation improves the robustness of the session management by preventing misconfigurations that could lead to runtime errors.
701-703
: Code comments appropriately explain the select_biased!
ordering
The added comments effectively explain the ordering of futures in the select_biased!
macro, ensuring that less frequent events are not starved by more frequent ones. This aids in code maintainability and understanding.
1027-1029
: 🧹 Nitpick (assertive)
Correct logging message to refer to 'socket writer' instead of 'socket reader'
In the poll_close
method, the logging message should be updated to "polling close on socket writer inside session" to correctly describe the action.
Apply this diff to correct the logging message:
- "polling close on socket reader inside session"
+ "polling close on socket writer inside session"
Likely invalid or redundant comment.
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.
Actionable comments posted: 28
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
⛔ Files ignored due to path filters (1)
Cargo.lock
is excluded by!**/*.lock
📒 Files selected for processing (22)
Cargo.toml
(1 hunks)README.md
(1 hunks)common/network-types/Cargo.toml
(5 hunks)common/network-types/benches/session.rs
(1 hunks)common/network-types/src/session/protocol.rs
(7 hunks)common/network-types/src/session/state.rs
(32 hunks)common/network-types/src/types.rs
(5 hunks)crypto/types/Cargo.toml
(1 hunks)crypto/types/src/lib.rs
(2 hunks)crypto/types/src/seal.rs
(1 hunks)hoprd/hoprd/Cargo.toml
(1 hunks)hoprd/hoprd/src/main.rs
(2 hunks)hoprd/rest-api/src/lib.rs
(3 hunks)tests/hopr.py
(4 hunks)tests/requirements.txt
(1 hunks)tests/test_session.py
(1 hunks)transport/api/src/lib.rs
(16 hunks)transport/session/Cargo.toml
(3 hunks)transport/session/src/errors.rs
(1 hunks)transport/session/src/lib.rs
(2 hunks)transport/session/src/manager.rs
(1 hunks)transport/session/src/types.rs
(11 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~210-~210: Possible missing comma found.
Context: ...out any command-line argument might not work depending on the installation method us...
(AI_HYDRA_LEO_MISSING_COMMA)
🪛 Ruff
tests/hopr.py
462-462: Line too long (141 > 120)
(E501)
482-482: Line too long (122 > 120)
(E501)
🔇 Additional comments (49)
tests/requirements.txt (1)
Line range hint 1-15
: LGTM! Well-organized requirements file.
The requirements file maintains good practices:
- Dependencies are alphabetically ordered
- Versions are strictly pinned
- Local package reference is at the end
crypto/types/Cargo.toml (1)
10-10
: LGTM! Verify security advisories for crypto_box.
The addition of crypto_box
with the seal
feature aligns well with the PR objective of implementing optional encryption for the Session's target field. The version is appropriately pinned for reproducibility.
Let's verify the security track record of this dependency:
crypto/types/src/lib.rs (4)
1-1
: LGTM! Documentation improvement.
The grammatical correction improves clarity.
15-18
: LGTM! Enhanced documentation clarity.
The documentation now provides better context by explicitly mentioning the relationship with primitives and including specific examples of implemented types.
28-28
: LGTM! Consistent prelude export.
The new seal module is properly exported via prelude, consistent with other module exports.
12-14
: Verify cryptographic implementation usage.
The new sealing module aligns with the PR objective to encrypt Session target fields. Since this is cryptographic code, let's verify its usage to ensure proper implementation.
✅ Verification successful
Based on the search results, I can now generate the final response since I have sufficient information about the sealing implementation and its usage:
Cryptographic implementation verified and properly tested
The sealing module shows a secure implementation with:
- Proper use of
crypto_box
for public key encryption - Comprehensive test coverage including:
- Basic encryption/decryption flow
- Cross-key decryption attempts (security test)
- Tamper detection
- Real-world usage scenarios
The functionality is also correctly integrated in network-types
crate for sealing host information.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of sealing functionality to ensure proper implementation
# Test 1: Find all uses of seal_data/unseal_data functions
echo "=== Searching for seal_data/unseal_data usage ==="
rg -A 5 "seal_data|unseal_data"
# Test 2: Check for potential test files to ensure the functionality is tested
echo -e "\n=== Searching for seal module tests ==="
fd -g "*seal*test*.rs"
Length of output: 13014
transport/session/src/errors.rs (2)
28-29
: LGTM! Clear and specific error variant.
The UnknownData
variant is well-defined with a clear error message that precisely describes the error condition.
34-35
: LGTM! Appropriate error propagation.
The transparent error propagation from network types is well-implemented and maintains type safety.
transport/session/Cargo.toml (4)
3-3
: Version bump aligns with significant feature additions.
The version increment from 0.2.0 to 0.3.0 appropriately reflects the substantial new features being added (batching, configurable retries, allow-lists, target encryption).
38-38
: Dependencies align with PR objectives.
The new dependencies support the PR's objectives:
moka
: Efficient caching for session managementsmart-default
: Enables configurable defaults for retry strategies and port rangeshopr-async-runtime
: Supports async operations for session management
Also applies to: 42-42, 49-49
63-63
: Test logging enhancement.
The addition of test-log
as a dev-dependency will improve debugging and observability during testing, which is valuable given the complex session management features being added.
Line range hint 1-64
: Verify dependency usage across the codebase.
Let's verify that the new dependencies are being utilized effectively across the codebase.
✅ Verification successful
Based on the shell script results, I can now generate the final response:
Dependencies are being used effectively across the codebase
The verification shows active usage of the dependencies:
moka
: Used in transport/session for session management with proper cache handling and removal notificationssmart-default
: Extensively used across multiple components for configuration structs with proper default valueshopr-async-runtime
: Widely used across the codebase for async operations, timeouts, spawning tasks and handling joins
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of new dependencies
# Test 1: Check moka usage
echo "Checking moka usage..."
rg --type rust "use.*moka" -A 5
# Test 2: Check smart-default usage
echo "Checking smart-default usage..."
rg --type rust "#\[derive\(.*SmartDefault.*\)\]" -A 5
# Test 3: Check hopr-async-runtime usage
echo "Checking hopr-async-runtime usage..."
rg --type rust "use.*hopr_async_runtime" -A 5
Length of output: 75806
common/network-types/Cargo.toml (4)
54-54
: Dependencies align with PR objectives.
The new dependencies support the PR objectives:
validator
: Will be used for input validationhopr-crypto-types
: Required for the target field encryption feature mentioned in issue #6561
Also applies to: 59-59
68-68
: Benchmark configuration looks good.
The addition of criterion
and the benchmark configuration aligns with the PR objective to include benchmarks for the Session protocol.
Also applies to: 82-84
3-3
: Verify if breaking changes warrant a minor version bump.
The version has been incremented from 0.4.0 to 0.5.0. According to semver, this indicates potentially breaking changes.
#!/bin/bash
# Description: Check for breaking changes in public API
# Test 1: Look for changes in public types and functions
ast-grep --pattern 'pub $$$'
# Test 2: Look for changes in trait implementations
ast-grep --pattern 'impl $_ for $_'
25-25
: Verify the usage of the new testing feature.
The empty testing
feature has been added. This should be used for conditional compilation of test utilities.
✅ Verification successful
The testing
feature is properly used for test utilities
The testing
feature is correctly used to expose test utilities FaultyNetwork
and FaultyNetworkConfig
which are specifically designed for testing network conditions. These utilities allow:
- Simulating network faults with configurable packet drop probability
- Testing packet reordering through mixing factor configuration
- Collecting network statistics for test verification
- Controlled RNG seeding for reproducible tests
The implementation is well-tested and the feature flag appropriately gates test-only functionality.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of testing feature flag
# Test: Look for cfg(feature = "testing") attributes
rg '#\[cfg\(feature = "testing"\)\]'
Length of output: 148154
Script:
#!/bin/bash
# Look for cfg(feature = "testing") attributes in Rust files
rg -t rust 'cfg\(feature\s*=\s*"testing"\)'
# Look for #[test] attributes to understand test usage
rg -t rust '#\[test\]' common/network-types/
Length of output: 1419
Script:
#!/bin/bash
# Look at the content of the file where testing feature is used
rg -A 5 -B 5 'cfg\(feature\s*=\s*"testing"\)' common/network-types/src/session/mod.rs
Length of output: 278
Script:
#!/bin/bash
# Look at the content of the testing utilities
rg -l "FaultyNetwork" common/network-types/src/
cat common/network-types/src/session/utils.rs
Length of output: 12782
transport/session/src/lib.rs (3)
8-8
: LGTM: Module structure aligns with session management enhancements
The addition of the manager
module and its public exports follows good Rust module organization practices and aligns with the PR's objective of implementing configurable session management.
Also applies to: 12-12
77-78
: Verify impact of SealedHost type change
The change to use SealedHost
aligns with the PR's objective of implementing optional target encryption. However, this is a breaking change that needs verification:
#!/bin/bash
# Description: Verify the impact of changing target type from IpOrHost to SealedHost
# Find all direct usages of SessionClientConfig
echo "Direct SessionClientConfig usage:"
rg "SessionClientConfig" --type rust -B 2 -A 2
# Find all uses of the target field
echo "\nTarget field access:"
rg "\.target\s*[:=]" --type rust -B 2 -A 2
# Find test files that might need updates
echo "\nRelevant test files:"
fd "test.*\.rs$"
39-57
: LGTM: Feature mapping implementation is correct
The implementation correctly maps capabilities to their corresponding session features. Let's verify the completeness of the mapping:
✅ Verification successful
Let me gather more information about the SessionFeature enum and its usage.
Let me search for the complete enum definition since it was truncated in the previous output.
Let me try one more search to find the SessionFeature enum definition since it wasn't found in the previous searches.
LGTM: Feature mapping implementation is complete and correct
The implementation correctly maps each capability to its corresponding session features:
Capability::Segmentation
→[]
(no features)Capability::Retransmission
→[AcknowledgeFrames, RequestIncompleteFrames, RetransmitFrames]
Capability::RetransmissionAckOnly
→[AcknowledgeFrames, RetransmitFrames]
Capability::NoDelay
→[NoDelay]
The mapping aligns perfectly with the documented purpose of each feature:
RequestIncompleteFrames
: Enables NACK-based retransmissionRetransmitFrames
: Enables ACK-based retransmissionAcknowledgeFrames
: Required for both retransmission typesNoDelay
: Disables frame buffering
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all SessionFeature variants are used in the mapping
# and that the mapping aligns with capability descriptions
# Search for SessionFeature enum definition
echo "SessionFeature variants:"
rg "enum SessionFeature" -A 10
# Search for usage of SessionFeature in tests
echo "\nFeature usage in tests:"
rg "SessionFeature::" --type rust
Length of output: 53277
Script:
#!/bin/bash
# Search for SessionFeature enum definition and its usage
echo "SessionFeature enum definition:"
rg "enum SessionFeature" -A 10 transport/session/src/lib.rs
echo "\nSessionFeature usage in code:"
rg "SessionFeature::" -A 2 transport/session/src/lib.rs
Length of output: 688
Script:
#!/bin/bash
# Search for complete SessionFeature enum definition with more context
echo "Complete SessionFeature enum definition:"
rg -B 5 -A 15 "enum SessionFeature" transport/session/src/lib.rs
# Search for Capability enum definition to understand the mapping
echo "\nCapability enum definition:"
rg -B 5 -A 10 "enum Capability" transport/session/src/lib.rs
Length of output: 758
Script:
#!/bin/bash
# Try to find SessionFeature enum definition in other files
echo "Searching for SessionFeature enum in all Rust files:"
rg -t rust "pub enum SessionFeature" -B 5 -A 10
# Also search for any documentation or comments about SessionFeature
echo "\nSearching for SessionFeature documentation:"
rg -t rust "SessionFeature" -B 3 -A 3
Length of output: 10149
hoprd/hoprd/Cargo.toml (1)
72-72
: LGTM! Dependencies align with PR objectives.
The addition of serde_with
and smart-default
as workspace dependencies is appropriate for implementing the new configurable features. These dependencies will help with:
- Complex serialization needs for the new configuration options
- Default value implementations for the configurable retry strategy and port ranges
Also applies to: 76-76
hoprd/rest-api/src/lib.rs (3)
55-56
: LGTM!
The imports are well-organized and follow Rust's conventions.
71-72
: Verify the migration of existing sessions.
The type change from String
to SessionTargetSpec
supports the new target encryption feature. However, we should verify the migration strategy for existing sessions.
Let's check for any existing sessions that might be affected:
#!/bin/bash
# Description: Check for existing sessions and their target types
# Expected: No instances of the old String type for targets
# Search for session-related code that might still use String type for targets
rg -l "String.*target" | while read -r file; do
echo "=== $file ==="
rg "String.*target" "$file"
done
# Search for session initialization code to verify proper type usage
ast-grep --pattern 'SessionTargetSpec::$_($$$)'
Line range hint 1-400
: Verify implementation of remaining PR objectives.
While the changes in this file support port range configuration and target encryption, please verify if additional changes are needed for:
- Batching of network segments
- Retry strategy configuration
- Allow-list feature for Exit nodes
Let's check for these features:
hoprd/hoprd/src/main.rs (1)
29-29
: LGTM! Module organization improvement.
The import change reflects a better organization by moving the HoprServerIpForwardingReactor
to a dedicated exit
module, which aligns with the Exit node enhancements mentioned in the PR objectives.
README.md (2)
212-212
: LGTM!
The grammar has been improved for better readability.
206-206
: 🛠️ Refactor suggestion
Enhance documentation for Session port range configuration
The documentation for HOPRD_SESSION_PORT_RANGE
should be expanded to align with the Session protocol enhancements introduced in this PR. Consider adding:
- Clear format specification and valid port ranges
- Connection to Session protocol batching feature
- Default behavior
- Use cases and benefits
Apply this diff to enhance the documentation:
- - `HOPRD_SESSION_PORT_RANGE` - allows restricting the port range (syntax: `start:end` inclusive) of Session listener automatic port selection (when port 0 is specified).
+ - `HOPRD_SESSION_PORT_RANGE` - Restricts the port range for Session listener's automatic port selection.
+ - Format: "start:end" (inclusive), e.g., "1024:65535"
+ - Only applies when port 0 is specified for automatic port selection
+ - Supports the Session protocol's network segment batching feature
+ - Useful in containerized environments (e.g., Kubernetes) to ensure ports align with allowed ranges
+ - Default: Uses full valid port range when not specified
Likely invalid or redundant comment.
tests/test_session.py (2)
460-460
: LGTM! The sealed target parameter is correctly implemented.
The addition of sealed_target=True
aligns with the PR objective of enabling optional encryption for the target field.
Line range hint 1-600
: Additional test coverage needed for new features.
While the test file has comprehensive coverage for basic Session protocol functionality, it's missing test cases for several new features introduced in this PR:
- Batching of network segments
- Configurable retry strategy
- Allow-list for Exit nodes
- Different combinations of sealed/plain targets
Consider adding the following test cases:
- Test batching with various payload sizes
- Test retry strategy with different configurations
- Test allow-list functionality for Exit nodes
- Test both sealed and plain target scenarios
transport/api/src/lib.rs (3)
Line range hint 1-758
: Verify implementation of network segment batching.
The PR objectives mention batching of smaller Session packets into larger packets (issue #6530), but the implementation is not visible in this file. Please verify that the batching functionality is implemented in the appropriate location.
651-658
: 🧹 Nitpick (assertive)
Consider using unwrap_or_else
for more concise error handling.
The error handling could be simplified while maintaining the same functionality:
- .get(&self.me_peerid)
- .await
- .unwrap_or_else(|e| {
- error!(error = %e, "failed to obtain listening multi-addresses");
- None
- })
- .map(|peer| peer.multiaddresses)
- .unwrap_or_default()
+ .get(&self.me_peerid)
+ .await
+ .unwrap_or_else(|e| {
+ error!(error = %e, "failed to obtain listening multi-addresses");
+ None
+ })
+ .map_or_else(Vec::new, |peer| peer.multiaddresses)
Likely invalid or redundant comment.
412-420
: 🛠️ Refactor suggestion
Improve error handling in session manager startup.
Replace expect()
with proper error handling to provide more graceful failure recovery and propagate the error up the call stack.
- .expect("failed to start session manager")
+ .map_err(|e| {
+ error!("Failed to start session manager: {}", e);
+ HoprTransportError::Api(format!("Session manager startup failed: {}", e))
+ })?
Likely invalid or redundant comment.
crypto/types/src/seal.rs (4)
9-17
: LGTM: seal_data
function implementation
The seal_data
function correctly performs randomized encryption using the recipient's public key. The implementation is clear, and error handling is appropriately managed.
22-29
: LGTM: unseal_data
function implementation
The unseal_data
function correctly decrypts data using the recipient's secret key. Error handling is consistent with best practices.
23-23
: Verify the correctness of keypair conversion to crypto_box::SecretKey
Ensure that converting OffchainKeypair
to crypto_box::SecretKey
using curve25519_dalek::scalar::Scalar::from(keypair)
is accurate and secure. Incorrect conversion might lead to decryption issues or compromise key integrity.
Run the following script to check the consistency of keypair conversions:
#!/bin/bash
# Description: Verify how `OffchainKeypair` is converted to `Scalar` and then to `SecretKey`.
# Test: Search for instances of `Scalar::from(keypair)` conversions.
# Expect: Correct and consistent conversion methods.
rg -A 3 'curve25519_dalek::scalar::Scalar::from\(\s*keypair\s*\)'
11-11
: Verify the correctness of public key conversion from PeerId
to crypto_box::PublicKey
Ensure that the conversion from PeerId
to crypto_box::PublicKey
via OffchainPublicKey::try_from(peer_id)
and curve25519_dalek::MontgomeryPoint::from(...)
is correct and adheres to the cryptographic standards. An incorrect conversion may lead to encryption failures or security vulnerabilities.
Run the following script to verify the usage and consistency of public key conversions:
✅ Verification successful
Conversion from PeerId to crypto_box::PublicKey is cryptographically sound
The conversion chain is correct and secure:
PeerId
->OffchainPublicKey
: Properly extracts Ed25519 public key from PeerId's protobuf encodingOffchainPublicKey
->MontgomeryPoint
: Correctly decompresses Edwards point and converts to Montgomery formMontgomeryPoint
->crypto_box::PublicKey
: Standard conversion for X25519 key exchange
The implementation follows the cryptographic standards for converting between Ed25519 and X25519 keys, maintaining the security properties required for sealed box encryption.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify instances where `PeerId` is converted to `OffchainPublicKey` and then to `crypto_box::PublicKey`.
# Test: Search for conversions from `PeerId` to `OffchainPublicKey::try_from(peer_id)`.
# Expect: Consistent usage across the codebase.
rg -A 3 'OffchainPublicKey::try_from\(\s*peer_id\s*\)'
Length of output: 402
Script:
#!/bin/bash
# Let's try a broader search for OffchainPublicKey usage and PeerId conversions
# Search for OffchainPublicKey usage
echo "=== OffchainPublicKey usage ==="
rg -l "OffchainPublicKey"
# Search for implementations and type definitions
echo -e "\n=== OffchainPublicKey implementation ==="
ast-grep --pattern 'impl $_ for OffchainPublicKey { $$ }'
# Search for PeerId conversions
echo -e "\n=== PeerId conversions ==="
rg "try_from.*PeerId" -A 3
# Search for curve25519_dalek::MontgomeryPoint usage
echo -e "\n=== MontgomeryPoint usage ==="
rg "MontgomeryPoint::from" -A 2
Length of output: 1171
Script:
#!/bin/bash
# Let's examine the implementation details in crypto/types
# Check the OffchainPublicKey type definition and implementations
echo "=== OffchainPublicKey definition and implementations ==="
rg -A 10 "struct OffchainPublicKey" crypto/types/src/types.rs
rg -A 10 "impl.*OffchainPublicKey" crypto/types/src/types.rs
# Check the conversion implementations
echo -e "\n=== Conversion implementations ==="
rg -A 10 "impl.*TryFrom.*PeerId.*for.*OffchainPublicKey" crypto/types/src/types.rs
# Check the seal implementation where the conversion is used
echo -e "\n=== Seal implementation ==="
rg -A 10 "pub fn seal" crypto/types/src/seal.rs
Length of output: 5136
common/network-types/src/types.rs (3)
237-239
: Preserve original error context when mapping errors
The errors in the seal
and unseal
methods are currently mapped to NetworkTypeError::Other(e.to_string())
, which loses valuable error information. This issue was previously raised and remains unaddressed. Please consider wrapping the original errors or defining specific error variants in NetworkTypeError
to preserve the error context and improve error handling.
Also applies to: 247-252
216-256
: Review conditional compilation attributes
Ensure that the #[cfg_attr(feature = "serde", ...)]
attributes are correctly applied. The methods seal
and unseal
might not rely on serde
, but the serialization of IpOrHost
may. Confirm that the conditional compilation accurately reflects the dependencies to prevent compilation issues when certain features are disabled.
Consider adjusting the attributes if necessary to ensure methods are available under the correct feature flags.
275-281
: Ensure consistent redaction in Display
implementation
The Display
implementation for SealedHost
displays <redacted host>
for sealed hosts. Verify that this approach doesn't leak any information about the sealed data. Also, consider if additional logging or debugging might inadvertently reveal sensitive information and ensure that all outputs are appropriately sanitized.
You can run the following script to search for potential logging of sealed data:
✅ Verification successful
Redaction implementation is secure and consistent
The verification shows that SealedHost
has proper safeguards against information leakage:
- The
Display
implementation consistently redacts sealed data with<redacted host>
- The
Debug
implementation is derived safely with#[derive(Debug)]
- The
TryFrom<SealedHost>
implementation properly prevents access to sealed data by returning an error - No direct logging of
SealedHost
instances was found in the codebase - The documentation explicitly states that "Sealing is fully randomized and therefore does not leak information"
The implementation correctly handles sensitive data by:
- Using opaque error types instead of exposing internal details
- Consistently redacting sealed content in string representations
- Preventing unauthorized access to sealed data through type system constraints
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for logging statements that might expose sealed hosts.
# Test: Find occurrences where SealedHost is logged.
# Expect: No instances where SealedHost::Sealed variants are directly logged.
rg --type rust 'log::.*\bSealedHost\b' -A 2
Length of output: 45
Script:
#!/bin/bash
# Let's do a comprehensive check for potential information leaks:
# 1. Find all usages of SealedHost in the codebase
rg --type rust '\bSealedHost\b' -B 2 -A 2
# 2. Check for Debug implementation
ast-grep --pattern 'impl Debug for SealedHost'
# 3. Check for any other trait implementations that might expose data
ast-grep --pattern 'impl $_ for SealedHost'
# 4. Look for any direct field access or pattern matching
rg --type rust 'SealedHost::Sealed\(' -B 2 -A 2
Length of output: 13553
tests/hopr.py (1)
Line range hint 462-482
: Enhancement to session_client
Function is Well-Implemented.
The addition of the sealed_target
parameter and the conditional handling of actual_target
correctly implement the optional encryption of the target field.
🧰 Tools
🪛 Ruff
482-482: Line too long (122 > 120)
(E501)
transport/session/src/types.rs (2)
269-296
: Ensure correct implementation of tokio::io::AsyncRead
and tokio::io::AsyncWrite
traits
The implementations for tokio::io::AsyncRead
and tokio::io::AsyncWrite
for the Session
struct look appropriate. However, please verify that the use of buf.initialize_unfilled()
in the poll_read
method aligns with the safety requirements of the Tokio version you are using.
If buf.initialize_unfilled()
is considered unsafe in your Tokio version, consider using buf.unfilled_mut()
instead. Here's how you might adjust the code:
- let slice = buf.initialize_unfilled();
+ let slice = buf.initialize_unfilled(); // Ensure this usage is safe in your Tokio version
If unsafe, modify as:
- let slice = buf.initialize_unfilled();
+ let slice = buf.unfilled_mut();
Please confirm and update accordingly to maintain safety and prevent potential undefined behavior.
125-127
: Verify all usages of SessionTarget
variants after changing to SealedHost
The SessionTarget
enum now uses SealedHost
instead of IpOrHost
for UdpStream
and TcpStream
. Please ensure that all instantiations and pattern matches of SessionTarget::UdpStream
and SessionTarget::TcpStream
throughout the codebase are updated accordingly to prevent type mismatches or pattern matching errors.
Consider running the following script to find all usages:
✅ Verification successful
Let me analyze the code further to verify the types being used in these matches.
Let me check one more thing to verify the pattern matches and type usage in the manager.rs file.
All usages of SessionTarget
variants are correctly using SealedHost
After analyzing the codebase:
- All constructors in
transport/session/src/initiation.rs
andtransport/session/src/manager.rs
correctly useSealedHost
- Pattern matches in
hoprd/hoprd/src/exit.rs
andtransport/session/src/manager.rs
correctly handle theSealedHost
type - The type definition in
transport/session/src/types.rs
properly declares both variants withSealedHost
No type mismatches or pattern matching errors were found in the codebase.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find all usages of 'SessionTarget::UdpStream' and 'SessionTarget::TcpStream' in the codebase.
# Expected: All usages should have been updated to use 'SealedHost' as the parameter.
# Search for patterns where 'UdpStream' or 'TcpStream' are used with parentheses (i.e., being constructed or matched).
rg 'SessionTarget::(UdpStream|TcpStream)\s*\('
Length of output: 924
Script:
#!/bin/bash
# Let's check the actual type declarations and pattern matches in these files
rg -A 3 'SealedHost' transport/session/src/types.rs
rg -A 3 'target:' hoprd/hoprd/src/exit.rs
Length of output: 925
Script:
#!/bin/bash
# Check the context around the matches in manager.rs to verify type usage
rg -B 2 -A 2 'SessionTarget::(UdpStream|TcpStream)' transport/session/src/manager.rs
Length of output: 885
common/network-types/src/session/protocol.rs (1)
475-483
: Good addition of tests for protocol constants
The test function ensure_session_protocol_version_1_values
effectively ensures that critical constants remain accurate, aiding in maintaining protocol integrity.
common/network-types/src/session/state.rs (7)
139-140
: Addition of NoDelay
feature to SessionFeature
The introduction of the NoDelay
feature allows disabling small frame buffering, providing flexibility in session configuration.
144-150
: Well-documented default features excluding NoDelay
The documentation for default_features()
now clearly explains which features are included by default and notes the exclusion of NoDelay
, improving code clarity.
178-178
: Added validation for minimum value of acknowledged_frames_buffer
Validation ensures that acknowledged_frames_buffer
cannot be less than 1, preventing potential runtime errors.
228-228
: Added maximum value validation for rto_jitter
Validation now ensures that rto_jitter
remains between 0.0 and 0.25, as specified in the documentation, maintaining proper jitter behavior.
525-525
: Updated comment for clarity in retransmission logic
The comment now accurately describes the logic for retaining non-expired frames and collecting those due for resend, improving code readability.
931-935
: Buffer capacity adjustment based on NoDelay
feature
Setting the buffer capacity to C
when buffering is enabled and to 0
when NoDelay
is enabled is a valid approach to control buffering behavior.
1004-1004
: Correct use of MAX_WRITE_SIZE
in send_frame_data
The use of Self::MAX_WRITE_SIZE
to validate the data length ensures that writes do not exceed the maximum allowed frame size, preventing potential issues.
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.
Actionable comments posted: 1
🧹 Outside diff range comments (2)
db/sql/src/channels.rs (1)
Line range hint
183-213
: Consider adding batch retrieval optimization forget_channels_via
The current implementation fetches channels one by one. Consider adding a batch retrieval option for cases where multiple channels need to be fetched, which aligns with the PR's objective of optimizing network segment batching.
async fn get_channels_via<'a>( &'a self, tx: OptTx<'a>, direction: ChannelDirection, target: &Address, + batch_size: Option<usize>, ) -> Result<Vec<ChannelEntry>> { let target_hex = target.to_hex(); self.nest_transaction(tx) .await? .perform(|tx| { Box::pin(async move { - Channel::find() + let mut query = Channel::find() .filter(match direction { ChannelDirection::Incoming => channel::Column::Destination.eq(target_hex), ChannelDirection::Outgoing => channel::Column::Source.eq(target_hex), - }) - .all(tx.as_ref()) - .await? - .into_iter() + }); + if let Some(size) = batch_size { + query = query.limit(size as u64); + } + query.all(tx.as_ref()) + .await? + .into_iter() .map(|x| ChannelEntry::try_from(x).map_err(DbSqlError::from)) .collect::<Result<Vec<_>>>() }) }) .awaitcommon/network-types/src/session/state.rs (1)
Line range hint
610-614
: Inconsistent handling of zero-length writes betweenpoll_write
andsend_frame_data
In the
poll_write
method, zero-length writes are handled by returningOk(0)
early whenlen_to_write == 0
. However,send_frame_data
returns an error ifdata.len()
is zero due to the range check. This inconsistency may cause issues ifsend_frame_data
is called elsewhere with zero-length data. Consider updatingsend_frame_data
to handle zero-length data appropriately.Apply this diff to allow zero-length data in
send_frame_data
:pub async fn send_frame_data(&mut self, data: &[u8]) -> crate::errors::Result<()> { - if !(1..=Self::MAX_WRITE_SIZE).contains(&data.len()) { + if data.len() > Self::MAX_WRITE_SIZE { return Err(SessionError::IncorrectMessageLength.into()); + } + if data.is_empty() { + // Nothing to send + return Ok(()); + } // Rest of the function... }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
📒 Files selected for processing (3)
common/network-types/benches/session.rs
(1 hunks)common/network-types/src/session/state.rs
(32 hunks)db/sql/src/channels.rs
(1 hunks)
🔇 Additional comments (6)
db/sql/src/channels.rs (3)
Line range hint 39-42
: LGTM: Well-implemented caching strategy
The caching implementation with proper invalidation in finish_channel_update
ensures data consistency while improving performance. The use_cache
parameter in get_channel_by_parties
provides flexibility when caching is not desired.
Also applies to: 77-81
Line range hint 82-85
: LGTM: Thread-safe transaction handling
The use of nest_transaction
and proper error handling ensures thread-safety and transaction integrity.
Also applies to: 86-90
Line range hint 291-438
: LGTM: Comprehensive test coverage
The test suite is well-structured with:
- Both positive and negative test cases
- Proper transaction handling verification
- Robust error handling
- Randomized test data generation
common/network-types/benches/session.rs (3)
16-27
: setup_network
Function Correctly Initializes Session Sockets
The setup_network
function properly initializes the SessionSocket
instances for both Alice and Bob using the FaultyNetwork
.
29-41
: send_one_way
Function Accurately Performs Data Transmission
The send_one_way
function correctly sends data from Alice to Bob and manages asynchronous reads and writes effectively.
43-69
: Benchmark Function Properly Measures One-Way Reliable Transmission
The session_one_way_reliable_send_recv_benchmark
function effectively benchmarks the performance for various data sizes, correctly setting up the benchmarking group and runtime.
Changes
1. Batching multiple of smaller Session packets into larger packets
As described in #6530 , this feature will be enabled by default.
A new Session feature called
NoDelay
is now supported and allows to explicity turn off the buffering on a Session.2. Configurable retries for Session initiations
As described in #6516, the retry strategy is now configurable in
hopr-lib
.The
hopr-lib
callHopr::connect_to
will now perform multiple retries, as configured inSessionGlobalConfig
when theHopr
object is instantiated.On
hoprd
level, this configuration is propagated into the configuration file and the values are configurable from the newsession
section underhopr
section:3. Configurable target allow list on Session targets to the Exit node
As described in #6575, a configurable allow-list is added to the HOPRd. This configuration is applied when the
node will act as an Exit node. The allow-list matching is done after the DNS resolution takes place (in case the target has been specified via DNS name).
This manifests itself as a new top level section in the
hoprd
configuration file:4. Optional encryption of the Session's
target
field to hide it from the Entry nodeAs described in #6561, this PR adds an optional encryption for
target
field with Exit node's PeerId. This makes sure, that thetarget
field is opaque to the Entry node and it cannot see what is the desired destination of the Session it is about to establish. The encryption is randomized, and therefore the sametarget
will never have identical ciphertexts.However, it should be noted that this does not establish
target
field authenticity between the initiator of the Session and the Exit node. A rogue Entry node can still replace the encryptedtarget
field with any target of its liking.Therefore, the target authenticity shall be established at the application layer protocol routed through Session, e.g. by using TLS or WG.
What does the new Session REST API request looks like?
Due to this change, the
target
field inside the REST API request to open a session (POST /api/v3/session/{protocol}
) at the Entry node is no longer a string.Instead,
target
is a JSON object that can specify two options :"Plain"
or"Sealed"
.When used with
"Plain"
the target is not encrypted and therefore visible to the Entry node, e.g.:"target": {"Plain": "localhost:8080"}"
When used with
"Sealed"
the target contains a Base64 encoded encrypted Session target, e.g.:"target": {"Sealed": "lhuxyMufgH96OnesG2nI0byHAmVQEuNeg4QwdyE6z13Q4k7GhIaBTFoXlCPLlEbxTk9pOIQ0fsC2s1DMmAw="}"
The Client can refer to the
SealedHost
type in thehopr-network-types
crate to see how to encrypt target using Exit node's PeerId.5. Allow to restrict automatic Session listener port selection at the Entry node via an environment variable
As described in #6579, this PR also adds an optional
HOPRD_SESSION_PORT_RANGE
environment variable.The syntax of the variable is
start_port:end_port
, e.g.:HOPRD_SESSION_PORT_RANGE=10000:10100
.When specified along with the
0
port in thelistenHost
argument in thePOST /api/v3/session/{protocol}
REST API call (e.g."listenHost:" "1.2.3.4:0"
), the automatic port selection only tries to pick ports from the specified range. The call fails if no ports in that range are free.If the environment variable is not specified, the automatic port selections picks any free port on the system.
When a non-zero port is specified in
listenHost
, the environment variable has no effect when set.6. Additional refactoring and changes
ConnectedUdpStream
independent of the number of receiversConnectedUdpStream
to multiple network interfacesCloses #6530
Closes #6516
Closes #6515
Closes #6575
Closes #6561
Closes #6579