mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-22 04:35:50 +00:00
@@ -359,7 +359,7 @@ toJson(ripple::SLE const& sle)
|
||||
}
|
||||
|
||||
boost::json::object
|
||||
toJson(ripple::LedgerHeader const& lgrInfo, bool const binary)
|
||||
toJson(ripple::LedgerHeader const& lgrInfo, bool const binary, std::uint32_t const apiVersion)
|
||||
{
|
||||
boost::json::object header;
|
||||
if (binary) {
|
||||
@@ -372,11 +372,16 @@ toJson(ripple::LedgerHeader const& lgrInfo, bool const binary)
|
||||
header[JS(close_time_resolution)] = lgrInfo.closeTimeResolution.count();
|
||||
header[JS(close_time_iso)] = ripple::to_string_iso(lgrInfo.closeTime);
|
||||
header[JS(ledger_hash)] = ripple::strHex(lgrInfo.hash);
|
||||
header[JS(ledger_index)] = std::to_string(lgrInfo.seq);
|
||||
header[JS(parent_close_time)] = lgrInfo.parentCloseTime.time_since_epoch().count();
|
||||
header[JS(parent_hash)] = ripple::strHex(lgrInfo.parentHash);
|
||||
header[JS(total_coins)] = ripple::to_string(lgrInfo.drops);
|
||||
header[JS(transaction_hash)] = ripple::strHex(lgrInfo.txHash);
|
||||
|
||||
if (apiVersion < 2u) {
|
||||
header[JS(ledger_index)] = std::to_string(lgrInfo.seq);
|
||||
} else {
|
||||
header[JS(ledger_index)] = lgrInfo.seq;
|
||||
}
|
||||
}
|
||||
header[JS(closed)] = true;
|
||||
return header;
|
||||
|
||||
@@ -115,10 +115,11 @@ toJson(ripple::SLE const& sle);
|
||||
*
|
||||
* @param entry The LedgerHeader to convert.
|
||||
* @param binary Whether to convert in hex format.
|
||||
* @param apiVersion The api version
|
||||
* @return The JSON object.
|
||||
*/
|
||||
boost::json::object
|
||||
toJson(ripple::LedgerHeader const& info, bool binary);
|
||||
toJson(ripple::LedgerHeader const& info, bool binary, std::uint32_t apiVersion);
|
||||
|
||||
boost::json::object
|
||||
toJson(ripple::TxMeta const& meta);
|
||||
|
||||
@@ -61,7 +61,7 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const
|
||||
auto const lgrInfo = std::get<ripple::LedgerHeader>(lgrInfoOrStatus);
|
||||
Output output;
|
||||
|
||||
output.header = toJson(lgrInfo, input.binary);
|
||||
output.header = toJson(lgrInfo, input.binary, ctx.apiVersion);
|
||||
|
||||
if (input.transactions) {
|
||||
output.header[JS(transactions)] = boost::json::value(boost::json::array_kind);
|
||||
@@ -86,8 +86,13 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const
|
||||
if (!input.binary) {
|
||||
boost::json::object entry;
|
||||
entry[JS(validated)] = true;
|
||||
// same with rippled, ledger_index is a string here
|
||||
entry[JS(ledger_index)] = std::to_string(lgrInfo.seq);
|
||||
|
||||
if (ctx.apiVersion < 2u) {
|
||||
entry[JS(ledger_index)] = std::to_string(lgrInfo.seq);
|
||||
} else {
|
||||
entry[JS(ledger_index)] = lgrInfo.seq;
|
||||
}
|
||||
|
||||
entry[JS(close_time_iso)] = isoTimeStr;
|
||||
entry[JS(ledger_hash)] = ripple::strHex(lgrInfo.hash);
|
||||
if (txn.contains(JS(hash))) {
|
||||
|
||||
@@ -105,7 +105,7 @@ LedgerDataHandler::process(Input input, Context const& ctx) const
|
||||
|
||||
// no marker -> first call, return header information
|
||||
if ((!input.marker) && (!input.diffMarker)) {
|
||||
output.header = toJson(lgrInfo, input.binary);
|
||||
output.header = toJson(lgrInfo, input.binary, ctx.apiVersion);
|
||||
} else {
|
||||
if (input.marker && !sharedPtrBackend_->fetchLedgerObject(*(input.marker), lgrInfo.seq, ctx.yield))
|
||||
return Error{Status{RippledError::rpcINVALID_PARAMS, "markerDoesNotExist"}};
|
||||
|
||||
@@ -443,7 +443,7 @@ TEST_F(RPCHelpersTest, DeliverMaxAliasV2)
|
||||
TEST_F(RPCHelpersTest, LedgerHeaderJson)
|
||||
{
|
||||
auto const ledgerHeader = CreateLedgerInfo(INDEX1, 30);
|
||||
auto const binJson = toJson(ledgerHeader, true);
|
||||
auto const binJson = toJson(ledgerHeader, true, 1u);
|
||||
|
||||
auto constexpr EXPECTBIN = R"({
|
||||
"ledger_data": "0000001E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -469,7 +469,35 @@ TEST_F(RPCHelpersTest, LedgerHeaderJson)
|
||||
INDEX1,
|
||||
30
|
||||
);
|
||||
auto json = toJson(ledgerHeader, false);
|
||||
auto json = toJson(ledgerHeader, false, 1u);
|
||||
// remove platform-related close_time_human field
|
||||
json.erase(JS(close_time_human));
|
||||
EXPECT_EQ(json, boost::json::parse(EXPECTJSON));
|
||||
}
|
||||
|
||||
TEST_F(RPCHelpersTest, LedgerHeaderJsonV2)
|
||||
{
|
||||
auto const ledgerHeader = CreateLedgerInfo(INDEX1, 30);
|
||||
|
||||
auto const EXPECTJSON = fmt::format(
|
||||
R"({{
|
||||
"account_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"close_flags": 0,
|
||||
"close_time": 0,
|
||||
"close_time_resolution": 0,
|
||||
"close_time_iso": "2000-01-01T00:00:00Z",
|
||||
"ledger_hash": "{}",
|
||||
"ledger_index": {},
|
||||
"parent_close_time": 0,
|
||||
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"total_coins": "0",
|
||||
"transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"closed": true
|
||||
}})",
|
||||
INDEX1,
|
||||
30
|
||||
);
|
||||
auto json = toJson(ledgerHeader, false, 2u);
|
||||
// remove platform-related close_time_human field
|
||||
json.erase(JS(close_time_human));
|
||||
EXPECT_EQ(json, boost::json::parse(EXPECTJSON));
|
||||
|
||||
@@ -262,9 +262,7 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
|
||||
mockBackendPtr->updateRange(RANGEMIN); // min
|
||||
mockBackendPtr->updateRange(RANGEMAX); // max
|
||||
|
||||
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).Times(1);
|
||||
ON_CALL(*rawBackendPtr, fetchLedgerBySequence(RANGEMAX, _))
|
||||
.WillByDefault(Return(CreateLedgerInfo(LEDGERHASH, RANGEMAX)));
|
||||
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).WillOnce(Return(CreateLedgerInfo(LEDGERHASH, RANGEMAX)));
|
||||
|
||||
// when 'type' not specified, default to all the types
|
||||
auto limitLine = 5;
|
||||
@@ -284,8 +282,7 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
|
||||
bbs.push_back(ticket.getSerializer().peekData());
|
||||
}
|
||||
|
||||
ON_CALL(*rawBackendPtr, doFetchLedgerObjects).WillByDefault(Return(bbs));
|
||||
EXPECT_CALL(*rawBackendPtr, doFetchLedgerObjects).Times(1);
|
||||
EXPECT_CALL(*rawBackendPtr, doFetchLedgerObjects).WillOnce(Return(bbs));
|
||||
|
||||
runSpawn([&, this](auto yield) {
|
||||
auto const handler = AnyHandler{LedgerDataHandler{mockBackendPtr}};
|
||||
@@ -293,7 +290,9 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
|
||||
auto output = handler.process(req, Context{yield});
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_TRUE(output->as_object().contains("ledger"));
|
||||
//"close_time_human" 's format depends on platform, might be sightly different
|
||||
|
||||
// Note: the format of "close_time_human" depends on the platform and might differ per platform. It is however
|
||||
// guaranteed to be consistent on the same platform.
|
||||
EXPECT_EQ(output->as_object().at("ledger").as_object().erase("close_time_human"), 1);
|
||||
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
|
||||
EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2);
|
||||
@@ -303,6 +302,64 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCLedgerDataHandlerTest, Version2)
|
||||
{
|
||||
static auto const ledgerExpected = R"({
|
||||
"account_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"close_flags": 0,
|
||||
"close_time": 0,
|
||||
"close_time_resolution": 0,
|
||||
"close_time_iso": "2000-01-01T00:00:00Z",
|
||||
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
||||
"ledger_index": 30,
|
||||
"parent_close_time": 0,
|
||||
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"total_coins": "0",
|
||||
"transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"closed": true
|
||||
})";
|
||||
|
||||
auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
|
||||
ASSERT_NE(rawBackendPtr, nullptr);
|
||||
mockBackendPtr->updateRange(RANGEMIN); // min
|
||||
mockBackendPtr->updateRange(RANGEMAX); // max
|
||||
|
||||
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).WillOnce(Return(CreateLedgerInfo(LEDGERHASH, RANGEMAX)));
|
||||
|
||||
// When 'type' not specified, default to all the types
|
||||
auto limitLine = 5;
|
||||
auto limitTicket = 5;
|
||||
|
||||
std::vector<Blob> bbs;
|
||||
EXPECT_CALL(*rawBackendPtr, doFetchSuccessorKey).Times(limitLine + limitTicket);
|
||||
ON_CALL(*rawBackendPtr, doFetchSuccessorKey(_, RANGEMAX, _)).WillByDefault(Return(ripple::uint256{INDEX2}));
|
||||
|
||||
while ((limitLine--) != 0) {
|
||||
auto const line = CreateRippleStateLedgerObject("USD", ACCOUNT2, 10, ACCOUNT, 100, ACCOUNT2, 200, TXNID, 123);
|
||||
bbs.push_back(line.getSerializer().peekData());
|
||||
}
|
||||
|
||||
while ((limitTicket--) != 0) {
|
||||
auto const ticket = CreateTicketLedgerObject(ACCOUNT, limitTicket);
|
||||
bbs.push_back(ticket.getSerializer().peekData());
|
||||
}
|
||||
|
||||
EXPECT_CALL(*rawBackendPtr, doFetchLedgerObjects).WillOnce(Return(bbs));
|
||||
|
||||
runSpawn([&, this](auto yield) {
|
||||
auto const handler = AnyHandler{LedgerDataHandler{mockBackendPtr}};
|
||||
auto const req = json::parse(R"({"limit":10})");
|
||||
auto output = handler.process(req, Context{.yield = yield, .apiVersion = 2});
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_TRUE(output->as_object().contains("ledger"));
|
||||
|
||||
// Note: the format of "close_time_human" depends on the platform and might differ per platform. It is however
|
||||
// guaranteed to be consistent on the same platform.
|
||||
EXPECT_EQ(output->as_object().at("ledger").as_object().erase("close_time_human"), 1);
|
||||
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCLedgerDataHandlerTest, TypeFilter)
|
||||
{
|
||||
static auto const ledgerExpected = R"({
|
||||
@@ -359,7 +416,9 @@ TEST_F(RPCLedgerDataHandlerTest, TypeFilter)
|
||||
auto output = handler.process(req, Context{yield});
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_TRUE(output->as_object().contains("ledger"));
|
||||
//"close_time_human" 's format depends on platform, might be sightly different
|
||||
|
||||
// Note: the format of "close_time_human" depends on the platform and might differ per platform. It is however
|
||||
// guaranteed to be consistent on the same platform.
|
||||
EXPECT_EQ(output->as_object().at("ledger").as_object().erase("close_time_human"), 1);
|
||||
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
|
||||
EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2);
|
||||
@@ -422,7 +481,9 @@ TEST_F(RPCLedgerDataHandlerTest, TypeFilterAMM)
|
||||
auto output = handler.process(req, Context{yield});
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_TRUE(output->as_object().contains("ledger"));
|
||||
//"close_time_human" 's format depends on platform, might be sightly different
|
||||
|
||||
// Note: the format of "close_time_human" depends on the platform and might differ per platform. It is however
|
||||
// guaranteed to be consistent on the same platform.
|
||||
EXPECT_EQ(output->as_object().at("ledger").as_object().erase("close_time_human"), 1);
|
||||
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
|
||||
EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2);
|
||||
|
||||
@@ -623,7 +623,7 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinaryV2)
|
||||
"close_time_resolution": 0,
|
||||
"closed": true,
|
||||
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
||||
"ledger_index": "30",
|
||||
"ledger_index": 30,
|
||||
"parent_close_time": 0,
|
||||
"close_time_iso": "2000-01-01T00:00:00Z",
|
||||
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -635,7 +635,7 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinaryV2)
|
||||
"close_time_iso": "2000-01-01T00:00:00Z",
|
||||
"hash": "70436A9332F7CD928FAEC1A41269A677739D8B11F108CE23AE23CBF0C9113F8C",
|
||||
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
|
||||
"ledger_index": "30",
|
||||
"ledger_index": 30,
|
||||
"tx_json":
|
||||
{
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
|
||||
Reference in New Issue
Block a user