mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-01 17:15:52 +00:00
@@ -528,19 +528,21 @@ public:
|
||||
SELECT hash, seq_idx
|
||||
FROM {}
|
||||
WHERE account = ?
|
||||
AND seq_idx < ?
|
||||
AND seq_idx <= ?
|
||||
LIMIT ?
|
||||
)",
|
||||
qualifiedTableName(settingsProvider_.get(), "account_tx")));
|
||||
}();
|
||||
|
||||
// the smallest transaction idx is 0, we use uint to store the transaction index, so we shall use ">=" to
|
||||
// include it(the transaction with idx 0) in the result
|
||||
PreparedStatement selectAccountTxForward = [this]() {
|
||||
return handle_.get().prepare(fmt::format(
|
||||
R"(
|
||||
SELECT hash, seq_idx
|
||||
FROM {}
|
||||
WHERE account = ?
|
||||
AND seq_idx > ?
|
||||
AND seq_idx >= ?
|
||||
ORDER BY seq_idx ASC
|
||||
LIMIT ?
|
||||
)",
|
||||
|
||||
@@ -49,7 +49,7 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con
|
||||
if (minIndex > maxIndex)
|
||||
return Error{Status{RippledError::rpcLGR_IDXS_INVALID}};
|
||||
|
||||
if (input.ledgerHash || input.ledgerIndex)
|
||||
if (input.ledgerHash || input.ledgerIndex || input.usingValidatedLedger)
|
||||
{
|
||||
// rippled does not have this check
|
||||
if (input.ledgerIndexMax || input.ledgerIndexMin)
|
||||
@@ -190,6 +190,9 @@ tag_invoke(boost::json::value_to_tag<AccountTxHandler::Input>, boost::json::valu
|
||||
input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64();
|
||||
else if (jsonObject.at(JS(ledger_index)).as_string() != "validated")
|
||||
input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str());
|
||||
else
|
||||
// could not get the latest validated ledger seq here, using this flag to indicate that
|
||||
input.usingValidatedLedger = true;
|
||||
}
|
||||
|
||||
if (jsonObject.contains(JS(binary)))
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
std::optional<uint32_t> ledgerIndex;
|
||||
std::optional<int32_t> ledgerIndexMin;
|
||||
std::optional<int32_t> ledgerIndexMax;
|
||||
bool usingValidatedLedger = false;
|
||||
bool binary = false;
|
||||
bool forward = false;
|
||||
std::optional<uint32_t> limit;
|
||||
|
||||
@@ -191,6 +191,16 @@ generateTestValuesForParametersTest()
|
||||
})",
|
||||
"invalidParams",
|
||||
"containsLedgerSpecifierAndRange"},
|
||||
AccountTxParamTestCaseBundle{
|
||||
"LedgerIndexMaxMinAndLedgerIndexValidated",
|
||||
R"({
|
||||
"account":"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"ledger_index_max": 20,
|
||||
"ledger_index_min": 11,
|
||||
"ledger_index": "validated"
|
||||
})",
|
||||
"invalidParams",
|
||||
"containsLedgerSpecifierAndRange"},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -631,6 +641,48 @@ TEST_F(RPCAccountTxHandlerTest, SpecificLedgerHash)
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCAccountTxHandlerTest, SpecificLedgerIndexValidated)
|
||||
{
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
MockBackend* rawBackendPtr = static_cast<MockBackend*>(mockBackendPtr.get());
|
||||
// adjust the order for forward->false
|
||||
auto const transactions = genTransactions(MAXSEQ, MAXSEQ - 1);
|
||||
auto const transCursor = TransactionsAndCursor{transactions, TransactionsCursor{12, 34}};
|
||||
ON_CALL(*rawBackendPtr, fetchAccountTransactions).WillByDefault(Return(transCursor));
|
||||
EXPECT_CALL(
|
||||
*rawBackendPtr,
|
||||
fetchAccountTransactions(
|
||||
testing::_,
|
||||
testing::_,
|
||||
false,
|
||||
testing::Optional(testing::Eq(TransactionsCursor{MAXSEQ, INT32_MAX})),
|
||||
testing::_))
|
||||
.Times(1);
|
||||
|
||||
auto const ledgerinfo = CreateLedgerInfo(LEDGERHASH, MAXSEQ);
|
||||
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).Times(1);
|
||||
ON_CALL(*rawBackendPtr, fetchLedgerBySequence(MAXSEQ, _)).WillByDefault(Return(ledgerinfo));
|
||||
|
||||
runSpawn([&, this](auto& yield) {
|
||||
auto const handler = AnyHandler{AccountTxHandler{mockBackendPtr}};
|
||||
auto const static input = boost::json::parse(fmt::format(
|
||||
R"({{
|
||||
"account":"{}",
|
||||
"ledger_index":"validated"
|
||||
}})",
|
||||
ACCOUNT));
|
||||
auto const output = handler.process(input, Context{std::ref(yield)});
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_EQ(output->at("account").as_string(), ACCOUNT);
|
||||
EXPECT_EQ(output->at("ledger_index_min").as_uint64(), MAXSEQ);
|
||||
EXPECT_EQ(output->at("ledger_index_max").as_uint64(), MAXSEQ);
|
||||
EXPECT_FALSE(output->as_object().contains("limit"));
|
||||
EXPECT_FALSE(output->as_object().contains("marker"));
|
||||
EXPECT_EQ(output->at("transactions").as_array().size(), 1);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCAccountTxHandlerTest, TxLessThanMinSeq)
|
||||
{
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
|
||||
Reference in New Issue
Block a user