Unify ledger_index type (#1019)

Fix #1014
This commit is contained in:
cyan317
2023-12-08 14:20:40 +00:00
committed by GitHub
parent a57abb15a3
commit b886586de3
7 changed files with 119 additions and 19 deletions

View File

@@ -359,7 +359,7 @@ toJson(ripple::SLE const& sle)
} }
boost::json::object 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; boost::json::object header;
if (binary) { 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_resolution)] = lgrInfo.closeTimeResolution.count();
header[JS(close_time_iso)] = ripple::to_string_iso(lgrInfo.closeTime); header[JS(close_time_iso)] = ripple::to_string_iso(lgrInfo.closeTime);
header[JS(ledger_hash)] = ripple::strHex(lgrInfo.hash); 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_close_time)] = lgrInfo.parentCloseTime.time_since_epoch().count();
header[JS(parent_hash)] = ripple::strHex(lgrInfo.parentHash); header[JS(parent_hash)] = ripple::strHex(lgrInfo.parentHash);
header[JS(total_coins)] = ripple::to_string(lgrInfo.drops); header[JS(total_coins)] = ripple::to_string(lgrInfo.drops);
header[JS(transaction_hash)] = ripple::strHex(lgrInfo.txHash); 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; header[JS(closed)] = true;
return header; return header;

View File

@@ -115,10 +115,11 @@ toJson(ripple::SLE const& sle);
* *
* @param entry The LedgerHeader to convert. * @param entry The LedgerHeader to convert.
* @param binary Whether to convert in hex format. * @param binary Whether to convert in hex format.
* @param apiVersion The api version
* @return The JSON object. * @return The JSON object.
*/ */
boost::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 boost::json::object
toJson(ripple::TxMeta const& meta); toJson(ripple::TxMeta const& meta);

View File

@@ -61,7 +61,7 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const
auto const lgrInfo = std::get<ripple::LedgerHeader>(lgrInfoOrStatus); auto const lgrInfo = std::get<ripple::LedgerHeader>(lgrInfoOrStatus);
Output output; Output output;
output.header = toJson(lgrInfo, input.binary); output.header = toJson(lgrInfo, input.binary, ctx.apiVersion);
if (input.transactions) { if (input.transactions) {
output.header[JS(transactions)] = boost::json::value(boost::json::array_kind); 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) { if (!input.binary) {
boost::json::object entry; boost::json::object entry;
entry[JS(validated)] = true; 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(close_time_iso)] = isoTimeStr;
entry[JS(ledger_hash)] = ripple::strHex(lgrInfo.hash); entry[JS(ledger_hash)] = ripple::strHex(lgrInfo.hash);
if (txn.contains(JS(hash))) { if (txn.contains(JS(hash))) {

View File

@@ -105,7 +105,7 @@ LedgerDataHandler::process(Input input, Context const& ctx) const
// no marker -> first call, return header information // no marker -> first call, return header information
if ((!input.marker) && (!input.diffMarker)) { if ((!input.marker) && (!input.diffMarker)) {
output.header = toJson(lgrInfo, input.binary); output.header = toJson(lgrInfo, input.binary, ctx.apiVersion);
} else { } else {
if (input.marker && !sharedPtrBackend_->fetchLedgerObject(*(input.marker), lgrInfo.seq, ctx.yield)) if (input.marker && !sharedPtrBackend_->fetchLedgerObject(*(input.marker), lgrInfo.seq, ctx.yield))
return Error{Status{RippledError::rpcINVALID_PARAMS, "markerDoesNotExist"}}; return Error{Status{RippledError::rpcINVALID_PARAMS, "markerDoesNotExist"}};

View File

@@ -443,7 +443,7 @@ TEST_F(RPCHelpersTest, DeliverMaxAliasV2)
TEST_F(RPCHelpersTest, LedgerHeaderJson) TEST_F(RPCHelpersTest, LedgerHeaderJson)
{ {
auto const ledgerHeader = CreateLedgerInfo(INDEX1, 30); auto const ledgerHeader = CreateLedgerInfo(INDEX1, 30);
auto const binJson = toJson(ledgerHeader, true); auto const binJson = toJson(ledgerHeader, true, 1u);
auto constexpr EXPECTBIN = R"({ auto constexpr EXPECTBIN = R"({
"ledger_data": "0000001E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "ledger_data": "0000001E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@@ -469,7 +469,35 @@ TEST_F(RPCHelpersTest, LedgerHeaderJson)
INDEX1, INDEX1,
30 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 // remove platform-related close_time_human field
json.erase(JS(close_time_human)); json.erase(JS(close_time_human));
EXPECT_EQ(json, boost::json::parse(EXPECTJSON)); EXPECT_EQ(json, boost::json::parse(EXPECTJSON));

View File

@@ -262,9 +262,7 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
mockBackendPtr->updateRange(RANGEMIN); // min mockBackendPtr->updateRange(RANGEMIN); // min
mockBackendPtr->updateRange(RANGEMAX); // max mockBackendPtr->updateRange(RANGEMAX); // max
EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).Times(1); EXPECT_CALL(*rawBackendPtr, fetchLedgerBySequence).WillOnce(Return(CreateLedgerInfo(LEDGERHASH, RANGEMAX)));
ON_CALL(*rawBackendPtr, fetchLedgerBySequence(RANGEMAX, _))
.WillByDefault(Return(CreateLedgerInfo(LEDGERHASH, RANGEMAX)));
// when 'type' not specified, default to all the types // when 'type' not specified, default to all the types
auto limitLine = 5; auto limitLine = 5;
@@ -284,8 +282,7 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
bbs.push_back(ticket.getSerializer().peekData()); bbs.push_back(ticket.getSerializer().peekData());
} }
ON_CALL(*rawBackendPtr, doFetchLedgerObjects).WillByDefault(Return(bbs)); EXPECT_CALL(*rawBackendPtr, doFetchLedgerObjects).WillOnce(Return(bbs));
EXPECT_CALL(*rawBackendPtr, doFetchLedgerObjects).Times(1);
runSpawn([&, this](auto yield) { runSpawn([&, this](auto yield) {
auto const handler = AnyHandler{LedgerDataHandler{mockBackendPtr}}; auto const handler = AnyHandler{LedgerDataHandler{mockBackendPtr}};
@@ -293,7 +290,9 @@ TEST_F(RPCLedgerDataHandlerTest, NoMarker)
auto output = handler.process(req, Context{yield}); auto output = handler.process(req, Context{yield});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output->as_object().contains("ledger")); 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").as_object().erase("close_time_human"), 1);
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected)); EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2); 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) TEST_F(RPCLedgerDataHandlerTest, TypeFilter)
{ {
static auto const ledgerExpected = R"({ static auto const ledgerExpected = R"({
@@ -359,7 +416,9 @@ TEST_F(RPCLedgerDataHandlerTest, TypeFilter)
auto output = handler.process(req, Context{yield}); auto output = handler.process(req, Context{yield});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output->as_object().contains("ledger")); 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").as_object().erase("close_time_human"), 1);
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected)); EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2); 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}); auto output = handler.process(req, Context{yield});
ASSERT_TRUE(output); ASSERT_TRUE(output);
EXPECT_TRUE(output->as_object().contains("ledger")); 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").as_object().erase("close_time_human"), 1);
EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected)); EXPECT_EQ(output->as_object().at("ledger"), json::parse(ledgerExpected));
EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2); EXPECT_EQ(output->as_object().at("marker").as_string(), INDEX2);

View File

@@ -623,7 +623,7 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinaryV2)
"close_time_resolution": 0, "close_time_resolution": 0,
"closed": true, "closed": true,
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652", "ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": "30", "ledger_index": 30,
"parent_close_time": 0, "parent_close_time": 0,
"close_time_iso": "2000-01-01T00:00:00Z", "close_time_iso": "2000-01-01T00:00:00Z",
"parent_hash": "0000000000000000000000000000000000000000000000000000000000000000", "parent_hash": "0000000000000000000000000000000000000000000000000000000000000000",
@@ -635,7 +635,7 @@ TEST_F(RPCLedgerHandlerTest, TransactionsExpandNotBinaryV2)
"close_time_iso": "2000-01-01T00:00:00Z", "close_time_iso": "2000-01-01T00:00:00Z",
"hash": "70436A9332F7CD928FAEC1A41269A677739D8B11F108CE23AE23CBF0C9113F8C", "hash": "70436A9332F7CD928FAEC1A41269A677739D8B11F108CE23AE23CBF0C9113F8C",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652", "ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"ledger_index": "30", "ledger_index": 30,
"tx_json": "tx_json":
{ {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",