diff --git a/src/rpc/handlers/AccountTx.hpp b/src/rpc/handlers/AccountTx.hpp index a5fea6e30..be91ee290 100644 --- a/src/rpc/handlers/AccountTx.hpp +++ b/src/rpc/handlers/AccountTx.hpp @@ -39,7 +39,6 @@ #include #include -#include #include #include #include @@ -57,8 +56,8 @@ class AccountTxHandler { std::shared_ptr sharedPtrBackend_; public: - // no max limit static auto constexpr LIMIT_MIN = 1; + static auto constexpr LIMIT_MAX = 1000; static auto constexpr LIMIT_DEFAULT = 200; /** @@ -133,7 +132,7 @@ class AccountTxHandler { {JS(limit), validation::Type{}, validation::Min(1u), - modifiers::Clamp{LIMIT_MIN, std::numeric_limits::max()}}, + modifiers::Clamp{LIMIT_MIN, LIMIT_MAX}}, {JS(marker), meta::WithCustomError{ validation::Type{}, diff --git a/tests/unit/rpc/handlers/AccountTxTests.cpp b/tests/unit/rpc/handlers/AccountTxTests.cpp index 67fb6c481..32ce62894 100644 --- a/tests/unit/rpc/handlers/AccountTxTests.cpp +++ b/tests/unit/rpc/handlers/AccountTxTests.cpp @@ -769,14 +769,13 @@ TEST_F(RPCAccountTxHandlerTest, LimitAndMarker) auto const transactions = genTransactions(MINSEQ + 1, MAXSEQ - 1); auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}}; - ON_CALL(*backend, fetchAccountTransactions).WillByDefault(Return(transCursor)); EXPECT_CALL( *backend, fetchAccountTransactions( testing::_, testing::_, false, testing::Optional(testing::Eq(TransactionsCursor{10, 11})), testing::_ ) ) - .Times(1); + .WillOnce(Return(transCursor)); runSpawn([&, this](auto yield) { auto const handler = AnyHandler{AccountTxHandler{backend}}; @@ -804,6 +803,73 @@ TEST_F(RPCAccountTxHandlerTest, LimitAndMarker) }); } +TEST_F(RPCAccountTxHandlerTest, LimitIsCapped) +{ + backend->setRange(MINSEQ, MAXSEQ); + + auto const transactions = genTransactions(MINSEQ + 1, MAXSEQ - 1); + auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}}; + EXPECT_CALL(*backend, fetchAccountTransactions(testing::_, testing::_, false, testing::_, testing::_)) + .WillOnce(Return(transCursor)); + + runSpawn([&, this](auto yield) { + auto const handler = AnyHandler{AccountTxHandler{backend}}; + auto static const input = json::parse(fmt::format( + R"({{ + "account": "{}", + "ledger_index_min": {}, + "ledger_index_max": {}, + "limit": 100000, + "forward": false + }})", + ACCOUNT, + -1, + -1 + )); + auto const output = handler.process(input, Context{yield}); + ASSERT_TRUE(output); + EXPECT_EQ(output.result->at("account").as_string(), ACCOUNT); + EXPECT_EQ(output.result->at("ledger_index_min").as_uint64(), MINSEQ); + EXPECT_EQ(output.result->at("ledger_index_max").as_uint64(), MAXSEQ); + EXPECT_EQ(output.result->at("limit").as_uint64(), AccountTxHandler::LIMIT_MAX); + EXPECT_EQ(output.result->at("transactions").as_array().size(), 2); + }); +} + +TEST_F(RPCAccountTxHandlerTest, LimitAllowedUpToCap) +{ + backend->setRange(MINSEQ, MAXSEQ); + + auto const transactions = genTransactions(MINSEQ + 1, MAXSEQ - 1); + auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}}; + EXPECT_CALL(*backend, fetchAccountTransactions(testing::_, testing::_, false, testing::_, testing::_)) + .WillOnce(Return(transCursor)); + + runSpawn([&, this](auto yield) { + auto const handler = AnyHandler{AccountTxHandler{backend}}; + auto static const input = json::parse(fmt::format( + R"({{ + "account": "{}", + "ledger_index_min": {}, + "ledger_index_max": {}, + "limit": {}, + "forward": false + }})", + ACCOUNT, + -1, + -1, + AccountTxHandler::LIMIT_MAX - 1 + )); + auto const output = handler.process(input, Context{yield}); + ASSERT_TRUE(output); + EXPECT_EQ(output.result->at("account").as_string(), ACCOUNT); + EXPECT_EQ(output.result->at("ledger_index_min").as_uint64(), MINSEQ); + EXPECT_EQ(output.result->at("ledger_index_max").as_uint64(), MAXSEQ); + EXPECT_EQ(output.result->at("limit").as_uint64(), AccountTxHandler::LIMIT_MAX - 1); + EXPECT_EQ(output.result->at("transactions").as_array().size(), 2); + }); +} + TEST_F(RPCAccountTxHandlerTest, SpecificLedgerIndex) { backend->setRange(MINSEQ, MAXSEQ);