From fe4f95dabd7d97727f46c05a71470427ed1bb309 Mon Sep 17 00:00:00 2001 From: Peter Chen <34582813+PeterChen13579@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:11:07 -0500 Subject: [PATCH] fix: Check ledger range in every handler (#1755) fixes #1565 --- src/rpc/common/impl/HandlerProvider.cpp | 2 +- src/rpc/handlers/AMMInfo.cpp | 3 + src/rpc/handlers/AccountChannels.cpp | 2 + src/rpc/handlers/AccountCurrencies.cpp | 2 + src/rpc/handlers/AccountInfo.cpp | 2 + src/rpc/handlers/AccountLines.cpp | 2 + src/rpc/handlers/AccountNFTs.cpp | 2 + src/rpc/handlers/AccountObjects.cpp | 2 + src/rpc/handlers/AccountOffers.cpp | 2 + src/rpc/handlers/AccountTx.cpp | 3 + src/rpc/handlers/BookChanges.cpp | 3 + src/rpc/handlers/BookOffers.cpp | 3 + src/rpc/handlers/DepositAuthorized.cpp | 2 + src/rpc/handlers/Feature.cpp | 3 + src/rpc/handlers/GatewayBalances.cpp | 3 + src/rpc/handlers/GetAggregatePrice.cpp | 3 + src/rpc/handlers/Ledger.cpp | 3 + src/rpc/handlers/LedgerData.cpp | 5 +- src/rpc/handlers/LedgerEntry.cpp | 2 +- src/rpc/handlers/LedgerIndex.cpp | 3 + src/rpc/handlers/MPTHolders.cpp | 3 + src/rpc/handlers/NFTHistory.cpp | 3 + src/rpc/handlers/NFTInfo.cpp | 3 + src/rpc/handlers/NFTOffersCommon.cpp | 3 + src/rpc/handlers/NFTsByIssuer.cpp | 3 + src/rpc/handlers/NoRippleCheck.cpp | 3 + src/rpc/handlers/ServerInfo.hpp | 3 + src/rpc/handlers/Subscribe.cpp | 5 +- src/rpc/handlers/TransactionEntry.cpp | 3 + src/rpc/handlers/Tx.hpp | 3 + src/rpc/handlers/Unsubscribe.cpp | 8 +- src/rpc/handlers/Unsubscribe.hpp | 8 +- tests/common/util/AsioContextTestFixture.hpp | 5 +- tests/unit/CMakeLists.txt | 1 + tests/unit/etl/LoadBalancerTests.cpp | 1 + .../rpc/handlers/AccountChannelsTests.cpp | 2 + tests/unit/rpc/handlers/AccountInfoTests.cpp | 2 + tests/unit/rpc/handlers/AccountLinesTests.cpp | 2 + tests/unit/rpc/handlers/AllHandlerTests.cpp | 261 ++++++++++++++++++ tests/unit/rpc/handlers/MPTHoldersTests.cpp | 2 + tests/unit/rpc/handlers/NFTBuyOffersTests.cpp | 2 + tests/unit/rpc/handlers/NFTInfoTests.cpp | 2 + .../unit/rpc/handlers/NFTSellOffersTests.cpp | 2 + tests/unit/rpc/handlers/NFTsByIssuerTest.cpp | 2 + .../unit/rpc/handlers/NoRippleCheckTests.cpp | 2 + .../rpc/handlers/TransactionEntryTests.cpp | 2 + tests/unit/rpc/handlers/UnsubscribeTests.cpp | 14 +- 47 files changed, 377 insertions(+), 25 deletions(-) create mode 100644 tests/unit/rpc/handlers/AllHandlerTests.cpp diff --git a/src/rpc/common/impl/HandlerProvider.cpp b/src/rpc/common/impl/HandlerProvider.cpp index be5abdb3c..a1be78015 100644 --- a/src/rpc/common/impl/HandlerProvider.cpp +++ b/src/rpc/common/impl/HandlerProvider.cpp @@ -111,7 +111,7 @@ ProductionHandlerProvider::ProductionHandlerProvider( {"transaction_entry", {TransactionEntryHandler{backend}}}, {"tx", {TxHandler{backend, etl}}}, {"subscribe", {SubscribeHandler{backend, subscriptionManager}}}, - {"unsubscribe", {UnsubscribeHandler{backend, subscriptionManager}}}, + {"unsubscribe", {UnsubscribeHandler{subscriptionManager}}}, {"version", {VersionHandler{config}}}, } { diff --git a/src/rpc/handlers/AMMInfo.cpp b/src/rpc/handlers/AMMInfo.cpp index 8fc1196a3..60d20f12d 100644 --- a/src/rpc/handlers/AMMInfo.cpp +++ b/src/rpc/handlers/AMMInfo.cpp @@ -28,6 +28,7 @@ #include "rpc/common/Specs.hpp" #include "rpc/common/Types.hpp" #include "rpc/common/Validators.hpp" +#include "util/Assert.hpp" #include #include @@ -94,6 +95,8 @@ AMMInfoHandler::process(AMMInfoHandler::Input input, Context const& ctx) const return Error{Status{RippledError::rpcINVALID_PARAMS}}; auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AMMInfo's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountChannels.cpp b/src/rpc/handlers/AccountChannels.cpp index bf446e054..b17cb9593 100644 --- a/src/rpc/handlers/AccountChannels.cpp +++ b/src/rpc/handlers/AccountChannels.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -84,6 +85,7 @@ AccountChannelsHandler::Result AccountChannelsHandler::process(AccountChannelsHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountChannel's ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountCurrencies.cpp b/src/rpc/handlers/AccountCurrencies.cpp index 7b0132a4e..0fdf64b6a 100644 --- a/src/rpc/handlers/AccountCurrencies.cpp +++ b/src/rpc/handlers/AccountCurrencies.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -46,6 +47,7 @@ AccountCurrenciesHandler::Result AccountCurrenciesHandler::process(AccountCurrenciesHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountCurrencies' ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountInfo.cpp b/src/rpc/handlers/AccountInfo.cpp index fddafc116..1b53a17a0 100644 --- a/src/rpc/handlers/AccountInfo.cpp +++ b/src/rpc/handlers/AccountInfo.cpp @@ -25,6 +25,7 @@ #include "rpc/RPCHelpers.hpp" #include "rpc/common/JsonBool.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -58,6 +59,7 @@ AccountInfoHandler::process(AccountInfoHandler::Input input, Context const& ctx) return Error{Status{RippledError::rpcINVALID_PARAMS, ripple::RPC::missing_field_message(JS(account))}}; auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountInfo's ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountLines.cpp b/src/rpc/handlers/AccountLines.cpp index 0af390b65..85c6c8036 100644 --- a/src/rpc/handlers/AccountLines.cpp +++ b/src/rpc/handlers/AccountLines.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -120,6 +121,7 @@ AccountLinesHandler::Result AccountLinesHandler::process(AccountLinesHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountLines' ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountNFTs.cpp b/src/rpc/handlers/AccountNFTs.cpp index 4d02fabad..d59989cca 100644 --- a/src/rpc/handlers/AccountNFTs.cpp +++ b/src/rpc/handlers/AccountNFTs.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -52,6 +53,7 @@ AccountNFTsHandler::Result AccountNFTsHandler::process(AccountNFTsHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountNFT's ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountObjects.cpp b/src/rpc/handlers/AccountObjects.cpp index 5aba213f6..0de8ab4b0 100644 --- a/src/rpc/handlers/AccountObjects.cpp +++ b/src/rpc/handlers/AccountObjects.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include "util/LedgerUtils.hpp" #include @@ -52,6 +53,7 @@ AccountObjectsHandler::Result AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountObject's ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountOffers.cpp b/src/rpc/handlers/AccountOffers.cpp index 061d7ee69..5e38dd14d 100644 --- a/src/rpc/handlers/AccountOffers.cpp +++ b/src/rpc/handlers/AccountOffers.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -68,6 +69,7 @@ AccountOffersHandler::Result AccountOffersHandler::process(AccountOffersHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountOffer's ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/AccountTx.cpp b/src/rpc/handlers/AccountTx.cpp index f93508cd4..9955d48f5 100644 --- a/src/rpc/handlers/AccountTx.cpp +++ b/src/rpc/handlers/AccountTx.cpp @@ -25,6 +25,7 @@ #include "rpc/RPCHelpers.hpp" #include "rpc/common/JsonBool.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include "util/JsonUtils.hpp" #include "util/Profiler.hpp" #include "util/log/Logger.hpp" @@ -55,6 +56,8 @@ AccountTxHandler::Result AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "AccountTX's ledger range must be available"); + auto [minIndex, maxIndex] = *range; if (input.ledgerIndexMin) { diff --git a/src/rpc/handlers/BookChanges.cpp b/src/rpc/handlers/BookChanges.cpp index 43e14701e..61cdd59bb 100644 --- a/src/rpc/handlers/BookChanges.cpp +++ b/src/rpc/handlers/BookChanges.cpp @@ -25,6 +25,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -45,6 +46,8 @@ BookChangesHandler::Result BookChangesHandler::process(BookChangesHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "BookChanges' ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/BookOffers.cpp b/src/rpc/handlers/BookOffers.cpp index 55799b428..65110ecb5 100644 --- a/src/rpc/handlers/BookOffers.cpp +++ b/src/rpc/handlers/BookOffers.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -51,6 +52,8 @@ BookOffersHandler::process(Input input, Context const& ctx) const // check ledger auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "BookOffer's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/DepositAuthorized.cpp b/src/rpc/handlers/DepositAuthorized.cpp index fb9c21e19..38f181ceb 100644 --- a/src/rpc/handlers/DepositAuthorized.cpp +++ b/src/rpc/handlers/DepositAuthorized.cpp @@ -53,6 +53,8 @@ DepositAuthorizedHandler::Result DepositAuthorizedHandler::process(DepositAuthorizedHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "DepositAuthorized ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/Feature.cpp b/src/rpc/handlers/Feature.cpp index 72a47910b..fc21eea8a 100644 --- a/src/rpc/handlers/Feature.cpp +++ b/src/rpc/handlers/Feature.cpp @@ -27,6 +27,7 @@ #include "rpc/common/Specs.hpp" #include "rpc/common/Types.hpp" #include "rpc/common/Validators.hpp" +#include "util/Assert.hpp" #include #include @@ -56,6 +57,8 @@ FeatureHandler::process(FeatureHandler::Input input, Context const& ctx) const namespace rg = std::ranges; auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "Feature's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/GatewayBalances.cpp b/src/rpc/handlers/GatewayBalances.cpp index 91155cece..adfba6448 100644 --- a/src/rpc/handlers/GatewayBalances.cpp +++ b/src/rpc/handlers/GatewayBalances.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -59,6 +60,8 @@ GatewayBalancesHandler::process(GatewayBalancesHandler::Input input, Context con { // check ledger auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "GatewayBalances' ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/GetAggregatePrice.cpp b/src/rpc/handlers/GetAggregatePrice.cpp index 2aac52ce9..23de6eca9 100644 --- a/src/rpc/handlers/GetAggregatePrice.cpp +++ b/src/rpc/handlers/GetAggregatePrice.cpp @@ -24,6 +24,7 @@ #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" #include "util/AccountUtils.hpp" +#include "util/Assert.hpp" #include #include @@ -61,6 +62,8 @@ GetAggregatePriceHandler::Result GetAggregatePriceHandler::process(GetAggregatePriceHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "GetAggregatePrice's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/Ledger.cpp b/src/rpc/handlers/Ledger.cpp index 5d4afd8e8..f6b7dd595 100644 --- a/src/rpc/handlers/Ledger.cpp +++ b/src/rpc/handlers/Ledger.cpp @@ -24,6 +24,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -52,6 +53,8 @@ LedgerHandler::Result LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "LedgerHandler's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/LedgerData.cpp b/src/rpc/handlers/LedgerData.cpp index 15287b40b..3b97015fc 100644 --- a/src/rpc/handlers/LedgerData.cpp +++ b/src/rpc/handlers/LedgerData.cpp @@ -24,6 +24,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include "util/LedgerUtils.hpp" #include "util/log/Logger.hpp" @@ -61,6 +62,8 @@ LedgerDataHandler::process(Input input, Context const& ctx) const return Error{Status{RippledError::rpcINVALID_PARAMS, "markerNotString"}}; auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "LedgerData's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); @@ -117,7 +120,7 @@ LedgerDataHandler::process(Input input, Context const& ctx) const if (page.cursor) { output.marker = ripple::strHex(*(page.cursor)); } else if (input.outOfOrder) { - output.diffMarker = sharedPtrBackend_->fetchLedgerRange()->maxSequence; + output.diffMarker = range->maxSequence; } } diff --git a/src/rpc/handlers/LedgerEntry.cpp b/src/rpc/handlers/LedgerEntry.cpp index d27a00458..cdbb70260 100644 --- a/src/rpc/handlers/LedgerEntry.cpp +++ b/src/rpc/handlers/LedgerEntry.cpp @@ -188,7 +188,7 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input input, Context const& ctx) // check ledger exists auto const range = sharedPtrBackend_->fetchLedgerRange(); - ASSERT(range.has_value(), "Ledger range must be available"); + ASSERT(range.has_value(), "LedgerEntry's ledger range must be available"); auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/LedgerIndex.cpp b/src/rpc/handlers/LedgerIndex.cpp index 9796f0799..e6816fddf 100644 --- a/src/rpc/handlers/LedgerIndex.cpp +++ b/src/rpc/handlers/LedgerIndex.cpp @@ -22,6 +22,7 @@ #include "rpc/Errors.hpp" #include "rpc/JS.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include "util/TimeUtils.hpp" #include @@ -42,6 +43,8 @@ LedgerIndexHandler::Result LedgerIndexHandler::process(LedgerIndexHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "LedgerIndex's ledger range must be available"); + auto const [minIndex, maxIndex] = *range; auto const fillOutputByIndex = [&](std::uint32_t index) { diff --git a/src/rpc/handlers/MPTHolders.cpp b/src/rpc/handlers/MPTHolders.cpp index e248297f1..03676c02e 100644 --- a/src/rpc/handlers/MPTHolders.cpp +++ b/src/rpc/handlers/MPTHolders.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -49,6 +50,8 @@ MPTHoldersHandler::Result MPTHoldersHandler::process(MPTHoldersHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "MPTHolder's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/NFTHistory.cpp b/src/rpc/handlers/NFTHistory.cpp index f07e4925f..ae4a66c1c 100644 --- a/src/rpc/handlers/NFTHistory.cpp +++ b/src/rpc/handlers/NFTHistory.cpp @@ -24,6 +24,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include "util/Profiler.hpp" #include "util/log/Logger.hpp" @@ -53,6 +54,8 @@ NFTHistoryHandler::Result NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "NFTHistory's ledger range must be available"); + auto [minIndex, maxIndex] = *range; if (input.ledgerIndexMin) { diff --git a/src/rpc/handlers/NFTInfo.cpp b/src/rpc/handlers/NFTInfo.cpp index 608d63c16..9fadcd16b 100644 --- a/src/rpc/handlers/NFTInfo.cpp +++ b/src/rpc/handlers/NFTInfo.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -47,6 +48,8 @@ NFTInfoHandler::process(NFTInfoHandler::Input input, Context const& ctx) const { auto const tokenID = ripple::uint256{input.nftID.c_str()}; auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "NFTInfo's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/NFTOffersCommon.cpp b/src/rpc/handlers/NFTOffersCommon.cpp index 465fe1727..3945916a5 100644 --- a/src/rpc/handlers/NFTOffersCommon.cpp +++ b/src/rpc/handlers/NFTOffersCommon.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -90,6 +91,8 @@ NFTOffersHandlerBase::iterateOfferDirectory( ) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "NFTOffersCommon's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/NFTsByIssuer.cpp b/src/rpc/handlers/NFTsByIssuer.cpp index 9f808f1a9..5b517affa 100644 --- a/src/rpc/handlers/NFTsByIssuer.cpp +++ b/src/rpc/handlers/NFTsByIssuer.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -48,6 +49,8 @@ NFTsByIssuerHandler::Result NFTsByIssuerHandler::process(NFTsByIssuerHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "NFTsByIssuer's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/NoRippleCheck.cpp b/src/rpc/handlers/NoRippleCheck.cpp index 6b2d1c9cd..8eec13db3 100644 --- a/src/rpc/handlers/NoRippleCheck.cpp +++ b/src/rpc/handlers/NoRippleCheck.cpp @@ -24,6 +24,7 @@ #include "rpc/RPCHelpers.hpp" #include "rpc/common/JsonBool.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -58,6 +59,8 @@ NoRippleCheckHandler::Result NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "NoRippleCheck's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/ServerInfo.hpp b/src/rpc/handlers/ServerInfo.hpp index efbc26a66..e68f56981 100644 --- a/src/rpc/handlers/ServerInfo.hpp +++ b/src/rpc/handlers/ServerInfo.hpp @@ -26,6 +26,7 @@ #include "rpc/JS.hpp" #include "rpc/common/Specs.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include "util/build/Build.hpp" #include @@ -196,6 +197,8 @@ class BaseServerInfoHandler { using namespace std::chrono; auto const range = backend_->fetchLedgerRange(); + ASSERT(range.has_value(), "ServerInfo's ledger range must be available"); + auto const lgrInfo = backend_->fetchLedgerBySequence(range->maxSequence, ctx.yield); if (not lgrInfo.has_value()) return Error{Status{RippledError::rpcINTERNAL}}; diff --git a/src/rpc/handlers/Subscribe.cpp b/src/rpc/handlers/Subscribe.cpp index 367168eeb..4e0ff2e7e 100644 --- a/src/rpc/handlers/Subscribe.cpp +++ b/src/rpc/handlers/Subscribe.cpp @@ -31,6 +31,7 @@ #include "rpc/common/Specs.hpp" #include "rpc/common/Types.hpp" #include "rpc/common/Validators.hpp" +#include "util/Assert.hpp" #include #include @@ -201,8 +202,10 @@ SubscribeHandler::subscribeToBooks( for (auto const& internalBook : books) { if (internalBook.snapshot) { - if (!rng) + if (!rng) { rng = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(rng.has_value(), "Subscribe's ledger range must be available"); + } auto const getOrderBook = [&](auto const& book, auto& snapshots) { auto const bookBase = getBookBase(book); diff --git a/src/rpc/handlers/TransactionEntry.cpp b/src/rpc/handlers/TransactionEntry.cpp index eadd61c08..83a983bbb 100644 --- a/src/rpc/handlers/TransactionEntry.cpp +++ b/src/rpc/handlers/TransactionEntry.cpp @@ -23,6 +23,7 @@ #include "rpc/JS.hpp" #include "rpc/RPCHelpers.hpp" #include "rpc/common/Types.hpp" +#include "util/Assert.hpp" #include #include @@ -43,6 +44,8 @@ TransactionEntryHandler::Result TransactionEntryHandler::process(TransactionEntryHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "TransactionEntry's ledger range must be available"); + auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence ); diff --git a/src/rpc/handlers/Tx.hpp b/src/rpc/handlers/Tx.hpp index c453e7b8e..e41a61db0 100644 --- a/src/rpc/handlers/Tx.hpp +++ b/src/rpc/handlers/Tx.hpp @@ -29,6 +29,7 @@ #include "rpc/common/Specs.hpp" #include "rpc/common/Types.hpp" #include "rpc/common/Validators.hpp" +#include "util/Assert.hpp" #include "util/JsonUtils.hpp" #include @@ -188,6 +189,8 @@ class BaseTxHandler { if (rangeSupplied && input.transaction) // ranges not for ctid { auto const range = sharedPtrBackend_->fetchLedgerRange(); + ASSERT(range.has_value(), "Tx's ledger range must be available"); + auto const searchedAll = range->maxSequence >= *input.maxLedger && range->minSequence <= *input.minLedger; boost::json::object extra; diff --git a/src/rpc/handlers/Unsubscribe.cpp b/src/rpc/handlers/Unsubscribe.cpp index 177b4d2e6..ac5f12b2c 100644 --- a/src/rpc/handlers/Unsubscribe.cpp +++ b/src/rpc/handlers/Unsubscribe.cpp @@ -19,7 +19,6 @@ #include "rpc/handlers/Unsubscribe.hpp" -#include "data/BackendInterface.hpp" #include "feed/SubscriptionManagerInterface.hpp" #include "feed/Types.hpp" #include "rpc/Errors.hpp" @@ -46,11 +45,8 @@ namespace rpc { -UnsubscribeHandler::UnsubscribeHandler( - std::shared_ptr const& sharedPtrBackend, - std::shared_ptr const& subscriptions -) - : sharedPtrBackend_(sharedPtrBackend), subscriptions_(subscriptions) +UnsubscribeHandler::UnsubscribeHandler(std::shared_ptr const& subscriptions) + : subscriptions_(subscriptions) { } diff --git a/src/rpc/handlers/Unsubscribe.hpp b/src/rpc/handlers/Unsubscribe.hpp index 1f89022b0..6814376cc 100644 --- a/src/rpc/handlers/Unsubscribe.hpp +++ b/src/rpc/handlers/Unsubscribe.hpp @@ -19,7 +19,6 @@ #pragma once -#include "data/BackendInterface.hpp" #include "feed/SubscriptionManagerInterface.hpp" #include "feed/Types.hpp" #include "rpc/common/Specs.hpp" @@ -49,7 +48,6 @@ namespace rpc { */ class UnsubscribeHandler { - std::shared_ptr sharedPtrBackend_; std::shared_ptr subscriptions_; public: @@ -77,13 +75,9 @@ class UnsubscribeHandler { /** * @brief Construct a new BaseUnsubscribeHandler object * - * @param sharedPtrBackend The backend to use * @param subscriptions The subscription manager to use */ - UnsubscribeHandler( - std::shared_ptr const& sharedPtrBackend, - std::shared_ptr const& subscriptions - ); + UnsubscribeHandler(std::shared_ptr const& subscriptions); /** * @brief Returns the API specification for the command diff --git a/tests/common/util/AsioContextTestFixture.hpp b/tests/common/util/AsioContextTestFixture.hpp index da00ad300..97958ab8f 100644 --- a/tests/common/util/AsioContextTestFixture.hpp +++ b/tests/common/util/AsioContextTestFixture.hpp @@ -77,11 +77,14 @@ struct AsyncAsioContextTest : virtual public NoLoggerFixture { struct SyncAsioContextTest : virtual public NoLoggerFixture { template void - runSpawn(F&& f) + runSpawn(F&& f, bool allowMockLeak = false) { using namespace boost::asio; testing::MockFunction call; + if (allowMockLeak) + testing::Mock::AllowLeak(&call); + spawn(ctx, [&, _ = make_work_guard(ctx)](yield_context yield) { f(yield); call.Call(); diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 01045e716..b454474d4 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -67,6 +67,7 @@ target_sources( rpc/handlers/AccountOffersTests.cpp rpc/handlers/AccountTxTests.cpp rpc/handlers/AMMInfoTests.cpp + rpc/handlers/AllHandlerTests.cpp rpc/handlers/BookChangesTests.cpp rpc/handlers/BookOffersTests.cpp rpc/handlers/CredentialHelpersTests.cpp diff --git a/tests/unit/etl/LoadBalancerTests.cpp b/tests/unit/etl/LoadBalancerTests.cpp index 6a321672d..780fe52bf 100644 --- a/tests/unit/etl/LoadBalancerTests.cpp +++ b/tests/unit/etl/LoadBalancerTests.cpp @@ -197,6 +197,7 @@ TEST_F(LoadBalancerConstructorDeathTest, numMarkersSpecifiedInConfigIsInvalid) { uint32_t const numMarkers = 257; configJson_.as_object()["num_markers"] = numMarkers; + testing::Mock::AllowLeak(&sourceFactory_); EXPECT_DEATH({ makeLoadBalancer(); }, ".*"); } diff --git a/tests/unit/rpc/handlers/AccountChannelsTests.cpp b/tests/unit/rpc/handlers/AccountChannelsTests.cpp index 6025d5c16..0bd6e4a88 100644 --- a/tests/unit/rpc/handlers/AccountChannelsTests.cpp +++ b/tests/unit/rpc/handlers/AccountChannelsTests.cpp @@ -273,6 +273,8 @@ TEST_F(RPCAccountChannelsHandlerTest, AccountNotString) // error case ledger non exist via hash TEST_F(RPCAccountChannelsHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) .WillByDefault(Return(std::optional{})); diff --git a/tests/unit/rpc/handlers/AccountInfoTests.cpp b/tests/unit/rpc/handlers/AccountInfoTests.cpp index befdfc335..f0ce70ba5 100644 --- a/tests/unit/rpc/handlers/AccountInfoTests.cpp +++ b/tests/unit/rpc/handlers/AccountInfoTests.cpp @@ -133,6 +133,8 @@ TEST_P(AccountInfoParameterTest, InvalidParams) TEST_F(AccountInfoParameterTest, ApiV1SignerListIsNotBool) { + backend->setRange(10, 30); + static constexpr auto reqJson = R"( {"ident":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", "signer_lists":1} )"; diff --git a/tests/unit/rpc/handlers/AccountLinesTests.cpp b/tests/unit/rpc/handlers/AccountLinesTests.cpp index 8c436db6a..5d4cf3e2a 100644 --- a/tests/unit/rpc/handlers/AccountLinesTests.cpp +++ b/tests/unit/rpc/handlers/AccountLinesTests.cpp @@ -319,6 +319,8 @@ TEST_F(RPCAccountLinesHandlerTest, LimitZero) // error case ledger non exist via hash TEST_F(RPCAccountLinesHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) .WillByDefault(Return(std::optional{})); diff --git a/tests/unit/rpc/handlers/AllHandlerTests.cpp b/tests/unit/rpc/handlers/AllHandlerTests.cpp new file mode 100644 index 000000000..62af29969 --- /dev/null +++ b/tests/unit/rpc/handlers/AllHandlerTests.cpp @@ -0,0 +1,261 @@ +//------------------------------------------------------------------------------ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2024, the clio developers. + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include "rpc/common/Types.hpp" +#include "rpc/handlers/AMMInfo.hpp" +#include "rpc/handlers/AccountChannels.hpp" +#include "rpc/handlers/AccountCurrencies.hpp" +#include "rpc/handlers/AccountInfo.hpp" +#include "rpc/handlers/AccountLines.hpp" +#include "rpc/handlers/AccountNFTs.hpp" +#include "rpc/handlers/AccountObjects.hpp" +#include "rpc/handlers/AccountOffers.hpp" +#include "rpc/handlers/AccountTx.hpp" +#include "rpc/handlers/BookChanges.hpp" +#include "rpc/handlers/BookOffers.hpp" +#include "rpc/handlers/DepositAuthorized.hpp" +#include "rpc/handlers/Feature.hpp" +#include "rpc/handlers/GatewayBalances.hpp" +#include "rpc/handlers/GetAggregatePrice.hpp" +#include "rpc/handlers/Ledger.hpp" +#include "rpc/handlers/LedgerData.hpp" +#include "rpc/handlers/LedgerEntry.hpp" +#include "rpc/handlers/LedgerIndex.hpp" +#include "rpc/handlers/MPTHolders.hpp" +#include "rpc/handlers/NFTBuyOffers.hpp" +#include "rpc/handlers/NFTHistory.hpp" +#include "rpc/handlers/NFTInfo.hpp" +#include "rpc/handlers/NFTSellOffers.hpp" +#include "rpc/handlers/NFTsByIssuer.hpp" +#include "rpc/handlers/NoRippleCheck.hpp" +#include "rpc/handlers/ServerInfo.hpp" +#include "rpc/handlers/Subscribe.hpp" +#include "rpc/handlers/TransactionEntry.hpp" +#include "util/Assert.hpp" +#include "util/HandlerBaseTestFixture.hpp" +#include "util/MockAmendmentCenter.hpp" +#include "util/MockCountersFixture.hpp" +#include "util/MockETLServiceTestFixture.hpp" +#include "util/MockSubscriptionManager.hpp" +#include "util/MockWsBase.hpp" +#include "util/TestObject.hpp" +#include "web/SubscriptionContextInterface.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using ::testing::Types; +using namespace rpc; +using TestServerInfoHandler = BaseServerInfoHandler; + +constexpr static auto Index1 = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DD"; +constexpr static auto AmmAccount = "rLcS7XL6nxRAi7JcbJcn1Na179oF3vdfbh"; +constexpr static auto Account = "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"; +constexpr static auto NftID = "00010000A7CAD27B688D14BA1A9FA5366554D6ADCF9CE0875B974D9F00000004"; +constexpr static auto Currency = "0158415500000000C1F76FF6ECB0BAC600000000"; + +using AnyHandlerType = Types< + AccountChannelsHandler, + AccountCurrenciesHandler, + AccountInfoHandler, + AccountLinesHandler, + AccountNFTsHandler, + AccountObjectsHandler, + AccountOffersHandler, + AccountTxHandler, + AMMInfoHandler, + BookChangesHandler, + BookOffersHandler, + DepositAuthorizedHandler, + FeatureHandler, + GatewayBalancesHandler, + GetAggregatePriceHandler, + LedgerHandler, + LedgerDataHandler, + LedgerEntryHandler, + LedgerIndexHandler, + MPTHoldersHandler, + NFTsByIssuerHandler, + NFTHistoryHandler, + NFTBuyOffersHandler, + NFTInfoHandler, + NFTSellOffersHandler, + NoRippleCheckHandler, + TestServerInfoHandler, + SubscribeHandler, + TransactionEntryHandler>; + +template +struct AllHandlersDeathTest : HandlerBaseTest, + MockLoadBalancerTest, + MockCountersTest, + testing::WithParamInterface { + AllHandlersDeathTest() : handler_{initHandler()} + { + ASSERT(mockAmendmentCenterPtr.amendmentCenterMock != nullptr, "mockAmendmentCenterPtr is not initialized."); + ASSERT(mockSubscriptionManagerPtr.subscriptionManagerMock != nullptr, "mockSubscriptionPtr is not initialized"); + } + + web::SubscriptionContextPtr session_ = std::make_shared(); + MockSession* mockSession_ = dynamic_cast(session_.get()); + StrictMockSubscriptionManagerSharedPtr mockSubscriptionManagerPtr; + StrictMockAmendmentCenterSharedPtr mockAmendmentCenterPtr; + HandlerType handler_; + +private: + HandlerType + initHandler() + { + if constexpr (std::is_same_v || std::is_same_v) { + return HandlerType{this->backend, this->mockAmendmentCenterPtr}; + } else if constexpr (std::is_same_v) { + return HandlerType{this->backend, this->mockSubscriptionManagerPtr}; + } else if constexpr (std::is_same_v) { + return HandlerType{ + this->backend, + this->mockSubscriptionManagerPtr, + mockLoadBalancerPtr, + mockETLServicePtr, + *mockCountersPtr + }; + } else { + return HandlerType{this->backend}; + } + } +}; + +template +Handler::Input +createInput() +{ + return typename Handler::Input{}; +} + +// need to set specific values for input for some handler's to pass checks in .process() function +template <> +AccountInfoHandler::Input +createInput() +{ + AccountInfoHandler::Input input{}; + input.account = Account; + input.ident = "asdf"; + return input; +} + +template <> +AMMInfoHandler::Input +createInput() +{ + AMMInfoHandler::Input input{}; + input.ammAccount = GetAccountIDWithString(AmmAccount); + return input; +} + +template <> +BookOffersHandler::Input +createInput() +{ + BookOffersHandler::Input input{}; + input.paysCurrency = ripple::xrpCurrency(); + input.getsCurrency = ripple::Currency(Currency); + input.paysID = ripple::xrpAccount(); + input.getsID = GetAccountIDWithString(Account); + + return input; +} + +template <> +LedgerEntryHandler::Input +createInput() +{ + LedgerEntryHandler::Input input{}; + input.index = Index1; + return input; +} + +template <> +NFTBuyOffersHandler::Input +createInput() +{ + NFTBuyOffersHandler::Input input{}; + input.nftID = NftID; + return input; +} + +template <> +NFTInfoHandler::Input +createInput() +{ + NFTInfoHandler::Input input{}; + input.nftID = NftID; + return input; +} + +template <> +NFTSellOffersHandler::Input +createInput() +{ + NFTSellOffersHandler::Input input{}; + input.nftID = NftID; + return input; +} + +template <> +SubscribeHandler::Input +createInput() +{ + SubscribeHandler::Input input{}; + + input.books = + std::vector{SubscribeHandler::OrderBook{ripple::Book{}, Account, true, true}}; + return input; +} + +TYPED_TEST_CASE(AllHandlersDeathTest, AnyHandlerType); + +TYPED_TEST(AllHandlersDeathTest, NoRangeAvailable) +{ + // doesn't work without 'this' + this->runSpawn( + [&](boost::asio::yield_context yield) { + TypeParam handler = this->handler_; + + auto const input = createInput(); + auto const context = Context{yield, this->session_}; + + EXPECT_DEATH( + { [[maybe_unused]] auto _unused = handler.process(input, context); }, "Assertion .* failed at .*" + ); + }, + true + ); +} diff --git a/tests/unit/rpc/handlers/MPTHoldersTests.cpp b/tests/unit/rpc/handlers/MPTHoldersTests.cpp index a432545f1..dbc5a4246 100644 --- a/tests/unit/rpc/handlers/MPTHoldersTests.cpp +++ b/tests/unit/rpc/handlers/MPTHoldersTests.cpp @@ -223,6 +223,8 @@ TEST_F(RPCMPTHoldersHandlerTest, MarkerNotString) // error case ledger non exist via hash TEST_F(RPCMPTHoldersHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty EXPECT_CALL(*backend, fetchLedgerByHash).Times(1); ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) diff --git a/tests/unit/rpc/handlers/NFTBuyOffersTests.cpp b/tests/unit/rpc/handlers/NFTBuyOffersTests.cpp index ef92752ab..250a94b38 100644 --- a/tests/unit/rpc/handlers/NFTBuyOffersTests.cpp +++ b/tests/unit/rpc/handlers/NFTBuyOffersTests.cpp @@ -210,6 +210,8 @@ TEST_F(RPCNFTBuyOffersHandlerTest, NFTIDNotString) // error case ledger non exist via hash TEST_F(RPCNFTBuyOffersHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) .WillByDefault(Return(std::optional{})); diff --git a/tests/unit/rpc/handlers/NFTInfoTests.cpp b/tests/unit/rpc/handlers/NFTInfoTests.cpp index 060d5d0ab..70250e87b 100644 --- a/tests/unit/rpc/handlers/NFTInfoTests.cpp +++ b/tests/unit/rpc/handlers/NFTInfoTests.cpp @@ -148,6 +148,8 @@ TEST_F(RPCNFTInfoHandlerTest, NFTIDNotString) // error case ledger non exist via hash TEST_F(RPCNFTInfoHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) .WillByDefault(Return(std::optional{})); diff --git a/tests/unit/rpc/handlers/NFTSellOffersTests.cpp b/tests/unit/rpc/handlers/NFTSellOffersTests.cpp index ded6568fe..091427110 100644 --- a/tests/unit/rpc/handlers/NFTSellOffersTests.cpp +++ b/tests/unit/rpc/handlers/NFTSellOffersTests.cpp @@ -210,6 +210,8 @@ TEST_F(RPCNFTSellOffersHandlerTest, NFTIDNotString) // error case ledger non exist via hash TEST_F(RPCNFTSellOffersHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) .WillByDefault(Return(std::optional{})); diff --git a/tests/unit/rpc/handlers/NFTsByIssuerTest.cpp b/tests/unit/rpc/handlers/NFTsByIssuerTest.cpp index 5d0bca69e..57609a8d5 100644 --- a/tests/unit/rpc/handlers/NFTsByIssuerTest.cpp +++ b/tests/unit/rpc/handlers/NFTsByIssuerTest.cpp @@ -206,6 +206,8 @@ TEST_F(RPCNFTsByIssuerHandlerTest, NFTIssuerNotString) // error case ledger non exist via hash TEST_F(RPCNFTsByIssuerHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty EXPECT_CALL(*backend, fetchLedgerByHash).Times(1); ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) diff --git a/tests/unit/rpc/handlers/NoRippleCheckTests.cpp b/tests/unit/rpc/handlers/NoRippleCheckTests.cpp index f8e3a48e9..3874ddf86 100644 --- a/tests/unit/rpc/handlers/NoRippleCheckTests.cpp +++ b/tests/unit/rpc/handlers/NoRippleCheckTests.cpp @@ -181,6 +181,8 @@ TEST_P(NoRippleCheckParameterTest, InvalidParams) TEST_F(NoRippleCheckParameterTest, V1ApiTransactionsIsNotBool) { + backend->setRange(10, 30); + static constexpr auto reqJson = R"( { "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", diff --git a/tests/unit/rpc/handlers/TransactionEntryTests.cpp b/tests/unit/rpc/handlers/TransactionEntryTests.cpp index 5289a7a89..1c7f5e9d2 100644 --- a/tests/unit/rpc/handlers/TransactionEntryTests.cpp +++ b/tests/unit/rpc/handlers/TransactionEntryTests.cpp @@ -77,6 +77,8 @@ TEST_F(RPCTransactionEntryHandlerTest, TxHashWrongFormat) TEST_F(RPCTransactionEntryHandlerTest, NonExistLedgerViaLedgerHash) { + backend->setRange(10, 30); + // mock fetchLedgerByHash return empty ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{INDEX}, _)) .WillByDefault(Return(std::optional{})); diff --git a/tests/unit/rpc/handlers/UnsubscribeTests.cpp b/tests/unit/rpc/handlers/UnsubscribeTests.cpp index 7c7f6bc0c..114dd3664 100644 --- a/tests/unit/rpc/handlers/UnsubscribeTests.cpp +++ b/tests/unit/rpc/handlers/UnsubscribeTests.cpp @@ -496,7 +496,7 @@ TEST_P(UnsubscribeParameterTest, InvalidParams) { auto const testBundle = GetParam(); runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const req = json::parse(testBundle.testJson); auto const output = handler.process(req, Context{yield}); ASSERT_FALSE(output); @@ -509,7 +509,7 @@ TEST_P(UnsubscribeParameterTest, InvalidParams) TEST_F(RPCUnsubscribeTest, EmptyResponse) { runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const output = handler.process(json::parse(R"({})"), Context{yield, session_}); ASSERT_TRUE(output); EXPECT_TRUE(output.result->as_object().empty()); @@ -532,7 +532,7 @@ TEST_F(RPCUnsubscribeTest, Streams) EXPECT_CALL(*mockSubscriptionManagerPtr, unsubProposedTransactions).Times(1); runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const output = handler.process(input, Context{yield, session_}); ASSERT_TRUE(output); EXPECT_TRUE(output.result->as_object().empty()); @@ -553,7 +553,7 @@ TEST_F(RPCUnsubscribeTest, Accounts) EXPECT_CALL(*mockSubscriptionManagerPtr, unsubAccount(rpc::accountFromStringStrict(ACCOUNT2).value(), _)).Times(1); runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const output = handler.process(input, Context{yield, session_}); ASSERT_TRUE(output); EXPECT_TRUE(output.result->as_object().empty()); @@ -576,7 +576,7 @@ TEST_F(RPCUnsubscribeTest, AccountsProposed) .Times(1); runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const output = handler.process(input, Context{yield, session_}); ASSERT_TRUE(output); EXPECT_TRUE(output.result->as_object().empty()); @@ -610,7 +610,7 @@ TEST_F(RPCUnsubscribeTest, Books) EXPECT_CALL(*mockSubscriptionManagerPtr, unsubBook(ripple::reversed(book), _)).Times(1); runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const output = handler.process(input, Context{yield, session_}); ASSERT_TRUE(output); EXPECT_TRUE(output.result->as_object().empty()); @@ -642,7 +642,7 @@ TEST_F(RPCUnsubscribeTest, SingleBooks) EXPECT_CALL(*mockSubscriptionManagerPtr, unsubBook(book, _)).Times(1); runSpawn([&, this](auto yield) { - auto const handler = AnyHandler{UnsubscribeHandler{backend, mockSubscriptionManagerPtr}}; + auto const handler = AnyHandler{UnsubscribeHandler{mockSubscriptionManagerPtr}}; auto const output = handler.process(input, Context{yield, session_}); ASSERT_TRUE(output); EXPECT_TRUE(output.result->as_object().empty());