diff --git a/src/rpc/handlers/AccountTx.hpp b/src/rpc/handlers/AccountTx.hpp index 712ff82c..0e620a8c 100644 --- a/src/rpc/handlers/AccountTx.hpp +++ b/src/rpc/handlers/AccountTx.hpp @@ -25,6 +25,7 @@ #include "rpc/common/JsonBool.hpp" #include "rpc/common/MetaProcessors.hpp" #include "rpc/common/Modifiers.hpp" +#include "rpc/common/Specs.hpp" #include "rpc/common/Types.hpp" #include "rpc/common/Validators.hpp" #include "util/TxUtils.hpp" @@ -39,7 +40,6 @@ #include #include -#include #include #include #include @@ -57,8 +57,8 @@ class AccountTxHandler { std::shared_ptr sharedPtrBackend_; public: - // no max limit static constexpr auto kLIMIT_MIN = 1; + static constexpr auto kLIMIT_MAX = 1000; static constexpr auto kLIMIT_DEFAULT = 200; /** @@ -133,7 +133,7 @@ public: {JS(limit), validation::Type{}, validation::Min(1u), - modifiers::Clamp{kLIMIT_MIN, std::numeric_limits::max()}}, + modifiers::Clamp{kLIMIT_MIN, kLIMIT_MAX}}, {JS(marker), meta::WithCustomError{ validation::Type{}, diff --git a/tests/unit/rpc/WorkQueueTests.cpp b/tests/unit/rpc/WorkQueueTests.cpp index ccc4fa5e..5253cc9e 100644 --- a/tests/unit/rpc/WorkQueueTests.cpp +++ b/tests/unit/rpc/WorkQueueTests.cpp @@ -56,12 +56,7 @@ TEST_F(WorkQueueTest, WhitelistedExecutionCountAddsUp) std::atomic_uint32_t executeCount = 0u; for (auto i = 0u; i < kTOTAL; ++i) { - queue.postCoro( - [&executeCount](auto /* yield */) { - ++executeCount; - }, - true - ); + queue.postCoro([&executeCount](auto /* yield */) { ++executeCount; }, true); } queue.join(); diff --git a/tests/unit/rpc/handlers/AccountTxTests.cpp b/tests/unit/rpc/handlers/AccountTxTests.cpp index 2b2beadd..049c5174 100644 --- a/tests/unit/rpc/handlers/AccountTxTests.cpp +++ b/tests/unit/rpc/handlers/AccountTxTests.cpp @@ -766,14 +766,13 @@ TEST_F(RPCAccountTxHandlerTest, LimitAndMarker) { auto const transactions = genTransactions(kMIN_SEQ + 1, kMAX_SEQ - 1); auto const transCursor = TransactionsAndCursor{.txns = transactions, .cursor = 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_}}; @@ -801,6 +800,69 @@ TEST_F(RPCAccountTxHandlerTest, LimitAndMarker) }); } +TEST_F(RPCAccountTxHandlerTest, LimitIsCapped) +{ + auto const transactions = genTransactions(kMIN_SEQ + 1, kMAX_SEQ - 1); + auto const transCursor = TransactionsAndCursor{.txns = transactions, .cursor = 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 kINPUT = json::parse(fmt::format( + R"({{ + "account": "{}", + "ledger_index_min": {}, + "ledger_index_max": {}, + "limit": 100000, + "forward": false + }})", + kACCOUNT, + -1, + -1 + )); + auto const output = handler.process(kINPUT, Context{yield}); + ASSERT_TRUE(output); + EXPECT_EQ(output.result->at("account").as_string(), kACCOUNT); + EXPECT_EQ(output.result->at("ledger_index_min").as_uint64(), kMIN_SEQ); + EXPECT_EQ(output.result->at("ledger_index_max").as_uint64(), kMAX_SEQ); + EXPECT_EQ(output.result->at("limit").as_uint64(), AccountTxHandler::kLIMIT_MAX); + EXPECT_EQ(output.result->at("transactions").as_array().size(), 2); + }); +} + +TEST_F(RPCAccountTxHandlerTest, LimitAllowedUpToCap) +{ + auto const transactions = genTransactions(kMIN_SEQ + 1, kMAX_SEQ - 1); + auto const transCursor = TransactionsAndCursor{.txns = transactions, .cursor = 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 kINPUT = json::parse(fmt::format( + R"({{ + "account": "{}", + "ledger_index_min": {}, + "ledger_index_max": {}, + "limit": {}, + "forward": false + }})", + kACCOUNT, + -1, + -1, + AccountTxHandler::kLIMIT_MAX - 1 + )); + auto const output = handler.process(kINPUT, Context{yield}); + ASSERT_TRUE(output); + EXPECT_EQ(output.result->at("account").as_string(), kACCOUNT); + EXPECT_EQ(output.result->at("ledger_index_min").as_uint64(), kMIN_SEQ); + EXPECT_EQ(output.result->at("ledger_index_max").as_uint64(), kMAX_SEQ); + EXPECT_EQ(output.result->at("limit").as_uint64(), AccountTxHandler::kLIMIT_MAX - 1); + EXPECT_EQ(output.result->at("transactions").as_array().size(), 2); + }); +} + TEST_F(RPCAccountTxHandlerTest, SpecificLedgerIndex) { // adjust the order for forward->false