From 1a421b4145ca95e13f1ac69c76ef38409de35516 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Thu, 10 Sep 2026 16:48:10 +0100 Subject: [PATCH] chore: Upgrade to `libxrpl-3.4.0-rc1` (#3203) --- conan.lock | 6 ++- conanfile.py | 3 +- src/data/AmendmentCenter.hpp | 4 ++ src/feed/impl/TransactionFeed.cpp | 6 ++- src/rpc/Errors.cpp | 6 +-- src/rpc/RPCHelpers.cpp | 9 +++-- src/rpc/handlers/AccountInfo.cpp | 2 +- src/rpc/handlers/LedgerEntry.cpp | 42 +++++++++++++------- src/rpc/handlers/ServerInfo.hpp | 2 +- src/rpc/handlers/VaultInfo.cpp | 3 +- tests/unit/rpc/handlers/LedgerEntryTests.cpp | 34 ++++++++++------ tests/unit/rpc/handlers/VaultInfoTests.cpp | 3 +- 12 files changed, 76 insertions(+), 44 deletions(-) diff --git a/conan.lock b/conan.lock index a599de081..1e7c54e73 100644 --- a/conan.lock +++ b/conan.lock @@ -4,7 +4,7 @@ "zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708", "xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688", "xrpl-rpc-spec/0.1.7#774d2f93c4b48a1523d8d5a94a2b082a%1787768955.574105", - "xrpl/3.3.0#5e356a24ae1f0d6da6bd617b926f92e6%1786467262.262007", + "xrpl/3.4.0-rc1#19678cbb46117ef8a669558ad19d6a1f%1789050823.813662", "sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447", "spdlog/1.17.0#bcbaaf7147bda6ad24ffbd1ac3d7142c%1782736610.443882", "soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521", @@ -25,10 +25,12 @@ "libarchive/3.8.7#c446109bd1f1d8ba7936c94189bc50e6%1782392403.066892", "http_parser/2.9.4#98d91690d6fd021e9e624218a85d9d97%1782736605.237778", "gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1782392402.791979", - "grpc/1.81.1#f729f6d75992d20f9c72828e9142d62f%1783945160.094135", + "grpc/1.81.1#b87796a4269034856cbc1a2522db16eb%1788275071.530512", "fmt/12.1.0#50abab23274d56bb8f42c94b3b9a40c7%1782736606.427131", + "fast_float/8.2.10#f6f28d6bb22112078e7dbda611caf681%1785888854.601666", "ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1782307148.15562", "date/3.0.4#862e11e80030356b53c2c38599ceb32b%1782392402.538492", + "corrosion/0.6.1#bfa292df0a957bc70a450ff316cd9435%1786119416.131296", "cassandra-cpp-driver/2.17.0#bd3934138689482102c265d01288a316%1782736662.877646", "c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1782392402.681654", "bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1782392402.296732", diff --git a/conanfile.py b/conanfile.py index 056f092b2..0404b34bb 100644 --- a/conanfile.py +++ b/conanfile.py @@ -18,7 +18,7 @@ class ClioConan(ConanFile): "libbacktrace/cci.20210118", "spdlog/1.17.0", "xrpl-rpc-spec/0.1.7", - "xrpl/3.3.0", + "xrpl/3.4.0-rc1", ] default_options = { @@ -34,6 +34,7 @@ class ClioConan(ConanFile): "protobuf/*:with_zlib": True, "snappy/*:shared": False, "xrpl-rpc-spec/*:server": "clio", + "xrpl/*:benchmark": False, "xrpl/*:rocksdb": True, # TODO: revert to false when includes are fixed in libxrpl "xrpl/*:tests": False, } diff --git a/src/data/AmendmentCenter.hpp b/src/data/AmendmentCenter.hpp index 5599a45ef..a76ca202b 100644 --- a/src/data/AmendmentCenter.hpp +++ b/src/data/AmendmentCenter.hpp @@ -147,6 +147,10 @@ struct Amendments { REGISTER(Sponsor); REGISTER(fixCleanup3_3_0); + // These amendments are added because of libxrpl 3.4.0, but they are not necessarily supported + // in Clio yet + REGISTER(fixCleanup3_4_0); + // Obsolete but supported by libxrpl REGISTER(CryptoConditionsSuite); REGISTER(NonFungibleTokensV1); diff --git a/src/feed/impl/TransactionFeed.cpp b/src/feed/impl/TransactionFeed.cpp index f8e60ed94..433bb10b7 100644 --- a/src/feed/impl/TransactionFeed.cpp +++ b/src/feed/impl/TransactionFeed.cpp @@ -21,7 +21,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -214,7 +215,8 @@ TransactionFeed::pub( rpc::insertMPTIssuanceID(txnPubobj, tx, metaPubobj, meta); json::Value nftJson; - xrpl::RPC::insertNFTSyntheticInJson(nftJson, tx, *meta); + xrpl::insertNFTokenID(nftJson[xrpl::jss::meta], tx, *meta); + xrpl::insertNFTokenOfferID(nftJson[xrpl::jss::meta], tx, *meta); auto const nftBoostJson = rpc::toBoostJson(nftJson).as_object(); if (nftBoostJson.contains(JS(meta)) && nftBoostJson.at(JS(meta)).is_object()) { auto& metaObjInPub = pubObj.at(JS(meta)).as_object(); diff --git a/src/rpc/Errors.cpp b/src/rpc/Errors.cpp index c0c3b0ea5..7f9487cdb 100644 --- a/src/rpc/Errors.cpp +++ b/src/rpc/Errors.cpp @@ -28,7 +28,7 @@ namespace rpc { * @brief Stream a Status in human readable form. * * Declared in rpcspec but implemented here: rendering a code needs Clio's - * getErrorInfo table and xrpl::RPC::getErrorInfo. + * getErrorInfo table and xrpl::rpc::getErrorInfo. * * @param stream The stream to write to * @param status The status to write @@ -46,7 +46,7 @@ operator<<(std::ostream& stream, Status const& status) if (!status.message.empty()) { stream << ", Message: " << status.message; } else { - stream << ", Message: " << xrpl::RPC::getErrorInfo(err).message; + stream << ", Message: " << xrpl::rpc::getErrorInfo(err).message; } }, [&stream, &status](ClioError err) { @@ -176,7 +176,7 @@ makeError( ) { boost::json::object json; - auto const& info = xrpl::RPC::getErrorInfo(err); + auto const& info = xrpl::rpc::getErrorInfo(err); json["error"] = customError.value_or(info.token.cStr()).data(); json["error_code"] = static_cast(err); diff --git a/src/rpc/RPCHelpers.cpp b/src/rpc/RPCHelpers.cpp index d9720f585..f6777f003 100644 --- a/src/rpc/RPCHelpers.cpp +++ b/src/rpc/RPCHelpers.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -45,7 +44,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -248,7 +248,8 @@ toExpandedJson( if (nftEnabled == NFTokenjson::ENABLE) { json::Value nftJson; - xrpl::RPC::insertNFTSyntheticInJson(nftJson, txn, *meta); + xrpl::insertNFTokenID(nftJson[xrpl::jss::meta], txn, *meta); + xrpl::insertNFTokenOfferID(nftJson[xrpl::jss::meta], txn, *meta); // if there is no nft fields, the nftJson will be {"meta":null} auto const nftBoostJson = toBoostJson(nftJson).as_object(); if (nftBoostJson.contains(JS(meta)) and nftBoostJson.at(JS(meta)).is_object()) { @@ -413,7 +414,7 @@ toJson(xrpl::SLE const& sle) std::string md5 = strHex(hash); boost::algorithm::to_lower(md5); value.as_object()["urlgravatar"] = - str(boost::format("http://www.gravatar.com/avatar/%s") % md5); + fmt::format("http://www.gravatar.com/avatar/{}", md5); } } return value.as_object(); diff --git a/src/rpc/handlers/AccountInfo.cpp b/src/rpc/handlers/AccountInfo.cpp index 870e22393..6c246568e 100644 --- a/src/rpc/handlers/AccountInfo.cpp +++ b/src/rpc/handlers/AccountInfo.cpp @@ -40,7 +40,7 @@ AccountInfoHandler::process(AccountInfoHandler::Input const& input, Context cons if (!input.account && !input.ident) { return Error{ - Status{RippledError::RpcInvalidParams, xrpl::RPC::missingFieldMessage(JS(account))} + Status{RippledError::RpcInvalidParams, xrpl::rpc::missingFieldMessage(JS(account))} }; } diff --git a/src/rpc/handlers/LedgerEntry.cpp b/src/rpc/handlers/LedgerEntry.cpp index e577d5c0f..60d939a61 100644 --- a/src/rpc/handlers/LedgerEntry.cpp +++ b/src/rpc/handlers/LedgerEntry.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -71,9 +72,13 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input const& input, Context cons ); // NOLINTBEGIN(bugprone-unchecked-optional-access) - key = - xrpl::keylet::offer(*id, boost::json::value_to(input.offer->at(JS(seq)))) - .key; + key = xrpl::keylet::offer( + *id, + xrpl::SeqProxy::rawSequence( + boost::json::value_to(input.offer->at(JS(seq))) + ) + ) + .key; // NOLINTEND(bugprone-unchecked-optional-access) } else if (input.rippleStateAccount) { auto const id1 = @@ -94,10 +99,14 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input const& input, Context cons auto const id = util::parseBase58Wrapper( boost::json::value_to(input.escrow->at(JS(owner))) ); - key = - // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - xrpl::keylet::escrow(*id, util::integralValueAs(input.escrow->at(JS(seq)))) - .key; + key = xrpl::keylet::escrow( + // NOLINTNEXTLINE(bugprone-unchecked-optional-access) + *id, + xrpl::SeqProxy::rawSequence( + util::integralValueAs(input.escrow->at(JS(seq))) + ) + ) + .key; } else if (input.depositPreauth) { auto const owner = util::parseBase58Wrapper( boost::json::value_to(input.depositPreauth->at(JS(owner))) @@ -137,10 +146,13 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input const& input, Context cons boost::json::value_to(input.ticket->at(JS(account))) ); - key = xrpl::getTicketIndex( - *id, // NOLINT(bugprone-unchecked-optional-access) - util::integralValueAs(input.ticket->at(JS(ticket_seq))) - ); + key = xrpl::keylet::ticket( + *id, // NOLINT(bugprone-unchecked-optional-access) + xrpl::SeqProxy::rawTicket( + util::integralValueAs(input.ticket->at(JS(ticket_seq))) + ) + ) + .key; } else if (input.amm) { auto const getIssuerFromJson = [](auto const& assetJson) { // the field check has been done in validator @@ -204,27 +216,27 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input const& input, Context cons ); auto const seq = util::integralValueAs(input.permissionedDomain->at(JS(seq))); // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - key = xrpl::keylet::permissionedDomain(*account, seq).key; + key = xrpl::keylet::permissionedDomain(*account, xrpl::SeqProxy::rawSequence(seq)).key; } else if (input.vault) { auto const account = xrpl::parseBase58( boost::json::value_to(input.vault->at(JS(owner))) ); auto const seq = util::integralValueAs(input.vault->at(JS(seq))); // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - key = xrpl::keylet::vault(*account, seq).key; + key = xrpl::keylet::vault(*account, xrpl::SeqProxy::rawSequence(seq)).key; } else if (input.loanBroker) { auto const account = xrpl::parseBase58( boost::json::value_to(input.loanBroker->at(JS(owner))) ); auto const seq = util::integralValueAs(input.loanBroker->at(JS(seq))); // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - key = xrpl::keylet::loanBroker(*account, seq).key; + key = xrpl::keylet::loanBroker(*account, xrpl::SeqProxy::rawSequence(seq)).key; } else if (input.loan) { auto const id = xrpl::uint256{ boost::json::value_to(input.loan->at(JS(loan_broker_id))).data() }; auto const seq = util::integralValueAs(input.loan->at(JS(loan_seq))); - key = xrpl::keylet::loan(id, seq).key; + key = xrpl::keylet::loan(id, xrpl::SeqProxy::rawSequence(seq)).key; } else if (input.delegate) { auto const account = xrpl::parseBase58( boost::json::value_to(input.delegate->at(JS(account))) diff --git a/src/rpc/handlers/ServerInfo.hpp b/src/rpc/handlers/ServerInfo.hpp index 00303cc51..5afd10fc1 100644 --- a/src/rpc/handlers/ServerInfo.hpp +++ b/src/rpc/handlers/ServerInfo.hpp @@ -103,7 +103,7 @@ public: std::chrono::time_point time = std::chrono::system_clock::now(); std::chrono::seconds uptime = {}; std::string clioVersion = util::build::getClioVersionString(); - std::string xrplVersion = xrpl::BuildInfo::getVersionString(); + std::string xrplVersion = xrpl::build_info::getVersionString(); std::optional rippledInfo = std::nullopt; ValidatedLedgerSection validatedLedger = {}; CacheSection cache = {}; diff --git a/src/rpc/handlers/VaultInfo.cpp b/src/rpc/handlers/VaultInfo.cpp index 7fee9f2ae..480e8b153 100644 --- a/src/rpc/handlers/VaultInfo.cpp +++ b/src/rpc/handlers/VaultInfo.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -96,7 +97,7 @@ VaultInfoHandler::process(VaultInfoHandler::Input const& input, Context const& c return std::unexpected{Status{RippledError::RpcEntryNotFound}}; } - return xrpl::keylet::vault(*accountID, *input.tnxSequence); + return xrpl::keylet::vault(*accountID, xrpl::SeqProxy::rawSequence(*input.tnxSequence)); } xrpl::uint256 nodeIndex; if (nodeIndex.parseHex(*input.vaultID)) diff --git a/tests/unit/rpc/handlers/LedgerEntryTests.cpp b/tests/unit/rpc/handlers/LedgerEntryTests.cpp index e9276e6c6..b3a7b7046 100644 --- a/tests/unit/rpc/handlers/LedgerEntryTests.cpp +++ b/tests/unit/rpc/handlers/LedgerEntryTests.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -2816,7 +2817,7 @@ generateTestValuesForNormalPathTest() }})JSON", kAccount ), - .expectedIndex = xrpl::keylet::escrow(account1, 1).key, + .expectedIndex = xrpl::keylet::escrow(account1, xrpl::SeqProxy::rawSequence(1)).key, .mockedEntity = createEscrowLedgerObject(kAccount, kAccount2) }, NormalPathTestBundle{ @@ -2924,7 +2925,7 @@ generateTestValuesForNormalPathTest() }})JSON", kAccount ), - .expectedIndex = xrpl::getTicketIndex(account1, 2), + .expectedIndex = xrpl::keylet::ticket(account1, xrpl::SeqProxy::rawTicket(2)).key, .mockedEntity = createTicketLedgerObject(kAccount, 0) }, NormalPathTestBundle{ @@ -2939,7 +2940,7 @@ generateTestValuesForNormalPathTest() }})JSON", kAccount ), - .expectedIndex = xrpl::keylet::offer(account1, 2).key, + .expectedIndex = xrpl::keylet::offer(account1, xrpl::SeqProxy::rawSequence(2)).key, .mockedEntity = createOfferLedgerObject( kAccount, 100, @@ -3281,7 +3282,7 @@ generateTestValuesForNormalPathTest() .expectedIndex = xrpl::keylet::permissionedDomain( // NOLINTNEXTLINE(bugprone-unchecked-optional-access) *xrpl::parseBase58(kAccount), - kRangeMax + xrpl::SeqProxy::rawSequence(kRangeMax) ) .key, .mockedEntity = @@ -3322,9 +3323,12 @@ generateTestValuesForNormalPathTest() kAccount, kRangeMax ), - .expectedIndex = - // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - xrpl::keylet::vault(*xrpl::parseBase58(kAccount), kRangeMax).key, + .expectedIndex = xrpl::keylet::vault( + // NOLINTNEXTLINE(bugprone-unchecked-optional-access) + *xrpl::parseBase58(kAccount), + xrpl::SeqProxy::rawSequence(kRangeMax) + ) + .key, .mockedEntity = createVault( kAccount, kAccount, @@ -3367,7 +3371,7 @@ generateTestValuesForNormalPathTest() .expectedIndex = xrpl::keylet::loanBroker( // NOLINTNEXTLINE(bugprone-unchecked-optional-access) *xrpl::parseBase58(kAccount), - kRangeMax + xrpl::SeqProxy::rawSequence(kRangeMax) ) .key, .mockedEntity = createLoanBroker( @@ -3400,7 +3404,8 @@ generateTestValuesForNormalPathTest() }})JSON", kIndex1 ), - .expectedIndex = xrpl::keylet::loan(xrpl::uint256{kIndex1}, 1).key, + .expectedIndex = + xrpl::keylet::loan(xrpl::uint256{kIndex1}, xrpl::SeqProxy::rawSequence(1)).key, .mockedEntity = createLoan( kAccount, xrpl::uint256{kIndex1}, 1, 1000, 86400, 100, xrpl::uint256{0}, 0 ) @@ -3550,9 +3555,12 @@ TEST_F(RPCLedgerEntryTest, Vault_BinaryFalse) 0 ); - auto const vaultKey = - // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - xrpl::keylet::vault(*xrpl::parseBase58(kAccount), kRangeMax).key; + auto const vaultKey = xrpl::keylet::vault( + // NOLINTNEXTLINE(bugprone-unchecked-optional-access) + *xrpl::parseBase58(kAccount), + xrpl::SeqProxy::rawSequence(kRangeMax) + ) + .key; xrpl::STLedgerEntry const sle{ xrpl::SerialIter{ @@ -3602,7 +3610,7 @@ TEST_F(RPCLedgerEntryTest, LoanBroker_BinaryFalse) auto const loanBrokerKey = xrpl::keylet::loanBroker( // NOLINTNEXTLINE(bugprone-unchecked-optional-access) *xrpl::parseBase58(kAccount), - kRangeMax + xrpl::SeqProxy::rawSequence(kRangeMax) ) .key; diff --git a/tests/unit/rpc/handlers/VaultInfoTests.cpp b/tests/unit/rpc/handlers/VaultInfoTests.cpp index 73e9dc580..a7910500c 100644 --- a/tests/unit/rpc/handlers/VaultInfoTests.cpp +++ b/tests/unit/rpc/handlers/VaultInfoTests.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -456,7 +457,7 @@ TEST_F(RPCVaultInfoHandlerTest, ValidVaultObjectQueryByOwnerAndSeq) auto const accountRoot = createAccountRootObject(kAccount, 0, kSeq, 200, 2, kIndex1, 2); auto const account = getAccountIdWithString(kAccount); auto const accountKeylet = xrpl::keylet::account(account).key; - auto const vaultKeylet = xrpl::keylet::vault(account, kSeq).key; + auto const vaultKeylet = xrpl::keylet::vault(account, xrpl::SeqProxy::rawSequence(kSeq)).key; auto const mptIssuance = xrpl::keylet::mptokenIssuance(mptSharesID).key; EXPECT_CALL(*backend_, doFetchLedgerObject(accountKeylet, kSeq, _))