fix: Check ledger range in every handler (#1755)

fixes #1565
This commit is contained in:
Peter Chen
2024-11-29 10:11:07 -05:00
committed by GitHub
parent f62fadc9f9
commit fe4f95dabd
47 changed files with 377 additions and 25 deletions

View File

@@ -111,7 +111,7 @@ ProductionHandlerProvider::ProductionHandlerProvider(
{"transaction_entry", {TransactionEntryHandler{backend}}}, {"transaction_entry", {TransactionEntryHandler{backend}}},
{"tx", {TxHandler{backend, etl}}}, {"tx", {TxHandler{backend, etl}}},
{"subscribe", {SubscribeHandler{backend, subscriptionManager}}}, {"subscribe", {SubscribeHandler{backend, subscriptionManager}}},
{"unsubscribe", {UnsubscribeHandler{backend, subscriptionManager}}}, {"unsubscribe", {UnsubscribeHandler{subscriptionManager}}},
{"version", {VersionHandler{config}}}, {"version", {VersionHandler{config}}},
} }
{ {

View File

@@ -28,6 +28,7 @@
#include "rpc/common/Specs.hpp" #include "rpc/common/Specs.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "rpc/common/Validators.hpp" #include "rpc/common/Validators.hpp"
#include "util/Assert.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -94,6 +95,8 @@ AMMInfoHandler::process(AMMInfoHandler::Input input, Context const& ctx) const
return Error{Status{RippledError::rpcINVALID_PARAMS}}; return Error{Status{RippledError::rpcINVALID_PARAMS}};
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AMMInfo's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
@@ -84,6 +85,7 @@ AccountChannelsHandler::Result
AccountChannelsHandler::process(AccountChannelsHandler::Input input, Context const& ctx) const AccountChannelsHandler::process(AccountChannelsHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountChannel's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
@@ -46,6 +47,7 @@ AccountCurrenciesHandler::Result
AccountCurrenciesHandler::process(AccountCurrenciesHandler::Input input, Context const& ctx) const AccountCurrenciesHandler::process(AccountCurrenciesHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountCurrencies' ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -25,6 +25,7 @@
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/JsonBool.hpp" #include "rpc/common/JsonBool.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -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))}}; return Error{Status{RippledError::rpcINVALID_PARAMS, ripple::RPC::missing_field_message(JS(account))}};
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountInfo's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
@@ -120,6 +121,7 @@ AccountLinesHandler::Result
AccountLinesHandler::process(AccountLinesHandler::Input input, Context const& ctx) const AccountLinesHandler::process(AccountLinesHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountLines' ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
@@ -52,6 +53,7 @@ AccountNFTsHandler::Result
AccountNFTsHandler::process(AccountNFTsHandler::Input input, Context const& ctx) const AccountNFTsHandler::process(AccountNFTsHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountNFT's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include "util/LedgerUtils.hpp" #include "util/LedgerUtils.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
@@ -52,6 +53,7 @@ AccountObjectsHandler::Result
AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const& ctx) const AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountObject's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
@@ -68,6 +69,7 @@ AccountOffersHandler::Result
AccountOffersHandler::process(AccountOffersHandler::Input input, Context const& ctx) const AccountOffersHandler::process(AccountOffersHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountOffer's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -25,6 +25,7 @@
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/JsonBool.hpp" #include "rpc/common/JsonBool.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include "util/JsonUtils.hpp" #include "util/JsonUtils.hpp"
#include "util/Profiler.hpp" #include "util/Profiler.hpp"
#include "util/log/Logger.hpp" #include "util/log/Logger.hpp"
@@ -55,6 +56,8 @@ AccountTxHandler::Result
AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) const AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "AccountTX's ledger range must be available");
auto [minIndex, maxIndex] = *range; auto [minIndex, maxIndex] = *range;
if (input.ledgerIndexMin) { if (input.ledgerIndexMin) {

View File

@@ -25,6 +25,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
@@ -45,6 +46,8 @@ BookChangesHandler::Result
BookChangesHandler::process(BookChangesHandler::Input input, Context const& ctx) const BookChangesHandler::process(BookChangesHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "BookChanges' ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
@@ -51,6 +52,8 @@ BookOffersHandler::process(Input input, Context const& ctx) const
// check ledger // check ledger
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "BookOffer's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -53,6 +53,8 @@ DepositAuthorizedHandler::Result
DepositAuthorizedHandler::process(DepositAuthorizedHandler::Input input, Context const& ctx) const DepositAuthorizedHandler::process(DepositAuthorizedHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "DepositAuthorized ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -27,6 +27,7 @@
#include "rpc/common/Specs.hpp" #include "rpc/common/Specs.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "rpc/common/Validators.hpp" #include "rpc/common/Validators.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
@@ -56,6 +57,8 @@ FeatureHandler::process(FeatureHandler::Input input, Context const& ctx) const
namespace rg = std::ranges; namespace rg = std::ranges;
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "Feature's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -59,6 +60,8 @@ GatewayBalancesHandler::process(GatewayBalancesHandler::Input input, Context con
{ {
// check ledger // check ledger
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "GatewayBalances' ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -24,6 +24,7 @@
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/AccountUtils.hpp" #include "util/AccountUtils.hpp"
#include "util/Assert.hpp"
#include <boost/asio/spawn.hpp> #include <boost/asio/spawn.hpp>
#include <boost/bimap/bimap.hpp> #include <boost/bimap/bimap.hpp>
@@ -61,6 +62,8 @@ GetAggregatePriceHandler::Result
GetAggregatePriceHandler::process(GetAggregatePriceHandler::Input input, Context const& ctx) const GetAggregatePriceHandler::process(GetAggregatePriceHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "GetAggregatePrice's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -24,6 +24,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -52,6 +53,8 @@ LedgerHandler::Result
LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "LedgerHandler's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -24,6 +24,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include "util/LedgerUtils.hpp" #include "util/LedgerUtils.hpp"
#include "util/log/Logger.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"}}; return Error{Status{RippledError::rpcINVALID_PARAMS, "markerNotString"}};
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "LedgerData's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );
@@ -117,7 +120,7 @@ LedgerDataHandler::process(Input input, Context const& ctx) const
if (page.cursor) { if (page.cursor) {
output.marker = ripple::strHex(*(page.cursor)); output.marker = ripple::strHex(*(page.cursor));
} else if (input.outOfOrder) { } else if (input.outOfOrder) {
output.diffMarker = sharedPtrBackend_->fetchLedgerRange()->maxSequence; output.diffMarker = range->maxSequence;
} }
} }

View File

@@ -188,7 +188,7 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input input, Context const& ctx)
// check ledger exists // check ledger exists
auto const range = sharedPtrBackend_->fetchLedgerRange(); 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( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -22,6 +22,7 @@
#include "rpc/Errors.hpp" #include "rpc/Errors.hpp"
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include "util/TimeUtils.hpp" #include "util/TimeUtils.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -42,6 +43,8 @@ LedgerIndexHandler::Result
LedgerIndexHandler::process(LedgerIndexHandler::Input input, Context const& ctx) const LedgerIndexHandler::process(LedgerIndexHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "LedgerIndex's ledger range must be available");
auto const [minIndex, maxIndex] = *range; auto const [minIndex, maxIndex] = *range;
auto const fillOutputByIndex = [&](std::uint32_t index) { auto const fillOutputByIndex = [&](std::uint32_t index) {

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -49,6 +50,8 @@ MPTHoldersHandler::Result
MPTHoldersHandler::process(MPTHoldersHandler::Input input, Context const& ctx) const MPTHoldersHandler::process(MPTHoldersHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "MPTHolder's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -24,6 +24,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include "util/Profiler.hpp" #include "util/Profiler.hpp"
#include "util/log/Logger.hpp" #include "util/log/Logger.hpp"
@@ -53,6 +54,8 @@ NFTHistoryHandler::Result
NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) const NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "NFTHistory's ledger range must be available");
auto [minIndex, maxIndex] = *range; auto [minIndex, maxIndex] = *range;
if (input.ledgerIndexMin) { if (input.ledgerIndexMin) {

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
@@ -47,6 +48,8 @@ NFTInfoHandler::process(NFTInfoHandler::Input input, Context const& ctx) const
{ {
auto const tokenID = ripple::uint256{input.nftID.c_str()}; auto const tokenID = ripple::uint256{input.nftID.c_str()};
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "NFTInfo's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/asio/spawn.hpp> #include <boost/asio/spawn.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -90,6 +91,8 @@ NFTOffersHandlerBase::iterateOfferDirectory(
) const ) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "NFTOffersCommon's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
@@ -48,6 +49,8 @@ NFTsByIssuerHandler::Result
NFTsByIssuerHandler::process(NFTsByIssuerHandler::Input input, Context const& ctx) const NFTsByIssuerHandler::process(NFTsByIssuerHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "NFTsByIssuer's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -24,6 +24,7 @@
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/JsonBool.hpp" #include "rpc/common/JsonBool.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -58,6 +59,8 @@ NoRippleCheckHandler::Result
NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& ctx) const NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "NoRippleCheck's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -26,6 +26,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/common/Specs.hpp" #include "rpc/common/Specs.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include "util/build/Build.hpp" #include "util/build/Build.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
@@ -196,6 +197,8 @@ public:
using namespace std::chrono; using namespace std::chrono;
auto const range = backend_->fetchLedgerRange(); 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); auto const lgrInfo = backend_->fetchLedgerBySequence(range->maxSequence, ctx.yield);
if (not lgrInfo.has_value()) if (not lgrInfo.has_value())
return Error{Status{RippledError::rpcINTERNAL}}; return Error{Status{RippledError::rpcINTERNAL}};

View File

@@ -31,6 +31,7 @@
#include "rpc/common/Specs.hpp" #include "rpc/common/Specs.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "rpc/common/Validators.hpp" #include "rpc/common/Validators.hpp"
#include "util/Assert.hpp"
#include <boost/asio/spawn.hpp> #include <boost/asio/spawn.hpp>
#include <boost/json/array.hpp> #include <boost/json/array.hpp>
@@ -201,8 +202,10 @@ SubscribeHandler::subscribeToBooks(
for (auto const& internalBook : books) { for (auto const& internalBook : books) {
if (internalBook.snapshot) { if (internalBook.snapshot) {
if (!rng) if (!rng) {
rng = sharedPtrBackend_->fetchLedgerRange(); rng = sharedPtrBackend_->fetchLedgerRange();
ASSERT(rng.has_value(), "Subscribe's ledger range must be available");
}
auto const getOrderBook = [&](auto const& book, auto& snapshots) { auto const getOrderBook = [&](auto const& book, auto& snapshots) {
auto const bookBase = getBookBase(book); auto const bookBase = getBookBase(book);

View File

@@ -23,6 +23,7 @@
#include "rpc/JS.hpp" #include "rpc/JS.hpp"
#include "rpc/RPCHelpers.hpp" #include "rpc/RPCHelpers.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "util/Assert.hpp"
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
@@ -43,6 +44,8 @@ TransactionEntryHandler::Result
TransactionEntryHandler::process(TransactionEntryHandler::Input input, Context const& ctx) const TransactionEntryHandler::process(TransactionEntryHandler::Input input, Context const& ctx) const
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "TransactionEntry's ledger range must be available");
auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq( auto const lgrInfoOrStatus = getLedgerHeaderFromHashOrSeq(
*sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence
); );

View File

@@ -29,6 +29,7 @@
#include "rpc/common/Specs.hpp" #include "rpc/common/Specs.hpp"
#include "rpc/common/Types.hpp" #include "rpc/common/Types.hpp"
#include "rpc/common/Validators.hpp" #include "rpc/common/Validators.hpp"
#include "util/Assert.hpp"
#include "util/JsonUtils.hpp" #include "util/JsonUtils.hpp"
#include <boost/asio/spawn.hpp> #include <boost/asio/spawn.hpp>
@@ -188,6 +189,8 @@ public:
if (rangeSupplied && input.transaction) // ranges not for ctid if (rangeSupplied && input.transaction) // ranges not for ctid
{ {
auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const range = sharedPtrBackend_->fetchLedgerRange();
ASSERT(range.has_value(), "Tx's ledger range must be available");
auto const searchedAll = auto const searchedAll =
range->maxSequence >= *input.maxLedger && range->minSequence <= *input.minLedger; range->maxSequence >= *input.maxLedger && range->minSequence <= *input.minLedger;
boost::json::object extra; boost::json::object extra;

View File

@@ -19,7 +19,6 @@
#include "rpc/handlers/Unsubscribe.hpp" #include "rpc/handlers/Unsubscribe.hpp"
#include "data/BackendInterface.hpp"
#include "feed/SubscriptionManagerInterface.hpp" #include "feed/SubscriptionManagerInterface.hpp"
#include "feed/Types.hpp" #include "feed/Types.hpp"
#include "rpc/Errors.hpp" #include "rpc/Errors.hpp"
@@ -46,11 +45,8 @@
namespace rpc { namespace rpc {
UnsubscribeHandler::UnsubscribeHandler( UnsubscribeHandler::UnsubscribeHandler(std::shared_ptr<feed::SubscriptionManagerInterface> const& subscriptions)
std::shared_ptr<BackendInterface> const& sharedPtrBackend, : subscriptions_(subscriptions)
std::shared_ptr<feed::SubscriptionManagerInterface> const& subscriptions
)
: sharedPtrBackend_(sharedPtrBackend), subscriptions_(subscriptions)
{ {
} }

View File

@@ -19,7 +19,6 @@
#pragma once #pragma once
#include "data/BackendInterface.hpp"
#include "feed/SubscriptionManagerInterface.hpp" #include "feed/SubscriptionManagerInterface.hpp"
#include "feed/Types.hpp" #include "feed/Types.hpp"
#include "rpc/common/Specs.hpp" #include "rpc/common/Specs.hpp"
@@ -49,7 +48,6 @@ namespace rpc {
*/ */
class UnsubscribeHandler { class UnsubscribeHandler {
std::shared_ptr<BackendInterface> sharedPtrBackend_;
std::shared_ptr<feed::SubscriptionManagerInterface> subscriptions_; std::shared_ptr<feed::SubscriptionManagerInterface> subscriptions_;
public: public:
@@ -77,13 +75,9 @@ public:
/** /**
* @brief Construct a new BaseUnsubscribeHandler object * @brief Construct a new BaseUnsubscribeHandler object
* *
* @param sharedPtrBackend The backend to use
* @param subscriptions The subscription manager to use * @param subscriptions The subscription manager to use
*/ */
UnsubscribeHandler( UnsubscribeHandler(std::shared_ptr<feed::SubscriptionManagerInterface> const& subscriptions);
std::shared_ptr<BackendInterface> const& sharedPtrBackend,
std::shared_ptr<feed::SubscriptionManagerInterface> const& subscriptions
);
/** /**
* @brief Returns the API specification for the command * @brief Returns the API specification for the command

View File

@@ -77,11 +77,14 @@ private:
struct SyncAsioContextTest : virtual public NoLoggerFixture { struct SyncAsioContextTest : virtual public NoLoggerFixture {
template <typename F> template <typename F>
void void
runSpawn(F&& f) runSpawn(F&& f, bool allowMockLeak = false)
{ {
using namespace boost::asio; using namespace boost::asio;
testing::MockFunction<void()> call; testing::MockFunction<void()> call;
if (allowMockLeak)
testing::Mock::AllowLeak(&call);
spawn(ctx, [&, _ = make_work_guard(ctx)](yield_context yield) { spawn(ctx, [&, _ = make_work_guard(ctx)](yield_context yield) {
f(yield); f(yield);
call.Call(); call.Call();

View File

@@ -67,6 +67,7 @@ target_sources(
rpc/handlers/AccountOffersTests.cpp rpc/handlers/AccountOffersTests.cpp
rpc/handlers/AccountTxTests.cpp rpc/handlers/AccountTxTests.cpp
rpc/handlers/AMMInfoTests.cpp rpc/handlers/AMMInfoTests.cpp
rpc/handlers/AllHandlerTests.cpp
rpc/handlers/BookChangesTests.cpp rpc/handlers/BookChangesTests.cpp
rpc/handlers/BookOffersTests.cpp rpc/handlers/BookOffersTests.cpp
rpc/handlers/CredentialHelpersTests.cpp rpc/handlers/CredentialHelpersTests.cpp

View File

@@ -197,6 +197,7 @@ TEST_F(LoadBalancerConstructorDeathTest, numMarkersSpecifiedInConfigIsInvalid)
{ {
uint32_t const numMarkers = 257; uint32_t const numMarkers = 257;
configJson_.as_object()["num_markers"] = numMarkers; configJson_.as_object()["num_markers"] = numMarkers;
testing::Mock::AllowLeak(&sourceFactory_);
EXPECT_DEATH({ makeLoadBalancer(); }, ".*"); EXPECT_DEATH({ makeLoadBalancer(); }, ".*");
} }

View File

@@ -273,6 +273,8 @@ TEST_F(RPCAccountChannelsHandlerTest, AccountNotString)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCAccountChannelsHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCAccountChannelsHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))
.WillByDefault(Return(std::optional<ripple::LedgerHeader>{})); .WillByDefault(Return(std::optional<ripple::LedgerHeader>{}));

View File

@@ -133,6 +133,8 @@ TEST_P(AccountInfoParameterTest, InvalidParams)
TEST_F(AccountInfoParameterTest, ApiV1SignerListIsNotBool) TEST_F(AccountInfoParameterTest, ApiV1SignerListIsNotBool)
{ {
backend->setRange(10, 30);
static constexpr auto reqJson = R"( static constexpr auto reqJson = R"(
{"ident":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", "signer_lists":1} {"ident":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", "signer_lists":1}
)"; )";

View File

@@ -319,6 +319,8 @@ TEST_F(RPCAccountLinesHandlerTest, LimitZero)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCAccountLinesHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCAccountLinesHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))
.WillByDefault(Return(std::optional<ripple::LedgerHeader>{})); .WillByDefault(Return(std::optional<ripple::LedgerHeader>{}));

View File

@@ -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 <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/json/parse.hpp>
#include <fmt/core.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/UintTypes.h>
#include <memory>
#include <string>
#include <vector>
using ::testing::Types;
using namespace rpc;
using TestServerInfoHandler = BaseServerInfoHandler<MockLoadBalancer, MockETLService, MockCounters>;
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 <typename HandlerType>
struct AllHandlersDeathTest : HandlerBaseTest,
MockLoadBalancerTest,
MockCountersTest,
testing::WithParamInterface<std::string> {
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* mockSession_ = dynamic_cast<MockSession*>(session_.get());
StrictMockSubscriptionManagerSharedPtr mockSubscriptionManagerPtr;
StrictMockAmendmentCenterSharedPtr mockAmendmentCenterPtr;
HandlerType handler_;
private:
HandlerType
initHandler()
{
if constexpr (std::is_same_v<HandlerType, AccountInfoHandler> || std::is_same_v<HandlerType, FeatureHandler>) {
return HandlerType{this->backend, this->mockAmendmentCenterPtr};
} else if constexpr (std::is_same_v<HandlerType, SubscribeHandler>) {
return HandlerType{this->backend, this->mockSubscriptionManagerPtr};
} else if constexpr (std::is_same_v<HandlerType, TestServerInfoHandler>) {
return HandlerType{
this->backend,
this->mockSubscriptionManagerPtr,
mockLoadBalancerPtr,
mockETLServicePtr,
*mockCountersPtr
};
} else {
return HandlerType{this->backend};
}
}
};
template <typename Handler>
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>()
{
AccountInfoHandler::Input input{};
input.account = Account;
input.ident = "asdf";
return input;
}
template <>
AMMInfoHandler::Input
createInput<AMMInfoHandler>()
{
AMMInfoHandler::Input input{};
input.ammAccount = GetAccountIDWithString(AmmAccount);
return input;
}
template <>
BookOffersHandler::Input
createInput<BookOffersHandler>()
{
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>()
{
LedgerEntryHandler::Input input{};
input.index = Index1;
return input;
}
template <>
NFTBuyOffersHandler::Input
createInput<NFTBuyOffersHandler>()
{
NFTBuyOffersHandler::Input input{};
input.nftID = NftID;
return input;
}
template <>
NFTInfoHandler::Input
createInput<NFTInfoHandler>()
{
NFTInfoHandler::Input input{};
input.nftID = NftID;
return input;
}
template <>
NFTSellOffersHandler::Input
createInput<NFTSellOffersHandler>()
{
NFTSellOffersHandler::Input input{};
input.nftID = NftID;
return input;
}
template <>
SubscribeHandler::Input
createInput<SubscribeHandler>()
{
SubscribeHandler::Input input{};
input.books =
std::vector<SubscribeHandler::OrderBook>{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<TypeParam>();
auto const context = Context{yield, this->session_};
EXPECT_DEATH(
{ [[maybe_unused]] auto _unused = handler.process(input, context); }, "Assertion .* failed at .*"
);
},
true
);
}

View File

@@ -223,6 +223,8 @@ TEST_F(RPCMPTHoldersHandlerTest, MarkerNotString)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCMPTHoldersHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCMPTHoldersHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
EXPECT_CALL(*backend, fetchLedgerByHash).Times(1); EXPECT_CALL(*backend, fetchLedgerByHash).Times(1);
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))

View File

@@ -210,6 +210,8 @@ TEST_F(RPCNFTBuyOffersHandlerTest, NFTIDNotString)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCNFTBuyOffersHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCNFTBuyOffersHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))
.WillByDefault(Return(std::optional<ripple::LedgerHeader>{})); .WillByDefault(Return(std::optional<ripple::LedgerHeader>{}));

View File

@@ -148,6 +148,8 @@ TEST_F(RPCNFTInfoHandlerTest, NFTIDNotString)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCNFTInfoHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCNFTInfoHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))
.WillByDefault(Return(std::optional<ripple::LedgerHeader>{})); .WillByDefault(Return(std::optional<ripple::LedgerHeader>{}));

View File

@@ -210,6 +210,8 @@ TEST_F(RPCNFTSellOffersHandlerTest, NFTIDNotString)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCNFTSellOffersHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCNFTSellOffersHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))
.WillByDefault(Return(std::optional<ripple::LedgerHeader>{})); .WillByDefault(Return(std::optional<ripple::LedgerHeader>{}));

View File

@@ -206,6 +206,8 @@ TEST_F(RPCNFTsByIssuerHandlerTest, NFTIssuerNotString)
// error case ledger non exist via hash // error case ledger non exist via hash
TEST_F(RPCNFTsByIssuerHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCNFTsByIssuerHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
EXPECT_CALL(*backend, fetchLedgerByHash).Times(1); EXPECT_CALL(*backend, fetchLedgerByHash).Times(1);
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{LEDGERHASH}, _))

View File

@@ -181,6 +181,8 @@ TEST_P(NoRippleCheckParameterTest, InvalidParams)
TEST_F(NoRippleCheckParameterTest, V1ApiTransactionsIsNotBool) TEST_F(NoRippleCheckParameterTest, V1ApiTransactionsIsNotBool)
{ {
backend->setRange(10, 30);
static constexpr auto reqJson = R"( static constexpr auto reqJson = R"(
{ {
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",

View File

@@ -77,6 +77,8 @@ TEST_F(RPCTransactionEntryHandlerTest, TxHashWrongFormat)
TEST_F(RPCTransactionEntryHandlerTest, NonExistLedgerViaLedgerHash) TEST_F(RPCTransactionEntryHandlerTest, NonExistLedgerViaLedgerHash)
{ {
backend->setRange(10, 30);
// mock fetchLedgerByHash return empty // mock fetchLedgerByHash return empty
ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{INDEX}, _)) ON_CALL(*backend, fetchLedgerByHash(ripple::uint256{INDEX}, _))
.WillByDefault(Return(std::optional<ripple::LedgerHeader>{})); .WillByDefault(Return(std::optional<ripple::LedgerHeader>{}));

View File

@@ -496,7 +496,7 @@ TEST_P(UnsubscribeParameterTest, InvalidParams)
{ {
auto const testBundle = GetParam(); auto const testBundle = GetParam();
runSpawn([&, this](auto yield) { 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 req = json::parse(testBundle.testJson);
auto const output = handler.process(req, Context{yield}); auto const output = handler.process(req, Context{yield});
ASSERT_FALSE(output); ASSERT_FALSE(output);
@@ -509,7 +509,7 @@ TEST_P(UnsubscribeParameterTest, InvalidParams)
TEST_F(RPCUnsubscribeTest, EmptyResponse) TEST_F(RPCUnsubscribeTest, EmptyResponse)
{ {
runSpawn([&, this](auto yield) { 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_}); auto const output = handler.process(json::parse(R"({})"), Context{yield, session_});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output.result->as_object().empty()); EXPECT_TRUE(output.result->as_object().empty());
@@ -532,7 +532,7 @@ TEST_F(RPCUnsubscribeTest, Streams)
EXPECT_CALL(*mockSubscriptionManagerPtr, unsubProposedTransactions).Times(1); EXPECT_CALL(*mockSubscriptionManagerPtr, unsubProposedTransactions).Times(1);
runSpawn([&, this](auto yield) { 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_}); auto const output = handler.process(input, Context{yield, session_});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output.result->as_object().empty()); 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); EXPECT_CALL(*mockSubscriptionManagerPtr, unsubAccount(rpc::accountFromStringStrict(ACCOUNT2).value(), _)).Times(1);
runSpawn([&, this](auto yield) { 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_}); auto const output = handler.process(input, Context{yield, session_});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output.result->as_object().empty()); EXPECT_TRUE(output.result->as_object().empty());
@@ -576,7 +576,7 @@ TEST_F(RPCUnsubscribeTest, AccountsProposed)
.Times(1); .Times(1);
runSpawn([&, this](auto yield) { 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_}); auto const output = handler.process(input, Context{yield, session_});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output.result->as_object().empty()); EXPECT_TRUE(output.result->as_object().empty());
@@ -610,7 +610,7 @@ TEST_F(RPCUnsubscribeTest, Books)
EXPECT_CALL(*mockSubscriptionManagerPtr, unsubBook(ripple::reversed(book), _)).Times(1); EXPECT_CALL(*mockSubscriptionManagerPtr, unsubBook(ripple::reversed(book), _)).Times(1);
runSpawn([&, this](auto yield) { 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_}); auto const output = handler.process(input, Context{yield, session_});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output.result->as_object().empty()); EXPECT_TRUE(output.result->as_object().empty());
@@ -642,7 +642,7 @@ TEST_F(RPCUnsubscribeTest, SingleBooks)
EXPECT_CALL(*mockSubscriptionManagerPtr, unsubBook(book, _)).Times(1); EXPECT_CALL(*mockSubscriptionManagerPtr, unsubBook(book, _)).Times(1);
runSpawn([&, this](auto yield) { 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_}); auto const output = handler.process(input, Context{yield, session_});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output.result->as_object().empty()); EXPECT_TRUE(output.result->as_object().empty());