From 8637d606a4dca70fa2e3a4229aa8361e99febb6e Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 13 Oct 2025 10:56:18 -0400 Subject: [PATCH 01/11] chore: Exclude code/unreachable transaction code from Codecov (#5847) This change excludes from Codecov unreachable/difficult-to-test transaction code (such as `tecINTERNAL`) and old code (from amendments that have been enabled for a long time that are only around for ledger replay reasons). This removes about 200 lines of misses and increases the Codecov coverage by 0.3% (79.2% to 79.5%). --- src/libxrpl/ledger/CredentialHelpers.cpp | 12 ++-- src/libxrpl/ledger/View.cpp | 63 ++++++++++++------- src/xrpld/app/misc/NetworkOPs.cpp | 21 ++++++- src/xrpld/app/tx/detail/AMMBid.cpp | 2 + src/xrpld/app/tx/detail/AMMCreate.cpp | 4 +- src/xrpld/app/tx/detail/AMMWithdraw.cpp | 4 +- src/xrpld/app/tx/detail/CancelCheck.cpp | 4 ++ src/xrpld/app/tx/detail/CancelOffer.cpp | 2 +- src/xrpld/app/tx/detail/CashCheck.cpp | 10 +++ src/xrpld/app/tx/detail/Clawback.cpp | 2 +- src/xrpld/app/tx/detail/CreateCheck.cpp | 6 +- src/xrpld/app/tx/detail/CreateOffer.cpp | 4 ++ src/xrpld/app/tx/detail/CreateTicket.cpp | 6 +- src/xrpld/app/tx/detail/Credentials.cpp | 12 ++-- src/xrpld/app/tx/detail/DID.cpp | 8 ++- src/xrpld/app/tx/detail/DeleteAccount.cpp | 6 +- src/xrpld/app/tx/detail/DepositPreauth.cpp | 14 +++-- src/xrpld/app/tx/detail/Escrow.cpp | 46 ++++++++++---- src/xrpld/app/tx/detail/LedgerStateFix.cpp | 4 +- src/xrpld/app/tx/detail/MPTokenAuthorize.cpp | 2 +- .../app/tx/detail/MPTokenIssuanceDestroy.cpp | 4 +- .../app/tx/detail/MPTokenIssuanceSet.cpp | 2 +- .../app/tx/detail/NFTokenAcceptOffer.cpp | 12 ++-- .../app/tx/detail/NFTokenCancelOffer.cpp | 2 + src/xrpld/app/tx/detail/NFTokenMint.cpp | 2 +- src/xrpld/app/tx/detail/NFTokenUtils.cpp | 4 +- src/xrpld/app/tx/detail/PayChan.cpp | 14 +++-- src/xrpld/app/tx/detail/Payment.cpp | 2 +- .../tx/detail/PermissionedDomainDelete.cpp | 8 ++- src/xrpld/app/tx/detail/SetAccount.cpp | 2 +- src/xrpld/app/tx/detail/SetRegularKey.cpp | 2 +- src/xrpld/app/tx/detail/SetSignerList.cpp | 8 ++- src/xrpld/app/tx/detail/SetTrust.cpp | 2 +- src/xrpld/app/tx/detail/Transactor.cpp | 8 +++ src/xrpld/app/tx/detail/XChainBridge.cpp | 55 +++++++++------- src/xrpld/rpc/detail/ServerHandler.cpp | 4 ++ src/xrpld/rpc/handlers/PayChanClaim.cpp | 2 + src/xrpld/rpc/handlers/Random.cpp | 2 +- 38 files changed, 246 insertions(+), 121 deletions(-) diff --git a/src/libxrpl/ledger/CredentialHelpers.cpp b/src/libxrpl/ledger/CredentialHelpers.cpp index 965d6f6911..4c625f5eee 100644 --- a/src/libxrpl/ledger/CredentialHelpers.cpp +++ b/src/libxrpl/ledger/CredentialHelpers.cpp @@ -77,19 +77,23 @@ deleteSLE( AccountID const& account, SField const& node, bool isOwner) -> TER { auto const sleAccount = view.peek(keylet::account(account)); if (!sleAccount) - { // LCOV_EXCL_START + { + // LCOV_EXCL_START JLOG(j.fatal()) << "Internal error: can't retrieve Owner account."; return tecINTERNAL; - } // LCOV_EXCL_STOP + // LCOV_EXCL_STOP + } // Remove object from owner directory std::uint64_t const page = sleCredential->getFieldU64(node); if (!view.dirRemove( keylet::ownerDir(account), page, sleCredential->key(), false)) - { // LCOV_EXCL_START + { + // LCOV_EXCL_START JLOG(j.fatal()) << "Unable to delete Credential from owner."; return tefBAD_LEDGER; - } // LCOV_EXCL_STOP + // LCOV_EXCL_STOP + } if (isOwner) adjustOwnerCount(view, sleAccount, -1, j); diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index 89d8137ac7..ace7a34f81 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -1292,7 +1292,7 @@ authorizeMPToken( { auto const sleAcct = view.peek(keylet::account(account)); if (!sleAcct) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE // If the account that submitted the tx is a holder // Note: `account_` is holder's account @@ -1357,17 +1357,17 @@ authorizeMPToken( auto const sleMptIssuance = view.read(keylet::mptIssuance(mptIssuanceID)); if (!sleMptIssuance) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE // If the account that submitted this tx is the issuer of the MPT // Note: `account_` is issuer's account // `holderID` is holder's account if (account != (*sleMptIssuance)[sfIssuer]) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID)); if (!sleMpt) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE std::uint32_t const flagsIn = sleMpt->getFieldU32(sfFlags); std::uint32_t flagsOut = flagsIn; @@ -1424,7 +1424,7 @@ trustCreate( describeOwnerDir(uLowAccountID)); if (!lowNode) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE auto highNode = view.dirInsert( keylet::ownerDir(uHighAccountID), @@ -1432,14 +1432,14 @@ trustCreate( describeOwnerDir(uHighAccountID)); if (!highNode) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE bool const bSetDst = saLimit.getIssuer() == uDstAccountID; bool const bSetHigh = bSrcHigh ^ bSetDst; XRPL_ASSERT(sleAccount, "ripple::trustCreate : non-null SLE"); if (!sleAccount) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE XRPL_ASSERT( sleAccount->getAccountID(sfAccount) == @@ -1518,10 +1518,12 @@ removeEmptyHolding( { auto const sle = view.read(keylet::account(accountID)); if (!sle) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE + auto const balance = sle->getFieldAmount(sfBalance); if (balance.xrp() != 0) return tecHAS_OBLIGATIONS; + return tesSUCCESS; } @@ -1539,7 +1541,8 @@ removeEmptyHolding( auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); if (!sleLowAccount) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE + adjustOwnerCount(view, sleLowAccount, -1, journal); // It's not really necessary to clear the reserve flag, since the line // is about to be deleted, but this will make the metadata reflect an @@ -1553,7 +1556,8 @@ removeEmptyHolding( auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); if (!sleHighAccount) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE + adjustOwnerCount(view, sleHighAccount, -1, journal); // It's not really necessary to clear the reserve flag, since the line // is about to be deleted, but this will make the metadata reflect an @@ -1613,7 +1617,7 @@ trustDelete( sleRippleState->key(), false)) { - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE } JLOG(j.trace()) << "trustDelete: Deleting ripple line: high"; @@ -1624,7 +1628,7 @@ trustDelete( sleRippleState->key(), false)) { - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE } JLOG(j.trace()) << "trustDelete: Deleting ripple line: state"; @@ -1650,7 +1654,7 @@ offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j) offerIndex, false)) { - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE } if (!view.dirRemove( @@ -1659,7 +1663,7 @@ offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j) offerIndex, false)) { - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE } if (sle->isFieldPresent(sfAdditionalBooks)) @@ -1823,7 +1827,7 @@ rippleCreditIOU( auto const sleAccount = view.peek(keylet::account(uReceiverID)); if (!sleAccount) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE bool const noRipple = (sleAccount->getFlags() & lsfDefaultRipple) == 0; @@ -1913,14 +1917,16 @@ accountSendIOU( { if (saAmount < beast::zero || saAmount.holds()) { - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } } else { + // LCOV_EXCL_START XRPL_ASSERT( saAmount >= beast::zero && !saAmount.holds(), "ripple::accountSendIOU : minimum amount and not MPT"); + // LCOV_EXCL_STOP } /* If we aren't sending anything or if the sender is the same as the @@ -1977,8 +1983,10 @@ accountSendIOU( { // VFALCO Its laborious to have to mutate the // TER based on params everywhere + // LCOV_EXCL_START terResult = view.open() ? TER{telFAILED_PROCESSING} : TER{tecFAILED_PROCESSING}; + // LCOV_EXCL_STOP } else { @@ -2065,7 +2073,7 @@ rippleCreditMPT( view.update(sleIssuance); } else - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } else { @@ -2325,7 +2333,7 @@ issueIOU( auto const receiverAccount = view.peek(keylet::account(account)); if (!receiverAccount) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE bool noRipple = (receiverAccount->getFlags() & lsfDefaultRipple) == 0; @@ -2413,11 +2421,13 @@ redeemIOU( // In order to hold an IOU, a trust line *MUST* exist to track the // balance. If it doesn't, then something is very wrong. Don't try // to continue. + // LCOV_EXCL_START JLOG(j.fatal()) << "redeemIOU: " << to_string(account) << " attempts to redeem " << amount.getFullText() << " but no trust line exists!"; return tefINTERNAL; + // LCOV_EXCL_STOP } TER @@ -2437,7 +2447,7 @@ transferXRP( SLE::pointer const sender = view.peek(keylet::account(from)); SLE::pointer const receiver = view.peek(keylet::account(to)); if (!sender || !receiver) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE JLOG(j.trace()) << "transferXRP: " << to_string(from) << " -> " << to_string(to) << ") : " << amount.getFullText(); @@ -2447,8 +2457,10 @@ transferXRP( // VFALCO Its unfortunate we have to keep // mutating these TER everywhere // FIXME: this logic should be moved to callers maybe? + // LCOV_EXCL_START return view.open() ? TER{telFAILED_PROCESSING} : TER{tecFAILED_PROCESSING}; + // LCOV_EXCL_STOP } // Decrement XRP balance. @@ -2729,11 +2741,13 @@ cleanupOnAccountDelete( if (!sleItem) { // Directory node has an invalid index. Bail out. + // LCOV_EXCL_START JLOG(j.fatal()) << "DeleteAccount: Directory node in ledger " << view.seq() << " has index to object that is missing: " << to_string(dirEntry); return tefBAD_LEDGER; + // LCOV_EXCL_STOP } LedgerEntryType const nodeType{safe_cast( @@ -2766,9 +2780,11 @@ cleanupOnAccountDelete( "ripple::cleanupOnAccountDelete : minimum dir entries"); if (uDirEntry == 0) { + // LCOV_EXCL_START JLOG(j.error()) << "DeleteAccount iterator re-validation failed."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } if (skipEntry == SkipEntry::No) uDirEntry--; @@ -2788,7 +2804,7 @@ deleteAMMTrustLine( beast::Journal j) { if (!sleState || sleState->getType() != ltRIPPLE_STATE) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const& [low, high] = std::minmax( sleState->getFieldAmount(sfLowLimit).getIssuer(), @@ -2796,13 +2812,14 @@ deleteAMMTrustLine( auto sleLow = view.peek(keylet::account(low)); auto sleHigh = view.peek(keylet::account(high)); if (!sleLow || !sleHigh) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE + bool const ammLow = sleLow->isFieldPresent(sfAMMID); bool const ammHigh = sleHigh->isFieldPresent(sfAMMID); // can't both be AMM if (ammLow && ammHigh) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE // at least one must be if (!ammLow && !ammHigh) @@ -2822,7 +2839,7 @@ deleteAMMTrustLine( auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve; if (!(sleState->getFlags() & uFlags)) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j); diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index e72b2732d0..3154426696 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -3728,6 +3728,9 @@ NetworkOPsImp::addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo) if (databaseType == DatabaseType::None) { + // LCOV_EXCL_START + UNREACHABLE( + "ripple::NetworkOPsImp::addAccountHistoryJob : no database"); JLOG(m_journal.error()) << "AccountHistory job for account " << toBase58(subInfo.index_->accountId_) << " no database"; @@ -3737,6 +3740,7 @@ NetworkOPsImp::addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo) unsubAccountHistory(sptr, subInfo.index_->accountId_, false); } return; + // LCOV_EXCL_STOP } app_.getJobQueue().addJob( @@ -3836,7 +3840,7 @@ NetworkOPsImp::addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo) // LCOV_EXCL_START default: { UNREACHABLE( - "ripple::NetworkOPsImp::addAccountHistoryJob::" + "ripple::NetworkOPsImp::addAccountHistoryJob : " "getMoreTxns : invalid database type"); return {}; } @@ -3901,11 +3905,16 @@ NetworkOPsImp::addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo) getMoreTxns(startLedgerSeq, lastLedgerSeq, marker); if (!dbResult) { + // LCOV_EXCL_START + UNREACHABLE( + "ripple::NetworkOPsImp::addAccountHistoryJob : " + "getMoreTxns failed"); JLOG(m_journal.debug()) << "AccountHistory job for account " << toBase58(accountId) << " getMoreTxns failed."; send(rpcError(rpcINTERNAL), true); return; + // LCOV_EXCL_STOP } auto const& txns = dbResult->first; @@ -3928,22 +3937,32 @@ NetworkOPsImp::addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo) tx->getLedger()); if (!curTxLedger) { + // LCOV_EXCL_START + UNREACHABLE( + "ripple::NetworkOPsImp::addAccountHistoryJob : " + "getLedgerBySeq failed"); JLOG(m_journal.debug()) << "AccountHistory job for account " << toBase58(accountId) << " no ledger."; send(rpcError(rpcINTERNAL), true); return; + // LCOV_EXCL_STOP } std::shared_ptr stTxn = tx->getSTransaction(); if (!stTxn) { + // LCOV_EXCL_START + UNREACHABLE( + "NetworkOPsImp::addAccountHistoryJob : " + "getSTransaction failed"); JLOG(m_journal.debug()) << "AccountHistory job for account " << toBase58(accountId) << " getSTransaction failed."; send(rpcError(rpcINTERNAL), true); return; + // LCOV_EXCL_STOP } auto const mRef = std::ref(*meta); diff --git a/src/xrpld/app/tx/detail/AMMBid.cpp b/src/xrpld/app/tx/detail/AMMBid.cpp index 769668b07b..028c1aac8b 100644 --- a/src/xrpld/app/tx/detail/AMMBid.cpp +++ b/src/xrpld/app/tx/detail/AMMBid.cpp @@ -247,10 +247,12 @@ applyBid( if (saBurn >= lptAMMBalance) { // This error case should never occur. + // LCOV_EXCL_START JLOG(ctx_.journal.fatal()) << "AMM Bid: LP Token burn exceeds AMM balance " << burn << " " << lptAMMBalance; return tecINTERNAL; + // LCOV_EXCL_STOP } auto res = redeemIOU(sb, account_, saBurn, lpTokens.issue(), ctx_.journal); diff --git a/src/xrpld/app/tx/detail/AMMCreate.cpp b/src/xrpld/app/tx/detail/AMMCreate.cpp index 63e20b42fb..a515783fb6 100644 --- a/src/xrpld/app/tx/detail/AMMCreate.cpp +++ b/src/xrpld/app/tx/detail/AMMCreate.cpp @@ -197,7 +197,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx) return tesSUCCESS; if (auto const sle = ctx.view.read(keylet::account(issue.account)); !sle) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE else if (sle->getFlags() & lsfAllowTrustLineClawback) return tecNO_PERMISSION; return tesSUCCESS; @@ -291,7 +291,7 @@ applyCreate( if (SLE::pointer sleRippleState = sb.peek(keylet::line(accountId, amount.issue())); !sleRippleState) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE else { auto const flags = sleRippleState->getFlags(); diff --git a/src/xrpld/app/tx/detail/AMMWithdraw.cpp b/src/xrpld/app/tx/detail/AMMWithdraw.cpp index f5af9dfb9c..8b6b58013a 100644 --- a/src/xrpld/app/tx/detail/AMMWithdraw.cpp +++ b/src/xrpld/app/tx/detail/AMMWithdraw.cpp @@ -196,9 +196,11 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx) if (amountBalance <= beast::zero || amount2Balance <= beast::zero || lptAMMBalance < beast::zero) { + // LCOV_EXCL_START JLOG(ctx.j.debug()) << "AMM Withdraw: reserves or tokens balance is zero."; - return tecINTERNAL; // LCOV_EXCL_LINE + return tecINTERNAL; + // LCOV_EXCL_STOP } auto const ammAccountID = ammSle->getAccountID(sfAccount); diff --git a/src/xrpld/app/tx/detail/CancelCheck.cpp b/src/xrpld/app/tx/detail/CancelCheck.cpp index f1a9b42a89..9dc792307c 100644 --- a/src/xrpld/app/tx/detail/CancelCheck.cpp +++ b/src/xrpld/app/tx/detail/CancelCheck.cpp @@ -93,8 +93,10 @@ CancelCheck::doApply() if (!view().dirRemove( keylet::ownerDir(dstId), page, sleCheck->key(), true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete check from destination."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } { @@ -102,8 +104,10 @@ CancelCheck::doApply() if (!view().dirRemove( keylet::ownerDir(srcId), page, sleCheck->key(), true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete check from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } diff --git a/src/xrpld/app/tx/detail/CancelOffer.cpp b/src/xrpld/app/tx/detail/CancelOffer.cpp index e7ec28ce17..ff5bfd085b 100644 --- a/src/xrpld/app/tx/detail/CancelOffer.cpp +++ b/src/xrpld/app/tx/detail/CancelOffer.cpp @@ -68,7 +68,7 @@ CancelOffer::doApply() auto const sle = view().read(keylet::account(account_)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE if (auto sleOffer = view().peek(keylet::offer(account_, offerSequence))) { diff --git a/src/xrpld/app/tx/detail/CashCheck.cpp b/src/xrpld/app/tx/detail/CashCheck.cpp index f8ab6189a3..73dedba170 100644 --- a/src/xrpld/app/tx/detail/CashCheck.cpp +++ b/src/xrpld/app/tx/detail/CashCheck.cpp @@ -87,8 +87,10 @@ CashCheck::preclaim(PreclaimContext const& ctx) { // They wrote a check to themselves. This should be caught when // the check is created, but better late than never. + // LCOV_EXCL_START JLOG(ctx.j.error()) << "Malformed transaction: Cashing check to self."; return tecINTERNAL; + // LCOV_EXCL_STOP } { auto const sleSrc = ctx.view.read(keylet::account(srcId)); @@ -245,17 +247,21 @@ CashCheck::doApply() auto sleCheck = psb.peek(keylet::check(ctx_.tx[sfCheckID])); if (!sleCheck) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Precheck did not verify check's existence."; return tecFAILED_PROCESSING; + // LCOV_EXCL_STOP } AccountID const srcId{sleCheck->getAccountID(sfAccount)}; if (!psb.exists(keylet::account(srcId)) || !psb.exists(keylet::account(account_))) { + // LCOV_EXCL_START JLOG(ctx_.journal.fatal()) << "Precheck did not verify source or destination's existence."; return tecFAILED_PROCESSING; + // LCOV_EXCL_STOP } // Preclaim already checked that source has at least the requested @@ -478,8 +484,10 @@ CashCheck::doApply() sleCheck->key(), true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete check from destination."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } // Remove check from check owner's directory. @@ -489,8 +497,10 @@ CashCheck::doApply() sleCheck->key(), true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete check from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } // If we succeeded, update the check owner's reserve. diff --git a/src/xrpld/app/tx/detail/Clawback.cpp b/src/xrpld/app/tx/detail/Clawback.cpp index b346e4a1c1..1c279389ec 100644 --- a/src/xrpld/app/tx/detail/Clawback.cpp +++ b/src/xrpld/app/tx/detail/Clawback.cpp @@ -235,7 +235,7 @@ applyHelper(ApplyContext& ctx) // Replace the `issuer` field with issuer's account clawAmount.setIssuer(issuer); if (holder == issuer) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE // Get the spendable balance. Must use `accountHolds`. STAmount const spendableAmount = accountHolds( diff --git a/src/xrpld/app/tx/detail/CreateCheck.cpp b/src/xrpld/app/tx/detail/CreateCheck.cpp index 57f3a92255..54bbdbdc25 100644 --- a/src/xrpld/app/tx/detail/CreateCheck.cpp +++ b/src/xrpld/app/tx/detail/CreateCheck.cpp @@ -159,7 +159,7 @@ CreateCheck::doApply() { auto const sle = view().peek(keylet::account(account_)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE // A check counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the @@ -209,7 +209,7 @@ CreateCheck::doApply() << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE sleCheck->setFieldU64(sfDestinationNode, *page); } @@ -225,7 +225,7 @@ CreateCheck::doApply() << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE sleCheck->setFieldU64(sfOwnerNode, *page); } diff --git a/src/xrpld/app/tx/detail/CreateOffer.cpp b/src/xrpld/app/tx/detail/CreateOffer.cpp index 86750eb51d..a503f913fa 100644 --- a/src/xrpld/app/tx/detail/CreateOffer.cpp +++ b/src/xrpld/app/tx/detail/CreateOffer.cpp @@ -848,9 +848,11 @@ CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) if (!ownerNode) { + // LCOV_EXCL_START JLOG(j_.debug()) << "final result: failed to add offer to owner's directory"; return {tecDIR_FULL, true}; + // LCOV_EXCL_STOP } // Update owner count. @@ -894,8 +896,10 @@ CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) if (!bookNode) { + // LCOV_EXCL_START JLOG(j_.debug()) << "final result: failed to add offer to book"; return {tecDIR_FULL, true}; + // LCOV_EXCL_STOP } auto sleOffer = std::make_shared(offer_index); diff --git a/src/xrpld/app/tx/detail/CreateTicket.cpp b/src/xrpld/app/tx/detail/CreateTicket.cpp index d48da2d780..f0b62bc67f 100644 --- a/src/xrpld/app/tx/detail/CreateTicket.cpp +++ b/src/xrpld/app/tx/detail/CreateTicket.cpp @@ -76,7 +76,7 @@ CreateTicket::doApply() { SLE::pointer const sleAccountRoot = view().peek(keylet::account(account_)); if (!sleAccountRoot) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE // Each ticket counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the @@ -102,7 +102,7 @@ CreateTicket::doApply() // increment the account root Sequence. if (std::uint32_t const txSeq = ctx_.tx[sfSequence]; txSeq != 0 && txSeq != (firstTicketSeq - 1)) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE for (std::uint32_t i = 0; i < ticketCount; ++i) { @@ -123,7 +123,7 @@ CreateTicket::doApply() << ": " << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE sleTicket->setFieldU64(sfOwnerNode, *page); } diff --git a/src/xrpld/app/tx/detail/Credentials.cpp b/src/xrpld/app/tx/detail/Credentials.cpp index 4b77163c5d..b6471d6a20 100644 --- a/src/xrpld/app/tx/detail/Credentials.cpp +++ b/src/xrpld/app/tx/detail/Credentials.cpp @@ -117,7 +117,7 @@ CredentialCreate::doApply() auto const sleCred = std::make_shared(credentialKey); if (!sleCred) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE auto const optExp = ctx_.tx[~sfExpiration]; if (optExp) @@ -137,7 +137,7 @@ CredentialCreate::doApply() auto const sleIssuer = view().peek(keylet::account(account_)); if (!sleIssuer) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE { STAmount const reserve{view().fees().accountReserve( @@ -162,7 +162,7 @@ CredentialCreate::doApply() << to_string(credentialKey.key) << ": " << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE sleCred->setFieldU64(sfIssuerNode, *page); adjustOwnerCount(view(), sleIssuer, 1, j_); @@ -182,7 +182,7 @@ CredentialCreate::doApply() << to_string(credentialKey.key) << ": " << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE sleCred->setFieldU64(sfSubjectNode, *page); view().update(view().peek(keylet::account(subject))); } @@ -258,7 +258,7 @@ CredentialDelete::doApply() auto const sleCred = view().peek(keylet::credential(subject, issuer, credType)); if (!sleCred) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE if ((subject != account_) && (issuer != account_) && !checkExpired(sleCred, ctx_.view().info().parentCloseTime)) @@ -342,7 +342,7 @@ CredentialAccept::doApply() auto const sleIssuer = view().peek(keylet::account(issuer)); if (!sleSubject || !sleIssuer) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE { STAmount const reserve{view().fees().accountReserve( diff --git a/src/xrpld/app/tx/detail/DID.cpp b/src/xrpld/app/tx/detail/DID.cpp index b38b207d36..f466777920 100644 --- a/src/xrpld/app/tx/detail/DID.cpp +++ b/src/xrpld/app/tx/detail/DID.cpp @@ -76,7 +76,7 @@ addSLE( { auto const sleAccount = ctx.view().peek(keylet::account(owner)); if (!sleAccount) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE // Check reserve availability for new object creation { @@ -96,7 +96,7 @@ addSLE( auto page = ctx.view().dirInsert( keylet::ownerDir(owner), sle->key(), describeOwnerDir(owner)); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE (*sle)[sfOwnerNode] = *page; } adjustOwnerCount(ctx.view(), sleAccount, 1, ctx.journal); @@ -189,13 +189,15 @@ DIDDelete::deleteSLE( if (!view.dirRemove( keylet::ownerDir(owner), (*sle)[sfOwnerNode], sle->key(), true)) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Unable to delete DID Token from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } auto const sleOwner = view.peek(keylet::account(owner)); if (!sleOwner) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE adjustOwnerCount(view, sleOwner, -1, j); view.update(sleOwner); diff --git a/src/xrpld/app/tx/detail/DeleteAccount.cpp b/src/xrpld/app/tx/detail/DeleteAccount.cpp index d52e84d755..805c023c04 100644 --- a/src/xrpld/app/tx/detail/DeleteAccount.cpp +++ b/src/xrpld/app/tx/detail/DeleteAccount.cpp @@ -141,7 +141,7 @@ removeNFTokenOfferFromLedger( beast::Journal) { if (!nft::deleteTokenOffer(view, sleDel)) - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE return tesSUCCESS; } @@ -336,11 +336,13 @@ DeleteAccount::preclaim(PreclaimContext const& ctx) if (!sleItem) { // Directory node has an invalid index. Bail out. + // LCOV_EXCL_START JLOG(ctx.j.fatal()) << "DeleteAccount: directory node in ledger " << ctx.view.seq() << " has index to object that is missing: " << to_string(dirEntry); return tefBAD_LEDGER; + // LCOV_EXCL_STOP } LedgerEntryType const nodeType{ @@ -373,7 +375,7 @@ DeleteAccount::doApply() dst, "ripple::DeleteAccount::doApply : non-null destination account"); if (!src || !dst) - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE if (ctx_.view().rules().enabled(featureDepositAuth) && ctx_.tx.isFieldPresent(sfCredentialIDs)) diff --git a/src/xrpld/app/tx/detail/DepositPreauth.cpp b/src/xrpld/app/tx/detail/DepositPreauth.cpp index 236b59a173..6f0e079290 100644 --- a/src/xrpld/app/tx/detail/DepositPreauth.cpp +++ b/src/xrpld/app/tx/detail/DepositPreauth.cpp @@ -138,7 +138,7 @@ DepositPreauth::preclaim(PreclaimContext const& ctx) return tecNO_ISSUER; auto [it, ins] = sorted.emplace(issuer, o[sfCredentialType]); if (!ins) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE } // Verify that the Preauth entry they asked to add is not already @@ -198,7 +198,7 @@ DepositPreauth::doApply() << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE slePreauth->setFieldU64(sfOwnerNode, *page); @@ -216,7 +216,7 @@ DepositPreauth::doApply() { auto const sleOwner = view().peek(keylet::account(account_)); if (!sleOwner) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE // A preauth counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the @@ -246,7 +246,7 @@ DepositPreauth::doApply() Keylet const preauthKey = keylet::depositPreauth(account_, sortedTX); auto slePreauth = std::make_shared(preauthKey); if (!slePreauth) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE slePreauth->setAccountID(sfAccount, account_); slePreauth->peekFieldArray(sfAuthorizeCredentials) = @@ -262,7 +262,7 @@ DepositPreauth::doApply() << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE slePreauth->setFieldU64(sfOwnerNode, *page); @@ -299,14 +299,16 @@ DepositPreauth::removeFromLedger( std::uint64_t const page{(*slePreauth)[sfOwnerNode]}; if (!view.dirRemove(keylet::ownerDir(account), page, preauthIndex, false)) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Unable to delete DepositPreauth from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } // If we succeeded, update the DepositPreauth owner's reserve. auto const sleOwner = view.peek(keylet::account(account)); if (!sleOwner) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE adjustOwnerCount(view, sleOwner, -1, j); diff --git a/src/xrpld/app/tx/detail/Escrow.cpp b/src/xrpld/app/tx/detail/Escrow.cpp index 969fd4dd4c..eb468626a4 100644 --- a/src/xrpld/app/tx/detail/Escrow.cpp +++ b/src/xrpld/app/tx/detail/Escrow.cpp @@ -414,10 +414,8 @@ escrowLockApplyHelper( beast::Journal journal) { // Defensive: Issuer cannot create an escrow - // LCOV_EXCL_START if (issuer == sender) - return tecINTERNAL; - // LCOV_EXCL_STOP + return tecINTERNAL; // LCOV_EXCL_LINE auto const ter = rippleCredit( view, @@ -441,10 +439,8 @@ escrowLockApplyHelper( beast::Journal journal) { // Defensive: Issuer cannot create an escrow - // LCOV_EXCL_START if (issuer == sender) - return tecINTERNAL; - // LCOV_EXCL_STOP + return tecINTERNAL; // LCOV_EXCL_LINE auto const ter = rippleLockEscrowMPT(view, sender, amount, journal); if (ter != tesSUCCESS) @@ -472,6 +468,9 @@ EscrowCreate::doApply() } else { + // This is old code that needs to stay to support replaying old ledgers, + // but does not need to be covered by new tests. + // LCOV_EXCL_START if (ctx_.tx[~sfCancelAfter]) { auto const cancelAfter = ctx_.tx[sfCancelAfter]; @@ -487,6 +486,7 @@ EscrowCreate::doApply() if (closeTime.time_since_epoch().count() >= finishAfter) return tecNO_PERMISSION; } + // LCOV_EXCL_STOP } auto const sle = ctx_.view().peek(keylet::account(account_)); @@ -514,12 +514,12 @@ EscrowCreate::doApply() auto const sled = ctx_.view().read(keylet::account(ctx_.tx[sfDestination])); if (!sled) - return tecNO_DST; + return tecNO_DST; // LCOV_EXCL_LINE if (((*sled)[sfFlags] & lsfRequireDestTag) && !ctx_.tx[~sfDestinationTag]) return tecDST_TAG_NEEDED; - // Obeying the lsfDissalowXRP flag was a bug. Piggyback on + // Obeying the lsfDisallowXRP flag was a bug. Piggyback on // featureDepositAuth to remove the bug. if (!ctx_.view().rules().enabled(featureDepositAuth) && ((*sled)[sfFlags] & lsfDisallowXRP)) @@ -601,7 +601,9 @@ EscrowCreate::doApply() }, amount.asset().value()); !isTesSuccess(ret)) + { return ret; // LCOV_EXCL_LINE + } } // increment owner count @@ -837,10 +839,8 @@ escrowUnlockApplyHelper( bool const receiverIssuer = issuer == receiver; bool const issuerHigh = issuer > receiver; - // LCOV_EXCL_START if (senderIssuer) - return tecINTERNAL; - // LCOV_EXCL_STOP + return tecINTERNAL; // LCOV_EXCL_LINE if (receiverIssuer) return tesSUCCESS; @@ -1057,6 +1057,9 @@ EscrowFinish::doApply() } else { + // This is old code that needs to stay to support replaying old ledgers, + // but does not need to be covered by new tests. + // LCOV_EXCL_START // Too soon? if ((*slep)[~sfFinishAfter] && ctx_.view().info().parentCloseTime.time_since_epoch().count() <= @@ -1068,6 +1071,7 @@ EscrowFinish::doApply() ctx_.view().info().parentCloseTime.time_since_epoch().count() <= (*slep)[sfCancelAfter]) return tecNO_PERMISSION; + // LCOV_EXCL_STOP } // Check cryptocondition fulfillment @@ -1082,6 +1086,7 @@ EscrowFinish::doApply() // simply re-run the check. if (cb && !any(flags & (SF_CF_INVALID | SF_CF_VALID))) { + // LCOV_EXCL_START auto const fb = ctx_.tx[~sfFulfillment]; if (!fb) @@ -1093,6 +1098,7 @@ EscrowFinish::doApply() flags = SF_CF_INVALID; ctx_.app.getHashRouter().setFlags(id, flags); + // LCOV_EXCL_STOP } // If the check failed, then simply return an error @@ -1139,8 +1145,10 @@ EscrowFinish::doApply() if (!ctx_.view().dirRemove( keylet::ownerDir(account), page, k.key, true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete Escrow from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } @@ -1150,8 +1158,10 @@ EscrowFinish::doApply() if (!ctx_.view().dirRemove( keylet::ownerDir(destID), *optPage, k.key, true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } @@ -1193,8 +1203,10 @@ EscrowFinish::doApply() if (!ctx_.view().dirRemove( keylet::ownerDir(issuer), *optPage, k.key, true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; return tefBAD_LEDGER; // LCOV_EXCL_LINE + // LCOV_EXCL_STOP } } } @@ -1338,11 +1350,15 @@ EscrowCancel::doApply() } else { + // This is old code that needs to stay to support replaying old ledgers, + // but does not need to be covered by new tests. + // LCOV_EXCL_START // Too soon? if (!(*slep)[~sfCancelAfter] || ctx_.view().info().parentCloseTime.time_since_epoch().count() <= (*slep)[sfCancelAfter]) return tecNO_PERMISSION; + // LCOV_EXCL_STOP } AccountID const account = (*slep)[sfAccount]; @@ -1353,8 +1369,10 @@ EscrowCancel::doApply() if (!ctx_.view().dirRemove( keylet::ownerDir(account), page, k.key, true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete Escrow from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } @@ -1367,8 +1385,10 @@ EscrowCancel::doApply() k.key, true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } @@ -1409,8 +1429,10 @@ EscrowCancel::doApply() if (!ctx_.view().dirRemove( keylet::ownerDir(issuer), *optPage, k.key, true)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete Escrow from recipient."; - return tefBAD_LEDGER; // LCOV_EXCL_LINE + return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } } diff --git a/src/xrpld/app/tx/detail/LedgerStateFix.cpp b/src/xrpld/app/tx/detail/LedgerStateFix.cpp index 6059e15313..017f67f2ee 100644 --- a/src/xrpld/app/tx/detail/LedgerStateFix.cpp +++ b/src/xrpld/app/tx/detail/LedgerStateFix.cpp @@ -67,7 +67,7 @@ LedgerStateFix::preclaim(PreclaimContext const& ctx) } // preflight is supposed to verify that only valid FixTypes get to preclaim. - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } TER @@ -83,7 +83,7 @@ LedgerStateFix::doApply() } // preflight is supposed to verify that only valid FixTypes get to doApply. - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } } // namespace ripple diff --git a/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp b/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp index edeb12e5c0..b8728d23cf 100644 --- a/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp +++ b/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp @@ -75,7 +75,7 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx) auto const sleMptIssuance = ctx.view.read( keylet::mptIssuance(ctx.tx[sfMPTokenIssuanceID])); if (!sleMptIssuance) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE return tecHAS_OBLIGATIONS; } diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp index 4c502f1106..1dd3fbfe68 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp @@ -66,11 +66,11 @@ MPTokenIssuanceDestroy::doApply() auto const mpt = view().peek(keylet::mptIssuance(ctx_.tx[sfMPTokenIssuanceID])); if (account_ != mpt->getAccountID(sfIssuer)) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE if (!view().dirRemove( keylet::ownerDir(account_), (*mpt)[sfOwnerNode], mpt->key(), false)) - return tefBAD_LEDGER; + return tefBAD_LEDGER; // LCOV_EXCL_LINE view().erase(mpt); diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp index 6fb87711c8..f2c9bd8a96 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp @@ -282,7 +282,7 @@ MPTokenIssuanceSet::doApply() sle = view().peek(keylet::mptIssuance(mptIssuanceID)); if (!sle) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE std::uint32_t const flagsIn = sle->getFieldU32(sfFlags); std::uint32_t flagsOut = flagsIn; diff --git a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp index 3b4a27ffd7..23874ee3e0 100644 --- a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp @@ -356,7 +356,7 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) auto const& offer = bo ? bo : so; if (!offer) // Purely defensive, should be caught in preflight. - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const& tokenID = offer->at(sfNFTokenID); auto const& amount = offer->at(sfAmount); @@ -428,7 +428,7 @@ NFTokenAcceptOffer::transferNFToken( auto tokenAndPage = nft::findTokenAndPage(view(), seller, nftokenID); if (!tokenAndPage) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE if (auto const ret = nft::removeToken( view(), seller, nftokenID, std::move(tokenAndPage->page)); @@ -437,7 +437,7 @@ NFTokenAcceptOffer::transferNFToken( auto const sleBuyer = view().read(keylet::account(buyer)); if (!sleBuyer) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE std::uint32_t const buyerOwnerCountBefore = sleBuyer->getFieldU32(sfOwnerCount); @@ -523,16 +523,20 @@ NFTokenAcceptOffer::doApply() if (bo && !nft::deleteTokenOffer(view(), bo)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete buy offer '" << to_string(bo->key()) << "': ignoring"; return tecINTERNAL; + // LCOV_EXCL_STOP } if (so && !nft::deleteTokenOffer(view(), so)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete sell offer '" << to_string(so->key()) << "': ignoring"; return tecINTERNAL; + // LCOV_EXCL_STOP } // Bridging two different offers @@ -603,7 +607,7 @@ NFTokenAcceptOffer::doApply() if (so) return acceptOffer(so); - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } } // namespace ripple diff --git a/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp b/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp index 86e804b1a5..2d3eb74775 100644 --- a/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp @@ -101,9 +101,11 @@ NFTokenCancelOffer::doApply() if (auto offer = view().peek(keylet::nftoffer(id)); offer && !nft::deleteTokenOffer(view(), offer)) { + // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete token offer " << id << " (ledger " << view().seq() << ")"; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } diff --git a/src/xrpld/app/tx/detail/NFTokenMint.cpp b/src/xrpld/app/tx/detail/NFTokenMint.cpp index 8149d3b59d..dd82443fee 100644 --- a/src/xrpld/app/tx/detail/NFTokenMint.cpp +++ b/src/xrpld/app/tx/detail/NFTokenMint.cpp @@ -306,7 +306,7 @@ NFTokenMint::doApply() if (nfTokenTemplate == nullptr) // Should never happen. - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const nftokenID = createNFTokenID( extractNFTokenFlagsFromTxFlags(ctx_.tx.getFlags()), diff --git a/src/xrpld/app/tx/detail/NFTokenUtils.cpp b/src/xrpld/app/tx/detail/NFTokenUtils.cpp index ad3e6f4d35..f246e89e65 100644 --- a/src/xrpld/app/tx/detail/NFTokenUtils.cpp +++ b/src/xrpld/app/tx/detail/NFTokenUtils.cpp @@ -1046,7 +1046,7 @@ tokenOfferCreateApply( keylet::ownerDir(acctID), offerID, describeOwnerDir(acctID)); if (!ownerNode) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE bool const isSellOffer = txFlags & tfSellNFToken; @@ -1063,7 +1063,7 @@ tokenOfferCreateApply( }); if (!offerNode) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE std::uint32_t sleFlags = 0; diff --git a/src/xrpld/app/tx/detail/PayChan.cpp b/src/xrpld/app/tx/detail/PayChan.cpp index 32c0abeb93..b495e00b3f 100644 --- a/src/xrpld/app/tx/detail/PayChan.cpp +++ b/src/xrpld/app/tx/detail/PayChan.cpp @@ -126,9 +126,11 @@ closeChannel( auto const page = (*slep)[sfOwnerNode]; if (!view.dirRemove(keylet::ownerDir(src), page, key, true)) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Could not remove paychan from src owner directory"; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } @@ -139,16 +141,18 @@ closeChannel( auto const dst = (*slep)[sfDestination]; if (!view.dirRemove(keylet::ownerDir(dst), *page, key, true)) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Could not remove paychan from dst owner directory"; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } } // Transfer amount back to owner, decrement owner count auto const sle = view.peek(keylet::account(src)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE XRPL_ASSERT( (*slep)[sfAmount] >= (*slep)[sfBalance], @@ -257,7 +261,7 @@ PayChanCreate::doApply() auto const account = ctx_.tx[sfAccount]; auto const sle = ctx_.view().peek(keylet::account(account)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE if (ctx_.view().rules().enabled(fixPayChanCancelAfter)) { @@ -301,7 +305,7 @@ PayChanCreate::doApply() payChanKeylet, describeOwnerDir(account)); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE (*slep)[sfOwnerNode] = *page; } @@ -311,7 +315,7 @@ PayChanCreate::doApply() auto const page = ctx_.view().dirInsert( keylet::ownerDir(dst), payChanKeylet, describeOwnerDir(dst)); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE (*slep)[sfDestinationNode] = *page; } @@ -389,7 +393,7 @@ PayChanFund::doApply() auto const sle = ctx_.view().peek(keylet::account(txAccount)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE { // Check reserve and funds availability diff --git a/src/xrpld/app/tx/detail/Payment.cpp b/src/xrpld/app/tx/detail/Payment.cpp index 8bc0e891d0..81a083e336 100644 --- a/src/xrpld/app/tx/detail/Payment.cpp +++ b/src/xrpld/app/tx/detail/Payment.cpp @@ -632,7 +632,7 @@ Payment::doApply() auto const sleSrc = view().peek(keylet::account(account_)); if (!sleSrc) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE // ownerCount is the number of entries in this ledger for this // account that require a reserve. diff --git a/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp b/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp index 9fe48ba515..097a2d7bad 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp +++ b/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp @@ -66,9 +66,11 @@ PermissionedDomainDelete::doApply() if (!view().dirRemove(keylet::ownerDir(account_), page, slePd->key(), true)) { - JLOG(j_.fatal()) // LCOV_EXCL_LINE - << "Unable to delete permissioned domain directory entry."; // LCOV_EXCL_LINE - return tefBAD_LEDGER; // LCOV_EXCL_LINE + // LCOV_EXCL_START + JLOG(j_.fatal()) + << "Unable to delete permissioned domain directory entry."; + return tefBAD_LEDGER; + // LCOV_EXCL_STOP } auto const ownerSle = view().peek(keylet::account(account_)); diff --git a/src/xrpld/app/tx/detail/SetAccount.cpp b/src/xrpld/app/tx/detail/SetAccount.cpp index c2129ba1e1..7c60ec646a 100644 --- a/src/xrpld/app/tx/detail/SetAccount.cpp +++ b/src/xrpld/app/tx/detail/SetAccount.cpp @@ -311,7 +311,7 @@ SetAccount::doApply() { auto const sle = view().peek(keylet::account(account_)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE std::uint32_t const uFlagsIn = sle->getFieldU32(sfFlags); std::uint32_t uFlagsOut = uFlagsIn; diff --git a/src/xrpld/app/tx/detail/SetRegularKey.cpp b/src/xrpld/app/tx/detail/SetRegularKey.cpp index 4e063e7d1f..93d5899861 100644 --- a/src/xrpld/app/tx/detail/SetRegularKey.cpp +++ b/src/xrpld/app/tx/detail/SetRegularKey.cpp @@ -66,7 +66,7 @@ SetRegularKey::doApply() { auto const sle = view().peek(keylet::account(account_)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE if (!minimumFee(ctx_.app, ctx_.baseFee, view().fees(), view().flags())) sle->setFlag(lsfPasswordSpent); diff --git a/src/xrpld/app/tx/detail/SetSignerList.cpp b/src/xrpld/app/tx/detail/SetSignerList.cpp index ec2f902009..010b6baa96 100644 --- a/src/xrpld/app/tx/detail/SetSignerList.cpp +++ b/src/xrpld/app/tx/detail/SetSignerList.cpp @@ -226,8 +226,10 @@ removeSignersFromLedger( if (!view.dirRemove(ownerDirKeylet, hint, signerListKeylet.key, false)) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Unable to delete SignerList from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } adjustOwnerCount( @@ -349,7 +351,7 @@ SetSignerList::replaceSignerList() auto const sle = view().peek(accountKeylet); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE // Compute new reserve. Verify the account has funds to meet the reserve. std::uint32_t const oldOwnerCount{(*sle)[sfOwnerCount]}; @@ -387,7 +389,7 @@ SetSignerList::replaceSignerList() << ": " << (page ? "success" : "failure"); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE signerList->setFieldU64(sfOwnerNode, *page); @@ -405,7 +407,7 @@ SetSignerList::destroySignerList() // is enabled or there is a regular key. SLE::pointer ledgerEntry = view().peek(accountKeylet); if (!ledgerEntry) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE if ((ledgerEntry->isFlag(lsfDisableMaster)) && (!ledgerEntry->isFieldPresent(sfRegularKey))) diff --git a/src/xrpld/app/tx/detail/SetTrust.cpp b/src/xrpld/app/tx/detail/SetTrust.cpp index 21d4534f93..d881425960 100644 --- a/src/xrpld/app/tx/detail/SetTrust.cpp +++ b/src/xrpld/app/tx/detail/SetTrust.cpp @@ -377,7 +377,7 @@ SetTrust::doApply() auto const sle = view().peek(keylet::account(account_)); if (!sle) - return tefINTERNAL; + return tefINTERNAL; // LCOV_EXCL_LINE std::uint32_t const uOwnerCount = sle->getFieldU32(sfOwnerCount); diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index 920b1a58bc..2f62a142c0 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -571,15 +571,19 @@ Transactor::ticketDelete( SLE::pointer const sleTicket = view.peek(keylet::ticket(ticketIndex)); if (!sleTicket) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Ticket disappeared from ledger."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } std::uint64_t const page{(*sleTicket)[sfOwnerNode]}; if (!view.dirRemove(keylet::ownerDir(account), page, ticketIndex, true)) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Unable to delete Ticket from owner."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } // Update the account root's TicketCount. If the ticket count drops to @@ -587,8 +591,10 @@ Transactor::ticketDelete( auto sleAccount = view.peek(keylet::account(account)); if (!sleAccount) { + // LCOV_EXCL_START JLOG(j.fatal()) << "Could not find Ticket owner account root."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } if (auto ticketCount = (*sleAccount)[~sfTicketCount]) @@ -600,8 +606,10 @@ Transactor::ticketDelete( } else { + // LCOV_EXCL_START JLOG(j.fatal()) << "TicketCount field missing from account root."; return tefBAD_LEDGER; + // LCOV_EXCL_STOP } // Update the Ticket owner's reserve. diff --git a/src/xrpld/app/tx/detail/XChainBridge.cpp b/src/xrpld/app/tx/detail/XChainBridge.cpp index 5f5c081e2f..d7731d8d98 100644 --- a/src/xrpld/app/tx/detail/XChainBridge.cpp +++ b/src/xrpld/app/tx/detail/XChainBridge.cpp @@ -444,7 +444,7 @@ transferHelper( auto const sleSrc = psb.peek(keylet::account(src)); XRPL_ASSERT(sleSrc, "ripple::transferHelper : non-null source account"); if (!sleSrc) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE { auto const ownerCount = sleSrc->getFieldU32(sfOwnerCount); @@ -714,7 +714,7 @@ finalizeClaimHelper( } if (distributed > rewardPool) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE return tesSUCCESS; }(); @@ -1152,7 +1152,7 @@ applyCreateAccountAttestations( // subsequent claim ids auto const sleBridge = psb.peek(bridgeK); if (!sleBridge) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE (*sleBridge)[sfXChainAccountClaimCount] = attBegin->createCount; psb.update(sleBridge); } @@ -1172,12 +1172,12 @@ applyCreateAccountAttestations( claimIDKeylet, describeOwnerDir(doorAccount)); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE (*createdSleClaimID)[sfOwnerNode] = *page; auto const sleDoor = psb.peek(doorK); if (!sleDoor) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE // Reserve was already checked adjustOwnerCount(psb, sleDoor, 1, j); @@ -1242,8 +1242,9 @@ TER attestationPreclaim(PreclaimContext const& ctx) { auto const att = toClaim(ctx.tx); + // checked in preflight if (!att) - return tecINTERNAL; // checked in preflight + return tecINTERNAL; // LCOV_EXCL_LINE STXChainBridge const bridgeSpec = ctx.tx[sfXChainBridge]; auto const sleBridge = readBridge(ctx.view, bridgeSpec); @@ -1274,7 +1275,7 @@ attestationDoApply(ApplyContext& ctx) auto const att = toClaim(ctx.tx); if (!att) // Should already be checked in preflight - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE STXChainBridge const bridgeSpec = ctx.tx[sfXChainBridge]; @@ -1505,7 +1506,7 @@ XChainCreateBridge::doApply() auto const sleAcct = ctx_.view().peek(keylet::account(account)); if (!sleAcct) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE STXChainBridge::ChainType const chainType = STXChainBridge::srcChain(account == bridgeSpec.lockingChainDoor()); @@ -1527,7 +1528,7 @@ XChainCreateBridge::doApply() auto const page = ctx_.view().dirInsert( keylet::ownerDir(account), bridgeKeylet, describeOwnerDir(account)); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE (*sleBridge)[sfOwnerNode] = *page; } @@ -1620,7 +1621,7 @@ BridgeModify::doApply() auto const sleAcct = ctx_.view().peek(keylet::account(account)); if (!sleAcct) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE STXChainBridge::ChainType const chainType = STXChainBridge::srcChain(account == bridgeSpec.lockingChainDoor()); @@ -1628,7 +1629,7 @@ BridgeModify::doApply() auto const sleBridge = ctx_.view().peek(keylet::bridge(bridgeSpec, chainType)); if (!sleBridge) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE if (reward) (*sleBridge)[sfSignatureReward] = *reward; @@ -1691,7 +1692,7 @@ XChainClaim::preclaim(PreclaimContext const& ctx) else if (thisDoor == bridgeSpec.issuingChainDoor()) isLockingChain = false; else - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } { @@ -1715,7 +1716,7 @@ XChainClaim::preclaim(PreclaimContext const& ctx) // Should have been caught when creating the bridge // Detect here so `otherChainAmount` doesn't switch from IOU -> XRP // and the numeric issues that need to be addressed with that. - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } auto const otherChainAmount = [&]() -> STAmount { @@ -1921,7 +1922,7 @@ XChainCommit::preclaim(PreclaimContext const& ctx) else if (thisDoor == bridgeSpec.issuingChainDoor()) isLockingChain = false; else - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } if (isLockingChain) @@ -1948,11 +1949,11 @@ XChainCommit::doApply() auto const bridgeSpec = ctx_.tx[sfXChainBridge]; if (!psb.read(keylet::account(account))) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const sleBridge = readBridge(psb, bridgeSpec); if (!sleBridge) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const dst = (*sleBridge)[sfAccount]; @@ -2040,21 +2041,27 @@ XChainCreateClaimID::doApply() auto const sleAcct = ctx_.view().peek(keylet::account(account)); if (!sleAcct) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const sleBridge = peekBridge(ctx_.view(), bridgeSpec); if (!sleBridge) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE std::uint32_t const claimID = (*sleBridge)[sfXChainClaimID] + 1; if (claimID == 0) - return tecINTERNAL; // overflow + { + // overflow + return tecINTERNAL; // LCOV_EXCL_LINE + } (*sleBridge)[sfXChainClaimID] = claimID; Keylet const claimIDKeylet = keylet::xChainClaimID(bridgeSpec, claimID); if (ctx_.view().exists(claimIDKeylet)) - return tecINTERNAL; // already checked out!?! + { + // already checked out!?! + return tecINTERNAL; // LCOV_EXCL_LINE + } auto const sleClaimID = std::make_shared(claimIDKeylet); @@ -2073,7 +2080,7 @@ XChainCreateClaimID::doApply() claimIDKeylet, describeOwnerDir(account)); if (!page) - return tecDIR_FULL; + return tecDIR_FULL; // LCOV_EXCL_LINE (*sleClaimID)[sfOwnerNode] = *page; } @@ -2191,7 +2198,7 @@ XChainCreateAccountCommit::preclaim(PreclaimContext const& ctx) else if (thisDoor == bridgeSpec.issuingChainDoor()) srcChain = STXChainBridge::ChainType::issuing; else - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE } STXChainBridge::ChainType const dstChain = STXChainBridge::otherChain(srcChain); @@ -2217,11 +2224,11 @@ XChainCreateAccountCommit::doApply() auto const sle = psb.peek(keylet::account(account)); if (!sle) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const sleBridge = peekBridge(psb, bridge); if (!sleBridge) - return tecINTERNAL; + return tecINTERNAL; // LCOV_EXCL_LINE auto const dst = (*sleBridge)[sfAccount]; diff --git a/src/xrpld/rpc/detail/ServerHandler.cpp b/src/xrpld/rpc/detail/ServerHandler.cpp index f5f5e53238..66f4efffc6 100644 --- a/src/xrpld/rpc/detail/ServerHandler.cpp +++ b/src/xrpld/rpc/detail/ServerHandler.cpp @@ -507,10 +507,12 @@ ServerHandler::processSession( } catch (std::exception const& ex) { + // LCOV_EXCL_START jr[jss::result] = RPC::make_error(rpcINTERNAL); JLOG(m_journal.error()) << "Exception while processing WS: " << ex.what() << "\n" << "Input JSON: " << Json::Compact{Json::Value{jv}}; + // LCOV_EXCL_STOP } is->getConsumer().charge(loadType); @@ -904,10 +906,12 @@ ServerHandler::processRequest( } catch (std::exception const& ex) { + // LCOV_EXCL_START result = RPC::make_error(rpcINTERNAL); JLOG(m_journal.error()) << "Internal error : " << ex.what() << " when processing request: " << Json::Compact{Json::Value{params}}; + // LCOV_EXCL_STOP } auto end = std::chrono::system_clock::now(); diff --git a/src/xrpld/rpc/handlers/PayChanClaim.cpp b/src/xrpld/rpc/handlers/PayChanClaim.cpp index 6945d2a051..6238af3ae3 100644 --- a/src/xrpld/rpc/handlers/PayChanClaim.cpp +++ b/src/xrpld/rpc/handlers/PayChanClaim.cpp @@ -94,9 +94,11 @@ doChannelAuthorize(RPC::JsonContext& context) } catch (std::exception const& ex) { + // LCOV_EXCL_START result = RPC::make_error( rpcINTERNAL, "Exception occurred during signing: " + std::string(ex.what())); + // LCOV_EXCL_STOP } return result; } diff --git a/src/xrpld/rpc/handlers/Random.cpp b/src/xrpld/rpc/handlers/Random.cpp index cea83a616c..c2a984a2c4 100644 --- a/src/xrpld/rpc/handlers/Random.cpp +++ b/src/xrpld/rpc/handlers/Random.cpp @@ -51,7 +51,7 @@ doRandom(RPC::JsonContext& context) } catch (std::exception const&) { - return rpcError(rpcINTERNAL); + return rpcError(rpcINTERNAL); // LCOV_EXCL_LINE } } From 459d0da010626e5669d53966ff14cd1ae9e77957 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Tue, 14 Oct 2025 16:18:34 +0100 Subject: [PATCH 02/11] chore: Support CMake 4 without workarounds (#5866) --- .github/scripts/strategy-matrix/linux.json | 44 +++++++++++----------- BUILD.md | 22 +---------- conan/profiles/default | 3 -- 3 files changed, 23 insertions(+), 46 deletions(-) diff --git a/.github/scripts/strategy-matrix/linux.json b/.github/scripts/strategy-matrix/linux.json index bae5c57087..b8da322118 100644 --- a/.github/scripts/strategy-matrix/linux.json +++ b/.github/scripts/strategy-matrix/linux.json @@ -15,154 +15,154 @@ "distro_version": "bookworm", "compiler_name": "gcc", "compiler_version": "12", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "gcc", "compiler_version": "13", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "gcc", "compiler_version": "14", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "gcc", "compiler_version": "15", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "clang", "compiler_version": "16", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "clang", "compiler_version": "17", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "clang", "compiler_version": "18", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "clang", "compiler_version": "19", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "debian", "distro_version": "bookworm", "compiler_name": "clang", "compiler_version": "20", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "rhel", "distro_version": "9", "compiler_name": "gcc", "compiler_version": "12", - "image_sha": "d133ce3" + "image_sha": "6948666" }, { "distro_name": "rhel", "distro_version": "9", "compiler_name": "gcc", "compiler_version": "13", - "image_sha": "d133ce3" + "image_sha": "6948666" }, { "distro_name": "rhel", "distro_version": "9", "compiler_name": "gcc", "compiler_version": "14", - "image_sha": "d133ce3" + "image_sha": "6948666" }, { "distro_name": "rhel", "distro_version": "9", "compiler_name": "clang", "compiler_version": "any", - "image_sha": "d133ce3" + "image_sha": "6948666" }, { "distro_name": "rhel", "distro_version": "10", "compiler_name": "gcc", "compiler_version": "14", - "image_sha": "d133ce3" + "image_sha": "6948666" }, { "distro_name": "rhel", "distro_version": "10", "compiler_name": "clang", "compiler_version": "any", - "image_sha": "d133ce3" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "jammy", "compiler_name": "gcc", "compiler_version": "12", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "noble", "compiler_name": "gcc", "compiler_version": "13", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "noble", "compiler_name": "gcc", "compiler_version": "14", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "noble", "compiler_name": "clang", "compiler_version": "16", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "noble", "compiler_name": "clang", "compiler_version": "17", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "noble", "compiler_name": "clang", "compiler_version": "18", - "image_sha": "6f723eb" + "image_sha": "6948666" }, { "distro_name": "ubuntu", "distro_version": "noble", "compiler_name": "clang", "compiler_version": "19", - "image_sha": "6f723eb" + "image_sha": "6948666" } ], "build_type": ["Debug", "Release"], diff --git a/BUILD.md b/BUILD.md index fd7a0b855d..ef6b5259df 100644 --- a/BUILD.md +++ b/BUILD.md @@ -39,17 +39,12 @@ found here](./docs/build/environment.md). - [Python 3.11](https://www.python.org/downloads/), or higher - [Conan 2.17](https://conan.io/downloads.html)[^1], or higher -- [CMake 3.22](https://cmake.org/download/)[^2], or higher +- [CMake 3.22](https://cmake.org/download/), or higher [^1]: It is possible to build with Conan 1.60+, but the instructions are significantly different, which is why we are not recommending it. -[^2]: - CMake 4 is not yet supported by all dependencies required by this project. - If you are affected by this issue, follow [conan workaround for cmake - 4](#workaround-for-cmake-4) - `rippled` is written in the C++20 dialect and includes the `` header. The [minimum compiler versions][2] required are: @@ -282,21 +277,6 @@ sed -i.bak -e 's|^arch=.*$|arch=x86_64|' $(conan config home)/profiles/default sed -i.bak -e 's|^compiler\.runtime=.*$|compiler.runtime=static|' $(conan config home)/profiles/default ``` -#### Workaround for CMake 4 - -If your system CMake is version 4 rather than 3, you may have to configure Conan -profile to use CMake version 3 for dependencies, by adding the following two -lines to your profile: - -```text -[tool_requires] -!cmake/*: cmake/[>=3 <4] -``` - -This will force Conan to download and use a locally cached CMake 3 version, and -is needed because some of the dependencies used by this project do not support -CMake 4. - #### Clang workaround for grpc If your compiler is clang, version 19 or later, or apple-clang, version 17 or diff --git a/conan/profiles/default b/conan/profiles/default index 3a7bcda1c6..03f19ca118 100644 --- a/conan/profiles/default +++ b/conan/profiles/default @@ -29,6 +29,3 @@ tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw'] {% if compiler == "gcc" and compiler_version < 13 %} tools.build:cxxflags=['-Wno-restrict'] {% endif %} - -[tool_requires] -!cmake/*: cmake/[>=3 <4] From 3509de9c5f6a62ebe02a916265a4238dd4f3bcd1 Mon Sep 17 00:00:00 2001 From: tequ Date: Wed, 15 Oct 2025 03:37:39 +0900 Subject: [PATCH 03/11] refactor: Add `paychan` namespace and update related tests (#5840) This change adds a paychan namespace to the TestHelpers and implementation files, improving organization and clarity. Additionally, it updates the AMM test to use the new `paychan::create` function for payment channel creation. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- src/test/app/AMM_test.cpp | 2 +- src/test/app/PayChan_test.cpp | 2 ++ src/test/jtx/TestHelpers.h | 3 +++ src/test/jtx/impl/TestHelpers.cpp | 4 ++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index 1fe37bb7c1..3e0d65894f 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -3666,7 +3666,7 @@ private: auto const settleDelay = 100s; NetClock::time_point const cancelAfter = env.current()->info().parentCloseTime + 200s; - env(create( + env(paychan::create( carol, ammAlice.ammAccount(), XRP(1'000), diff --git a/src/test/app/PayChan_test.cpp b/src/test/app/PayChan_test.cpp index fe9b70cf7f..595a12aed9 100644 --- a/src/test/app/PayChan_test.cpp +++ b/src/test/app/PayChan_test.cpp @@ -31,6 +31,8 @@ namespace ripple { namespace test { +using namespace jtx::paychan; + struct PayChan_test : public beast::unit_test::suite { FeatureBitset const disallowIncoming{featureDisallowIncoming}; diff --git a/src/test/jtx/TestHelpers.h b/src/test/jtx/TestHelpers.h index 7d14f23c92..a7bdbb9b9f 100644 --- a/src/test/jtx/TestHelpers.h +++ b/src/test/jtx/TestHelpers.h @@ -502,6 +502,7 @@ expectLedgerEntryRoot( /* Payment Channel */ /******************************************************************************/ +namespace paychan { Json::Value create( @@ -561,6 +562,8 @@ channelBalance(ReadView const& view, uint256 const& chan); bool channelExists(ReadView const& view, uint256 const& chan); +} // namespace paychan + /* Crossing Limits */ /******************************************************************************/ diff --git a/src/test/jtx/impl/TestHelpers.cpp b/src/test/jtx/impl/TestHelpers.cpp index 20f24f0d84..71f44c691e 100644 --- a/src/test/jtx/impl/TestHelpers.cpp +++ b/src/test/jtx/impl/TestHelpers.cpp @@ -237,6 +237,8 @@ expectLedgerEntryRoot( /* Payment Channel */ /******************************************************************************/ +namespace paychan { + Json::Value create( AccountID const& account, @@ -328,6 +330,8 @@ channelExists(ReadView const& view, uint256 const& chan) return bool(slep); } +} // namespace paychan + /* Crossing Limits */ /******************************************************************************/ From 34619f2504c92f2967c855fcc0ca3d80682dcd3a Mon Sep 17 00:00:00 2001 From: zingero Date: Tue, 14 Oct 2025 22:10:19 +0300 Subject: [PATCH 04/11] docs: Fix typo in JSON writer documentation (#5881) Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- include/xrpl/json/json_writer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/xrpl/json/json_writer.h b/include/xrpl/json/json_writer.h index 7e21e766e3..ba3a51013f 100644 --- a/include/xrpl/json/json_writer.h +++ b/include/xrpl/json/json_writer.h @@ -46,7 +46,7 @@ public: * without formatting (not human friendly). * * The JSON document is written in a single line. It is not intended for 'human' - * consumption, but may be useful to support feature such as RPC where bandwith + * consumption, but may be useful to support feature such as RPC where bandwidth * is limited. \sa Reader, Value */ From 97bc94a7f6c6be467728d1da363eabdcbd2803f9 Mon Sep 17 00:00:00 2001 From: Michael Legleux Date: Tue, 14 Oct 2025 15:02:38 -0700 Subject: [PATCH 05/11] feat: Install validator-keys (#5841) * feat: Install validator-keys * output validator-keys with everything else --- cmake/RippledInstall.cmake | 4 ++-- cmake/RippledValidatorKeys.cmake | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/cmake/RippledInstall.cmake b/cmake/RippledInstall.cmake index 95c25a212f..50f09d5a4b 100644 --- a/cmake/RippledInstall.cmake +++ b/cmake/RippledInstall.cmake @@ -38,7 +38,7 @@ install(CODE " set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\") include(create_symbolic_link) create_symbolic_link(xrpl \ - \${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple) + \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple) ") install (EXPORT RippleExports @@ -72,7 +72,7 @@ if (is_root_project AND TARGET rippled) set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\") include(create_symbolic_link) create_symbolic_link(rippled${suffix} \ - \${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix}) + \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix}) ") endif () diff --git a/cmake/RippledValidatorKeys.cmake b/cmake/RippledValidatorKeys.cmake index b6760ca496..fa520ce9c1 100644 --- a/cmake/RippledValidatorKeys.cmake +++ b/cmake/RippledValidatorKeys.cmake @@ -1,4 +1,4 @@ -option (validator_keys "Enables building of validator-keys-tool as a separate target (imported via FetchContent)" OFF) +option (validator_keys "Enables building of validator-keys tool as a separate target (imported via FetchContent)" OFF) if (validator_keys) git_branch (current_branch) @@ -6,17 +6,15 @@ if (validator_keys) if (NOT (current_branch STREQUAL "release")) set (current_branch "master") endif () - message (STATUS "tracking ValidatorKeys branch: ${current_branch}") + message (STATUS "Tracking ValidatorKeys branch: ${current_branch}") FetchContent_Declare ( - validator_keys_src + validator_keys GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git GIT_TAG "${current_branch}" ) - FetchContent_GetProperties (validator_keys_src) - if (NOT validator_keys_src_POPULATED) - message (STATUS "Pausing to download ValidatorKeys...") - FetchContent_Populate (validator_keys_src) - endif () - add_subdirectory (${validator_keys_src_SOURCE_DIR} ${CMAKE_BINARY_DIR}/validator-keys) + FetchContent_MakeAvailable(validator_keys) + set_target_properties(validator-keys PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") + install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif () From 3d44758e5af811fc7dbdb47e81e887eaca87e184 Mon Sep 17 00:00:00 2001 From: Bart Date: Wed, 15 Oct 2025 14:23:44 -0400 Subject: [PATCH 06/11] fix: Update tools image shas (#5896) This change updates the Docker image hashes of the tools-rippled images to fix a missing dependency. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- .github/workflows/pre-commit.yml | 2 +- .github/workflows/publish-docs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 9b85a3bd11..da0fb02c19 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -12,4 +12,4 @@ jobs: uses: XRPLF/actions/.github/workflows/pre-commit.yml@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3 with: runs_on: ubuntu-latest - container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-d1496b8" }' + container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }' diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index efd89a5b22..84771ee4f7 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -27,7 +27,7 @@ env: jobs: publish: runs-on: ubuntu-latest - container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-d1496b8 + container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-a8c7be1 permissions: contents: write steps: From 519d1dbc34d21691bc48adb97c67e0d883e36dfb Mon Sep 17 00:00:00 2001 From: tequ Date: Thu, 16 Oct 2025 05:50:06 +0900 Subject: [PATCH 07/11] refactor: Replace fee().accountReserve(0) with fee().reserve (#5843) This PR changes fee().accountReserve(0) to fee().reserve, as the current network reserve amount should be used instead of the account reserve. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- src/test/app/AccountDelete_test.cpp | 2 +- src/test/app/Check_test.cpp | 4 ++-- src/test/app/Credentials_test.cpp | 2 +- src/test/app/DID_test.cpp | 2 +- src/test/app/EscrowToken_test.cpp | 4 ++-- src/test/app/MPToken_test.cpp | 2 +- src/test/app/NFToken_test.cpp | 13 ++++++------- src/test/app/PermissionedDomains_test.cpp | 2 +- src/test/app/SetTrust_test.cpp | 2 +- src/xrpld/app/misc/FeeVoteImpl.cpp | 6 +++--- src/xrpld/app/misc/NetworkOPs.cpp | 12 ++++-------- src/xrpld/app/misc/detail/TxQ.cpp | 2 +- src/xrpld/app/paths/PathRequest.cpp | 3 +-- src/xrpld/app/paths/Pathfinder.cpp | 2 +- src/xrpld/app/tx/detail/Payment.cpp | 4 ++-- src/xrpld/app/tx/detail/XChainBridge.cpp | 2 +- 16 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/test/app/AccountDelete_test.cpp b/src/test/app/AccountDelete_test.cpp index f7c4ddc509..a8f946c454 100644 --- a/src/test/app/AccountDelete_test.cpp +++ b/src/test/app/AccountDelete_test.cpp @@ -747,7 +747,7 @@ public: // Note that the fee structure for unit tests does not match the fees // on the production network (October 2019). Unit tests have a base // reserve of 200 XRP. - env.fund(env.current()->fees().accountReserve(0), noripple(alice)); + env.fund(env.current()->fees().reserve, noripple(alice)); env.close(); // Burn a chunk of alice's funds so she only has 1 XRP remaining in diff --git a/src/test/app/Check_test.cpp b/src/test/app/Check_test.cpp index e724b83535..74c8e9df6d 100644 --- a/src/test/app/Check_test.cpp +++ b/src/test/app/Check_test.cpp @@ -619,7 +619,7 @@ class Check_test : public beast::unit_test::suite } { // Write a check that chews into alice's reserve. - STAmount const reserve{env.current()->fees().accountReserve(0)}; + STAmount const reserve{env.current()->fees().reserve}; STAmount const checkAmount{ startBalance - reserve - drops(baseFeeDrops)}; uint256 const chkId{getCheckIndex(alice, env.seq(alice))}; @@ -657,7 +657,7 @@ class Check_test : public beast::unit_test::suite } { // Write a check that goes one drop past what alice can pay. - STAmount const reserve{env.current()->fees().accountReserve(0)}; + STAmount const reserve{env.current()->fees().reserve}; STAmount const checkAmount{ startBalance - reserve - drops(baseFeeDrops - 1)}; uint256 const chkId{getCheckIndex(alice, env.seq(alice))}; diff --git a/src/test/app/Credentials_test.cpp b/src/test/app/Credentials_test.cpp index 102d516b89..8f953bf35c 100644 --- a/src/test/app/Credentials_test.cpp +++ b/src/test/app/Credentials_test.cpp @@ -578,7 +578,7 @@ struct Credentials_test : public beast::unit_test::suite using namespace jtx; Env env{*this, features}; - auto const reserve = drops(env.current()->fees().accountReserve(0)); + auto const reserve = drops(env.current()->fees().reserve); env.fund(reserve, subject, issuer); env.close(); diff --git a/src/test/app/DID_test.cpp b/src/test/app/DID_test.cpp index 21fb6b584e..870a42fd99 100644 --- a/src/test/app/DID_test.cpp +++ b/src/test/app/DID_test.cpp @@ -64,7 +64,7 @@ struct DID_test : public beast::unit_test::suite // Fund alice enough to exist, but not enough to meet // the reserve for creating a DID. - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const baseFee = env.current()->fees().base; env.fund(acctReserve, alice); diff --git a/src/test/app/EscrowToken_test.cpp b/src/test/app/EscrowToken_test.cpp index 6caedb53f1..8535582af9 100644 --- a/src/test/app/EscrowToken_test.cpp +++ b/src/test/app/EscrowToken_test.cpp @@ -691,7 +691,7 @@ struct EscrowToken_test : public beast::unit_test::suite { Env env{*this, features}; auto const baseFee = env.current()->fees().base; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const alice = Account("alice"); auto const bob = Account("bob"); @@ -2691,7 +2691,7 @@ struct EscrowToken_test : public beast::unit_test::suite { Env env{*this, features}; auto const baseFee = env.current()->fees().base; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const alice = Account("alice"); diff --git a/src/test/app/MPToken_test.cpp b/src/test/app/MPToken_test.cpp index e9740e67de..f776695337 100644 --- a/src/test/app/MPToken_test.cpp +++ b/src/test/app/MPToken_test.cpp @@ -447,7 +447,7 @@ class MPToken_test : public beast::unit_test::suite // Test mptoken reserve requirement - first two mpts free (doApply) { Env env{*this, features}; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; // 1 drop diff --git a/src/test/app/NFToken_test.cpp b/src/test/app/NFToken_test.cpp index 1c4314643c..9edbe4652c 100644 --- a/src/test/app/NFToken_test.cpp +++ b/src/test/app/NFToken_test.cpp @@ -208,7 +208,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite // Fund alice and minter enough to exist, but not enough to meet // the reserve for creating their first NFT. - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const baseFee = env.current()->fees().base; @@ -6744,8 +6744,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite { // check reserve - auto const acctReserve = - env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; env.fund(acctReserve + incReserve, bob); @@ -7134,7 +7133,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite Account const bob{"bob"}; Env env{*this, features}; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const baseFee = env.current()->fees().base; @@ -7217,7 +7216,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite Account const bob{"bob"}; Env env{*this, features}; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; env.fund(XRP(10000), alice); @@ -7314,7 +7313,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite Account const bob{"bob"}; Env env{*this, features}; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const baseFee = env.current()->fees().base; @@ -7365,7 +7364,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite Account const broker{"broker"}; Env env{*this, features}; - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; auto const baseFee = env.current()->fees().base; diff --git a/src/test/app/PermissionedDomains_test.cpp b/src/test/app/PermissionedDomains_test.cpp index 31e34ccf17..b177261e37 100644 --- a/src/test/app/PermissionedDomains_test.cpp +++ b/src/test/app/PermissionedDomains_test.cpp @@ -528,7 +528,7 @@ class PermissionedDomains_test : public beast::unit_test::suite // Fund alice enough to exist, but not enough to meet // the reserve. - auto const acctReserve = env.current()->fees().accountReserve(0); + auto const acctReserve = env.current()->fees().reserve; auto const incReserve = env.current()->fees().increment; env.fund(acctReserve, alice); env.close(); diff --git a/src/test/app/SetTrust_test.cpp b/src/test/app/SetTrust_test.cpp index 18457b5faf..00ca0aa3a7 100644 --- a/src/test/app/SetTrust_test.cpp +++ b/src/test/app/SetTrust_test.cpp @@ -192,7 +192,7 @@ public: auto const& assistor = createOnHighAcct ? acctC : acctD; auto const txFee = env.current()->fees().base; - auto const baseReserve = env.current()->fees().accountReserve(0); + auto const baseReserve = env.current()->fees().reserve; auto const threelineReserve = env.current()->fees().accountReserve(3); env.fund(XRP(10000), gwA, gwB, assistor); diff --git a/src/xrpld/app/misc/FeeVoteImpl.cpp b/src/xrpld/app/misc/FeeVoteImpl.cpp index 85b5791d67..c688cd3b19 100644 --- a/src/xrpld/app/misc/FeeVoteImpl.cpp +++ b/src/xrpld/app/misc/FeeVoteImpl.cpp @@ -142,7 +142,7 @@ FeeVoteImpl::doValidation( }; vote(lastFees.base, target_.reference_fee, "base fee", sfBaseFeeDrops); vote( - lastFees.accountReserve(0), + lastFees.reserve, target_.account_reserve, "base reserve", sfReserveBaseDrops); @@ -178,7 +178,7 @@ FeeVoteImpl::doValidation( vote(lastFees.base, target_.reference_fee, to64, "base fee", sfBaseFee); vote( - lastFees.accountReserve(0), + lastFees.reserve, target_.account_reserve, to32, "base reserve", @@ -207,7 +207,7 @@ FeeVoteImpl::doVoting( lastClosedLedger->fees().base, target_.reference_fee); detail::VotableValue baseReserveVote( - lastClosedLedger->fees().accountReserve(0), target_.account_reserve); + lastClosedLedger->fees().reserve, target_.account_reserve); detail::VotableValue incReserveVote( lastClosedLedger->fees().increment, target_.owner_reserve); diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index 3154426696..d649bb3a29 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -2936,8 +2936,7 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters) if (!human) { l[jss::base_fee] = baseFee.jsonClipped(); - l[jss::reserve_base] = - lpClosed->fees().accountReserve(0).jsonClipped(); + l[jss::reserve_base] = lpClosed->fees().reserve.jsonClipped(); l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped(); l[jss::close_time] = Json::Value::UInt( lpClosed->info().closeTime.time_since_epoch().count()); @@ -2945,8 +2944,7 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters) else { l[jss::base_fee_xrp] = baseFee.decimalXRP(); - l[jss::reserve_base_xrp] = - lpClosed->fees().accountReserve(0).decimalXRP(); + l[jss::reserve_base_xrp] = lpClosed->fees().reserve.decimalXRP(); l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP(); if (auto const closeOffset = app_.timeKeeper().closeOffset(); @@ -3136,8 +3134,7 @@ NetworkOPsImp::pubLedger(std::shared_ptr const& lpAccepted) if (!lpAccepted->rules().enabled(featureXRPFees)) jvObj[jss::fee_ref] = Config::FEE_UNITS_DEPRECATED; jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped(); - jvObj[jss::reserve_base] = - lpAccepted->fees().accountReserve(0).jsonClipped(); + jvObj[jss::reserve_base] = lpAccepted->fees().reserve.jsonClipped(); jvObj[jss::reserve_inc] = lpAccepted->fees().increment.jsonClipped(); @@ -4215,8 +4212,7 @@ NetworkOPsImp::subLedger(InfoSub::ref isrListener, Json::Value& jvResult) if (!lpClosed->rules().enabled(featureXRPFees)) jvResult[jss::fee_ref] = Config::FEE_UNITS_DEPRECATED; jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped(); - jvResult[jss::reserve_base] = - lpClosed->fees().accountReserve(0).jsonClipped(); + jvResult[jss::reserve_base] = lpClosed->fees().reserve.jsonClipped(); jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped(); jvResult[jss::network_id] = app_.config().NETWORK_ID; } diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index 6924dae6c8..7c0a6f07e2 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -1113,7 +1113,7 @@ TxQ::apply( comparable scale to the base fee, ignore the reserve. Only check the account balance. */ - auto const reserve = view.fees().accountReserve(0); + auto const reserve = view.fees().reserve; auto const base = view.fees().base; if (totalFee >= balance || (reserve > 10 * base && totalFee >= reserve)) diff --git a/src/xrpld/app/paths/PathRequest.cpp b/src/xrpld/app/paths/PathRequest.cpp index 8a88e774d0..a9db61d5b3 100644 --- a/src/xrpld/app/paths/PathRequest.cpp +++ b/src/xrpld/app/paths/PathRequest.cpp @@ -206,8 +206,7 @@ PathRequest::isValid(std::shared_ptr const& crCache) return false; } - if (!convert_all_ && - saDstAmount < STAmount(lrLedger->fees().accountReserve(0))) + if (!convert_all_ && saDstAmount < STAmount(lrLedger->fees().reserve)) { // Payment must meet reserve. jvStatus = rpcError(rpcDST_AMT_MALFORMED); diff --git a/src/xrpld/app/paths/Pathfinder.cpp b/src/xrpld/app/paths/Pathfinder.cpp index 4bc9304853..7f9c2f8437 100644 --- a/src/xrpld/app/paths/Pathfinder.cpp +++ b/src/xrpld/app/paths/Pathfinder.cpp @@ -278,7 +278,7 @@ Pathfinder::findPaths( return false; } - auto const reserve = STAmount(mLedger->fees().accountReserve(0)); + auto const reserve = STAmount(mLedger->fees().reserve); if (mDstAmount < reserve) { JLOG(j_.debug()) diff --git a/src/xrpld/app/tx/detail/Payment.cpp b/src/xrpld/app/tx/detail/Payment.cpp index 81a083e336..b9bdbd0a34 100644 --- a/src/xrpld/app/tx/detail/Payment.cpp +++ b/src/xrpld/app/tx/detail/Payment.cpp @@ -346,7 +346,7 @@ Payment::preclaim(PreclaimContext const& ctx) // transaction would succeed. return telNO_DST_PARTIAL; } - else if (dstAmount < STAmount(ctx.view.fees().accountReserve(0))) + else if (dstAmount < STAmount(ctx.view.fees().reserve)) { // accountReserve is the minimum amount that an account can have. // Reserve is not scaled by load. @@ -690,7 +690,7 @@ Payment::doApply() // to get the account un-wedged. // Get the base reserve. - XRPAmount const dstReserve{view().fees().accountReserve(0)}; + XRPAmount const dstReserve{view().fees().reserve}; if (dstAmount > dstReserve || sleDst->getFieldAmount(sfBalance) > dstReserve) diff --git a/src/xrpld/app/tx/detail/XChainBridge.cpp b/src/xrpld/app/tx/detail/XChainBridge.cpp index d7731d8d98..503a01c3c9 100644 --- a/src/xrpld/app/tx/detail/XChainBridge.cpp +++ b/src/xrpld/app/tx/detail/XChainBridge.cpp @@ -476,7 +476,7 @@ transferHelper( // Already checked, but OK to check again return tecNO_DST; } - if (amt < psb.fees().accountReserve(0)) + if (amt < psb.fees().reserve) { JLOG(j.trace()) << "Insufficient payment to create account."; return tecNO_DST_INSUF_XRP; From 108f90586c68a83680e2f2710767684e22f5d97d Mon Sep 17 00:00:00 2001 From: Jingchen Date: Wed, 15 Oct 2025 21:53:01 +0100 Subject: [PATCH 08/11] chore: Reduce build log verbosity on Windows (#5865) Windows is extremely chatty and generates tons of logs when building, making it practically impossible to use the build logs to debug issues. This change sets the verbosity to 'quiet' on Windows. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- .github/actions/build-deps/action.yml | 7 +++++++ .github/workflows/upload-conan-deps.yml | 3 +++ conan/global.conf | 5 +---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/actions/build-deps/action.yml b/.github/actions/build-deps/action.yml index a908c656e8..7b2a3c385a 100644 --- a/.github/actions/build-deps/action.yml +++ b/.github/actions/build-deps/action.yml @@ -4,6 +4,10 @@ description: "Install Conan dependencies, optionally forcing a rebuild of all de # Note that actions do not support 'type' and all inputs are strings, see # https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs. inputs: + verbosity: + description: "The build verbosity." + required: false + default: "verbose" build_dir: description: "The directory where to build." required: true @@ -34,4 +38,7 @@ runs: --options:host='&:tests=True' \ --options:host='&:xrpld=True' \ --settings:all build_type='${{ env.BUILD_TYPE }}' \ + --conf:all tools.build:verbosity='${{ inputs.verbosity }}' \ + --conf:all tools.compilation:verbosity='${{ inputs.verbosity }}' \ + --conf:all tools.build:jobs=$(nproc) \ .. diff --git a/.github/workflows/upload-conan-deps.yml b/.github/workflows/upload-conan-deps.yml index 680602d978..aedd367f65 100644 --- a/.github/workflows/upload-conan-deps.yml +++ b/.github/workflows/upload-conan-deps.yml @@ -79,6 +79,9 @@ jobs: build_dir: .build build_type: ${{ matrix.build_type }} force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }} + # The verbosity is set to "quiet" for Windows to avoid an excessive amount of logs, while it + # is set to "verbose" otherwise to provide more information during the build process. + verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }} - name: Log into Conan remote if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }} diff --git a/conan/global.conf b/conan/global.conf index ae03818232..41ac76da89 100644 --- a/conan/global.conf +++ b/conan/global.conf @@ -1,9 +1,6 @@ # Global configuration for Conan. This is used to set the number of parallel -# downloads, uploads, and build jobs. The verbosity is set to verbose to -# provide more information during the build process. +# downloads, uploads, and build jobs. core:non_interactive=True core.download:parallel={{ os.cpu_count() }} core.upload:parallel={{ os.cpu_count() }} tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} -tools.build:verbosity=verbose -tools.compilation:verbosity=verbose From a422855ea7415c1e2e8d135812021823d8a641c1 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 15 Oct 2025 16:55:11 -0400 Subject: [PATCH 09/11] refactor: replace JSON LastLedgerSequence with last_ledger_seq (#5884) This change replaces instances of JSON LastLedgerSequence with last_ledger_seq, which makes the tests a bit simpler and easier to read. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- src/test/app/Transaction_ordering_test.cpp | 16 +++------ src/test/app/TxQ_test.cpp | 42 +++++++++------------- src/test/rpc/LedgerRPC_test.cpp | 2 +- 3 files changed, 23 insertions(+), 37 deletions(-) diff --git a/src/test/app/Transaction_ordering_test.cpp b/src/test/app/Transaction_ordering_test.cpp index 472d4e2ab8..5ace79db59 100644 --- a/src/test/app/Transaction_ordering_test.cpp +++ b/src/test/app/Transaction_ordering_test.cpp @@ -37,10 +37,8 @@ struct Transaction_ordering_test : public beast::unit_test::suite auto const aliceSequence = env.seq(alice); auto const tx1 = env.jt(noop(alice), seq(aliceSequence)); - auto const tx2 = env.jt( - noop(alice), - seq(aliceSequence + 1), - json(R"({"LastLedgerSequence":7})")); + auto const tx2 = + env.jt(noop(alice), seq(aliceSequence + 1), last_ledger_seq(7)); env(tx1); env.close(); @@ -83,10 +81,8 @@ struct Transaction_ordering_test : public beast::unit_test::suite auto const aliceSequence = env.seq(alice); auto const tx1 = env.jt(noop(alice), seq(aliceSequence)); - auto const tx2 = env.jt( - noop(alice), - seq(aliceSequence + 1), - json(R"({"LastLedgerSequence":7})")); + auto const tx2 = + env.jt(noop(alice), seq(aliceSequence + 1), last_ledger_seq(7)); env(tx2, ter(terPRE_SEQ)); BEAST_EXPECT(env.seq(alice) == aliceSequence); @@ -131,9 +127,7 @@ struct Transaction_ordering_test : public beast::unit_test::suite for (auto i = 0; i < 5; ++i) { tx.emplace_back(env.jt( - noop(alice), - seq(aliceSequence + i), - json(R"({"LastLedgerSequence":7})"))); + noop(alice), seq(aliceSequence + i), last_ledger_seq(7))); } for (auto i = 1; i < 5; ++i) diff --git a/src/test/app/TxQ_test.cpp b/src/test/app/TxQ_test.cpp index d0965cc8ff..190acfeddf 100644 --- a/src/test/app/TxQ_test.cpp +++ b/src/test/app/TxQ_test.cpp @@ -747,11 +747,9 @@ public: BEAST_EXPECT(env.current()->info().seq == 6); // Fail to queue an item with a low LastLedgerSeq - env(noop(alice), - json(R"({"LastLedgerSequence":7})"), - ter(telCAN_NOT_QUEUE)); + env(noop(alice), last_ledger_seq(7), ter(telCAN_NOT_QUEUE)); // Queue an item with a sufficient LastLedgerSeq. - env(noop(alice), json(R"({"LastLedgerSequence":8})"), queued); + env(noop(alice), last_ledger_seq(8), queued); constexpr auto largeFeeMultiplier = 700; auto const largeFee = baseFee * largeFeeMultiplier; @@ -2705,21 +2703,15 @@ public: auto const aliceSeq = env.seq(alice); BEAST_EXPECT(env.current()->info().seq == 3); - env(noop(alice), - seq(aliceSeq), - json(R"({"LastLedgerSequence":5})"), - ter(terQUEUED)); - env(noop(alice), - seq(aliceSeq + 1), - json(R"({"LastLedgerSequence":5})"), - ter(terQUEUED)); + env(noop(alice), seq(aliceSeq), last_ledger_seq(5), ter(terQUEUED)); + env(noop(alice), seq(aliceSeq + 1), last_ledger_seq(5), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 2), - json(R"({"LastLedgerSequence":10})"), + last_ledger_seq(10), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 3), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); checkMetrics(*this, env, 4, std::nullopt, 2, 1); auto const bobSeq = env.seq(bob); @@ -2816,39 +2808,39 @@ public: ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 11), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 12), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 13), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 14), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 15), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 16), - json(R"({"LastLedgerSequence": 5})"), + last_ledger_seq(5), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 17), - json(R"({"LastLedgerSequence": 5})"), + last_ledger_seq(5), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 18), - json(R"({"LastLedgerSequence": 5})"), + last_ledger_seq(5), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 19), - json(R"({"LastLedgerSequence":11})"), + last_ledger_seq(11), ter(terQUEUED)); checkMetrics(*this, env, 10, std::nullopt, 2, 1); @@ -4575,7 +4567,7 @@ public: env(noop(alice), seq(seqAlice++), fee(--feeDrops), - json(R"({"LastLedgerSequence": 7})"), + last_ledger_seq(7), ter(terQUEUED)); env(noop(alice), seq(seqAlice++), fee(--feeDrops), ter(terQUEUED)); env(noop(alice), seq(seqAlice++), fee(--feeDrops), ter(terQUEUED)); @@ -4585,7 +4577,7 @@ public: // The drop penalty works a little differently with tickets. env(noop(bob), ticket::use(bobTicketSeq + 0), - json(R"({"LastLedgerSequence": 7})"), + last_ledger_seq(7), ter(terQUEUED)); env(noop(bob), ticket::use(bobTicketSeq + 1), diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index 9309fbdd6c..3c8da6dc13 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -527,7 +527,7 @@ class LedgerRPC_test : public beast::unit_test::suite // Alice auto aliceSeq = env.seq(alice); env(pay(alice, "george", XRP(1000)), - json(R"({"LastLedgerSequence":7})"), + last_ledger_seq(7), ter(terQUEUED)); env(offer(alice, XRP(50000), alice["USD"](5000)), seq(aliceSeq + 1), From 640ce4988fdb98bfcfda3e6fd973d4fc7cfb1e56 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 16 Oct 2025 08:46:21 -0400 Subject: [PATCH 10/11] refactor: replace boost::lexical_cast with to_string (#5883) This change replaces boost::lexical_cast with to_string in some of the tests to make them more readable. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- src/test/app/NFTokenBurn_test.cpp | 24 +++---- src/test/app/NFTokenDir_test.cpp | 6 +- src/test/app/Oracle_test.cpp | 6 +- src/test/jtx/impl/Env.cpp | 2 +- src/test/rpc/AccountCurrencies_test.cpp | 36 +++------- src/test/rpc/Feature_test.cpp | 18 ++--- src/test/rpc/LedgerData_test.cpp | 65 +++++------------- src/test/rpc/LedgerRPC_test.cpp | 89 ++++++------------------- src/test/rpc/NoRippleCheck_test.cpp | 66 ++++++------------ src/test/rpc/TransactionEntry_test.cpp | 15 ++--- 10 files changed, 91 insertions(+), 236 deletions(-) diff --git a/src/test/app/NFTokenBurn_test.cpp b/src/test/app/NFTokenBurn_test.cpp index 44c55f2b8c..7e582446ef 100644 --- a/src/test/app/NFTokenBurn_test.cpp +++ b/src/test/app/NFTokenBurn_test.cpp @@ -88,10 +88,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = false; { - Json::Value jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams)); + Json::Value jrr = + env.rpc("json", "ledger_data", to_string(jvParams)); // Iterate the state and print all NFTokenPages. if (!jrr.isMember(jss::result) || @@ -413,10 +411,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = false; { - Json::Value jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams)); + Json::Value jrr = + env.rpc("json", "ledger_data", to_string(jvParams)); Json::Value& state = jrr[jss::result][jss::state]; @@ -460,10 +456,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = false; { - Json::Value jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams)); + Json::Value jrr = + env.rpc("json", "ledger_data", to_string(jvParams)); Json::Value& state = jrr[jss::result][jss::state]; @@ -1235,10 +1229,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = false; { - Json::Value jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams)); + Json::Value jrr = + env.rpc("json", "ledger_data", to_string(jvParams)); Json::Value& state = jrr[jss::result][jss::state]; diff --git a/src/test/app/NFTokenDir_test.cpp b/src/test/app/NFTokenDir_test.cpp index a63653d8dc..19f4f7efba 100644 --- a/src/test/app/NFTokenDir_test.cpp +++ b/src/test/app/NFTokenDir_test.cpp @@ -47,10 +47,8 @@ class NFTokenDir_test : public beast::unit_test::suite jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = false; { - Json::Value jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams)); + Json::Value jrr = + env.rpc("json", "ledger_data", to_string(jvParams)); // Iterate the state and print all NFTokenPages. if (!jrr.isMember(jss::result) || diff --git a/src/test/app/Oracle_test.cpp b/src/test/app/Oracle_test.cpp index f0cde41394..c81d441abc 100644 --- a/src/test/app/Oracle_test.cpp +++ b/src/test/app/Oracle_test.cpp @@ -592,10 +592,8 @@ private: jvParams[field] = value; jvParams[jss::binary] = false; jvParams[jss::type] = jss::oracle; - Json::Value jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams)); + Json::Value jrr = + env.rpc("json", "ledger_data", to_string(jvParams)); BEAST_EXPECT(jrr[jss::result][jss::state].size() == 2); }; verifyLedgerData(jss::ledger_index, index); diff --git a/src/test/jtx/impl/Env.cpp b/src/test/jtx/impl/Env.cpp index ae99e1b5d6..f17f6cb39d 100644 --- a/src/test/jtx/impl/Env.cpp +++ b/src/test/jtx/impl/Env.cpp @@ -411,7 +411,7 @@ Env::sign_and_submit(JTx const& jt, Json::Value params) if (params.isNull()) { // Use the command line interface - auto const jv = boost::lexical_cast(jt.jv); + auto const jv = to_string(jt.jv); jr = rpc("submit", passphrase, jv); } else diff --git a/src/test/rpc/AccountCurrencies_test.cpp b/src/test/rpc/AccountCurrencies_test.cpp index 3ccb89c471..b21aacf865 100644 --- a/src/test/rpc/AccountCurrencies_test.cpp +++ b/src/test/rpc/AccountCurrencies_test.cpp @@ -43,9 +43,7 @@ class AccountCurrencies_test : public beast::unit_test::suite params[jss::account] = Account{"bob"}.human(); params[jss::ledger_hash] = 1; auto const result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "invalidParams"); BEAST_EXPECT(result[jss::error_message] == "ledgerHashNotString"); } @@ -107,9 +105,7 @@ class AccountCurrencies_test : public beast::unit_test::suite params[jss::account] = "llIIOO"; // these are invalid in bitcoin alphabet auto const result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "actMalformed"); BEAST_EXPECT(result[jss::error_message] == "Account malformed."); } @@ -119,9 +115,7 @@ class AccountCurrencies_test : public beast::unit_test::suite Json::Value params; params[jss::account] = "Bob"; auto const result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "actMalformed"); BEAST_EXPECT(result[jss::error_message] == "Account malformed."); } @@ -130,9 +124,7 @@ class AccountCurrencies_test : public beast::unit_test::suite Json::Value params; params[jss::account] = Account{"bob"}.human(); auto const result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "actNotFound"); BEAST_EXPECT(result[jss::error_message] == "Account not found."); } @@ -161,9 +153,7 @@ class AccountCurrencies_test : public beast::unit_test::suite Json::Value params; params[jss::account] = alice.human(); auto result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; auto arrayCheck = [&result]( @@ -189,9 +179,7 @@ class AccountCurrencies_test : public beast::unit_test::suite // send_currencies should be populated now result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrencies)); BEAST_EXPECT(arrayCheck(jss::send_currencies, gwCurrencies)); @@ -203,9 +191,7 @@ class AccountCurrencies_test : public beast::unit_test::suite BEAST_EXPECT( l[jss::freeze].asBool() == (l[jss::currency] == "USD")); result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrencies)); BEAST_EXPECT(arrayCheck(jss::send_currencies, gwCurrencies)); // clear the freeze @@ -215,9 +201,7 @@ class AccountCurrencies_test : public beast::unit_test::suite env(pay(gw, alice, gw["USA"](50))); // USA should now be missing from receive_currencies result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; decltype(gwCurrencies) gwCurrenciesNoUSA( gwCurrencies.begin() + 1, gwCurrencies.end()); BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrenciesNoUSA)); @@ -228,9 +212,7 @@ class AccountCurrencies_test : public beast::unit_test::suite env(trust(gw, alice["USA"](100))); env(pay(alice, gw, alice["USA"](200))); result = env.rpc( - "json", - "account_currencies", - boost::lexical_cast(params))[jss::result]; + "json", "account_currencies", to_string(params))[jss::result]; BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrencies)); BEAST_EXPECT(arrayCheck(jss::send_currencies, gwCurrenciesNoUSA)); } diff --git a/src/test/rpc/Feature_test.cpp b/src/test/rpc/Feature_test.cpp index 06697f80c1..84fc284b13 100644 --- a/src/test/rpc/Feature_test.cpp +++ b/src/test/rpc/Feature_test.cpp @@ -309,10 +309,8 @@ class Feature_test : public beast::unit_test::suite params[jss::feature] = "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD" "EF"; - auto const result = env.rpc( - "json", - "feature", - boost::lexical_cast(params))[jss::result]; + auto const result = + env.rpc("json", "feature", to_string(params))[jss::result]; BEAST_EXPECTS( result[jss::error] == "badFeature", result.toStyledString()); BEAST_EXPECT( @@ -326,10 +324,8 @@ class Feature_test : public beast::unit_test::suite "A7"; // invalid param params[jss::vetoed] = true; - auto const result = env.rpc( - "json", - "feature", - boost::lexical_cast(params))[jss::result]; + auto const result = + env.rpc("json", "feature", to_string(params))[jss::result]; BEAST_EXPECTS( result[jss::error] == "noPermission", result[jss::error].asString()); @@ -344,10 +340,8 @@ class Feature_test : public beast::unit_test::suite "37"; Json::Value params; params[jss::feature] = feature; - auto const result = env.rpc( - "json", - "feature", - boost::lexical_cast(params))[jss::result]; + auto const result = + env.rpc("json", "feature", to_string(params))[jss::result]; BEAST_EXPECT(result.isMember(feature)); auto const amendmentResult = result[feature]; BEAST_EXPECT(amendmentResult[jss::enabled].asBool() == false); diff --git a/src/test/rpc/LedgerData_test.cpp b/src/test/rpc/LedgerData_test.cpp index d57b33013a..120e49f129 100644 --- a/src/test/rpc/LedgerData_test.cpp +++ b/src/test/rpc/LedgerData_test.cpp @@ -63,9 +63,7 @@ public: jvParams[jss::binary] = false; { auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT( jrr[jss::ledger_current_index].isIntegral() && jrr[jss::ledger_current_index].asInt() > 0); @@ -78,9 +76,7 @@ public: { jvParams[jss::limit] = max_limit + delta; auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(checkArraySize( jrr[jss::state], (delta > 0 && !asAdmin) ? max_limit : max_limit + delta)); @@ -109,10 +105,8 @@ public: Json::Value jvParams; jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = true; - auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + auto const jrr = + env.rpc("json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT( jrr[jss::ledger_current_index].isIntegral() && jrr[jss::ledger_current_index].asInt() > 0); @@ -137,9 +131,7 @@ public: Json::Value jvParams; jvParams[jss::limit] = "0"; // NOT an integer auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::status] == "error"); BEAST_EXPECT( @@ -152,9 +144,7 @@ public: Json::Value jvParams; jvParams[jss::marker] = "NOT_A_MARKER"; auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::status] == "error"); BEAST_EXPECT( @@ -167,9 +157,7 @@ public: Json::Value jvParams; jvParams[jss::marker] = 1; auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::status] == "error"); BEAST_EXPECT( @@ -182,9 +170,7 @@ public: Json::Value jvParams; jvParams[jss::ledger_index] = 10u; auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "lgrNotFound"); BEAST_EXPECT(jrr[jss::status] == "error"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound"); @@ -213,27 +199,20 @@ public: Json::Value jvParams; jvParams[jss::ledger_index] = "current"; jvParams[jss::binary] = false; - auto jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + auto jrr = + env.rpc("json", "ledger_data", to_string(jvParams))[jss::result]; auto const total_count = jrr[jss::state].size(); // now make request with a limit and loop until we get all jvParams[jss::limit] = 5; - jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(checkMarker(jrr)); auto running_total = jrr[jss::state].size(); while (jrr.isMember(jss::marker)) { jvParams[jss::marker] = jrr[jss::marker]; jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; running_total += jrr[jss::state].size(); } BEAST_EXPECT(running_total == total_count); @@ -253,9 +232,7 @@ public: Json::Value jvParams; jvParams[jss::ledger_index] = "closed"; auto jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; if (BEAST_EXPECT(jrr.isMember(jss::ledger))) BEAST_EXPECT( jrr[jss::ledger][jss::ledger_hash] == @@ -267,9 +244,7 @@ public: jvParams[jss::ledger_index] = "closed"; jvParams[jss::binary] = true; auto jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; if (BEAST_EXPECT(jrr.isMember(jss::ledger))) { auto data = @@ -288,9 +263,7 @@ public: Json::Value jvParams; jvParams[jss::binary] = true; auto jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(!jrr[jss::ledger].isMember(jss::ledger_data)); } @@ -319,9 +292,7 @@ public: jvParams[jss::ledger_index] = "current"; jvParams[jss::type] = type; return env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; }; // Assert that state is an empty array. @@ -500,9 +471,7 @@ public: jvParams[jss::ledger_index] = "current"; jvParams[jss::type] = "misspelling"; auto const jrr = env.rpc( - "json", - "ledger_data", - boost::lexical_cast(jvParams))[jss::result]; + "json", "ledger_data", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember("error")); BEAST_EXPECT(jrr["error"] == "invalidParams"); BEAST_EXPECT(jrr["error_message"] == "Invalid field 'type'."); diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index 3c8da6dc13..6e132857ae 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -287,56 +287,39 @@ class LedgerRPC_test : public beast::unit_test::suite // access via the legacy ledger field, keyword index values Json::Value jvParams; jvParams[jss::ledger] = "closed"; - auto jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + auto jrr = + env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5"); jvParams[jss::ledger] = "validated"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5"); jvParams[jss::ledger] = "current"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "6"); // ask for a bad ledger keyword jvParams[jss::ledger] = "invalid"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerIndexMalformed"); // numeric index jvParams[jss::ledger] = 4; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "4"); // numeric index - out of range jvParams[jss::ledger] = 20; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "lgrNotFound"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound"); } @@ -348,29 +331,21 @@ class LedgerRPC_test : public beast::unit_test::suite // access via the ledger_hash field Json::Value jvParams; jvParams[jss::ledger_hash] = hash3; - auto jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + auto jrr = + env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "3"); // extra leading hex chars in hash are not allowed jvParams[jss::ledger_hash] = "DEADBEEF" + hash3; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerHashMalformed"); // request with non-string ledger_hash jvParams[jss::ledger_hash] = 2; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerHashNotString"); @@ -378,10 +353,7 @@ class LedgerRPC_test : public beast::unit_test::suite jvParams[jss::ledger_hash] = "2E81FC6EC0DD943197EGC7E3FBE9AE30" "7F2775F2F7485BB37307984C3C0F2340"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerHashMalformed"); @@ -389,10 +361,7 @@ class LedgerRPC_test : public beast::unit_test::suite jvParams[jss::ledger_hash] = "8C3EEDB3124D92E49E75D81A8826A2E6" "5A75FD71FC3FD6F36FEB803C5F1D812D"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "lgrNotFound"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound"); } @@ -401,39 +370,28 @@ class LedgerRPC_test : public beast::unit_test::suite // access via the ledger_index field, keyword index values Json::Value jvParams; jvParams[jss::ledger_index] = "closed"; - auto jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + auto jrr = + env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5"); BEAST_EXPECT(jrr.isMember(jss::ledger_index)); jvParams[jss::ledger_index] = "validated"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5"); jvParams[jss::ledger_index] = "current"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "6"); BEAST_EXPECT(jrr.isMember(jss::ledger_current_index)); // ask for a bad ledger keyword jvParams[jss::ledger_index] = "invalid"; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "invalidParams"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerIndexMalformed"); @@ -441,10 +399,8 @@ class LedgerRPC_test : public beast::unit_test::suite for (auto i : {1, 2, 3, 4, 5, 6}) { jvParams[jss::ledger_index] = i; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = + env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr.isMember(jss::ledger)); if (i < 6) BEAST_EXPECT(jrr.isMember(jss::ledger_hash)); @@ -454,10 +410,7 @@ class LedgerRPC_test : public beast::unit_test::suite // numeric index - out of range jvParams[jss::ledger_index] = 7; - jrr = env.rpc( - "json", - "ledger", - boost::lexical_cast(jvParams))[jss::result]; + jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result]; BEAST_EXPECT(jrr[jss::error] == "lgrNotFound"); BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound"); } diff --git a/src/test/rpc/NoRippleCheck_test.cpp b/src/test/rpc/NoRippleCheck_test.cpp index 6cd566e144..f379e273dd 100644 --- a/src/test/rpc/NoRippleCheck_test.cpp +++ b/src/test/rpc/NoRippleCheck_test.cpp @@ -59,9 +59,7 @@ class NoRippleCheck_test : public beast::unit_test::suite Json::Value params; params[jss::account] = alice.human(); auto const result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + "json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "invalidParams"); BEAST_EXPECT(result[jss::error_message] == "Missing field 'role'."); } @@ -92,9 +90,7 @@ class NoRippleCheck_test : public beast::unit_test::suite params[jss::account] = alice.human(); params[jss::role] = "not_a_role"; auto const result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + "json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "invalidParams"); BEAST_EXPECT(result[jss::error_message] == "Invalid field 'role'."); } @@ -105,9 +101,7 @@ class NoRippleCheck_test : public beast::unit_test::suite params[jss::role] = "user"; params[jss::limit] = -1; auto const result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + "json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "invalidParams"); BEAST_EXPECT( result[jss::error_message] == @@ -120,9 +114,7 @@ class NoRippleCheck_test : public beast::unit_test::suite params[jss::role] = "user"; params[jss::ledger_hash] = 1; auto const result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + "json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "invalidParams"); BEAST_EXPECT(result[jss::error_message] == "ledgerHashNotString"); } @@ -133,9 +125,7 @@ class NoRippleCheck_test : public beast::unit_test::suite params[jss::role] = "user"; params[jss::ledger] = "current"; auto const result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + "json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "actNotFound"); BEAST_EXPECT(result[jss::error_message] == "Account not found."); } @@ -147,9 +137,7 @@ class NoRippleCheck_test : public beast::unit_test::suite params[jss::role] = "user"; params[jss::ledger] = "current"; auto const result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + "json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result[jss::error] == "actMalformed"); BEAST_EXPECT(result[jss::error_message] == "Account malformed."); } @@ -184,10 +172,8 @@ class NoRippleCheck_test : public beast::unit_test::suite params[jss::account] = alice.human(); params[jss::role] = (user ? "user" : "gateway"); params[jss::ledger] = "current"; - auto result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + auto result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; auto const pa = result["problems"]; if (!BEAST_EXPECT(pa.isArray())) @@ -221,10 +207,8 @@ class NoRippleCheck_test : public beast::unit_test::suite // now make a second request asking for the relevant transactions this // time. params[jss::transactions] = true; - result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; if (!BEAST_EXPECT(result[jss::transactions].isArray())) return; @@ -343,43 +327,33 @@ class NoRippleCheckLimits_test : public beast::unit_test::suite params[jss::account] = alice.human(); params[jss::role] = "user"; params[jss::ledger] = "current"; - auto result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + auto result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result["problems"].size() == 301); // one below minimum params[jss::limit] = 9; - result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result["problems"].size() == (admin ? 10 : 11)); // at minimum params[jss::limit] = 10; - result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result["problems"].size() == 11); // at max params[jss::limit] = 400; - result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result["problems"].size() == 401); // at max+1 params[jss::limit] = 401; - result = env.rpc( - "json", - "noripple_check", - boost::lexical_cast(params))[jss::result]; + result = + env.rpc("json", "noripple_check", to_string(params))[jss::result]; BEAST_EXPECT(result["problems"].size() == (admin ? 402 : 401)); } diff --git a/src/test/rpc/TransactionEntry_test.cpp b/src/test/rpc/TransactionEntry_test.cpp index e07fdf0320..d8f685f568 100644 --- a/src/test/rpc/TransactionEntry_test.cpp +++ b/src/test/rpc/TransactionEntry_test.cpp @@ -258,15 +258,13 @@ class TransactionEntry_test : public beast::unit_test::suite Account A2{"A2"}; env.fund(XRP(10000), A1); - auto fund_1_tx = - boost::lexical_cast(env.tx()->getTransactionID()); + auto fund_1_tx = to_string(env.tx()->getTransactionID()); BEAST_EXPECT( fund_1_tx == "F4E9DF90D829A9E8B423FF68C34413E240D8D8BB0EFD080DF08114ED398E2506"); env.fund(XRP(10000), A2); - auto fund_2_tx = - boost::lexical_cast(env.tx()->getTransactionID()); + auto fund_2_tx = to_string(env.tx()->getTransactionID()); BEAST_EXPECT( fund_2_tx == "6853CD8226A05068C951CB1F54889FF4E40C5B440DC1C5BA38F114C4E0B1E705"); @@ -308,15 +306,13 @@ class TransactionEntry_test : public beast::unit_test::suite // the trust tx is actually a payment since the trust method // refunds fees with a payment after TrustSet..so just ignore the type // in the check below - auto trust_tx = - boost::lexical_cast(env.tx()->getTransactionID()); + auto trust_tx = to_string(env.tx()->getTransactionID()); BEAST_EXPECT( trust_tx == "C992D97D88FF444A1AB0C06B27557EC54B7F7DA28254778E60238BEA88E0C101"); env(pay(A2, A1, A2["USD"](5))); - auto pay_tx = - boost::lexical_cast(env.tx()->getTransactionID()); + auto pay_tx = to_string(env.tx()->getTransactionID()); env.close(); BEAST_EXPECT( pay_tx == @@ -362,8 +358,7 @@ class TransactionEntry_test : public beast::unit_test::suite "2000-01-01T00:00:20Z"); env(offer(A2, XRP(100), A2["USD"](1))); - auto offer_tx = - boost::lexical_cast(env.tx()->getTransactionID()); + auto offer_tx = to_string(env.tx()->getTransactionID()); BEAST_EXPECT( offer_tx == "5FCC1A27A7664F82A0CC4BE5766FBBB7C560D52B93AA7B550CD33B27AEC7EFFB"); From e80642fc121562217a3ce4c5b196e22d8ad910bd Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Thu, 16 Oct 2025 13:54:36 +0100 Subject: [PATCH 11/11] fix: Fix regression in ConnectAttempt (#5900) A regression was introduced in #5669 which would cause rippled to potentially dereference a disengaged std::optional when connecting to a peer. This would cause UB in release build and crash in debug. Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com> --- src/xrpld/overlay/detail/ConnectAttempt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrpld/overlay/detail/ConnectAttempt.cpp b/src/xrpld/overlay/detail/ConnectAttempt.cpp index c1bc4bb069..15a3b91802 100644 --- a/src/xrpld/overlay/detail/ConnectAttempt.cpp +++ b/src/xrpld/overlay/detail/ConnectAttempt.cpp @@ -600,8 +600,8 @@ ConnectAttempt::processResponse() JLOG(journal_.info()) << "Cluster name: " << *member; } - auto const result = - overlay_.peerFinder().activate(slot_, publicKey, !member->empty()); + auto const result = overlay_.peerFinder().activate( + slot_, publicKey, member.has_value()); if (result != PeerFinder::Result::success) { std::stringstream ss;