Skip to content

Conversation

NumberFour8
Copy link
Contributor

@NumberFour8 NumberFour8 commented Nov 7, 2024

Introduced MAX_MESSAGE_SIZE constant in session protocol and added validation for message length. The upper six bits of length are reserved for future use.

Also, replaced magic numbers with constants for timeout and retries in transport configuration.

Introduced `MAX_MESSAGE_SIZE` constant in session protocol and added validation for message length.
The upper six bits are reserved for future use.

Also, replaced magic numbers with constants for timeout and retries in transport configuration.
@NumberFour8 NumberFour8 added this to the 2.2.0-rc.1 milestone Nov 7, 2024
@NumberFour8 NumberFour8 requested a review from a team November 7, 2024 08:52
@NumberFour8 NumberFour8 self-assigned this Nov 7, 2024
Copy link
Contributor

coderabbitai bot commented Nov 7, 2024

📝 Walkthrough
📝 Walkthrough
## Walkthrough
The changes introduced in this pull request enhance the `SessionMessage` protocol and session configuration management. A new constant `MAX_MESSAGE_SIZE` is added to the `SessionMessage` struct, along with improved error handling in the `try_next` method. In the session configuration file, several constants related to session management are defined and integrated into the `SessionGlobalConfig` struct, replacing hardcoded values. Additionally, the `Segment` struct's maximum size constraint is removed, allowing for more flexible segment sizes. These modifications aim to improve the integrity and maintainability of the protocol without altering its core functionality.

## Changes

| File Path                                    | Change Summary                                                                                   |
|----------------------------------------------|-------------------------------------------------------------------------------------------------|
| common/network-types/src/session/protocol.rs | - Added constant `pub const MAX_MESSAGE_SIZE: usize` in `SessionMessage`. <br> - Updated `try_next` method in `SessionMessageIter` to include checks for message length and reserved bits. <br> - Enhanced error handling for message parsing. |
| transport/api/src/config.rs                  | - Added constants: `const DEFAULT_SESSION_IDLE_TIMEOUT: Duration`, `const SESSION_IDLE_MIN_TIMEOUT: Duration`, `const DEFAULT_SESSION_ESTABLISH_RETRY_DELAY: Duration`, `const DEFAULT_SESSION_ESTABLISH_MAX_RETRIES: u32`. <br> - Updated `SessionGlobalConfig` to use new constants. <br> - Modified `validate_session_idle_timeout` function to use `SESSION_IDLE_MIN_TIMEOUT`. <br> - Removed utility functions returning hardcoded durations. <br> - Reordered import statements. |
| common/network-types/src/session/frame.rs    | - Removed constant `pub const MAXIMUM_SIZE: usize` from `Segment`. <br> - Updated `try_from` implementation to remove maximum size checks. |

## Possibly related PRs
- **#6312**: This PR introduces a new session protocol that includes segmentation and retransmission features, which are closely related to the changes in the `SessionMessage` protocol implementation in the main PR.
- **#6500**: Although primarily focused on HTTPS communication tests, this PR's enhancements to session management could relate to the robustness improvements in the `SessionMessage` protocol.
- **#6506**: This PR adds a test for a WireGuard tunnel, which may involve session management and message handling similar to the changes in the main PR.
- **#6580**: The updates to the OpenAPI specification regarding message tagging could relate to the validation improvements in the `SessionMessage` protocol.
- **#6583**: This PR addresses network heartbeat behavior, which may indirectly relate to session management and message handling in the context of the main PR's changes.

## Suggested labels
`feature`, `improvement`, `crate:core-protocol`, `crate:hoprd`

## Suggested reviewers
- Teebor-Choka
- QYuQianchen

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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@NumberFour8 NumberFour8 marked this pull request as ready for review November 7, 2024 08:54
Changed `MAX_MESSAGE_SIZE` to match Ethernet MTU minus segment overhead, and removed redundant `MAXIMUM_SIZE` constant from `segment`. This ensures consistency with typical Ethernet MTU constraints and removes superfluous checks on segment size.
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 and nitpick comments (6)
transport/api/src/config.rs (3)

168-174: Add documentation for the session-related constants.

The constants effectively replace magic numbers and have reasonable values. Consider adding documentation to explain the rationale behind these values and any constraints they must satisfy.

Add rustdoc comments for each constant:

+/// Default session idle timeout (3 minutes).
 const DEFAULT_SESSION_IDLE_TIMEOUT: Duration = Duration::from_secs(180);

+/// Minimum allowed session idle timeout (1 minute).
 const SESSION_IDLE_MIN_TIMEOUT: Duration = Duration::from_secs(60);

+/// Default delay between session establishment retry attempts.
 const DEFAULT_SESSION_ESTABLISH_RETRY_DELAY: Duration = Duration::from_secs(2);

+/// Default maximum number of session establishment retry attempts.
 const DEFAULT_SESSION_ESTABLISH_MAX_RETRIES: u32 = 3;

Line range hint 189-193: Enhance the validation error message.

The error message could be more descriptive by including the minimum allowed value.

-        Err(ValidationError::new("session idle timeout is too low"))
+        Err(ValidationError::new(&format!(
+            "session idle timeout must be at least {} seconds",
+            SESSION_IDLE_MIN_TIMEOUT.as_secs()
+        )))

Line range hint 205-224: Extract validation range limits as constants.

For consistency with other constants and to make the limits more maintainable, consider extracting the validation range for establish_max_retries.

+/// Minimum allowed value for session establishment retries.
+const MIN_SESSION_ESTABLISH_RETRIES: u32 = 0;
+
+/// Maximum allowed value for session establishment retries.
+const MAX_SESSION_ESTABLISH_RETRIES: u32 = 20;
+
 #[validate(range(min = 0, max = 20))]
 #[default(DEFAULT_SESSION_ESTABLISH_MAX_RETRIES)]
 #[serde(default = "default_session_establish_max_retries")]

Then update the validation:

-#[validate(range(min = 0, max = 20))]
+#[validate(range(min = "MIN_SESSION_ESTABLISH_RETRIES", max = "MAX_SESSION_ESTABLISH_RETRIES"))]
common/network-types/src/session/protocol.rs (3)

311-315: Consider enhancing documentation for MAX_MESSAGE_SIZE

The new constant MAX_MESSAGE_SIZE has been introduced. Providing additional details in the documentation comments about its purpose and how it relates to Segment::MAXIMUM_SIZE would improve code readability and help other developers understand its significance.


428-429: Define the reserved bits mask as a constant for clarity

The mask 0b111111_0000000000 used to extract reserved bits could be defined as a named constant (e.g., RESERVED_BITS_MASK). This would improve code readability and make future maintenance easier.


501-501: Explain the magic number in the test assertion

In the test assertion assert!(SessionMessage::<0>::MAX_MESSAGE_SIZE < 2048);, the magic number 2048 is used without context. Consider defining it as a constant or adding a comment to explain its significance, enhancing the clarity of the test.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d57dc43 and 43fbf9b.

📒 Files selected for processing (2)
  • common/network-types/src/session/protocol.rs (3 hunks)
  • transport/api/src/config.rs (4 hunks)
🔇 Additional comments (2)
transport/api/src/config.rs (2)

5-9: LGTM: Import statements are well-organized.

The new imports are properly scoped and necessary for the added functionality.


176-185: LGTM: Default value functions are well-implemented.

The functions provide a clean way to use the constants as default values in the serde deserialization.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
common/network-types/src/session/protocol.rs (1)

500-501: Consider adding specific test cases for size validation.

While the basic size constraint is tested, consider adding test cases that specifically verify:

  1. Messages exactly at MAX_MESSAGE_SIZE
  2. Messages exceeding MAX_MESSAGE_SIZE
  3. Messages with non-zero reserved bits
#[test]
fn session_message_should_validate_size_and_reserved_bits() {
    // Test maximum allowed size
    let msg = create_message_with_size(SessionMessage::<0>::MAX_MESSAGE_SIZE);
    assert!(SessionMessage::try_from(&msg[..]).is_ok());

    // Test exceeding maximum size
    let msg = create_message_with_size(SessionMessage::<0>::MAX_MESSAGE_SIZE + 1);
    assert!(matches!(
        SessionMessage::try_from(&msg[..]),
        Err(SessionError::IncorrectMessageLength)
    ));

    // Test non-zero reserved bits
    let mut msg = create_valid_message();
    set_reserved_bits(&mut msg, 0b100000_0000000000);
    assert!(matches!(
        SessionMessage::try_from(&msg[..]),
        Err(SessionError::ParseError)
    ));
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 43fbf9b and 0d24598.

📒 Files selected for processing (2)
  • common/network-types/src/session/frame.rs (0 hunks)
  • common/network-types/src/session/protocol.rs (3 hunks)
💤 Files with no reviewable changes (1)
  • common/network-types/src/session/frame.rs
🔇 Additional comments (2)
common/network-types/src/session/protocol.rs (2)

311-314: LGTM! Well-documented constant definition.

The MAX_MESSAGE_SIZE constant is appropriately defined and documented, accounting for protocol overhead based on typical Ethernet MTU size.


422-434: LGTM! Robust validation implementation.

The validation logic effectively enforces:

  1. Message size limits using MAX_MESSAGE_SIZE
  2. Reserved bits constraint for future protocol extensions

The error handling and comments are clear and appropriate.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
common/network-types/src/session/protocol.rs (1)

500-501: Consider documenting the significance of 2048.

While the test verifies that MAX_MESSAGE_SIZE is less than 2048, it would be helpful to document why this specific value was chosen as the upper bound.

-        assert!(SessionMessage::<0>::MAX_MESSAGE_SIZE < 2048);
+        // Ensure MAX_MESSAGE_SIZE fits within 11 bits (< 2048) since we reserve 
+        // the upper 6 bits of the u16 message length field
+        assert!(SessionMessage::<0>::MAX_MESSAGE_SIZE < 2048);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 43fbf9b and 0d24598.

📒 Files selected for processing (2)
  • common/network-types/src/session/frame.rs (0 hunks)
  • common/network-types/src/session/protocol.rs (3 hunks)
💤 Files with no reviewable changes (1)
  • common/network-types/src/session/frame.rs
🔇 Additional comments (2)
common/network-types/src/session/protocol.rs (2)

311-314: LGTM! Well-documented constant definition.

The MAX_MESSAGE_SIZE constant is well-defined and documented, with a clear explanation of how it's calculated based on the Ethernet MTU size minus the segment overhead.


422-434: LGTM! Robust message validation logic.

The implementation includes two important validations:

  1. Message length check against MAX_MESSAGE_SIZE
  2. Reserved bits validation for future protocol versions

This ensures both safety (preventing buffer overflows) and forward compatibility.

Copy link
Contributor

@Teebor-Choka Teebor-Choka left a comment

Choose a reason for hiding this comment

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

I wonder whether these should be exposed in the configuration like this. These are more of niche config options... that probably should not be presented to the user, but could be configured by env variables, e.g. as libp2p does.

@NumberFour8
Copy link
Contributor Author

I wonder whether these should be exposed in the configuration like this. These are more of niche config options... that probably should not be presented to the user, but could be configured by env variables, e.g. as libp2p does.

As I mentioned earlier, the Exit node's config exposure was requested for Ronny.

@Teebor-Choka
Copy link
Contributor

I wonder whether these should be exposed in the configuration like this. These are more of niche config options... that probably should not be presented to the user, but could be configured by env variables, e.g. as libp2p does.

As I mentioned earlier, the Exit node's config exposure was requested for Ronny.

Yeah, but could it be done in the form of ENV variables?

@NumberFour8
Copy link
Contributor Author

I wonder whether these should be exposed in the configuration like this. These are more of niche config options... that probably should not be presented to the user, but could be configured by env variables, e.g. as libp2p does.

As I mentioned earlier, the Exit node's config exposure was requested for Ronny.

Yeah, but could it be done in the form of ENV variables?

Which ones would you rather have as env variables? And why would it be better than exposing them in the config?

@Teebor-Choka
Copy link
Contributor

We can change everything in 3.0.

@NumberFour8 NumberFour8 added this pull request to the merge queue Nov 7, 2024
@NumberFour8
Copy link
Contributor Author

We can change everything in 3.0.

Right. I believe the configs in hopr-lib should be as detailed as possible.

And in the top-level binaries, there should be new (simplified) configs which will subset of hopr-lib config.
It will be used to fill in the hopr-lib configs where desired. The rest will be defaulted or filled in from env variables.

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 7, 2024
@NumberFour8 NumberFour8 added this pull request to the merge queue Nov 7, 2024
Merged via the queue into master with commit 4bd5b82 Nov 7, 2024
28 checks passed
@NumberFour8 NumberFour8 deleted the lukas/reserve-session-bits branch November 7, 2024 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants