Skip to content

fix casting issues in RPC CLIs, remove proof from book_offers#6044

Open
mvadari wants to merge 55 commits intodevelopfrom
mvadari/fix-bad-cast
Open

fix casting issues in RPC CLIs, remove proof from book_offers#6044
mvadari wants to merge 55 commits intodevelopfrom
mvadari/fix-bad-cast

Conversation

@mvadari
Copy link
Collaborator

@mvadari mvadari commented Nov 17, 2025

High Level Overview of Change

This PR fixes some casting issues that resulted in some bad errors in the RPC CLIs, namely:

  • account_tx
  • book_offers
  • can_delete
  • connect
  • get_counts
  • tx_history

This PR also removes the proof parameter from book_offers, which isn't documented anywhere and also doesn't do anything (there will be no change in behavior except in the CLI, since rippled just ignores other parameters).

This also results in some serious simplification opportunities in the RPCCall_test tests.

Context of Change

Downstream of #6043

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Tests (you added tests for code that already exists, or your new feature included in this PR)

API Impact

Some bugs were fixed in the CLI API. The proof parameter was also removed, which decreases the number of CLI params in book_offers.

There are no changes to HTTPS and WS API users.

Test Plan

CI passes. Tests were adjusted.

@mvadari mvadari requested review from a team and vvysokikh1 November 17, 2025 12:45
@codecov
Copy link

codecov bot commented Nov 17, 2025

Codecov Report

❌ Patch coverage is 86.79245% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.8%. Comparing base (afc660a) to head (c7b39df).

Files with missing lines Patch % Lines
src/xrpld/rpc/detail/RPCCall.cpp 86.8% 7 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           develop   #6044   +/-   ##
=======================================
  Coverage     79.8%   79.8%           
=======================================
  Files          858     858           
  Lines        67757   67785   +28     
  Branches      7557    7554    -3     
=======================================
+ Hits         54064   54095   +31     
+ Misses       13693   13690    -3     
Files with missing lines Coverage Δ
include/xrpl/server/NetworkOPs.h 100.0% <ø> (ø)
src/xrpld/app/misc/NetworkOPs.cpp 70.1% <ø> (ø)
src/xrpld/rpc/handlers/BookOffers.cpp 98.9% <ø> (-<0.1%) ⬇️
src/xrpld/rpc/handlers/Subscribe.cpp 91.0% <ø> (ø)
src/xrpld/rpc/detail/RPCCall.cpp 93.5% <86.8%> (-0.2%) ⬇️

... and 5 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mvadari mvadari changed the title fix casting issues in RPC CLIs fix casting issues in RPC CLIs, remove proof from book_offers Nov 17, 2025
@bthomee bthomee requested a review from Tapanito November 19, 2025 22:27
@mvadari mvadari requested a review from Tapanito November 20, 2025 10:11
Copilot AI review requested due to automatic review settings February 10, 2026 22:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +325 to 327
jvRequest[jss::ledger_index_min] = ledgerMin;
jvRequest[jss::ledger_index_max] = ledgerMax;

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

In parseAccountTransactions, ledger_index_min/ledger_index_max are parsed into std::int32_t via jvParseInt. This rejects valid ledger indices above INT32_MAX (e.g. 3,000,000,000), even though the RPC handler (AccountTx.cpp) supports full uint32_t ranges for these fields. Consider parsing ledger min/max as a wider signed type (e.g. int64_t) or as uint32_t with a special-case for -1, then emitting Json::UInt for non-negative values so the full 0..UINT32_MAX range works from the CLI.

Suggested change
jvRequest[jss::ledger_index_min] = ledgerMin;
jvRequest[jss::ledger_index_max] = ledgerMax;
if (ledgerMin >= 0)
jvRequest[jss::ledger_index_min] =
static_cast<Json::UInt>(ledgerMin);
else
jvRequest[jss::ledger_index_min] = ledgerMin;
if (ledgerMax >= 0)
jvRequest[jss::ledger_index_max] =
static_cast<Json::UInt>(ledgerMax);
else
jvRequest[jss::ledger_index_max] = ledgerMax;

Copilot uses AI. Check for mistakes.
Comment on lines 385 to 389

if (jvParams.size() >= 5)
{
try
if (auto const limit = jvParseUInt(jvParams[4u]))
{
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

parseBookOffers no longer supports the positional proof argument, but the function’s header comment still describes [<proof> ...] and proof: 0 or 1. Please update that comment to match the new CLI signature (taker/ledger/limit/marker only) so the in-code documentation stays accurate.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 13, 2026 22:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings February 26, 2026 05:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 413 to +420
std::string input = jvParams[0u].asString();
if (input.find_first_not_of("0123456789") == std::string::npos)
jvRequest["can_delete"] = jvParams[0u].asUInt();
{
if (auto const seq = jvParseUInt(jvParams[0u]))
jvRequest["can_delete"] = *seq;
else
return RPC::invalid_field_error(jss::can_delete);
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

parseCanDelete treats any all-digit input as a ledger index. This incorrectly rejects valid ledger hashes that contain only digits (still valid hex) and now returns invalid_field_error for them. Consider checking for the 64-hex-character ledger-hash form first (e.g., length==64 and hex), or reusing the existing jvParseLedger-style logic so ledger hashes are accepted regardless of whether they contain A-F characters.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@mvadari, can you respond please.

Comment on lines 387 to 396

if (jvParams.size() >= 5)
{
try
if (auto const limit = jvParseUInt(jvParams[4u]))
{
int iLimit = jvParams[4u].asInt();

if (iLimit > 0)
jvRequest[jss::limit] = iLimit;
jvRequest[jss::limit] = *limit;
}
catch (std::exception const&)
{
else
return RPC::invalid_field_error(jss::limit);
}
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The book_offers CLI doc comment above parseBookOffers still describes a <proof> argument and mentions proof: 0 or 1, but proof has been removed from this parser (and from jss). Please update the comment/signature description to match the new argument list so future changes don’t reintroduce off-by-one parsing bugs.

Copilot uses AI. Check for mistakes.

### Additions and bugfixes

- `book_offers`: the `proof` parameter is removed from both the RPC and CLI versions. It did not do anything.
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

The changelog entry says book_offers proof was removed from the “RPC and CLI versions”, but the PR description states there are no changes for HTTPS/WS API users. If the server-side RPC still accepts and ignores unknown fields (including proof), consider rewording this to clarify it’s removed from the CLI and no longer processed internally (but not a breaking change / not rejected for HTTP/WS callers).

Suggested change
- `book_offers`: the `proof` parameter is removed from both the RPC and CLI versions. It did not do anything.
- `book_offers`: the `proof` parameter has been removed from the CLI interface and is no longer processed by the server. For HTTP and WebSocket API requests, `proof` is still accepted and ignored if present, so this is not a breaking change.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@mvadari ditto

jvParseUInt(Json::Value const& param)
{
if (param.isUInt() || (param.isInt() && param.asInt() >= 0))
return param.asUInt();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't we check that the result fits into uint32_t?

Comment on lines +136 to +137
if (param.isInt())
return param.asInt();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't we check that the result fits into int32_t?

std::int64_t uLedgerMax = jvParams[2u].asInt();
std::int32_t ledgerMin = 0,
ledgerMax = 0; // note: these are only used when properly set
if (auto const ledgerMinOpt = jvParseInt(jvParams[1u]))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor, feel free to ignore: maybe this form is a bit more readablle?

Suggested change
if (auto const ledgerMinOpt = jvParseInt(jvParams[1u]))
if (auto const ledgerMinOpt = jvParseInt(jvParams[1u]); ledgerMinOpt.has_value())

Comment on lines +300 to +301
// A value of -1 instructs the server to use the most recent
// validated ledger version available
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably this comment is not needed here because it is explained below.

}

// book_offers <taker_pays> <taker_gets> [<taker> [<ledger> [<limit>
// [<proof> [<marker>]]]]] limit: 0 = no limit proof: 0 or 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

The proof is no longer used.

Comment on lines 413 to +420
std::string input = jvParams[0u].asString();
if (input.find_first_not_of("0123456789") == std::string::npos)
jvRequest["can_delete"] = jvParams[0u].asUInt();
{
if (auto const seq = jvParseUInt(jvParams[0u]))
jvRequest["can_delete"] = *seq;
else
return RPC::invalid_field_error(jss::can_delete);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

@mvadari, can you respond please.


### Additions and bugfixes

- `book_offers`: the `proof` parameter is removed from both the RPC and CLI versions. It did not do anything.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@mvadari ditto

Copilot AI review requested due to automatic review settings February 27, 2026 21:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +296 to +302
std::int32_t ledgerMin = 0,
ledgerMax = 0; // note: these are only used when properly set
if (auto const ledgerMinOpt = jvParseInt(jvParams[1u]))
{
// A value of -1 instructs the server to use the most recent
// validated ledger version available
ledgerMin = *ledgerMinOpt;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

parseAccountTransactions parses ledger_index_min/max into std::int32_t. That prevents the CLI from emitting valid ledger indexes in the upper half of the uint32_t range (e.g. > 2,147,483,647), even though the RPC handler ultimately reads these as uint32_t when non-negative (see AccountTx.cpp using asUInt()). Consider parsing these as a wider signed type (e.g. int64_t) and validating/serializing as: allow -1 sentinel, otherwise require 0..UINT32_MAX and store as Json::UInt.

Copilot uses AI. Check for mistakes.
Comment on lines +300 to +302
// A value of -1 instructs the server to use the most recent
// validated ledger version available
ledgerMin = *ledgerMinOpt;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The inline comment says -1 means “most recent validated ledger version available”, but this block applies that explanation to ledger_index_min as well. In the account_tx handler, negative ledger_index_min is treated as “earliest” (mapped to 0) while negative ledger_index_max is treated as “latest” (mapped to UINT32_MAX). Please adjust the comment (or separate min/max semantics) to match the server-side interpretation.

Copilot uses AI. Check for mistakes.

if (iLimit > 0)
jvRequest[jss::limit] = iLimit;
jvRequest[jss::limit] = *limit;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

parseBookOffers now forwards any successfully parsed limit value, including 0, into the request. However, on the server side readLimitField treats limit == 0 as invalid and returns invalid_field_error(limit). Consider rejecting 0 here (return an invalid-field error) or preserving prior behavior by omitting the limit field when the CLI argument is 0, to avoid surprising CLI users with a new server-side error.

Suggested change
jvRequest[jss::limit] = *limit;
// Preserve prior behavior: treat a limit of 0 as "no limit" and
// omit the field instead of forwarding 0 to the server, which
// would be rejected by readLimitField.
if (*limit != 0)
jvRequest[jss::limit] = *limit;

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 2, 2026 21:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

4 participants