Skip to content

Conversation

@fresh3nough
Copy link

@fresh3nough fresh3nough commented Jan 20, 2026

Fixes #10496

The ForwardingHistory RPC documentation states that the maximum number of events that can be returned is 50,000 to avoid exceeding the 4 MiB gRPC message size limit. However, this limit was not actually enforced in the code, allowing users to request arbitrarily large numbers of events which could cause gRPC message size errors.

This commit:

  • Adds a maxForwardingEvents constant (50,000)
  • Validates the requested max_events against this limit
  • Returns an error if the limit is exceeded
  • Adds comprehensive unit tests to verify the validation

Change Description

Description of change / link to associated issue.

Steps to Test

Steps for reviewers to follow to test the change.

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

@gemini-code-assist
Copy link

Summary of Changes

Hello @fresh3nough, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a crucial validation step for the ForwardingHistory RPC, ensuring that the number of requested events does not exceed a predefined maximum. This change directly addresses a previously unenforced documentation constraint, safeguarding against gRPC message size limitations and improving the robustness of the API by preventing potential errors from excessively large responses.

Highlights

  • Enforce max_events limit: The ForwardingHistory RPC now strictly enforces a maximum number of events (50,000) that can be requested, preventing potential gRPC message size errors.
  • New constant maxForwardingEvents: A constant maxForwardingEvents set to 50,000 has been introduced in rpcserver.go to define this limit, accompanied by a clear comment explaining its purpose related to gRPC message size.
  • Input validation: The ForwardingHistory RPC handler now validates the NumMaxEvents parameter against maxForwardingEvents, returning an error if the requested number exceeds the limit.
  • Comprehensive unit tests: A new test TestForwardingHistoryMaxEvents has been added to rpcserver_test.go to thoroughly verify the correct enforcement of the event limit under various scenarios, including cases within, at, and exceeding the limit, as well as the default behavior for zero maxEvents.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request effectively addresses the issue of enforcing a max_events limit for the ForwardingHistory RPC, preventing potential gRPC message size errors. The introduction of the maxForwardingEvents constant and its validation within the ForwardingHistory method are correctly implemented. Comprehensive unit tests have been added to cover various scenarios, ensuring the robustness of the new validation logic.

Comment on lines 191 to 198
} else if tt.maxEvents != 0 && tt.maxEvents <= maxForwardingEvents {
// For valid non-zero values, we expect a different
// error (htlcSwitch nil), not the max events error.
if err != nil {
require.NotContains(t, err.Error(),
"exceeds maximum allowed")
}
}

Choose a reason for hiding this comment

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

medium

This else if condition is a bit complex. It might be clearer to separate the tt.maxEvents != 0 and tt.maxEvents <= maxForwardingEvents checks into distinct if blocks or simplify the condition if possible. For instance, if tt.maxEvents == 0, the numEvents defaults to 100, which is within limit, so it should not expect an error. This could be handled as a separate if tt.maxEvents == 0 case.

            } else if tt.maxEvents == 0 {
                // For zero maxEvents, it defaults to 100, which is within
                // the limit, so we expect no max events error.
                if err != nil {
                    require.NotContains(t, err.Error(),
                        "exceeds maximum allowed")
                }
            } else if tt.maxEvents <= maxForwardingEvents {
                // For valid non-zero values, we expect a different
                // error (htlcSwitch nil), not the max events error.
                if err != nil {
                    require.NotContains(t, err.Error(),
                        "exceeds maximum allowed")
                }
            }

@Roasbeef
Copy link
Member

Roasbeef commented Jan 20, 2026

Perhaps better to consolidate, or help to improve/review: #10503 ?

The API documentation states that ForwardingHistory responses can only
contain 50k records, but this limit was not actually enforced in the
code. This change adds validation to return an error when a client
requests more than the maximum allowed events, rather than silently
capping or allowing potentially oversized responses.

This implementation uses the existing channeldb.MaxResponseEvents
constant to avoid code duplication and ensure the limit is defined
in a single place. Comprehensive unit tests cover various scenarios
including valid values, boundary conditions, and exceeding the limit.

This change consolidates the approaches from PR lightningnetwork#10503 and lightningnetwork#10512,
combining the error-returning validation with the use of the existing
channeldb constant.

Closes lightningnetwork#10496

Co-Authored-By: Warp <agent@warp.dev>
@fresh3nough
Copy link
Author

I've consolidated this PR with #10503, combining the best approaches from both:

  • Error-returning validation (from this PR) instead of silently capping - better UX as clients are explicitly informed when they exceed the limit
  • Use of existing constant (from rpcserver: enforce max_events limit of 50000 for ForwardingHistory #10503) - now uses channeldb.MaxResponseEvents to avoid code duplication
  • Comprehensive unit tests (from this PR) covering various scenarios

The updated implementation has been pushed to this branch. This approach provides better error handling while maintaining code consistency with the existing codebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: maximum max_events documentation for ForwardingHistory not actually implemented

2 participants