From c463d0ff06d18c55d8f3982597667d29fd6f6166 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 10:04:22 -0400 Subject: [PATCH 01/10] ci: [DEPENDABOT] bump codecov/codecov-action from 5.5.2 to 5.5.3 (#6615) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-build-test-config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index 02a47e169d..1cc768f9fa 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -298,7 +298,7 @@ jobs: - name: Upload coverage report if: ${{ github.repository == 'XRPLF/rippled' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }} - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 with: disable_search: true disable_telem: true From e0dbe9037086248dc2a5b99511953a6677fcfc6b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 23 Mar 2026 08:39:58 -0700 Subject: [PATCH 02/10] refactor: Move ledger entry helper functions from View.h/View.cpp to dedicated helper files (#6453) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- include/xrpl/ledger/Credit.h | 43 - include/xrpl/ledger/View.h | 876 +---- .../xrpl/ledger/helpers/AccountRootHelpers.h | 112 + .../ledger/{ => helpers}/CredentialHelpers.h | 0 .../xrpl/ledger/helpers/DirectoryHelpers.h | 223 ++ include/xrpl/ledger/helpers/MPTokenHelpers.h | 160 + include/xrpl/ledger/helpers/OfferHelpers.h | 28 + .../xrpl/ledger/helpers/RippleStateHelpers.h | 255 ++ include/xrpl/ledger/helpers/TokenHelpers.h | 286 ++ include/xrpl/ledger/helpers/VaultHelpers.h | 81 + include/xrpl/tx/paths/detail/StrandFlow.h | 3 +- src/libxrpl/ledger/Credit.cpp | 60 - src/libxrpl/ledger/View.cpp | 3212 +---------------- .../ledger/helpers/AccountRootHelpers.cpp | 247 ++ .../{ => helpers}/CredentialHelpers.cpp | 4 +- .../ledger/helpers/DirectoryHelpers.cpp | 177 + src/libxrpl/ledger/helpers/MPTokenHelpers.cpp | 766 ++++ src/libxrpl/ledger/helpers/OfferHelpers.cpp | 58 + .../ledger/helpers/RippleStateHelpers.cpp | 759 ++++ src/libxrpl/ledger/helpers/TokenHelpers.cpp | 1392 +++++++ src/libxrpl/ledger/helpers/VaultHelpers.cpp | 112 + src/libxrpl/tx/Transactor.cpp | 2 +- .../PermissionedDomainInvariant.cpp | 2 +- src/libxrpl/tx/paths/Flow.cpp | 2 +- .../tx/transactors/account/AccountDelete.cpp | 2 +- .../credentials/CredentialAccept.cpp | 2 +- .../credentials/CredentialCreate.cpp | 2 +- .../credentials/CredentialDelete.cpp | 2 +- .../dex/PermissionedDEXHelpers.cpp | 2 +- .../tx/transactors/escrow/EscrowFinish.cpp | 2 +- .../lending/LoanBrokerCoverWithdraw.cpp | 2 +- .../tx/transactors/payment/DepositPreauth.cpp | 2 +- .../tx/transactors/payment/Payment.cpp | 2 +- .../payment_channel/PaymentChannelClaim.cpp | 2 +- .../PermissionedDomainSet.cpp | 2 +- .../tx/transactors/vault/VaultDeposit.cpp | 2 +- .../tx/transactors/vault/VaultWithdraw.cpp | 2 +- src/test/app/Credentials_test.cpp | 2 +- src/xrpld/app/paths/detail/DirectStep.cpp | 2 +- .../app/paths/detail/XRPEndpointStep.cpp | 2 +- src/xrpld/rpc/handlers/DepositAuthorized.cpp | 2 +- src/xrpld/rpc/handlers/LedgerEntry.cpp | 2 +- 42 files changed, 4692 insertions(+), 4204 deletions(-) delete mode 100644 include/xrpl/ledger/Credit.h create mode 100644 include/xrpl/ledger/helpers/AccountRootHelpers.h rename include/xrpl/ledger/{ => helpers}/CredentialHelpers.h (100%) create mode 100644 include/xrpl/ledger/helpers/DirectoryHelpers.h create mode 100644 include/xrpl/ledger/helpers/MPTokenHelpers.h create mode 100644 include/xrpl/ledger/helpers/OfferHelpers.h create mode 100644 include/xrpl/ledger/helpers/RippleStateHelpers.h create mode 100644 include/xrpl/ledger/helpers/TokenHelpers.h create mode 100644 include/xrpl/ledger/helpers/VaultHelpers.h delete mode 100644 src/libxrpl/ledger/Credit.cpp create mode 100644 src/libxrpl/ledger/helpers/AccountRootHelpers.cpp rename src/libxrpl/ledger/{ => helpers}/CredentialHelpers.cpp (99%) create mode 100644 src/libxrpl/ledger/helpers/DirectoryHelpers.cpp create mode 100644 src/libxrpl/ledger/helpers/MPTokenHelpers.cpp create mode 100644 src/libxrpl/ledger/helpers/OfferHelpers.cpp create mode 100644 src/libxrpl/ledger/helpers/RippleStateHelpers.cpp create mode 100644 src/libxrpl/ledger/helpers/TokenHelpers.cpp create mode 100644 src/libxrpl/ledger/helpers/VaultHelpers.cpp diff --git a/include/xrpl/ledger/Credit.h b/include/xrpl/ledger/Credit.h deleted file mode 100644 index 770b82a650..0000000000 --- a/include/xrpl/ledger/Credit.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace xrpl { - -/** Calculate the maximum amount of IOUs that an account can hold - @param ledger the ledger to check against. - @param account the account of interest. - @param issuer the issuer of the IOU. - @param currency the IOU to check. - @return The maximum amount that can be held. -*/ -/** @{ */ -STAmount -creditLimit( - ReadView const& view, - AccountID const& account, - AccountID const& issuer, - Currency const& currency); - -IOUAmount -creditLimit2(ReadView const& v, AccountID const& acc, AccountID const& iss, Currency const& cur); -/** @} */ - -/** Returns the amount of IOUs issued by issuer that are held by an account - @param ledger the ledger to check against. - @param account the account of interest. - @param issuer the issuer of the IOU. - @param currency the IOU to check. -*/ -/** @{ */ -STAmount -creditBalance( - ReadView const& view, - AccountID const& account, - AccountID const& issuer, - Currency const& currency); -/** @} */ - -} // namespace xrpl diff --git a/include/xrpl/ledger/View.h b/include/xrpl/ledger/View.h index cd23cf4978..2ea38c5b8b 100644 --- a/include/xrpl/ledger/View.h +++ b/include/xrpl/ledger/View.h @@ -4,6 +4,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -21,7 +28,6 @@ namespace xrpl { -enum class WaiveTransferFee : bool { No = false, Yes }; enum class SkipEntry : bool { No = false, Yes }; //------------------------------------------------------------------------------ @@ -54,24 +60,6 @@ enum class SkipEntry : bool { No = false, Yes }; [[nodiscard]] bool hasExpired(ReadView const& view, std::optional const& exp); -/** Controls the treatment of frozen account balances */ -enum FreezeHandling { fhIGNORE_FREEZE, fhZERO_IF_FROZEN }; - -/** Controls the treatment of unauthorized MPT balances */ -enum AuthHandling { ahIGNORE_AUTH, ahZERO_IF_UNAUTHORIZED }; - -/** Controls whether to include the account's full spendable balance */ -enum SpendableHandling { shSIMPLE_BALANCE, shFULL_BALANCE }; - -[[nodiscard]] bool -isGlobalFrozen(ReadView const& view, AccountID const& issuer); - -[[nodiscard]] bool -isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue); - -[[nodiscard]] bool -isGlobalFrozen(ReadView const& view, Asset const& asset); - // Note, depth parameter is used to limit the recursion depth [[nodiscard]] bool isVaultPseudoAccountFrozen( @@ -80,175 +68,6 @@ isVaultPseudoAccountFrozen( MPTIssue const& mptShare, int depth); -[[nodiscard]] bool -isIndividualFrozen( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer); - -[[nodiscard]] inline bool -isIndividualFrozen(ReadView const& view, AccountID const& account, Issue const& issue) -{ - return isIndividualFrozen(view, account, issue.currency, issue.account); -} - -[[nodiscard]] bool -isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue); - -[[nodiscard]] inline bool -isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset) -{ - return std::visit( - [&](auto const& issue) { return isIndividualFrozen(view, account, issue); }, asset.value()); -} - -[[nodiscard]] bool -isFrozen( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer); - -[[nodiscard]] inline bool -isFrozen(ReadView const& view, AccountID const& account, Issue const& issue, int = 0 /*ignored*/) -{ - return isFrozen(view, account, issue.currency, issue.account); -} - -[[nodiscard]] bool -isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth = 0); - -/** - * isFrozen check is recursive for MPT shares in a vault, descending to - * assets in the vault, up to maxAssetCheckDepth recursion depth. This is - * purely defensive, as we currently do not allow such vaults to be created. - */ -[[nodiscard]] inline bool -isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth = 0) -{ - return std::visit( - [&](auto const& issue) { return isFrozen(view, account, issue, depth); }, asset.value()); -} - -[[nodiscard]] inline TER -checkFrozen(ReadView const& view, AccountID const& account, Issue const& issue) -{ - return isFrozen(view, account, issue) ? (TER)tecFROZEN : (TER)tesSUCCESS; -} - -[[nodiscard]] inline TER -checkFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) -{ - return isFrozen(view, account, mptIssue) ? (TER)tecLOCKED : (TER)tesSUCCESS; -} - -[[nodiscard]] inline TER -checkFrozen(ReadView const& view, AccountID const& account, Asset const& asset) -{ - return std::visit( - [&](auto const& issue) { return checkFrozen(view, account, issue); }, asset.value()); -} - -[[nodiscard]] bool -isAnyFrozen( - ReadView const& view, - std::initializer_list const& accounts, - MPTIssue const& mptIssue, - int depth = 0); - -[[nodiscard]] inline bool -isAnyFrozen( - ReadView const& view, - std::initializer_list const& accounts, - Issue const& issue) -{ - for (auto const& account : accounts) - { - if (isFrozen(view, account, issue.currency, issue.account)) - return true; - } - return false; -} - -[[nodiscard]] inline bool -isAnyFrozen( - ReadView const& view, - std::initializer_list const& accounts, - Asset const& asset, - int depth = 0) -{ - return std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - return isAnyFrozen(view, accounts, issue); - else - return isAnyFrozen(view, accounts, issue, depth); - }, - asset.value()); -} - -[[nodiscard]] bool -isDeepFrozen( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer); - -[[nodiscard]] inline bool -isDeepFrozen( - ReadView const& view, - AccountID const& account, - Issue const& issue, - int = 0 /*ignored*/) -{ - return isDeepFrozen(view, account, issue.currency, issue.account); -} - -[[nodiscard]] inline bool -isDeepFrozen( - ReadView const& view, - AccountID const& account, - MPTIssue const& mptIssue, - int depth = 0) -{ - // Unlike IOUs, frozen / locked MPTs are not allowed to send or receive - // funds, so checking "deep frozen" is the same as checking "frozen". - return isFrozen(view, account, mptIssue, depth); -} - -/** - * isFrozen check is recursive for MPT shares in a vault, descending to - * assets in the vault, up to maxAssetCheckDepth recursion depth. This is - * purely defensive, as we currently do not allow such vaults to be created. - */ -[[nodiscard]] inline bool -isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth = 0) -{ - return std::visit( - [&](auto const& issue) { return isDeepFrozen(view, account, issue, depth); }, - asset.value()); -} - -[[nodiscard]] inline TER -checkDeepFrozen(ReadView const& view, AccountID const& account, Issue const& issue) -{ - return isDeepFrozen(view, account, issue) ? (TER)tecFROZEN : (TER)tesSUCCESS; -} - -[[nodiscard]] inline TER -checkDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) -{ - return isDeepFrozen(view, account, mptIssue) ? (TER)tecLOCKED : (TER)tesSUCCESS; -} - -[[nodiscard]] inline TER -checkDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset) -{ - return std::visit( - [&](auto const& issue) { return checkDeepFrozen(view, account, issue); }, asset.value()); -} - [[nodiscard]] bool isLPTokenFrozen( ReadView const& view, @@ -256,159 +75,6 @@ isLPTokenFrozen( Issue const& asset, Issue const& asset2); -// Returns the amount an account can spend. -// -// If shSIMPLE_BALANCE is specified, this is the amount the account can spend -// without going into debt. -// -// If shFULL_BALANCE is specified, this is the amount the account can spend -// total. Specifically: -// * The account can go into debt if using a trust line, and the other side has -// a non-zero limit. -// * If the account is the asset issuer the limit is defined by the asset / -// issuance. -// -// <-- saAmount: amount of currency held by account. May be negative. -[[nodiscard]] STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer, - FreezeHandling zeroIfFrozen, - beast::Journal j, - SpendableHandling includeFullBalance = shSIMPLE_BALANCE); - -[[nodiscard]] STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - Issue const& issue, - FreezeHandling zeroIfFrozen, - beast::Journal j, - SpendableHandling includeFullBalance = shSIMPLE_BALANCE); - -[[nodiscard]] STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - MPTIssue const& mptIssue, - FreezeHandling zeroIfFrozen, - AuthHandling zeroIfUnauthorized, - beast::Journal j, - SpendableHandling includeFullBalance = shSIMPLE_BALANCE); - -[[nodiscard]] STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - Asset const& asset, - FreezeHandling zeroIfFrozen, - AuthHandling zeroIfUnauthorized, - beast::Journal j, - SpendableHandling includeFullBalance = shSIMPLE_BALANCE); - -// Returns the amount an account can spend of the currency type saDefault, or -// returns saDefault if this account is the issuer of the currency in -// question. Should be used in favor of accountHolds when questioning how much -// an account can spend while also allowing currency issuers to spend -// unlimited amounts of their own currency (since they can always issue more). -[[nodiscard]] STAmount -accountFunds( - ReadView const& view, - AccountID const& id, - STAmount const& saDefault, - FreezeHandling freezeHandling, - beast::Journal j); - -// Return the account's liquid (not reserved) XRP. Generally prefer -// calling accountHolds() over this interface. However, this interface -// allows the caller to temporarily adjust the owner count should that be -// necessary. -// -// @param ownerCountAdj positive to add to count, negative to reduce count. -[[nodiscard]] XRPAmount -xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j); - -/** Iterate all items in the given directory. */ -void -forEachItem( - ReadView const& view, - Keylet const& root, - std::function const&)> const& f); - -/** Iterate all items after an item in the given directory. - @param after The key of the item to start after - @param hint The directory page containing `after` - @param limit The maximum number of items to return - @return `false` if the iteration failed -*/ -bool -forEachItemAfter( - ReadView const& view, - Keylet const& root, - uint256 const& after, - std::uint64_t const hint, - unsigned int limit, - std::function const&)> const& f); - -/** Iterate all items in an account's owner directory. */ -inline void -forEachItem( - ReadView const& view, - AccountID const& id, - std::function const&)> const& f) -{ - return forEachItem(view, keylet::ownerDir(id), f); -} - -/** Iterate all items after an item in an owner directory. - @param after The key of the item to start after - @param hint The directory page containing `after` - @param limit The maximum number of items to return - @return `false` if the iteration failed -*/ -inline bool -forEachItemAfter( - ReadView const& view, - AccountID const& id, - uint256 const& after, - std::uint64_t const hint, - unsigned int limit, - std::function const&)> const& f) -{ - return forEachItemAfter(view, keylet::ownerDir(id), after, hint, limit, f); -} - -/** Returns IOU issuer transfer fee as Rate. Rate specifies - * the fee as fractions of 1 billion. For example, 1% transfer rate - * is represented as 1,010,000,000. - * @param issuer The IOU issuer - */ -[[nodiscard]] Rate -transferRate(ReadView const& view, AccountID const& issuer); - -/** Returns MPT transfer fee as Rate. Rate specifies - * the fee as fractions of 1 billion. For example, 1% transfer rate - * is represented as 1,010,000,000. - * @param issuanceID MPTokenIssuanceID of MPTTokenIssuance object - */ -[[nodiscard]] Rate -transferRate(ReadView const& view, MPTID const& issuanceID); - -/** Returns the transfer fee as Rate based on the type of token - * @param view The ledger view - * @param amount The amount to transfer - */ -[[nodiscard]] Rate -transferRate(ReadView const& view, STAmount const& amount); - -/** Returns `true` if the directory is empty - @param key The key of the directory -*/ -[[nodiscard]] bool -dirIsEmpty(ReadView const& view, Keylet const& k); - // Return the list of enabled amendments [[nodiscard]] std::set getEnabledAmendments(ReadView const& view); @@ -474,81 +140,6 @@ areCompatible( // //------------------------------------------------------------------------------ -/** Adjust the owner count up or down. */ -void -adjustOwnerCount( - ApplyView& view, - std::shared_ptr const& sle, - std::int32_t amount, - beast::Journal j); - -/** @{ */ -/** Returns the first entry in the directory, advancing the index - - @deprecated These are legacy function that are considered deprecated - and will soon be replaced with an iterator-based model - that is easier to use. You should not use them in new code. - - @param view The view against which to operate - @param root The root (i.e. first page) of the directory to iterate - @param page The current page - @param index The index inside the current page - @param entry The entry at the current index - - @return true if the directory isn't empty; false otherwise - */ -bool -cdirFirst( - ReadView const& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry); - -bool -dirFirst( - ApplyView& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry); -/** @} */ - -/** @{ */ -/** Returns the next entry in the directory, advancing the index - - @deprecated These are legacy function that are considered deprecated - and will soon be replaced with an iterator-based model - that is easier to use. You should not use them in new code. - - @param view The view against which to operate - @param root The root (i.e. first page) of the directory to iterate - @param page The current page - @param index The index inside the current page - @param entry The entry at the current index - - @return true if the directory isn't empty; false otherwise - */ -bool -cdirNext( - ReadView const& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry); - -bool -dirNext( - ApplyView& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry); -/** @} */ - -[[nodiscard]] std::function -describeOwnerDir(AccountID const& account); - [[nodiscard]] TER dirLink( ApplyView& view, @@ -556,63 +147,6 @@ dirLink( std::shared_ptr& object, SF_UINT64 const& node = sfOwnerNode); -AccountID -pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey); - -/** - * - * Create pseudo-account, storing pseudoOwnerKey into ownerField. - * - * The list of valid ownerField is maintained in View.cpp and the caller to - * this function must perform necessary amendment check(s) before using a - * field. The amendment check is **not** performed in createPseudoAccount. - */ -[[nodiscard]] Expected, TER> -createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField); - -// Returns true if and only if sleAcct is a pseudo-account or specific -// pseudo-accounts in pseudoFieldFilter. -// -// Returns false if sleAcct is -// * NOT a pseudo-account OR -// * NOT a ltACCOUNT_ROOT OR -// * null pointer -[[nodiscard]] bool -isPseudoAccount( - std::shared_ptr sleAcct, - std::set const& pseudoFieldFilter = {}); - -// Returns the list of fields that define an ACCOUNT_ROOT as a pseudo-account if -// set -// Pseudo-account designator fields MUST be maintained by including the -// SField::sMD_PseudoAccount flag in the SField definition. (Don't forget to -// "| SField::sMD_Default"!) The fields do NOT need to be amendment-gated, -// since a non-active amendment will not set any field, by definition. -// Specific properties of a pseudo-account are NOT checked here, that's what -// InvariantCheck is for. -[[nodiscard]] std::vector const& -getPseudoAccountFields(); - -[[nodiscard]] inline bool -isPseudoAccount( - ReadView const& view, - AccountID const& accountId, - std::set const& pseudoFieldFilter = {}) -{ - return isPseudoAccount(view.read(keylet::account(accountId)), pseudoFieldFilter); -} - -[[nodiscard]] TER -canAddHolding(ReadView const& view, Asset const& asset); - -/** Validates that the destination SLE and tag are valid - - - Checks that the SLE is not null. - - If the SLE requires a destination tag, checks that there is a tag. -*/ -[[nodiscard]] TER -checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag); - /** Checks that can withdraw funds from an object to itself or a destination. * * The receiver may be either the submitting account (sfAccount) or a different @@ -686,351 +220,6 @@ doWithdraw( STAmount const& amount, beast::Journal j); -/// Any transactors that call addEmptyHolding() in doApply must call -/// canAddHolding() in preflight with the same View and Asset -[[nodiscard]] TER -addEmptyHolding( - ApplyView& view, - AccountID const& accountID, - XRPAmount priorBalance, - Issue const& issue, - beast::Journal journal); - -[[nodiscard]] TER -addEmptyHolding( - ApplyView& view, - AccountID const& accountID, - XRPAmount priorBalance, - MPTIssue const& mptIssue, - beast::Journal journal); - -[[nodiscard]] inline TER -addEmptyHolding( - ApplyView& view, - AccountID const& accountID, - XRPAmount priorBalance, - Asset const& asset, - beast::Journal journal) -{ - return std::visit( - [&](TIss const& issue) -> TER { - return addEmptyHolding(view, accountID, priorBalance, issue, journal); - }, - asset.value()); -} - -[[nodiscard]] TER -authorizeMPToken( - ApplyView& view, - XRPAmount const& priorBalance, - MPTID const& mptIssuanceID, - AccountID const& account, - beast::Journal journal, - std::uint32_t flags = 0, - std::optional holderID = std::nullopt); - -// VFALCO NOTE Both STAmount parameters should just -// be "Amount", a unit-less number. -// -/** Create a trust line - - This can set an initial balance. -*/ -[[nodiscard]] TER -trustCreate( - ApplyView& view, - bool const bSrcHigh, - AccountID const& uSrcAccountID, - AccountID const& uDstAccountID, - uint256 const& uIndex, // --> ripple state entry - SLE::ref sleAccount, // --> the account being set. - bool const bAuth, // --> authorize account. - bool const bNoRipple, // --> others cannot ripple through - bool const bFreeze, // --> funds cannot leave - bool bDeepFreeze, // --> can neither receive nor send funds - STAmount const& saBalance, // --> balance of account being set. - // Issuer should be noAccount() - STAmount const& saLimit, // --> limit for account being set. - // Issuer should be the account being set. - std::uint32_t uSrcQualityIn, - std::uint32_t uSrcQualityOut, - beast::Journal j); - -[[nodiscard]] TER -removeEmptyHolding( - ApplyView& view, - AccountID const& accountID, - Issue const& issue, - beast::Journal journal); - -[[nodiscard]] TER -removeEmptyHolding( - ApplyView& view, - AccountID const& accountID, - MPTIssue const& mptIssue, - beast::Journal journal); - -[[nodiscard]] inline TER -removeEmptyHolding( - ApplyView& view, - AccountID const& accountID, - Asset const& asset, - beast::Journal journal) -{ - return std::visit( - [&](TIss const& issue) -> TER { - return removeEmptyHolding(view, accountID, issue, journal); - }, - asset.value()); -} - -[[nodiscard]] TER -trustDelete( - ApplyView& view, - std::shared_ptr const& sleRippleState, - AccountID const& uLowAccountID, - AccountID const& uHighAccountID, - beast::Journal j); - -/** Delete an offer. - - Requirements: - The passed `sle` be obtained from a prior - call to view.peek() -*/ -// [[nodiscard]] // nodiscard commented out so Flow, BookTip and others compile. -TER -offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j); - -//------------------------------------------------------------------------------ - -// -// Money Transfers -// - -// Direct send w/o fees: -// - Redeeming IOUs and/or sending sender's own IOUs. -// - Create trust line of needed. -// --> bCheckIssuer : normally require issuer to be involved. -// [[nodiscard]] // nodiscard commented out so DirectStep.cpp compiles. - -/** Calls static rippleCreditIOU if saAmount represents Issue. - * Calls static rippleCreditMPT if saAmount represents MPTIssue. - */ -TER -rippleCredit( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - bool bCheckIssuer, - beast::Journal j); - -TER -rippleLockEscrowMPT( - ApplyView& view, - AccountID const& uGrantorID, - STAmount const& saAmount, - beast::Journal j); - -TER -rippleUnlockEscrowMPT( - ApplyView& view, - AccountID const& uGrantorID, - AccountID const& uGranteeID, - STAmount const& netAmount, - STAmount const& grossAmount, - beast::Journal j); - -/** Calls static accountSendIOU if saAmount represents Issue. - * Calls static accountSendMPT if saAmount represents MPTIssue. - */ -[[nodiscard]] TER -accountSend( - ApplyView& view, - AccountID const& from, - AccountID const& to, - STAmount const& saAmount, - beast::Journal j, - WaiveTransferFee waiveFee = WaiveTransferFee::No); - -using MultiplePaymentDestinations = std::vector>; -/** Like accountSend, except one account is sending multiple payments (with the - * same asset!) simultaneously - * - * Calls static accountSendMultiIOU if saAmount represents Issue. - * Calls static accountSendMultiMPT if saAmount represents MPTIssue. - */ -[[nodiscard]] TER -accountSendMulti( - ApplyView& view, - AccountID const& senderID, - Asset const& asset, - MultiplePaymentDestinations const& receivers, - beast::Journal j, - WaiveTransferFee waiveFee = WaiveTransferFee::No); - -[[nodiscard]] TER -issueIOU( - ApplyView& view, - AccountID const& account, - STAmount const& amount, - Issue const& issue, - beast::Journal j); - -[[nodiscard]] TER -redeemIOU( - ApplyView& view, - AccountID const& account, - STAmount const& amount, - Issue const& issue, - beast::Journal j); - -[[nodiscard]] TER -transferXRP( - ApplyView& view, - AccountID const& from, - AccountID const& to, - STAmount const& amount, - beast::Journal j); - -/* Check if MPToken (for MPT) or trust line (for IOU) exists: - * - StrongAuth - before checking if authorization is required - * - WeakAuth - * for MPT - after checking lsfMPTRequireAuth flag - * for IOU - do not check if trust line exists - * - Legacy - * for MPT - before checking lsfMPTRequireAuth flag i.e. same as StrongAuth - * for IOU - do not check if trust line exists i.e. same as WeakAuth - */ -enum class AuthType { StrongAuth, WeakAuth, Legacy }; - -/** Check if the account lacks required authorization. - * - * Return tecNO_AUTH or tecNO_LINE if it does - * and tesSUCCESS otherwise. - * - * If StrongAuth then return tecNO_LINE if the RippleState doesn't exist. Return - * tecNO_AUTH if lsfRequireAuth is set on the issuer's AccountRoot, and the - * RippleState does exist, and the RippleState is not authorized. - * - * If WeakAuth then return tecNO_AUTH if lsfRequireAuth is set, and the - * RippleState exists, and is not authorized. Return tecNO_LINE if - * lsfRequireAuth is set and the RippleState doesn't exist. Consequently, if - * WeakAuth and lsfRequireAuth is *not* set, this function will return - * tesSUCCESS even if RippleState does *not* exist. - * - * The default "Legacy" auth type is equivalent to WeakAuth. - */ -[[nodiscard]] TER -requireAuth( - ReadView const& view, - Issue const& issue, - AccountID const& account, - AuthType authType = AuthType::Legacy); - -/** Check if the account lacks required authorization. - * - * This will also check for expired credentials. If it is called directly - * from preclaim, the user should convert result tecEXPIRED to tesSUCCESS and - * proceed to also check permissions with enforceMPTokenAuthorization inside - * doApply. This will ensure that any expired credentials are deleted. - * - * requireAuth check is recursive for MPT shares in a vault, descending to - * assets in the vault, up to maxAssetCheckDepth recursion depth. This is - * purely defensive, as we currently do not allow such vaults to be created. - * - * If StrongAuth then return tecNO_AUTH if MPToken doesn't exist or - * lsfMPTRequireAuth is set and MPToken is not authorized. Vault and LoanBroker - * pseudo-accounts are implicitly authorized. - * - * If WeakAuth then return tecNO_AUTH if lsfMPTRequireAuth is set and MPToken - * doesn't exist or is not authorized (explicitly or via credentials, if - * DomainID is set in MPTokenIssuance). Consequently, if WeakAuth and - * lsfMPTRequireAuth is *not* set, this function will return true even if - * MPToken does *not* exist. - * - * The default "Legacy" auth type is equivalent to StrongAuth. - */ -[[nodiscard]] TER -requireAuth( - ReadView const& view, - MPTIssue const& mptIssue, - AccountID const& account, - AuthType authType = AuthType::Legacy, - int depth = 0); - -[[nodiscard]] TER inline requireAuth( - ReadView const& view, - Asset const& asset, - AccountID const& account, - AuthType authType = AuthType::Legacy) -{ - return std::visit( - [&](TIss const& issue_) { - return requireAuth(view, issue_, account, authType); - }, - asset.value()); -} - -/** Enforce account has MPToken to match its authorization. - * - * Called from doApply - it will check for expired (and delete if found any) - * credentials matching DomainID set in MPTokenIssuance. Must be called if - * requireAuth(...MPTIssue...) returned tesSUCCESS or tecEXPIRED in preclaim, - * which implies that preclaim should replace `tecEXPIRED` with `tesSUCCESS` - * in order for the transactor to proceed to doApply. - * - * This function will create MPToken (if needed) on the basis of any - * non-expired credentials and will delete any expired credentials, indirectly - * via verifyValidDomain, as per DomainID (if set in MPTokenIssuance). - * - * The caller does NOT need to ensure that DomainID is actually set - this - * function handles gracefully both cases when DomainID is set and when not. - * - * The caller does NOT need to look for existing MPToken to match - * mptIssue/account - this function checks lsfMPTAuthorized of an existing - * MPToken iff DomainID is not set. - * - * Do not use for accounts which hold implied permission e.g. object owners or - * if MPTokenIssuance does not require authorization. In both cases use - * MPTokenAuthorize::authorize if MPToken does not yet exist. - */ -[[nodiscard]] TER -enforceMPTokenAuthorization( - ApplyView& view, - MPTID const& mptIssuanceID, - AccountID const& account, - XRPAmount const& priorBalance, - beast::Journal j); - -/** Check if the destination account is allowed - * to receive MPT. Return tecNO_AUTH if it doesn't - * and tesSUCCESS otherwise. - */ -[[nodiscard]] TER -canTransfer( - ReadView const& view, - MPTIssue const& mptIssue, - AccountID const& from, - AccountID const& to); - -[[nodiscard]] TER -canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, AccountID const& to); - -[[nodiscard]] TER inline canTransfer( - ReadView const& view, - Asset const& asset, - AccountID const& from, - AccountID const& to) -{ - return std::visit( - [&](TIss const& issue) -> TER { - return canTransfer(view, issue, from, to); - }, - asset.value()); -} - /** Deleter function prototype. Returns the status of the entry deletion * (if should not be skipped) and if the entry should be skipped. The status * is always tesSUCCESS if the entry should be skipped. @@ -1052,57 +241,6 @@ cleanupOnAccountDelete( beast::Journal j, std::optional maxNodesToDelete = std::nullopt); -/** Delete trustline to AMM. The passed `sle` must be obtained from a prior - * call to view.peek(). Fail if neither side of the trustline is AMM or - * if ammAccountID is seated and is not one of the trustline's side. - */ -[[nodiscard]] TER -deleteAMMTrustLine( - ApplyView& view, - std::shared_ptr sleState, - std::optional const& ammAccountID, - beast::Journal j); - -// From the perspective of a vault, return the number of shares to give the -// depositor when they deposit a fixed amount of assets. Since shares are MPT -// this number is integral and always truncated in this calculation. -[[nodiscard]] std::optional -assetsToSharesDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets); - -// From the perspective of a vault, return the number of assets to take from -// depositor when they receive a fixed amount of shares. Note, since shares are -// MPT, they are always an integral number. -[[nodiscard]] std::optional -sharesToAssetsDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares); - -enum class TruncateShares : bool { no = false, yes = true }; - -// From the perspective of a vault, return the number of shares to demand from -// the depositor when they ask to withdraw a fixed amount of assets. Since -// shares are MPT this number is integral, and it will be rounded to nearest -// unless explicitly requested to be truncated instead. -[[nodiscard]] std::optional -assetsToSharesWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets, - TruncateShares truncate = TruncateShares::no); - -// From the perspective of a vault, return the number of assets to give the -// depositor when they redeem a fixed amount of shares. Note, since shares are -// MPT, they are always an integral number. -[[nodiscard]] std::optional -sharesToAssetsWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares); - /** Has the specified time passed? @param now the current time diff --git a/include/xrpl/ledger/helpers/AccountRootHelpers.h b/include/xrpl/ledger/helpers/AccountRootHelpers.h new file mode 100644 index 0000000000..353c27fe41 --- /dev/null +++ b/include/xrpl/ledger/helpers/AccountRootHelpers.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl { + +/** Check if the issuer has the global freeze flag set. + @param issuer The account to check + @return true if the account has global freeze set +*/ +[[nodiscard]] bool +isGlobalFrozen(ReadView const& view, AccountID const& issuer); + +// Calculate liquid XRP balance for an account. +// This function may be used to calculate the amount of XRP that +// the holder is able to freely spend. It subtracts reserve requirements. +// +// ownerCountAdj adjusts the owner count in case the caller calculates +// before ledger entries are added or removed. Positive to add, negative +// to subtract. +// +// @param ownerCountAdj positive to add to count, negative to reduce count. +[[nodiscard]] XRPAmount +xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j); + +/** Adjust the owner count up or down. */ +void +adjustOwnerCount( + ApplyView& view, + std::shared_ptr const& sle, + std::int32_t amount, + beast::Journal j); + +/** Returns IOU issuer transfer fee as Rate. Rate specifies + * the fee as fractions of 1 billion. For example, 1% transfer rate + * is represented as 1,010,000,000. + * @param issuer The IOU issuer + */ +[[nodiscard]] Rate +transferRate(ReadView const& view, AccountID const& issuer); + +/** Generate a pseudo-account address from a pseudo owner key. + @param pseudoOwnerKey The key to generate the address from + @return The generated account ID +*/ +AccountID +pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey); + +/** Returns the list of fields that define an ACCOUNT_ROOT as a pseudo-account + if set. + + The list is constructed during initialization and is const after that. + Pseudo-account designator fields MUST be maintained by including the + SField::sMD_PseudoAccount flag in the SField definition. +*/ +[[nodiscard]] std::vector const& +getPseudoAccountFields(); + +/** Returns true if and only if sleAcct is a pseudo-account or specific + pseudo-accounts in pseudoFieldFilter. + + Returns false if sleAcct is: + - NOT a pseudo-account OR + - NOT a ltACCOUNT_ROOT OR + - null pointer +*/ +[[nodiscard]] bool +isPseudoAccount( + std::shared_ptr sleAcct, + std::set const& pseudoFieldFilter = {}); + +/** Convenience overload that reads the account from the view. */ +[[nodiscard]] inline bool +isPseudoAccount( + ReadView const& view, + AccountID const& accountId, + std::set const& pseudoFieldFilter = {}) +{ + return isPseudoAccount(view.read(keylet::account(accountId)), pseudoFieldFilter); +} + +/** + * Create pseudo-account, storing pseudoOwnerKey into ownerField. + * + * The list of valid ownerField is maintained in AccountRootHelpers.cpp and + * the caller to this function must perform necessary amendment check(s) + * before using a field. The amendment check is **not** performed in + * createPseudoAccount. + */ +[[nodiscard]] Expected, TER> +createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField); + +/** Checks the destination and tag. + + - Checks that the SLE is not null. + - If the SLE requires a destination tag, checks that there is a tag. +*/ +[[nodiscard]] TER +checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag); + +} // namespace xrpl diff --git a/include/xrpl/ledger/CredentialHelpers.h b/include/xrpl/ledger/helpers/CredentialHelpers.h similarity index 100% rename from include/xrpl/ledger/CredentialHelpers.h rename to include/xrpl/ledger/helpers/CredentialHelpers.h diff --git a/include/xrpl/ledger/helpers/DirectoryHelpers.h b/include/xrpl/ledger/helpers/DirectoryHelpers.h new file mode 100644 index 0000000000..189dfcd263 --- /dev/null +++ b/include/xrpl/ledger/helpers/DirectoryHelpers.h @@ -0,0 +1,223 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl { + +namespace detail { + +template < + class V, + class N, + class = std::enable_if_t< + std::is_same_v, SLE> && std::is_base_of_v>> +bool +internalDirNext( + V& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry) +{ + auto const& svIndexes = page->getFieldV256(sfIndexes); + XRPL_ASSERT(index <= svIndexes.size(), "xrpl::detail::internalDirNext : index inside range"); + + if (index >= svIndexes.size()) + { + auto const next = page->getFieldU64(sfIndexNext); + + if (!next) + { + entry.zero(); + return false; + } + + if constexpr (std::is_const_v) + { + page = view.read(keylet::page(root, next)); + } + else + { + page = view.peek(keylet::page(root, next)); + } + + XRPL_ASSERT(page, "xrpl::detail::internalDirNext : non-null root"); + + if (!page) + return false; + + index = 0; + + return internalDirNext(view, root, page, index, entry); + } + + entry = svIndexes[index++]; + return true; +} + +template < + class V, + class N, + class = std::enable_if_t< + std::is_same_v, SLE> && std::is_base_of_v>> +bool +internalDirFirst( + V& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry) +{ + if constexpr (std::is_const_v) + { + page = view.read(keylet::page(root)); + } + else + { + page = view.peek(keylet::page(root)); + } + + if (!page) + return false; + + index = 0; + + return internalDirNext(view, root, page, index, entry); +} + +} // namespace detail + +/** @{ */ +/** Returns the first entry in the directory, advancing the index + + @deprecated These are legacy function that are considered deprecated + and will soon be replaced with an iterator-based model + that is easier to use. You should not use them in new code. + + @param view The view against which to operate + @param root The root (i.e. first page) of the directory to iterate + @param page The current page + @param index The index inside the current page + @param entry The entry at the current index + + @return true if the directory isn't empty; false otherwise + */ +bool +cdirFirst( + ReadView const& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry); + +bool +dirFirst( + ApplyView& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry); +/** @} */ + +/** @{ */ +/** Returns the next entry in the directory, advancing the index + + @deprecated These are legacy function that are considered deprecated + and will soon be replaced with an iterator-based model + that is easier to use. You should not use them in new code. + + @param view The view against which to operate + @param root The root (i.e. first page) of the directory to iterate + @param page The current page + @param index The index inside the current page + @param entry The entry at the current index + + @return true if the directory isn't empty; false otherwise + */ +bool +cdirNext( + ReadView const& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry); + +bool +dirNext( + ApplyView& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry); +/** @} */ + +/** Iterate all items in the given directory. */ +void +forEachItem( + ReadView const& view, + Keylet const& root, + std::function const&)> const& f); + +/** Iterate all items after an item in the given directory. + @param after The key of the item to start after + @param hint The directory page containing `after` + @param limit The maximum number of items to return + @return `false` if the iteration failed +*/ +bool +forEachItemAfter( + ReadView const& view, + Keylet const& root, + uint256 const& after, + std::uint64_t const hint, + unsigned int limit, + std::function const&)> const& f); + +/** Iterate all items in an account's owner directory. */ +inline void +forEachItem( + ReadView const& view, + AccountID const& id, + std::function const&)> const& f) +{ + return forEachItem(view, keylet::ownerDir(id), f); +} + +/** Iterate all items after an item in an owner directory. + @param after The key of the item to start after + @param hint The directory page containing `after` + @param limit The maximum number of items to return + @return `false` if the iteration failed +*/ +inline bool +forEachItemAfter( + ReadView const& view, + AccountID const& id, + uint256 const& after, + std::uint64_t const hint, + unsigned int limit, + std::function const&)> const& f) +{ + return forEachItemAfter(view, keylet::ownerDir(id), after, hint, limit, f); +} + +/** Returns `true` if the directory is empty + @param key The key of the directory +*/ +[[nodiscard]] bool +dirIsEmpty(ReadView const& view, Keylet const& k); + +/** Returns a function that sets the owner on a directory SLE */ +[[nodiscard]] std::function +describeOwnerDir(AccountID const& account); + +} // namespace xrpl diff --git a/include/xrpl/ledger/helpers/MPTokenHelpers.h b/include/xrpl/ledger/helpers/MPTokenHelpers.h new file mode 100644 index 0000000000..ab487280b9 --- /dev/null +++ b/include/xrpl/ledger/helpers/MPTokenHelpers.h @@ -0,0 +1,160 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl { + +//------------------------------------------------------------------------------ +// +// Freeze checking (MPT-specific) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] bool +isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue); + +[[nodiscard]] bool +isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue); + +[[nodiscard]] bool +isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth = 0); + +[[nodiscard]] bool +isAnyFrozen( + ReadView const& view, + std::initializer_list const& accounts, + MPTIssue const& mptIssue, + int depth = 0); + +//------------------------------------------------------------------------------ +// +// Transfer rate (MPT-specific) +// +//------------------------------------------------------------------------------ + +/** Returns MPT transfer fee as Rate. Rate specifies + * the fee as fractions of 1 billion. For example, 1% transfer rate + * is represented as 1,010,000,000. + * @param issuanceID MPTokenIssuanceID of MPTTokenIssuance object + */ +[[nodiscard]] Rate +transferRate(ReadView const& view, MPTID const& issuanceID); + +//------------------------------------------------------------------------------ +// +// Holding checks (MPT-specific) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +canAddHolding(ReadView const& view, MPTIssue const& mptIssue); + +//------------------------------------------------------------------------------ +// +// Authorization (MPT-specific) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +authorizeMPToken( + ApplyView& view, + XRPAmount const& priorBalance, + MPTID const& mptIssuanceID, + AccountID const& account, + beast::Journal journal, + std::uint32_t flags = 0, + std::optional holderID = std::nullopt); + +/** Check if the account lacks required authorization for MPT. + * + * requireAuth check is recursive for MPT shares in a vault, descending to + * assets in the vault, up to maxAssetCheckDepth recursion depth. This is + * purely defensive, as we currently do not allow such vaults to be created. + */ +[[nodiscard]] TER +requireAuth( + ReadView const& view, + MPTIssue const& mptIssue, + AccountID const& account, + AuthType authType = AuthType::Legacy, + int depth = 0); + +/** Enforce account has MPToken to match its authorization. + * + * Called from doApply - it will check for expired (and delete if found any) + * credentials matching DomainID set in MPTokenIssuance. Must be called if + * requireAuth(...MPTIssue...) returned tesSUCCESS or tecEXPIRED in preclaim. + */ +[[nodiscard]] TER +enforceMPTokenAuthorization( + ApplyView& view, + MPTID const& mptIssuanceID, + AccountID const& account, + XRPAmount const& priorBalance, + beast::Journal j); + +/** Check if the destination account is allowed + * to receive MPT. Return tecNO_AUTH if it doesn't + * and tesSUCCESS otherwise. + */ +[[nodiscard]] TER +canTransfer( + ReadView const& view, + MPTIssue const& mptIssue, + AccountID const& from, + AccountID const& to); + +//------------------------------------------------------------------------------ +// +// Empty holding operations (MPT-specific) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +addEmptyHolding( + ApplyView& view, + AccountID const& accountID, + XRPAmount priorBalance, + MPTIssue const& mptIssue, + beast::Journal journal); + +[[nodiscard]] TER +removeEmptyHolding( + ApplyView& view, + AccountID const& accountID, + MPTIssue const& mptIssue, + beast::Journal journal); + +//------------------------------------------------------------------------------ +// +// Escrow operations (MPT-specific) +// +//------------------------------------------------------------------------------ + +TER +rippleLockEscrowMPT( + ApplyView& view, + AccountID const& uGrantorID, + STAmount const& saAmount, + beast::Journal j); + +TER +rippleUnlockEscrowMPT( + ApplyView& view, + AccountID const& uGrantorID, + AccountID const& uGranteeID, + STAmount const& netAmount, + STAmount const& grossAmount, + beast::Journal j); + +} // namespace xrpl diff --git a/include/xrpl/ledger/helpers/OfferHelpers.h b/include/xrpl/ledger/helpers/OfferHelpers.h new file mode 100644 index 0000000000..9096071811 --- /dev/null +++ b/include/xrpl/ledger/helpers/OfferHelpers.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace xrpl { + +/** Delete an offer. + + Requirements: + The offer must exist. + The caller must have already checked permissions. + + @param view The ApplyView to modify. + @param sle The offer to delete. + @param j Journal for logging. + + @return tesSUCCESS on success, otherwise an error code. +*/ +// [[nodiscard]] // nodiscard commented out so Flow, BookTip and others compile. +TER +offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j); + +} // namespace xrpl diff --git a/include/xrpl/ledger/helpers/RippleStateHelpers.h b/include/xrpl/ledger/helpers/RippleStateHelpers.h new file mode 100644 index 0000000000..3feba59d1f --- /dev/null +++ b/include/xrpl/ledger/helpers/RippleStateHelpers.h @@ -0,0 +1,255 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// +// RippleState (Trustline) helpers +// +//------------------------------------------------------------------------------ + +namespace xrpl { + +//------------------------------------------------------------------------------ +// +// Credit functions (from Credit.h) +// +//------------------------------------------------------------------------------ + +/** Calculate the maximum amount of IOUs that an account can hold + @param view the ledger to check against. + @param account the account of interest. + @param issuer the issuer of the IOU. + @param currency the IOU to check. + @return The maximum amount that can be held. +*/ +/** @{ */ +STAmount +creditLimit( + ReadView const& view, + AccountID const& account, + AccountID const& issuer, + Currency const& currency); + +IOUAmount +creditLimit2(ReadView const& v, AccountID const& acc, AccountID const& iss, Currency const& cur); +/** @} */ + +/** Returns the amount of IOUs issued by issuer that are held by an account + @param view the ledger to check against. + @param account the account of interest. + @param issuer the issuer of the IOU. + @param currency the IOU to check. +*/ +/** @{ */ +STAmount +creditBalance( + ReadView const& view, + AccountID const& account, + AccountID const& issuer, + Currency const& currency); +/** @} */ + +//------------------------------------------------------------------------------ +// +// Freeze checking (IOU-specific) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] bool +isIndividualFrozen( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer); + +[[nodiscard]] inline bool +isIndividualFrozen(ReadView const& view, AccountID const& account, Issue const& issue) +{ + return isIndividualFrozen(view, account, issue.currency, issue.account); +} + +[[nodiscard]] bool +isFrozen( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer); + +[[nodiscard]] inline bool +isFrozen(ReadView const& view, AccountID const& account, Issue const& issue) +{ + return isFrozen(view, account, issue.currency, issue.account); +} + +// Overload with depth parameter for uniformity with MPTIssue version. +// The depth parameter is ignored for IOUs since they don't have vault recursion. +[[nodiscard]] inline bool +isFrozen(ReadView const& view, AccountID const& account, Issue const& issue, int /*depth*/) +{ + return isFrozen(view, account, issue); +} + +[[nodiscard]] bool +isDeepFrozen( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer); + +[[nodiscard]] inline bool +isDeepFrozen( + ReadView const& view, + AccountID const& account, + Issue const& issue, + int = 0 /*ignored*/) +{ + return isDeepFrozen(view, account, issue.currency, issue.account); +} + +[[nodiscard]] inline TER +checkDeepFrozen(ReadView const& view, AccountID const& account, Issue const& issue) +{ + return isDeepFrozen(view, account, issue) ? (TER)tecFROZEN : (TER)tesSUCCESS; +} + +//------------------------------------------------------------------------------ +// +// Trust line operations +// +//------------------------------------------------------------------------------ + +/** Create a trust line + + This can set an initial balance. +*/ +[[nodiscard]] TER +trustCreate( + ApplyView& view, + bool const bSrcHigh, + AccountID const& uSrcAccountID, + AccountID const& uDstAccountID, + uint256 const& uIndex, // --> ripple state entry + SLE::ref sleAccount, // --> the account being set. + bool const bAuth, // --> authorize account. + bool const bNoRipple, // --> others cannot ripple through + bool const bFreeze, // --> funds cannot leave + bool bDeepFreeze, // --> can neither receive nor send funds + STAmount const& saBalance, // --> balance of account being set. + // Issuer should be noAccount() + STAmount const& saLimit, // --> limit for account being set. + // Issuer should be the account being set. + std::uint32_t uQualityIn, + std::uint32_t uQualityOut, + beast::Journal j); + +[[nodiscard]] TER +trustDelete( + ApplyView& view, + std::shared_ptr const& sleRippleState, + AccountID const& uLowAccountID, + AccountID const& uHighAccountID, + beast::Journal j); + +//------------------------------------------------------------------------------ +// +// IOU issuance/redemption +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +issueIOU( + ApplyView& view, + AccountID const& account, + STAmount const& amount, + Issue const& issue, + beast::Journal j); + +[[nodiscard]] TER +redeemIOU( + ApplyView& view, + AccountID const& account, + STAmount const& amount, + Issue const& issue, + beast::Journal j); + +//------------------------------------------------------------------------------ +// +// Authorization and transfer checks (IOU-specific) +// +//------------------------------------------------------------------------------ + +/** Check if the account lacks required authorization. + * + * Return tecNO_AUTH or tecNO_LINE if it does + * and tesSUCCESS otherwise. + * + * If StrongAuth then return tecNO_LINE if the RippleState doesn't exist. Return + * tecNO_AUTH if lsfRequireAuth is set on the issuer's AccountRoot, and the + * RippleState does exist, and the RippleState is not authorized. + * + * If WeakAuth then return tecNO_AUTH if lsfRequireAuth is set, and the + * RippleState exists, and is not authorized. Return tecNO_LINE if + * lsfRequireAuth is set and the RippleState doesn't exist. Consequently, if + * WeakAuth and lsfRequireAuth is *not* set, this function will return + * tesSUCCESS even if RippleState does *not* exist. + * + * The default "Legacy" auth type is equivalent to WeakAuth. + */ +[[nodiscard]] TER +requireAuth( + ReadView const& view, + Issue const& issue, + AccountID const& account, + AuthType authType = AuthType::Legacy); + +/** Check if the destination account is allowed + * to receive IOU. Return terNO_RIPPLE if rippling is + * disabled on both sides and tesSUCCESS otherwise. + */ +[[nodiscard]] TER +canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, AccountID const& to); + +//------------------------------------------------------------------------------ +// +// Empty holding operations (IOU-specific) +// +//------------------------------------------------------------------------------ + +/// Any transactors that call addEmptyHolding() in doApply must call +/// canAddHolding() in preflight with the same View and Asset +[[nodiscard]] TER +addEmptyHolding( + ApplyView& view, + AccountID const& accountID, + XRPAmount priorBalance, + Issue const& issue, + beast::Journal journal); + +[[nodiscard]] TER +removeEmptyHolding( + ApplyView& view, + AccountID const& accountID, + Issue const& issue, + beast::Journal journal); + +/** Delete trustline to AMM. The passed `sle` must be obtained from a prior + * call to view.peek(). Fail if neither side of the trustline is AMM or + * if ammAccountID is seated and is not one of the trustline's side. + */ +[[nodiscard]] TER +deleteAMMTrustLine( + ApplyView& view, + std::shared_ptr sleState, + std::optional const& ammAccountID, + beast::Journal j); + +} // namespace xrpl diff --git a/include/xrpl/ledger/helpers/TokenHelpers.h b/include/xrpl/ledger/helpers/TokenHelpers.h new file mode 100644 index 0000000000..74d1e4848e --- /dev/null +++ b/include/xrpl/ledger/helpers/TokenHelpers.h @@ -0,0 +1,286 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl { + +//------------------------------------------------------------------------------ +// +// Enums for token handling +// +//------------------------------------------------------------------------------ + +/** Controls the treatment of frozen account balances */ +enum FreezeHandling { fhIGNORE_FREEZE, fhZERO_IF_FROZEN }; + +/** Controls the treatment of unauthorized MPT balances */ +enum AuthHandling { ahIGNORE_AUTH, ahZERO_IF_UNAUTHORIZED }; + +/** Controls whether to include the account's full spendable balance */ +enum SpendableHandling { shSIMPLE_BALANCE, shFULL_BALANCE }; + +enum class WaiveTransferFee : bool { No = false, Yes }; + +/* Check if MPToken (for MPT) or trust line (for IOU) exists: + * - StrongAuth - before checking if authorization is required + * - WeakAuth + * for MPT - after checking lsfMPTRequireAuth flag + * for IOU - do not check if trust line exists + * - Legacy + * for MPT - before checking lsfMPTRequireAuth flag i.e. same as StrongAuth + * for IOU - do not check if trust line exists i.e. same as WeakAuth + */ +enum class AuthType { StrongAuth, WeakAuth, Legacy }; + +//------------------------------------------------------------------------------ +// +// Freeze checking (Asset-based dispatchers) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] bool +isGlobalFrozen(ReadView const& view, Asset const& asset); + +[[nodiscard]] bool +isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset); + +/** + * isFrozen check is recursive for MPT shares in a vault, descending to + * assets in the vault, up to maxAssetCheckDepth recursion depth. This is + * purely defensive, as we currently do not allow such vaults to be created. + */ +[[nodiscard]] bool +isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth = 0); + +[[nodiscard]] TER +checkFrozen(ReadView const& view, AccountID const& account, Issue const& issue); + +[[nodiscard]] TER +checkFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue); + +[[nodiscard]] TER +checkFrozen(ReadView const& view, AccountID const& account, Asset const& asset); + +[[nodiscard]] bool +isAnyFrozen( + ReadView const& view, + std::initializer_list const& accounts, + Issue const& issue); + +[[nodiscard]] bool +isAnyFrozen( + ReadView const& view, + std::initializer_list const& accounts, + Asset const& asset, + int depth = 0); + +[[nodiscard]] bool +isDeepFrozen( + ReadView const& view, + AccountID const& account, + MPTIssue const& mptIssue, + int depth = 0); + +/** + * isFrozen check is recursive for MPT shares in a vault, descending to + * assets in the vault, up to maxAssetCheckDepth recursion depth. This is + * purely defensive, as we currently do not allow such vaults to be created. + */ +[[nodiscard]] bool +isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth = 0); + +[[nodiscard]] TER +checkDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue); + +[[nodiscard]] TER +checkDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset); + +//------------------------------------------------------------------------------ +// +// Account balance functions (Asset-based dispatchers) +// +//------------------------------------------------------------------------------ + +// Returns the amount an account can spend. +// +// If shSIMPLE_BALANCE is specified, this is the amount the account can spend +// without going into debt. +// +// If shFULL_BALANCE is specified, this is the amount the account can spend +// total. Specifically: +// * The account can go into debt if using a trust line, and the other side has +// a non-zero limit. +// * If the account is the asset issuer the limit is defined by the asset / +// issuance. +// +// <-- saAmount: amount of currency held by account. May be negative. +[[nodiscard]] STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer, + FreezeHandling zeroIfFrozen, + beast::Journal j, + SpendableHandling includeFullBalance = shSIMPLE_BALANCE); + +[[nodiscard]] STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + Issue const& issue, + FreezeHandling zeroIfFrozen, + beast::Journal j, + SpendableHandling includeFullBalance = shSIMPLE_BALANCE); + +[[nodiscard]] STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + MPTIssue const& mptIssue, + FreezeHandling zeroIfFrozen, + AuthHandling zeroIfUnauthorized, + beast::Journal j, + SpendableHandling includeFullBalance = shSIMPLE_BALANCE); + +[[nodiscard]] STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + Asset const& asset, + FreezeHandling zeroIfFrozen, + AuthHandling zeroIfUnauthorized, + beast::Journal j, + SpendableHandling includeFullBalance = shSIMPLE_BALANCE); + +// Returns the amount an account can spend of the currency type saDefault, or +// returns saDefault if this account is the issuer of the currency in +// question. Should be used in favor of accountHolds when questioning how much +// an account can spend while also allowing currency issuers to spend +// unlimited amounts of their own currency (since they can always issue more). +[[nodiscard]] STAmount +accountFunds( + ReadView const& view, + AccountID const& id, + STAmount const& saDefault, + FreezeHandling freezeHandling, + beast::Journal j); + +/** Returns the transfer fee as Rate based on the type of token + * @param view The ledger view + * @param amount The amount to transfer + */ +[[nodiscard]] Rate +transferRate(ReadView const& view, STAmount const& amount); + +//------------------------------------------------------------------------------ +// +// Holding operations (Asset-based dispatchers) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +canAddHolding(ReadView const& view, Asset const& asset); + +[[nodiscard]] TER +addEmptyHolding( + ApplyView& view, + AccountID const& accountID, + XRPAmount priorBalance, + Asset const& asset, + beast::Journal journal); + +[[nodiscard]] TER +removeEmptyHolding( + ApplyView& view, + AccountID const& accountID, + Asset const& asset, + beast::Journal journal); + +//------------------------------------------------------------------------------ +// +// Authorization and transfer checks (Asset-based dispatchers) +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +requireAuth( + ReadView const& view, + Asset const& asset, + AccountID const& account, + AuthType authType = AuthType::Legacy); + +[[nodiscard]] TER +canTransfer(ReadView const& view, Asset const& asset, AccountID const& from, AccountID const& to); + +//------------------------------------------------------------------------------ +// +// Money Transfers (Asset-based dispatchers) +// +//------------------------------------------------------------------------------ + +// Direct send w/o fees: +// - Redeeming IOUs and/or sending sender's own IOUs. +// - Create trust line of needed. +// --> bCheckIssuer : normally require issuer to be involved. +// [[nodiscard]] // nodiscard commented out so DirectStep.cpp compiles. + +/** Calls static rippleCreditIOU if saAmount represents Issue. + * Calls static rippleCreditMPT if saAmount represents MPTIssue. + */ +TER +rippleCredit( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + bool bCheckIssuer, + beast::Journal j); + +/** Calls static accountSendIOU if saAmount represents Issue. + * Calls static accountSendMPT if saAmount represents MPTIssue. + */ +[[nodiscard]] TER +accountSend( + ApplyView& view, + AccountID const& from, + AccountID const& to, + STAmount const& saAmount, + beast::Journal j, + WaiveTransferFee waiveFee = WaiveTransferFee::No); + +using MultiplePaymentDestinations = std::vector>; +/** Like accountSend, except one account is sending multiple payments (with the + * same asset!) simultaneously + * + * Calls static accountSendMultiIOU if saAmount represents Issue. + * Calls static accountSendMultiMPT if saAmount represents MPTIssue. + */ +[[nodiscard]] TER +accountSendMulti( + ApplyView& view, + AccountID const& senderID, + Asset const& asset, + MultiplePaymentDestinations const& receivers, + beast::Journal j, + WaiveTransferFee waiveFee = WaiveTransferFee::No); + +[[nodiscard]] TER +transferXRP( + ApplyView& view, + AccountID const& from, + AccountID const& to, + STAmount const& amount, + beast::Journal j); + +} // namespace xrpl diff --git a/include/xrpl/ledger/helpers/VaultHelpers.h b/include/xrpl/ledger/helpers/VaultHelpers.h new file mode 100644 index 0000000000..8aef30aa27 --- /dev/null +++ b/include/xrpl/ledger/helpers/VaultHelpers.h @@ -0,0 +1,81 @@ +#pragma once + +#include +#include + +#include +#include + +namespace xrpl { + +/** From the perspective of a vault, return the number of shares to give + depositor when they offer a fixed amount of assets. Note, since shares are + MPT, this number is integral and always truncated in this calculation. + + @param vault The vault SLE. + @param issuance The MPTokenIssuance SLE for the vault's shares. + @param assets The amount of assets to convert. + + @return The number of shares, or nullopt on error. +*/ +[[nodiscard]] std::optional +assetsToSharesDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets); + +/** From the perspective of a vault, return the number of assets to take from + depositor when they receive a fixed amount of shares. Note, since shares are + MPT, they are always an integral number. + + @param vault The vault SLE. + @param issuance The MPTokenIssuance SLE for the vault's shares. + @param shares The amount of shares to convert. + + @return The number of assets, or nullopt on error. +*/ +[[nodiscard]] std::optional +sharesToAssetsDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares); + +/** Controls whether to truncate shares instead of rounding. */ +enum class TruncateShares : bool { no = false, yes = true }; + +/** From the perspective of a vault, return the number of shares to demand from + the depositor when they ask to withdraw a fixed amount of assets. Since + shares are MPT this number is integral, and it will be rounded to nearest + unless explicitly requested to be truncated instead. + + @param vault The vault SLE. + @param issuance The MPTokenIssuance SLE for the vault's shares. + @param assets The amount of assets to convert. + @param truncate Whether to truncate instead of rounding. + + @return The number of shares, or nullopt on error. +*/ +[[nodiscard]] std::optional +assetsToSharesWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets, + TruncateShares truncate = TruncateShares::no); + +/** From the perspective of a vault, return the number of assets to give the + depositor when they redeem a fixed amount of shares. Note, since shares are + MPT, they are always an integral number. + + @param vault The vault SLE. + @param issuance The MPTokenIssuance SLE for the vault's shares. + @param shares The amount of shares to convert. + + @return The number of assets, or nullopt on error. +*/ +[[nodiscard]] std::optional +sharesToAssetsWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares); + +} // namespace xrpl diff --git a/include/xrpl/tx/paths/detail/StrandFlow.h b/include/xrpl/tx/paths/detail/StrandFlow.h index 67e333f2e6..f99f54d0e8 100644 --- a/include/xrpl/tx/paths/detail/StrandFlow.h +++ b/include/xrpl/tx/paths/detail/StrandFlow.h @@ -1,7 +1,8 @@ #pragma once #include -#include +#include +#include #include #include #include diff --git a/src/libxrpl/ledger/Credit.cpp b/src/libxrpl/ledger/Credit.cpp deleted file mode 100644 index 0a0283c3b8..0000000000 --- a/src/libxrpl/ledger/Credit.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include - -namespace xrpl { - -STAmount -creditLimit( - ReadView const& view, - AccountID const& account, - AccountID const& issuer, - Currency const& currency) -{ - STAmount result(Issue{currency, account}); - - auto sleRippleState = view.read(keylet::line(account, issuer, currency)); - - if (sleRippleState) - { - result = sleRippleState->getFieldAmount(account < issuer ? sfLowLimit : sfHighLimit); - result.setIssuer(account); - } - - XRPL_ASSERT(result.getIssuer() == account, "xrpl::creditLimit : result issuer match"); - XRPL_ASSERT(result.getCurrency() == currency, "xrpl::creditLimit : result currency match"); - return result; -} - -IOUAmount -creditLimit2(ReadView const& v, AccountID const& acc, AccountID const& iss, Currency const& cur) -{ - return toAmount(creditLimit(v, acc, iss, cur)); -} - -STAmount -creditBalance( - ReadView const& view, - AccountID const& account, - AccountID const& issuer, - Currency const& currency) -{ - STAmount result(Issue{currency, account}); - - auto sleRippleState = view.read(keylet::line(account, issuer, currency)); - - if (sleRippleState) - { - result = sleRippleState->getFieldAmount(sfBalance); - if (account < issuer) - result.negate(); - result.setIssuer(account); - } - - XRPL_ASSERT(result.getIssuer() == account, "xrpl::creditBalance : result issuer match"); - XRPL_ASSERT(result.getCurrency() == currency, "xrpl::creditBalance : result currency match"); - return result; -} - -} // namespace xrpl diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index d5c94a9981..f51fb97993 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -2,10 +2,9 @@ #include #include #include -#include -#include #include #include +#include #include #include #include @@ -22,133 +21,6 @@ namespace xrpl { -namespace detail { - -template < - class V, - class N, - class = std::enable_if_t< - std::is_same_v, SLE> && std::is_base_of_v>> -bool -internalDirNext( - V& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry) -{ - auto const& svIndexes = page->getFieldV256(sfIndexes); - XRPL_ASSERT(index <= svIndexes.size(), "xrpl::detail::internalDirNext : index inside range"); - - if (index >= svIndexes.size()) - { - auto const next = page->getFieldU64(sfIndexNext); - - if (!next) - { - entry.zero(); - return false; - } - - if constexpr (std::is_const_v) - { - page = view.read(keylet::page(root, next)); - } - else - { - page = view.peek(keylet::page(root, next)); - } - - XRPL_ASSERT(page, "xrpl::detail::internalDirNext : non-null root"); - - if (!page) - return false; - - index = 0; - - return internalDirNext(view, root, page, index, entry); - } - - entry = svIndexes[index++]; - return true; -} - -template < - class V, - class N, - class = std::enable_if_t< - std::is_same_v, SLE> && std::is_base_of_v>> -bool -internalDirFirst( - V& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry) -{ - if constexpr (std::is_const_v) - { - page = view.read(keylet::page(root)); - } - else - { - page = view.peek(keylet::page(root)); - } - - if (!page) - return false; - - index = 0; - - return internalDirNext(view, root, page, index, entry); -} - -} // namespace detail - -bool -dirFirst( - ApplyView& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry) -{ - return detail::internalDirFirst(view, root, page, index, entry); -} - -bool -dirNext( - ApplyView& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry) -{ - return detail::internalDirNext(view, root, page, index, entry); -} - -bool -cdirFirst( - ReadView const& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry) -{ - return detail::internalDirFirst(view, root, page, index, entry); -} - -bool -cdirNext( - ReadView const& view, - uint256 const& root, - std::shared_ptr& page, - unsigned int& index, - uint256& entry) -{ - return detail::internalDirNext(view, root, page, index, entry); -} - //------------------------------------------------------------------------------ // // Observers @@ -164,124 +36,6 @@ hasExpired(ReadView const& view, std::optional const& exp) return exp && (view.parentCloseTime() >= tp{d{*exp}}); } -bool -isGlobalFrozen(ReadView const& view, AccountID const& issuer) -{ - if (isXRP(issuer)) - return false; - if (auto const sle = view.read(keylet::account(issuer))) - return sle->isFlag(lsfGlobalFreeze); - return false; -} - -bool -isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue) -{ - if (auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID()))) - return sle->isFlag(lsfMPTLocked); - return false; -} - -bool -isGlobalFrozen(ReadView const& view, Asset const& asset) -{ - return std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - { - return isGlobalFrozen(view, issue.getIssuer()); - } - else - { - return isGlobalFrozen(view, issue); - } - }, - asset.value()); -} - -bool -isIndividualFrozen( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer) -{ - if (isXRP(currency)) - return false; - if (issuer != account) - { - // Check if the issuer froze the line - auto const sle = view.read(keylet::line(account, issuer, currency)); - if (sle && sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze)) - return true; - } - return false; -} - -bool -isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) -{ - if (auto const sle = view.read(keylet::mptoken(mptIssue.getMptID(), account))) - return sle->isFlag(lsfMPTLocked); - return false; -} - -// Can the specified account spend the specified currency issued by -// the specified issuer or does the freeze flag prohibit it? -bool -isFrozen( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer) -{ - if (isXRP(currency)) - return false; - auto sle = view.read(keylet::account(issuer)); - if (sle && sle->isFlag(lsfGlobalFreeze)) - return true; - if (issuer != account) - { - // Check if the issuer froze the line - sle = view.read(keylet::line(account, issuer, currency)); - if (sle && sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze)) - return true; - } - return false; -} - -bool -isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth) -{ - return isGlobalFrozen(view, mptIssue) || isIndividualFrozen(view, account, mptIssue) || - isVaultPseudoAccountFrozen(view, account, mptIssue, depth); -} - -[[nodiscard]] bool -isAnyFrozen( - ReadView const& view, - std::initializer_list const& accounts, - MPTIssue const& mptIssue, - int depth) -{ - if (isGlobalFrozen(view, mptIssue)) - return true; - - for (auto const& account : accounts) - { - if (isIndividualFrozen(view, account, mptIssue)) - return true; - } - - for (auto const& account : accounts) - { - if (isVaultPseudoAccountFrozen(view, account, mptIssue, depth)) - return true; - } - - return false; -} - bool isVaultPseudoAccountFrozen( ReadView const& view, @@ -323,32 +77,6 @@ isVaultPseudoAccountFrozen( return isAnyFrozen(view, {issuer, account}, vault->at(sfAsset), depth + 1); } -bool -isDeepFrozen( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer) -{ - if (isXRP(currency)) - { - return false; - } - - if (issuer == account) - { - return false; - } - - auto const sle = view.read(keylet::line(account, issuer, currency)); - if (!sle) - { - return false; - } - - return sle->isFlag(lsfHighDeepFreeze) || sle->isFlag(lsfLowDeepFreeze); -} - bool isLPTokenFrozen( ReadView const& view, @@ -360,468 +88,6 @@ isLPTokenFrozen( isFrozen(view, account, asset2.currency, asset2.account); } -static SLE::const_pointer -getLineIfUsable( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer, - FreezeHandling zeroIfFrozen, - beast::Journal j) -{ - auto const sle = view.read(keylet::line(account, issuer, currency)); - - if (!sle) - { - return nullptr; - } - - if (zeroIfFrozen == fhZERO_IF_FROZEN) - { - if (isFrozen(view, account, currency, issuer) || - isDeepFrozen(view, account, currency, issuer)) - { - return nullptr; - } - - // when fixFrozenLPTokenTransfer is enabled, if currency is lptoken, - // we need to check if the associated assets have been frozen - if (view.rules().enabled(fixFrozenLPTokenTransfer)) - { - auto const sleIssuer = view.read(keylet::account(issuer)); - if (!sleIssuer) - { - return nullptr; // LCOV_EXCL_LINE - } - if (sleIssuer->isFieldPresent(sfAMMID)) - { - auto const sleAmm = view.read(keylet::amm((*sleIssuer)[sfAMMID])); - - if (!sleAmm || - isLPTokenFrozen( - view, - account, - (*sleAmm)[sfAsset].get(), - (*sleAmm)[sfAsset2].get())) - { - return nullptr; - } - } - } - } - - return sle; -} - -static STAmount -getTrustLineBalance( - ReadView const& view, - SLE::const_ref sle, - AccountID const& account, - Currency const& currency, - AccountID const& issuer, - bool includeOppositeLimit, - beast::Journal j) -{ - STAmount amount; - if (sle) - { - amount = sle->getFieldAmount(sfBalance); - bool const accountHigh = account > issuer; - auto const& oppositeField = accountHigh ? sfLowLimit : sfHighLimit; - if (accountHigh) - { - // Put balance in account terms. - amount.negate(); - } - if (includeOppositeLimit) - { - amount += sle->getFieldAmount(oppositeField); - } - amount.setIssuer(issuer); - } - else - { - amount.clear(Issue{currency, issuer}); - } - - JLOG(j.trace()) << "getTrustLineBalance:" << " account=" << to_string(account) - << " amount=" << amount.getFullText(); - - return view.balanceHook(account, issuer, amount); -} - -STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - Currency const& currency, - AccountID const& issuer, - FreezeHandling zeroIfFrozen, - beast::Journal j, - SpendableHandling includeFullBalance) -{ - STAmount amount; - if (isXRP(currency)) - { - return {xrpLiquid(view, account, 0, j)}; - } - - bool const returnSpendable = (includeFullBalance == shFULL_BALANCE); - if (returnSpendable && account == issuer) - { - // If the account is the issuer, then their limit is effectively - // infinite - return STAmount{Issue{currency, issuer}, STAmount::cMaxValue, STAmount::cMaxOffset}; - } - - // IOU: Return balance on trust line modulo freeze - SLE::const_pointer const sle = - getLineIfUsable(view, account, currency, issuer, zeroIfFrozen, j); - - return getTrustLineBalance(view, sle, account, currency, issuer, returnSpendable, j); -} - -STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - Issue const& issue, - FreezeHandling zeroIfFrozen, - beast::Journal j, - SpendableHandling includeFullBalance) -{ - return accountHolds( - view, account, issue.currency, issue.account, zeroIfFrozen, j, includeFullBalance); -} - -STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - MPTIssue const& mptIssue, - FreezeHandling zeroIfFrozen, - AuthHandling zeroIfUnauthorized, - beast::Journal j, - SpendableHandling includeFullBalance) -{ - bool const returnSpendable = (includeFullBalance == shFULL_BALANCE); - - if (returnSpendable && account == mptIssue.getIssuer()) - { - // if the account is the issuer, and the issuance exists, their limit is - // the issuance limit minus the outstanding value - auto const issuance = view.read(keylet::mptIssuance(mptIssue.getMptID())); - - if (!issuance) - { - return STAmount{mptIssue}; - } - return STAmount{ - mptIssue, - issuance->at(~sfMaximumAmount).value_or(maxMPTokenAmount) - - issuance->at(sfOutstandingAmount)}; - } - - STAmount amount; - - auto const sleMpt = view.read(keylet::mptoken(mptIssue.getMptID(), account)); - - if (!sleMpt) - { - amount.clear(mptIssue); - } - else if (zeroIfFrozen == fhZERO_IF_FROZEN && isFrozen(view, account, mptIssue)) - { - amount.clear(mptIssue); - } - else - { - amount = STAmount{mptIssue, sleMpt->getFieldU64(sfMPTAmount)}; - - // Only if auth check is needed, as it needs to do an additional read - // operation. Note featureSingleAssetVault will affect error codes. - if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED && - view.rules().enabled(featureSingleAssetVault)) - { - if (auto const err = requireAuth(view, mptIssue, account, AuthType::StrongAuth); - !isTesSuccess(err)) - amount.clear(mptIssue); - } - else if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED) - { - auto const sleIssuance = view.read(keylet::mptIssuance(mptIssue.getMptID())); - - // if auth is enabled on the issuance and mpt is not authorized, - // clear amount - if (sleIssuance && sleIssuance->isFlag(lsfMPTRequireAuth) && - !sleMpt->isFlag(lsfMPTAuthorized)) - amount.clear(mptIssue); - } - } - - return amount; -} - -[[nodiscard]] STAmount -accountHolds( - ReadView const& view, - AccountID const& account, - Asset const& asset, - FreezeHandling zeroIfFrozen, - AuthHandling zeroIfUnauthorized, - beast::Journal j, - SpendableHandling includeFullBalance) -{ - return std::visit( - [&](TIss const& value) { - if constexpr (std::is_same_v) - { - return accountHolds(view, account, value, zeroIfFrozen, j, includeFullBalance); - } - else if constexpr (std::is_same_v) - { - return accountHolds( - view, account, value, zeroIfFrozen, zeroIfUnauthorized, j, includeFullBalance); - } - }, - asset.value()); -} - -STAmount -accountFunds( - ReadView const& view, - AccountID const& id, - STAmount const& saDefault, - FreezeHandling freezeHandling, - beast::Journal j) -{ - if (!saDefault.native() && saDefault.getIssuer() == id) - return saDefault; - - return accountHolds( - view, id, saDefault.getCurrency(), saDefault.getIssuer(), freezeHandling, j); -} - -// Prevent ownerCount from wrapping under error conditions. -// -// adjustment allows the ownerCount to be adjusted up or down in multiple steps. -// If id != std::nullopt, then do error reporting. -// -// Returns adjusted owner count. -static std::uint32_t -confineOwnerCount( - std::uint32_t current, - std::int32_t adjustment, - std::optional const& id = std::nullopt, - beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) -{ - std::uint32_t adjusted{current + adjustment}; - if (adjustment > 0) - { - // Overflow is well defined on unsigned - if (adjusted < current) - { - if (id) - { - JLOG(j.fatal()) << "Account " << *id << " owner count exceeds max!"; - } - adjusted = std::numeric_limits::max(); - } - } - else - { - // Underflow is well defined on unsigned - if (adjusted > current) - { - if (id) - { - JLOG(j.fatal()) << "Account " << *id << " owner count set below 0!"; - } - adjusted = 0; - XRPL_ASSERT(!id, "xrpl::confineOwnerCount : id is not set"); - } - } - return adjusted; -} - -XRPAmount -xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j) -{ - auto const sle = view.read(keylet::account(id)); - if (sle == nullptr) - return beast::zero; - - // Return balance minus reserve - std::uint32_t const ownerCount = - confineOwnerCount(view.ownerCountHook(id, sle->getFieldU32(sfOwnerCount)), ownerCountAdj); - - // Pseudo-accounts have no reserve requirement - auto const reserve = - isPseudoAccount(sle) ? XRPAmount{0} : view.fees().accountReserve(ownerCount); - - auto const fullBalance = sle->getFieldAmount(sfBalance); - - auto const balance = view.balanceHook(id, xrpAccount(), fullBalance); - - STAmount const amount = (balance < reserve) ? STAmount{0} : balance - reserve; - - JLOG(j.trace()) << "accountHolds:" << " account=" << to_string(id) - << " amount=" << amount.getFullText() - << " fullBalance=" << fullBalance.getFullText() - << " balance=" << balance.getFullText() << " reserve=" << reserve - << " ownerCount=" << ownerCount << " ownerCountAdj=" << ownerCountAdj; - - return amount.xrp(); -} - -void -forEachItem( - ReadView const& view, - Keylet const& root, - std::function const&)> const& f) -{ - XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItem : valid root type"); - - if (root.type != ltDIR_NODE) - return; - - auto pos = root; - - while (true) - { - auto sle = view.read(pos); - if (!sle) - return; - for (auto const& key : sle->getFieldV256(sfIndexes)) - f(view.read(keylet::child(key))); - auto const next = sle->getFieldU64(sfIndexNext); - if (!next) - return; - pos = keylet::page(root, next); - } -} - -bool -forEachItemAfter( - ReadView const& view, - Keylet const& root, - uint256 const& after, - std::uint64_t const hint, - unsigned int limit, - std::function const&)> const& f) -{ - XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItemAfter : valid root type"); - - if (root.type != ltDIR_NODE) - return false; - - auto currentIndex = root; - - // If startAfter is not zero try jumping to that page using the hint - if (after.isNonZero()) - { - auto const hintIndex = keylet::page(root, hint); - - if (auto hintDir = view.read(hintIndex)) - { - for (auto const& key : hintDir->getFieldV256(sfIndexes)) - { - if (key == after) - { - // We found the hint, we can start here - currentIndex = hintIndex; - break; - } - } - } - - bool found = false; - for (;;) - { - auto const ownerDir = view.read(currentIndex); - if (!ownerDir) - return found; - for (auto const& key : ownerDir->getFieldV256(sfIndexes)) - { - if (!found) - { - if (key == after) - found = true; - } - else if (f(view.read(keylet::child(key))) && limit-- <= 1) - { - return found; - } - } - - auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext); - if (uNodeNext == 0) - return found; - currentIndex = keylet::page(root, uNodeNext); - } - } - else - { - for (;;) - { - auto const ownerDir = view.read(currentIndex); - if (!ownerDir) - return true; - for (auto const& key : ownerDir->getFieldV256(sfIndexes)) - { - if (f(view.read(keylet::child(key))) && limit-- <= 1) - return true; - } - auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext); - if (uNodeNext == 0) - return true; - currentIndex = keylet::page(root, uNodeNext); - } - } -} - -Rate -transferRate(ReadView const& view, AccountID const& issuer) -{ - auto const sle = view.read(keylet::account(issuer)); - - if (sle && sle->isFieldPresent(sfTransferRate)) - return Rate{sle->getFieldU32(sfTransferRate)}; - - return parityRate; -} - -Rate -transferRate(ReadView const& view, MPTID const& issuanceID) -{ - // fee is 0-50,000 (0-50%), rate is 1,000,000,000-2,000,000,000 - // For example, if transfer fee is 50% then 10,000 * 50,000 = 500,000 - // which represents 50% of 1,000,000,000 - if (auto const sle = view.read(keylet::mptIssuance(issuanceID)); - sle && sle->isFieldPresent(sfTransferFee)) - return Rate{1'000'000'000u + 10'000 * sle->getFieldU16(sfTransferFee)}; - - return parityRate; -} - -Rate -transferRate(ReadView const& view, STAmount const& amount) -{ - return std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - { - return transferRate(view, issue.getIssuer()); - } - else - { - return transferRate(view, issue.getMptID()); - } - }, - amount.asset().value()); -} - bool areCompatible( ReadView const& validLedger, @@ -920,20 +186,6 @@ areCompatible( return ret; } -bool -dirIsEmpty(ReadView const& view, Keylet const& k) -{ - auto const sleNode = view.read(k); - if (!sleNode) - return true; - if (!sleNode->getFieldV256(sfIndexes).empty()) - return false; - // The first page of a directory may legitimately be empty even if there - // are other pages (the first page is the anchor page) so check to see if - // there is another page. If there is, the directory isn't empty. - return sleNode->getFieldU64(sfIndexNext) == 0; -} - std::set getEnabledAmendments(ReadView const& view) { @@ -1037,30 +289,6 @@ hashOfSeq(ReadView const& ledger, LedgerIndex seq, beast::Journal journal) // //------------------------------------------------------------------------------ -void -adjustOwnerCount( - ApplyView& view, - std::shared_ptr const& sle, - std::int32_t amount, - beast::Journal j) -{ - if (!sle) - return; - XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input"); - std::uint32_t const current{sle->getFieldU32(sfOwnerCount)}; - AccountID const id = (*sle)[sfAccount]; - std::uint32_t const adjusted = confineOwnerCount(current, amount, id, j); - view.adjustOwnerCountHook(id, current, adjusted); - sle->at(sfOwnerCount) = adjusted; - view.update(sle); -} - -std::function -describeOwnerDir(AccountID const& account) -{ - return [account](std::shared_ptr const& sle) { (*sle)[sfOwner] = account; }; -} - TER dirLink( ApplyView& view, @@ -1076,168 +304,6 @@ dirLink( return tesSUCCESS; } -AccountID -pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey) -{ - // This number must not be changed without an amendment - constexpr std::uint16_t maxAccountAttempts = 256; - for (std::uint16_t i = 0; i < maxAccountAttempts; ++i) - { - ripesha_hasher rsh; - auto const hash = sha512Half(i, view.header().parentHash, pseudoOwnerKey); - rsh(hash.data(), hash.size()); - AccountID const ret{static_cast(rsh)}; - if (!view.read(keylet::account(ret))) - return ret; - } - return beast::zero; -} - -// Pseudo-account designator fields MUST be maintained by including the -// SField::sMD_PseudoAccount flag in the SField definition. (Don't forget to -// "| SField::sMD_Default"!) The fields do NOT need to be amendment-gated, -// since a non-active amendment will not set any field, by definition. -// Specific properties of a pseudo-account are NOT checked here, that's what -// InvariantCheck is for. -[[nodiscard]] std::vector const& -getPseudoAccountFields() -{ - static std::vector const pseudoFields = []() { - auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT); - if (!ar) - { - // LCOV_EXCL_START - LogicError( - "xrpl::getPseudoAccountFields : unable to find account root " - "ledger format"); - // LCOV_EXCL_STOP - } - auto const& soTemplate = ar->getSOTemplate(); - - std::vector pseudoFields; - for (auto const& field : soTemplate) - { - if (field.sField().shouldMeta(SField::sMD_PseudoAccount)) - pseudoFields.emplace_back(&field.sField()); - } - return pseudoFields; - }(); - return pseudoFields; -} - -[[nodiscard]] bool -isPseudoAccount( - std::shared_ptr sleAcct, - std::set const& pseudoFieldFilter) -{ - auto const& fields = getPseudoAccountFields(); - - // Intentionally use defensive coding here because it's cheap and makes the - // semantics of true return value clean. - return sleAcct && sleAcct->getType() == ltACCOUNT_ROOT && - std::count_if( - fields.begin(), fields.end(), [&sleAcct, &pseudoFieldFilter](SField const* sf) -> bool { - return sleAcct->isFieldPresent(*sf) && - (pseudoFieldFilter.empty() || pseudoFieldFilter.contains(sf)); - }) > 0; -} - -Expected, TER> -createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField) -{ - [[maybe_unused]] - auto const& fields = getPseudoAccountFields(); - XRPL_ASSERT( - std::count_if( - fields.begin(), - fields.end(), - [&ownerField](SField const* sf) -> bool { return *sf == ownerField; }) == 1, - "xrpl::createPseudoAccount : valid owner field"); - - auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey); - if (accountId == beast::zero) - return Unexpected(tecDUPLICATE); - - // Create pseudo-account. - auto account = std::make_shared(keylet::account(accountId)); - account->setAccountID(sfAccount, accountId); - account->setFieldAmount(sfBalance, STAmount{}); - - // Pseudo-accounts can't submit transactions, so set the sequence number - // to 0 to make them easier to spot and verify, and add an extra level - // of protection. - std::uint32_t const seqno = // - view.rules().enabled(featureSingleAssetVault) || // - view.rules().enabled(featureLendingProtocol) // - ? 0 // - : view.seq(); - account->setFieldU32(sfSequence, seqno); - // Ignore reserves requirement, disable the master key, allow default - // rippling, and enable deposit authorization to prevent payments into - // pseudo-account. - account->setFieldU32(sfFlags, lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth); - // Link the pseudo-account with its owner object. - account->setFieldH256(ownerField, pseudoOwnerKey); - - view.insert(account); - - return account; -} - -[[nodiscard]] TER -canAddHolding(ReadView const& view, Issue const& issue) -{ - if (issue.native()) - return tesSUCCESS; // No special checks for XRP - - auto const issuer = view.read(keylet::account(issue.getIssuer())); - if (!issuer) - { - return terNO_ACCOUNT; - } - if (!issuer->isFlag(lsfDefaultRipple)) - { - return terNO_RIPPLE; - } - - return tesSUCCESS; -} - -[[nodiscard]] TER -canAddHolding(ReadView const& view, MPTIssue const& mptIssue) -{ - auto mptID = mptIssue.getMptID(); - auto issuance = view.read(keylet::mptIssuance(mptID)); - if (!issuance) - return tecOBJECT_NOT_FOUND; - if (!issuance->isFlag(lsfMPTCanTransfer)) - return tecNO_AUTH; - - return tesSUCCESS; -} - -[[nodiscard]] TER -canAddHolding(ReadView const& view, Asset const& asset) -{ - return std::visit( - [&](TIss const& issue) -> TER { return canAddHolding(view, issue); }, - asset.value()); -} - -[[nodiscard]] TER -checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag) -{ - if (toSle == nullptr) - return tecNO_DST; - - // The tag is basically account-specific information we don't - // understand, but we can require someone to fill it in. - if (toSle->isFlag(lsfRequireDestTag) && !hasDestinationTag) - return tecDST_TAG_NEEDED; // Cannot send without a tag - - return tesSUCCESS; -} - /* * Checks if a withdrawal amount into the destination account exceeds * any applicable receiving limit. @@ -1375,1837 +441,6 @@ doWithdraw( return accountSend(view, sourceAcct, dstAcct, amount, j, WaiveTransferFee::Yes); } -[[nodiscard]] TER -addEmptyHolding( - ApplyView& view, - AccountID const& accountID, - XRPAmount priorBalance, - Issue const& issue, - beast::Journal journal) -{ - // Every account can hold XRP. An issuer can issue directly. - if (issue.native() || accountID == issue.getIssuer()) - return tesSUCCESS; - - auto const& issuerId = issue.getIssuer(); - auto const& currency = issue.currency; - if (isGlobalFrozen(view, issuerId)) - return tecFROZEN; // LCOV_EXCL_LINE - - auto const& srcId = issuerId; - auto const& dstId = accountID; - auto const high = srcId > dstId; - auto const index = keylet::line(srcId, dstId, currency); - auto const sleSrc = view.peek(keylet::account(srcId)); - auto const sleDst = view.peek(keylet::account(dstId)); - if (!sleDst || !sleSrc) - return tefINTERNAL; // LCOV_EXCL_LINE - if (!sleSrc->isFlag(lsfDefaultRipple)) - return tecINTERNAL; // LCOV_EXCL_LINE - // If the line already exists, don't create it again. - if (view.read(index)) - return tecDUPLICATE; - - // Can the account cover the trust line reserve ? - std::uint32_t const ownerCount = sleDst->at(sfOwnerCount); - if (priorBalance < view.fees().accountReserve(ownerCount + 1)) - return tecNO_LINE_INSUF_RESERVE; - - return trustCreate( - view, - high, - srcId, - dstId, - index.key, - sleDst, - /*bAuth=*/false, - /*bNoRipple=*/true, - /*bFreeze=*/false, - /*deepFreeze*/ false, - /*saBalance=*/STAmount{Issue{currency, noAccount()}}, - /*saLimit=*/STAmount{Issue{currency, dstId}}, - /*uSrcQualityIn=*/0, - /*uSrcQualityOut=*/0, - journal); -} - -[[nodiscard]] TER -addEmptyHolding( - ApplyView& view, - AccountID const& accountID, - XRPAmount priorBalance, - MPTIssue const& mptIssue, - beast::Journal journal) -{ - auto const& mptID = mptIssue.getMptID(); - auto const mpt = view.peek(keylet::mptIssuance(mptID)); - if (!mpt) - return tefINTERNAL; // LCOV_EXCL_LINE - if (mpt->isFlag(lsfMPTLocked)) - return tefINTERNAL; // LCOV_EXCL_LINE - if (view.peek(keylet::mptoken(mptID, accountID))) - return tecDUPLICATE; - if (accountID == mptIssue.getIssuer()) - return tesSUCCESS; - - return authorizeMPToken(view, priorBalance, mptID, accountID, journal); -} - -[[nodiscard]] TER -authorizeMPToken( - ApplyView& view, - XRPAmount const& priorBalance, - MPTID const& mptIssuanceID, - AccountID const& account, - beast::Journal journal, - std::uint32_t flags, - std::optional holderID) -{ - auto const sleAcct = view.peek(keylet::account(account)); - if (!sleAcct) - return tecINTERNAL; // LCOV_EXCL_LINE - - // If the account that submitted the tx is a holder - // Note: `account_` is holder's account - // `holderID` is NOT used - if (!holderID) - { - // When a holder wants to unauthorize/delete a MPT, the ledger must - // - delete mptokenKey from owner directory - // - delete the MPToken - if (flags & tfMPTUnauthorize) - { - auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); - auto const sleMpt = view.peek(mptokenKey); - if (!sleMpt || (*sleMpt)[sfMPTAmount] != 0) - return tecINTERNAL; // LCOV_EXCL_LINE - - if (!view.dirRemove( - keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false)) - return tecINTERNAL; // LCOV_EXCL_LINE - - adjustOwnerCount(view, sleAcct, -1, journal); - - view.erase(sleMpt); - return tesSUCCESS; - } - - // A potential holder wants to authorize/hold a mpt, the ledger must: - // - add the new mptokenKey to the owner directory - // - create the MPToken object for the holder - - // The reserve that is required to create the MPToken. Note - // that although the reserve increases with every item - // an account owns, in the case of MPTokens we only - // *enforce* a reserve if the user owns more than two - // items. This is similar to the reserve requirements of trust lines. - std::uint32_t const uOwnerCount = sleAcct->getFieldU32(sfOwnerCount); - XRPAmount const reserveCreate( - (uOwnerCount < 2) ? XRPAmount(beast::zero) - : view.fees().accountReserve(uOwnerCount + 1)); - - if (priorBalance < reserveCreate) - return tecINSUFFICIENT_RESERVE; - - // Defensive check before we attempt to create MPToken for the issuer - auto const mpt = view.read(keylet::mptIssuance(mptIssuanceID)); - if (!mpt || mpt->getAccountID(sfIssuer) == account) - { - // LCOV_EXCL_START - UNREACHABLE("xrpl::authorizeMPToken : invalid issuance or issuers token"); - if (view.rules().enabled(featureLendingProtocol)) - return tecINTERNAL; - // LCOV_EXCL_STOP - } - - auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); - auto mptoken = std::make_shared(mptokenKey); - if (auto ter = dirLink(view, account, mptoken)) - return ter; // LCOV_EXCL_LINE - - (*mptoken)[sfAccount] = account; - (*mptoken)[sfMPTokenIssuanceID] = mptIssuanceID; - (*mptoken)[sfFlags] = 0; - view.insert(mptoken); - - // Update owner count. - adjustOwnerCount(view, sleAcct, 1, journal); - - return tesSUCCESS; - } - - auto const sleMptIssuance = view.read(keylet::mptIssuance(mptIssuanceID)); - if (!sleMptIssuance) - 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; // LCOV_EXCL_LINE - - auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID)); - if (!sleMpt) - return tecINTERNAL; // LCOV_EXCL_LINE - - std::uint32_t const flagsIn = sleMpt->getFieldU32(sfFlags); - std::uint32_t flagsOut = flagsIn; - - // Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on - // their MPToken - if (flags & tfMPTUnauthorize) - { - flagsOut &= ~lsfMPTAuthorized; - } - // Issuer wants to authorize a holder, set lsfMPTAuthorized on their - // MPToken - else - { - flagsOut |= lsfMPTAuthorized; - } - - if (flagsIn != flagsOut) - sleMpt->setFieldU32(sfFlags, flagsOut); - - view.update(sleMpt); - return tesSUCCESS; -} - -TER -trustCreate( - ApplyView& view, - bool const bSrcHigh, - AccountID const& uSrcAccountID, - AccountID const& uDstAccountID, - uint256 const& uIndex, // --> ripple state entry - SLE::ref sleAccount, // --> the account being set. - bool const bAuth, // --> authorize account. - bool const bNoRipple, // --> others cannot ripple through - bool const bFreeze, // --> funds cannot leave - bool bDeepFreeze, // --> can neither receive nor send funds - STAmount const& saBalance, // --> balance of account being set. - // Issuer should be noAccount() - STAmount const& saLimit, // --> limit for account being set. - // Issuer should be the account being set. - std::uint32_t uQualityIn, - std::uint32_t uQualityOut, - beast::Journal j) -{ - JLOG(j.trace()) << "trustCreate: " << to_string(uSrcAccountID) << ", " - << to_string(uDstAccountID) << ", " << saBalance.getFullText(); - - auto const& uLowAccountID = !bSrcHigh ? uSrcAccountID : uDstAccountID; - auto const& uHighAccountID = bSrcHigh ? uSrcAccountID : uDstAccountID; - if (uLowAccountID == uHighAccountID) - { - // LCOV_EXCL_START - UNREACHABLE("xrpl::trustCreate : trust line to self"); - if (view.rules().enabled(featureLendingProtocol)) - return tecINTERNAL; - // LCOV_EXCL_STOP - } - - auto const sleRippleState = std::make_shared(ltRIPPLE_STATE, uIndex); - view.insert(sleRippleState); - - auto lowNode = view.dirInsert( - keylet::ownerDir(uLowAccountID), sleRippleState->key(), describeOwnerDir(uLowAccountID)); - - if (!lowNode) - return tecDIR_FULL; // LCOV_EXCL_LINE - - auto highNode = view.dirInsert( - keylet::ownerDir(uHighAccountID), sleRippleState->key(), describeOwnerDir(uHighAccountID)); - - if (!highNode) - return tecDIR_FULL; // LCOV_EXCL_LINE - - bool const bSetDst = saLimit.getIssuer() == uDstAccountID; - bool const bSetHigh = bSrcHigh ^ bSetDst; - - XRPL_ASSERT(sleAccount, "xrpl::trustCreate : non-null SLE"); - if (!sleAccount) - return tefINTERNAL; // LCOV_EXCL_LINE - - XRPL_ASSERT( - sleAccount->getAccountID(sfAccount) == (bSetHigh ? uHighAccountID : uLowAccountID), - "xrpl::trustCreate : matching account ID"); - auto const slePeer = view.peek(keylet::account(bSetHigh ? uLowAccountID : uHighAccountID)); - if (!slePeer) - return tecNO_TARGET; - - // Remember deletion hints. - sleRippleState->setFieldU64(sfLowNode, *lowNode); - sleRippleState->setFieldU64(sfHighNode, *highNode); - - sleRippleState->setFieldAmount(bSetHigh ? sfHighLimit : sfLowLimit, saLimit); - sleRippleState->setFieldAmount( - bSetHigh ? sfLowLimit : sfHighLimit, - STAmount(Issue{saBalance.getCurrency(), bSetDst ? uSrcAccountID : uDstAccountID})); - - if (uQualityIn) - sleRippleState->setFieldU32(bSetHigh ? sfHighQualityIn : sfLowQualityIn, uQualityIn); - - if (uQualityOut) - sleRippleState->setFieldU32(bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut); - - std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve; - - if (bAuth) - { - uFlags |= (bSetHigh ? lsfHighAuth : lsfLowAuth); - } - if (bNoRipple) - { - uFlags |= (bSetHigh ? lsfHighNoRipple : lsfLowNoRipple); - } - if (bFreeze) - { - uFlags |= (bSetHigh ? lsfHighFreeze : lsfLowFreeze); - } - if (bDeepFreeze) - { - uFlags |= (bSetHigh ? lsfHighDeepFreeze : lsfLowDeepFreeze); - } - - if ((slePeer->getFlags() & lsfDefaultRipple) == 0) - { - // The other side's default is no rippling - uFlags |= (bSetHigh ? lsfLowNoRipple : lsfHighNoRipple); - } - - sleRippleState->setFieldU32(sfFlags, uFlags); - adjustOwnerCount(view, sleAccount, 1, j); - - // ONLY: Create ripple balance. - sleRippleState->setFieldAmount(sfBalance, bSetHigh ? -saBalance : saBalance); - - view.creditHook(uSrcAccountID, uDstAccountID, saBalance, saBalance.zeroed()); - - return tesSUCCESS; -} - -[[nodiscard]] TER -removeEmptyHolding( - ApplyView& view, - AccountID const& accountID, - Issue const& issue, - beast::Journal journal) -{ - if (issue.native()) - { - auto const sle = view.read(keylet::account(accountID)); - if (!sle) - return tecINTERNAL; // LCOV_EXCL_LINE - - auto const balance = sle->getFieldAmount(sfBalance); - if (balance.xrp() != 0) - return tecHAS_OBLIGATIONS; - - return tesSUCCESS; - } - - // `asset` is an IOU. - // If the account is the issuer, then no line should exist. Check anyway. If - // a line does exist, it will get deleted. If not, return success. - bool const accountIsIssuer = accountID == issue.account; - auto const line = view.peek(keylet::line(accountID, issue)); - if (!line) - return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; - if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::zero) - return tecHAS_OBLIGATIONS; - - // Adjust the owner count(s) - if (line->isFlag(lsfLowReserve)) - { - // Clear reserve for low account. - auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); - if (!sleLowAccount) - 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 - // accurate state at the time of deletion. - line->clearFlag(lsfLowReserve); - } - - if (line->isFlag(lsfHighReserve)) - { - // Clear reserve for high account. - auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); - if (!sleHighAccount) - 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 - // accurate state at the time of deletion. - line->clearFlag(lsfHighReserve); - } - - return trustDelete( - view, line, line->at(sfLowLimit)->getIssuer(), line->at(sfHighLimit)->getIssuer(), journal); -} - -[[nodiscard]] TER -removeEmptyHolding( - ApplyView& view, - AccountID const& accountID, - MPTIssue const& mptIssue, - beast::Journal journal) -{ - // If the account is the issuer, then no token should exist. MPTs do not - // have the legacy ability to create such a situation, but check anyway. If - // a token does exist, it will get deleted. If not, return success. - bool const accountIsIssuer = accountID == mptIssue.getIssuer(); - auto const& mptID = mptIssue.getMptID(); - auto const mptoken = view.peek(keylet::mptoken(mptID, accountID)); - if (!mptoken) - return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; - // Unlike a trust line, if the account is the issuer, and the token has a - // balance, it can not just be deleted, because that will throw the issuance - // accounting out of balance, so fail. Since this should be impossible - // anyway, I'm not going to put any effort into it. - if (mptoken->at(sfMPTAmount) != 0) - return tecHAS_OBLIGATIONS; - - return authorizeMPToken( - view, - {}, // priorBalance - mptID, - accountID, - journal, - tfMPTUnauthorize // flags - ); -} - -TER -trustDelete( - ApplyView& view, - std::shared_ptr const& sleRippleState, - AccountID const& uLowAccountID, - AccountID const& uHighAccountID, - beast::Journal j) -{ - // Detect legacy dirs. - std::uint64_t uLowNode = sleRippleState->getFieldU64(sfLowNode); - std::uint64_t uHighNode = sleRippleState->getFieldU64(sfHighNode); - - JLOG(j.trace()) << "trustDelete: Deleting ripple line: low"; - - if (!view.dirRemove(keylet::ownerDir(uLowAccountID), uLowNode, sleRippleState->key(), false)) - { - return tefBAD_LEDGER; // LCOV_EXCL_LINE - } - - JLOG(j.trace()) << "trustDelete: Deleting ripple line: high"; - - if (!view.dirRemove(keylet::ownerDir(uHighAccountID), uHighNode, sleRippleState->key(), false)) - { - return tefBAD_LEDGER; // LCOV_EXCL_LINE - } - - JLOG(j.trace()) << "trustDelete: Deleting ripple line: state"; - view.erase(sleRippleState); - - return tesSUCCESS; -} - -TER -offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j) -{ - if (!sle) - return tesSUCCESS; - auto offerIndex = sle->key(); - auto owner = sle->getAccountID(sfAccount); - - // Detect legacy directories. - uint256 uDirectory = sle->getFieldH256(sfBookDirectory); - - if (!view.dirRemove(keylet::ownerDir(owner), sle->getFieldU64(sfOwnerNode), offerIndex, false)) - { - return tefBAD_LEDGER; // LCOV_EXCL_LINE - } - - if (!view.dirRemove(keylet::page(uDirectory), sle->getFieldU64(sfBookNode), offerIndex, false)) - { - return tefBAD_LEDGER; // LCOV_EXCL_LINE - } - - if (sle->isFieldPresent(sfAdditionalBooks)) - { - XRPL_ASSERT( - sle->isFlag(lsfHybrid) && sle->isFieldPresent(sfDomainID), - "xrpl::offerDelete : should be a hybrid domain offer"); - - auto const& additionalBookDirs = sle->getFieldArray(sfAdditionalBooks); - - for (auto const& bookDir : additionalBookDirs) - { - auto const& dirIndex = bookDir.getFieldH256(sfBookDirectory); - auto const& dirNode = bookDir.getFieldU64(sfBookNode); - - if (!view.dirRemove(keylet::page(dirIndex), dirNode, offerIndex, false)) - { - return tefBAD_LEDGER; // LCOV_EXCL_LINE - } - } - } - - adjustOwnerCount(view, view.peek(keylet::account(owner)), -1, j); - - view.erase(sle); - - return tesSUCCESS; -} - -// Direct send w/o fees: -// - Redeeming IOUs and/or sending sender's own IOUs. -// - Create trust line if needed. -// --> bCheckIssuer : normally require issuer to be involved. -static TER -rippleCreditIOU( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - bool bCheckIssuer, - beast::Journal j) -{ - AccountID const& issuer = saAmount.getIssuer(); - Currency const& currency = saAmount.getCurrency(); - - // Make sure issuer is involved. - XRPL_ASSERT( - !bCheckIssuer || uSenderID == issuer || uReceiverID == issuer, - "xrpl::rippleCreditIOU : matching issuer or don't care"); - (void)issuer; - - // Disallow sending to self. - XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleCreditIOU : sender is not receiver"); - - bool const bSenderHigh = uSenderID > uReceiverID; - auto const index = keylet::line(uSenderID, uReceiverID, currency); - - XRPL_ASSERT( - !isXRP(uSenderID) && uSenderID != noAccount(), "xrpl::rippleCreditIOU : sender is not XRP"); - XRPL_ASSERT( - !isXRP(uReceiverID) && uReceiverID != noAccount(), - "xrpl::rippleCreditIOU : receiver is not XRP"); - - // If the line exists, modify it accordingly. - if (auto const sleRippleState = view.peek(index)) - { - STAmount saBalance = sleRippleState->getFieldAmount(sfBalance); - - if (bSenderHigh) - saBalance.negate(); // Put balance in sender terms. - - view.creditHook(uSenderID, uReceiverID, saAmount, saBalance); - - STAmount const saBefore = saBalance; - - saBalance -= saAmount; - - JLOG(j.trace()) << "rippleCreditIOU: " << to_string(uSenderID) << " -> " - << to_string(uReceiverID) << " : before=" << saBefore.getFullText() - << " amount=" << saAmount.getFullText() - << " after=" << saBalance.getFullText(); - - std::uint32_t const uFlags(sleRippleState->getFieldU32(sfFlags)); - bool bDelete = false; - - // FIXME This NEEDS to be cleaned up and simplified. It's impossible - // for anyone to understand. - if (saBefore > beast::zero - // Sender balance was positive. - && saBalance <= beast::zero - // Sender is zero or negative. - && (uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) - // Sender reserve is set. - && static_cast(uFlags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) != - static_cast( - view.read(keylet::account(uSenderID))->getFlags() & lsfDefaultRipple) && - !(uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) && - !sleRippleState->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit) - // Sender trust limit is 0. - && !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) - // Sender quality in is 0. - && !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut)) - // Sender quality out is 0. - { - // Clear the reserve of the sender, possibly delete the line! - adjustOwnerCount(view, view.peek(keylet::account(uSenderID)), -1, j); - - // Clear reserve flag. - sleRippleState->setFieldU32( - sfFlags, uFlags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve)); - - // Balance is zero, receiver reserve is clear. - bDelete = !saBalance // Balance is zero. - && !(uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)); - // Receiver reserve is clear. - } - - if (bSenderHigh) - saBalance.negate(); - - // Want to reflect balance to zero even if we are deleting line. - sleRippleState->setFieldAmount(sfBalance, saBalance); - // ONLY: Adjust ripple balance. - - if (bDelete) - { - return trustDelete( - view, - sleRippleState, - bSenderHigh ? uReceiverID : uSenderID, - !bSenderHigh ? uReceiverID : uSenderID, - j); - } - - view.update(sleRippleState); - return tesSUCCESS; - } - - STAmount const saReceiverLimit(Issue{currency, uReceiverID}); - STAmount saBalance{saAmount}; - - saBalance.setIssuer(noAccount()); - - JLOG(j.debug()) << "rippleCreditIOU: " - "create line: " - << to_string(uSenderID) << " -> " << to_string(uReceiverID) << " : " - << saAmount.getFullText(); - - auto const sleAccount = view.peek(keylet::account(uReceiverID)); - if (!sleAccount) - return tefINTERNAL; // LCOV_EXCL_LINE - - bool const noRipple = (sleAccount->getFlags() & lsfDefaultRipple) == 0; - - return trustCreate( - view, - bSenderHigh, - uSenderID, - uReceiverID, - index.key, - sleAccount, - false, - noRipple, - false, - false, - saBalance, - saReceiverLimit, - 0, - 0, - j); -} - -// Send regardless of limits. -// --> saAmount: Amount/currency/issuer to deliver to receiver. -// <-- saActual: Amount actually cost. Sender pays fees. -static TER -rippleSendIOU( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - STAmount& saActual, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - auto const& issuer = saAmount.getIssuer(); - - XRPL_ASSERT( - !isXRP(uSenderID) && !isXRP(uReceiverID), - "xrpl::rippleSendIOU : neither sender nor receiver is XRP"); - XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleSendIOU : sender is not receiver"); - - if (uSenderID == issuer || uReceiverID == issuer || issuer == noAccount()) - { - // Direct send: redeeming IOUs and/or sending own IOUs. - auto const ter = rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, false, j); - if (!isTesSuccess(ter)) - return ter; - saActual = saAmount; - return tesSUCCESS; - } - - // Sending 3rd party IOUs: transit. - - // Calculate the amount to transfer accounting - // for any transfer fees if the fee is not waived: - saActual = (waiveFee == WaiveTransferFee::Yes) ? saAmount - : multiply(saAmount, transferRate(view, issuer)); - - JLOG(j.debug()) << "rippleSendIOU> " << to_string(uSenderID) << " - > " - << to_string(uReceiverID) << " : deliver=" << saAmount.getFullText() - << " cost=" << saActual.getFullText(); - - TER terResult = rippleCreditIOU(view, issuer, uReceiverID, saAmount, true, j); - - if (tesSUCCESS == terResult) - terResult = rippleCreditIOU(view, uSenderID, issuer, saActual, true, j); - - return terResult; -} - -// Send regardless of limits. -// --> receivers: Amount/currency/issuer to deliver to receivers. -// <-- saActual: Amount actually cost to sender. Sender pays fees. -static TER -rippleSendMultiIOU( - ApplyView& view, - AccountID const& senderID, - Issue const& issue, - MultiplePaymentDestinations const& receivers, - STAmount& actual, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - auto const& issuer = issue.getIssuer(); - - XRPL_ASSERT(!isXRP(senderID), "xrpl::rippleSendMultiIOU : sender is not XRP"); - - // These may diverge - STAmount takeFromSender{issue}; - actual = takeFromSender; - - // Failures return immediately. - for (auto const& r : receivers) - { - auto const& receiverID = r.first; - STAmount amount{issue, r.second}; - - /* If we aren't sending anything or if the sender is the same as the - * receiver then we don't need to do anything. - */ - if (!amount || (senderID == receiverID)) - continue; - - XRPL_ASSERT(!isXRP(receiverID), "xrpl::rippleSendMultiIOU : receiver is not XRP"); - - if (senderID == issuer || receiverID == issuer || issuer == noAccount()) - { - // Direct send: redeeming IOUs and/or sending own IOUs. - if (auto const ter = rippleCreditIOU(view, senderID, receiverID, amount, false, j)) - return ter; - actual += amount; - // Do not add amount to takeFromSender, because rippleCreditIOU took - // it. - - continue; - } - - // Sending 3rd party IOUs: transit. - - // Calculate the amount to transfer accounting - // for any transfer fees if the fee is not waived: - STAmount actualSend = (waiveFee == WaiveTransferFee::Yes) - ? amount - : multiply(amount, transferRate(view, issuer)); - actual += actualSend; - takeFromSender += actualSend; - - JLOG(j.debug()) << "rippleSendMultiIOU> " << to_string(senderID) << " - > " - << to_string(receiverID) << " : deliver=" << amount.getFullText() - << " cost=" << actual.getFullText(); - - if (TER const terResult = rippleCreditIOU(view, issuer, receiverID, amount, true, j)) - return terResult; - } - - if (senderID != issuer && takeFromSender) - { - if (TER const terResult = rippleCreditIOU(view, senderID, issuer, takeFromSender, true, j)) - return terResult; - } - - return tesSUCCESS; -} - -static TER -accountSendIOU( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - if (view.rules().enabled(fixAMMv1_1)) - { - if (saAmount < beast::zero || saAmount.holds()) - { - return tecINTERNAL; // LCOV_EXCL_LINE - } - } - else - { - // LCOV_EXCL_START - XRPL_ASSERT( - saAmount >= beast::zero && !saAmount.holds(), - "xrpl::accountSendIOU : minimum amount and not MPT"); - // LCOV_EXCL_STOP - } - - /* If we aren't sending anything or if the sender is the same as the - * receiver then we don't need to do anything. - */ - if (!saAmount || (uSenderID == uReceiverID)) - return tesSUCCESS; - - if (!saAmount.native()) - { - STAmount saActual; - - JLOG(j.trace()) << "accountSendIOU: " << to_string(uSenderID) << " -> " - << to_string(uReceiverID) << " : " << saAmount.getFullText(); - - return rippleSendIOU(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee); - } - - /* XRP send which does not check reserve and can do pure adjustment. - * Note that sender or receiver may be null and this not a mistake; this - * setup is used during pathfinding and it is carefully controlled to - * ensure that transfers are balanced. - */ - TER terResult(tesSUCCESS); - - SLE::pointer sender = - uSenderID != beast::zero ? view.peek(keylet::account(uSenderID)) : SLE::pointer(); - SLE::pointer receiver = - uReceiverID != beast::zero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer(); - - if (auto stream = j.trace()) - { - std::string sender_bal("-"); - std::string receiver_bal("-"); - - if (sender) - sender_bal = sender->getFieldAmount(sfBalance).getFullText(); - - if (receiver) - receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); - - stream << "accountSendIOU> " << to_string(uSenderID) << " (" << sender_bal << ") -> " - << to_string(uReceiverID) << " (" << receiver_bal - << ") : " << saAmount.getFullText(); - } - - if (sender) - { - if (sender->getFieldAmount(sfBalance) < saAmount) - { - // 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 - { - auto const sndBal = sender->getFieldAmount(sfBalance); - view.creditHook(uSenderID, xrpAccount(), saAmount, sndBal); - - // Decrement XRP balance. - sender->setFieldAmount(sfBalance, sndBal - saAmount); - view.update(sender); - } - } - - if (tesSUCCESS == terResult && receiver) - { - // Increment XRP balance. - auto const rcvBal = receiver->getFieldAmount(sfBalance); - receiver->setFieldAmount(sfBalance, rcvBal + saAmount); - view.creditHook(xrpAccount(), uReceiverID, saAmount, -rcvBal); - - view.update(receiver); - } - - if (auto stream = j.trace()) - { - std::string sender_bal("-"); - std::string receiver_bal("-"); - - if (sender) - sender_bal = sender->getFieldAmount(sfBalance).getFullText(); - - if (receiver) - receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); - - stream << "accountSendIOU< " << to_string(uSenderID) << " (" << sender_bal << ") -> " - << to_string(uReceiverID) << " (" << receiver_bal - << ") : " << saAmount.getFullText(); - } - - return terResult; -} - -static TER -accountSendMultiIOU( - ApplyView& view, - AccountID const& senderID, - Issue const& issue, - MultiplePaymentDestinations const& receivers, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - XRPL_ASSERT_PARTS( - receivers.size() > 1, "xrpl::accountSendMultiIOU", "multiple recipients provided"); - - if (!issue.native()) - { - STAmount actual; - JLOG(j.trace()) << "accountSendMultiIOU: " << to_string(senderID) << " sending " - << receivers.size() << " IOUs"; - - return rippleSendMultiIOU(view, senderID, issue, receivers, actual, j, waiveFee); - } - - /* XRP send which does not check reserve and can do pure adjustment. - * Note that sender or receiver may be null and this not a mistake; this - * setup could be used during pathfinding and it is carefully controlled to - * ensure that transfers are balanced. - */ - - SLE::pointer sender = - senderID != beast::zero ? view.peek(keylet::account(senderID)) : SLE::pointer(); - - if (auto stream = j.trace()) - { - std::string sender_bal("-"); - - if (sender) - sender_bal = sender->getFieldAmount(sfBalance).getFullText(); - - stream << "accountSendMultiIOU> " << to_string(senderID) << " (" << sender_bal << ") -> " - << receivers.size() << " receivers."; - } - - // Failures return immediately. - STAmount takeFromSender{issue}; - for (auto const& r : receivers) - { - auto const& receiverID = r.first; - STAmount amount{issue, r.second}; - - if (amount < beast::zero) - { - return tecINTERNAL; // LCOV_EXCL_LINE - } - - /* If we aren't sending anything or if the sender is the same as the - * receiver then we don't need to do anything. - */ - if (!amount || (senderID == receiverID)) - continue; - - SLE::pointer receiver = - receiverID != beast::zero ? view.peek(keylet::account(receiverID)) : SLE::pointer(); - - if (auto stream = j.trace()) - { - std::string receiver_bal("-"); - - if (receiver) - receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); - - stream << "accountSendMultiIOU> " << to_string(senderID) << " -> " - << to_string(receiverID) << " (" << receiver_bal - << ") : " << amount.getFullText(); - } - - if (receiver) - { - // Increment XRP balance. - auto const rcvBal = receiver->getFieldAmount(sfBalance); - receiver->setFieldAmount(sfBalance, rcvBal + amount); - view.creditHook(xrpAccount(), receiverID, amount, -rcvBal); - - view.update(receiver); - - // Take what is actually sent - takeFromSender += amount; - } - - if (auto stream = j.trace()) - { - std::string receiver_bal("-"); - - if (receiver) - receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); - - stream << "accountSendMultiIOU< " << to_string(senderID) << " -> " - << to_string(receiverID) << " (" << receiver_bal - << ") : " << amount.getFullText(); - } - } - - if (sender) - { - if (sender->getFieldAmount(sfBalance) < takeFromSender) - { - return TER{tecFAILED_PROCESSING}; - } - - auto const sndBal = sender->getFieldAmount(sfBalance); - view.creditHook(senderID, xrpAccount(), takeFromSender, sndBal); - - // Decrement XRP balance. - sender->setFieldAmount(sfBalance, sndBal - takeFromSender); - view.update(sender); - } - - if (auto stream = j.trace()) - { - std::string sender_bal("-"); - - if (sender) - sender_bal = sender->getFieldAmount(sfBalance).getFullText(); - - stream << "accountSendMultiIOU< " << to_string(senderID) << " (" << sender_bal << ") -> " - << receivers.size() << " receivers."; - } - return tesSUCCESS; -} - -static TER -rippleCreditMPT( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - beast::Journal j) -{ - // Do not check MPT authorization here - it must have been checked earlier - auto const mptID = keylet::mptIssuance(saAmount.get().getMptID()); - auto const& issuer = saAmount.getIssuer(); - auto sleIssuance = view.peek(mptID); - if (!sleIssuance) - return tecOBJECT_NOT_FOUND; - if (uSenderID == issuer) - { - (*sleIssuance)[sfOutstandingAmount] += saAmount.mpt().value(); - view.update(sleIssuance); - } - else - { - auto const mptokenID = keylet::mptoken(mptID.key, uSenderID); - if (auto sle = view.peek(mptokenID)) - { - auto const amt = sle->getFieldU64(sfMPTAmount); - auto const pay = saAmount.mpt().value(); - if (amt < pay) - return tecINSUFFICIENT_FUNDS; - (*sle)[sfMPTAmount] = amt - pay; - view.update(sle); - } - else - { - return tecNO_AUTH; - } - } - - if (uReceiverID == issuer) - { - auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount); - auto const redeem = saAmount.mpt().value(); - if (outstanding >= redeem) - { - sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - redeem); - view.update(sleIssuance); - } - else - { - return tecINTERNAL; // LCOV_EXCL_LINE - } - } - else - { - auto const mptokenID = keylet::mptoken(mptID.key, uReceiverID); - if (auto sle = view.peek(mptokenID)) - { - (*sle)[sfMPTAmount] += saAmount.mpt().value(); - view.update(sle); - } - else - { - return tecNO_AUTH; - } - } - - return tesSUCCESS; -} - -static TER -rippleSendMPT( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - STAmount& saActual, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleSendMPT : sender is not receiver"); - - // Safe to get MPT since rippleSendMPT is only called by accountSendMPT - auto const& issuer = saAmount.getIssuer(); - - auto const sle = view.read(keylet::mptIssuance(saAmount.get().getMptID())); - if (!sle) - return tecOBJECT_NOT_FOUND; - - if (uSenderID == issuer || uReceiverID == issuer) - { - // if sender is issuer, check that the new OutstandingAmount will not - // exceed MaximumAmount - if (uSenderID == issuer) - { - auto const sendAmount = saAmount.mpt().value(); - auto const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount); - if (sendAmount > maximumAmount || - sle->getFieldU64(sfOutstandingAmount) > maximumAmount - sendAmount) - return tecPATH_DRY; - } - - // Direct send: redeeming MPTs and/or sending own MPTs. - auto const ter = rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j); - if (!isTesSuccess(ter)) - return ter; - saActual = saAmount; - return tesSUCCESS; - } - - // Sending 3rd party MPTs: transit. - saActual = (waiveFee == WaiveTransferFee::Yes) - ? saAmount - : multiply(saAmount, transferRate(view, saAmount.get().getMptID())); - - JLOG(j.debug()) << "rippleSendMPT> " << to_string(uSenderID) << " - > " - << to_string(uReceiverID) << " : deliver=" << saAmount.getFullText() - << " cost=" << saActual.getFullText(); - - if (auto const terResult = rippleCreditMPT(view, issuer, uReceiverID, saAmount, j); - !isTesSuccess(terResult)) - return terResult; - - return rippleCreditMPT(view, uSenderID, issuer, saActual, j); -} - -static TER -rippleSendMultiMPT( - ApplyView& view, - AccountID const& senderID, - MPTIssue const& mptIssue, - MultiplePaymentDestinations const& receivers, - STAmount& actual, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - // Safe to get MPT since rippleSendMultiMPT is only called by - // accountSendMultiMPT - auto const& issuer = mptIssue.getIssuer(); - - auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID())); - if (!sle) - return tecOBJECT_NOT_FOUND; - - // These may diverge - STAmount takeFromSender{mptIssue}; - actual = takeFromSender; - - for (auto const& r : receivers) - { - auto const& receiverID = r.first; - STAmount amount{mptIssue, r.second}; - - if (amount < beast::zero) - { - return tecINTERNAL; // LCOV_EXCL_LINE - } - - /* If we aren't sending anything or if the sender is the same as the - * receiver then we don't need to do anything. - */ - if (!amount || (senderID == receiverID)) - continue; - - if (senderID == issuer || receiverID == issuer) - { - // if sender is issuer, check that the new OutstandingAmount will - // not exceed MaximumAmount - if (senderID == issuer) - { - XRPL_ASSERT_PARTS( - takeFromSender == beast::zero, - "rippler::rippleSendMultiMPT", - "sender == issuer, takeFromSender == zero"); - auto const sendAmount = amount.mpt().value(); - auto const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount); - if (sendAmount > maximumAmount || - sle->getFieldU64(sfOutstandingAmount) > maximumAmount - sendAmount) - return tecPATH_DRY; - } - - // Direct send: redeeming MPTs and/or sending own MPTs. - if (auto const ter = rippleCreditMPT(view, senderID, receiverID, amount, j)) - return ter; - actual += amount; - // Do not add amount to takeFromSender, because rippleCreditMPT took - // it - - continue; - } - - // Sending 3rd party MPTs: transit. - STAmount actualSend = (waiveFee == WaiveTransferFee::Yes) - ? amount - : multiply(amount, transferRate(view, amount.get().getMptID())); - actual += actualSend; - takeFromSender += actualSend; - - JLOG(j.debug()) << "rippleSendMultiMPT> " << to_string(senderID) << " - > " - << to_string(receiverID) << " : deliver=" << amount.getFullText() - << " cost=" << actualSend.getFullText(); - - if (auto const terResult = rippleCreditMPT(view, issuer, receiverID, amount, j)) - return terResult; - } - if (senderID != issuer && takeFromSender) - { - if (TER const terResult = rippleCreditMPT(view, senderID, issuer, takeFromSender, j)) - return terResult; - } - - return tesSUCCESS; -} - -static TER -accountSendMPT( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - XRPL_ASSERT( - saAmount >= beast::zero && saAmount.holds(), - "xrpl::accountSendMPT : minimum amount and MPT"); - - /* If we aren't sending anything or if the sender is the same as the - * receiver then we don't need to do anything. - */ - if (!saAmount || (uSenderID == uReceiverID)) - return tesSUCCESS; - - STAmount saActual{saAmount.asset()}; - - return rippleSendMPT(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee); -} - -static TER -accountSendMultiMPT( - ApplyView& view, - AccountID const& senderID, - MPTIssue const& mptIssue, - MultiplePaymentDestinations const& receivers, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - STAmount actual; - - return rippleSendMultiMPT(view, senderID, mptIssue, receivers, actual, j, waiveFee); -} - -TER -accountSend( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - return std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - { - return accountSendIOU(view, uSenderID, uReceiverID, saAmount, j, waiveFee); - } - else - { - return accountSendMPT(view, uSenderID, uReceiverID, saAmount, j, waiveFee); - } - }, - saAmount.asset().value()); -} - -TER -accountSendMulti( - ApplyView& view, - AccountID const& senderID, - Asset const& asset, - MultiplePaymentDestinations const& receivers, - beast::Journal j, - WaiveTransferFee waiveFee) -{ - XRPL_ASSERT_PARTS( - receivers.size() > 1, "xrpl::accountSendMulti", "multiple recipients provided"); - return std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - { - return accountSendMultiIOU(view, senderID, issue, receivers, j, waiveFee); - } - else - { - return accountSendMultiMPT(view, senderID, issue, receivers, j, waiveFee); - } - }, - asset.value()); -} - -static bool -updateTrustLine( - ApplyView& view, - SLE::pointer state, - bool bSenderHigh, - AccountID const& sender, - STAmount const& before, - STAmount const& after, - beast::Journal j) -{ - if (!state) - return false; - std::uint32_t const flags(state->getFieldU32(sfFlags)); - - auto sle = view.peek(keylet::account(sender)); - if (!sle) - return false; - - // YYY Could skip this if rippling in reverse. - if (before > beast::zero - // Sender balance was positive. - && after <= beast::zero - // Sender is zero or negative. - && (flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) - // Sender reserve is set. - && static_cast(flags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) != - static_cast(sle->getFlags() & lsfDefaultRipple) && - !(flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) && - !state->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit) - // Sender trust limit is 0. - && !state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) - // Sender quality in is 0. - && !state->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut)) - // Sender quality out is 0. - { - // VFALCO Where is the line being deleted? - // Clear the reserve of the sender, possibly delete the line! - adjustOwnerCount(view, sle, -1, j); - - // Clear reserve flag. - state->setFieldU32(sfFlags, flags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve)); - - // Balance is zero, receiver reserve is clear. - if (!after // Balance is zero. - && !(flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve))) - return true; - } - return false; -} - -TER -issueIOU( - ApplyView& view, - AccountID const& account, - STAmount const& amount, - Issue const& issue, - beast::Journal j) -{ - XRPL_ASSERT( - !isXRP(account) && !isXRP(issue.account), - "xrpl::issueIOU : neither account nor issuer is XRP"); - - // Consistency check - XRPL_ASSERT(issue == amount.issue(), "xrpl::issueIOU : matching issue"); - - // Can't send to self! - XRPL_ASSERT(issue.account != account, "xrpl::issueIOU : not issuer account"); - - JLOG(j.trace()) << "issueIOU: " << to_string(account) << ": " << amount.getFullText(); - - bool bSenderHigh = issue.account > account; - - auto const index = keylet::line(issue.account, account, issue.currency); - - if (auto state = view.peek(index)) - { - STAmount final_balance = state->getFieldAmount(sfBalance); - - if (bSenderHigh) - final_balance.negate(); // Put balance in sender terms. - - STAmount const start_balance = final_balance; - - final_balance -= amount; - - auto const must_delete = updateTrustLine( - view, state, bSenderHigh, issue.account, start_balance, final_balance, j); - - view.creditHook(issue.account, account, amount, start_balance); - - if (bSenderHigh) - final_balance.negate(); - - // Adjust the balance on the trust line if necessary. We do this even if - // we are going to delete the line to reflect the correct balance at the - // time of deletion. - state->setFieldAmount(sfBalance, final_balance); - if (must_delete) - { - return trustDelete( - view, - state, - bSenderHigh ? account : issue.account, - bSenderHigh ? issue.account : account, - j); - } - - view.update(state); - - return tesSUCCESS; - } - - // NIKB TODO: The limit uses the receiver's account as the issuer and - // this is unnecessarily inefficient as copying which could be avoided - // is now required. Consider available options. - STAmount const limit(Issue{issue.currency, account}); - STAmount final_balance = amount; - - final_balance.setIssuer(noAccount()); - - auto const receiverAccount = view.peek(keylet::account(account)); - if (!receiverAccount) - return tefINTERNAL; // LCOV_EXCL_LINE - - bool noRipple = (receiverAccount->getFlags() & lsfDefaultRipple) == 0; - - return trustCreate( - view, - bSenderHigh, - issue.account, - account, - index.key, - receiverAccount, - false, - noRipple, - false, - false, - final_balance, - limit, - 0, - 0, - j); -} - -TER -redeemIOU( - ApplyView& view, - AccountID const& account, - STAmount const& amount, - Issue const& issue, - beast::Journal j) -{ - XRPL_ASSERT( - !isXRP(account) && !isXRP(issue.account), - "xrpl::redeemIOU : neither account nor issuer is XRP"); - - // Consistency check - XRPL_ASSERT(issue == amount.issue(), "xrpl::redeemIOU : matching issue"); - - // Can't send to self! - XRPL_ASSERT(issue.account != account, "xrpl::redeemIOU : not issuer account"); - - JLOG(j.trace()) << "redeemIOU: " << to_string(account) << ": " << amount.getFullText(); - - bool bSenderHigh = account > issue.account; - - if (auto state = view.peek(keylet::line(account, issue.account, issue.currency))) - { - STAmount final_balance = state->getFieldAmount(sfBalance); - - if (bSenderHigh) - final_balance.negate(); // Put balance in sender terms. - - STAmount const start_balance = final_balance; - - final_balance -= amount; - - auto const must_delete = - updateTrustLine(view, state, bSenderHigh, account, start_balance, final_balance, j); - - view.creditHook(account, issue.account, amount, start_balance); - - if (bSenderHigh) - final_balance.negate(); - - // Adjust the balance on the trust line if necessary. We do this even if - // we are going to delete the line to reflect the correct balance at the - // time of deletion. - state->setFieldAmount(sfBalance, final_balance); - - if (must_delete) - { - return trustDelete( - view, - state, - bSenderHigh ? issue.account : account, - bSenderHigh ? account : issue.account, - j); - } - - view.update(state); - return tesSUCCESS; - } - - // 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 -transferXRP( - ApplyView& view, - AccountID const& from, - AccountID const& to, - STAmount const& amount, - beast::Journal j) -{ - XRPL_ASSERT(from != beast::zero, "xrpl::transferXRP : nonzero from account"); - XRPL_ASSERT(to != beast::zero, "xrpl::transferXRP : nonzero to account"); - XRPL_ASSERT(from != to, "xrpl::transferXRP : sender is not receiver"); - XRPL_ASSERT(amount.native(), "xrpl::transferXRP : amount is XRP"); - - SLE::pointer const sender = view.peek(keylet::account(from)); - SLE::pointer const receiver = view.peek(keylet::account(to)); - if (!sender || !receiver) - return tefINTERNAL; // LCOV_EXCL_LINE - - JLOG(j.trace()) << "transferXRP: " << to_string(from) << " -> " << to_string(to) - << ") : " << amount.getFullText(); - - if (sender->getFieldAmount(sfBalance) < amount) - { - // 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. - sender->setFieldAmount(sfBalance, sender->getFieldAmount(sfBalance) - amount); - view.update(sender); - - receiver->setFieldAmount(sfBalance, receiver->getFieldAmount(sfBalance) + amount); - view.update(receiver); - - return tesSUCCESS; -} - -TER -requireAuth(ReadView const& view, Issue const& issue, AccountID const& account, AuthType authType) -{ - if (isXRP(issue) || issue.account == account) - return tesSUCCESS; - - auto const trustLine = view.read(keylet::line(account, issue.account, issue.currency)); - // If account has no line, and this is a strong check, fail - if (!trustLine && authType == AuthType::StrongAuth) - return tecNO_LINE; - - // If this is a weak or legacy check, or if the account has a line, fail if - // auth is required and not set on the line - if (auto const issuerAccount = view.read(keylet::account(issue.account)); - issuerAccount && (*issuerAccount)[sfFlags] & lsfRequireAuth) - { - if (trustLine) - { - return ((*trustLine)[sfFlags] & ((account > issue.account) ? lsfLowAuth : lsfHighAuth)) - ? tesSUCCESS - : TER{tecNO_AUTH}; - } - return TER{tecNO_LINE}; - } - - return tesSUCCESS; -} - -TER -requireAuth( - ReadView const& view, - MPTIssue const& mptIssue, - AccountID const& account, - AuthType authType, - int depth) -{ - auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); - auto const sleIssuance = view.read(mptID); - if (!sleIssuance) - return tecOBJECT_NOT_FOUND; - - auto const mptIssuer = sleIssuance->getAccountID(sfIssuer); - - // issuer is always "authorized" - if (mptIssuer == account) // Issuer won't have MPToken - return tesSUCCESS; - - bool const featureSAVEnabled = view.rules().enabled(featureSingleAssetVault); - - if (featureSAVEnabled) - { - if (depth >= maxAssetCheckDepth) - return tecINTERNAL; // LCOV_EXCL_LINE - - // requireAuth is recursive if the issuer is a vault pseudo-account - auto const sleIssuer = view.read(keylet::account(mptIssuer)); - if (!sleIssuer) - return tefINTERNAL; // LCOV_EXCL_LINE - - if (sleIssuer->isFieldPresent(sfVaultID)) - { - auto const sleVault = view.read(keylet::vault(sleIssuer->getFieldH256(sfVaultID))); - if (!sleVault) - return tefINTERNAL; // LCOV_EXCL_LINE - - auto const asset = sleVault->at(sfAsset); - if (auto const err = std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - { - return requireAuth(view, issue, account, authType); - } - else - { - return requireAuth(view, issue, account, authType, depth + 1); - } - }, - asset.value()); - !isTesSuccess(err)) - return err; - } - } - - auto const mptokenID = keylet::mptoken(mptID.key, account); - auto const sleToken = view.read(mptokenID); - - // if account has no MPToken, fail - if (!sleToken && (authType == AuthType::StrongAuth || authType == AuthType::Legacy)) - return tecNO_AUTH; - - // Note, this check is not amendment-gated because DomainID will be always - // empty **unless** writing to it has been enabled by an amendment - auto const maybeDomainID = sleIssuance->at(~sfDomainID); - if (maybeDomainID) - { - XRPL_ASSERT( - sleIssuance->getFieldU32(sfFlags) & lsfMPTRequireAuth, - "xrpl::requireAuth : issuance requires authorization"); - // ter = tefINTERNAL | tecOBJECT_NOT_FOUND | tecNO_AUTH | tecEXPIRED - auto const ter = credentials::validDomain(view, *maybeDomainID, account); - if (isTesSuccess(ter)) - { - return ter; // Note: sleToken might be null - } - if (!sleToken) - { - return ter; - } - // We ignore error from validDomain if we found sleToken, as it could - // belong to someone who is explicitly authorized e.g. a vault owner. - } - - if (featureSAVEnabled) - { - // Implicitly authorize Vault and LoanBroker pseudo-accounts - if (isPseudoAccount(view, account, {&sfVaultID, &sfLoanBrokerID})) - return tesSUCCESS; - } - - // mptoken must be authorized if issuance enabled requireAuth - if (sleIssuance->isFlag(lsfMPTRequireAuth) && - (!sleToken || !sleToken->isFlag(lsfMPTAuthorized))) - return tecNO_AUTH; - - return tesSUCCESS; // Note: sleToken might be null -} - -[[nodiscard]] TER -enforceMPTokenAuthorization( - ApplyView& view, - MPTID const& mptIssuanceID, - AccountID const& account, - XRPAmount const& priorBalance, // for MPToken authorization - beast::Journal j) -{ - auto const sleIssuance = view.read(keylet::mptIssuance(mptIssuanceID)); - if (!sleIssuance) - return tefINTERNAL; // LCOV_EXCL_LINE - - XRPL_ASSERT( - sleIssuance->isFlag(lsfMPTRequireAuth), - "xrpl::enforceMPTokenAuthorization : authorization required"); - - if (account == sleIssuance->at(sfIssuer)) - return tefINTERNAL; // LCOV_EXCL_LINE - - auto const keylet = keylet::mptoken(mptIssuanceID, account); - auto const sleToken = view.read(keylet); // NOTE: might be null - auto const maybeDomainID = sleIssuance->at(~sfDomainID); - bool expired = false; - bool const authorizedByDomain = [&]() -> bool { - // NOTE: defensive here, should be checked in preclaim - if (!maybeDomainID.has_value()) - return false; // LCOV_EXCL_LINE - - auto const ter = verifyValidDomain(view, account, *maybeDomainID, j); - if (isTesSuccess(ter)) - return true; - if (ter == tecEXPIRED) - expired = true; - return false; - }(); - - if (!authorizedByDomain && sleToken == nullptr) - { - // Could not find MPToken and won't create one, could be either of: - // - // 1. Field sfDomainID not set in MPTokenIssuance or - // 2. Account has no matching and accepted credentials or - // 3. Account has all expired credentials (deleted in verifyValidDomain) - // - // Either way, return tecNO_AUTH and there is nothing else to do - return expired ? tecEXPIRED : tecNO_AUTH; - } - if (!authorizedByDomain && maybeDomainID.has_value()) - { - // Found an MPToken but the account is not authorized and we expect - // it to have been authorized by the domain. This could be because the - // credentials used to create the MPToken have expired or been deleted. - return expired ? tecEXPIRED : tecNO_AUTH; - } - if (!authorizedByDomain) - { - // We found an MPToken, but sfDomainID is not set, so this is a classic - // MPToken which requires authorization by the token issuer. - XRPL_ASSERT( - sleToken != nullptr && !maybeDomainID.has_value(), - "xrpl::enforceMPTokenAuthorization : found MPToken"); - if (sleToken->isFlag(lsfMPTAuthorized)) - return tesSUCCESS; - - return tecNO_AUTH; - } - if (authorizedByDomain && sleToken != nullptr) - { - // Found an MPToken, authorized by the domain. Ignore authorization flag - // lsfMPTAuthorized because it is meaningless. Return tesSUCCESS - XRPL_ASSERT( - maybeDomainID.has_value(), - "xrpl::enforceMPTokenAuthorization : found MPToken for domain"); - return tesSUCCESS; - } - if (authorizedByDomain) - { - // Could not find MPToken but there should be one because we are - // authorized by domain. Proceed to create it, then return tesSUCCESS - XRPL_ASSERT( - maybeDomainID.has_value() && sleToken == nullptr, - "xrpl::enforceMPTokenAuthorization : new MPToken for domain"); - if (auto const err = authorizeMPToken( - view, - priorBalance, // priorBalance - mptIssuanceID, // mptIssuanceID - account, // account - j); - !isTesSuccess(err)) - return err; - - return tesSUCCESS; - } - - // LCOV_EXCL_START - UNREACHABLE("xrpl::enforceMPTokenAuthorization : condition list is incomplete"); - return tefINTERNAL; - // LCOV_EXCL_STOP -} - -TER -canTransfer( - ReadView const& view, - MPTIssue const& mptIssue, - AccountID const& from, - AccountID const& to) -{ - auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); - auto const sleIssuance = view.read(mptID); - if (!sleIssuance) - return tecOBJECT_NOT_FOUND; - - if (!(sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer)) - { - if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer]) - return TER{tecNO_AUTH}; - } - return tesSUCCESS; -} - -[[nodiscard]] TER -canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, AccountID const& to) -{ - if (issue.native()) - return tesSUCCESS; - - auto const& issuerId = issue.getIssuer(); - if (issuerId == from || issuerId == to) - return tesSUCCESS; - auto const sleIssuer = view.read(keylet::account(issuerId)); - if (sleIssuer == nullptr) - return tefINTERNAL; // LCOV_EXCL_LINE - - auto const isRippleDisabled = [&](AccountID account) -> bool { - // Line might not exist, but some transfers can create it. If this - // is the case, just check the default ripple on the issuer account. - auto const line = view.read(keylet::line(account, issue)); - if (line) - { - bool const issuerHigh = issuerId > account; - return line->isFlag(issuerHigh ? lsfHighNoRipple : lsfLowNoRipple); - } - return sleIssuer->isFlag(lsfDefaultRipple) == false; - }; - - // Fail if rippling disabled on both trust lines - if (isRippleDisabled(from) && isRippleDisabled(to)) - return terNO_RIPPLE; - - return tesSUCCESS; -} - TER cleanupOnAccountDelete( ApplyView& view, @@ -3234,7 +469,7 @@ cleanupOnAccountDelete( { // Directory node has an invalid index. Bail out. // LCOV_EXCL_START - JLOG(j.fatal()) << "AccountDelete: Directory node in ledger " << view.seq() + 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 @@ -3269,7 +504,7 @@ cleanupOnAccountDelete( if (uDirEntry == 0) { // LCOV_EXCL_START - JLOG(j.error()) << "AccountDelete iterator re-validation failed."; + JLOG(j.error()) << "DeleteAccount iterator re-validation failed."; return tefBAD_LEDGER; // LCOV_EXCL_STOP } @@ -3282,447 +517,6 @@ cleanupOnAccountDelete( return tesSUCCESS; } -TER -deleteAMMTrustLine( - ApplyView& view, - std::shared_ptr sleState, - std::optional const& ammAccountID, - beast::Journal j) -{ - if (!sleState || sleState->getType() != ltRIPPLE_STATE) - return tecINTERNAL; // LCOV_EXCL_LINE - - auto const& [low, high] = std::minmax( - sleState->getFieldAmount(sfLowLimit).getIssuer(), - sleState->getFieldAmount(sfHighLimit).getIssuer()); - auto sleLow = view.peek(keylet::account(low)); - auto sleHigh = view.peek(keylet::account(high)); - if (!sleLow || !sleHigh) - 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; // LCOV_EXCL_LINE - - // at least one must be - if (!ammLow && !ammHigh) - return terNO_AMM; - - // one must be the target amm - if (ammAccountID && (low != *ammAccountID && high != *ammAccountID)) - return terNO_AMM; - - if (auto const ter = trustDelete(view, sleState, low, high, j); !isTesSuccess(ter)) - { - JLOG(j.error()) << "deleteAMMTrustLine: failed to delete the trustline."; - return ter; - } - - auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve; - if (!(sleState->getFlags() & uFlags)) - return tecINTERNAL; // LCOV_EXCL_LINE - - adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j); - - return tesSUCCESS; -} - -TER -rippleCredit( - ApplyView& view, - AccountID const& uSenderID, - AccountID const& uReceiverID, - STAmount const& saAmount, - bool bCheckIssuer, - beast::Journal j) -{ - return std::visit( - [&](TIss const& issue) { - if constexpr (std::is_same_v) - { - return rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, bCheckIssuer, j); - } - else - { - XRPL_ASSERT(!bCheckIssuer, "xrpl::rippleCredit : not checking issuer"); - return rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j); - } - }, - saAmount.asset().value()); -} - -[[nodiscard]] std::optional -assetsToSharesDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets) -{ - XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); - XRPL_ASSERT( - assets.asset() == vault->at(sfAsset), - "xrpl::assetsToSharesDeposit : assets and vault match"); - if (assets.negative() || assets.asset() != vault->at(sfAsset)) - return std::nullopt; // LCOV_EXCL_LINE - - Number const assetTotal = vault->at(sfAssetsTotal); - STAmount shares{vault->at(sfShareMPTID)}; - if (assetTotal == 0) - { - return STAmount{ - shares.asset(), - Number(assets.mantissa(), assets.exponent() + vault->at(sfScale)).truncate()}; - } - - Number const shareTotal = issuance->at(sfOutstandingAmount); - shares = ((shareTotal * assets) / assetTotal).truncate(); - return shares; -} - -[[nodiscard]] std::optional -sharesToAssetsDeposit( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares) -{ - XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); - XRPL_ASSERT( - shares.asset() == vault->at(sfShareMPTID), - "xrpl::sharesToAssetsDeposit : shares and vault match"); - if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) - return std::nullopt; // LCOV_EXCL_LINE - - Number const assetTotal = vault->at(sfAssetsTotal); - STAmount assets{vault->at(sfAsset)}; - if (assetTotal == 0) - { - return STAmount{ - assets.asset(), shares.mantissa(), shares.exponent() - vault->at(sfScale), false}; - } - - Number const shareTotal = issuance->at(sfOutstandingAmount); - assets = (assetTotal * shares) / shareTotal; - return assets; -} - -[[nodiscard]] std::optional -assetsToSharesWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& assets, - TruncateShares truncate) -{ - XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); - XRPL_ASSERT( - assets.asset() == vault->at(sfAsset), - "xrpl::assetsToSharesWithdraw : assets and vault match"); - if (assets.negative() || assets.asset() != vault->at(sfAsset)) - return std::nullopt; // LCOV_EXCL_LINE - - Number assetTotal = vault->at(sfAssetsTotal); - assetTotal -= vault->at(sfLossUnrealized); - STAmount shares{vault->at(sfShareMPTID)}; - if (assetTotal == 0) - return shares; - Number const shareTotal = issuance->at(sfOutstandingAmount); - Number result = (shareTotal * assets) / assetTotal; - if (truncate == TruncateShares::yes) - result = result.truncate(); - shares = result; - return shares; -} - -[[nodiscard]] std::optional -sharesToAssetsWithdraw( - std::shared_ptr const& vault, - std::shared_ptr const& issuance, - STAmount const& shares) -{ - XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); - XRPL_ASSERT( - shares.asset() == vault->at(sfShareMPTID), - "xrpl::sharesToAssetsWithdraw : shares and vault match"); - if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) - return std::nullopt; // LCOV_EXCL_LINE - - Number assetTotal = vault->at(sfAssetsTotal); - assetTotal -= vault->at(sfLossUnrealized); - STAmount assets{vault->at(sfAsset)}; - if (assetTotal == 0) - return assets; - Number const shareTotal = issuance->at(sfOutstandingAmount); - assets = (assetTotal * shares) / shareTotal; - return assets; -} - -TER -rippleLockEscrowMPT( - ApplyView& view, - AccountID const& sender, - STAmount const& amount, - beast::Journal j) -{ - auto const mptIssue = amount.get(); - auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); - auto sleIssuance = view.peek(mptID); - if (!sleIssuance) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleLockEscrowMPT: MPT issuance not found for " - << mptIssue.getMptID(); - return tecOBJECT_NOT_FOUND; - } // LCOV_EXCL_STOP - - if (amount.getIssuer() == sender) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleLockEscrowMPT: sender is the issuer, cannot lock MPTs."; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - // 1. Decrease the MPT Holder MPTAmount - // 2. Increase the MPT Holder EscrowedAmount - { - auto const mptokenID = keylet::mptoken(mptID.key, sender); - auto sle = view.peek(mptokenID); - if (!sle) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleLockEscrowMPT: MPToken not found for " << sender; - return tecOBJECT_NOT_FOUND; - } // LCOV_EXCL_STOP - - auto const amt = sle->getFieldU64(sfMPTAmount); - auto const pay = amount.mpt().value(); - - // Underflow check for subtraction - if (!canSubtract(STAmount(mptIssue, amt), STAmount(mptIssue, pay))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleLockEscrowMPT: insufficient MPTAmount for " - << to_string(sender) << ": " << amt << " < " << pay; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - (*sle)[sfMPTAmount] = amt - pay; - - // Overflow check for addition - uint64_t const locked = (*sle)[~sfLockedAmount].value_or(0); - - if (!canAdd(STAmount(mptIssue, locked), STAmount(mptIssue, pay))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleLockEscrowMPT: overflow on locked amount for " - << to_string(sender) << ": " << locked << " + " << pay; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - if (sle->isFieldPresent(sfLockedAmount)) - { - (*sle)[sfLockedAmount] += pay; - } - else - { - sle->setFieldU64(sfLockedAmount, pay); - } - - view.update(sle); - } - - // 1. Increase the Issuance EscrowedAmount - // 2. DO NOT change the Issuance OutstandingAmount - { - uint64_t const issuanceEscrowed = (*sleIssuance)[~sfLockedAmount].value_or(0); - auto const pay = amount.mpt().value(); - - // Overflow check for addition - if (!canAdd(STAmount(mptIssue, issuanceEscrowed), STAmount(mptIssue, pay))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleLockEscrowMPT: overflow on issuance " - "locked amount for " - << mptIssue.getMptID() << ": " << issuanceEscrowed << " + " << pay; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - if (sleIssuance->isFieldPresent(sfLockedAmount)) - { - (*sleIssuance)[sfLockedAmount] += pay; - } - else - { - sleIssuance->setFieldU64(sfLockedAmount, pay); - } - - view.update(sleIssuance); - } - return tesSUCCESS; -} - -TER -rippleUnlockEscrowMPT( - ApplyView& view, - AccountID const& sender, - AccountID const& receiver, - STAmount const& netAmount, - STAmount const& grossAmount, - beast::Journal j) -{ - if (!view.rules().enabled(fixTokenEscrowV1)) - { - XRPL_ASSERT( - netAmount == grossAmount, "xrpl::rippleUnlockEscrowMPT : netAmount == grossAmount"); - } - - auto const& issuer = netAmount.getIssuer(); - auto const& mptIssue = netAmount.get(); - auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); - auto sleIssuance = view.peek(mptID); - if (!sleIssuance) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: MPT issuance not found for " - << mptIssue.getMptID(); - return tecOBJECT_NOT_FOUND; - } // LCOV_EXCL_STOP - - // Decrease the Issuance EscrowedAmount - { - if (!sleIssuance->isFieldPresent(sfLockedAmount)) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in issuance for " - << mptIssue.getMptID(); - return tecINTERNAL; - } // LCOV_EXCL_STOP - - auto const locked = sleIssuance->getFieldU64(sfLockedAmount); - auto const redeem = grossAmount.mpt().value(); - - // Underflow check for subtraction - if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, redeem))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for " - << mptIssue.getMptID() << ": " << locked << " < " << redeem; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - auto const newLocked = locked - redeem; - if (newLocked == 0) - { - sleIssuance->makeFieldAbsent(sfLockedAmount); - } - else - { - sleIssuance->setFieldU64(sfLockedAmount, newLocked); - } - view.update(sleIssuance); - } - - if (issuer != receiver) - { - // Increase the MPT Holder MPTAmount - auto const mptokenID = keylet::mptoken(mptID.key, receiver); - auto sle = view.peek(mptokenID); - if (!sle) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << receiver; - return tecOBJECT_NOT_FOUND; - } // LCOV_EXCL_STOP - - auto current = sle->getFieldU64(sfMPTAmount); - auto delta = netAmount.mpt().value(); - - // Overflow check for addition - if (!canAdd(STAmount(mptIssue, current), STAmount(mptIssue, delta))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: overflow on MPTAmount for " - << to_string(receiver) << ": " << current << " + " << delta; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - (*sle)[sfMPTAmount] += delta; - view.update(sle); - } - else - { - // Decrease the Issuance OutstandingAmount - auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount); - auto const redeem = netAmount.mpt().value(); - - // Underflow check for subtraction - if (!canSubtract(STAmount(mptIssue, outstanding), STAmount(mptIssue, redeem))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient outstanding amount for " - << mptIssue.getMptID() << ": " << outstanding << " < " << redeem; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - redeem); - view.update(sleIssuance); - } - - if (issuer == sender) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: sender is the issuer, " - "cannot unlock MPTs."; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - // Decrease the MPT Holder EscrowedAmount - auto const mptokenID = keylet::mptoken(mptID.key, sender); - auto sle = view.peek(mptokenID); - if (!sle) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << sender; - return tecOBJECT_NOT_FOUND; - } // LCOV_EXCL_STOP - - if (!sle->isFieldPresent(sfLockedAmount)) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in MPToken for " - << to_string(sender); - return tecINTERNAL; - } // LCOV_EXCL_STOP - - auto const locked = sle->getFieldU64(sfLockedAmount); - auto const delta = grossAmount.mpt().value(); - - // Underflow check for subtraction - if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, delta))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for " - << to_string(sender) << ": " << locked << " < " << delta; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - auto const newLocked = locked - delta; - if (newLocked == 0) - { - sle->makeFieldAbsent(sfLockedAmount); - } - else - { - sle->setFieldU64(sfLockedAmount, newLocked); - } - view.update(sle); - - // Note: The gross amount is the amount that was locked, the net - // amount is the amount that is being unlocked. The difference is the fee - // that was charged for the transfer. If this difference is greater than - // zero, we need to update the outstanding amount. - auto const diff = grossAmount.mpt().value() - netAmount.mpt().value(); - if (diff != 0) - { - auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount); - // Underflow check for subtraction - if (!canSubtract(STAmount(mptIssue, outstanding), STAmount(mptIssue, diff))) - { // LCOV_EXCL_START - JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient outstanding amount for " - << mptIssue.getMptID() << ": " << outstanding << " < " << diff; - return tecINTERNAL; - } // LCOV_EXCL_STOP - - sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - diff); - view.update(sleIssuance); - } - return tesSUCCESS; -} - bool after(NetClock::time_point now, std::uint32_t mark) { diff --git a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp new file mode 100644 index 0000000000..399494bc5f --- /dev/null +++ b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp @@ -0,0 +1,247 @@ +#include +// +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl { + +bool +isGlobalFrozen(ReadView const& view, AccountID const& issuer) +{ + if (isXRP(issuer)) + return false; + if (auto const sle = view.read(keylet::account(issuer))) + return sle->isFlag(lsfGlobalFreeze); + return false; +} + +// An owner count cannot be negative. If adjustment would cause a negative +// owner count, clamp the owner count at 0. Similarly for overflow. This +// adjustment allows the ownerCount to be adjusted up or down in multiple steps. +// If id != std::nullopt, then do error reporting. +// +// Returns adjusted owner count. +static std::uint32_t +confineOwnerCount( + std::uint32_t current, + std::int32_t adjustment, + std::optional const& id = std::nullopt, + beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) +{ + std::uint32_t adjusted{current + adjustment}; + if (adjustment > 0) + { + // Overflow is well defined on unsigned + if (adjusted < current) + { + if (id) + { + JLOG(j.fatal()) << "Account " << *id << " owner count exceeds max!"; + } + adjusted = std::numeric_limits::max(); + } + } + else + { + // Underflow is well defined on unsigned + if (adjusted > current) + { + if (id) + { + JLOG(j.fatal()) << "Account " << *id << " owner count set below 0!"; + } + adjusted = 0; + XRPL_ASSERT(!id, "xrpl::confineOwnerCount : id is not set"); + } + } + return adjusted; +} + +XRPAmount +xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j) +{ + auto const sle = view.read(keylet::account(id)); + if (sle == nullptr) + return beast::zero; + + // Return balance minus reserve + std::uint32_t const ownerCount = + confineOwnerCount(view.ownerCountHook(id, sle->getFieldU32(sfOwnerCount)), ownerCountAdj); + + // Pseudo-accounts have no reserve requirement + auto const reserve = + isPseudoAccount(sle) ? XRPAmount{0} : view.fees().accountReserve(ownerCount); + + auto const fullBalance = sle->getFieldAmount(sfBalance); + + auto const balance = view.balanceHook(id, xrpAccount(), fullBalance); + + STAmount const amount = (balance < reserve) ? STAmount{0} : balance - reserve; + + JLOG(j.trace()) << "accountHolds:" << " account=" << to_string(id) + << " amount=" << amount.getFullText() + << " fullBalance=" << fullBalance.getFullText() + << " balance=" << balance.getFullText() << " reserve=" << reserve + << " ownerCount=" << ownerCount << " ownerCountAdj=" << ownerCountAdj; + + return amount.xrp(); +} + +Rate +transferRate(ReadView const& view, AccountID const& issuer) +{ + auto const sle = view.read(keylet::account(issuer)); + + if (sle && sle->isFieldPresent(sfTransferRate)) + return Rate{sle->getFieldU32(sfTransferRate)}; + + return parityRate; +} + +void +adjustOwnerCount( + ApplyView& view, + std::shared_ptr const& sle, + std::int32_t amount, + beast::Journal j) +{ + if (!sle) + return; + XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input"); + std::uint32_t const current{sle->getFieldU32(sfOwnerCount)}; + AccountID const id = (*sle)[sfAccount]; + std::uint32_t const adjusted = confineOwnerCount(current, amount, id, j); + view.adjustOwnerCountHook(id, current, adjusted); + sle->at(sfOwnerCount) = adjusted; + view.update(sle); +} + +AccountID +pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey) +{ + // This number must not be changed without an amendment + constexpr std::uint16_t maxAccountAttempts = 256; + for (std::uint16_t i = 0; i < maxAccountAttempts; ++i) + { + ripesha_hasher rsh; + auto const hash = sha512Half(i, view.header().parentHash, pseudoOwnerKey); + rsh(hash.data(), hash.size()); + AccountID const ret{static_cast(rsh)}; + if (!view.read(keylet::account(ret))) + return ret; + } + return beast::zero; +} + +// Pseudo-account designator fields MUST be maintained by including the +// SField::sMD_PseudoAccount flag in the SField definition. (Don't forget to +// "| SField::sMD_Default"!) The fields do NOT need to be amendment-gated, +// since a non-active amendment will not set any field, by definition. +// Specific properties of a pseudo-account are NOT checked here, that's what +// InvariantCheck is for. +[[nodiscard]] std::vector const& +getPseudoAccountFields() +{ + static std::vector const pseudoFields = []() { + auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT); + if (!ar) + { + // LCOV_EXCL_START + LogicError( + "xrpl::getPseudoAccountFields : unable to find account root " + "ledger format"); + // LCOV_EXCL_STOP + } + auto const& soTemplate = ar->getSOTemplate(); + + std::vector pseudoFields; + for (auto const& field : soTemplate) + { + if (field.sField().shouldMeta(SField::sMD_PseudoAccount)) + pseudoFields.emplace_back(&field.sField()); + } + return pseudoFields; + }(); + return pseudoFields; +} + +[[nodiscard]] bool +isPseudoAccount( + std::shared_ptr sleAcct, + std::set const& pseudoFieldFilter) +{ + auto const& fields = getPseudoAccountFields(); + + // Intentionally use defensive coding here because it's cheap and makes the + // semantics of true return value clean. + return sleAcct && sleAcct->getType() == ltACCOUNT_ROOT && + std::count_if( + fields.begin(), fields.end(), [&sleAcct, &pseudoFieldFilter](SField const* sf) -> bool { + return sleAcct->isFieldPresent(*sf) && + (pseudoFieldFilter.empty() || pseudoFieldFilter.contains(sf)); + }) > 0; +} + +Expected, TER> +createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField) +{ + [[maybe_unused]] + auto const& fields = getPseudoAccountFields(); + XRPL_ASSERT( + std::count_if( + fields.begin(), + fields.end(), + [&ownerField](SField const* sf) -> bool { return *sf == ownerField; }) == 1, + "xrpl::createPseudoAccount : valid owner field"); + + auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey); + if (accountId == beast::zero) + return Unexpected(tecDUPLICATE); + + // Create pseudo-account. + auto account = std::make_shared(keylet::account(accountId)); + account->setAccountID(sfAccount, accountId); + account->setFieldAmount(sfBalance, STAmount{}); + + // Pseudo-accounts can't submit transactions, so set the sequence number + // to 0 to make them easier to spot and verify, and add an extra level + // of protection. + std::uint32_t const seqno = // + view.rules().enabled(featureSingleAssetVault) || // + view.rules().enabled(featureLendingProtocol) // + ? 0 // + : view.seq(); + account->setFieldU32(sfSequence, seqno); + // Ignore reserves requirement, disable the master key, allow default + // rippling, and enable deposit authorization to prevent payments into + // pseudo-account. + account->setFieldU32(sfFlags, lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth); + // Link the pseudo-account with its owner object. + account->setFieldH256(ownerField, pseudoOwnerKey); + + view.insert(account); + + return account; +} + +[[nodiscard]] TER +checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag) +{ + if (toSle == nullptr) + return tecNO_DST; + + // The tag is basically account-specific information we don't + // understand, but we can require someone to fill it in. + if (toSle->isFlag(lsfRequireDestTag) && !hasDestinationTag) + return tecDST_TAG_NEEDED; // Cannot send without a tag + + return tesSUCCESS; +} + +} // namespace xrpl diff --git a/src/libxrpl/ledger/CredentialHelpers.cpp b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp similarity index 99% rename from src/libxrpl/ledger/CredentialHelpers.cpp rename to src/libxrpl/ledger/helpers/CredentialHelpers.cpp index 0782eda67d..234ca7ea17 100644 --- a/src/libxrpl/ledger/CredentialHelpers.cpp +++ b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp @@ -1,5 +1,7 @@ -#include +#include +// #include +#include #include #include diff --git a/src/libxrpl/ledger/helpers/DirectoryHelpers.cpp b/src/libxrpl/ledger/helpers/DirectoryHelpers.cpp new file mode 100644 index 0000000000..f0ca83f2cd --- /dev/null +++ b/src/libxrpl/ledger/helpers/DirectoryHelpers.cpp @@ -0,0 +1,177 @@ +#include +// +#include + +namespace xrpl { + +bool +dirFirst( + ApplyView& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry) +{ + return detail::internalDirFirst(view, root, page, index, entry); +} + +bool +dirNext( + ApplyView& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry) +{ + return detail::internalDirNext(view, root, page, index, entry); +} + +bool +cdirFirst( + ReadView const& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry) +{ + return detail::internalDirFirst(view, root, page, index, entry); +} + +bool +cdirNext( + ReadView const& view, + uint256 const& root, + std::shared_ptr& page, + unsigned int& index, + uint256& entry) +{ + return detail::internalDirNext(view, root, page, index, entry); +} + +void +forEachItem( + ReadView const& view, + Keylet const& root, + std::function const&)> const& f) +{ + XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItem : valid root type"); + + if (root.type != ltDIR_NODE) + return; + + auto pos = root; + + while (true) + { + auto sle = view.read(pos); + if (!sle) + return; + for (auto const& key : sle->getFieldV256(sfIndexes)) + f(view.read(keylet::child(key))); + auto const next = sle->getFieldU64(sfIndexNext); + if (!next) + return; + pos = keylet::page(root, next); + } +} + +bool +forEachItemAfter( + ReadView const& view, + Keylet const& root, + uint256 const& after, + std::uint64_t const hint, + unsigned int limit, + std::function const&)> const& f) +{ + XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItemAfter : valid root type"); + + if (root.type != ltDIR_NODE) + return false; + + auto currentIndex = root; + + // If startAfter is not zero try jumping to that page using the hint + if (after.isNonZero()) + { + auto const hintIndex = keylet::page(root, hint); + + if (auto hintDir = view.read(hintIndex)) + { + for (auto const& key : hintDir->getFieldV256(sfIndexes)) + { + if (key == after) + { + // We found the hint, we can start here + currentIndex = hintIndex; + break; + } + } + } + + bool found = false; + for (;;) + { + auto const ownerDir = view.read(currentIndex); + if (!ownerDir) + return found; + for (auto const& key : ownerDir->getFieldV256(sfIndexes)) + { + if (!found) + { + if (key == after) + found = true; + } + else if (f(view.read(keylet::child(key))) && limit-- <= 1) + { + return found; + } + } + + auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext); + if (uNodeNext == 0) + return found; + currentIndex = keylet::page(root, uNodeNext); + } + } + else + { + for (;;) + { + auto const ownerDir = view.read(currentIndex); + if (!ownerDir) + return true; + for (auto const& key : ownerDir->getFieldV256(sfIndexes)) + { + if (f(view.read(keylet::child(key))) && limit-- <= 1) + return true; + } + auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext); + if (uNodeNext == 0) + return true; + currentIndex = keylet::page(root, uNodeNext); + } + } +} + +bool +dirIsEmpty(ReadView const& view, Keylet const& k) +{ + auto const sleNode = view.read(k); + if (!sleNode) + return true; + if (!sleNode->getFieldV256(sfIndexes).empty()) + return false; + // The first page of a directory may legitimately be empty even if there + // are other pages (the first page is the anchor page) so check to see if + // there is another page. If there is, the directory isn't empty. + return sleNode->getFieldU64(sfIndexNext) == 0; +} + +std::function +describeOwnerDir(AccountID const& account) +{ + return [account](std::shared_ptr const& sle) { (*sle)[sfOwner] = account; }; +} + +} // namespace xrpl diff --git a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp new file mode 100644 index 0000000000..cbf37a06a8 --- /dev/null +++ b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp @@ -0,0 +1,766 @@ +#include +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xrpl { + +// Forward declarations for functions that remain in View.h/cpp +bool +isVaultPseudoAccountFrozen( + ReadView const& view, + AccountID const& account, + MPTIssue const& mptShare, + int depth); + +[[nodiscard]] TER +dirLink( + ApplyView& view, + AccountID const& owner, + std::shared_ptr& object, + SF_UINT64 const& node = sfOwnerNode); + +bool +isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue) +{ + if (auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID()))) + return sle->isFlag(lsfMPTLocked); + return false; +} + +bool +isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) +{ + if (auto const sle = view.read(keylet::mptoken(mptIssue.getMptID(), account))) + return sle->isFlag(lsfMPTLocked); + return false; +} + +bool +isFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth) +{ + return isGlobalFrozen(view, mptIssue) || isIndividualFrozen(view, account, mptIssue) || + isVaultPseudoAccountFrozen(view, account, mptIssue, depth); +} + +[[nodiscard]] bool +isAnyFrozen( + ReadView const& view, + std::initializer_list const& accounts, + MPTIssue const& mptIssue, + int depth) +{ + if (isGlobalFrozen(view, mptIssue)) + return true; + + for (auto const& account : accounts) + { + if (isIndividualFrozen(view, account, mptIssue)) + return true; + } + + for (auto const& account : accounts) + { + if (isVaultPseudoAccountFrozen(view, account, mptIssue, depth)) + return true; + } + + return false; +} + +Rate +transferRate(ReadView const& view, MPTID const& issuanceID) +{ + // fee is 0-50,000 (0-50%), rate is 1,000,000,000-2,000,000,000 + // For example, if transfer fee is 50% then 10,000 * 50,000 = 500,000 + // which represents 50% of 1,000,000,000 + if (auto const sle = view.read(keylet::mptIssuance(issuanceID)); + sle && sle->isFieldPresent(sfTransferFee)) + return Rate{1'000'000'000u + 10'000 * sle->getFieldU16(sfTransferFee)}; + + return parityRate; +} + +[[nodiscard]] TER +canAddHolding(ReadView const& view, MPTIssue const& mptIssue) +{ + auto mptID = mptIssue.getMptID(); + auto issuance = view.read(keylet::mptIssuance(mptID)); + if (!issuance) + { + return tecOBJECT_NOT_FOUND; + } + if (!issuance->isFlag(lsfMPTCanTransfer)) + { + return tecNO_AUTH; + } + + return tesSUCCESS; +} + +[[nodiscard]] TER +addEmptyHolding( + ApplyView& view, + AccountID const& accountID, + XRPAmount priorBalance, + MPTIssue const& mptIssue, + beast::Journal journal) +{ + auto const& mptID = mptIssue.getMptID(); + auto const mpt = view.peek(keylet::mptIssuance(mptID)); + if (!mpt) + return tefINTERNAL; // LCOV_EXCL_LINE + if (mpt->isFlag(lsfMPTLocked)) + return tefINTERNAL; // LCOV_EXCL_LINE + if (view.peek(keylet::mptoken(mptID, accountID))) + return tecDUPLICATE; + if (accountID == mptIssue.getIssuer()) + return tesSUCCESS; + + return authorizeMPToken(view, priorBalance, mptID, accountID, journal); +} + +[[nodiscard]] TER +authorizeMPToken( + ApplyView& view, + XRPAmount const& priorBalance, + MPTID const& mptIssuanceID, + AccountID const& account, + beast::Journal journal, + std::uint32_t flags, + std::optional holderID) +{ + auto const sleAcct = view.peek(keylet::account(account)); + if (!sleAcct) + return tecINTERNAL; // LCOV_EXCL_LINE + + // If the account that submitted the tx is a holder + // Note: `account_` is holder's account + // `holderID` is NOT used + if (!holderID) + { + // When a holder wants to unauthorize/delete a MPT, the ledger must + // - delete mptokenKey from owner directory + // - delete the MPToken + if (flags & tfMPTUnauthorize) + { + auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); + auto const sleMpt = view.peek(mptokenKey); + if (!sleMpt || (*sleMpt)[sfMPTAmount] != 0) + return tecINTERNAL; // LCOV_EXCL_LINE + + if (!view.dirRemove( + keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false)) + return tecINTERNAL; // LCOV_EXCL_LINE + + adjustOwnerCount(view, sleAcct, -1, journal); + + view.erase(sleMpt); + return tesSUCCESS; + } + + // A potential holder wants to authorize/hold a mpt, the ledger must: + // - add the new mptokenKey to the owner directory + // - create the MPToken object for the holder + + // The reserve that is required to create the MPToken. Note + // that although the reserve increases with every item + // an account owns, in the case of MPTokens we only + // *enforce* a reserve if the user owns more than two + // items. This is similar to the reserve requirements of trust lines. + std::uint32_t const uOwnerCount = sleAcct->getFieldU32(sfOwnerCount); + XRPAmount const reserveCreate( + (uOwnerCount < 2) ? XRPAmount(beast::zero) + : view.fees().accountReserve(uOwnerCount + 1)); + + if (priorBalance < reserveCreate) + return tecINSUFFICIENT_RESERVE; + + // Defensive check before we attempt to create MPToken for the issuer + auto const mpt = view.read(keylet::mptIssuance(mptIssuanceID)); + if (!mpt || mpt->getAccountID(sfIssuer) == account) + { + // LCOV_EXCL_START + UNREACHABLE("xrpl::authorizeMPToken : invalid issuance or issuers token"); + if (view.rules().enabled(featureLendingProtocol)) + return tecINTERNAL; + // LCOV_EXCL_STOP + } + + auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); + auto mptoken = std::make_shared(mptokenKey); + if (auto ter = dirLink(view, account, mptoken)) + return ter; // LCOV_EXCL_LINE + + (*mptoken)[sfAccount] = account; + (*mptoken)[sfMPTokenIssuanceID] = mptIssuanceID; + (*mptoken)[sfFlags] = 0; + view.insert(mptoken); + + // Update owner count. + adjustOwnerCount(view, sleAcct, 1, journal); + + return tesSUCCESS; + } + + auto const sleMptIssuance = view.read(keylet::mptIssuance(mptIssuanceID)); + if (!sleMptIssuance) + 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; // LCOV_EXCL_LINE + + auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID)); + if (!sleMpt) + return tecINTERNAL; // LCOV_EXCL_LINE + + std::uint32_t const flagsIn = sleMpt->getFieldU32(sfFlags); + std::uint32_t flagsOut = flagsIn; + + // Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on + // their MPToken + if (flags & tfMPTUnauthorize) + { + flagsOut &= ~lsfMPTAuthorized; + } + // Issuer wants to authorize a holder, set lsfMPTAuthorized on their + // MPToken + else + { + flagsOut |= lsfMPTAuthorized; + } + + if (flagsIn != flagsOut) + sleMpt->setFieldU32(sfFlags, flagsOut); + + view.update(sleMpt); + return tesSUCCESS; +} + +[[nodiscard]] TER +removeEmptyHolding( + ApplyView& view, + AccountID const& accountID, + MPTIssue const& mptIssue, + beast::Journal journal) +{ + // If the account is the issuer, then no token should exist. MPTs do not + // have the legacy ability to create such a situation, but check anyway. If + // a token does exist, it will get deleted. If not, return success. + bool const accountIsIssuer = accountID == mptIssue.getIssuer(); + auto const& mptID = mptIssue.getMptID(); + auto const mptoken = view.peek(keylet::mptoken(mptID, accountID)); + if (!mptoken) + return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; + // Unlike a trust line, if the account is the issuer, and the token has a + // balance, it can not just be deleted, because that will throw the issuance + // accounting out of balance, so fail. Since this should be impossible + // anyway, I'm not going to put any effort into it. + if (mptoken->at(sfMPTAmount) != 0) + return tecHAS_OBLIGATIONS; + + return authorizeMPToken( + view, + {}, // priorBalance + mptID, + accountID, + journal, + tfMPTUnauthorize // flags + ); +} + +[[nodiscard]] TER +requireAuth( + ReadView const& view, + MPTIssue const& mptIssue, + AccountID const& account, + AuthType authType, + int depth) +{ + auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); + auto const sleIssuance = view.read(mptID); + if (!sleIssuance) + return tecOBJECT_NOT_FOUND; + + auto const mptIssuer = sleIssuance->getAccountID(sfIssuer); + + // issuer is always "authorized" + if (mptIssuer == account) // Issuer won't have MPToken + return tesSUCCESS; + + bool const featureSAVEnabled = view.rules().enabled(featureSingleAssetVault); + + if (featureSAVEnabled) + { + if (depth >= maxAssetCheckDepth) + return tecINTERNAL; // LCOV_EXCL_LINE + + // requireAuth is recursive if the issuer is a vault pseudo-account + auto const sleIssuer = view.read(keylet::account(mptIssuer)); + if (!sleIssuer) + return tefINTERNAL; // LCOV_EXCL_LINE + + if (sleIssuer->isFieldPresent(sfVaultID)) + { + auto const sleVault = view.read(keylet::vault(sleIssuer->getFieldH256(sfVaultID))); + if (!sleVault) + return tefINTERNAL; // LCOV_EXCL_LINE + + auto const asset = sleVault->at(sfAsset); + if (auto const err = std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return requireAuth(view, issue, account, authType); + } + else + { + return requireAuth(view, issue, account, authType, depth + 1); + } + }, + asset.value()); + !isTesSuccess(err)) + return err; + } + } + + auto const mptokenID = keylet::mptoken(mptID.key, account); + auto const sleToken = view.read(mptokenID); + + // if account has no MPToken, fail + if (!sleToken && (authType == AuthType::StrongAuth || authType == AuthType::Legacy)) + return tecNO_AUTH; + + // Note, this check is not amendment-gated because DomainID will be always + // empty **unless** writing to it has been enabled by an amendment + auto const maybeDomainID = sleIssuance->at(~sfDomainID); + if (maybeDomainID) + { + XRPL_ASSERT( + sleIssuance->getFieldU32(sfFlags) & lsfMPTRequireAuth, + "xrpl::requireAuth : issuance requires authorization"); + // ter = tefINTERNAL | tecOBJECT_NOT_FOUND | tecNO_AUTH | tecEXPIRED + auto const ter = credentials::validDomain(view, *maybeDomainID, account); + if (isTesSuccess(ter)) + { + return ter; // Note: sleToken might be null + } + if (!sleToken) + { + return ter; + } + // We ignore error from validDomain if we found sleToken, as it could + // belong to someone who is explicitly authorized e.g. a vault owner. + } + + if (featureSAVEnabled) + { + // Implicitly authorize Vault and LoanBroker pseudo-accounts + if (isPseudoAccount(view, account, {&sfVaultID, &sfLoanBrokerID})) + return tesSUCCESS; + } + + // mptoken must be authorized if issuance enabled requireAuth + if (sleIssuance->isFlag(lsfMPTRequireAuth) && + (!sleToken || !sleToken->isFlag(lsfMPTAuthorized))) + return tecNO_AUTH; + + return tesSUCCESS; // Note: sleToken might be null +} + +[[nodiscard]] TER +enforceMPTokenAuthorization( + ApplyView& view, + MPTID const& mptIssuanceID, + AccountID const& account, + XRPAmount const& priorBalance, // for MPToken authorization + beast::Journal j) +{ + auto const sleIssuance = view.read(keylet::mptIssuance(mptIssuanceID)); + if (!sleIssuance) + return tefINTERNAL; // LCOV_EXCL_LINE + + XRPL_ASSERT( + sleIssuance->isFlag(lsfMPTRequireAuth), + "xrpl::enforceMPTokenAuthorization : authorization required"); + + if (account == sleIssuance->at(sfIssuer)) + return tefINTERNAL; // LCOV_EXCL_LINE + + auto const keylet = keylet::mptoken(mptIssuanceID, account); + auto const sleToken = view.read(keylet); // NOTE: might be null + auto const maybeDomainID = sleIssuance->at(~sfDomainID); + bool expired = false; + bool const authorizedByDomain = [&]() -> bool { + // NOTE: defensive here, should be checked in preclaim + if (!maybeDomainID.has_value()) + return false; // LCOV_EXCL_LINE + + auto const ter = verifyValidDomain(view, account, *maybeDomainID, j); + if (isTesSuccess(ter)) + return true; + if (ter == tecEXPIRED) + expired = true; + return false; + }(); + + if (!authorizedByDomain && sleToken == nullptr) + { + // Could not find MPToken and won't create one, could be either of: + // + // 1. Field sfDomainID not set in MPTokenIssuance or + // 2. Account has no matching and accepted credentials or + // 3. Account has all expired credentials (deleted in verifyValidDomain) + // + // Either way, return tecNO_AUTH and there is nothing else to do + return expired ? tecEXPIRED : tecNO_AUTH; + } + if (!authorizedByDomain && maybeDomainID.has_value()) + { + // Found an MPToken but the account is not authorized and we expect + // it to have been authorized by the domain. This could be because the + // credentials used to create the MPToken have expired or been deleted. + return expired ? tecEXPIRED : tecNO_AUTH; + } + if (!authorizedByDomain) + { + // We found an MPToken, but sfDomainID is not set, so this is a classic + // MPToken which requires authorization by the token issuer. + XRPL_ASSERT( + sleToken != nullptr && !maybeDomainID.has_value(), + "xrpl::enforceMPTokenAuthorization : found MPToken"); + if (sleToken->isFlag(lsfMPTAuthorized)) + return tesSUCCESS; + + return tecNO_AUTH; + } + if (authorizedByDomain && sleToken != nullptr) + { + // Found an MPToken, authorized by the domain. Ignore authorization flag + // lsfMPTAuthorized because it is meaningless. Return tesSUCCESS + XRPL_ASSERT( + maybeDomainID.has_value(), + "xrpl::enforceMPTokenAuthorization : found MPToken for domain"); + return tesSUCCESS; + } + if (authorizedByDomain) + { + // Could not find MPToken but there should be one because we are + // authorized by domain. Proceed to create it, then return tesSUCCESS + XRPL_ASSERT( + maybeDomainID.has_value() && sleToken == nullptr, + "xrpl::enforceMPTokenAuthorization : new MPToken for domain"); + if (auto const err = authorizeMPToken( + view, + priorBalance, // priorBalance + mptIssuanceID, // mptIssuanceID + account, // account + j); + !isTesSuccess(err)) + return err; + + return tesSUCCESS; + } + + // LCOV_EXCL_START + UNREACHABLE("xrpl::enforceMPTokenAuthorization : condition list is incomplete"); + return tefINTERNAL; + // LCOV_EXCL_STOP +} + +TER +canTransfer( + ReadView const& view, + MPTIssue const& mptIssue, + AccountID const& from, + AccountID const& to) +{ + auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); + auto const sleIssuance = view.read(mptID); + if (!sleIssuance) + return tecOBJECT_NOT_FOUND; + + if (!(sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer)) + { + if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer]) + return TER{tecNO_AUTH}; + } + return tesSUCCESS; +} + +TER +rippleLockEscrowMPT( + ApplyView& view, + AccountID const& sender, + STAmount const& amount, + beast::Journal j) +{ + auto const mptIssue = amount.get(); + auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); + auto sleIssuance = view.peek(mptID); + if (!sleIssuance) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleLockEscrowMPT: MPT issuance not found for " + << mptIssue.getMptID(); + return tecOBJECT_NOT_FOUND; + } // LCOV_EXCL_STOP + + if (amount.getIssuer() == sender) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleLockEscrowMPT: sender is the issuer, cannot lock MPTs."; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + // 1. Decrease the MPT Holder MPTAmount + // 2. Increase the MPT Holder EscrowedAmount + { + auto const mptokenID = keylet::mptoken(mptID.key, sender); + auto sle = view.peek(mptokenID); + if (!sle) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleLockEscrowMPT: MPToken not found for " << sender; + return tecOBJECT_NOT_FOUND; + } // LCOV_EXCL_STOP + + auto const amt = sle->getFieldU64(sfMPTAmount); + auto const pay = amount.mpt().value(); + + // Underflow check for subtraction + if (!canSubtract(STAmount(mptIssue, amt), STAmount(mptIssue, pay))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleLockEscrowMPT: insufficient MPTAmount for " + << to_string(sender) << ": " << amt << " < " << pay; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + (*sle)[sfMPTAmount] = amt - pay; + + // Overflow check for addition + uint64_t const locked = (*sle)[~sfLockedAmount].value_or(0); + + if (!canAdd(STAmount(mptIssue, locked), STAmount(mptIssue, pay))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleLockEscrowMPT: overflow on locked amount for " + << to_string(sender) << ": " << locked << " + " << pay; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + if (sle->isFieldPresent(sfLockedAmount)) + { + (*sle)[sfLockedAmount] += pay; + } + else + { + sle->setFieldU64(sfLockedAmount, pay); + } + + view.update(sle); + } + + // 1. Increase the Issuance EscrowedAmount + // 2. DO NOT change the Issuance OutstandingAmount + { + uint64_t const issuanceEscrowed = (*sleIssuance)[~sfLockedAmount].value_or(0); + auto const pay = amount.mpt().value(); + + // Overflow check for addition + if (!canAdd(STAmount(mptIssue, issuanceEscrowed), STAmount(mptIssue, pay))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleLockEscrowMPT: overflow on issuance " + "locked amount for " + << mptIssue.getMptID() << ": " << issuanceEscrowed << " + " << pay; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + if (sleIssuance->isFieldPresent(sfLockedAmount)) + { + (*sleIssuance)[sfLockedAmount] += pay; + } + else + { + sleIssuance->setFieldU64(sfLockedAmount, pay); + } + + view.update(sleIssuance); + } + return tesSUCCESS; +} + +TER +rippleUnlockEscrowMPT( + ApplyView& view, + AccountID const& sender, + AccountID const& receiver, + STAmount const& netAmount, + STAmount const& grossAmount, + beast::Journal j) +{ + if (!view.rules().enabled(fixTokenEscrowV1)) + { + XRPL_ASSERT( + netAmount == grossAmount, "xrpl::rippleUnlockEscrowMPT : netAmount == grossAmount"); + } + + auto const& issuer = netAmount.getIssuer(); + auto const& mptIssue = netAmount.get(); + auto const mptID = keylet::mptIssuance(mptIssue.getMptID()); + auto sleIssuance = view.peek(mptID); + if (!sleIssuance) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: MPT issuance not found for " + << mptIssue.getMptID(); + return tecOBJECT_NOT_FOUND; + } // LCOV_EXCL_STOP + + // Decrease the Issuance EscrowedAmount + { + if (!sleIssuance->isFieldPresent(sfLockedAmount)) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in issuance for " + << mptIssue.getMptID(); + return tecINTERNAL; + } // LCOV_EXCL_STOP + + auto const locked = sleIssuance->getFieldU64(sfLockedAmount); + auto const redeem = grossAmount.mpt().value(); + + // Underflow check for subtraction + if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, redeem))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for " + << mptIssue.getMptID() << ": " << locked << " < " << redeem; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + auto const newLocked = locked - redeem; + if (newLocked == 0) + { + sleIssuance->makeFieldAbsent(sfLockedAmount); + } + else + { + sleIssuance->setFieldU64(sfLockedAmount, newLocked); + } + view.update(sleIssuance); + } + + if (issuer != receiver) + { + // Increase the MPT Holder MPTAmount + auto const mptokenID = keylet::mptoken(mptID.key, receiver); + auto sle = view.peek(mptokenID); + if (!sle) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << receiver; + return tecOBJECT_NOT_FOUND; + } // LCOV_EXCL_STOP + + auto current = sle->getFieldU64(sfMPTAmount); + auto delta = netAmount.mpt().value(); + + // Overflow check for addition + if (!canAdd(STAmount(mptIssue, current), STAmount(mptIssue, delta))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: overflow on MPTAmount for " + << to_string(receiver) << ": " << current << " + " << delta; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + (*sle)[sfMPTAmount] += delta; + view.update(sle); + } + else + { + // Decrease the Issuance OutstandingAmount + auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount); + auto const redeem = netAmount.mpt().value(); + + // Underflow check for subtraction + if (!canSubtract(STAmount(mptIssue, outstanding), STAmount(mptIssue, redeem))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient outstanding amount for " + << mptIssue.getMptID() << ": " << outstanding << " < " << redeem; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - redeem); + view.update(sleIssuance); + } + + if (issuer == sender) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: sender is the issuer, " + "cannot unlock MPTs."; + return tecINTERNAL; + } // LCOV_EXCL_STOP + // Decrease the MPT Holder EscrowedAmount + auto const mptokenID = keylet::mptoken(mptID.key, sender); + auto sle = view.peek(mptokenID); + if (!sle) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: MPToken not found for " << sender; + return tecOBJECT_NOT_FOUND; + } // LCOV_EXCL_STOP + + if (!sle->isFieldPresent(sfLockedAmount)) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: no locked amount in MPToken for " + << to_string(sender); + return tecINTERNAL; + } // LCOV_EXCL_STOP + + auto const locked = sle->getFieldU64(sfLockedAmount); + auto const delta = grossAmount.mpt().value(); + + // Underflow check for subtraction + if (!canSubtract(STAmount(mptIssue, locked), STAmount(mptIssue, delta))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient locked amount for " + << to_string(sender) << ": " << locked << " < " << delta; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + auto const newLocked = locked - delta; + if (newLocked == 0) + { + sle->makeFieldAbsent(sfLockedAmount); + } + else + { + sle->setFieldU64(sfLockedAmount, newLocked); + } + view.update(sle); + + // Note: The gross amount is the amount that was locked, the net + // amount is the amount that is being unlocked. The difference is the fee + // that was charged for the transfer. If this difference is greater than + // zero, we need to update the outstanding amount. + auto const diff = grossAmount.mpt().value() - netAmount.mpt().value(); + if (diff != 0) + { + auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount); + // Underflow check for subtraction + if (!canSubtract(STAmount(mptIssue, outstanding), STAmount(mptIssue, diff))) + { // LCOV_EXCL_START + JLOG(j.error()) << "rippleUnlockEscrowMPT: insufficient outstanding amount for " + << mptIssue.getMptID() << ": " << outstanding << " < " << diff; + return tecINTERNAL; + } // LCOV_EXCL_STOP + + sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - diff); + view.update(sleIssuance); + } + return tesSUCCESS; +} + +} // namespace xrpl diff --git a/src/libxrpl/ledger/helpers/OfferHelpers.cpp b/src/libxrpl/ledger/helpers/OfferHelpers.cpp new file mode 100644 index 0000000000..9422153b10 --- /dev/null +++ b/src/libxrpl/ledger/helpers/OfferHelpers.cpp @@ -0,0 +1,58 @@ +#include +// +#include +#include +#include +#include + +namespace xrpl { + +TER +offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j) +{ + if (!sle) + return tesSUCCESS; + auto offerIndex = sle->key(); + auto owner = sle->getAccountID(sfAccount); + + // Detect legacy directories. + uint256 uDirectory = sle->getFieldH256(sfBookDirectory); + + if (!view.dirRemove(keylet::ownerDir(owner), sle->getFieldU64(sfOwnerNode), offerIndex, false)) + { + return tefBAD_LEDGER; // LCOV_EXCL_LINE + } + + if (!view.dirRemove(keylet::page(uDirectory), sle->getFieldU64(sfBookNode), offerIndex, false)) + { + return tefBAD_LEDGER; // LCOV_EXCL_LINE + } + + if (sle->isFieldPresent(sfAdditionalBooks)) + { + XRPL_ASSERT( + sle->isFlag(lsfHybrid) && sle->isFieldPresent(sfDomainID), + "xrpl::offerDelete : should be a hybrid domain offer"); + + auto const& additionalBookDirs = sle->getFieldArray(sfAdditionalBooks); + + for (auto const& bookDir : additionalBookDirs) + { + auto const& dirIndex = bookDir.getFieldH256(sfBookDirectory); + auto const& dirNode = bookDir.getFieldU64(sfBookNode); + + if (!view.dirRemove(keylet::page(dirIndex), dirNode, offerIndex, false)) + { + return tefBAD_LEDGER; // LCOV_EXCL_LINE + } + } + } + + adjustOwnerCount(view, view.peek(keylet::account(owner)), -1, j); + + view.erase(sle); + + return tesSUCCESS; +} + +} // namespace xrpl diff --git a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp new file mode 100644 index 0000000000..e88afe0cfb --- /dev/null +++ b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp @@ -0,0 +1,759 @@ +#include +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xrpl { + +//------------------------------------------------------------------------------ +// +// Credit functions (from Credit.cpp) +// +//------------------------------------------------------------------------------ + +STAmount +creditLimit( + ReadView const& view, + AccountID const& account, + AccountID const& issuer, + Currency const& currency) +{ + STAmount result(Issue{currency, account}); + + auto sleRippleState = view.read(keylet::line(account, issuer, currency)); + + if (sleRippleState) + { + result = sleRippleState->getFieldAmount(account < issuer ? sfLowLimit : sfHighLimit); + result.setIssuer(account); + } + + XRPL_ASSERT(result.getIssuer() == account, "xrpl::creditLimit : result issuer match"); + XRPL_ASSERT(result.getCurrency() == currency, "xrpl::creditLimit : result currency match"); + return result; +} + +IOUAmount +creditLimit2(ReadView const& v, AccountID const& acc, AccountID const& iss, Currency const& cur) +{ + return toAmount(creditLimit(v, acc, iss, cur)); +} + +STAmount +creditBalance( + ReadView const& view, + AccountID const& account, + AccountID const& issuer, + Currency const& currency) +{ + STAmount result(Issue{currency, account}); + + auto sleRippleState = view.read(keylet::line(account, issuer, currency)); + + if (sleRippleState) + { + result = sleRippleState->getFieldAmount(sfBalance); + if (account < issuer) + result.negate(); + result.setIssuer(account); + } + + XRPL_ASSERT(result.getIssuer() == account, "xrpl::creditBalance : result issuer match"); + XRPL_ASSERT(result.getCurrency() == currency, "xrpl::creditBalance : result currency match"); + return result; +} + +//------------------------------------------------------------------------------ +// +// Freeze checking (IOU-specific) +// +//------------------------------------------------------------------------------ + +bool +isIndividualFrozen( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer) +{ + if (isXRP(currency)) + return false; + if (issuer != account) + { + // Check if the issuer froze the line + auto const sle = view.read(keylet::line(account, issuer, currency)); + if (sle && sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze)) + return true; + } + return false; +} + +// Can the specified account spend the specified currency issued by +// the specified issuer or does the freeze flag prohibit it? +bool +isFrozen( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer) +{ + if (isXRP(currency)) + return false; + auto sle = view.read(keylet::account(issuer)); + if (sle && sle->isFlag(lsfGlobalFreeze)) + return true; + if (issuer != account) + { + // Check if the issuer froze the line + sle = view.read(keylet::line(account, issuer, currency)); + if (sle && sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze)) + return true; + } + return false; +} + +bool +isDeepFrozen( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer) +{ + if (isXRP(currency)) + { + return false; + } + + if (issuer == account) + { + return false; + } + + auto const sle = view.read(keylet::line(account, issuer, currency)); + if (!sle) + { + return false; + } + + return sle->isFlag(lsfHighDeepFreeze) || sle->isFlag(lsfLowDeepFreeze); +} + +//------------------------------------------------------------------------------ +// +// Trust line operations +// +//------------------------------------------------------------------------------ + +TER +trustCreate( + ApplyView& view, + bool const bSrcHigh, + AccountID const& uSrcAccountID, + AccountID const& uDstAccountID, + uint256 const& uIndex, // --> ripple state entry + SLE::ref sleAccount, // --> the account being set. + bool const bAuth, // --> authorize account. + bool const bNoRipple, // --> others cannot ripple through + bool const bFreeze, // --> funds cannot leave + bool bDeepFreeze, // --> can neither receive nor send funds + STAmount const& saBalance, // --> balance of account being set. + // Issuer should be noAccount() + STAmount const& saLimit, // --> limit for account being set. + // Issuer should be the account being set. + std::uint32_t uQualityIn, + std::uint32_t uQualityOut, + beast::Journal j) +{ + JLOG(j.trace()) << "trustCreate: " << to_string(uSrcAccountID) << ", " + << to_string(uDstAccountID) << ", " << saBalance.getFullText(); + + auto const& uLowAccountID = !bSrcHigh ? uSrcAccountID : uDstAccountID; + auto const& uHighAccountID = bSrcHigh ? uSrcAccountID : uDstAccountID; + if (uLowAccountID == uHighAccountID) + { + // LCOV_EXCL_START + UNREACHABLE("xrpl::trustCreate : trust line to self"); + if (view.rules().enabled(featureLendingProtocol)) + return tecINTERNAL; + // LCOV_EXCL_STOP + } + + auto const sleRippleState = std::make_shared(ltRIPPLE_STATE, uIndex); + view.insert(sleRippleState); + + auto lowNode = view.dirInsert( + keylet::ownerDir(uLowAccountID), sleRippleState->key(), describeOwnerDir(uLowAccountID)); + + if (!lowNode) + return tecDIR_FULL; // LCOV_EXCL_LINE + + auto highNode = view.dirInsert( + keylet::ownerDir(uHighAccountID), sleRippleState->key(), describeOwnerDir(uHighAccountID)); + + if (!highNode) + return tecDIR_FULL; // LCOV_EXCL_LINE + + bool const bSetDst = saLimit.getIssuer() == uDstAccountID; + bool const bSetHigh = bSrcHigh ^ bSetDst; + + XRPL_ASSERT(sleAccount, "xrpl::trustCreate : non-null SLE"); + if (!sleAccount) + return tefINTERNAL; // LCOV_EXCL_LINE + + XRPL_ASSERT( + sleAccount->getAccountID(sfAccount) == (bSetHigh ? uHighAccountID : uLowAccountID), + "xrpl::trustCreate : matching account ID"); + auto const slePeer = view.peek(keylet::account(bSetHigh ? uLowAccountID : uHighAccountID)); + if (!slePeer) + return tecNO_TARGET; + + // Remember deletion hints. + sleRippleState->setFieldU64(sfLowNode, *lowNode); + sleRippleState->setFieldU64(sfHighNode, *highNode); + + sleRippleState->setFieldAmount(bSetHigh ? sfHighLimit : sfLowLimit, saLimit); + sleRippleState->setFieldAmount( + bSetHigh ? sfLowLimit : sfHighLimit, + STAmount(Issue{saBalance.getCurrency(), bSetDst ? uSrcAccountID : uDstAccountID})); + + if (uQualityIn) + sleRippleState->setFieldU32(bSetHigh ? sfHighQualityIn : sfLowQualityIn, uQualityIn); + + if (uQualityOut) + sleRippleState->setFieldU32(bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut); + + std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve; + + if (bAuth) + { + uFlags |= (bSetHigh ? lsfHighAuth : lsfLowAuth); + } + if (bNoRipple) + { + uFlags |= (bSetHigh ? lsfHighNoRipple : lsfLowNoRipple); + } + if (bFreeze) + { + uFlags |= (bSetHigh ? lsfHighFreeze : lsfLowFreeze); + } + if (bDeepFreeze) + { + uFlags |= (bSetHigh ? lsfHighDeepFreeze : lsfLowDeepFreeze); + } + + if ((slePeer->getFlags() & lsfDefaultRipple) == 0) + { + // The other side's default is no rippling + uFlags |= (bSetHigh ? lsfLowNoRipple : lsfHighNoRipple); + } + + sleRippleState->setFieldU32(sfFlags, uFlags); + adjustOwnerCount(view, sleAccount, 1, j); + + // ONLY: Create ripple balance. + sleRippleState->setFieldAmount(sfBalance, bSetHigh ? -saBalance : saBalance); + + view.creditHook(uSrcAccountID, uDstAccountID, saBalance, saBalance.zeroed()); + + return tesSUCCESS; +} + +TER +trustDelete( + ApplyView& view, + std::shared_ptr const& sleRippleState, + AccountID const& uLowAccountID, + AccountID const& uHighAccountID, + beast::Journal j) +{ + // Detect legacy dirs. + std::uint64_t uLowNode = sleRippleState->getFieldU64(sfLowNode); + std::uint64_t uHighNode = sleRippleState->getFieldU64(sfHighNode); + + JLOG(j.trace()) << "trustDelete: Deleting ripple line: low"; + + if (!view.dirRemove(keylet::ownerDir(uLowAccountID), uLowNode, sleRippleState->key(), false)) + { + return tefBAD_LEDGER; // LCOV_EXCL_LINE + } + + JLOG(j.trace()) << "trustDelete: Deleting ripple line: high"; + + if (!view.dirRemove(keylet::ownerDir(uHighAccountID), uHighNode, sleRippleState->key(), false)) + { + return tefBAD_LEDGER; // LCOV_EXCL_LINE + } + + JLOG(j.trace()) << "trustDelete: Deleting ripple line: state"; + view.erase(sleRippleState); + + return tesSUCCESS; +} + +//------------------------------------------------------------------------------ +// +// IOU issuance/redemption +// +//------------------------------------------------------------------------------ + +static bool +updateTrustLine( + ApplyView& view, + SLE::pointer state, + bool bSenderHigh, + AccountID const& sender, + STAmount const& before, + STAmount const& after, + beast::Journal j) +{ + if (!state) + return false; + std::uint32_t const flags(state->getFieldU32(sfFlags)); + + auto sle = view.peek(keylet::account(sender)); + if (!sle) + return false; + + // YYY Could skip this if rippling in reverse. + if (before > beast::zero + // Sender balance was positive. + && after <= beast::zero + // Sender is zero or negative. + && (flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) + // Sender reserve is set. + && static_cast(flags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) != + static_cast(sle->getFlags() & lsfDefaultRipple) && + !(flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) && + !state->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit) + // Sender trust limit is 0. + && !state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) + // Sender quality in is 0. + && !state->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut)) + // Sender quality out is 0. + { + // VFALCO Where is the line being deleted? + // Clear the reserve of the sender, possibly delete the line! + adjustOwnerCount(view, sle, -1, j); + + // Clear reserve flag. + state->setFieldU32(sfFlags, flags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve)); + + // Balance is zero, receiver reserve is clear. + if (!after // Balance is zero. + && !(flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve))) + return true; + } + return false; +} + +TER +issueIOU( + ApplyView& view, + AccountID const& account, + STAmount const& amount, + Issue const& issue, + beast::Journal j) +{ + XRPL_ASSERT( + !isXRP(account) && !isXRP(issue.account), + "xrpl::issueIOU : neither account nor issuer is XRP"); + + // Consistency check + XRPL_ASSERT(issue == amount.issue(), "xrpl::issueIOU : matching issue"); + + // Can't send to self! + XRPL_ASSERT(issue.account != account, "xrpl::issueIOU : not issuer account"); + + JLOG(j.trace()) << "issueIOU: " << to_string(account) << ": " << amount.getFullText(); + + bool bSenderHigh = issue.account > account; + + auto const index = keylet::line(issue.account, account, issue.currency); + + if (auto state = view.peek(index)) + { + STAmount final_balance = state->getFieldAmount(sfBalance); + + if (bSenderHigh) + final_balance.negate(); // Put balance in sender terms. + + STAmount const start_balance = final_balance; + + final_balance -= amount; + + auto const must_delete = updateTrustLine( + view, state, bSenderHigh, issue.account, start_balance, final_balance, j); + + view.creditHook(issue.account, account, amount, start_balance); + + if (bSenderHigh) + final_balance.negate(); + + // Adjust the balance on the trust line if necessary. We do this even + // if we are going to delete the line to reflect the correct balance + // at the time of deletion. + state->setFieldAmount(sfBalance, final_balance); + if (must_delete) + { + return trustDelete( + view, + state, + bSenderHigh ? account : issue.account, + bSenderHigh ? issue.account : account, + j); + } + + view.update(state); + + return tesSUCCESS; + } + + // NIKB TODO: The limit uses the receiver's account as the issuer and + // this is unnecessarily inefficient as copying which could be avoided + // is now required. Consider available options. + STAmount const limit(Issue{issue.currency, account}); + STAmount final_balance = amount; + + final_balance.setIssuer(noAccount()); + + auto const receiverAccount = view.peek(keylet::account(account)); + if (!receiverAccount) + return tefINTERNAL; // LCOV_EXCL_LINE + + bool noRipple = (receiverAccount->getFlags() & lsfDefaultRipple) == 0; + + return trustCreate( + view, + bSenderHigh, + issue.account, + account, + index.key, + receiverAccount, + false, + noRipple, + false, + false, + final_balance, + limit, + 0, + 0, + j); +} + +TER +redeemIOU( + ApplyView& view, + AccountID const& account, + STAmount const& amount, + Issue const& issue, + beast::Journal j) +{ + XRPL_ASSERT( + !isXRP(account) && !isXRP(issue.account), + "xrpl::redeemIOU : neither account nor issuer is XRP"); + + // Consistency check + XRPL_ASSERT(issue == amount.issue(), "xrpl::redeemIOU : matching issue"); + + // Can't send to self! + XRPL_ASSERT(issue.account != account, "xrpl::redeemIOU : not issuer account"); + + JLOG(j.trace()) << "redeemIOU: " << to_string(account) << ": " << amount.getFullText(); + + bool bSenderHigh = account > issue.account; + + if (auto state = view.peek(keylet::line(account, issue.account, issue.currency))) + { + STAmount final_balance = state->getFieldAmount(sfBalance); + + if (bSenderHigh) + final_balance.negate(); // Put balance in sender terms. + + STAmount const start_balance = final_balance; + + final_balance -= amount; + + auto const must_delete = + updateTrustLine(view, state, bSenderHigh, account, start_balance, final_balance, j); + + view.creditHook(account, issue.account, amount, start_balance); + + if (bSenderHigh) + final_balance.negate(); + + // Adjust the balance on the trust line if necessary. We do this even + // if we are going to delete the line to reflect the correct balance + // at the time of deletion. + state->setFieldAmount(sfBalance, final_balance); + + if (must_delete) + { + return trustDelete( + view, + state, + bSenderHigh ? issue.account : account, + bSenderHigh ? account : issue.account, + j); + } + + view.update(state); + return tesSUCCESS; + } + + // 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 +} + +//------------------------------------------------------------------------------ +// +// Authorization and transfer checks (IOU-specific) +// +//------------------------------------------------------------------------------ + +TER +requireAuth(ReadView const& view, Issue const& issue, AccountID const& account, AuthType authType) +{ + if (isXRP(issue) || issue.account == account) + return tesSUCCESS; + + auto const trustLine = view.read(keylet::line(account, issue.account, issue.currency)); + // If account has no line, and this is a strong check, fail + if (!trustLine && authType == AuthType::StrongAuth) + return tecNO_LINE; + + // If this is a weak or legacy check, or if the account has a line, fail if + // auth is required and not set on the line + if (auto const issuerAccount = view.read(keylet::account(issue.account)); + issuerAccount && (*issuerAccount)[sfFlags] & lsfRequireAuth) + { + if (trustLine) + { + return ((*trustLine)[sfFlags] & ((account > issue.account) ? lsfLowAuth : lsfHighAuth)) + ? tesSUCCESS + : TER{tecNO_AUTH}; + } + return TER{tecNO_LINE}; + } + + return tesSUCCESS; +} + +TER +canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, AccountID const& to) +{ + if (issue.native()) + return tesSUCCESS; + + auto const& issuerId = issue.getIssuer(); + if (issuerId == from || issuerId == to) + return tesSUCCESS; + auto const sleIssuer = view.read(keylet::account(issuerId)); + if (sleIssuer == nullptr) + return tefINTERNAL; // LCOV_EXCL_LINE + + auto const isRippleDisabled = [&](AccountID account) -> bool { + // Line might not exist, but some transfers can create it. If this + // is the case, just check the default ripple on the issuer account. + auto const line = view.read(keylet::line(account, issue)); + if (line) + { + bool const issuerHigh = issuerId > account; + return line->isFlag(issuerHigh ? lsfHighNoRipple : lsfLowNoRipple); + } + return sleIssuer->isFlag(lsfDefaultRipple) == false; + }; + + // Fail if rippling disabled on both trust lines + if (isRippleDisabled(from) && isRippleDisabled(to)) + return terNO_RIPPLE; + + return tesSUCCESS; +} + +//------------------------------------------------------------------------------ +// +// Empty holding operations (IOU-specific) +// +//------------------------------------------------------------------------------ + +TER +addEmptyHolding( + ApplyView& view, + AccountID const& accountID, + XRPAmount priorBalance, + Issue const& issue, + beast::Journal journal) +{ + // Every account can hold XRP. An issuer can issue directly. + if (issue.native() || accountID == issue.getIssuer()) + return tesSUCCESS; + + auto const& issuerId = issue.getIssuer(); + auto const& currency = issue.currency; + if (isGlobalFrozen(view, issuerId)) + return tecFROZEN; // LCOV_EXCL_LINE + + auto const& srcId = issuerId; + auto const& dstId = accountID; + auto const high = srcId > dstId; + auto const index = keylet::line(srcId, dstId, currency); + auto const sleSrc = view.peek(keylet::account(srcId)); + auto const sleDst = view.peek(keylet::account(dstId)); + if (!sleDst || !sleSrc) + return tefINTERNAL; // LCOV_EXCL_LINE + if (!sleSrc->isFlag(lsfDefaultRipple)) + return tecINTERNAL; // LCOV_EXCL_LINE + // If the line already exists, don't create it again. + if (view.read(index)) + return tecDUPLICATE; + + // Can the account cover the trust line reserve ? + std::uint32_t const ownerCount = sleDst->at(sfOwnerCount); + if (priorBalance < view.fees().accountReserve(ownerCount + 1)) + return tecNO_LINE_INSUF_RESERVE; + + return trustCreate( + view, + high, + srcId, + dstId, + index.key, + sleDst, + /*bAuth=*/false, + /*bNoRipple=*/true, + /*bFreeze=*/false, + /*deepFreeze*/ false, + /*saBalance=*/STAmount{Issue{currency, noAccount()}}, + /*saLimit=*/STAmount{Issue{currency, dstId}}, + /*uQualityIn=*/0, + /*uQualityOut=*/0, + journal); +} + +TER +removeEmptyHolding( + ApplyView& view, + AccountID const& accountID, + Issue const& issue, + beast::Journal journal) +{ + if (issue.native()) + { + auto const sle = view.read(keylet::account(accountID)); + if (!sle) + return tecINTERNAL; // LCOV_EXCL_LINE + + auto const balance = sle->getFieldAmount(sfBalance); + if (balance.xrp() != 0) + return tecHAS_OBLIGATIONS; + + return tesSUCCESS; + } + + // `asset` is an IOU. + // If the account is the issuer, then no line should exist. Check anyway. + // If a line does exist, it will get deleted. If not, return success. + bool const accountIsIssuer = accountID == issue.account; + auto const line = view.peek(keylet::line(accountID, issue)); + if (!line) + return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; + if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::zero) + return tecHAS_OBLIGATIONS; + + // Adjust the owner count(s) + if (line->isFlag(lsfLowReserve)) + { + // Clear reserve for low account. + auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); + if (!sleLowAccount) + 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 + // accurate state at the time of deletion. + line->clearFlag(lsfLowReserve); + } + + if (line->isFlag(lsfHighReserve)) + { + // Clear reserve for high account. + auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); + if (!sleHighAccount) + 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 + // accurate state at the time of deletion. + line->clearFlag(lsfHighReserve); + } + + return trustDelete( + view, line, line->at(sfLowLimit)->getIssuer(), line->at(sfHighLimit)->getIssuer(), journal); +} + +TER +deleteAMMTrustLine( + ApplyView& view, + std::shared_ptr sleState, + std::optional const& ammAccountID, + beast::Journal j) +{ + if (!sleState || sleState->getType() != ltRIPPLE_STATE) + return tecINTERNAL; // LCOV_EXCL_LINE + + auto const& [low, high] = std::minmax( + sleState->getFieldAmount(sfLowLimit).getIssuer(), + sleState->getFieldAmount(sfHighLimit).getIssuer()); + auto sleLow = view.peek(keylet::account(low)); + auto sleHigh = view.peek(keylet::account(high)); + if (!sleLow || !sleHigh) + 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; // LCOV_EXCL_LINE + + // at least one must be + if (!ammLow && !ammHigh) + return terNO_AMM; + + // one must be the target amm + if (ammAccountID && (low != *ammAccountID && high != *ammAccountID)) + return terNO_AMM; + + if (auto const ter = trustDelete(view, sleState, low, high, j); !isTesSuccess(ter)) + { + JLOG(j.error()) << "deleteAMMTrustLine: failed to delete the trustline."; + return ter; + } + + auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve; + if (!(sleState->getFlags() & uFlags)) + return tecINTERNAL; // LCOV_EXCL_LINE + + adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j); + + return tesSUCCESS; +} + +} // namespace xrpl diff --git a/src/libxrpl/ledger/helpers/TokenHelpers.cpp b/src/libxrpl/ledger/helpers/TokenHelpers.cpp new file mode 100644 index 0000000000..7a98445b0a --- /dev/null +++ b/src/libxrpl/ledger/helpers/TokenHelpers.cpp @@ -0,0 +1,1392 @@ +#include +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl { + +// Forward declaration for function that remains in View.h/cpp +bool +isLPTokenFrozen( + ReadView const& view, + AccountID const& account, + Issue const& asset, + Issue const& asset2); + +//------------------------------------------------------------------------------ +// +// Freeze checking (Asset-based) +// +//------------------------------------------------------------------------------ + +bool +isGlobalFrozen(ReadView const& view, Asset const& asset) +{ + return std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return isGlobalFrozen(view, issue.getIssuer()); + } + else + { + return isGlobalFrozen(view, issue); + } + }, + asset.value()); +} + +bool +isIndividualFrozen(ReadView const& view, AccountID const& account, Asset const& asset) +{ + return std::visit( + [&](auto const& issue) { return isIndividualFrozen(view, account, issue); }, asset.value()); +} + +bool +isFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth) +{ + return std::visit( + [&](auto const& issue) { return isFrozen(view, account, issue, depth); }, asset.value()); +} + +TER +checkFrozen(ReadView const& view, AccountID const& account, Issue const& issue) +{ + return isFrozen(view, account, issue) ? (TER)tecFROZEN : (TER)tesSUCCESS; +} + +TER +checkFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) +{ + return isFrozen(view, account, mptIssue) ? (TER)tecLOCKED : (TER)tesSUCCESS; +} + +TER +checkFrozen(ReadView const& view, AccountID const& account, Asset const& asset) +{ + return std::visit( + [&](auto const& issue) { return checkFrozen(view, account, issue); }, asset.value()); +} + +bool +isAnyFrozen( + ReadView const& view, + std::initializer_list const& accounts, + Issue const& issue) +{ + for (auto const& account : accounts) + { + if (isFrozen(view, account, issue.currency, issue.account)) + return true; + } + return false; +} + +bool +isAnyFrozen( + ReadView const& view, + std::initializer_list const& accounts, + Asset const& asset, + int depth) +{ + return std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return isAnyFrozen(view, accounts, issue); + } + else + { + return isAnyFrozen(view, accounts, issue, depth); + } + }, + asset.value()); +} + +bool +isDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue, int depth) +{ + // Unlike IOUs, frozen / locked MPTs are not allowed to send or receive + // funds, so checking "deep frozen" is the same as checking "frozen". + return isFrozen(view, account, mptIssue, depth); +} + +bool +isDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset, int depth) +{ + return std::visit( + [&](auto const& issue) { return isDeepFrozen(view, account, issue, depth); }, + asset.value()); +} + +TER +checkDeepFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) +{ + return isDeepFrozen(view, account, mptIssue) ? (TER)tecLOCKED : (TER)tesSUCCESS; +} + +TER +checkDeepFrozen(ReadView const& view, AccountID const& account, Asset const& asset) +{ + return std::visit( + [&](auto const& issue) { return checkDeepFrozen(view, account, issue); }, asset.value()); +} + +//------------------------------------------------------------------------------ +// +// Account balance functions +// +//------------------------------------------------------------------------------ + +static SLE::const_pointer +getLineIfUsable( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer, + FreezeHandling zeroIfFrozen, + beast::Journal j) +{ + auto const sle = view.read(keylet::line(account, issuer, currency)); + + if (!sle) + { + return nullptr; + } + + if (zeroIfFrozen == fhZERO_IF_FROZEN) + { + if (isFrozen(view, account, currency, issuer) || + isDeepFrozen(view, account, currency, issuer)) + { + return nullptr; + } + + // when fixFrozenLPTokenTransfer is enabled, if currency is lptoken, + // we need to check if the associated assets have been frozen + if (view.rules().enabled(fixFrozenLPTokenTransfer)) + { + auto const sleIssuer = view.read(keylet::account(issuer)); + if (!sleIssuer) + { + return nullptr; // LCOV_EXCL_LINE + } + if (sleIssuer->isFieldPresent(sfAMMID)) + { + auto const sleAmm = view.read(keylet::amm((*sleIssuer)[sfAMMID])); + + if (!sleAmm || + isLPTokenFrozen( + view, + account, + (*sleAmm)[sfAsset].get(), + (*sleAmm)[sfAsset2].get())) + { + return nullptr; + } + } + } + } + + return sle; +} + +static STAmount +getTrustLineBalance( + ReadView const& view, + SLE::const_ref sle, + AccountID const& account, + Currency const& currency, + AccountID const& issuer, + bool includeOppositeLimit, + beast::Journal j) +{ + STAmount amount; + if (sle) + { + amount = sle->getFieldAmount(sfBalance); + bool const accountHigh = account > issuer; + auto const& oppositeField = accountHigh ? sfLowLimit : sfHighLimit; + if (accountHigh) + { + // Put balance in account terms. + amount.negate(); + } + if (includeOppositeLimit) + { + amount += sle->getFieldAmount(oppositeField); + } + amount.setIssuer(issuer); + } + else + { + amount.clear(Issue{currency, issuer}); + } + + JLOG(j.trace()) << "getTrustLineBalance:" << " account=" << to_string(account) + << " amount=" << amount.getFullText(); + + return view.balanceHook(account, issuer, amount); +} + +STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + Currency const& currency, + AccountID const& issuer, + FreezeHandling zeroIfFrozen, + beast::Journal j, + SpendableHandling includeFullBalance) +{ + STAmount amount; + if (isXRP(currency)) + { + return {xrpLiquid(view, account, 0, j)}; + } + + bool const returnSpendable = (includeFullBalance == shFULL_BALANCE); + if (returnSpendable && account == issuer) + { + // If the account is the issuer, then their limit is effectively + // infinite + return STAmount{Issue{currency, issuer}, STAmount::cMaxValue, STAmount::cMaxOffset}; + } + + // IOU: Return balance on trust line modulo freeze + SLE::const_pointer const sle = + getLineIfUsable(view, account, currency, issuer, zeroIfFrozen, j); + + return getTrustLineBalance(view, sle, account, currency, issuer, returnSpendable, j); +} + +STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + Issue const& issue, + FreezeHandling zeroIfFrozen, + beast::Journal j, + SpendableHandling includeFullBalance) +{ + return accountHolds( + view, account, issue.currency, issue.account, zeroIfFrozen, j, includeFullBalance); +} + +STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + MPTIssue const& mptIssue, + FreezeHandling zeroIfFrozen, + AuthHandling zeroIfUnauthorized, + beast::Journal j, + SpendableHandling includeFullBalance) +{ + bool const returnSpendable = (includeFullBalance == shFULL_BALANCE); + + if (returnSpendable && account == mptIssue.getIssuer()) + { + // if the account is the issuer, and the issuance exists, their limit is + // the issuance limit minus the outstanding value + auto const issuance = view.read(keylet::mptIssuance(mptIssue.getMptID())); + + if (!issuance) + { + return STAmount{mptIssue}; + } + return STAmount{ + mptIssue, + issuance->at(~sfMaximumAmount).value_or(maxMPTokenAmount) - + issuance->at(sfOutstandingAmount)}; + } + + STAmount amount; + + auto const sleMpt = view.read(keylet::mptoken(mptIssue.getMptID(), account)); + + if (!sleMpt) + { + amount.clear(mptIssue); + } + else if (zeroIfFrozen == fhZERO_IF_FROZEN && isFrozen(view, account, mptIssue)) + { + amount.clear(mptIssue); + } + else + { + amount = STAmount{mptIssue, sleMpt->getFieldU64(sfMPTAmount)}; + + // Only if auth check is needed, as it needs to do an additional read + // operation. Note featureSingleAssetVault will affect error codes. + if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED && + view.rules().enabled(featureSingleAssetVault)) + { + if (auto const err = requireAuth(view, mptIssue, account, AuthType::StrongAuth); + !isTesSuccess(err)) + amount.clear(mptIssue); + } + else if (zeroIfUnauthorized == ahZERO_IF_UNAUTHORIZED) + { + auto const sleIssuance = view.read(keylet::mptIssuance(mptIssue.getMptID())); + + // if auth is enabled on the issuance and mpt is not authorized, + // clear amount + if (sleIssuance && sleIssuance->isFlag(lsfMPTRequireAuth) && + !sleMpt->isFlag(lsfMPTAuthorized)) + amount.clear(mptIssue); + } + } + + return amount; +} + +[[nodiscard]] STAmount +accountHolds( + ReadView const& view, + AccountID const& account, + Asset const& asset, + FreezeHandling zeroIfFrozen, + AuthHandling zeroIfUnauthorized, + beast::Journal j, + SpendableHandling includeFullBalance) +{ + return std::visit( + [&](TIss const& value) { + if constexpr (std::is_same_v) + { + return accountHolds(view, account, value, zeroIfFrozen, j, includeFullBalance); + } + else if constexpr (std::is_same_v) + { + return accountHolds( + view, account, value, zeroIfFrozen, zeroIfUnauthorized, j, includeFullBalance); + } + }, + asset.value()); +} + +STAmount +accountFunds( + ReadView const& view, + AccountID const& id, + STAmount const& saDefault, + FreezeHandling freezeHandling, + beast::Journal j) +{ + if (!saDefault.native() && saDefault.getIssuer() == id) + return saDefault; + + return accountHolds( + view, id, saDefault.getCurrency(), saDefault.getIssuer(), freezeHandling, j); +} + +Rate +transferRate(ReadView const& view, STAmount const& amount) +{ + return std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return transferRate(view, issue.getIssuer()); + } + else + { + return transferRate(view, issue.getMptID()); + } + }, + amount.asset().value()); +} + +//------------------------------------------------------------------------------ +// +// Holding operations +// +//------------------------------------------------------------------------------ + +[[nodiscard]] TER +canAddHolding(ReadView const& view, Issue const& issue) +{ + if (issue.native()) + { + return tesSUCCESS; // No special checks for XRP + } + + auto const issuer = view.read(keylet::account(issue.getIssuer())); + if (!issuer) + { + return terNO_ACCOUNT; + } + if (!issuer->isFlag(lsfDefaultRipple)) + { + return terNO_RIPPLE; + } + + return tesSUCCESS; +} + +[[nodiscard]] TER +canAddHolding(ReadView const& view, Asset const& asset) +{ + return std::visit( + [&](TIss const& issue) -> TER { return canAddHolding(view, issue); }, + asset.value()); +} + +TER +addEmptyHolding( + ApplyView& view, + AccountID const& accountID, + XRPAmount priorBalance, + Asset const& asset, + beast::Journal journal) +{ + return std::visit( + [&](TIss const& issue) -> TER { + return addEmptyHolding(view, accountID, priorBalance, issue, journal); + }, + asset.value()); +} + +TER +removeEmptyHolding( + ApplyView& view, + AccountID const& accountID, + Asset const& asset, + beast::Journal journal) +{ + return std::visit( + [&](TIss const& issue) -> TER { + return removeEmptyHolding(view, accountID, issue, journal); + }, + asset.value()); +} + +//------------------------------------------------------------------------------ +// +// Authorization and transfer checks +// +//------------------------------------------------------------------------------ + +TER +requireAuth(ReadView const& view, Asset const& asset, AccountID const& account, AuthType authType) +{ + return std::visit( + [&](TIss const& issue_) { + return requireAuth(view, issue_, account, authType); + }, + asset.value()); +} + +TER +canTransfer(ReadView const& view, Asset const& asset, AccountID const& from, AccountID const& to) +{ + return std::visit( + [&](TIss const& issue) -> TER { + return canTransfer(view, issue, from, to); + }, + asset.value()); +} + +//------------------------------------------------------------------------------ +// +// Money Transfers +// +//------------------------------------------------------------------------------ + +// Direct send w/o fees: +// - Redeeming IOUs and/or sending sender's own IOUs. +// - Create trust line if needed. +// --> bCheckIssuer : normally require issuer to be involved. +static TER +rippleCreditIOU( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + bool bCheckIssuer, + beast::Journal j) +{ + AccountID const& issuer = saAmount.getIssuer(); + Currency const& currency = saAmount.getCurrency(); + + // Make sure issuer is involved. + XRPL_ASSERT( + !bCheckIssuer || uSenderID == issuer || uReceiverID == issuer, + "xrpl::rippleCreditIOU : matching issuer or don't care"); + (void)issuer; + + // Disallow sending to self. + XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleCreditIOU : sender is not receiver"); + + bool const bSenderHigh = uSenderID > uReceiverID; + auto const index = keylet::line(uSenderID, uReceiverID, currency); + + XRPL_ASSERT( + !isXRP(uSenderID) && uSenderID != noAccount(), "xrpl::rippleCreditIOU : sender is not XRP"); + XRPL_ASSERT( + !isXRP(uReceiverID) && uReceiverID != noAccount(), + "xrpl::rippleCreditIOU : receiver is not XRP"); + + // If the line exists, modify it accordingly. + if (auto const sleRippleState = view.peek(index)) + { + STAmount saBalance = sleRippleState->getFieldAmount(sfBalance); + + if (bSenderHigh) + saBalance.negate(); // Put balance in sender terms. + + view.creditHook(uSenderID, uReceiverID, saAmount, saBalance); + + STAmount const saBefore = saBalance; + + saBalance -= saAmount; + + JLOG(j.trace()) << "rippleCreditIOU: " << to_string(uSenderID) << " -> " + << to_string(uReceiverID) << " : before=" << saBefore.getFullText() + << " amount=" << saAmount.getFullText() + << " after=" << saBalance.getFullText(); + + std::uint32_t const uFlags(sleRippleState->getFieldU32(sfFlags)); + bool bDelete = false; + + // FIXME This NEEDS to be cleaned up and simplified. It's impossible + // for anyone to understand. + if (saBefore > beast::zero + // Sender balance was positive. + && saBalance <= beast::zero + // Sender is zero or negative. + && (uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) + // Sender reserve is set. + && static_cast(uFlags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) != + static_cast( + view.read(keylet::account(uSenderID))->getFlags() & lsfDefaultRipple) && + !(uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) && + !sleRippleState->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit) + // Sender trust limit is 0. + && !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) + // Sender quality in is 0. + && !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut)) + // Sender quality out is 0. + { + // Clear the reserve of the sender, possibly delete the line! + adjustOwnerCount(view, view.peek(keylet::account(uSenderID)), -1, j); + + // Clear reserve flag. + sleRippleState->setFieldU32( + sfFlags, uFlags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve)); + + // Balance is zero, receiver reserve is clear. + bDelete = !saBalance // Balance is zero. + && !(uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)); + // Receiver reserve is clear. + } + + if (bSenderHigh) + saBalance.negate(); + + // Want to reflect balance to zero even if we are deleting line. + sleRippleState->setFieldAmount(sfBalance, saBalance); + // ONLY: Adjust ripple balance. + + if (bDelete) + { + return trustDelete( + view, + sleRippleState, + bSenderHigh ? uReceiverID : uSenderID, + !bSenderHigh ? uReceiverID : uSenderID, + j); + } + + view.update(sleRippleState); + return tesSUCCESS; + } + + STAmount const saReceiverLimit(Issue{currency, uReceiverID}); + STAmount saBalance{saAmount}; + + saBalance.setIssuer(noAccount()); + + JLOG(j.debug()) << "rippleCreditIOU: " + "create line: " + << to_string(uSenderID) << " -> " << to_string(uReceiverID) << " : " + << saAmount.getFullText(); + + auto const sleAccount = view.peek(keylet::account(uReceiverID)); + if (!sleAccount) + return tefINTERNAL; // LCOV_EXCL_LINE + + bool const noRipple = (sleAccount->getFlags() & lsfDefaultRipple) == 0; + + return trustCreate( + view, + bSenderHigh, + uSenderID, + uReceiverID, + index.key, + sleAccount, + false, + noRipple, + false, + false, + saBalance, + saReceiverLimit, + 0, + 0, + j); +} + +// Send regardless of limits. +// --> saAmount: Amount/currency/issuer to deliver to receiver. +// <-- saActual: Amount actually cost. Sender pays fees. +static TER +rippleSendIOU( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + STAmount& saActual, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + auto const& issuer = saAmount.getIssuer(); + + XRPL_ASSERT( + !isXRP(uSenderID) && !isXRP(uReceiverID), + "xrpl::rippleSendIOU : neither sender nor receiver is XRP"); + XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleSendIOU : sender is not receiver"); + + if (uSenderID == issuer || uReceiverID == issuer || issuer == noAccount()) + { + // Direct send: redeeming IOUs and/or sending own IOUs. + auto const ter = rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, false, j); + if (!isTesSuccess(ter)) + return ter; + saActual = saAmount; + return tesSUCCESS; + } + + // Sending 3rd party IOUs: transit. + + // Calculate the amount to transfer accounting + // for any transfer fees if the fee is not waived: + saActual = (waiveFee == WaiveTransferFee::Yes) ? saAmount + : multiply(saAmount, transferRate(view, issuer)); + + JLOG(j.debug()) << "rippleSendIOU> " << to_string(uSenderID) << " - > " + << to_string(uReceiverID) << " : deliver=" << saAmount.getFullText() + << " cost=" << saActual.getFullText(); + + TER terResult = rippleCreditIOU(view, issuer, uReceiverID, saAmount, true, j); + + if (tesSUCCESS == terResult) + terResult = rippleCreditIOU(view, uSenderID, issuer, saActual, true, j); + + return terResult; +} + +// Send regardless of limits. +// --> receivers: Amount/currency/issuer to deliver to receivers. +// <-- saActual: Amount actually cost to sender. Sender pays fees. +static TER +rippleSendMultiIOU( + ApplyView& view, + AccountID const& senderID, + Issue const& issue, + MultiplePaymentDestinations const& receivers, + STAmount& actual, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + auto const& issuer = issue.getIssuer(); + + XRPL_ASSERT(!isXRP(senderID), "xrpl::rippleSendMultiIOU : sender is not XRP"); + + // These may diverge + STAmount takeFromSender{issue}; + actual = takeFromSender; + + // Failures return immediately. + for (auto const& r : receivers) + { + auto const& receiverID = r.first; + STAmount amount{issue, r.second}; + + /* If we aren't sending anything or if the sender is the same as the + * receiver then we don't need to do anything. + */ + if (!amount || (senderID == receiverID)) + continue; + + XRPL_ASSERT(!isXRP(receiverID), "xrpl::rippleSendMultiIOU : receiver is not XRP"); + + if (senderID == issuer || receiverID == issuer || issuer == noAccount()) + { + // Direct send: redeeming IOUs and/or sending own IOUs. + if (auto const ter = rippleCreditIOU(view, senderID, receiverID, amount, false, j)) + return ter; + actual += amount; + // Do not add amount to takeFromSender, because rippleCreditIOU took + // it. + + continue; + } + + // Sending 3rd party IOUs: transit. + + // Calculate the amount to transfer accounting + // for any transfer fees if the fee is not waived: + STAmount actualSend = (waiveFee == WaiveTransferFee::Yes) + ? amount + : multiply(amount, transferRate(view, issuer)); + actual += actualSend; + takeFromSender += actualSend; + + JLOG(j.debug()) << "rippleSendMultiIOU> " << to_string(senderID) << " - > " + << to_string(receiverID) << " : deliver=" << amount.getFullText() + << " cost=" << actual.getFullText(); + + if (TER const terResult = rippleCreditIOU(view, issuer, receiverID, amount, true, j)) + return terResult; + } + + if (senderID != issuer && takeFromSender) + { + if (TER const terResult = rippleCreditIOU(view, senderID, issuer, takeFromSender, true, j)) + return terResult; + } + + return tesSUCCESS; +} + +static TER +accountSendIOU( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + if (view.rules().enabled(fixAMMv1_1)) + { + if (saAmount < beast::zero || saAmount.holds()) + { + return tecINTERNAL; // LCOV_EXCL_LINE + } + } + else + { + // LCOV_EXCL_START + XRPL_ASSERT( + saAmount >= beast::zero && !saAmount.holds(), + "xrpl::accountSendIOU : minimum amount and not MPT"); + // LCOV_EXCL_STOP + } + + /* If we aren't sending anything or if the sender is the same as the + * receiver then we don't need to do anything. + */ + if (!saAmount || (uSenderID == uReceiverID)) + return tesSUCCESS; + + if (!saAmount.native()) + { + STAmount saActual; + + JLOG(j.trace()) << "accountSendIOU: " << to_string(uSenderID) << " -> " + << to_string(uReceiverID) << " : " << saAmount.getFullText(); + + return rippleSendIOU(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee); + } + + /* XRP send which does not check reserve and can do pure adjustment. + * Note that sender or receiver may be null and this not a mistake; this + * setup is used during pathfinding and it is carefully controlled to + * ensure that transfers are balanced. + */ + TER terResult(tesSUCCESS); + + SLE::pointer sender = + uSenderID != beast::zero ? view.peek(keylet::account(uSenderID)) : SLE::pointer(); + SLE::pointer receiver = + uReceiverID != beast::zero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer(); + + if (auto stream = j.trace()) + { + std::string sender_bal("-"); + std::string receiver_bal("-"); + + if (sender) + sender_bal = sender->getFieldAmount(sfBalance).getFullText(); + + if (receiver) + receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); + + stream << "accountSendIOU> " << to_string(uSenderID) << " (" << sender_bal << ") -> " + << to_string(uReceiverID) << " (" << receiver_bal + << ") : " << saAmount.getFullText(); + } + + if (sender) + { + if (sender->getFieldAmount(sfBalance) < saAmount) + { + // 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 + { + auto const sndBal = sender->getFieldAmount(sfBalance); + view.creditHook(uSenderID, xrpAccount(), saAmount, sndBal); + + // Decrement XRP balance. + sender->setFieldAmount(sfBalance, sndBal - saAmount); + view.update(sender); + } + } + + if (tesSUCCESS == terResult && receiver) + { + // Increment XRP balance. + auto const rcvBal = receiver->getFieldAmount(sfBalance); + receiver->setFieldAmount(sfBalance, rcvBal + saAmount); + view.creditHook(xrpAccount(), uReceiverID, saAmount, -rcvBal); + + view.update(receiver); + } + + if (auto stream = j.trace()) + { + std::string sender_bal("-"); + std::string receiver_bal("-"); + + if (sender) + sender_bal = sender->getFieldAmount(sfBalance).getFullText(); + + if (receiver) + receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); + + stream << "accountSendIOU< " << to_string(uSenderID) << " (" << sender_bal << ") -> " + << to_string(uReceiverID) << " (" << receiver_bal + << ") : " << saAmount.getFullText(); + } + + return terResult; +} + +static TER +accountSendMultiIOU( + ApplyView& view, + AccountID const& senderID, + Issue const& issue, + MultiplePaymentDestinations const& receivers, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + XRPL_ASSERT_PARTS( + receivers.size() > 1, "xrpl::accountSendMultiIOU", "multiple recipients provided"); + + if (!issue.native()) + { + STAmount actual; + JLOG(j.trace()) << "accountSendMultiIOU: " << to_string(senderID) << " sending " + << receivers.size() << " IOUs"; + + return rippleSendMultiIOU(view, senderID, issue, receivers, actual, j, waiveFee); + } + + /* XRP send which does not check reserve and can do pure adjustment. + * Note that sender or receiver may be null and this not a mistake; this + * setup could be used during pathfinding and it is carefully controlled to + * ensure that transfers are balanced. + */ + + SLE::pointer sender = + senderID != beast::zero ? view.peek(keylet::account(senderID)) : SLE::pointer(); + + if (auto stream = j.trace()) + { + std::string sender_bal("-"); + + if (sender) + sender_bal = sender->getFieldAmount(sfBalance).getFullText(); + + stream << "accountSendMultiIOU> " << to_string(senderID) << " (" << sender_bal << ") -> " + << receivers.size() << " receivers."; + } + + // Failures return immediately. + STAmount takeFromSender{issue}; + for (auto const& r : receivers) + { + auto const& receiverID = r.first; + STAmount amount{issue, r.second}; + + if (amount < beast::zero) + { + return tecINTERNAL; // LCOV_EXCL_LINE + } + + /* If we aren't sending anything or if the sender is the same as the + * receiver then we don't need to do anything. + */ + if (!amount || (senderID == receiverID)) + continue; + + SLE::pointer receiver = + receiverID != beast::zero ? view.peek(keylet::account(receiverID)) : SLE::pointer(); + + if (auto stream = j.trace()) + { + std::string receiver_bal("-"); + + if (receiver) + receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); + + stream << "accountSendMultiIOU> " << to_string(senderID) << " -> " + << to_string(receiverID) << " (" << receiver_bal + << ") : " << amount.getFullText(); + } + + if (receiver) + { + // Increment XRP balance. + auto const rcvBal = receiver->getFieldAmount(sfBalance); + receiver->setFieldAmount(sfBalance, rcvBal + amount); + view.creditHook(xrpAccount(), receiverID, amount, -rcvBal); + + view.update(receiver); + + // Take what is actually sent + takeFromSender += amount; + } + + if (auto stream = j.trace()) + { + std::string receiver_bal("-"); + + if (receiver) + receiver_bal = receiver->getFieldAmount(sfBalance).getFullText(); + + stream << "accountSendMultiIOU< " << to_string(senderID) << " -> " + << to_string(receiverID) << " (" << receiver_bal + << ") : " << amount.getFullText(); + } + } + + if (sender) + { + if (sender->getFieldAmount(sfBalance) < takeFromSender) + { + return TER{tecFAILED_PROCESSING}; + } + auto const sndBal = sender->getFieldAmount(sfBalance); + view.creditHook(senderID, xrpAccount(), takeFromSender, sndBal); + + // Decrement XRP balance. + sender->setFieldAmount(sfBalance, sndBal - takeFromSender); + view.update(sender); + } + + if (auto stream = j.trace()) + { + std::string sender_bal("-"); + + if (sender) + sender_bal = sender->getFieldAmount(sfBalance).getFullText(); + + stream << "accountSendMultiIOU< " << to_string(senderID) << " (" << sender_bal << ") -> " + << receivers.size() << " receivers."; + } + return tesSUCCESS; +} + +static TER +rippleCreditMPT( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + beast::Journal j) +{ + // Do not check MPT authorization here - it must have been checked earlier + auto const mptID = keylet::mptIssuance(saAmount.get().getMptID()); + auto const& issuer = saAmount.getIssuer(); + auto sleIssuance = view.peek(mptID); + if (!sleIssuance) + return tecOBJECT_NOT_FOUND; + if (uSenderID == issuer) + { + (*sleIssuance)[sfOutstandingAmount] += saAmount.mpt().value(); + view.update(sleIssuance); + } + else + { + auto const mptokenID = keylet::mptoken(mptID.key, uSenderID); + if (auto sle = view.peek(mptokenID)) + { + auto const amt = sle->getFieldU64(sfMPTAmount); + auto const pay = saAmount.mpt().value(); + if (amt < pay) + return tecINSUFFICIENT_FUNDS; + (*sle)[sfMPTAmount] = amt - pay; + view.update(sle); + } + else + { + return tecNO_AUTH; + } + } + + if (uReceiverID == issuer) + { + auto const outstanding = sleIssuance->getFieldU64(sfOutstandingAmount); + auto const redeem = saAmount.mpt().value(); + if (outstanding >= redeem) + { + sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - redeem); + view.update(sleIssuance); + } + else + { + return tecINTERNAL; // LCOV_EXCL_LINE + } + } + else + { + auto const mptokenID = keylet::mptoken(mptID.key, uReceiverID); + if (auto sle = view.peek(mptokenID)) + { + (*sle)[sfMPTAmount] += saAmount.mpt().value(); + view.update(sle); + } + else + { + return tecNO_AUTH; + } + } + + return tesSUCCESS; +} + +static TER +rippleSendMPT( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + STAmount& saActual, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + XRPL_ASSERT(uSenderID != uReceiverID, "xrpl::rippleSendMPT : sender is not receiver"); + + // Safe to get MPT since rippleSendMPT is only called by accountSendMPT + auto const& issuer = saAmount.getIssuer(); + + auto const sle = view.read(keylet::mptIssuance(saAmount.get().getMptID())); + if (!sle) + return tecOBJECT_NOT_FOUND; + + if (uSenderID == issuer || uReceiverID == issuer) + { + // if sender is issuer, check that the new OutstandingAmount will not + // exceed MaximumAmount + if (uSenderID == issuer) + { + auto const sendAmount = saAmount.mpt().value(); + auto const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount); + if (sendAmount > maximumAmount || + sle->getFieldU64(sfOutstandingAmount) > maximumAmount - sendAmount) + return tecPATH_DRY; + } + + // Direct send: redeeming MPTs and/or sending own MPTs. + auto const ter = rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j); + if (!isTesSuccess(ter)) + return ter; + saActual = saAmount; + return tesSUCCESS; + } + + // Sending 3rd party MPTs: transit. + saActual = (waiveFee == WaiveTransferFee::Yes) + ? saAmount + : multiply(saAmount, transferRate(view, saAmount.get().getMptID())); + + JLOG(j.debug()) << "rippleSendMPT> " << to_string(uSenderID) << " - > " + << to_string(uReceiverID) << " : deliver=" << saAmount.getFullText() + << " cost=" << saActual.getFullText(); + + if (auto const terResult = rippleCreditMPT(view, issuer, uReceiverID, saAmount, j); + !isTesSuccess(terResult)) + return terResult; + + return rippleCreditMPT(view, uSenderID, issuer, saActual, j); +} + +static TER +rippleSendMultiMPT( + ApplyView& view, + AccountID const& senderID, + MPTIssue const& mptIssue, + MultiplePaymentDestinations const& receivers, + STAmount& actual, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + // Safe to get MPT since rippleSendMultiMPT is only called by + // accountSendMultiMPT + auto const& issuer = mptIssue.getIssuer(); + + auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID())); + if (!sle) + return tecOBJECT_NOT_FOUND; + + // These may diverge + STAmount takeFromSender{mptIssue}; + actual = takeFromSender; + + for (auto const& r : receivers) + { + auto const& receiverID = r.first; + STAmount amount{mptIssue, r.second}; + + if (amount < beast::zero) + { + return tecINTERNAL; // LCOV_EXCL_LINE + } + + /* If we aren't sending anything or if the sender is the same as the + * receiver then we don't need to do anything. + */ + if (!amount || (senderID == receiverID)) + continue; + + if (senderID == issuer || receiverID == issuer) + { + // if sender is issuer, check that the new OutstandingAmount will + // not exceed MaximumAmount + if (senderID == issuer) + { + XRPL_ASSERT_PARTS( + takeFromSender == beast::zero, + "xrpl::rippleSendMultiMPT", + "sender == issuer, takeFromSender == zero"); + auto const sendAmount = amount.mpt().value(); + auto const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount); + if (sendAmount > maximumAmount || + sle->getFieldU64(sfOutstandingAmount) > maximumAmount - sendAmount) + return tecPATH_DRY; + } + + // Direct send: redeeming MPTs and/or sending own MPTs. + if (auto const ter = rippleCreditMPT(view, senderID, receiverID, amount, j)) + return ter; + actual += amount; + // Do not add amount to takeFromSender, because rippleCreditMPT took + // it + + continue; + } + + // Sending 3rd party MPTs: transit. + STAmount actualSend = (waiveFee == WaiveTransferFee::Yes) + ? amount + : multiply(amount, transferRate(view, amount.get().getMptID())); + actual += actualSend; + takeFromSender += actualSend; + + JLOG(j.debug()) << "rippleSendMultiMPT> " << to_string(senderID) << " - > " + << to_string(receiverID) << " : deliver=" << amount.getFullText() + << " cost=" << actualSend.getFullText(); + + if (auto const terResult = rippleCreditMPT(view, issuer, receiverID, amount, j)) + return terResult; + } + if (senderID != issuer && takeFromSender) + { + if (TER const terResult = rippleCreditMPT(view, senderID, issuer, takeFromSender, j)) + return terResult; + } + + return tesSUCCESS; +} + +static TER +accountSendMPT( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + XRPL_ASSERT( + saAmount >= beast::zero && saAmount.holds(), + "xrpl::accountSendMPT : minimum amount and MPT"); + + /* If we aren't sending anything or if the sender is the same as the + * receiver then we don't need to do anything. + */ + if (!saAmount || (uSenderID == uReceiverID)) + return tesSUCCESS; + + STAmount saActual{saAmount.asset()}; + + return rippleSendMPT(view, uSenderID, uReceiverID, saAmount, saActual, j, waiveFee); +} + +static TER +accountSendMultiMPT( + ApplyView& view, + AccountID const& senderID, + MPTIssue const& mptIssue, + MultiplePaymentDestinations const& receivers, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + STAmount actual; + + return rippleSendMultiMPT(view, senderID, mptIssue, receivers, actual, j, waiveFee); +} + +//------------------------------------------------------------------------------ +// +// Public Dispatcher Functions +// +//------------------------------------------------------------------------------ + +TER +rippleCredit( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + bool bCheckIssuer, + beast::Journal j) +{ + return std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, bCheckIssuer, j); + } + else + { + XRPL_ASSERT(!bCheckIssuer, "xrpl::rippleCredit : not checking issuer"); + return rippleCreditMPT(view, uSenderID, uReceiverID, saAmount, j); + } + }, + saAmount.asset().value()); +} + +TER +accountSend( + ApplyView& view, + AccountID const& uSenderID, + AccountID const& uReceiverID, + STAmount const& saAmount, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + return std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return accountSendIOU(view, uSenderID, uReceiverID, saAmount, j, waiveFee); + } + else + { + return accountSendMPT(view, uSenderID, uReceiverID, saAmount, j, waiveFee); + } + }, + saAmount.asset().value()); +} + +TER +accountSendMulti( + ApplyView& view, + AccountID const& senderID, + Asset const& asset, + MultiplePaymentDestinations const& receivers, + beast::Journal j, + WaiveTransferFee waiveFee) +{ + XRPL_ASSERT_PARTS( + receivers.size() > 1, "xrpl::accountSendMulti", "multiple recipients provided"); + return std::visit( + [&](TIss const& issue) { + if constexpr (std::is_same_v) + { + return accountSendMultiIOU(view, senderID, issue, receivers, j, waiveFee); + } + else + { + return accountSendMultiMPT(view, senderID, issue, receivers, j, waiveFee); + } + }, + asset.value()); +} + +TER +transferXRP( + ApplyView& view, + AccountID const& from, + AccountID const& to, + STAmount const& amount, + beast::Journal j) +{ + XRPL_ASSERT(from != beast::zero, "xrpl::transferXRP : nonzero from account"); + XRPL_ASSERT(to != beast::zero, "xrpl::transferXRP : nonzero to account"); + XRPL_ASSERT(from != to, "xrpl::transferXRP : sender is not receiver"); + XRPL_ASSERT(amount.native(), "xrpl::transferXRP : amount is XRP"); + + SLE::pointer const sender = view.peek(keylet::account(from)); + SLE::pointer const receiver = view.peek(keylet::account(to)); + if (!sender || !receiver) + return tefINTERNAL; // LCOV_EXCL_LINE + + JLOG(j.trace()) << "transferXRP: " << to_string(from) << " -> " << to_string(to) + << ") : " << amount.getFullText(); + + if (sender->getFieldAmount(sfBalance) < amount) + { + // 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. + sender->setFieldAmount(sfBalance, sender->getFieldAmount(sfBalance) - amount); + view.update(sender); + + receiver->setFieldAmount(sfBalance, receiver->getFieldAmount(sfBalance) + amount); + view.update(receiver); + + return tesSUCCESS; +} + +} // namespace xrpl diff --git a/src/libxrpl/ledger/helpers/VaultHelpers.cpp b/src/libxrpl/ledger/helpers/VaultHelpers.cpp new file mode 100644 index 0000000000..3ded720289 --- /dev/null +++ b/src/libxrpl/ledger/helpers/VaultHelpers.cpp @@ -0,0 +1,112 @@ +#include +// +#include +#include +#include + +namespace xrpl { + +[[nodiscard]] std::optional +assetsToSharesDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets) +{ + XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); + XRPL_ASSERT( + assets.asset() == vault->at(sfAsset), + "xrpl::assetsToSharesDeposit : assets and vault match"); + if (assets.negative() || assets.asset() != vault->at(sfAsset)) + return std::nullopt; // LCOV_EXCL_LINE + + Number const assetTotal = vault->at(sfAssetsTotal); + STAmount shares{vault->at(sfShareMPTID)}; + if (assetTotal == 0) + { + return STAmount{ + shares.asset(), + Number(assets.mantissa(), assets.exponent() + vault->at(sfScale)).truncate()}; + } + + Number const shareTotal = issuance->at(sfOutstandingAmount); + shares = ((shareTotal * assets) / assetTotal).truncate(); + return shares; +} + +[[nodiscard]] std::optional +sharesToAssetsDeposit( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares) +{ + XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); + XRPL_ASSERT( + shares.asset() == vault->at(sfShareMPTID), + "xrpl::sharesToAssetsDeposit : shares and vault match"); + if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) + return std::nullopt; // LCOV_EXCL_LINE + + Number const assetTotal = vault->at(sfAssetsTotal); + STAmount assets{vault->at(sfAsset)}; + if (assetTotal == 0) + { + return STAmount{ + assets.asset(), shares.mantissa(), shares.exponent() - vault->at(sfScale), false}; + } + + Number const shareTotal = issuance->at(sfOutstandingAmount); + assets = (assetTotal * shares) / shareTotal; + return assets; +} + +[[nodiscard]] std::optional +assetsToSharesWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& assets, + TruncateShares truncate) +{ + XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesWithdraw : non-negative assets"); + XRPL_ASSERT( + assets.asset() == vault->at(sfAsset), + "xrpl::assetsToSharesWithdraw : assets and vault match"); + if (assets.negative() || assets.asset() != vault->at(sfAsset)) + return std::nullopt; // LCOV_EXCL_LINE + + Number assetTotal = vault->at(sfAssetsTotal); + assetTotal -= vault->at(sfLossUnrealized); + STAmount shares{vault->at(sfShareMPTID)}; + if (assetTotal == 0) + return shares; + Number const shareTotal = issuance->at(sfOutstandingAmount); + Number result = (shareTotal * assets) / assetTotal; + if (truncate == TruncateShares::yes) + result = result.truncate(); + shares = result; + return shares; +} + +[[nodiscard]] std::optional +sharesToAssetsWithdraw( + std::shared_ptr const& vault, + std::shared_ptr const& issuance, + STAmount const& shares) +{ + XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); + XRPL_ASSERT( + shares.asset() == vault->at(sfShareMPTID), + "xrpl::sharesToAssetsWithdraw : shares and vault match"); + if (shares.negative() || shares.asset() != vault->at(sfShareMPTID)) + return std::nullopt; // LCOV_EXCL_LINE + + Number assetTotal = vault->at(sfAssetsTotal); + assetTotal -= vault->at(sfLossUnrealized); + STAmount assets{vault->at(sfAsset)}; + if (assetTotal == 0) + return assets; + Number const shareTotal = issuance->at(sfOutstandingAmount); + assets = (assetTotal * shares) / shareTotal; + return assets; +} + +} // namespace xrpl diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index ff42441e2f..1c937f9380 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/invariants/PermissionedDomainInvariant.cpp b/src/libxrpl/tx/invariants/PermissionedDomainInvariant.cpp index d4cbe81f9b..02eaee0552 100644 --- a/src/libxrpl/tx/invariants/PermissionedDomainInvariant.cpp +++ b/src/libxrpl/tx/invariants/PermissionedDomainInvariant.cpp @@ -1,7 +1,7 @@ #include // #include -#include +#include #include #include #include diff --git a/src/libxrpl/tx/paths/Flow.cpp b/src/libxrpl/tx/paths/Flow.cpp index fc33585179..5a706ea812 100644 --- a/src/libxrpl/tx/paths/Flow.cpp +++ b/src/libxrpl/tx/paths/Flow.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/account/AccountDelete.cpp b/src/libxrpl/tx/transactors/account/AccountDelete.cpp index b50b254ec9..822b6121de 100644 --- a/src/libxrpl/tx/transactors/account/AccountDelete.cpp +++ b/src/libxrpl/tx/transactors/account/AccountDelete.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp index 1c5608c09f..26ecf311fe 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp index 5dafd146c7..8d70e00d43 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp b/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp index d273135aa9..5f78ba6757 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/dex/PermissionedDEXHelpers.cpp b/src/libxrpl/tx/transactors/dex/PermissionedDEXHelpers.cpp index 37db2d632f..d857795e39 100644 --- a/src/libxrpl/tx/transactors/dex/PermissionedDEXHelpers.cpp +++ b/src/libxrpl/tx/transactors/dex/PermissionedDEXHelpers.cpp @@ -1,4 +1,4 @@ -#include +#include #include namespace xrpl { diff --git a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp index 680a20a077..e85b00e606 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp index 57d9cbc173..ca64c6bb56 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp @@ -1,6 +1,6 @@ #include // -#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index 2b9a8dfd3a..55a27e28ed 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -1,6 +1,6 @@ #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment/Payment.cpp b/src/libxrpl/tx/transactors/payment/Payment.cpp index 8bf86b7b38..6fc6d995fa 100644 --- a/src/libxrpl/tx/transactors/payment/Payment.cpp +++ b/src/libxrpl/tx/transactors/payment/Payment.cpp @@ -1,6 +1,6 @@ #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp index a97b4c9e56..6ba489bbc3 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp index c27c884b10..f4d4f6a805 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp @@ -1,7 +1,7 @@ #include // -#include #include +#include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp index 66f4fb09b8..bceaa354a1 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp index a473ac7c36..2507563bde 100644 --- a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include #include diff --git a/src/test/app/Credentials_test.cpp b/src/test/app/Credentials_test.cpp index 3c3d8b6df8..d23431f68e 100644 --- a/src/test/app/Credentials_test.cpp +++ b/src/test/app/Credentials_test.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/xrpld/app/paths/detail/DirectStep.cpp b/src/xrpld/app/paths/detail/DirectStep.cpp index a07e5824d6..142f07bf73 100644 --- a/src/xrpld/app/paths/detail/DirectStep.cpp +++ b/src/xrpld/app/paths/detail/DirectStep.cpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/xrpld/app/paths/detail/XRPEndpointStep.cpp b/src/xrpld/app/paths/detail/XRPEndpointStep.cpp index 6eaa0d04c4..e37a184e07 100644 --- a/src/xrpld/app/paths/detail/XRPEndpointStep.cpp +++ b/src/xrpld/app/paths/detail/XRPEndpointStep.cpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/DepositAuthorized.cpp b/src/xrpld/rpc/handlers/DepositAuthorized.cpp index 7ab7e30c8a..080b136964 100644 --- a/src/xrpld/rpc/handlers/DepositAuthorized.cpp +++ b/src/xrpld/rpc/handlers/DepositAuthorized.cpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/LedgerEntry.cpp b/src/xrpld/rpc/handlers/LedgerEntry.cpp index 8e3b7f214d..640369c04b 100644 --- a/src/xrpld/rpc/handlers/LedgerEntry.cpp +++ b/src/xrpld/rpc/handlers/LedgerEntry.cpp @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include #include From dcfcdab14e7944ac4a2a93af8844bec3ec01b7f6 Mon Sep 17 00:00:00 2001 From: Olek <115580134+oleks-rip@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:29:34 -0400 Subject: [PATCH 03/10] fix: Remove superfluous view update from credentials (#6545) --- .../tx/transactors/credentials/CredentialCreate.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp index 8d70e00d43..af5c786c59 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp @@ -146,14 +146,15 @@ CredentialCreate::doApply() } else { + // Added to both dirs, owned only by issuer. CredentialAccept will transfer ownership to + // subject. CredentialDelete will remove from both dirs and decrement 1 ownerCount. auto const page = view().dirInsert(keylet::ownerDir(subject), credentialKey, describeOwnerDir(subject)); - JLOG(j_.trace()) << "Adding Credential to owner directory " << to_string(credentialKey.key) - << ": " << (page ? "success" : "failure"); + JLOG(j_.trace()) << "Adding Credential to subject directory " + << to_string(credentialKey.key) << ": " << (page ? "success" : "failure"); if (!page) return tecDIR_FULL; sleCred->setFieldU64(sfSubjectNode, *page); - view().update(view().peek(keylet::account(subject))); } view().insert(sleCred); From 8b986e4ab0bceae1310f10ee43bcbce35034f4c6 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 24 Mar 2026 03:20:32 -0700 Subject: [PATCH 04/10] refactor: Improve imports to only call the needed helpers (#6624) --- include/xrpl/ledger/View.h | 19 +++++-------------- include/xrpl/tx/paths/detail/StrandFlow.h | 1 + include/xrpl/tx/transactors/dex/AMMUtils.h | 1 + include/xrpl/tx/transactors/dex/AMMWithdraw.h | 1 + src/libxrpl/ledger/AcceptedLedgerTx.cpp | 1 + src/libxrpl/ledger/BookDirs.cpp | 1 + src/libxrpl/ledger/View.cpp | 3 +++ src/libxrpl/tx/Transactor.cpp | 3 +++ src/libxrpl/tx/invariants/InvariantCheck.cpp | 2 ++ src/libxrpl/tx/invariants/LoanInvariant.cpp | 1 + src/libxrpl/tx/invariants/VaultInvariant.cpp | 1 + src/libxrpl/tx/paths/BookTip.cpp | 2 ++ src/libxrpl/tx/paths/OfferStream.cpp | 2 ++ .../tx/transactors/account/AccountDelete.cpp | 2 ++ .../tx/transactors/account/AccountSet.cpp | 1 + .../tx/transactors/account/SignerListSet.cpp | 3 ++- .../tx/transactors/bridge/XChainBridge.cpp | 3 ++- .../tx/transactors/check/CheckCancel.cpp | 1 + .../tx/transactors/check/CheckCash.cpp | 2 ++ .../tx/transactors/check/CheckCreate.cpp | 3 +++ .../credentials/CredentialAccept.cpp | 2 +- .../credentials/CredentialCreate.cpp | 3 ++- .../tx/transactors/delegate/DelegateSet.cpp | 2 ++ src/libxrpl/tx/transactors/dex/AMMCreate.cpp | 1 + src/libxrpl/tx/transactors/dex/AMMDeposit.cpp | 1 + .../tx/transactors/dex/OfferCancel.cpp | 1 + .../tx/transactors/dex/OfferCreate.cpp | 4 ++++ src/libxrpl/tx/transactors/did/DIDDelete.cpp | 2 +- src/libxrpl/tx/transactors/did/DIDSet.cpp | 3 ++- .../tx/transactors/escrow/EscrowCancel.cpp | 4 ++++ .../tx/transactors/escrow/EscrowCreate.cpp | 5 +++++ .../tx/transactors/escrow/EscrowFinish.cpp | 3 +++ .../tx/transactors/escrow/EscrowHelpers.h | 4 ++++ .../lending/LoanBrokerCoverClawback.cpp | 1 + .../lending/LoanBrokerCoverDeposit.cpp | 1 + .../lending/LoanBrokerCoverWithdraw.cpp | 2 ++ .../transactors/lending/LoanBrokerDelete.cpp | 2 ++ .../tx/transactors/lending/LoanBrokerSet.cpp | 2 ++ .../tx/transactors/lending/LoanDelete.cpp | 1 + .../tx/transactors/lending/LoanManage.cpp | 1 + .../tx/transactors/lending/LoanPay.cpp | 1 + .../tx/transactors/lending/LoanSet.cpp | 2 ++ .../tx/transactors/nft/NFTokenAcceptOffer.cpp | 1 + .../tx/transactors/nft/NFTokenUtils.cpp | 4 ++++ .../tx/transactors/oracle/OracleDelete.cpp | 1 + .../tx/transactors/oracle/OracleSet.cpp | 2 ++ .../tx/transactors/payment/DepositPreauth.cpp | 2 ++ .../tx/transactors/payment/Payment.cpp | 4 ++++ .../payment_channel/PaymentChannelCreate.cpp | 2 ++ .../payment_channel/PaymentChannelHelpers.cpp | 1 + .../PermissionedDomainDelete.cpp | 1 + .../PermissionedDomainSet.cpp | 2 ++ .../tx/transactors/system/TicketCreate.cpp | 2 ++ src/libxrpl/tx/transactors/token/Clawback.cpp | 2 ++ .../tx/transactors/token/MPTokenAuthorize.cpp | 3 +++ .../token/MPTokenIssuanceCreate.cpp | 2 ++ .../token/MPTokenIssuanceDestroy.cpp | 1 + src/libxrpl/tx/transactors/token/TrustSet.cpp | 2 ++ .../tx/transactors/vault/VaultClawback.cpp | 2 ++ .../tx/transactors/vault/VaultCreate.cpp | 3 +++ .../tx/transactors/vault/VaultDelete.cpp | 3 +++ .../tx/transactors/vault/VaultDeposit.cpp | 3 +++ .../tx/transactors/vault/VaultWithdraw.cpp | 2 ++ src/test/app/AMM_test.cpp | 1 + src/test/app/AccountSet_test.cpp | 1 + src/test/app/Check_test.cpp | 1 + src/test/app/FeeVote_test.cpp | 2 +- src/test/app/Flow_test.cpp | 1 + src/test/app/Invariants_test.cpp | 3 +++ src/test/app/Vault_test.cpp | 3 ++- src/test/consensus/NegativeUNL_test.cpp | 2 +- src/test/jtx/PathSet.h | 1 + src/test/jtx/impl/TestHelpers.cpp | 1 + src/test/jtx/impl/mpt.cpp | 1 + src/test/jtx/impl/owners.cpp | 2 ++ src/test/jtx/owners.h | 2 +- src/test/ledger/Directory_test.cpp | 1 + src/test/ledger/PaymentSandbox_test.cpp | 3 ++- src/test/ledger/View_test.cpp | 2 ++ src/test/rpc/Book_test.cpp | 1 + src/xrpld/app/ledger/detail/LedgerToJson.cpp | 1 + src/xrpld/app/misc/NetworkOPs.cpp | 4 ++++ src/xrpld/app/paths/AMMOffer.h | 1 + src/xrpld/app/paths/TrustLine.cpp | 1 + src/xrpld/app/paths/detail/BookStep.cpp | 1 + src/xrpld/app/paths/detail/DirectStep.cpp | 1 + .../app/paths/detail/XRPEndpointStep.cpp | 1 + src/xrpld/rpc/handlers/AccountChannels.cpp | 1 + src/xrpld/rpc/handlers/AccountInfo.cpp | 1 + src/xrpld/rpc/handlers/AccountLines.cpp | 1 + src/xrpld/rpc/handlers/AccountOffers.cpp | 1 + src/xrpld/rpc/handlers/GatewayBalances.cpp | 1 + src/xrpld/rpc/handlers/NFTOffers.cpp | 1 + src/xrpld/rpc/handlers/NoRippleCheck.cpp | 1 + 94 files changed, 166 insertions(+), 25 deletions(-) diff --git a/include/xrpl/ledger/View.h b/include/xrpl/ledger/View.h index 2ea38c5b8b..55be01d677 100644 --- a/include/xrpl/ledger/View.h +++ b/include/xrpl/ledger/View.h @@ -2,28 +2,19 @@ #include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include -#include -#include +#include #include +#include #include -#include #include +#include +#include +#include #include namespace xrpl { diff --git a/include/xrpl/tx/paths/detail/StrandFlow.h b/include/xrpl/tx/paths/detail/StrandFlow.h index f99f54d0e8..2a94b9b968 100644 --- a/include/xrpl/tx/paths/detail/StrandFlow.h +++ b/include/xrpl/tx/paths/detail/StrandFlow.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/include/xrpl/tx/transactors/dex/AMMUtils.h b/include/xrpl/tx/transactors/dex/AMMUtils.h index 18db7e6555..77ad18106e 100644 --- a/include/xrpl/tx/transactors/dex/AMMUtils.h +++ b/include/xrpl/tx/transactors/dex/AMMUtils.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/include/xrpl/tx/transactors/dex/AMMWithdraw.h b/include/xrpl/tx/transactors/dex/AMMWithdraw.h index c15bb68644..5328b03abb 100644 --- a/include/xrpl/tx/transactors/dex/AMMWithdraw.h +++ b/include/xrpl/tx/transactors/dex/AMMWithdraw.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace xrpl { diff --git a/src/libxrpl/ledger/AcceptedLedgerTx.cpp b/src/libxrpl/ledger/AcceptedLedgerTx.cpp index f0d243f9b6..005d48e6f6 100644 --- a/src/libxrpl/ledger/AcceptedLedgerTx.cpp +++ b/src/libxrpl/ledger/AcceptedLedgerTx.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/src/libxrpl/ledger/BookDirs.cpp b/src/libxrpl/ledger/BookDirs.cpp index 699d6c2879..2bdf6ac9a5 100644 --- a/src/libxrpl/ledger/BookDirs.cpp +++ b/src/libxrpl/ledger/BookDirs.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace xrpl { diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index f51fb97993..ef6a66744d 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -4,7 +4,10 @@ #include #include #include +#include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index 1c937f9380..6e334b5563 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -3,7 +3,10 @@ #include #include #include +#include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/invariants/InvariantCheck.cpp b/src/libxrpl/tx/invariants/InvariantCheck.cpp index 00580b2548..16108472aa 100644 --- a/src/libxrpl/tx/invariants/InvariantCheck.cpp +++ b/src/libxrpl/tx/invariants/InvariantCheck.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/invariants/LoanInvariant.cpp b/src/libxrpl/tx/invariants/LoanInvariant.cpp index 01c4da46ac..0df7e409d1 100644 --- a/src/libxrpl/tx/invariants/LoanInvariant.cpp +++ b/src/libxrpl/tx/invariants/LoanInvariant.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/invariants/VaultInvariant.cpp b/src/libxrpl/tx/invariants/VaultInvariant.cpp index e955e00b50..f0dd82c2f8 100644 --- a/src/libxrpl/tx/invariants/VaultInvariant.cpp +++ b/src/libxrpl/tx/invariants/VaultInvariant.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/paths/BookTip.cpp b/src/libxrpl/tx/paths/BookTip.cpp index f00da6d7c7..5611a081c3 100644 --- a/src/libxrpl/tx/paths/BookTip.cpp +++ b/src/libxrpl/tx/paths/BookTip.cpp @@ -1,3 +1,5 @@ +#include +#include #include namespace xrpl { diff --git a/src/libxrpl/tx/paths/OfferStream.cpp b/src/libxrpl/tx/paths/OfferStream.cpp index b406c27298..b7dc431b23 100644 --- a/src/libxrpl/tx/paths/OfferStream.cpp +++ b/src/libxrpl/tx/paths/OfferStream.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/account/AccountDelete.cpp b/src/libxrpl/tx/transactors/account/AccountDelete.cpp index 822b6121de..fed265c125 100644 --- a/src/libxrpl/tx/transactors/account/AccountDelete.cpp +++ b/src/libxrpl/tx/transactors/account/AccountDelete.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/account/AccountSet.cpp b/src/libxrpl/tx/transactors/account/AccountSet.cpp index a3afe2092c..33759c6ec4 100644 --- a/src/libxrpl/tx/transactors/account/AccountSet.cpp +++ b/src/libxrpl/tx/transactors/account/AccountSet.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/account/SignerListSet.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp index 399e832740..fe9e80d7e0 100644 --- a/src/libxrpl/tx/transactors/account/SignerListSet.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp index 2e274f138d..9ac755cf4d 100644 --- a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp +++ b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp @@ -5,7 +5,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/check/CheckCancel.cpp b/src/libxrpl/tx/transactors/check/CheckCancel.cpp index d2a77698e0..2d08b2f1b0 100644 --- a/src/libxrpl/tx/transactors/check/CheckCancel.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCancel.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/check/CheckCash.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp index 2edd3c3a9c..7fa53c7352 100644 --- a/src/libxrpl/tx/transactors/check/CheckCash.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/check/CheckCreate.cpp b/src/libxrpl/tx/transactors/check/CheckCreate.cpp index 43e000ad5b..50554a1beb 100644 --- a/src/libxrpl/tx/transactors/check/CheckCreate.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp index 26ecf311fe..c4842b54e4 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp index af5c786c59..f8f0f01b63 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp @@ -1,7 +1,8 @@ #include #include -#include +#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp index 2a9aafc6be..9fb17c4d1f 100644 --- a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp +++ b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp index 86128ed1cd..dd717948b3 100644 --- a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp index 9b78b9e2bf..cae83ccef1 100644 --- a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/dex/OfferCancel.cpp b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp index 58f9525f61..9d60347778 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCancel.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp index 90c00c6280..d52fa94877 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp @@ -2,6 +2,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/did/DIDDelete.cpp b/src/libxrpl/tx/transactors/did/DIDDelete.cpp index e09fdd3510..0d5b63635f 100644 --- a/src/libxrpl/tx/transactors/did/DIDDelete.cpp +++ b/src/libxrpl/tx/transactors/did/DIDDelete.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/src/libxrpl/tx/transactors/did/DIDSet.cpp b/src/libxrpl/tx/transactors/did/DIDSet.cpp index 32edbce82e..cd5c9bbc96 100644 --- a/src/libxrpl/tx/transactors/did/DIDSet.cpp +++ b/src/libxrpl/tx/transactors/did/DIDSet.cpp @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp index 61e27a7c38..1250d950cd 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp @@ -1,8 +1,12 @@ #include #include #include +#include +#include +#include #include #include +#include #include #include diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp index adeee09390..8b823de160 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp @@ -3,9 +3,14 @@ #include #include #include +#include +#include +#include +#include #include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp index e85b00e606..8a05b2b160 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp @@ -6,8 +6,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h b/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h index 2aa6ae6db5..5fdc43c359 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h +++ b/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h @@ -3,9 +3,13 @@ #include #include #include +#include +#include +#include #include #include #include +#include #include namespace xrpl { diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp index 4c55a7d33a..24aa3f8bf2 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverClawback.cpp @@ -1,5 +1,6 @@ #include // +#include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp index 83f7d2d1c6..4630e6a360 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverDeposit.cpp @@ -1,5 +1,6 @@ #include // +#include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp index ca64c6bb56..6946992376 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp @@ -1,6 +1,8 @@ #include // +#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp index 85026654da..a755db7942 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp @@ -1,5 +1,7 @@ #include // +#include +#include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp index 2632b55812..f8813ddbef 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp @@ -1,5 +1,7 @@ #include // +#include +#include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanDelete.cpp index e7d219d6c8..39b28f5110 100644 --- a/src/libxrpl/tx/transactors/lending/LoanDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanDelete.cpp @@ -1,5 +1,6 @@ #include // +#include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanManage.cpp b/src/libxrpl/tx/transactors/lending/LoanManage.cpp index 2dacb453b5..d507ba5499 100644 --- a/src/libxrpl/tx/transactors/lending/LoanManage.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanManage.cpp @@ -1,5 +1,6 @@ #include // +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanPay.cpp b/src/libxrpl/tx/transactors/lending/LoanPay.cpp index 3543b7607f..8739cb645a 100644 --- a/src/libxrpl/tx/transactors/lending/LoanPay.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanPay.cpp @@ -1,6 +1,7 @@ #include // #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/lending/LoanSet.cpp b/src/libxrpl/tx/transactors/lending/LoanSet.cpp index 7212f079ce..f046a24961 100644 --- a/src/libxrpl/tx/transactors/lending/LoanSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanSet.cpp @@ -1,5 +1,7 @@ #include // +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp b/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp index 3022188ccf..15a745b8dd 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp b/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp index 40b7171015..f7c12b5488 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp @@ -1,6 +1,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp index e55d96e246..bde403f821 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/oracle/OracleSet.cpp b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp index 6b21df4d2a..061dd16b0c 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleSet.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index 55a27e28ed..60b8dcd823 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment/Payment.cpp b/src/libxrpl/tx/transactors/payment/Payment.cpp index 6fc6d995fa..38765016b5 100644 --- a/src/libxrpl/tx/transactors/payment/Payment.cpp +++ b/src/libxrpl/tx/transactors/payment/Payment.cpp @@ -1,8 +1,12 @@ #include #include +#include #include +#include +#include #include #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp index 113dd89221..3f7e1e1814 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp index 75b68768ed..176b920e6b 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp index 2c7e934fc0..565631b3fd 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp index f4d4f6a805..e8df51c9d9 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp @@ -1,7 +1,9 @@ #include // #include +#include #include +#include #include #include diff --git a/src/libxrpl/tx/transactors/system/TicketCreate.cpp b/src/libxrpl/tx/transactors/system/TicketCreate.cpp index 8a9a5cbc93..a064c158d1 100644 --- a/src/libxrpl/tx/transactors/system/TicketCreate.cpp +++ b/src/libxrpl/tx/transactors/system/TicketCreate.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/token/Clawback.cpp b/src/libxrpl/tx/transactors/token/Clawback.cpp index a3ac810e90..e8ba3cc0c5 100644 --- a/src/libxrpl/tx/transactors/token/Clawback.cpp +++ b/src/libxrpl/tx/transactors/token/Clawback.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp index 208936a5e6..77551b372b 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp index 9f9362da4e..58accf0271 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp index 1df4da47ab..8ec1f37886 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/token/TrustSet.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp index c620592619..22588b977a 100644 --- a/src/libxrpl/tx/transactors/token/TrustSet.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp index ed47dfb63d..a650aed310 100644 --- a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp index a5b039f06b..0fc074bae2 100644 --- a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp index ad39ed9cf2..1e2e46e165 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp index bceaa354a1..04b249d211 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include #include #include diff --git a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp index 2507563bde..e4c671b462 100644 --- a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index f84253588c..a0a38b9791 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include diff --git a/src/test/app/AccountSet_test.cpp b/src/test/app/AccountSet_test.cpp index cfd7262a50..7af917a0b9 100644 --- a/src/test/app/AccountSet_test.cpp +++ b/src/test/app/AccountSet_test.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include diff --git a/src/test/app/Check_test.cpp b/src/test/app/Check_test.cpp index f8bb0ddcf2..671f8aab1a 100644 --- a/src/test/app/Check_test.cpp +++ b/src/test/app/Check_test.cpp @@ -1,5 +1,6 @@ #include +#include #include #include diff --git a/src/test/app/FeeVote_test.cpp b/src/test/app/FeeVote_test.cpp index f4b8c1874c..f0599b8771 100644 --- a/src/test/app/FeeVote_test.cpp +++ b/src/test/app/FeeVote_test.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/test/app/Flow_test.cpp b/src/test/app/Flow_test.cpp index 692d9d2b50..1e9514f756 100644 --- a/src/test/app/Flow_test.cpp +++ b/src/test/app/Flow_test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/test/app/Invariants_test.cpp b/src/test/app/Invariants_test.cpp index e17ef1fd55..8372bb340b 100644 --- a/src/test/app/Invariants_test.cpp +++ b/src/test/app/Invariants_test.cpp @@ -4,6 +4,9 @@ #include #include +#include +#include +#include #include #include #include diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index e62f7fee50..27a8d3b2e0 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -9,8 +9,9 @@ #include #include #include +#include #include -#include +#include #include #include #include diff --git a/src/test/consensus/NegativeUNL_test.cpp b/src/test/consensus/NegativeUNL_test.cpp index 23f7610300..46c6936809 100644 --- a/src/test/consensus/NegativeUNL_test.cpp +++ b/src/test/consensus/NegativeUNL_test.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include namespace xrpl { diff --git a/src/test/jtx/PathSet.h b/src/test/jtx/PathSet.h index a363f9dff9..c522ed635e 100644 --- a/src/test/jtx/PathSet.h +++ b/src/test/jtx/PathSet.h @@ -3,6 +3,7 @@ #include #include +#include #include namespace xrpl { diff --git a/src/test/jtx/impl/TestHelpers.cpp b/src/test/jtx/impl/TestHelpers.cpp index 5e7a31adcd..e10a0c46d0 100644 --- a/src/test/jtx/impl/TestHelpers.cpp +++ b/src/test/jtx/impl/TestHelpers.cpp @@ -2,6 +2,7 @@ #include #include +#include #include namespace xrpl { diff --git a/src/test/jtx/impl/mpt.cpp b/src/test/jtx/impl/mpt.cpp index b6b08734c7..a6283bb6f9 100644 --- a/src/test/jtx/impl/mpt.cpp +++ b/src/test/jtx/impl/mpt.cpp @@ -1,5 +1,6 @@ #include +#include #include #include diff --git a/src/test/jtx/impl/owners.cpp b/src/test/jtx/impl/owners.cpp index 53f2302143..855c5b04ff 100644 --- a/src/test/jtx/impl/owners.cpp +++ b/src/test/jtx/impl/owners.cpp @@ -1,5 +1,7 @@ #include +#include + namespace xrpl { namespace detail { diff --git a/src/test/jtx/owners.h b/src/test/jtx/owners.h index 785a9347dd..3f54e0c55f 100644 --- a/src/test/jtx/owners.h +++ b/src/test/jtx/owners.h @@ -2,7 +2,7 @@ #include -#include +#include #include #include diff --git a/src/test/ledger/Directory_test.cpp b/src/test/ledger/Directory_test.cpp index ec76b67e9c..18649a20a8 100644 --- a/src/test/ledger/Directory_test.cpp +++ b/src/test/ledger/Directory_test.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/src/test/ledger/PaymentSandbox_test.cpp b/src/test/ledger/PaymentSandbox_test.cpp index 2a0d74e3d9..a5023aa328 100644 --- a/src/test/ledger/PaymentSandbox_test.cpp +++ b/src/test/ledger/PaymentSandbox_test.cpp @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include #include diff --git a/src/test/ledger/View_test.cpp b/src/test/ledger/View_test.cpp index bae29445c2..f57cb609cc 100644 --- a/src/test/ledger/View_test.cpp +++ b/src/test/ledger/View_test.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include diff --git a/src/test/rpc/Book_test.cpp b/src/test/rpc/Book_test.cpp index 7ebe6e97ae..8136af310a 100644 --- a/src/test/rpc/Book_test.cpp +++ b/src/test/rpc/Book_test.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/app/ledger/detail/LedgerToJson.cpp b/src/xrpld/app/ledger/detail/LedgerToJson.cpp index c0211059a1..ff8e7e55e9 100644 --- a/src/xrpld/app/ledger/detail/LedgerToJson.cpp +++ b/src/xrpld/app/ledger/detail/LedgerToJson.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index d709981c46..aabb53230f 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -43,11 +43,15 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include #include #include #include diff --git a/src/xrpld/app/paths/AMMOffer.h b/src/xrpld/app/paths/AMMOffer.h index ebaa7311c0..aa6132dfce 100644 --- a/src/xrpld/app/paths/AMMOffer.h +++ b/src/xrpld/app/paths/AMMOffer.h @@ -2,6 +2,7 @@ #include #include +#include #include #include diff --git a/src/xrpld/app/paths/TrustLine.cpp b/src/xrpld/app/paths/TrustLine.cpp index 6c54aa52d7..963e1402be 100644 --- a/src/xrpld/app/paths/TrustLine.cpp +++ b/src/xrpld/app/paths/TrustLine.cpp @@ -1,5 +1,6 @@ #include +#include #include #include diff --git a/src/xrpld/app/paths/detail/BookStep.cpp b/src/xrpld/app/paths/detail/BookStep.cpp index ae0c371e3e..e0053956a8 100644 --- a/src/xrpld/app/paths/detail/BookStep.cpp +++ b/src/xrpld/app/paths/detail/BookStep.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/src/xrpld/app/paths/detail/DirectStep.cpp b/src/xrpld/app/paths/detail/DirectStep.cpp index 142f07bf73..0c8693eef4 100644 --- a/src/xrpld/app/paths/detail/DirectStep.cpp +++ b/src/xrpld/app/paths/detail/DirectStep.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/app/paths/detail/XRPEndpointStep.cpp b/src/xrpld/app/paths/detail/XRPEndpointStep.cpp index e37a184e07..620d901f22 100644 --- a/src/xrpld/app/paths/detail/XRPEndpointStep.cpp +++ b/src/xrpld/app/paths/detail/XRPEndpointStep.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/AccountChannels.cpp b/src/xrpld/rpc/handlers/AccountChannels.cpp index d2c3d4546d..c418386a71 100644 --- a/src/xrpld/rpc/handlers/AccountChannels.cpp +++ b/src/xrpld/rpc/handlers/AccountChannels.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/AccountInfo.cpp b/src/xrpld/rpc/handlers/AccountInfo.cpp index f144c934ec..15a6786e22 100644 --- a/src/xrpld/rpc/handlers/AccountInfo.cpp +++ b/src/xrpld/rpc/handlers/AccountInfo.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/AccountLines.cpp b/src/xrpld/rpc/handlers/AccountLines.cpp index 952141fb8d..b3b93c0eb1 100644 --- a/src/xrpld/rpc/handlers/AccountLines.cpp +++ b/src/xrpld/rpc/handlers/AccountLines.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/AccountOffers.cpp b/src/xrpld/rpc/handlers/AccountOffers.cpp index 842cac71eb..86ab140b03 100644 --- a/src/xrpld/rpc/handlers/AccountOffers.cpp +++ b/src/xrpld/rpc/handlers/AccountOffers.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/GatewayBalances.cpp b/src/xrpld/rpc/handlers/GatewayBalances.cpp index 60e031c812..f7acbc77e6 100644 --- a/src/xrpld/rpc/handlers/GatewayBalances.cpp +++ b/src/xrpld/rpc/handlers/GatewayBalances.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/NFTOffers.cpp b/src/xrpld/rpc/handlers/NFTOffers.cpp index 3af7c28f9e..5fe2e3bede 100644 --- a/src/xrpld/rpc/handlers/NFTOffers.cpp +++ b/src/xrpld/rpc/handlers/NFTOffers.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/xrpld/rpc/handlers/NoRippleCheck.cpp b/src/xrpld/rpc/handlers/NoRippleCheck.cpp index f21a67a31d..73f51fca1a 100644 --- a/src/xrpld/rpc/handlers/NoRippleCheck.cpp +++ b/src/xrpld/rpc/handlers/NoRippleCheck.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include From 0eedefbf455ca893fae6832f52e0aa46408b78d2 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Tue, 24 Mar 2026 15:42:12 +0000 Subject: [PATCH 05/10] refactor: Enable more clang-tidy readability checks (#6595) Co-authored-by: Sergey Kuznetsov --- .clang-tidy | 14 ++-- include/xrpl/beast/utility/instrumentation.h | 2 +- include/xrpl/core/JobQueue.h | 2 +- include/xrpl/protocol/Permissions.h | 8 +- include/xrpl/protocol/Serializer.h | 2 +- include/xrpl/shamap/SHAMap.h | 2 +- include/xrpl/tx/ApplyContext.h | 2 +- include/xrpl/tx/invariants/FreezeInvariant.h | 6 +- include/xrpl/tx/invariants/InvariantCheck.h | 2 +- include/xrpl/tx/invariants/LoanInvariant.h | 4 +- src/libxrpl/basics/Number.cpp | 4 +- src/libxrpl/basics/ResolverAsio.cpp | 12 +-- src/libxrpl/basics/StringUtilities.cpp | 2 +- src/libxrpl/basics/base64.cpp | 6 +- src/libxrpl/basics/make_SSLContext.cpp | 2 +- src/libxrpl/beast/insight/StatsDCollector.cpp | 2 +- src/libxrpl/beast/net/IPAddressV6.cpp | 2 +- src/libxrpl/beast/net/IPEndpoint.cpp | 10 +-- src/libxrpl/core/detail/JobQueue.cpp | 3 +- src/libxrpl/core/detail/LoadMonitor.cpp | 2 +- src/libxrpl/core/detail/Workers.cpp | 2 +- src/libxrpl/crypto/RFC1751.cpp | 16 ++-- src/libxrpl/json/Writer.cpp | 2 +- src/libxrpl/json/json_reader.cpp | 6 +- src/libxrpl/json/json_value.cpp | 65 ++++++++-------- src/libxrpl/json/json_valueiterator.cpp | 6 +- src/libxrpl/json/json_writer.cpp | 8 +- src/libxrpl/ledger/ApplyStateTable.cpp | 4 +- src/libxrpl/ledger/ApplyView.cpp | 2 +- src/libxrpl/ledger/PaymentSandbox.cpp | 4 +- .../ledger/helpers/CredentialHelpers.cpp | 10 +-- src/libxrpl/net/HTTPClient.cpp | 1 + src/libxrpl/nodestore/ManagerImp.cpp | 2 +- .../nodestore/backend/RocksDBFactory.cpp | 2 +- src/libxrpl/protocol/BuildInfo.cpp | 2 +- src/libxrpl/protocol/ErrorCodes.cpp | 4 +- src/libxrpl/protocol/Feature.cpp | 8 +- src/libxrpl/protocol/IOUAmount.cpp | 2 +- src/libxrpl/protocol/InnerObjectFormats.cpp | 2 +- src/libxrpl/protocol/NFTokenOfferID.cpp | 2 +- src/libxrpl/protocol/Permissions.cpp | 4 +- src/libxrpl/protocol/PublicKey.cpp | 2 +- src/libxrpl/protocol/STAccount.cpp | 2 +- src/libxrpl/protocol/STAmount.cpp | 23 ++---- src/libxrpl/protocol/STBlob.cpp | 2 +- src/libxrpl/protocol/STCurrency.cpp | 2 +- src/libxrpl/protocol/STIssue.cpp | 2 +- src/libxrpl/protocol/STLedgerEntry.cpp | 2 +- src/libxrpl/protocol/STObject.cpp | 22 +++--- src/libxrpl/protocol/STParsedJSON.cpp | 10 +-- src/libxrpl/protocol/STPathSet.cpp | 22 +++--- src/libxrpl/protocol/STTx.cpp | 8 +- src/libxrpl/protocol/STValidation.cpp | 2 +- src/libxrpl/protocol/STVar.cpp | 2 +- src/libxrpl/protocol/STVector256.cpp | 2 +- src/libxrpl/protocol/STXChainBridge.cpp | 2 +- src/libxrpl/protocol/Serializer.cpp | 6 +- src/libxrpl/protocol/TxMeta.cpp | 4 +- src/libxrpl/protocol/UintTypes.cpp | 2 +- src/libxrpl/protocol/tokens.cpp | 14 ++-- src/libxrpl/rdb/DatabaseCon.cpp | 4 +- src/libxrpl/rdb/SociDB.cpp | 6 +- src/libxrpl/resource/Consumer.cpp | 14 ++-- src/libxrpl/server/State.cpp | 4 +- src/libxrpl/shamap/SHAMap.cpp | 34 ++++----- src/libxrpl/shamap/SHAMapDelta.cpp | 2 +- src/libxrpl/shamap/SHAMapNodeID.cpp | 4 +- src/libxrpl/shamap/SHAMapSync.cpp | 22 +++--- src/libxrpl/tx/ApplyContext.cpp | 2 +- src/libxrpl/tx/Transactor.cpp | 16 ++-- src/libxrpl/tx/apply.cpp | 8 +- src/libxrpl/tx/invariants/AMMInvariant.cpp | 2 +- src/libxrpl/tx/invariants/FreezeInvariant.cpp | 7 +- src/libxrpl/tx/invariants/InvariantCheck.cpp | 8 +- src/libxrpl/tx/invariants/LoanInvariant.cpp | 4 +- src/libxrpl/tx/paths/RippleCalc.cpp | 4 +- .../tx/transactors/account/AccountDelete.cpp | 11 +-- .../tx/transactors/account/AccountSet.cpp | 63 ++++++++-------- .../tx/transactors/account/SetRegularKey.cpp | 2 +- .../tx/transactors/account/SignerListSet.cpp | 4 +- .../tx/transactors/bridge/XChainBridge.cpp | 12 +-- .../tx/transactors/check/CheckCash.cpp | 7 +- .../tx/transactors/check/CheckCreate.cpp | 4 +- .../credentials/CredentialAccept.cpp | 2 +- .../tx/transactors/dex/AMMClawback.cpp | 7 +- src/libxrpl/tx/transactors/dex/AMMDeposit.cpp | 16 ++-- .../tx/transactors/dex/AMMWithdraw.cpp | 22 +++--- .../tx/transactors/dex/OfferCancel.cpp | 2 +- .../tx/transactors/dex/OfferCreate.cpp | 44 ++++++----- .../tx/transactors/escrow/EscrowCreate.cpp | 5 +- .../tx/transactors/lending/LoanManage.cpp | 2 +- .../tx/transactors/nft/NFTokenBurn.cpp | 2 +- .../tx/transactors/nft/NFTokenCreateOffer.cpp | 2 +- .../tx/transactors/nft/NFTokenModify.cpp | 2 +- .../tx/transactors/nft/NFTokenUtils.cpp | 23 +++--- .../tx/transactors/payment/DepositPreauth.cpp | 7 +- .../tx/transactors/payment/Payment.cpp | 20 ++--- .../payment_channel/PaymentChannelClaim.cpp | 6 +- .../payment_channel/PaymentChannelCreate.cpp | 4 +- src/libxrpl/tx/transactors/system/Batch.cpp | 4 +- src/libxrpl/tx/transactors/system/Change.cpp | 2 +- src/libxrpl/tx/transactors/token/Clawback.cpp | 5 +- .../tx/transactors/token/MPTokenAuthorize.cpp | 4 +- .../token/MPTokenIssuanceCreate.cpp | 4 +- .../transactors/token/MPTokenIssuanceSet.cpp | 24 +++--- src/libxrpl/tx/transactors/token/TrustSet.cpp | 74 +++++++++---------- .../tx/transactors/vault/VaultCreate.cpp | 6 +- src/libxrpl/tx/transactors/vault/VaultSet.cpp | 5 +- src/test/app/AMMCalc_test.cpp | 14 ++-- src/test/app/AMM_test.cpp | 20 ++--- src/test/app/AccountTxPaging_test.cpp | 4 +- src/test/app/AmendmentTable_test.cpp | 4 +- src/test/app/Batch_test.cpp | 6 +- src/test/app/Credentials_test.cpp | 1 + src/test/app/DepositAuth_test.cpp | 6 +- src/test/app/EscrowToken_test.cpp | 4 +- src/test/app/FeeVote_test.cpp | 2 +- src/test/app/FixNFTokenPageLinks_test.cpp | 2 +- src/test/app/Flow_test.cpp | 2 +- src/test/app/Freeze_test.cpp | 4 +- src/test/app/HashRouter_test.cpp | 2 +- src/test/app/Invariants_test.cpp | 2 +- src/test/app/LedgerMaster_test.cpp | 2 +- src/test/app/LedgerReplay_test.cpp | 29 +++----- src/test/app/Loan_test.cpp | 22 +++--- src/test/app/Manifest_test.cpp | 4 +- src/test/app/NFTokenAuth_test.cpp | 2 +- src/test/app/NFTokenBurn_test.cpp | 4 +- src/test/app/NFTokenDir_test.cpp | 2 +- src/test/app/NFToken_test.cpp | 11 +-- src/test/app/NetworkID_test.cpp | 2 +- src/test/app/Offer_test.cpp | 24 +++--- src/test/app/OversizeMeta_test.cpp | 6 +- src/test/app/Path_test.cpp | 2 +- src/test/app/PayChan_test.cpp | 4 +- src/test/app/PayStrand_test.cpp | 4 +- src/test/app/PermissionedDEX_test.cpp | 12 +-- src/test/app/PseudoTx_test.cpp | 4 +- src/test/app/RCLValidations_test.cpp | 2 +- src/test/app/ReducedOffer_test.cpp | 2 +- src/test/app/SHAMapStore_test.cpp | 8 +- src/test/app/TrustSet_test.cpp | 4 +- src/test/app/TxQ_test.cpp | 24 +++--- src/test/app/ValidatorList_test.cpp | 18 ++--- src/test/app/ValidatorSite_test.cpp | 2 +- src/test/app/Vault_test.cpp | 8 +- src/test/app/XChain_test.cpp | 2 +- src/test/basics/Buffer_test.cpp | 4 +- src/test/basics/Number_test.cpp | 12 +-- src/test/basics/PerfLog_test.cpp | 16 ++-- src/test/basics/base58_test.cpp | 2 +- .../beast/aged_associative_container_test.cpp | 2 +- src/test/consensus/Consensus_test.cpp | 24 +++--- src/test/consensus/NegativeUNL_test.cpp | 4 +- src/test/core/ClosureCounter_test.cpp | 2 +- src/test/core/Config_test.cpp | 8 +- src/test/core/JobQueue_test.cpp | 2 +- src/test/csf/Sim.h | 4 +- src/test/csf/impl/Sim.cpp | 2 +- src/test/csf/impl/ledgers.cpp | 2 +- src/test/csf/ledgers.h | 4 +- src/test/jtx/AMMTest.h | 8 +- src/test/jtx/Env.h | 1 + src/test/jtx/Env_test.cpp | 2 +- src/test/jtx/impl/AMM.cpp | 4 +- src/test/jtx/impl/AMMTest.cpp | 4 +- src/test/jtx/impl/Env.cpp | 5 +- src/test/jtx/impl/Oracle.cpp | 2 +- src/test/jtx/impl/mpt.cpp | 2 +- src/test/jtx/impl/multisign.cpp | 2 +- src/test/jtx/impl/offer.cpp | 2 +- src/test/jtx/impl/sig.cpp | 4 +- src/test/jtx/vault.h | 10 +-- src/test/ledger/Directory_test.cpp | 4 +- src/test/nodestore/NuDBFactory_test.cpp | 2 +- src/test/nodestore/Timing_test.cpp | 6 +- src/test/nodestore/import_test.cpp | 8 +- src/test/overlay/TMGetObjectByHash_test.cpp | 2 +- src/test/overlay/cluster_test.cpp | 2 +- src/test/overlay/compression_test.cpp | 14 ++-- src/test/overlay/reduce_relay_test.cpp | 16 ++-- src/test/protocol/PublicKey_test.cpp | 4 +- src/test/protocol/STAmount_test.cpp | 2 +- src/test/protocol/STParsedJSON_test.cpp | 2 +- src/test/protocol/SeqProxy_test.cpp | 2 +- src/test/resource/Logic_test.cpp | 4 +- src/test/rpc/AccountObjects_test.cpp | 2 +- src/test/rpc/Book_test.cpp | 4 +- src/test/rpc/DeliveredAmount_test.cpp | 3 +- src/test/rpc/LedgerEntry_test.cpp | 4 +- src/test/rpc/LedgerRPC_test.cpp | 2 +- src/test/rpc/Roles_test.cpp | 2 +- src/test/rpc/ServerInfo_test.cpp | 2 +- src/test/rpc/Simulate_test.cpp | 4 +- src/test/rpc/Transaction_test.cpp | 6 +- src/test/server/ServerStatus_test.cpp | 8 +- src/test/server/Server_test.cpp | 14 ++-- src/test/shamap/FetchPack_test.cpp | 6 +- src/tests/libxrpl/basics/RangeSet.cpp | 2 +- src/tests/libxrpl/json/Value.cpp | 4 +- src/xrpld/app/consensus/RCLConsensus.cpp | 4 +- src/xrpld/app/consensus/RCLCxPeerPos.cpp | 4 +- src/xrpld/app/ledger/detail/BuildLedger.cpp | 4 +- src/xrpld/app/ledger/detail/LedgerMaster.cpp | 4 +- src/xrpld/app/ledger/detail/LedgerToJson.cpp | 19 ++--- .../app/ledger/detail/TransactionMaster.cpp | 2 +- src/xrpld/app/main/Application.cpp | 2 +- src/xrpld/app/main/BasicApp.cpp | 2 +- src/xrpld/app/main/Main.cpp | 4 +- src/xrpld/app/misc/NegativeUNLVote.h | 2 +- src/xrpld/app/misc/NetworkOPs.cpp | 26 +++---- src/xrpld/app/misc/SHAMapStoreImp.cpp | 16 ++-- src/xrpld/app/misc/TxQ.h | 4 +- src/xrpld/app/misc/detail/AmendmentTable.cpp | 10 +-- src/xrpld/app/misc/detail/Transaction.cpp | 2 +- src/xrpld/app/misc/detail/TxQ.cpp | 17 +++-- src/xrpld/app/misc/detail/ValidatorList.cpp | 14 ++-- src/xrpld/app/paths/PathRequest.cpp | 4 +- src/xrpld/app/paths/Pathfinder.cpp | 18 ++--- src/xrpld/app/paths/RippleLineCache.cpp | 2 +- src/xrpld/app/paths/detail/BookStep.cpp | 17 +++-- src/xrpld/app/paths/detail/DirectStep.cpp | 48 ++++++------ src/xrpld/app/paths/detail/PaySteps.cpp | 24 +++--- .../app/paths/detail/XRPEndpointStep.cpp | 2 +- src/xrpld/app/rdb/backend/detail/Node.cpp | 4 +- src/xrpld/core/detail/Config.cpp | 20 ++--- src/xrpld/overlay/Message.h | 6 +- src/xrpld/overlay/detail/Message.cpp | 3 +- src/xrpld/overlay/detail/OverlayImpl.cpp | 10 +-- src/xrpld/overlay/detail/OverlayImpl.h | 2 +- src/xrpld/overlay/detail/PeerImp.cpp | 4 +- .../peerfinder/detail/PeerfinderConfig.cpp | 2 +- src/xrpld/perflog/detail/PerfLogImp.cpp | 12 +-- src/xrpld/rpc/detail/DeliveredAmount.cpp | 9 +-- src/xrpld/rpc/detail/Handler.cpp | 2 +- src/xrpld/rpc/detail/RPCCall.cpp | 58 +++++++++++---- src/xrpld/rpc/detail/RPCHandler.cpp | 4 +- src/xrpld/rpc/detail/RPCHelpers.cpp | 2 +- src/xrpld/rpc/detail/RPCLedgerHelpers.cpp | 2 +- src/xrpld/rpc/detail/ServerHandler.cpp | 10 +-- src/xrpld/rpc/detail/TransactionSign.cpp | 6 +- src/xrpld/rpc/handlers/AccountInfo.cpp | 4 +- src/xrpld/rpc/handlers/CanDelete.cpp | 2 +- src/xrpld/rpc/handlers/DepositAuthorized.cpp | 4 +- src/xrpld/rpc/handlers/GetAggregatePrice.cpp | 2 +- src/xrpld/rpc/handlers/LedgerHandler.cpp | 2 +- src/xrpld/rpc/handlers/NoRippleCheck.cpp | 6 +- src/xrpld/rpc/handlers/ServerDefinitions.cpp | 2 +- 248 files changed, 948 insertions(+), 935 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index d8a7cb1b6f..261da1e367 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -104,10 +104,13 @@ Checks: "-*, readability-const-return-type, readability-container-contains, readability-container-size-empty, + readability-convert-member-functions-to-static, readability-duplicate-include, readability-else-after-return, readability-enum-initial-value, + readability-implicit-bool-conversion, readability-make-member-function-const, + readability-math-missing-parentheses, readability-misleading-indentation, readability-non-const-parameter, readability-redundant-casting, @@ -116,7 +119,9 @@ Checks: "-*, readability-redundant-member-init, readability-redundant-string-init, readability-reference-to-constructed-temporary, + readability-simplify-boolean-expr, readability-static-definition-in-anonymous-namespace, + readability-suspicious-call-argument, readability-use-std-min-max " # --- @@ -127,14 +132,9 @@ Checks: "-*, # misc-include-cleaner, # misc-redundant-expression, # -# readability-convert-member-functions-to-static, -# readability-implicit-bool-conversion, -# readability-inconsistent-declaration-parameter-name, +# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names +# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable # readability-identifier-naming, -# readability-math-missing-parentheses, -# readability-simplify-boolean-expr, -# readability-suspicious-call-argument, -# readability-static-accessed-through-instance, # # modernize-concat-nested-namespaces, # modernize-pass-by-value, diff --git a/include/xrpl/beast/utility/instrumentation.h b/include/xrpl/beast/utility/instrumentation.h index 106856514b..39b80bc438 100644 --- a/include/xrpl/beast/utility/instrumentation.h +++ b/include/xrpl/beast/utility/instrumentation.h @@ -15,7 +15,7 @@ #define ALWAYS_OR_UNREACHABLE(cond, message) assert((message) && (cond)) #define SOMETIMES(cond, message, ...) #define REACHABLE(message, ...) -#define UNREACHABLE(message, ...) assert((message) && false) +#define UNREACHABLE(message, ...) assert((message) && false) // NOLINT(misc-static-assert) #endif #define XRPL_ASSERT ALWAYS_OR_UNREACHABLE diff --git a/include/xrpl/core/JobQueue.h b/include/xrpl/core/JobQueue.h index f40a892173..583e8bc26a 100644 --- a/include/xrpl/core/JobQueue.h +++ b/include/xrpl/core/JobQueue.h @@ -316,7 +316,7 @@ private: // Returns the limit of running jobs for the given job type. // For jobs with no limit, we return the largest int. Hopefully that // will be enough. - int + static int getJobLimit(JobType type); }; diff --git a/include/xrpl/protocol/Permissions.h b/include/xrpl/protocol/Permissions.h index 65861addc7..0ec4f04f1a 100644 --- a/include/xrpl/protocol/Permissions.h +++ b/include/xrpl/protocol/Permissions.h @@ -72,12 +72,12 @@ public: isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const; // for tx level permission, permission value is equal to tx type plus one - uint32_t - txToPermissionType(TxType const& type) const; + static uint32_t + txToPermissionType(TxType const& type); // tx type value is permission value minus one - TxType - permissionToTxType(uint32_t const& value) const; + static TxType + permissionToTxType(uint32_t const& value); }; } // namespace xrpl diff --git a/include/xrpl/protocol/Serializer.h b/include/xrpl/protocol/Serializer.h index 98cefb4d08..75f5dbdf96 100644 --- a/include/xrpl/protocol/Serializer.h +++ b/include/xrpl/protocol/Serializer.h @@ -336,7 +336,7 @@ public: static_assert(N > 0, ""); } - std::size_t + [[nodiscard]] bool empty() const noexcept { return remain_ == 0; diff --git a/include/xrpl/shamap/SHAMap.h b/include/xrpl/shamap/SHAMap.h index 2c0910a830..213e7ce0ce 100644 --- a/include/xrpl/shamap/SHAMap.h +++ b/include/xrpl/shamap/SHAMap.h @@ -520,7 +520,7 @@ private: // getMissingNodes helper functions void gmn_ProcessNodes(MissingNodes&, MissingNodes::StackEntry& node); - void + static void gmn_ProcessDeferredReads(MissingNodes&); // fetch from DB helper function diff --git a/include/xrpl/tx/ApplyContext.h b/include/xrpl/tx/ApplyContext.h index 9e382556c2..efef568f29 100644 --- a/include/xrpl/tx/ApplyContext.h +++ b/include/xrpl/tx/ApplyContext.h @@ -111,7 +111,7 @@ public: checkInvariants(TER const result, XRPAmount const fee); private: - TER + static TER failInvariantCheck(TER const result); template diff --git a/include/xrpl/tx/invariants/FreezeInvariant.h b/include/xrpl/tx/invariants/FreezeInvariant.h index ac9d83166e..645f444462 100644 --- a/include/xrpl/tx/invariants/FreezeInvariant.h +++ b/include/xrpl/tx/invariants/FreezeInvariant.h @@ -48,7 +48,7 @@ private: bool isValidEntry(std::shared_ptr const& before, std::shared_ptr const& after); - STAmount + static STAmount calculateBalanceChange( std::shared_ptr const& before, std::shared_ptr const& after, @@ -63,7 +63,7 @@ private: std::shared_ptr findIssuer(AccountID const& issuerID, ReadView const& view); - bool + static bool validateIssuerChanges( std::shared_ptr const& issuer, IssuerChanges const& changes, @@ -71,7 +71,7 @@ private: beast::Journal const& j, bool enforce); - bool + static bool validateFrozenState( BalanceChange const& change, bool high, diff --git a/include/xrpl/tx/invariants/InvariantCheck.h b/include/xrpl/tx/invariants/InvariantCheck.h index e0ad65f14c..a053d127fb 100644 --- a/include/xrpl/tx/invariants/InvariantCheck.h +++ b/include/xrpl/tx/invariants/InvariantCheck.h @@ -111,7 +111,7 @@ public: void visitEntry(bool, std::shared_ptr const&, std::shared_ptr const&); - bool + static bool finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&); }; diff --git a/include/xrpl/tx/invariants/LoanInvariant.h b/include/xrpl/tx/invariants/LoanInvariant.h index be771cd582..02e9db1698 100644 --- a/include/xrpl/tx/invariants/LoanInvariant.h +++ b/include/xrpl/tx/invariants/LoanInvariant.h @@ -41,8 +41,8 @@ class ValidLoanBroker // for LoanBroker pseudo-accounts. std::vector mpts_; - bool - goodZeroDirectory(ReadView const& view, SLE::const_ref dir, beast::Journal const& j) const; + static bool + goodZeroDirectory(ReadView const& view, SLE::const_ref dir, beast::Journal const& j); public: void diff --git a/src/libxrpl/basics/Number.cpp b/src/libxrpl/basics/Number.cpp index b520261ffe..f0655cd8a9 100644 --- a/src/libxrpl/basics/Number.cpp +++ b/src/libxrpl/basics/Number.cpp @@ -981,7 +981,7 @@ root(Number f, unsigned d) auto ex = [e = e, di = di]() // Euclidean remainder of e/d { int k = (e >= 0 ? e : e - (di - 1)) / di; - int k2 = e - k * di; + int k2 = e - (k * di); if (k2 == 0) return 0; return di - k2; @@ -998,7 +998,7 @@ root(Number f, unsigned d) } // Quadratic least squares curve fit of f^(1/d) in the range [0, 1] - auto const D = ((6 * di + 11) * di + 6) * di + 1; + auto const D = (((6 * di + 11) * di + 6) * di) + 1; auto const a0 = 3 * di * ((2 * di - 3) * di + 1); auto const a1 = 24 * di * (2 * di - 1); auto const a2 = -30 * (di - 1) * di; diff --git a/src/libxrpl/basics/ResolverAsio.cpp b/src/libxrpl/basics/ResolverAsio.cpp index b746092645..aa1cb1470d 100644 --- a/src/libxrpl/basics/ResolverAsio.cpp +++ b/src/libxrpl/basics/ResolverAsio.cpp @@ -169,7 +169,7 @@ public: XRPL_ASSERT(m_stopped == true, "xrpl::ResolverAsioImpl::start : stopped"); XRPL_ASSERT(m_stop_called == false, "xrpl::ResolverAsioImpl::start : not stopping"); - if (m_stopped.exchange(false) == true) + if (m_stopped.exchange(false)) { { std::lock_guard lk{m_mut}; @@ -182,7 +182,7 @@ public: void stop_async() override { - if (m_stop_called.exchange(true) == false) + if (!m_stop_called.exchange(true)) { boost::asio::dispatch( m_io_context, @@ -229,7 +229,7 @@ public: { XRPL_ASSERT(m_stop_called == true, "xrpl::ResolverAsioImpl::do_stop : stopping"); - if (m_stopped.exchange(true) == false) + if (!m_stopped.exchange(true)) { m_work.clear(); m_resolver.cancel(); @@ -271,7 +271,7 @@ public: m_strand, std::bind(&ResolverAsioImpl::do_work, this, CompletionCounter(this)))); } - HostAndPort + static HostAndPort parseName(std::string const& str) { // first attempt to parse as an endpoint (IP addr + port). @@ -319,7 +319,7 @@ public: void do_work(CompletionCounter) { - if (m_stop_called == true) + if (m_stop_called) return; // We don't have any work to do at this time @@ -367,7 +367,7 @@ public: { XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::do_resolve : names non-empty"); - if (m_stop_called == false) + if (!m_stop_called) { m_work.emplace_back(names, handler); diff --git a/src/libxrpl/basics/StringUtilities.cpp b/src/libxrpl/basics/StringUtilities.cpp index 0dd466c9b4..c47618db82 100644 --- a/src/libxrpl/basics/StringUtilities.cpp +++ b/src/libxrpl/basics/StringUtilities.cpp @@ -24,7 +24,7 @@ sqlBlobLiteral(Blob const& blob) { std::string j; - j.reserve(blob.size() * 2 + 3); + j.reserve((blob.size() * 2) + 3); j.push_back('X'); j.push_back('\''); boost::algorithm::hex(blob.begin(), blob.end(), std::back_inserter(j)); diff --git a/src/libxrpl/basics/base64.cpp b/src/libxrpl/basics/base64.cpp index 31888ec99c..a510fbf6c9 100644 --- a/src/libxrpl/basics/base64.cpp +++ b/src/libxrpl/basics/base64.cpp @@ -107,7 +107,7 @@ encode(void* dest, void const* src, std::size_t len) char const* in = static_cast(src); auto const tab = base64::get_alphabet(); - for (auto n = len / 3; n--;) + for (auto n = len / 3; n != 0u; --n) { *out++ = tab[(in[0] & 0xfc) >> 2]; *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)]; @@ -162,7 +162,7 @@ decode(void* dest, char const* src, std::size_t len) auto const inverse = base64::get_inverse(); - while (len-- && *in != '=') + while (((len--) != 0u) && *in != '=') { auto const v = inverse[*in]; if (v == -1) @@ -181,7 +181,7 @@ decode(void* dest, char const* src, std::size_t len) } } - if (i) + if (i != 0) { c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4); c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2); diff --git a/src/libxrpl/basics/make_SSLContext.cpp b/src/libxrpl/basics/make_SSLContext.cpp index 74aab709d8..de16e8c6cf 100644 --- a/src/libxrpl/basics/make_SSLContext.cpp +++ b/src/libxrpl/basics/make_SSLContext.cpp @@ -253,7 +253,7 @@ initAuthenticated( // VFALCO Replace fopen() with RAII FILE* f = fopen(chain_file.c_str(), "r"); - if (!f) + if (f == nullptr) { LogicError( "Problem opening SSL chain file" + diff --git a/src/libxrpl/beast/insight/StatsDCollector.cpp b/src/libxrpl/beast/insight/StatsDCollector.cpp index cc3bbf2861..83fc65e92c 100644 --- a/src/libxrpl/beast/insight/StatsDCollector.cpp +++ b/src/libxrpl/beast/insight/StatsDCollector.cpp @@ -352,7 +352,7 @@ public: } } - void + static void log(std::vector const& buffers) { (void)buffers; diff --git a/src/libxrpl/beast/net/IPAddressV6.cpp b/src/libxrpl/beast/net/IPAddressV6.cpp index a261002ed3..30e2eefb96 100644 --- a/src/libxrpl/beast/net/IPAddressV6.cpp +++ b/src/libxrpl/beast/net/IPAddressV6.cpp @@ -10,7 +10,7 @@ bool is_private(AddressV6 const& addr) { return ( - (addr.to_bytes()[0] & 0xfd) || // TODO fc00::/8 too ? + ((addr.to_bytes()[0] & 0xfd) != 0) || // TODO fc00::/8 too ? (addr.is_v4_mapped() && is_private(boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, addr)))); } diff --git a/src/libxrpl/beast/net/IPEndpoint.cpp b/src/libxrpl/beast/net/IPEndpoint.cpp index f8352f4318..70e7bff2c5 100644 --- a/src/libxrpl/beast/net/IPEndpoint.cpp +++ b/src/libxrpl/beast/net/IPEndpoint.cpp @@ -57,7 +57,7 @@ Endpoint::to_string() const if (port() != 0 && address().is_v6()) s += '['; s += address().to_string(); - if (port()) + if (port() != 0u) { if (address().is_v6()) s += ']'; @@ -111,7 +111,7 @@ operator>>(std::istream& is, Endpoint& endpoint) // so we continue to honor that here by assuming we are at the end // of the address portion if we hit a space (or the separator // we were expecting to see) - if (isspace(static_cast(i)) || (readTo && i == readTo)) + if ((isspace(static_cast(i)) != 0) || ((readTo != 0) && i == readTo)) break; if ((i == '.') || (i >= '0' && i <= ':') || (i >= 'a' && i <= 'f') || @@ -121,13 +121,13 @@ operator>>(std::istream& is, Endpoint& endpoint) // don't exceed a reasonable length... if (addrStr.size() == INET6_ADDRSTRLEN || - (readTo && readTo == ':' && addrStr.size() > 15)) + ((readTo != 0) && readTo == ':' && addrStr.size() > 15)) { is.setstate(std::ios_base::failbit); return is; } - if (!readTo && (i == '.' || i == ':')) + if ((readTo == 0) && (i == '.' || i == ':')) { // if we see a dot first, must be IPv4 // otherwise must be non-bracketed IPv6 @@ -145,7 +145,7 @@ operator>>(std::istream& is, Endpoint& endpoint) if (readTo == ']' && is.rdbuf()->in_avail() > 0) { is.get(i); - if (!(isspace(static_cast(i)) || i == ':')) + if ((isspace(static_cast(i)) == 0) && i != ':') { is.unget(); is.setstate(std::ios_base::failbit); diff --git a/src/libxrpl/core/detail/JobQueue.cpp b/src/libxrpl/core/detail/JobQueue.cpp index 9adbf6312b..2fe5a5b0fd 100644 --- a/src/libxrpl/core/detail/JobQueue.cpp +++ b/src/libxrpl/core/detail/JobQueue.cpp @@ -84,8 +84,7 @@ JobQueue::addRefCountedJob(JobType type, std::string const& name, JobFunction co JobType const type(job.getType()); XRPL_ASSERT(type != jtINVALID, "xrpl::JobQueue::addRefCountedJob : has valid job type"); - XRPL_ASSERT( - m_jobSet.find(job) != m_jobSet.end(), "xrpl::JobQueue::addRefCountedJob : job found"); + XRPL_ASSERT(m_jobSet.contains(job), "xrpl::JobQueue::addRefCountedJob : job found"); perfLog_.jobQueue(type); JobTypeData& data(getJobTypeData(type)); diff --git a/src/libxrpl/core/detail/LoadMonitor.cpp b/src/libxrpl/core/detail/LoadMonitor.cpp index 89a364ca30..9891bdb8b8 100644 --- a/src/libxrpl/core/detail/LoadMonitor.cpp +++ b/src/libxrpl/core/detail/LoadMonitor.cpp @@ -141,7 +141,7 @@ LoadMonitor::isOver() update(); if (mLatencyEvents == 0) - return 0; + return false; return isOverTarget( mLatencyMSAvg / (mLatencyEvents * 4), mLatencyMSPeak / (mLatencyEvents * 4)); diff --git a/src/libxrpl/core/detail/Workers.cpp b/src/libxrpl/core/detail/Workers.cpp index c037169a29..21bf75b958 100644 --- a/src/libxrpl/core/detail/Workers.cpp +++ b/src/libxrpl/core/detail/Workers.cpp @@ -47,7 +47,7 @@ Workers::setNumberOfThreads(int numberOfThreads) if (m_numberOfThreads == numberOfThreads) return; - if (perfLog_) + if (perfLog_ != nullptr) perfLog_->resizeJobs(numberOfThreads); if (numberOfThreads > m_numberOfThreads) diff --git a/src/libxrpl/crypto/RFC1751.cpp b/src/libxrpl/crypto/RFC1751.cpp index f7c1e675cb..becd0aab8d 100644 --- a/src/libxrpl/crypto/RFC1751.cpp +++ b/src/libxrpl/crypto/RFC1751.cpp @@ -210,8 +210,8 @@ RFC1751::extract(char const* s, int start, int length) int const shiftR = 24 - (length + (start % 8)); cl = s[start / 8]; // get components - cc = (shiftR < 16) ? s[start / 8 + 1] : 0; - cr = (shiftR < 8) ? s[start / 8 + 2] : 0; + cc = (shiftR < 16) ? s[(start / 8) + 1] : 0; + cr = (shiftR < 8) ? s[(start / 8) + 2] : 0; x = ((long)(cl << 8 | cc) << 8 | cr); // Put bits together x = x >> shiftR; // Right justify number @@ -265,13 +265,13 @@ RFC1751::insert(char* s, int x, int start, int length) if (shift + length > 16) { s[start / 8] |= cl; - s[start / 8 + 1] |= cc; - s[start / 8 + 2] |= cr; + s[(start / 8) + 1] |= cc; + s[(start / 8) + 2] |= cr; } else if (shift + length > 8) { s[start / 8] |= cc; - s[start / 8 + 1] |= cr; + s[(start / 8) + 1] |= cr; } else { @@ -284,7 +284,7 @@ RFC1751::standard(std::string& strWord) { for (auto& letter : strWord) { - if (islower(static_cast(letter))) + if (islower(static_cast(letter)) != 0) { letter = toupper(static_cast(letter)); } @@ -312,10 +312,10 @@ RFC1751::wsrch(std::string const& strWord, int iMin, int iMax) while (iResult < 0 && iMin != iMax) { // Have a range to search. - int iMid = iMin + (iMax - iMin) / 2; + int iMid = iMin + ((iMax - iMin) / 2); int iDir = strWord.compare(s_dictionary[iMid]); - if (!iDir) + if (iDir == 0) { iResult = iMid; // Found it. } diff --git a/src/libxrpl/json/Writer.cpp b/src/libxrpl/json/Writer.cpp index 6ff5a130dd..796ec35dfd 100644 --- a/src/libxrpl/json/Writer.cpp +++ b/src/libxrpl/json/Writer.cpp @@ -152,7 +152,7 @@ public: #ifndef NDEBUG // Make sure we haven't already seen this tag. auto& tags = stack_.top().tags; - check(tags.find(tag) == tags.end(), "Already seen tag " + tag); + check(!tags.contains(tag), "Already seen tag " + tag); tags.insert(tag); #endif diff --git a/src/libxrpl/json/json_reader.cpp b/src/libxrpl/json/json_reader.cpp index 4c2a27400f..6475a5b68b 100644 --- a/src/libxrpl/json/json_reader.cpp +++ b/src/libxrpl/json/json_reader.cpp @@ -296,7 +296,7 @@ Reader::match(Location pattern, int patternLength) int index = patternLength; - while (index--) + while ((index--) != 0) { if (current_[index] != pattern[index]) return false; @@ -362,7 +362,7 @@ Reader::readNumber() while (current_ != end_) { - if (!std::isdigit(static_cast(*current_))) + if (std::isdigit(static_cast(*current_)) == 0) { auto ret = std::find(std::begin(extended_tokens), std::end(extended_tokens), *current_); @@ -913,7 +913,7 @@ Reader::getFormattedErrorMessages() const formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; - if (error.extra_) + if (error.extra_ != nullptr) formattedMessage += "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; } diff --git a/src/libxrpl/json/json_value.cpp b/src/libxrpl/json/json_value.cpp index 94b077d224..988a25a3ff 100644 --- a/src/libxrpl/json/json_value.cpp +++ b/src/libxrpl/json/json_value.cpp @@ -40,10 +40,10 @@ public: // return 0; if (length == unknown) - length = value ? (unsigned int)strlen(value) : 0; + length = (value != nullptr) ? (unsigned int)strlen(value) : 0; char* newString = static_cast(malloc(length + 1)); - if (value) + if (value != nullptr) memcpy(newString, value, length); newString[length] = 0; return newString; @@ -52,7 +52,7 @@ public: void releaseStringValue(char* value) override { - if (value) + if (value != nullptr) free(value); } }; @@ -108,14 +108,14 @@ Value::CZString::CZString(CZString const& other) Value::CZString::~CZString() { - if (cstr_ && index_ == duplicate) + if ((cstr_ != nullptr) && index_ == duplicate) valueAllocator()->releaseMemberName(const_cast(cstr_)); } bool Value::CZString::operator<(CZString const& other) const { - if (cstr_ && other.cstr_) + if ((cstr_ != nullptr) && (other.cstr_ != nullptr)) return strcmp(cstr_, other.cstr_) < 0; return index_ < other.index_; @@ -124,7 +124,7 @@ Value::CZString::operator<(CZString const& other) const bool Value::CZString::operator==(CZString const& other) const { - if (cstr_ && other.cstr_) + if ((cstr_ != nullptr) && (other.cstr_ != nullptr)) return strcmp(cstr_, other.cstr_) == 0; return index_ == other.index_; @@ -251,7 +251,7 @@ Value::Value(Value const& other) : type_(other.type_) break; case stringValue: - if (other.value_.string_) + if (other.value_.string_ != nullptr) { value_.string_ = valueAllocator()->duplicateStringValue(other.value_.string_); allocated_ = true; @@ -294,7 +294,7 @@ Value::~Value() case arrayValue: case objectValue: - if (value_.map_) + if (value_.map_ != nullptr) delete value_.map_; break; @@ -392,11 +392,11 @@ operator<(Value const& x, Value const& y) return x.value_.real_ < y.value_.real_; case booleanValue: - return x.value_.bool_ < y.value_.bool_; + return static_cast(x.value_.bool_) < static_cast(y.value_.bool_); case stringValue: - return (x.value_.string_ == 0 && y.value_.string_) || - (y.value_.string_ && x.value_.string_ && + return (x.value_.string_ == 0 && (y.value_.string_ != nullptr)) || + ((y.value_.string_ != nullptr) && (x.value_.string_ != nullptr) && strcmp(x.value_.string_, y.value_.string_) < 0); case arrayValue: @@ -413,7 +413,7 @@ operator<(Value const& x, Value const& y) // LCOV_EXCL_STOP } - return 0; // unreachable + return false; // unreachable } bool @@ -422,9 +422,9 @@ operator==(Value const& x, Value const& y) if (x.type_ != y.type_) { if (x.type_ == intValue && y.type_ == uintValue) - return !integerCmp(x.value_.int_, y.value_.uint_); + return integerCmp(x.value_.int_, y.value_.uint_) == 0; if (x.type_ == uintValue && y.type_ == intValue) - return !integerCmp(y.value_.int_, x.value_.uint_); + return integerCmp(y.value_.int_, x.value_.uint_) == 0; return false; } @@ -447,8 +447,8 @@ operator==(Value const& x, Value const& y) case stringValue: return x.value_.string_ == y.value_.string_ || - (y.value_.string_ && x.value_.string_ && - !strcmp(x.value_.string_, y.value_.string_)); + ((y.value_.string_ != nullptr) && (x.value_.string_ != nullptr) && + (strcmp(x.value_.string_, y.value_.string_) == 0)); case arrayValue: case objectValue: @@ -461,7 +461,7 @@ operator==(Value const& x, Value const& y) // LCOV_EXCL_STOP } - return 0; // unreachable + return false; // unreachable } char const* @@ -480,7 +480,7 @@ Value::asString() const return ""; case stringValue: - return value_.string_ ? value_.string_ : ""; + return (value_.string_ != nullptr) ? value_.string_ : ""; case booleanValue: return value_.bool_ ? "true" : "false"; @@ -525,7 +525,7 @@ Value::asInt() const case realValue: JSON_ASSERT_MESSAGE( - value_.real_ >= minInt && value_.real_ <= maxInt, + (value_.real_ >= minInt && value_.real_ <= maxInt), "Real out of signed integer range"); return Int(value_.real_); @@ -533,7 +533,7 @@ Value::asInt() const return value_.bool_ ? 1 : 0; case stringValue: { - char const* const str{value_.string_ ? value_.string_ : ""}; + char const* const str{(value_.string_ != nullptr) ? value_.string_ : ""}; return beast::lexicalCastThrow(str); } @@ -584,7 +584,7 @@ Value::asAbsUInt() const return value_.bool_ ? 1 : 0; case stringValue: { - char const* const str{value_.string_ ? value_.string_ : ""}; + char const* const str{(value_.string_ != nullptr) ? value_.string_ : ""}; auto const temp = beast::lexicalCastThrow(str); if (temp < 0) { @@ -626,14 +626,15 @@ Value::asUInt() const case realValue: JSON_ASSERT_MESSAGE( - value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range"); + (value_.real_ >= 0 && value_.real_ <= maxUInt), + "Real out of unsigned integer range"); return UInt(value_.real_); case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: { - char const* const str{value_.string_ ? value_.string_ : ""}; + char const* const str{(value_.string_ != nullptr) ? value_.string_ : ""}; return beast::lexicalCastThrow(str); } @@ -703,7 +704,7 @@ Value::asBool() const return value_.bool_; case stringValue: - return value_.string_ && value_.string_[0] != 0; + return (value_.string_ != nullptr) && value_.string_[0] != 0; case arrayValue: case objectValue: @@ -745,13 +746,13 @@ Value::isConvertibleTo(ValueType other) const other == realValue || other == stringValue || other == booleanValue; case booleanValue: - return (other == nullValue && value_.bool_ == false) || other == intValue || + return (other == nullValue && !value_.bool_) || other == intValue || other == uintValue || other == realValue || other == stringValue || other == booleanValue; case stringValue: return other == stringValue || - (other == nullValue && (!value_.string_ || value_.string_[0] == 0)); + (other == nullValue && ((value_.string_ == nullptr) || value_.string_[0] == 0)); case arrayValue: return other == arrayValue || (other == nullValue && value_.map_->empty()); @@ -813,10 +814,10 @@ operator bool() const if (isString()) { auto s = asCString(); - return s && s[0]; + return (s != nullptr) && (s[0] != 0); } - return !(isArray() || isObject()) || size(); + return !(isArray() || isObject()) || (size() != 0u); } void @@ -1139,7 +1140,7 @@ Value::begin() const { case arrayValue: case objectValue: - if (value_.map_) + if (value_.map_ != nullptr) return const_iterator(value_.map_->begin()); break; @@ -1157,7 +1158,7 @@ Value::end() const { case arrayValue: case objectValue: - if (value_.map_) + if (value_.map_ != nullptr) return const_iterator(value_.map_->end()); break; @@ -1175,7 +1176,7 @@ Value::begin() { case arrayValue: case objectValue: - if (value_.map_) + if (value_.map_ != nullptr) return iterator(value_.map_->begin()); break; default: @@ -1192,7 +1193,7 @@ Value::end() { case arrayValue: case objectValue: - if (value_.map_) + if (value_.map_ != nullptr) return iterator(value_.map_->end()); break; default: diff --git a/src/libxrpl/json/json_valueiterator.cpp b/src/libxrpl/json/json_valueiterator.cpp index e49ad50f9a..b3cf7e6538 100644 --- a/src/libxrpl/json/json_valueiterator.cpp +++ b/src/libxrpl/json/json_valueiterator.cpp @@ -89,7 +89,7 @@ ValueIteratorBase::key() const { Value::CZString const czString = (*current_).first; - if (czString.c_str()) + if (czString.c_str() != nullptr) { if (czString.isStaticString()) return Value(StaticString(czString.c_str())); @@ -105,7 +105,7 @@ ValueIteratorBase::index() const { Value::CZString const czString = (*current_).first; - if (!czString.c_str()) + if (czString.c_str() == nullptr) return czString.index(); return Value::UInt(-1); @@ -115,7 +115,7 @@ char const* ValueIteratorBase::memberName() const { char const* name = (*current_).first.c_str(); - return name ? name : ""; + return (name != nullptr) ? name : ""; } // ////////////////////////////////////////////////////////////////// diff --git a/src/libxrpl/json/json_writer.cpp b/src/libxrpl/json/json_writer.cpp index 66507f0111..b51da5bb68 100644 --- a/src/libxrpl/json/json_writer.cpp +++ b/src/libxrpl/json/json_writer.cpp @@ -23,7 +23,7 @@ isControlCharacter(char ch) static bool containsControlCharacter(char const* str) { - while (*str) + while (*str != 0) { if (isControlCharacter(*(str++))) return true; @@ -106,7 +106,7 @@ valueToQuotedString(char const* value) // We have to walk value and escape any special characters. // Appending to std::string is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - unsigned maxsize = strlen(value) * 2 + 3; // all-escaped+quotes+NULL + unsigned maxsize = (strlen(value) * 2) + 3; // all-escaped+quotes+NULL std::string result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; @@ -416,7 +416,7 @@ StyledWriter::isMultilineArray(Value const& value) { childValues_.reserve(size); addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + int lineLength = 4 + ((size - 1) * 2); // '[ ' + ', '*n + ' ]' for (int index = 0; index < size; ++index) { @@ -651,7 +651,7 @@ StyledStreamWriter::isMultilineArray(Value const& value) { childValues_.reserve(size); addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + int lineLength = 4 + ((size - 1) * 2); // '[ ' + ', '*n + ' ]' for (int index = 0; index < size; ++index) { diff --git a/src/libxrpl/ledger/ApplyStateTable.cpp b/src/libxrpl/ledger/ApplyStateTable.cpp index a0074c0b53..a48c3910e1 100644 --- a/src/libxrpl/ledger/ApplyStateTable.cpp +++ b/src/libxrpl/ledger/ApplyStateTable.cpp @@ -275,9 +275,7 @@ ApplyStateTable::exists(ReadView const& base, Keylet const& k) const case Action::modify: break; } - if (!k.check(*sle)) - return false; - return true; + return k.check(*sle); } auto diff --git a/src/libxrpl/ledger/ApplyView.cpp b/src/libxrpl/ledger/ApplyView.cpp index 463b2ba538..fe2e046b26 100644 --- a/src/libxrpl/ledger/ApplyView.cpp +++ b/src/libxrpl/ledger/ApplyView.cpp @@ -36,7 +36,7 @@ findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start) auto node = start; - if (page) + if (page != 0u) { node = view.peek(keylet::page(directory, page)); if (!node) diff --git a/src/libxrpl/ledger/PaymentSandbox.cpp b/src/libxrpl/ledger/PaymentSandbox.cpp index 1f84da1dcb..a56d730b5a 100644 --- a/src/libxrpl/ledger/PaymentSandbox.cpp +++ b/src/libxrpl/ledger/PaymentSandbox.cpp @@ -164,7 +164,7 @@ PaymentSandbox::balanceHook( auto delta = amount.zeroed(); auto lastBal = amount; auto minBal = amount; - for (auto curSB = this; curSB; curSB = curSB->ps_) + for (auto curSB = this; curSB != nullptr; curSB = curSB->ps_) { if (auto adj = curSB->tab_.adjustments(account, issuer, currency)) { @@ -198,7 +198,7 @@ std::uint32_t PaymentSandbox::ownerCountHook(AccountID const& account, std::uint32_t count) const { std::uint32_t result = count; - for (auto curSB = this; curSB; curSB = curSB->ps_) + for (auto curSB = this; curSB != nullptr; curSB = curSB->ps_) { if (auto adj = curSB->tab_.ownerCount(account)) result = std::max(result, *adj); diff --git a/src/libxrpl/ledger/helpers/CredentialHelpers.cpp b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp index 234ca7ea17..32db285f1e 100644 --- a/src/libxrpl/ledger/helpers/CredentialHelpers.cpp +++ b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp @@ -78,7 +78,7 @@ deleteSLE(ApplyView& view, std::shared_ptr const& sleCredential, beast::Jou auto const issuer = sleCredential->getAccountID(sfIssuer); auto const subject = sleCredential->getAccountID(sfSubject); - bool const accepted = sleCredential->getFlags() & lsfAccepted; + bool const accepted = (sleCredential->getFlags() & lsfAccepted) != 0u; auto err = delSLE(issuer, sfIssuerNode, !accepted || (subject == issuer)); if (!isTesSuccess(err)) @@ -147,7 +147,7 @@ valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal return tecBAD_CREDENTIALS; } - if (!(sleCred->getFlags() & lsfAccepted)) + if ((sleCred->getFlags() & lsfAccepted) == 0u) { JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h; return tecBAD_CREDENTIALS; @@ -188,7 +188,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject) foundExpired = true; continue; } - if (sleCredential->getFlags() & lsfAccepted) + if ((sleCredential->getFlags() & lsfAccepted) != 0u) { return tesSUCCESS; } @@ -309,7 +309,7 @@ verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, b if (!sleCredential) continue; // expired, i.e. deleted in credentials::removeExpired - if (sleCredential->getFlags() & lsfAccepted) + if ((sleCredential->getFlags() & lsfAccepted) != 0u) return tesSUCCESS; } @@ -336,7 +336,7 @@ verifyDepositPreauth( if (credentialsPresent && credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j)) return tecEXPIRED; - if (sleDst && (sleDst->getFlags() & lsfDepositAuth)) + if (sleDst && ((sleDst->getFlags() & lsfDepositAuth) != 0u)) { if (src != dst) { diff --git a/src/libxrpl/net/HTTPClient.cpp b/src/libxrpl/net/HTTPClient.cpp index 8ddae12a7e..65205be39c 100644 --- a/src/libxrpl/net/HTTPClient.cpp +++ b/src/libxrpl/net/HTTPClient.cpp @@ -59,6 +59,7 @@ public: //-------------------------------------------------------------------------- void + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) makeGet(std::string const& strPath, boost::asio::streambuf& sb, std::string const& strHost) { std::ostream osRequest(&sb); diff --git a/src/libxrpl/nodestore/ManagerImp.cpp b/src/libxrpl/nodestore/ManagerImp.cpp index b749a329ff..da9534f68b 100644 --- a/src/libxrpl/nodestore/ManagerImp.cpp +++ b/src/libxrpl/nodestore/ManagerImp.cpp @@ -55,7 +55,7 @@ ManagerImp::make_Backend( missing_backend(); auto factory{find(type)}; - if (!factory) + if (factory == nullptr) { missing_backend(); } diff --git a/src/libxrpl/nodestore/backend/RocksDBFactory.cpp b/src/libxrpl/nodestore/backend/RocksDBFactory.cpp index 67c329bb4a..ac040f178b 100644 --- a/src/libxrpl/nodestore/backend/RocksDBFactory.cpp +++ b/src/libxrpl/nodestore/backend/RocksDBFactory.cpp @@ -213,7 +213,7 @@ public: rocksdb::DB* db = nullptr; m_options.create_if_missing = createIfMissing; rocksdb::Status status = rocksdb::DB::Open(m_options, m_name, &db); - if (!status.ok() || !db) + if (!status.ok() || (db == nullptr)) { Throw( std::string("Unable to open/create RocksDB: ") + status.ToString()); diff --git a/src/libxrpl/protocol/BuildInfo.cpp b/src/libxrpl/protocol/BuildInfo.cpp index 7d9a2047a9..6a30a02756 100644 --- a/src/libxrpl/protocol/BuildInfo.cpp +++ b/src/libxrpl/protocol/BuildInfo.cpp @@ -140,7 +140,7 @@ encodeSoftwareVersion(std::string_view versionStr) if (x == 0) x = parsePreRelease(id, "b", 0x40, 0, 63); - if (x & 0xC0) + if ((x & 0xC0) != 0) { c |= static_cast(x) << 16; break; diff --git a/src/libxrpl/protocol/ErrorCodes.cpp b/src/libxrpl/protocol/ErrorCodes.cpp index 33ec869db6..407e1ab3f3 100644 --- a/src/libxrpl/protocol/ErrorCodes.cpp +++ b/src/libxrpl/protocol/ErrorCodes.cpp @@ -205,9 +205,7 @@ make_error(error_code_i code, std::string const& message) bool contains_error(Json::Value const& json) { - if (json.isObject() && json.isMember(jss::error)) - return true; - return false; + return json.isObject() && json.isMember(jss::error); } int diff --git a/src/libxrpl/protocol/Feature.cpp b/src/libxrpl/protocol/Feature.cpp index f91e164c92..1762d7d22d 100644 --- a/src/libxrpl/protocol/Feature.cpp +++ b/src/libxrpl/protocol/Feature.cpp @@ -209,7 +209,7 @@ FeatureCollections::getRegisteredFeature(std::string const& name) const XRPL_ASSERT( readOnly.load(), "xrpl::FeatureCollections::getRegisteredFeature : startup completed"); Feature const* feature = getByName(name); - if (feature) + if (feature != nullptr) return feature->feature; return std::nullopt; } @@ -229,7 +229,7 @@ FeatureCollections::registerFeature(std::string const& name, Supported support, support == Supported::yes || vote == VoteBehavior::DefaultNo, "Invalid feature parameters. Must be supported to be up-voted."); Feature const* i = getByName(name); - if (!i) + if (i == nullptr) { check(features.size() < detail::numFeatures, "More features defined than allocated."); @@ -283,7 +283,7 @@ FeatureCollections::featureToBitsetIndex(uint256 const& f) const readOnly.load(), "xrpl::FeatureCollections::featureToBitsetIndex : startup completed"); Feature const* feature = getByFeature(f); - if (!feature) + if (feature == nullptr) LogicError("Invalid Feature ID"); return getIndex(*feature); @@ -303,7 +303,7 @@ FeatureCollections::featureToName(uint256 const& f) const { XRPL_ASSERT(readOnly.load(), "xrpl::FeatureCollections::featureToName : startup completed"); Feature const* feature = getByFeature(f); - return feature ? feature->name : to_string(f); + return (feature != nullptr) ? feature->name : to_string(f); } FeatureCollections featureCollections; diff --git a/src/libxrpl/protocol/IOUAmount.cpp b/src/libxrpl/protocol/IOUAmount.cpp index eba78e6051..338f2c2760 100644 --- a/src/libxrpl/protocol/IOUAmount.cpp +++ b/src/libxrpl/protocol/IOUAmount.cpp @@ -186,7 +186,7 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU { using namespace boost::multiprecision; - if (!den) + if (den == 0u) Throw("division by zero"); // A vector with the value 10^index for indexes from 0 to 29 diff --git a/src/libxrpl/protocol/InnerObjectFormats.cpp b/src/libxrpl/protocol/InnerObjectFormats.cpp index 8139ef0f55..bccfe210d1 100644 --- a/src/libxrpl/protocol/InnerObjectFormats.cpp +++ b/src/libxrpl/protocol/InnerObjectFormats.cpp @@ -172,7 +172,7 @@ SOTemplate const* InnerObjectFormats::findSOTemplateBySField(SField const& sField) const { auto itemPtr = findByType(sField.getCode()); - if (itemPtr) + if (itemPtr != nullptr) return &(itemPtr->getSOTemplate()); return nullptr; diff --git a/src/libxrpl/protocol/NFTokenOfferID.cpp b/src/libxrpl/protocol/NFTokenOfferID.cpp index e7ebbcf84b..4af589a4e9 100644 --- a/src/libxrpl/protocol/NFTokenOfferID.cpp +++ b/src/libxrpl/protocol/NFTokenOfferID.cpp @@ -24,7 +24,7 @@ canHaveNFTokenOfferID( return false; TxType const tt = serializedTx->getTxnType(); - if (!(tt == ttNFTOKEN_MINT && serializedTx->isFieldPresent(sfAmount)) && + if ((tt != ttNFTOKEN_MINT || !serializedTx->isFieldPresent(sfAmount)) && tt != ttNFTOKEN_CREATE_OFFER) return false; diff --git a/src/libxrpl/protocol/Permissions.cpp b/src/libxrpl/protocol/Permissions.cpp index 4137c73624..47fc0d28b6 100644 --- a/src/libxrpl/protocol/Permissions.cpp +++ b/src/libxrpl/protocol/Permissions.cpp @@ -176,13 +176,13 @@ Permission::isDelegable(std::uint32_t const& permissionValue, Rules const& rules } uint32_t -Permission::txToPermissionType(TxType const& type) const +Permission::txToPermissionType(TxType const& type) { return static_cast(type) + 1; } TxType -Permission::permissionToTxType(uint32_t const& value) const +Permission::permissionToTxType(uint32_t const& value) { return static_cast(value - 1); } diff --git a/src/libxrpl/protocol/PublicKey.cpp b/src/libxrpl/protocol/PublicKey.cpp index 2c63ddac64..2e08c49a4e 100644 --- a/src/libxrpl/protocol/PublicKey.cpp +++ b/src/libxrpl/protocol/PublicKey.cpp @@ -75,7 +75,7 @@ static std::string sliceToHex(Slice const& slice) { std::string s; - if (slice[0] & 0x80) + if ((slice[0] & 0x80) != 0) { s.reserve(2 * (slice.size() + 2)); s = "0x00"; diff --git a/src/libxrpl/protocol/STAccount.cpp b/src/libxrpl/protocol/STAccount.cpp index ffd0b5d3c8..2dc83cb591 100644 --- a/src/libxrpl/protocol/STAccount.cpp +++ b/src/libxrpl/protocol/STAccount.cpp @@ -84,7 +84,7 @@ bool STAccount::isEquivalent(STBase const& t) const { auto const* const tPtr = dynamic_cast(&t); - return tPtr && (default_ == tPtr->default_) && (value_ == tPtr->value_); + return (tPtr != nullptr) && (default_ == tPtr->default_) && (value_ == tPtr->value_); } bool diff --git a/src/libxrpl/protocol/STAmount.cpp b/src/libxrpl/protocol/STAmount.cpp index 92ce129825..8c0068a275 100644 --- a/src/libxrpl/protocol/STAmount.cpp +++ b/src/libxrpl/protocol/STAmount.cpp @@ -152,7 +152,7 @@ STAmount::STAmount(SerialIter& sit, SField const& name) : STBase(name) value &= ~(1023ull << (64 - 10)); - if (value) + if (value != 0u) { bool isNegative = (offset & 256) == 0; offset = (offset & 255) - 97; // center the range @@ -505,14 +505,11 @@ canAdd(STAmount const& a, STAmount const& b) XRPAmount A = a.xrp(); XRPAmount B = b.xrp(); - if ((B > XRPAmount{0} && + return !( + (B > XRPAmount{0} && A > XRPAmount{std::numeric_limits::max()} - B) || (B < XRPAmount{0} && - A < XRPAmount{std::numeric_limits::min()} - B)) - { - return false; - } - return true; + A < XRPAmount{std::numeric_limits::min()} - B)); } // IOU case (precision check) @@ -530,15 +527,11 @@ canAdd(STAmount const& a, STAmount const& b) { MPTAmount A = a.mpt(); MPTAmount B = b.mpt(); - if ((B > MPTAmount{0} && + return !( + (B > MPTAmount{0} && A > MPTAmount{std::numeric_limits::max()} - B) || (B < MPTAmount{0} && - A < MPTAmount{std::numeric_limits::min()} - B)) - { - return false; - } - - return true; + A < MPTAmount{std::numeric_limits::min()} - B)); } // LCOV_EXCL_START UNREACHABLE("STAmount::canAdd : unexpected STAmount type"); @@ -803,7 +796,7 @@ bool STAmount::isEquivalent(STBase const& t) const { STAmount const* v = dynamic_cast(&t); - return v && (*v == *this); + return (v != nullptr) && (*v == *this); } bool diff --git a/src/libxrpl/protocol/STBlob.cpp b/src/libxrpl/protocol/STBlob.cpp index 1a9dae7771..e7d45a698d 100644 --- a/src/libxrpl/protocol/STBlob.cpp +++ b/src/libxrpl/protocol/STBlob.cpp @@ -53,7 +53,7 @@ bool STBlob::isEquivalent(STBase const& t) const { STBlob const* v = dynamic_cast(&t); - return v && (value_ == v->value_); + return (v != nullptr) && (value_ == v->value_); } bool diff --git a/src/libxrpl/protocol/STCurrency.cpp b/src/libxrpl/protocol/STCurrency.cpp index 1616de59b9..3ca7b60d6b 100644 --- a/src/libxrpl/protocol/STCurrency.cpp +++ b/src/libxrpl/protocol/STCurrency.cpp @@ -56,7 +56,7 @@ bool STCurrency::isEquivalent(STBase const& t) const { STCurrency const* v = dynamic_cast(&t); - return v && (*v == *this); + return (v != nullptr) && (*v == *this); } bool diff --git a/src/libxrpl/protocol/STIssue.cpp b/src/libxrpl/protocol/STIssue.cpp index 1d37554251..bc39ea1b55 100644 --- a/src/libxrpl/protocol/STIssue.cpp +++ b/src/libxrpl/protocol/STIssue.cpp @@ -110,7 +110,7 @@ bool STIssue::isEquivalent(STBase const& t) const { STIssue const* v = dynamic_cast(&t); - return v && (*v == *this); + return (v != nullptr) && (*v == *this); } bool diff --git a/src/libxrpl/protocol/STLedgerEntry.cpp b/src/libxrpl/protocol/STLedgerEntry.cpp index aa97b6b3a2..02e5ddb451 100644 --- a/src/libxrpl/protocol/STLedgerEntry.cpp +++ b/src/libxrpl/protocol/STLedgerEntry.cpp @@ -136,7 +136,7 @@ STLedgerEntry::isThreadedType(Rules const& rules) const // Exclude PrevTxnID/PrevTxnLgrSeq if the fixPreviousTxnID amendment is not // enabled and the ledger object type is in the above set bool const excludePrevTxnID = !rules.enabled(fixPreviousTxnID) && - std::count(newPreviousTxnIDTypes.cbegin(), newPreviousTxnIDTypes.cend(), type_); + (std::count(newPreviousTxnIDTypes.cbegin(), newPreviousTxnIDTypes.cend(), type_) != 0); return !excludePrevTxnID && getFieldIndex(sfPreviousTxnID) != -1; } diff --git a/src/libxrpl/protocol/STObject.cpp b/src/libxrpl/protocol/STObject.cpp index fe9e95cc82..182653d11d 100644 --- a/src/libxrpl/protocol/STObject.cpp +++ b/src/libxrpl/protocol/STObject.cpp @@ -204,7 +204,7 @@ void STObject::applyTemplateFromSField(SField const& sField) { SOTemplate const* elements = InnerObjectFormats::getInstance().findSOTemplateBySField(sField); - if (elements) + if (elements != nullptr) applyTemplate(*elements); // May throw } @@ -276,7 +276,7 @@ STObject::hasMatchingEntry(STBase const& t) const { STBase const* o = peekAtPField(t.getFName()); - if (!o) + if (o == nullptr) return false; return t == *o; @@ -343,7 +343,7 @@ STObject::isEquivalent(STBase const& t) const { STObject const* v = dynamic_cast(&t); - if (!v) + if (v == nullptr) return false; if (mType != nullptr && v->mType == mType) @@ -480,7 +480,7 @@ STObject::setFlag(std::uint32_t f) { STUInt32* t = dynamic_cast(getPField(sfFlags, true)); - if (!t) + if (t == nullptr) return false; t->setValue(t->value() | f); @@ -492,7 +492,7 @@ STObject::clearFlag(std::uint32_t f) { STUInt32* t = dynamic_cast(getPField(sfFlags)); - if (!t) + if (t == nullptr) return false; t->setValue(t->value() & ~f); @@ -510,7 +510,7 @@ STObject::getFlags(void) const { STUInt32 const* t = dynamic_cast(peekAtPField(sfFlags)); - if (!t) + if (t == nullptr) return 0; return t->value(); @@ -574,7 +574,7 @@ STObject::delField(int index) SOEStyle STObject::getStyle(SField const& field) const { - return mType ? mType->style(field) : soeINVALID; + return (mType != nullptr) ? mType->style(field) : soeINVALID; } unsigned char @@ -877,10 +877,7 @@ STObject::operator==(STObject const& obj) const ++fields; } - if (fields != matches) - return false; - - return true; + return fields == matches; } void @@ -917,7 +914,8 @@ STObject::getSortedFields(STObject const& objToSort, WhichFields whichFields) for (detail::STVar const& elem : objToSort.v_) { STBase const& base = elem.get(); - if ((base.getSType() != STI_NOTPRESENT) && base.getFName().shouldInclude(whichFields)) + if ((base.getSType() != STI_NOTPRESENT) && + base.getFName().shouldInclude(static_cast(whichFields))) { sf.push_back(&base); } diff --git a/src/libxrpl/protocol/STParsedJSON.cpp b/src/libxrpl/protocol/STParsedJSON.cpp index 0bf0c827af..702ad28414 100644 --- a/src/libxrpl/protocol/STParsedJSON.cpp +++ b/src/libxrpl/protocol/STParsedJSON.cpp @@ -1075,20 +1075,20 @@ parseArray( // TODO: There doesn't seem to be a nice way to get just the // first/only key in an object without copying all keys into // a vector - std::string const objectName(json[i].getMemberNames()[0]); + std::string const memberName(json[i].getMemberNames()[0]); ; - auto const& nameField(SField::getField(objectName)); + auto const& nameField(SField::getField(memberName)); if (nameField == sfInvalid) { - error = unknown_field(json_name, objectName); + error = unknown_field(json_name, memberName); return std::nullopt; } - Json::Value const objectFields(json[i][objectName]); + Json::Value const objectFields(json[i][memberName]); std::stringstream ss; - ss << json_name << "." << "[" << i << "]." << objectName; + ss << json_name << "." << "[" << i << "]." << memberName; auto ret = parseObject(ss.str(), objectFields, nameField, depth + 1, error); if (!ret) diff --git a/src/libxrpl/protocol/STPathSet.cpp b/src/libxrpl/protocol/STPathSet.cpp index 060f5c4d7c..86e61e91bf 100644 --- a/src/libxrpl/protocol/STPathSet.cpp +++ b/src/libxrpl/protocol/STPathSet.cpp @@ -61,7 +61,7 @@ STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name) if (iType == STPathElement::typeNone) return; } - else if (iType & ~STPathElement::typeAll) + else if ((iType & ~STPathElement::typeAll) != 0) { JLOG(debugLog().error()) << "Bad path element " << iType << " in pathset"; Throw("bad path element"); @@ -76,13 +76,13 @@ STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name) Currency currency; AccountID issuer; - if (hasAccount) + if (hasAccount != 0) account = sit.get160(); - if (hasCurrency) + if (hasCurrency != 0) currency = sit.get160(); - if (hasIssuer) + if (hasIssuer != 0) issuer = sit.get160(); path.emplace_back(account, currency, issuer, hasCurrency); @@ -127,7 +127,7 @@ bool STPathSet::isEquivalent(STBase const& t) const { STPathSet const* v = dynamic_cast(&t); - return v && (value == v->value); + return (v != nullptr) && (value == v->value); } bool @@ -160,13 +160,13 @@ STPath::getJson(JsonOptions) const elem[jss::type] = iType; - if (iType & STPathElement::typeAccount) + if ((iType & STPathElement::typeAccount) != 0u) elem[jss::account] = to_string(it.getAccountID()); - if (iType & STPathElement::typeCurrency) + if ((iType & STPathElement::typeCurrency) != 0u) elem[jss::currency] = to_string(it.getCurrency()); - if (iType & STPathElement::typeIssuer) + if ((iType & STPathElement::typeIssuer) != 0u) elem[jss::issuer] = to_string(it.getIssuerID()); ret.append(elem); @@ -209,13 +209,13 @@ STPathSet::add(Serializer& s) const s.add8(iType); - if (iType & STPathElement::typeAccount) + if ((iType & STPathElement::typeAccount) != 0) s.addBitString(speElement.getAccountID()); - if (iType & STPathElement::typeCurrency) + if ((iType & STPathElement::typeCurrency) != 0) s.addBitString(speElement.getCurrency()); - if (iType & STPathElement::typeIssuer) + if ((iType & STPathElement::typeIssuer) != 0) s.addBitString(speElement.getIssuerID()); } diff --git a/src/libxrpl/protocol/STTx.cpp b/src/libxrpl/protocol/STTx.cpp index 00a2acd788..7da1919f35 100644 --- a/src/libxrpl/protocol/STTx.cpp +++ b/src/libxrpl/protocol/STTx.cpp @@ -574,7 +574,7 @@ STTx::getBatchTransactionIDs() const { XRPL_ASSERT(getTxnType() == ttBATCH, "STTx::getBatchTransactionIDs : not a batch transaction"); XRPL_ASSERT( - getFieldArray(sfRawTransactions).size() != 0, + !getFieldArray(sfRawTransactions).empty(), "STTx::getBatchTransactionIDs : empty raw transactions"); // The list of inner ids is built once, then reused on subsequent calls. @@ -618,7 +618,7 @@ isMemoOkay(STObject const& st, std::string& reason) { auto memoObj = dynamic_cast(&memo); - if (!memoObj || (memoObj->getFName() != sfMemo)) + if ((memoObj == nullptr) || (memoObj->getFName() != sfMemo)) { reason = "A memo array may contain only Memo objects."; return false; @@ -669,7 +669,7 @@ isMemoOkay(STObject const& st, std::string& reason) for (unsigned char c : *optData) { - if (!allowedSymbols[c]) + if (allowedSymbols[c] == 0) { reason = "The MemoType and MemoFormat fields may only " @@ -691,7 +691,7 @@ isAccountFieldOkay(STObject const& st) for (int i = 0; i < st.getCount(); ++i) { auto t = dynamic_cast(st.peekAtPIndex(i)); - if (t && t->isDefault()) + if ((t != nullptr) && t->isDefault()) return false; } diff --git a/src/libxrpl/protocol/STValidation.cpp b/src/libxrpl/protocol/STValidation.cpp index f6f89d43e9..ba6e679081 100644 --- a/src/libxrpl/protocol/STValidation.cpp +++ b/src/libxrpl/protocol/STValidation.cpp @@ -107,7 +107,7 @@ STValidation::isValid() const noexcept getSignerPublic(), getSigningHash(), makeSlice(getFieldVL(sfSignature)), - getFlags() & vfFullyCanonicalSig); + (getFlags() & vfFullyCanonicalSig) != 0u); } return valid_.value(); diff --git a/src/libxrpl/protocol/STVar.cpp b/src/libxrpl/protocol/STVar.cpp index 255514d70c..8b76d8a322 100644 --- a/src/libxrpl/protocol/STVar.cpp +++ b/src/libxrpl/protocol/STVar.cpp @@ -60,7 +60,7 @@ STVar::operator=(STVar const& rhs) if (&rhs != this) { destroy(); - if (rhs.p_) + if (rhs.p_ != nullptr) { p_ = rhs.p_->copy(max_size, &d_); } diff --git a/src/libxrpl/protocol/STVector256.cpp b/src/libxrpl/protocol/STVector256.cpp index 6357e2f2cb..2a70dd1e05 100644 --- a/src/libxrpl/protocol/STVector256.cpp +++ b/src/libxrpl/protocol/STVector256.cpp @@ -68,7 +68,7 @@ bool STVector256::isEquivalent(STBase const& t) const { STVector256 const* v = dynamic_cast(&t); - return v && (mValue == v->mValue); + return (v != nullptr) && (mValue == v->mValue); } Json::Value diff --git a/src/libxrpl/protocol/STXChainBridge.cpp b/src/libxrpl/protocol/STXChainBridge.cpp index 85d36f9b46..428e4655ff 100644 --- a/src/libxrpl/protocol/STXChainBridge.cpp +++ b/src/libxrpl/protocol/STXChainBridge.cpp @@ -167,7 +167,7 @@ bool STXChainBridge::isEquivalent(STBase const& t) const { STXChainBridge const* v = dynamic_cast(&t); - return v && (*v == *this); + return (v != nullptr) && (*v == *this); } bool diff --git a/src/libxrpl/protocol/Serializer.cpp b/src/libxrpl/protocol/Serializer.cpp index 08d221f75b..0e8beae0d9 100644 --- a/src/libxrpl/protocol/Serializer.cpp +++ b/src/libxrpl/protocol/Serializer.cpp @@ -199,7 +199,7 @@ Serializer::addVL(void const* ptr, int len) { int ret = addEncoded(len); - if (len) + if (len != 0) addRaw(ptr, len); return ret; @@ -298,7 +298,7 @@ Serializer::decodeVLLength(int b1, int b2) if (b1 > 240) Throw("b1>240"); - return 193 + (b1 - 193) * 256 + b2; + return 193 + ((b1 - 193) * 256) + b2; } int @@ -310,7 +310,7 @@ Serializer::decodeVLLength(int b1, int b2, int b3) if (b1 > 254) Throw("b1>254"); - return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3; + return 12481 + ((b1 - 241) * 65536) + (b2 * 256) + b3; } //------------------------------------------------------------------------------ diff --git a/src/libxrpl/protocol/TxMeta.cpp b/src/libxrpl/protocol/TxMeta.cpp index f4932b2af4..19a2755a29 100644 --- a/src/libxrpl/protocol/TxMeta.cpp +++ b/src/libxrpl/protocol/TxMeta.cpp @@ -28,7 +28,7 @@ TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj) auto affectedNodes = dynamic_cast(obj.peekAtPField(sfAffectedNodes)); XRPL_ASSERT(affectedNodes, "xrpl::TxMeta::TxMeta(STObject) : type cast succeeded"); - if (affectedNodes) + if (affectedNodes != nullptr) nodes_ = *affectedNodes; setAdditionalFields(obj); @@ -96,7 +96,7 @@ TxMeta::getAffectedAccounts() const { auto const* inner = dynamic_cast(&node.peekAtIndex(index)); XRPL_ASSERT(inner, "xrpl::getAffectedAccounts : STObject type cast succeeded"); - if (inner) + if (inner != nullptr) { for (auto const& field : *inner) { diff --git a/src/libxrpl/protocol/UintTypes.cpp b/src/libxrpl/protocol/UintTypes.cpp index df9eadb511..5ace6c29d6 100644 --- a/src/libxrpl/protocol/UintTypes.cpp +++ b/src/libxrpl/protocol/UintTypes.cpp @@ -63,7 +63,7 @@ to_string(Currency const& currency) bool to_currency(Currency& currency, std::string const& code) { - if (code.empty() || !code.compare(systemCurrencyCode())) + if (code.empty() || (code.compare(systemCurrencyCode()) == 0)) { currency = beast::zero; return true; diff --git a/src/libxrpl/protocol/tokens.cpp b/src/libxrpl/protocol/tokens.cpp index b46591725f..bca8919c4e 100644 --- a/src/libxrpl/protocol/tokens.cpp +++ b/src/libxrpl/protocol/tokens.cpp @@ -263,7 +263,7 @@ decodeBase58(std::string const& s) // Allocate enough space in big-endian base256 representation. // log(58) / log(256), rounded up. - std::vector b256(remain * 733 / 1000 + 1); + std::vector b256((remain * 733 / 1000) + 1); while (remain > 0) { auto carry = alphabetReverse[*psz]; @@ -308,7 +308,7 @@ encodeBase58Token(TokenType type, void const* token, std::size_t size) // Lay the data out as // buf[0] = safe_cast>(type); - if (size) + if (size != 0u) std::memcpy(buf.data() + 1, token, size); checksum(buf.data() + 1 + size, buf.data(), 1 + size); @@ -383,7 +383,7 @@ b256_to_b58_be(std::span input, std::span out) { break; } - auto const src_i_end = input.size() - i * 8; + auto const src_i_end = input.size() - (i * 8); if (src_i_end >= 8) { std::memcpy(&base_2_64_coeff_buf[num_coeff], &input[src_i_end - 8], 8); @@ -450,7 +450,7 @@ b256_to_b58_be(std::span input, std::span out) { to_skip = count_leading_zeros(b58_be_s); skip_zeros = false; - if (out.size() < (i + 1) * 10 - to_skip) + if (out.size() < ((i + 1) * 10) - to_skip) { return Unexpected(TokenCodecErrc::outputTooSmall); } @@ -502,7 +502,7 @@ b58_to_b256_be(std::string_view input, std::span out) // log(2^(38*8),58^10)) ~= 5.18. So 6 coeff are enough std::array b_58_10_coeff{}; auto [num_full_coeffs, partial_coeff_len] = xrpl::b58_fast::detail::div_rem(input.size(), 10); - auto const num_partial_coeffs = partial_coeff_len ? 1 : 0; + auto const num_partial_coeffs = (partial_coeff_len != 0u) ? 1 : 0; auto const num_b_58_10_coeffs = num_full_coeffs + num_partial_coeffs; XRPL_ASSERT( num_b_58_10_coeffs <= b_58_10_coeff.size(), @@ -521,7 +521,7 @@ b58_to_b256_be(std::string_view input, std::span out) { for (int j = 0; j < num_full_coeffs; ++j) { - unsigned char c = input[partial_coeff_len + j * 10 + i]; + unsigned char c = input[partial_coeff_len + (j * 10) + i]; auto cur_val = ::xrpl::alphabetReverse[c]; if (cur_val < 0) { @@ -586,7 +586,7 @@ b58_to_b256_be(std::string_view input, std::span out) cur_out_i += 1; } } - if ((cur_out_i + 8 * (cur_result_size - 1)) > out.size()) + if ((cur_out_i + (8 * (cur_result_size - 1))) > out.size()) { return Unexpected(TokenCodecErrc::outputTooSmall); } diff --git a/src/libxrpl/rdb/DatabaseCon.cpp b/src/libxrpl/rdb/DatabaseCon.cpp index 344df85b4a..6552a1d7ce 100644 --- a/src/libxrpl/rdb/DatabaseCon.cpp +++ b/src/libxrpl/rdb/DatabaseCon.cpp @@ -72,7 +72,7 @@ DatabaseCon::~DatabaseCon() // checkpoint is currently in progress. Wait for it to end, otherwise // creating a new DatabaseCon to the same database may fail due to the // database being locked by our (now old) Checkpointer. - while (wk.use_count()) + while (wk.use_count() != 0) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -84,7 +84,7 @@ std::unique_ptr const> DatabaseCon::Setup::globalPragma void DatabaseCon::setupCheckpointing(JobQueue* q, Logs& l) { - if (!q) + if (q == nullptr) Throw("No JobQueue"); checkpointer_ = checkpointers.create(session_, *q, l); } diff --git a/src/libxrpl/rdb/SociDB.cpp b/src/libxrpl/rdb/SociDB.cpp index baadeef00a..576105016e 100644 --- a/src/libxrpl/rdb/SociDB.cpp +++ b/src/libxrpl/rdb/SociDB.cpp @@ -98,7 +98,7 @@ getConnection(soci::session& s) if (auto b = dynamic_cast(be)) result = b->conn_; - if (!result) + if (result == nullptr) Throw("Didn't get a database connection."); return result; @@ -107,7 +107,7 @@ getConnection(soci::session& s) std::uint32_t getKBUsedAll(soci::session& s) { - if (!getConnection(s)) + if (getConnection(s) == nullptr) Throw("No connection found."); return static_cast(sqlite_api::sqlite3_memory_used() / kilobytes(1)); } @@ -249,7 +249,7 @@ public: { auto [conn, keepAlive] = getConnection(); (void)keepAlive; - if (!conn) + if (conn == nullptr) return; int log = 0, ckpt = 0; diff --git a/src/libxrpl/resource/Consumer.cpp b/src/libxrpl/resource/Consumer.cpp index e9435bd340..c1cb9d4367 100644 --- a/src/libxrpl/resource/Consumer.cpp +++ b/src/libxrpl/resource/Consumer.cpp @@ -23,7 +23,7 @@ Consumer::Consumer() : m_logic(nullptr), m_entry(nullptr) Consumer::Consumer(Consumer const& other) : m_logic(other.m_logic), m_entry(nullptr) { - if (m_logic && other.m_entry) + if ((m_logic != nullptr) && (other.m_entry != nullptr)) { m_entry = other.m_entry; m_logic->acquire(*m_entry); @@ -32,7 +32,7 @@ Consumer::Consumer(Consumer const& other) : m_logic(other.m_logic), m_entry(null Consumer::~Consumer() { - if (m_logic && m_entry) + if ((m_logic != nullptr) && (m_entry != nullptr)) m_logic->release(*m_entry); } @@ -43,14 +43,14 @@ Consumer::operator=(Consumer const& other) return *this; // remove old ref - if (m_logic && m_entry) + if ((m_logic != nullptr) && (m_entry != nullptr)) m_logic->release(*m_entry); m_logic = other.m_logic; m_entry = other.m_entry; // add new ref - if (m_logic && m_entry) + if ((m_logic != nullptr) && (m_entry != nullptr)) m_logic->acquire(*m_entry); return *this; @@ -68,7 +68,7 @@ Consumer::to_string() const bool Consumer::isUnlimited() const { - if (m_entry) + if (m_entry != nullptr) return m_entry->isUnlimited(); return false; @@ -78,7 +78,7 @@ Disposition Consumer::disposition() const { Disposition d = ok; - if (m_logic && m_entry) + if ((m_logic != nullptr) && (m_entry != nullptr)) d = m_logic->charge(*m_entry, Charge(0)); return d; @@ -89,7 +89,7 @@ Consumer::charge(Charge const& what, std::string const& context) { Disposition d = ok; - if (m_logic && m_entry && !m_entry->isUnlimited()) + if ((m_logic != nullptr) && (m_entry != nullptr) && !m_entry->isUnlimited()) d = m_logic->charge(*m_entry, what, context); return d; diff --git a/src/libxrpl/server/State.cpp b/src/libxrpl/server/State.cpp index 371f2b4d0a..a7c0c0fca2 100644 --- a/src/libxrpl/server/State.cpp +++ b/src/libxrpl/server/State.cpp @@ -31,7 +31,7 @@ initStateDB(soci::session& session, BasicConfig const& config, std::string const count = *countO; } - if (!count) + if (count == 0) { session << "INSERT INTO DbState VALUES (1, '', '', 0);"; } @@ -45,7 +45,7 @@ initStateDB(soci::session& session, BasicConfig const& config, std::string const count = *countO; } - if (!count) + if (count == 0) { session << "INSERT INTO CanDelete VALUES (1, 0);"; } diff --git a/src/libxrpl/shamap/SHAMap.cpp b/src/libxrpl/shamap/SHAMap.cpp index a6aacfabc9..a9182a59cf 100644 --- a/src/libxrpl/shamap/SHAMap.cpp +++ b/src/libxrpl/shamap/SHAMap.cpp @@ -130,7 +130,7 @@ SHAMapLeafNode* SHAMap::findKey(uint256 const& id) const { SHAMapLeafNode* leaf = walkTowardsKey(id); - if (leaf && leaf->peekItem()->key() != id) + if ((leaf != nullptr) && leaf->peekItem()->key() != id) leaf = nullptr; return leaf; } @@ -221,7 +221,7 @@ SHAMap::fetchNodeNT(SHAMapHash const& hash, SHAMapSyncFilter* filter) const } } - if (filter) + if (filter != nullptr) node = checkFilter(hash, filter); return node; @@ -255,7 +255,7 @@ SHAMap::descendThrow(SHAMapInnerNode* parent, int branch) const { SHAMapTreeNode* ret = descend(parent, branch); - if (!ret && !parent->isEmptyBranch(branch)) + if ((ret == nullptr) && !parent->isEmptyBranch(branch)) Throw(type_, parent->getChildHash(branch)); return ret; @@ -276,7 +276,7 @@ SHAMapTreeNode* SHAMap::descend(SHAMapInnerNode* parent, int branch) const { SHAMapTreeNode* ret = parent->getChildPointer(branch); - if (ret || !backed_) + if ((ret != nullptr) || !backed_) return ret; intr_ptr::SharedPtr node = fetchNodeNT(parent->getChildHash(branch)); @@ -328,7 +328,7 @@ SHAMap::descend( SHAMapTreeNode* child = parent->getChildPointer(branch); - if (!child) + if (child == nullptr) { auto const& childHash = parent->getChildHash(branch); intr_ptr::SharedPtr childNode = fetchNodeNT(childHash, filter); @@ -354,7 +354,7 @@ SHAMap::descendAsync( pending = false; SHAMapTreeNode* ret = parent->getChildPointer(branch); - if (ret) + if (ret != nullptr) return ret; auto const& hash = parent->getChildHash(branch); @@ -362,7 +362,7 @@ SHAMap::descendAsync( auto ptr = cacheLookup(hash); if (!ptr) { - if (filter) + if (filter != nullptr) ptr = checkFilter(hash, filter); if (!ptr && backed_) @@ -483,14 +483,14 @@ SHAMap::onlyBelow(SHAMapTreeNode* node) const { if (!inner->isEmptyBranch(i)) { - if (nextNode) + if (nextNode != nullptr) return no_item; nextNode = descendThrow(inner, i); } } - if (!nextNode) + if (nextNode == nullptr) { // LCOV_EXCL_START UNREACHABLE("xrpl::SHAMap::onlyBelow : no next node"); @@ -514,7 +514,7 @@ SHAMap::peekFirstItem(SharedPtrNodeStack& stack) const { XRPL_ASSERT(stack.empty(), "xrpl::SHAMap::peekFirstItem : empty stack input"); SHAMapLeafNode* node = firstBelow(root_, stack); - if (!node) + if (node == nullptr) { while (!stack.empty()) stack.pop(); @@ -540,7 +540,7 @@ SHAMap::peekNextItem(uint256 const& id, SharedPtrNodeStack& stack) const { node = descendThrow(*inner, i); auto leaf = firstBelow(node, stack, i); - if (!leaf) + if (leaf == nullptr) Throw(type_, id); XRPL_ASSERT(leaf->isLeaf(), "xrpl::SHAMap::peekNextItem : leaf is valid"); return leaf; @@ -557,7 +557,7 @@ SHAMap::peekItem(uint256 const& id) const { SHAMapLeafNode* leaf = findKey(id); - if (!leaf) + if (leaf == nullptr) return no_item; return leaf->peekItem(); @@ -568,7 +568,7 @@ SHAMap::peekItem(uint256 const& id, SHAMapHash& hash) const { SHAMapLeafNode* leaf = findKey(id); - if (!leaf) + if (leaf == nullptr) return no_item; hash = leaf->getHash(); @@ -598,7 +598,7 @@ SHAMap::upper_bound(uint256 const& id) const { node = descendThrow(*inner, branch); auto leaf = firstBelow(node, stack, branch); - if (!leaf) + if (leaf == nullptr) Throw(type_, id); return const_iterator(this, leaf->peekItem().get(), std::move(stack)); } @@ -631,7 +631,7 @@ SHAMap::lower_bound(uint256 const& id) const { node = descendThrow(*inner, branch); auto leaf = lastBelow(node, stack, branch); - if (!leaf) + if (leaf == nullptr) Throw(type_, id); return const_iterator(this, leaf->peekItem().get(), std::move(stack)); } @@ -995,7 +995,7 @@ SHAMap::walkSubTree(bool doWrite, NodeObjectType t) int pos = 0; // We can't flush an inner node until we flush its children - while (1) + while (true) { while (pos < branchFactor) { @@ -1109,7 +1109,7 @@ SHAMap::dump(bool hash) const if (!inner->isEmptyBranch(i)) { auto child = inner->getChildPointer(i); - if (child) + if (child != nullptr) { XRPL_ASSERT( child->getHash() == inner->getChildHash(i), diff --git a/src/libxrpl/shamap/SHAMapDelta.cpp b/src/libxrpl/shamap/SHAMapDelta.cpp index 98a31fea55..0b5a09d4a7 100644 --- a/src/libxrpl/shamap/SHAMapDelta.cpp +++ b/src/libxrpl/shamap/SHAMapDelta.cpp @@ -136,7 +136,7 @@ SHAMap::compare(SHAMap const& otherMap, Delta& differences, int maxCount) const auto [ourNode, otherNode] = nodeStack.top(); nodeStack.pop(); - if (!ourNode || !otherNode) + if ((ourNode == nullptr) || (otherNode == nullptr)) { // LCOV_EXCL_START UNREACHABLE("xrpl::SHAMap::compare : missing a node"); diff --git a/src/libxrpl/shamap/SHAMapNodeID.cpp b/src/libxrpl/shamap/SHAMapNodeID.cpp index 6536e628ef..97a8b26a3b 100644 --- a/src/libxrpl/shamap/SHAMapNodeID.cpp +++ b/src/libxrpl/shamap/SHAMapNodeID.cpp @@ -76,7 +76,7 @@ SHAMapNodeID::getChildNodeID(unsigned int m) const Throw("Incorrect mask for " + to_string(*this)); SHAMapNodeID node{depth_ + 1, id_}; - node.id_.begin()[depth_ / 2] |= (depth_ & 1) ? m : (m << 4); + node.id_.begin()[depth_ / 2] |= ((depth_ & 1) != 0u) ? m : (m << 4); return node; } @@ -106,7 +106,7 @@ selectBranch(SHAMapNodeID const& id, uint256 const& hash) auto const depth = id.getDepth(); auto branch = static_cast(*(hash.begin() + (depth / 2))); - if (depth & 1) + if ((depth & 1) != 0u) { branch &= 0xf; } diff --git a/src/libxrpl/shamap/SHAMapSync.cpp b/src/libxrpl/shamap/SHAMapSync.cpp index c6e4c3dcb0..14ccdca2eb 100644 --- a/src/libxrpl/shamap/SHAMapSync.cpp +++ b/src/libxrpl/shamap/SHAMapSync.cpp @@ -93,13 +93,13 @@ SHAMap::visitDifferences( if (root_->getHash().isZero()) return; - if (have && (root_->getHash() == have->root_->getHash())) + if ((have != nullptr) && (root_->getHash() == have->root_->getHash())) return; if (root_->isLeaf()) { auto leaf = intr_ptr::static_pointer_cast(root_); - if (!have || !have->hasLeafNode(leaf->peekItem()->key(), leaf->getHash())) + if ((have == nullptr) || !have->hasLeafNode(leaf->peekItem()->key(), leaf->getHash())) function(*root_); return; } @@ -129,11 +129,11 @@ SHAMap::visitDifferences( if (next->isInner()) { - if (!have || !have->hasInnerNode(childID, childHash)) + if ((have == nullptr) || !have->hasInnerNode(childID, childHash)) stack.push({safe_downcast(next), childID}); } else if ( - !have || + (have == nullptr) || !have->hasLeafNode( safe_downcast(next)->peekItem()->key(), childHash)) { @@ -192,7 +192,7 @@ SHAMap::gmn_ProcessNodes(MissingNodes& mn, MissingNodes::StackEntry& se) fullBelow = false; ++mn.deferred_; } - else if (!d) + else if (d == nullptr) { // node is not in database @@ -347,7 +347,7 @@ SHAMap::getMissingNodes(int max, SHAMapSyncFilter* filter) // We have either emptied the stack or // posted as many deferred reads as we can - if (mn.deferred_) + if (mn.deferred_ != 0) gmn_ProcessDeferredReads(mn); if (mn.max_ <= 0) @@ -402,7 +402,7 @@ SHAMap::getNodeFat( auto node = root_.get(); SHAMapNodeID nodeID; - while (node && node->isInner() && (nodeID.getDepth() < wanted.getDepth())) + while ((node != nullptr) && node->isInner() && (nodeID.getDepth() < wanted.getDepth())) { int branch = selectBranch(nodeID, wanted.getNodeID()); auto inner = safe_downcast(node); @@ -509,7 +509,7 @@ SHAMap::addRootNode(SHAMapHash const& hash, Slice const& rootNode, SHAMapSyncFil if (root_->isLeaf()) clearSynching(); - if (filter) + if (filter != nullptr) { Serializer s; root_->serializeWithPrefix(s); @@ -615,7 +615,7 @@ SHAMap::addKnownNode(SHAMapNodeID const& node, Slice const& rawNode, SHAMapSyncF newNode = prevNode->canonicalizeChild(branch, std::move(newNode)); - if (filter) + if (filter != nullptr) { Serializer s; newNode->serializeWithPrefix(s); @@ -643,7 +643,7 @@ SHAMap::deepCompare(SHAMap& other) const auto const [node, otherNode] = stack.top(); stack.pop(); - if (!node || !otherNode) + if ((node == nullptr) || (otherNode == nullptr)) { JLOG(journal_.info()) << "unable to fetch node"; return false; @@ -685,7 +685,7 @@ SHAMap::deepCompare(SHAMap& other) const auto next = descend(node_inner, i); auto otherNext = other.descend(other_inner, i); - if (!next || !otherNext) + if ((next == nullptr) || (otherNext == nullptr)) { JLOG(journal_.warn()) << "unable to fetch inner node"; return false; diff --git a/src/libxrpl/tx/ApplyContext.cpp b/src/libxrpl/tx/ApplyContext.cpp index f62c63d1e6..edca31c04a 100644 --- a/src/libxrpl/tx/ApplyContext.cpp +++ b/src/libxrpl/tx/ApplyContext.cpp @@ -40,7 +40,7 @@ ApplyContext::discard() std::optional ApplyContext::apply(TER ter) { - return view_->apply(base_, tx, ter, parentBatchId_, flags_ & tapDRY_RUN, journal); + return view_->apply(base_, tx, ter, parentBatchId_, (flags_ & tapDRY_RUN) != 0u, journal); } std::size_t diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index 6e334b5563..d579d26c67 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -65,7 +65,7 @@ preflight0(PreflightContext const& ctx, std::uint32_t flagMask) return temINVALID; } - if (ctx.tx.getFlags() & flagMask) + if ((ctx.tx.getFlags() & flagMask) != 0u) { JLOG(ctx.j.debug()) << ctx.tx.peekAtField(sfTransactionType).getFullText() << ": invalid flags."; @@ -96,7 +96,7 @@ preflightCheckSigningKey(STObject const& sigObject, beast::Journal j) std::optional preflightCheckSimulateKeys(ApplyFlags flags, STObject const& sigObject, beast::Journal j) { - if (flags & tapDRY_RUN) // simulation + if ((flags & tapDRY_RUN) != 0u) // simulation { std::optional const signature = sigObject[~sfTxnSignature]; if (signature && !signature->empty()) @@ -318,7 +318,7 @@ Transactor::minimumFee( Fees const& fees, ApplyFlags flags) { - return scaleFeeLoad(baseFee, registry.getFeeTrack(), fees, flags & tapUNLIMITED); + return scaleFeeLoad(baseFee, registry.getFeeTrack(), fees, (flags & tapUNLIMITED) != 0u); } TER @@ -329,7 +329,7 @@ Transactor::checkFee(PreclaimContext const& ctx, XRPAmount baseFee) auto const feePaid = ctx.tx[sfFee].xrp(); - if (ctx.flags & tapBATCH) + if ((ctx.flags & tapBATCH) != 0u) { if (feePaid == beast::zero) return tesSUCCESS; @@ -653,7 +653,7 @@ Transactor::checkSign( return tesSUCCESS; } - if ((flags & tapDRY_RUN) && pkSigner.empty() && !sigObject.isFieldPresent(sfSigners)) + if (((flags & tapDRY_RUN) != 0u) && pkSigner.empty() && !sigObject.isFieldPresent(sfSigners)) { // simulate: skip signature validation when neither SigningPubKey nor // Signers are provided @@ -886,7 +886,7 @@ Transactor::checkMultiSign( // Master Key. Account may not have asfDisableMaster set. std::uint32_t const signerAccountFlags = sleTxSignerRoot->getFieldU32(sfFlags); - if (signerAccountFlags & lsfDisableMaster) + if ((signerAccountFlags & lsfDisableMaster) != 0u) { JLOG(j.trace()) << "applyTransaction: Signer:Account lsfDisableMaster."; return tefMASTER_DISABLED; @@ -1119,7 +1119,7 @@ Transactor::operator()() if (ctx_.size() > oversizeMetaDataCap) result = tecOVERSIZE; - if (isTecClaim(result) && (view().flags() & tapFAIL_HARD)) + if (isTecClaim(result) && ((view().flags() & tapFAIL_HARD) != 0u)) { // If the tapFAIL_HARD flag is set, a tec result // must not do anything @@ -1264,7 +1264,7 @@ Transactor::operator()() metadata = ctx_.apply(result); } - if (ctx_.flags() & tapDRY_RUN) + if ((ctx_.flags() & tapDRY_RUN) != 0u) { applied = false; } diff --git a/src/libxrpl/tx/apply.cpp b/src/libxrpl/tx/apply.cpp index 8fd898366e..caf716eda6 100644 --- a/src/libxrpl/tx/apply.cpp +++ b/src/libxrpl/tx/apply.cpp @@ -149,7 +149,7 @@ applyBatchTransactions( beast::Journal j) { XRPL_ASSERT( - batchTxn.getTxnType() == ttBATCH && batchTxn.getFieldArray(sfRawTransactions).size() != 0, + batchTxn.getTxnType() == ttBATCH && !batchTxn.getFieldArray(sfRawTransactions).empty(), "Batch transaction missing sfRawTransactions"); auto const parentBatchId = batchTxn.getTransactionID(); @@ -188,13 +188,13 @@ applyBatchTransactions( if (!isTesSuccess(result.ter)) { - if (mode & tfAllOrNothing) + if ((mode & tfAllOrNothing) != 0u) return false; - if (mode & tfUntilFailure) + if ((mode & tfUntilFailure) != 0u) break; } - else if (mode & tfOnlyOne) + else if ((mode & tfOnlyOne) != 0u) { break; } diff --git a/src/libxrpl/tx/invariants/AMMInvariant.cpp b/src/libxrpl/tx/invariants/AMMInvariant.cpp index b64be6192b..96df97016f 100644 --- a/src/libxrpl/tx/invariants/AMMInvariant.cpp +++ b/src/libxrpl/tx/invariants/AMMInvariant.cpp @@ -28,7 +28,7 @@ ValidAMM::visitEntry( } // AMM pool changed else if ( - (type == ltRIPPLE_STATE && after->getFlags() & lsfAMMNode) || + (type == ltRIPPLE_STATE && ((after->getFlags() & lsfAMMNode) != 0u)) || (type == ltACCOUNT_ROOT && after->isFieldPresent(sfAMMID))) { ammPoolChanged_ = true; diff --git a/src/libxrpl/tx/invariants/FreezeInvariant.cpp b/src/libxrpl/tx/invariants/FreezeInvariant.cpp index f38d260782..c8723b9bbf 100644 --- a/src/libxrpl/tx/invariants/FreezeInvariant.cpp +++ b/src/libxrpl/tx/invariants/FreezeInvariant.cpp @@ -271,12 +271,7 @@ TransfersNotFrozen::validateFrozenState( "xrpl::TransfersNotFrozen::validateFrozenState : enforce " "invariant."); - if (enforce) - { - return false; - } - - return true; + return !enforce; } } // namespace xrpl diff --git a/src/libxrpl/tx/invariants/InvariantCheck.cpp b/src/libxrpl/tx/invariants/InvariantCheck.cpp index 16108472aa..bf0f65f000 100644 --- a/src/libxrpl/tx/invariants/InvariantCheck.cpp +++ b/src/libxrpl/tx/invariants/InvariantCheck.cpp @@ -631,11 +631,11 @@ NoDeepFreezeTrustLinesWithoutFreeze::visitEntry( if (after && after->getType() == ltRIPPLE_STATE) { std::uint32_t const uFlags = after->getFieldU32(sfFlags); - bool const lowFreeze = uFlags & lsfLowFreeze; - bool const lowDeepFreeze = uFlags & lsfLowDeepFreeze; + bool const lowFreeze = (uFlags & lsfLowFreeze) != 0u; + bool const lowDeepFreeze = (uFlags & lsfLowDeepFreeze) != 0u; - bool const highFreeze = uFlags & lsfHighFreeze; - bool const highDeepFreeze = uFlags & lsfHighDeepFreeze; + bool const highFreeze = (uFlags & lsfHighFreeze) != 0u; + bool const highDeepFreeze = (uFlags & lsfHighDeepFreeze) != 0u; deepFreezeWithoutFreeze_ = (lowDeepFreeze && !lowFreeze) || (highDeepFreeze && !highFreeze); } diff --git a/src/libxrpl/tx/invariants/LoanInvariant.cpp b/src/libxrpl/tx/invariants/LoanInvariant.cpp index 0df7e409d1..c0ce320846 100644 --- a/src/libxrpl/tx/invariants/LoanInvariant.cpp +++ b/src/libxrpl/tx/invariants/LoanInvariant.cpp @@ -46,11 +46,11 @@ bool ValidLoanBroker::goodZeroDirectory( ReadView const& view, SLE::const_ref dir, - beast::Journal const& j) const + beast::Journal const& j) { auto const next = dir->at(~sfIndexNext); auto const prev = dir->at(~sfIndexPrevious); - if ((prev && *prev) || (next && *next)) + if ((prev && (*prev != 0u)) || (next && (*next != 0u))) { JLOG(j.fatal()) << "Invariant failed: Loan Broker with zero " "OwnerCount has multiple directory pages"; diff --git a/src/libxrpl/tx/paths/RippleCalc.cpp b/src/libxrpl/tx/paths/RippleCalc.cpp index e87ecab90f..cebb5c6dcc 100644 --- a/src/libxrpl/tx/paths/RippleCalc.cpp +++ b/src/libxrpl/tx/paths/RippleCalc.cpp @@ -43,9 +43,9 @@ RippleCalc::rippleCalculate( auto j = l.journal("Flow"); { - bool const defaultPaths = !pInputs ? true : pInputs->defaultPathsAllowed; + bool const defaultPaths = (pInputs == nullptr) ? true : pInputs->defaultPathsAllowed; - bool const partialPayment = !pInputs ? false : pInputs->partialPaymentAllowed; + bool const partialPayment = (pInputs == nullptr) ? false : pInputs->partialPaymentAllowed; auto const limitQuality = [&]() -> std::optional { if (pInputs && pInputs->limitQuality && saMaxAmountReq > beast::zero) diff --git a/src/libxrpl/tx/transactors/account/AccountDelete.cpp b/src/libxrpl/tx/transactors/account/AccountDelete.cpp index fed265c125..8c2f23b754 100644 --- a/src/libxrpl/tx/transactors/account/AccountDelete.cpp +++ b/src/libxrpl/tx/transactors/account/AccountDelete.cpp @@ -22,10 +22,7 @@ namespace xrpl { bool AccountDelete::checkExtraFeatures(PreflightContext const& ctx) { - if (ctx.tx.isFieldPresent(sfCredentialIDs) && !ctx.rules.enabled(featureCredentials)) - return false; - - return true; + return !ctx.tx.isFieldPresent(sfCredentialIDs) || ctx.rules.enabled(featureCredentials); } NotTEC @@ -216,7 +213,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx) if (!sleDst) return tecNO_DST; - if ((*sleDst)[sfFlags] & lsfRequireDestTag && !ctx.tx[~sfDestinationTag]) + if ((((*sleDst)[sfFlags] & lsfRequireDestTag) != 0u) && !ctx.tx[~sfDestinationTag]) return tecDST_TAG_NEEDED; // If credentials are provided - check them anyway @@ -228,7 +225,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx) if (!ctx.tx.isFieldPresent(sfCredentialIDs)) { // Check whether the destination account requires deposit authorization. - if (sleDst->getFlags() & lsfDepositAuth) + if ((sleDst->getFlags() & lsfDepositAuth) != 0u) { if (!ctx.view.exists(keylet::depositPreauth(dst, account))) return tecNO_PERMISSION; @@ -313,7 +310,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx) LedgerEntryType const nodeType{safe_cast((*sleItem)[sfLedgerEntryType])}; - if (!nonObligationDeleter(nodeType)) + if (nonObligationDeleter(nodeType) == nullptr) return tecHAS_OBLIGATIONS; // We found a deletable directory entry. Count it. If we find too diff --git a/src/libxrpl/tx/transactors/account/AccountSet.cpp b/src/libxrpl/tx/transactors/account/AccountSet.cpp index 33759c6ec4..d99324f802 100644 --- a/src/libxrpl/tx/transactors/account/AccountSet.cpp +++ b/src/libxrpl/tx/transactors/account/AccountSet.cpp @@ -63,8 +63,8 @@ AccountSet::preflight(PreflightContext const& ctx) // // RequireAuth // - bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth); - bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth); + bool bSetRequireAuth = ((uTxFlags & tfRequireAuth) != 0u) || (uSetFlag == asfRequireAuth); + bool bClearRequireAuth = ((uTxFlags & tfOptionalAuth) != 0u) || (uClearFlag == asfRequireAuth); if (bSetRequireAuth && bClearRequireAuth) { @@ -75,8 +75,9 @@ AccountSet::preflight(PreflightContext const& ctx) // // RequireDestTag // - bool bSetRequireDest = (uTxFlags & tfRequireDestTag) || (uSetFlag == asfRequireDest); - bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest); + bool bSetRequireDest = ((uTxFlags & tfRequireDestTag) != 0u) || (uSetFlag == asfRequireDest); + bool bClearRequireDest = + ((uTxFlags & tfOptionalDestTag) != 0u) || (uClearFlag == asfRequireDest); if (bSetRequireDest && bClearRequireDest) { @@ -87,8 +88,8 @@ AccountSet::preflight(PreflightContext const& ctx) // // DisallowXRP // - bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP); - bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP); + bool bSetDisallowXRP = ((uTxFlags & tfDisallowXRP) != 0u) || (uSetFlag == asfDisallowXRP); + bool bClearDisallowXRP = ((uTxFlags & tfAllowXRP) != 0u) || (uClearFlag == asfDisallowXRP); if (bSetDisallowXRP && bClearDisallowXRP) { @@ -101,7 +102,7 @@ AccountSet::preflight(PreflightContext const& ctx) { std::uint32_t uRate = tx.getFieldU32(sfTransferRate); - if (uRate && (uRate < QUALITY_ONE)) + if ((uRate != 0u) && (uRate < QUALITY_ONE)) { JLOG(j.trace()) << "Malformed transaction: Transfer rate too small."; return temBAD_TRANSFER_RATE; @@ -118,7 +119,8 @@ AccountSet::preflight(PreflightContext const& ctx) if (tx.isFieldPresent(sfTickSize)) { auto uTickSize = tx[sfTickSize]; - if (uTickSize && ((uTickSize < Quality::minTickSize) || (uTickSize > Quality::maxTickSize))) + if ((uTickSize != 0u) && + ((uTickSize < Quality::minTickSize) || (uTickSize > Quality::maxTickSize))) { JLOG(j.trace()) << "Malformed transaction: Bad tick size."; return temBAD_TICK_SIZE; @@ -175,7 +177,7 @@ AccountSet::checkPermission(ReadView const& view, STTx const& tx) // AccountSet transaction. If any delegated account is trying to // update the flag on behalf of another account, it is not // authorized. - if (uSetFlag != 0 || uClearFlag != 0 || uTxFlags & tfUniversalMask) + if (uSetFlag != 0 || uClearFlag != 0 || ((uTxFlags & tfUniversalMask) != 0u)) return terNO_DELEGATE_PERMISSION; if (tx.isFieldPresent(sfEmailHash) && !granularPermissions.contains(AccountEmailHashSet)) @@ -215,17 +217,17 @@ AccountSet::preclaim(PreclaimContext const& ctx) std::uint32_t const uSetFlag = ctx.tx.getFieldU32(sfSetFlag); // legacy AccountSet flags - bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth); + bool bSetRequireAuth = ((uTxFlags & tfRequireAuth) != 0u) || (uSetFlag == asfRequireAuth); // // RequireAuth // - if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth)) + if (bSetRequireAuth && ((uFlagsIn & lsfRequireAuth) == 0u)) { if (!dirIsEmpty(ctx.view, keylet::ownerDir(id))) { JLOG(ctx.j.trace()) << "Retry: Owner directory not empty."; - return (ctx.flags & tapRETRY) ? TER{terOWNERS} : TER{tecOWNERS}; + return ((ctx.flags & tapRETRY) != 0u) ? TER{terOWNERS} : TER{tecOWNERS}; } } @@ -236,7 +238,7 @@ AccountSet::preclaim(PreclaimContext const& ctx) { if (uSetFlag == asfAllowTrustLineClawback) { - if (uFlagsIn & lsfNoFreeze) + if ((uFlagsIn & lsfNoFreeze) != 0u) { JLOG(ctx.j.trace()) << "Can't set Clawback if NoFreeze is set"; return tecNO_PERMISSION; @@ -251,7 +253,7 @@ AccountSet::preclaim(PreclaimContext const& ctx) else if (uSetFlag == asfNoFreeze) { // Cannot set NoFreeze if clawback is enabled - if (uFlagsIn & lsfAllowTrustLineClawback) + if ((uFlagsIn & lsfAllowTrustLineClawback) != 0u) { JLOG(ctx.j.trace()) << "Can't set NoFreeze if clawback is enabled"; return tecNO_PERMISSION; @@ -278,12 +280,15 @@ AccountSet::doApply() // legacy AccountSet flags std::uint32_t const uTxFlags{tx.getFlags()}; - bool const bSetRequireDest{(uTxFlags & tfRequireDestTag) || (uSetFlag == asfRequireDest)}; - bool const bClearRequireDest{(uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest)}; - bool const bSetRequireAuth{(uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth)}; - bool const bClearRequireAuth{(uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth)}; - bool const bSetDisallowXRP{(uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP)}; - bool const bClearDisallowXRP{(uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP)}; + bool const bSetRequireDest{ + ((uTxFlags & tfRequireDestTag) != 0u) || (uSetFlag == asfRequireDest)}; + bool const bClearRequireDest{ + ((uTxFlags & tfOptionalDestTag) != 0u) || (uClearFlag == asfRequireDest)}; + bool const bSetRequireAuth{((uTxFlags & tfRequireAuth) != 0u) || (uSetFlag == asfRequireAuth)}; + bool const bClearRequireAuth{ + ((uTxFlags & tfOptionalAuth) != 0u) || (uClearFlag == asfRequireAuth)}; + bool const bSetDisallowXRP{((uTxFlags & tfDisallowXRP) != 0u) || (uSetFlag == asfDisallowXRP)}; + bool const bClearDisallowXRP{((uTxFlags & tfAllowXRP) != 0u) || (uClearFlag == asfDisallowXRP)}; bool const sigWithMaster{[&tx, &acct = account_]() { auto const spk = tx.getSigningPubKey(); @@ -301,13 +306,13 @@ AccountSet::doApply() // // RequireAuth // - if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth)) + if (bSetRequireAuth && ((uFlagsIn & lsfRequireAuth) == 0u)) { JLOG(j_.trace()) << "Set RequireAuth."; uFlagsOut |= lsfRequireAuth; } - if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth)) + if (bClearRequireAuth && ((uFlagsIn & lsfRequireAuth) != 0u)) { JLOG(j_.trace()) << "Clear RequireAuth."; uFlagsOut &= ~lsfRequireAuth; @@ -316,13 +321,13 @@ AccountSet::doApply() // // RequireDestTag // - if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag)) + if (bSetRequireDest && ((uFlagsIn & lsfRequireDestTag) == 0u)) { JLOG(j_.trace()) << "Set lsfRequireDestTag."; uFlagsOut |= lsfRequireDestTag; } - if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag)) + if (bClearRequireDest && ((uFlagsIn & lsfRequireDestTag) != 0u)) { JLOG(j_.trace()) << "Clear lsfRequireDestTag."; uFlagsOut &= ~lsfRequireDestTag; @@ -331,13 +336,13 @@ AccountSet::doApply() // // DisallowXRP // - if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP)) + if (bSetDisallowXRP && ((uFlagsIn & lsfDisallowXRP) == 0u)) { JLOG(j_.trace()) << "Set lsfDisallowXRP."; uFlagsOut |= lsfDisallowXRP; } - if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP)) + if (bClearDisallowXRP && ((uFlagsIn & lsfDisallowXRP) != 0u)) { JLOG(j_.trace()) << "Clear lsfDisallowXRP."; uFlagsOut &= ~lsfDisallowXRP; @@ -346,7 +351,7 @@ AccountSet::doApply() // // DisableMaster // - if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster)) + if ((uSetFlag == asfDisableMaster) && ((uFlagsIn & lsfDisableMaster) == 0u)) { if (!sigWithMaster) { @@ -364,7 +369,7 @@ AccountSet::doApply() uFlagsOut |= lsfDisableMaster; } - if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster)) + if ((uClearFlag == asfDisableMaster) && ((uFlagsIn & lsfDisableMaster) != 0u)) { JLOG(j_.trace()) << "Clear lsfDisableMaster."; uFlagsOut &= ~lsfDisableMaster; @@ -389,7 +394,7 @@ AccountSet::doApply() // if (uSetFlag == asfNoFreeze) { - if (!sigWithMaster && !(uFlagsIn & lsfDisableMaster)) + if (!sigWithMaster && ((uFlagsIn & lsfDisableMaster) == 0u)) { JLOG(j_.trace()) << "Must use master key to set NoFreeze."; return tecNEED_MASTER_KEY; diff --git a/src/libxrpl/tx/transactors/account/SetRegularKey.cpp b/src/libxrpl/tx/transactors/account/SetRegularKey.cpp index 08175b196f..471da26c88 100644 --- a/src/libxrpl/tx/transactors/account/SetRegularKey.cpp +++ b/src/libxrpl/tx/transactors/account/SetRegularKey.cpp @@ -17,7 +17,7 @@ SetRegularKey::calculateBaseFee(ReadView const& view, STTx const& tx) { auto const sle = view.read(keylet::account(id)); - if (sle && (!(sle->getFlags() & lsfPasswordSpent))) + if (sle && ((sle->getFlags() & lsfPasswordSpent) == 0u)) { // flag is armed and they signed with the right account return XRPAmount{0}; diff --git a/src/libxrpl/tx/transactors/account/SignerListSet.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp index fe9e80d7e0..fcc74a6b2c 100644 --- a/src/libxrpl/tx/transactors/account/SignerListSet.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -30,7 +30,7 @@ SignerListSet::determineOperation(STTx const& tx, ApplyFlags flags, beast::Journ Operation op = unknown; bool const hasSignerEntries(tx.isFieldPresent(sfSignerEntries)); - if (quorum && hasSignerEntries) + if ((quorum != 0u) && hasSignerEntries) { auto signers = SignerEntries::deserialize(tx, j, "transaction"); @@ -363,7 +363,7 @@ SignerListSet::writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t } ledgerEntry->setFieldU32(sfSignerQuorum, quorum_); ledgerEntry->setFieldU32(sfSignerListID, DEFAULT_SIGNER_LIST_ID); - if (flags) // Only set flags if they are non-default (default is zero). + if (flags != 0u) // Only set flags if they are non-default (default is zero). ledgerEntry->setFieldU32(sfFlags, flags); // Create the SignerListArray one SignerEntry at a time. diff --git a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp index 9ac755cf4d..8c09fefe5a 100644 --- a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp +++ b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp @@ -109,7 +109,7 @@ checkAttestationPublicKey( if (accountFromPK == attestationSignerAccount) { // master key - if (sleAttestationSigningAccount->getFieldU32(sfFlags) & lsfDisableMaster) + if ((sleAttestationSigningAccount->getFieldU32(sfFlags) & lsfDisableMaster) != 0u) { JLOG(j.trace()) << "Attempt to add an attestation with " "disabled master key."; @@ -386,7 +386,7 @@ transferHelper( { // Check dst tag and deposit auth - if ((sleDst->getFlags() & lsfRequireDestTag) && !dstTag) + if (((sleDst->getFlags() & lsfRequireDestTag) != 0u) && !dstTag) return tecDST_TAG_NEEDED; // If the destination is the claim owner, and this is a claim @@ -395,7 +395,7 @@ transferHelper( bool const canBypassDepositAuth = dst == claimOwner && depositAuthPolicy == DepositAuthPolicy::dstCanBypass; - if (!canBypassDepositAuth && (sleDst->getFlags() & lsfDepositAuth) && + if (!canBypassDepositAuth && ((sleDst->getFlags() & lsfDepositAuth) != 0u) && !psb.exists(keylet::depositPreauth(dst, src))) { return tecNO_PERMISSION; @@ -1403,7 +1403,7 @@ XChainCreateBridge::preclaim(PreclaimContext const& ctx) // Allowing clawing back funds would break the bridge's invariant that // wrapped funds are always backed by locked funds - if (sleIssuer->getFlags() & lsfAllowTrustLineClawback) + if ((sleIssuer->getFlags() & lsfAllowTrustLineClawback) != 0u) return tecNO_PERMISSION; } @@ -1482,7 +1482,7 @@ BridgeModify::preflight(PreflightContext const& ctx) auto const reward = ctx.tx[~sfSignatureReward]; auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount]; auto const bridgeSpec = ctx.tx[sfXChainBridge]; - bool const clearAccountCreate = ctx.tx.getFlags() & tfClearAccountCreateAmount; + bool const clearAccountCreate = (ctx.tx.getFlags() & tfClearAccountCreateAmount) != 0u; if (!reward && !minAccountCreate && !clearAccountCreate) { @@ -1540,7 +1540,7 @@ BridgeModify::doApply() auto const bridgeSpec = ctx_.tx[sfXChainBridge]; auto const reward = ctx_.tx[~sfSignatureReward]; auto const minAccountCreate = ctx_.tx[~sfMinAccountCreateAmount]; - bool const clearAccountCreate = ctx_.tx.getFlags() & tfClearAccountCreateAmount; + bool const clearAccountCreate = (ctx_.tx.getFlags() & tfClearAccountCreateAmount) != 0u; auto const sleAcct = ctx_.view().peek(keylet::account(account)); if (!sleAcct) diff --git a/src/libxrpl/tx/transactors/check/CheckCash.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp index 7fa53c7352..2546c2635c 100644 --- a/src/libxrpl/tx/transactors/check/CheckCash.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -82,7 +82,8 @@ CheckCash::preclaim(PreclaimContext const& ctx) return tecNO_ENTRY; } - if ((sleDst->getFlags() & lsfRequireDestTag) && !sleCheck->isFieldPresent(sfDestinationTag)) + if (((sleDst->getFlags() & lsfRequireDestTag) != 0u) && + !sleCheck->isFieldPresent(sfDestinationTag)) { // The tag is basically account-specific information we don't // understand, but we can require someone to fill it in. @@ -155,7 +156,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) return tecNO_ISSUER; } - if (sleIssuer->at(sfFlags) & lsfRequireAuth) + if ((sleIssuer->at(sfFlags) & lsfRequireAuth) != 0u) { auto const sleTrustLine = ctx.view.read(keylet::line(dstId, issuerId, currency)); @@ -172,7 +173,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) bool const canonical_gt(dstId > issuerId); bool const is_authorized( - sleTrustLine->at(sfFlags) & (canonical_gt ? lsfLowAuth : lsfHighAuth)); + (sleTrustLine->at(sfFlags) & (canonical_gt ? lsfLowAuth : lsfHighAuth)) != 0u); if (!is_authorized) { diff --git a/src/libxrpl/tx/transactors/check/CheckCreate.cpp b/src/libxrpl/tx/transactors/check/CheckCreate.cpp index 50554a1beb..1aa4ac15ba 100644 --- a/src/libxrpl/tx/transactors/check/CheckCreate.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -63,7 +63,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) auto const flags = sleDst->getFlags(); // Check if the destination has disallowed incoming checks - if (flags & lsfDisallowIncomingCheck) + if ((flags & lsfDisallowIncomingCheck) != 0u) return tecNO_PERMISSION; // Pseudo-accounts cannot cash checks. Note, this is not amendment-gated @@ -73,7 +73,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) if (isPseudoAccount(sleDst)) return tecNO_PERMISSION; - if ((flags & lsfRequireDestTag) && !ctx.tx.isFieldPresent(sfDestinationTag)) + if (((flags & lsfRequireDestTag) != 0u) && !ctx.tx.isFieldPresent(sfDestinationTag)) { // The tag is basically account-specific information we don't // understand, but we can require someone to fill it in. diff --git a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp index c4842b54e4..9c0018a647 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp @@ -60,7 +60,7 @@ CredentialAccept::preclaim(PreclaimContext const& ctx) return tecNO_ENTRY; } - if (sleCred->getFieldU32(sfFlags) & lsfAccepted) + if ((sleCred->getFieldU32(sfFlags) & lsfAccepted) != 0u) { JLOG(ctx.j.warn()) << "Credential already accepted: " << to_string(subject) << ", " << to_string(issuer) << ", " << credType; diff --git a/src/libxrpl/tx/transactors/dex/AMMClawback.cpp b/src/libxrpl/tx/transactors/dex/AMMClawback.cpp index a5fda15033..b8f4fe4b1b 100644 --- a/src/libxrpl/tx/transactors/dex/AMMClawback.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMClawback.cpp @@ -40,7 +40,7 @@ AMMClawback::preflight(PreflightContext const& ctx) auto const flags = ctx.tx.getFlags(); - if (flags & tfClawTwoAssets && asset.account != asset2.account) + if (((flags & tfClawTwoAssets) != 0u) && asset.account != asset2.account) { JLOG(ctx.j.trace()) << "AMMClawback: tfClawTwoAssets can only be enabled when two " "assets in the AMM pool are both issued by the issuer"; @@ -90,7 +90,8 @@ AMMClawback::preclaim(PreclaimContext const& ctx) // If AllowTrustLineClawback is not set or NoFreeze is set, return no // permission - if (!(issuerFlagsIn & lsfAllowTrustLineClawback) || (issuerFlagsIn & lsfNoFreeze)) + if (((issuerFlagsIn & lsfAllowTrustLineClawback) == 0u) || + ((issuerFlagsIn & lsfNoFreeze) != 0u)) return tecNO_PERMISSION; return tesSUCCESS; @@ -215,7 +216,7 @@ AMMClawback::applyGuts(Sandbox& sb) return tecINTERNAL; // LCOV_EXCL_LINE auto const flags = ctx_.tx.getFlags(); - if (flags & tfClawTwoAssets) + if ((flags & tfClawTwoAssets) != 0u) return rippleCredit(sb, holder, issuer, *amount2Withdraw, true, j_); return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp index cae83ccef1..eb3e61e80b 100644 --- a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp @@ -44,35 +44,35 @@ AMMDeposit::preflight(PreflightContext const& ctx) JLOG(ctx.j.debug()) << "AMM Deposit: invalid flags."; return temMALFORMED; } - if (flags & tfLPToken) + if ((flags & tfLPToken) != 0u) { // if included then both amount and amount2 are deposit min if (!lpTokens || ePrice || (amount && !amount2) || (!amount && amount2) || tradingFee) return temMALFORMED; } - else if (flags & tfSingleAsset) + else if ((flags & tfSingleAsset) != 0u) { // if included then lpTokens is deposit min if (!amount || amount2 || ePrice || tradingFee) return temMALFORMED; } - else if (flags & tfTwoAsset) + else if ((flags & tfTwoAsset) != 0u) { // if included then lpTokens is deposit min if (!amount || !amount2 || ePrice || tradingFee) return temMALFORMED; } - else if (flags & tfOneAssetLPToken) + else if ((flags & tfOneAssetLPToken) != 0u) { if (!amount || !lpTokens || amount2 || ePrice || tradingFee) return temMALFORMED; } - else if (flags & tfLimitLPToken) + else if ((flags & tfLimitLPToken) != 0u) { if (!amount || !ePrice || lpTokens || amount2 || tradingFee) return temMALFORMED; } - else if (flags & tfTwoAssetIfEmpty) + else if ((flags & tfTwoAssetIfEmpty) != 0u) { if (!amount || !amount2 || ePrice || lpTokens) return temMALFORMED; @@ -156,7 +156,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) if (!expected) return expected.error(); // LCOV_EXCL_LINE auto const [amountBalance, amount2Balance, lptAMMBalance] = *expected; - if (ctx.tx.getFlags() & tfTwoAssetIfEmpty) + if ((ctx.tx.getFlags() & tfTwoAssetIfEmpty) != 0u) { if (lptAMMBalance != beast::zero) return tecAMM_NOT_EMPTY; @@ -283,7 +283,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) }; // amount and amount2 are deposit min in case of tfLPToken - if (!(ctx.tx.getFlags() & tfLPToken)) + if ((ctx.tx.getFlags() & tfLPToken) == 0u) { if (auto const ter = checkAmount(amount, true)) return ter; diff --git a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp index b822ff6b84..7c87d53ea0 100644 --- a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp @@ -42,37 +42,37 @@ AMMWithdraw::preflight(PreflightContext const& ctx) JLOG(ctx.j.debug()) << "AMM Withdraw: invalid flags."; return temMALFORMED; } - if (flags & tfLPToken) + if ((flags & tfLPToken) != 0u) { if (!lpTokens || amount || amount2 || ePrice) return temMALFORMED; } - else if (flags & tfWithdrawAll) + else if ((flags & tfWithdrawAll) != 0u) { if (lpTokens || amount || amount2 || ePrice) return temMALFORMED; } - else if (flags & tfOneAssetWithdrawAll) + else if ((flags & tfOneAssetWithdrawAll) != 0u) { if (!amount || lpTokens || amount2 || ePrice) return temMALFORMED; } - else if (flags & tfSingleAsset) + else if ((flags & tfSingleAsset) != 0u) { if (!amount || lpTokens || amount2 || ePrice) return temMALFORMED; } - else if (flags & tfTwoAsset) + else if ((flags & tfTwoAsset) != 0u) { if (!amount || !amount2 || lpTokens || ePrice) return temMALFORMED; } - else if (flags & tfOneAssetLPToken) + else if ((flags & tfOneAssetLPToken) != 0u) { if (!amount || !lpTokens || amount2 || ePrice) return temMALFORMED; } - else if (flags & tfLimitLPToken) + else if ((flags & tfLimitLPToken) != 0u) { if (!amount || !ePrice || lpTokens || amount2) return temMALFORMED; @@ -104,7 +104,7 @@ AMMWithdraw::preflight(PreflightContext const& ctx) if (auto const res = invalidAMMAmount( *amount, std::make_optional(std::make_pair(asset, asset2)), - (flags & (tfOneAssetWithdrawAll | tfOneAssetLPToken)) || ePrice)) + ((flags & (tfOneAssetWithdrawAll | tfOneAssetLPToken)) != 0u) || ePrice)) { JLOG(ctx.j.debug()) << "AMM Withdraw: invalid Asset1Out"; return res; @@ -139,7 +139,7 @@ tokensWithdraw( std::optional const& tokensIn, std::uint32_t flags) { - if (flags & (tfWithdrawAll | tfOneAssetWithdrawAll)) + if ((flags & (tfWithdrawAll | tfOneAssetWithdrawAll)) != 0u) return lpTokens; return tokensIn; } @@ -248,7 +248,7 @@ AMMWithdraw::preclaim(PreclaimContext const& ctx) return temBAD_AMM_TOKENS; } - if (ctx.tx.getFlags() & (tfLPToken | tfWithdrawAll)) + if ((ctx.tx.getFlags() & (tfLPToken | tfWithdrawAll)) != 0u) { if (auto const ter = checkAmount(amountBalance, amountBalance)) return ter; @@ -1018,7 +1018,7 @@ AMMWithdraw::singleWithdrawEPrice( WithdrawAll AMMWithdraw::isWithdrawAll(STTx const& tx) { - if (tx[sfFlags] & (tfWithdrawAll | tfOneAssetWithdrawAll)) + if ((tx[sfFlags] & (tfWithdrawAll | tfOneAssetWithdrawAll)) != 0u) return WithdrawAll::Yes; return WithdrawAll::No; } diff --git a/src/libxrpl/tx/transactors/dex/OfferCancel.cpp b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp index 9d60347778..a9e7cac85a 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCancel.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp @@ -9,7 +9,7 @@ namespace xrpl { NotTEC OfferCancel::preflight(PreflightContext const& ctx) { - if (!ctx.tx[sfOfferSequence]) + if (ctx.tx[sfOfferSequence] == 0u) { JLOG(ctx.j.trace()) << "OfferCancel::preflight: missing sequence"; return temBAD_SEQUENCE; diff --git a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp index d52fa94877..17dd2d2c57 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp @@ -30,10 +30,7 @@ OfferCreate::makeTxConsequences(PreflightContext const& ctx) bool OfferCreate::checkExtraFeatures(PreflightContext const& ctx) { - if (ctx.tx.isFieldPresent(sfDomainID) && !ctx.rules.enabled(featurePermissionedDEX)) - return false; - - return true; + return !ctx.tx.isFieldPresent(sfDomainID) || ctx.rules.enabled(featurePermissionedDEX); } std::uint32_t @@ -59,8 +56,8 @@ OfferCreate::preflight(PreflightContext const& ctx) if (tx.isFlag(tfHybrid) && !tx.isFieldPresent(sfDomainID)) return temINVALID_FLAG; - bool const bImmediateOrCancel(uTxFlags & tfImmediateOrCancel); - bool const bFillOrKill(uTxFlags & tfFillOrKill); + bool const bImmediateOrCancel((uTxFlags & tfImmediateOrCancel) != 0u); + bool const bFillOrKill((uTxFlags & tfFillOrKill) != 0u); if (bImmediateOrCancel && bFillOrKill) { @@ -215,7 +212,7 @@ OfferCreate::checkAcceptAsset( JLOG(j.debug()) << "delay: can't receive IOUs from non-existent issuer: " << to_string(issue.account); - return (flags & tapRETRY) ? TER{terNO_ACCOUNT} : TER{tecNO_ISSUER}; + return ((flags & tapRETRY) != 0u) ? TER{terNO_ACCOUNT} : TER{tecNO_ISSUER}; } // An account cannot create a trustline to itself, so no line can exist @@ -224,13 +221,13 @@ OfferCreate::checkAcceptAsset( if (issue.account == id) return tesSUCCESS; - if ((*issuerAccount)[sfFlags] & lsfRequireAuth) + if (((*issuerAccount)[sfFlags] & lsfRequireAuth) != 0u) { auto const trustLine = view.read(keylet::line(id, issue.account, issue.currency)); if (!trustLine) { - return (flags & tapRETRY) ? TER{terNO_LINE} : TER{tecNO_LINE}; + return ((flags & tapRETRY) != 0u) ? TER{terNO_LINE} : TER{tecNO_LINE}; } // Entries have a canonical representation, determined by a @@ -238,13 +235,14 @@ OfferCreate::checkAcceptAsset( // ordering. Determine which entry we need to access. bool const canonical_gt(id > issue.account); - bool const is_authorized((*trustLine)[sfFlags] & (canonical_gt ? lsfLowAuth : lsfHighAuth)); + bool const is_authorized( + ((*trustLine)[sfFlags] & (canonical_gt ? lsfLowAuth : lsfHighAuth)) != 0u); if (!is_authorized) { JLOG(j.debug()) << "delay: can't receive IOUs from issuer without auth."; - return (flags & tapRETRY) ? TER{terNO_AUTH} : TER{tecNO_AUTH}; + return ((flags & tapRETRY) != 0u) ? TER{terNO_AUTH} : TER{tecNO_AUTH}; } } @@ -257,7 +255,7 @@ OfferCreate::checkAcceptAsset( // There's no difference which side enacted deep freeze, accepting // tokens shouldn't be possible. - bool const deepFrozen = (*trustLine)[sfFlags] & (lsfLowDeepFreeze | lsfHighDeepFreeze); + bool const deepFrozen = ((*trustLine)[sfFlags] & (lsfLowDeepFreeze | lsfHighDeepFreeze)) != 0u; if (deepFrozen) { @@ -313,7 +311,7 @@ OfferCreate::flowCross( // If we're creating a passive offer adjust the threshold so we only // cross offers that have a better quality than this one. std::uint32_t const txFlags = ctx_.tx.getFlags(); - if (txFlags & tfPassive) + if ((txFlags & tfPassive) != 0u) ++threshold; // Don't send more than our balance. @@ -334,7 +332,7 @@ OfferCreate::flowCross( // Special handling for the tfSell flag. STAmount deliver = takerAmount.out; OfferCrossing offerCrossing = OfferCrossing::yes; - if (txFlags & tfSell) + if ((txFlags & tfSell) != 0u) { offerCrossing = OfferCrossing::sell; // We are selling, so we will accept *more* than the offer @@ -362,9 +360,9 @@ OfferCreate::flowCross( account_, account_, paths, - true, // default path - !(txFlags & tfFillOrKill), // partial payment - true, // owner pays transfer fee + true, // default path + (txFlags & tfFillOrKill) == 0u, // partial payment + true, // owner pays transfer fee offerCrossing, threshold, sendMax, @@ -398,7 +396,7 @@ OfferCreate::flowCross( { STAmount const rate{Quality{takerAmount.out, takerAmount.in}.rate()}; - if (txFlags & tfSell) + if ((txFlags & tfSell) != 0u) { // If selling then scale the new out amount based on how // much we sold during crossing. This preserves the offer @@ -517,11 +515,11 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel) std::uint32_t const uTxFlags = ctx_.tx.getFlags(); - bool const bPassive(uTxFlags & tfPassive); - bool const bImmediateOrCancel(uTxFlags & tfImmediateOrCancel); - bool const bFillOrKill(uTxFlags & tfFillOrKill); - bool const bSell(uTxFlags & tfSell); - bool const bHybrid(uTxFlags & tfHybrid); + bool const bPassive((uTxFlags & tfPassive) != 0u); + bool const bImmediateOrCancel((uTxFlags & tfImmediateOrCancel) != 0u); + bool const bFillOrKill((uTxFlags & tfFillOrKill) != 0u); + bool const bSell((uTxFlags & tfSell) != 0u); + bool const bHybrid((uTxFlags & tfHybrid) != 0u); auto saTakerPays = ctx_.tx[sfTakerPays]; auto saTakerGets = ctx_.tx[sfTakerGets]; diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp index 8b823de160..634b9b3a06 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp @@ -353,8 +353,7 @@ escrowLockApplyHelper( if (issuer == sender) return tecINTERNAL; // LCOV_EXCL_LINE - auto const ter = rippleCredit( - view, sender, issuer, amount, amount.holds() ? false : true, journal); + auto const ter = rippleCredit(view, sender, issuer, amount, !amount.holds(), journal); if (!isTesSuccess(ter)) return ter; // LCOV_EXCL_LINE return tesSUCCESS; @@ -415,7 +414,7 @@ EscrowCreate::doApply() auto const sled = ctx_.view().read(keylet::account(ctx_.tx[sfDestination])); if (!sled) return tecNO_DST; // LCOV_EXCL_LINE - if (((*sled)[sfFlags] & lsfRequireDestTag) && !ctx_.tx[~sfDestinationTag]) + if ((((*sled)[sfFlags] & lsfRequireDestTag) != 0u) && !ctx_.tx[~sfDestinationTag]) return tecDST_TAG_NEEDED; } diff --git a/src/libxrpl/tx/transactors/lending/LoanManage.cpp b/src/libxrpl/tx/transactors/lending/LoanManage.cpp index d507ba5499..6cc9df1aab 100644 --- a/src/libxrpl/tx/transactors/lending/LoanManage.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanManage.cpp @@ -26,7 +26,7 @@ LoanManage::preflight(PreflightContext const& ctx) return temINVALID; // Flags are mutually exclusive - if (auto const flagField = ctx.tx[~sfFlags]; flagField && *flagField) + if (auto const flagField = ctx.tx[~sfFlags]; flagField && (*flagField != 0u)) { auto const flags = *flagField & tfUniversalMask; if ((flags & (flags - 1)) != 0) diff --git a/src/libxrpl/tx/transactors/nft/NFTokenBurn.cpp b/src/libxrpl/tx/transactors/nft/NFTokenBurn.cpp index 6d9ee56c51..5a31e35470 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenBurn.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenBurn.cpp @@ -29,7 +29,7 @@ NFTokenBurn::preclaim(PreclaimContext const& ctx) // do so if the token is marked as burnable. if (auto const account = ctx.tx[sfAccount]; owner != account) { - if (!(nft::getFlags(ctx.tx[sfNFTokenID]) & nft::flagBurnable)) + if ((nft::getFlags(ctx.tx[sfNFTokenID]) & nft::flagBurnable) == 0) return tecNO_PERMISSION; if (auto const issuer = nft::getIssuer(ctx.tx[sfNFTokenID]); issuer != account) diff --git a/src/libxrpl/tx/transactors/nft/NFTokenCreateOffer.cpp b/src/libxrpl/tx/transactors/nft/NFTokenCreateOffer.cpp index eaca8b3380..f5fdc89550 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenCreateOffer.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenCreateOffer.cpp @@ -45,7 +45,7 @@ NFTokenCreateOffer::preclaim(PreclaimContext const& ctx) std::uint32_t const txFlags = ctx.tx.getFlags(); if (!nft::findToken( - ctx.view, ctx.tx[(txFlags & tfSellNFToken) ? sfAccount : sfOwner], nftokenID)) + ctx.view, ctx.tx[((txFlags & tfSellNFToken) != 0u) ? sfAccount : sfOwner], nftokenID)) return tecNO_ENTRY; // Use implementation shared with NFTokenMint diff --git a/src/libxrpl/tx/transactors/nft/NFTokenModify.cpp b/src/libxrpl/tx/transactors/nft/NFTokenModify.cpp index 1b2c9c2ab0..8ccd4e9552 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenModify.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenModify.cpp @@ -30,7 +30,7 @@ NFTokenModify::preclaim(PreclaimContext const& ctx) return tecNO_ENTRY; // Check if the NFT is mutable - if (!(nft::getFlags(ctx.tx[sfNFTokenID]) & nft::flagMutable)) + if ((nft::getFlags(ctx.tx[sfNFTokenID]) & nft::flagMutable) == 0) return tecNO_PERMISSION; // Verify permissions for the issuer diff --git a/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp b/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp index f7c12b5488..84826314e7 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp @@ -601,7 +601,7 @@ removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t if (maxDeletableOffers == deletedOffersCount) break; } - } while (pageIndex.value_or(0) && maxDeletableOffers != deletedOffersCount); + } while ((pageIndex.value_or(0) != 0u) && maxDeletableOffers != deletedOffersCount); return deletedOffersCount; } @@ -647,8 +647,8 @@ deleteTokenOffer(ApplyView& view, std::shared_ptr const& offer) auto const nftokenID = (*offer)[sfNFTokenID]; if (!view.dirRemove( - ((*offer)[sfFlags] & lsfSellNFToken) ? keylet::nft_sells(nftokenID) - : keylet::nft_buys(nftokenID), + (((*offer)[sfFlags] & lsfSellNFToken) != 0u) ? keylet::nft_sells(nftokenID) + : keylet::nft_buys(nftokenID), (*offer)[sfNFTokenOfferNode], offer->key(), false)) @@ -799,7 +799,7 @@ tokenOfferCreatePreflight( if (!isXRP(amount)) { - if (nftFlags & nft::flagOnlyXRP) + if ((nftFlags & nft::flagOnlyXRP) != 0) return temBAD_AMOUNT; if (!amount) @@ -808,7 +808,7 @@ tokenOfferCreatePreflight( // If this is an offer to buy, you must offer something; if it's an // offer to sell, you can ask for nothing. - bool const isSellOffer = txFlags & tfSellNFToken; + bool const isSellOffer = (txFlags & tfSellNFToken) != 0u; if (!isSellOffer && !amount) return temBAD_AMOUNT; @@ -844,7 +844,7 @@ tokenOfferCreatePreclaim( std::optional const& owner, std::uint32_t txFlags) { - if (!(nftFlags & nft::flagCreateTrustLines) && !amount.native() && xferFee) + if (((nftFlags & nft::flagCreateTrustLines) == 0) && !amount.native() && (xferFee != 0u)) { if (!view.exists(keylet::account(nftIssuer))) return tecNO_ISSUER; @@ -866,7 +866,7 @@ tokenOfferCreatePreclaim( return tecFROZEN; } - if (nftIssuer != acctID && !(nftFlags & nft::flagTransferable)) + if (nftIssuer != acctID && ((nftFlags & nft::flagTransferable) == 0)) { auto const root = view.read(keylet::account(nftIssuer)); XRPL_ASSERT(root, "xrpl::nft::tokenOfferCreatePreclaim : non-null account"); @@ -899,7 +899,7 @@ tokenOfferCreatePreclaim( return tecNO_DST; // check if the destination has disallowed incoming offers - if (sleDst->getFlags() & lsfDisallowIncomingNFTokenOffer) + if ((sleDst->getFlags() & lsfDisallowIncomingNFTokenOffer) != 0u) return tecNO_PERMISSION; } @@ -912,7 +912,7 @@ tokenOfferCreatePreclaim( if (!sleOwner) return tecNO_TARGET; - if (sleOwner->getFlags() & lsfDisallowIncomingNFTokenOffer) + if ((sleOwner->getFlags() & lsfDisallowIncomingNFTokenOffer) != 0u) return tecNO_PERMISSION; } @@ -960,7 +960,7 @@ tokenOfferCreateApply( if (!ownerNode) return tecDIR_FULL; // LCOV_EXCL_LINE - bool const isSellOffer = txFlags & tfSellNFToken; + bool const isSellOffer = (txFlags & tfSellNFToken) != 0u; // Token offers are also added to the token's buy or sell offer // directory @@ -1094,7 +1094,8 @@ checkTrustlineDeepFrozen( // There's no difference which side enacted deep freeze, accepting // tokens shouldn't be possible. - bool const deepFrozen = (*trustLine)[sfFlags] & (lsfLowDeepFreeze | lsfHighDeepFreeze); + bool const deepFrozen = + ((*trustLine)[sfFlags] & (lsfLowDeepFreeze | lsfHighDeepFreeze)) != 0u; if (deepFrozen) { diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index 60b8dcd823..0f4681a3ad 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -19,10 +19,7 @@ DepositPreauth::checkExtraFeatures(PreflightContext const& ctx) bool const unauthArrPresent = ctx.tx.isFieldPresent(sfUnauthorizeCredentials); bool const authCredPresent = authArrPresent || unauthArrPresent; - if (authCredPresent && !ctx.rules.enabled(featureCredentials)) - return false; - - return true; + return !authCredPresent || ctx.rules.enabled(featureCredentials); } NotTEC @@ -46,7 +43,7 @@ DepositPreauth::preflight(PreflightContext const& ctx) return temMALFORMED; } - if (authPresent) + if (authPresent != 0) { // Make sure that the passed account is valid. AccountID const& target(optAuth ? *optAuth : *optUnauth); diff --git a/src/libxrpl/tx/transactors/payment/Payment.cpp b/src/libxrpl/tx/transactors/payment/Payment.cpp index 38765016b5..c95afc33f9 100644 --- a/src/libxrpl/tx/transactors/payment/Payment.cpp +++ b/src/libxrpl/tx/transactors/payment/Payment.cpp @@ -91,9 +91,9 @@ Payment::preflight(PreflightContext const& ctx) if (mptDirect && ctx.tx.isFieldPresent(sfPaths)) return temMALFORMED; - bool const partialPaymentAllowed = txFlags & tfPartialPayment; - bool const limitQuality = txFlags & tfLimitQuality; - bool const defaultPathsAllowed = !(txFlags & tfNoRippleDirect); + bool const partialPaymentAllowed = (txFlags & tfPartialPayment) != 0u; + bool const limitQuality = (txFlags & tfLimitQuality) != 0u; + bool const defaultPathsAllowed = (txFlags & tfNoRippleDirect) == 0u; bool const hasPaths = tx.isFieldPresent(sfPaths); bool const hasMax = tx.isFieldPresent(sfSendMax); @@ -269,7 +269,7 @@ Payment::preclaim(PreclaimContext const& ctx) { // Ripple if source or destination is non-native or if there are paths. std::uint32_t const txFlags = ctx.tx.getFlags(); - bool const partialPaymentAllowed = txFlags & tfPartialPayment; + bool const partialPaymentAllowed = (txFlags & tfPartialPayment) != 0u; auto const hasPaths = ctx.tx.isFieldPresent(sfPaths); auto const sendMax = ctx.tx[~sfSendMax]; @@ -314,7 +314,9 @@ Payment::preclaim(PreclaimContext const& ctx) return tecNO_DST_INSUF_XRP; } } - else if ((sleDst->getFlags() & lsfRequireDestTag) && !ctx.tx.isFieldPresent(sfDestinationTag)) + else if ( + ((sleDst->getFlags() & lsfRequireDestTag) != 0u) && + !ctx.tx.isFieldPresent(sfDestinationTag)) { // The tag is basically account-specific information we don't // understand, but we can require someone to fill it in. @@ -363,9 +365,9 @@ Payment::doApply() // Ripple if source or destination is non-native or if there are paths. std::uint32_t const txFlags = ctx_.tx.getFlags(); - bool const partialPaymentAllowed = txFlags & tfPartialPayment; - bool const limitQuality = txFlags & tfLimitQuality; - bool const defaultPathsAllowed = !(txFlags & tfNoRippleDirect); + bool const partialPaymentAllowed = (txFlags & tfPartialPayment) != 0u; + bool const limitQuality = (txFlags & tfLimitQuality) != 0u; + bool const defaultPathsAllowed = (txFlags & tfNoRippleDirect) == 0u; auto const hasPaths = ctx_.tx.isFieldPresent(sfPaths); auto const sendMax = ctx_.tx[~sfSendMax]; @@ -619,7 +621,7 @@ Payment::doApply() sleDst->setFieldAmount(sfBalance, sleDst->getFieldAmount(sfBalance) + dstAmount); // Re-arm the password change fee if we can and need to. - if ((sleDst->getFlags() & lsfPasswordSpent)) + if ((sleDst->getFlags() & lsfPasswordSpent) != 0u) sleDst->clearFlag(lsfPasswordSpent); return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp index 6ba489bbc3..dccaf8f071 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp @@ -42,7 +42,7 @@ PaymentChannelClaim::preflight(PreflightContext const& ctx) { auto const flags = ctx.tx.getFlags(); - if ((flags & tfClose) && (flags & tfRenew)) + if (((flags & tfClose) != 0u) && ((flags & tfRenew) != 0u)) return temMALFORMED; } @@ -158,7 +158,7 @@ PaymentChannelClaim::doApply() ctx_.view().update(slep); } - if (ctx_.tx.getFlags() & tfRenew) + if ((ctx_.tx.getFlags() & tfRenew) != 0u) { if (src != txAccount) return tecNO_PERMISSION; @@ -166,7 +166,7 @@ PaymentChannelClaim::doApply() ctx_.view().update(slep); } - if (ctx_.tx.getFlags() & tfClose) + if ((ctx_.tx.getFlags() & tfClose) != 0u) { // Channel will close immediately if dry or the receiver closes if (dst == txAccount || (*slep)[sfBalance] == (*slep)[sfAmount]) diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp index 3f7e1e1814..c12169fc0e 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp @@ -85,10 +85,10 @@ PaymentChannelCreate::preclaim(PreclaimContext const& ctx) auto const flags = sled->getFlags(); // Check if they have disallowed incoming payment channels - if (flags & lsfDisallowIncomingPayChan) + if ((flags & lsfDisallowIncomingPayChan) != 0u) return tecNO_PERMISSION; - if ((flags & lsfRequireDestTag) && !ctx.tx[~sfDestinationTag]) + if (((flags & lsfRequireDestTag) != 0u) && !ctx.tx[~sfDestinationTag]) return tecDST_TAG_NEEDED; // Pseudo-accounts cannot receive payment channels, other than native diff --git a/src/libxrpl/tx/transactors/system/Batch.cpp b/src/libxrpl/tx/transactors/system/Batch.cpp index b2a111a182..b8b0d3234a 100644 --- a/src/libxrpl/tx/transactors/system/Batch.cpp +++ b/src/libxrpl/tx/transactors/system/Batch.cpp @@ -270,7 +270,7 @@ Batch::preflight(PreflightContext const& ctx) return temINVALID_INNER_BATCH; } - if (!(stx.getFlags() & tfInnerBatchTxn)) + if ((stx.getFlags() & tfInnerBatchTxn) == 0u) { JLOG(ctx.j.debug()) << "BatchTrace[" << parentBatchId << "]: " << "inner txn must have the tfInnerBatchTxn flag. " @@ -335,7 +335,7 @@ Batch::preflight(PreflightContext const& ctx) } // Duplicate sequence and ticket checks - if (flags & (tfAllOrNothing | tfUntilFailure)) + if ((flags & (tfAllOrNothing | tfUntilFailure)) != 0u) { if (auto const seq = stx.getFieldU32(sfSequence); seq != 0) { diff --git a/src/libxrpl/tx/transactors/system/Change.cpp b/src/libxrpl/tx/transactors/system/Change.cpp index 5b0a431004..b863f06cad 100644 --- a/src/libxrpl/tx/transactors/system/Change.cpp +++ b/src/libxrpl/tx/transactors/system/Change.cpp @@ -292,7 +292,7 @@ Change::applyUNLModify() return tefFAILURE; } - bool const disabling = ctx_.tx.getFieldU8(sfUNLModifyDisabling); + bool const disabling = ctx_.tx.getFieldU8(sfUNLModifyDisabling) != 0u; auto const seq = ctx_.tx.getFieldU32(sfLedgerSequence); if (seq != view().seq()) { diff --git a/src/libxrpl/tx/transactors/token/Clawback.cpp b/src/libxrpl/tx/transactors/token/Clawback.cpp index e8ba3cc0c5..57175ba427 100644 --- a/src/libxrpl/tx/transactors/token/Clawback.cpp +++ b/src/libxrpl/tx/transactors/token/Clawback.cpp @@ -90,7 +90,8 @@ preclaimHelper( // If AllowTrustLineClawback is not set or NoFreeze is set, return no // permission - if (!(issuerFlagsIn & lsfAllowTrustLineClawback) || (issuerFlagsIn & lsfNoFreeze)) + if (((issuerFlagsIn & lsfAllowTrustLineClawback) == 0u) || + ((issuerFlagsIn & lsfNoFreeze) != 0u)) return tecNO_PERMISSION; auto const sleRippleState = @@ -138,7 +139,7 @@ preclaimHelper( if (!sleIssuance) return tecOBJECT_NOT_FOUND; - if (!((*sleIssuance)[sfFlags] & lsfMPTCanClawback)) + if (((*sleIssuance)[sfFlags] & lsfMPTCanClawback) == 0u) return tecNO_PERMISSION; if (sleIssuance->getAccountID(sfIssuer) != issuer) diff --git a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp index 77551b372b..464ede9de7 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp @@ -48,7 +48,7 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx) // before fetching the MPTIssuance object. // if holder wants to delete/unauthorize a mpt - if (ctx.tx.getFlags() & tfMPTUnauthorize) + if ((ctx.tx.getFlags() & tfMPTUnauthorize) != 0u) { if (!sleMpt) return tecOBJECT_NOT_FOUND; @@ -116,7 +116,7 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx) // If tx is submitted by issuer, it only applies for MPT with // lsfMPTRequireAuth set - if (!(mptIssuanceFlags & lsfMPTRequireAuth)) + if ((mptIssuanceFlags & lsfMPTRequireAuth) == 0u) return tecNO_AUTH; // The holder must create the MPT before the issuer can authorize it. diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp index 58accf0271..6bcb1175e8 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp @@ -33,8 +33,8 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) { // If the mutable flags field is included, at least one flag must be // specified. - if (auto const mutableFlags = ctx.tx[~sfMutableFlags]; - mutableFlags && (!*mutableFlags || *mutableFlags & tmfMPTokenIssuanceCreateMutableMask)) + if (auto const mutableFlags = ctx.tx[~sfMutableFlags]; mutableFlags && + ((*mutableFlags == 0u) || ((*mutableFlags & tmfMPTokenIssuanceCreateMutableMask) != 0u))) return temINVALID_FLAG; if (auto const fee = ctx.tx[~sfTransferFee]) diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp index dc5827419b..fc09a53ae1 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp @@ -55,7 +55,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) auto const txFlags = ctx.tx.getFlags(); // fails if both flags are set - if ((txFlags & tfMPTLock) && (txFlags & tfMPTUnlock)) + if (((txFlags & tfMPTLock) != 0u) && ((txFlags & tfMPTUnlock) != 0u)) return temINVALID_FLAG; auto const accountID = ctx.tx[sfAccount]; @@ -77,7 +77,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) return temMALFORMED; // Can not set flags when mutating MPTokenIssuance - if (isMutate && (txFlags & tfUniversalMask)) + if (isMutate && ((txFlags & tfUniversalMask) != 0u)) return temMALFORMED; if (transferFee && *transferFee > maxTransferFee) @@ -88,7 +88,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) if (mutableFlags) { - if (!*mutableFlags || (*mutableFlags & tmfMPTokenIssuanceSetMutableMask)) + if ((*mutableFlags == 0u) || ((*mutableFlags & tmfMPTokenIssuanceSetMutableMask) != 0u)) return temINVALID_FLAG; // Can not set and clear the same flag @@ -102,7 +102,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) // Trying to set a non-zero TransferFee and clear MPTCanTransfer // in the same transaction is not allowed. - if (transferFee.value_or(0) && (*mutableFlags & tmfMPTClearCanTransfer)) + if ((transferFee.value_or(0) != 0u) && ((*mutableFlags & tmfMPTClearCanTransfer) != 0u)) return temMALFORMED; } } @@ -130,16 +130,16 @@ MPTokenIssuanceSet::checkPermission(ReadView const& view, STTx const& tx) // this is added in case more flags will be added for MPTokenIssuanceSet // in the future. Currently unreachable. - if (txFlags & tfMPTokenIssuanceSetMask) + if ((txFlags & tfMPTokenIssuanceSetMask) != 0u) return terNO_DELEGATE_PERMISSION; // LCOV_EXCL_LINE std::unordered_set granularPermissions; loadGranularPermission(sle, ttMPTOKEN_ISSUANCE_SET, granularPermissions); - if (txFlags & tfMPTLock && !granularPermissions.contains(MPTokenIssuanceLock)) + if (((txFlags & tfMPTLock) != 0u) && !granularPermissions.contains(MPTokenIssuanceLock)) return terNO_DELEGATE_PERMISSION; - if (txFlags & tfMPTUnlock && !granularPermissions.contains(MPTokenIssuanceUnlock)) + if (((txFlags & tfMPTUnlock) != 0u) && !granularPermissions.contains(MPTokenIssuanceUnlock)) return terNO_DELEGATE_PERMISSION; return tesSUCCESS; @@ -258,11 +258,11 @@ MPTokenIssuanceSet::doApply() std::uint32_t const flagsIn = sle->getFieldU32(sfFlags); std::uint32_t flagsOut = flagsIn; - if (txFlags & tfMPTLock) + if ((txFlags & tfMPTLock) != 0u) { flagsOut |= lsfMPTLocked; } - else if (txFlags & tfMPTUnlock) + else if ((txFlags & tfMPTUnlock) != 0u) { flagsOut &= ~lsfMPTLocked; } @@ -271,17 +271,17 @@ MPTokenIssuanceSet::doApply() { for (auto const& f : mptMutabilityFlags) { - if (mutableFlags & f.setFlag) + if ((mutableFlags & f.setFlag) != 0u) { flagsOut |= f.canMutateFlag; } - else if (mutableFlags & f.clearFlag) + else if ((mutableFlags & f.clearFlag) != 0u) { flagsOut &= ~f.canMutateFlag; } } - if (mutableFlags & tmfMPTClearCanTransfer) + if ((mutableFlags & tmfMPTClearCanTransfer) != 0u) { // If the lsfMPTCanTransfer flag is being cleared, then also clear // the TransferFee field. diff --git a/src/libxrpl/tx/transactors/token/TrustSet.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp index 22588b977a..918620c3de 100644 --- a/src/libxrpl/tx/transactors/token/TrustSet.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -65,7 +65,7 @@ TrustSet::preflight(PreflightContext const& ctx) { // Even though the deep freeze flags are included in the // `tfTrustSetMask`, they are not valid if the amendment is not enabled. - if (uTxFlags & (tfSetDeepFreeze | tfClearDeepFreeze)) + if ((uTxFlags & (tfSetDeepFreeze | tfClearDeepFreeze)) != 0u) { return temINVALID_FLAG; } @@ -128,7 +128,7 @@ TrustSet::checkPermission(ReadView const& view, STTx const& tx) // Currently we only support TrustlineAuthorize, TrustlineFreeze and // TrustlineUnfreeze granular permission. Setting other flags returns // error. - if (txFlags & tfTrustSetPermissionMask) + if ((txFlags & tfTrustSetPermissionMask) != 0u) return terNO_DELEGATE_PERMISSION; if (tx.isFieldPresent(sfQualityIn) || tx.isFieldPresent(sfQualityOut)) @@ -146,11 +146,11 @@ TrustSet::checkPermission(ReadView const& view, STTx const& tx) std::unordered_set granularPermissions; loadGranularPermission(sle, ttTRUST_SET, granularPermissions); - if (txFlags & tfSetfAuth && !granularPermissions.contains(TrustlineAuthorize)) + if (((txFlags & tfSetfAuth) != 0u) && !granularPermissions.contains(TrustlineAuthorize)) return terNO_DELEGATE_PERMISSION; - if (txFlags & tfSetFreeze && !granularPermissions.contains(TrustlineFreeze)) + if (((txFlags & tfSetFreeze) != 0u) && !granularPermissions.contains(TrustlineFreeze)) return terNO_DELEGATE_PERMISSION; - if (txFlags & tfClearFreeze && !granularPermissions.contains(TrustlineUnfreeze)) + if (((txFlags & tfClearFreeze) != 0u) && !granularPermissions.contains(TrustlineUnfreeze)) return terNO_DELEGATE_PERMISSION; // updating LimitAmount is not allowed only with granular permissions, @@ -179,9 +179,9 @@ TrustSet::preclaim(PreclaimContext const& ctx) std::uint32_t const uTxFlags = ctx.tx.getFlags(); - bool const bSetAuth = (uTxFlags & tfSetfAuth); + bool const bSetAuth = (uTxFlags & tfSetfAuth) != 0u; - if (bSetAuth && !(sle->getFieldU32(sfFlags) & lsfRequireAuth)) + if (bSetAuth && ((sle->getFieldU32(sfFlags) & lsfRequireAuth) == 0u)) { JLOG(ctx.j.trace()) << "Retry: Auth not required."; return tefNO_AUTH_REQUIRED; @@ -203,7 +203,7 @@ TrustSet::preclaim(PreclaimContext const& ctx) // If the destination has opted to disallow incoming trustlines // then honour that flag - if (sleDst->getFlags() & lsfDisallowIncomingTrustline) + if ((sleDst->getFlags() & lsfDisallowIncomingTrustline) != 0u) { // The original implementation of featureDisallowIncoming was // too restrictive. If @@ -268,8 +268,8 @@ TrustSet::preclaim(PreclaimContext const& ctx) if (ctx.view.rules().enabled(featureDeepFreeze)) { bool const bNoFreeze = sle->isFlag(lsfNoFreeze); - bool const bSetFreeze = (uTxFlags & tfSetFreeze); - bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze); + bool const bSetFreeze = (uTxFlags & tfSetFreeze) != 0u; + bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze) != 0u; if (bNoFreeze && (bSetFreeze || bSetDeepFreeze)) { @@ -277,8 +277,8 @@ TrustSet::preclaim(PreclaimContext const& ctx) return tecNO_PERMISSION; } - bool const bClearFreeze = (uTxFlags & tfClearFreeze); - bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze); + bool const bClearFreeze = (uTxFlags & tfClearFreeze) != 0u; + bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze) != 0u; if ((bSetFreeze || bSetDeepFreeze) && (bClearFreeze || bClearDeepFreeze)) { // Freezing and unfreezing in the same transaction should be @@ -300,7 +300,7 @@ TrustSet::preclaim(PreclaimContext const& ctx) // Trying to set deep freeze on not already frozen trust line must // fail. This also checks that clearing normal freeze while deep // frozen must not work - if (deepFrozen && !frozen) + if ((deepFrozen != 0u) && (frozen == 0u)) { return tecNO_PERMISSION; } @@ -359,13 +359,13 @@ TrustSet::doApply() std::uint32_t const uTxFlags = ctx_.tx.getFlags(); - bool const bSetAuth = (uTxFlags & tfSetfAuth); - bool const bSetNoRipple = (uTxFlags & tfSetNoRipple); - bool const bClearNoRipple = (uTxFlags & tfClearNoRipple); - bool const bSetFreeze = (uTxFlags & tfSetFreeze); - bool const bClearFreeze = (uTxFlags & tfClearFreeze); - bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze); - bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze); + bool const bSetAuth = (uTxFlags & tfSetfAuth) != 0u; + bool const bSetNoRipple = (uTxFlags & tfSetNoRipple) != 0u; + bool const bClearNoRipple = (uTxFlags & tfClearNoRipple) != 0u; + bool const bSetFreeze = (uTxFlags & tfSetFreeze) != 0u; + bool const bClearFreeze = (uTxFlags & tfClearFreeze) != 0u; + bool const bSetDeepFreeze = (uTxFlags & tfSetDeepFreeze) != 0u; + bool const bClearDeepFreeze = (uTxFlags & tfClearDeepFreeze) != 0u; auto viewJ = ctx_.registry.journal("View"); @@ -424,7 +424,7 @@ TrustSet::doApply() uLowQualityIn = sleRippleState->getFieldU32(sfLowQualityIn); uHighQualityIn = sleRippleState->getFieldU32(sfHighQualityIn); } - else if (uQualityIn) + else if (uQualityIn != 0u) { // Setting. @@ -460,7 +460,7 @@ TrustSet::doApply() uLowQualityOut = sleRippleState->getFieldU32(sfLowQualityOut); uHighQualityOut = sleRippleState->getFieldU32(sfHighQualityOut); } - else if (uQualityOut) + else if (uQualityOut != 0u) { // Setting. @@ -516,23 +516,23 @@ TrustSet::doApply() if (QUALITY_ONE == uHighQualityOut) uHighQualityOut = 0; - bool const bLowDefRipple = sleLowAccount->getFlags() & lsfDefaultRipple; - bool const bHighDefRipple = sleHighAccount->getFlags() & lsfDefaultRipple; + bool const bLowDefRipple = (sleLowAccount->getFlags() & lsfDefaultRipple) != 0u; + bool const bHighDefRipple = (sleHighAccount->getFlags() & lsfDefaultRipple) != 0u; - bool const bLowReserveSet = uLowQualityIn || uLowQualityOut || - ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple || (uFlagsOut & lsfLowFreeze) || - saLowLimit || saLowBalance > beast::zero; + bool const bLowReserveSet = (uLowQualityIn != 0u) || (uLowQualityOut != 0u) || + ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple || + ((uFlagsOut & lsfLowFreeze) != 0u) || saLowLimit || saLowBalance > beast::zero; bool const bLowReserveClear = !bLowReserveSet; - bool const bHighReserveSet = uHighQualityIn || uHighQualityOut || - ((uFlagsOut & lsfHighNoRipple) == 0) != bHighDefRipple || (uFlagsOut & lsfHighFreeze) || - saHighLimit || saHighBalance > beast::zero; + bool const bHighReserveSet = (uHighQualityIn != 0u) || (uHighQualityOut != 0u) || + ((uFlagsOut & lsfHighNoRipple) == 0) != bHighDefRipple || + ((uFlagsOut & lsfHighFreeze) != 0u) || saHighLimit || saHighBalance > beast::zero; bool const bHighReserveClear = !bHighReserveSet; bool const bDefault = bLowReserveClear && bHighReserveClear; - bool const bLowReserved = (uFlagsIn & lsfLowReserve); - bool const bHighReserved = (uFlagsIn & lsfHighReserve); + bool const bLowReserved = (uFlagsIn & lsfLowReserve) != 0u; + bool const bHighReserved = (uFlagsIn & lsfHighReserve) != 0u; bool bReserveIncrease = false; @@ -603,11 +603,11 @@ TrustSet::doApply() } // Line does not exist. else if ( - !saLimitAmount && // Setting default limit. - (!bQualityIn || !uQualityIn) && // Not setting quality in or - // setting default quality in. - (!bQualityOut || !uQualityOut) && // Not setting quality out or - // setting default quality out. + !saLimitAmount && // Setting default limit. + (!bQualityIn || (uQualityIn == 0u)) && // Not setting quality in or + // setting default quality in. + (!bQualityOut || (uQualityOut == 0u)) && // Not setting quality out or + // setting default quality out. (!bSetAuth)) { JLOG(j_.trace()) << "Redundant: Setting non-existent ripple line to defaults."; diff --git a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp index 0fc074bae2..02f8ecb57b 100644 --- a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp @@ -165,7 +165,7 @@ VaultCreate::doApply() std::uint32_t mptFlags = 0; if ((txFlags & tfVaultShareNonTransferable) == 0) mptFlags |= (lsfMPTCanEscrow | lsfMPTCanTrade | lsfMPTCanTransfer); - if (txFlags & tfVaultPrivate) + if ((txFlags & tfVaultPrivate) != 0u) mptFlags |= lsfMPTRequireAuth; // Note, here we are **not** creating an MPToken for the assets held in @@ -211,7 +211,7 @@ VaultCreate::doApply() { vault->at(sfWithdrawalPolicy) = vaultStrategyFirstComeFirstServe; } - if (scale) + if (scale != 0u) vault->at(sfScale) = scale; view().insert(vault); @@ -222,7 +222,7 @@ VaultCreate::doApply() return err; // If the vault is private, set the authorized flag for the vault owner - if (txFlags & tfVaultPrivate) + if ((txFlags & tfVaultPrivate) != 0u) { if (auto const err = authorizeMPToken( view(), preFeeBalance_, mptIssuanceID, pseudoId, ctx_.journal, {}, account_); diff --git a/src/libxrpl/tx/transactors/vault/VaultSet.cpp b/src/libxrpl/tx/transactors/vault/VaultSet.cpp index 532edcdcef..b54389bcde 100644 --- a/src/libxrpl/tx/transactors/vault/VaultSet.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultSet.cpp @@ -14,10 +14,7 @@ namespace xrpl { bool VaultSet::checkExtraFeatures(PreflightContext const& ctx) { - if (ctx.tx.isFieldPresent(sfDomainID) && !ctx.rules.enabled(featurePermissionedDomains)) - return false; - - return true; + return !ctx.tx.isFieldPresent(sfDomainID) || ctx.rules.enabled(featurePermissionedDomains); } NotTEC diff --git a/src/test/app/AMMCalc_test.cpp b/src/test/app/AMMCalc_test.cpp index c1068b08ba..b4043f239b 100644 --- a/src/test/app/AMMCalc_test.cpp +++ b/src/test/app/AMMCalc_test.cpp @@ -40,7 +40,7 @@ class AMMCalc_test : public beast::unit_test::suite boost::regex rx("^([^(]+)[(]([^)]+)[)]([)])?$"); if (boost::regex_search(str, match, rx)) { - if (delimited) + if (delimited != nullptr) *delimited = (match[3] != ""); if (match[1] == "XRP") { @@ -72,7 +72,7 @@ class AMMCalc_test : public beast::unit_test::suite // input is rate * 100, no fraction std::uint32_t rate = 10'000'000 * std::stoi(match[2].str()); // true if delimited - ) - return {{currency, rate, match[3] != "" ? true : false}}; + return {{currency, rate, match[3] != ""}}; } return std::nullopt; } @@ -94,7 +94,7 @@ class AMMCalc_test : public beast::unit_test::suite if (p == end_) return std::nullopt; std::string const s = *p; - bool const amm = s[0] == 'O' ? false : true; + bool const amm = s[0] != 'O'; auto const a1 = getAmt(p++); if (!a1 || p == end_) return std::nullopt; @@ -161,7 +161,7 @@ class AMMCalc_test : public beast::unit_test::suite return {{pairs, *swap, *rate, fee}}; } - std::string + static std::string toString(STAmount const& a) { std::stringstream str; @@ -169,7 +169,7 @@ class AMMCalc_test : public beast::unit_test::suite return str.str(); } - STAmount + static STAmount mulratio(STAmount const& amt, std::uint32_t a, std::uint32_t b, bool round) { if (a == b) @@ -179,7 +179,7 @@ class AMMCalc_test : public beast::unit_test::suite return toSTAmount(mulRatio(amt.iou(), a, b, round), amt.issue()); } - void + static void swapOut(swapargs const& args) { auto const vp = std::get(args); @@ -242,7 +242,7 @@ class AMMCalc_test : public beast::unit_test::suite std::cout << "in: " << toString(resultIn) << " out: " << toString(resultOut) << std::endl; } - void + static void swapIn(swapargs const& args) { auto const vp = std::get(args); diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index a0a38b9791..704ced2b86 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -1918,7 +1918,7 @@ private: BEAST_EXPECT(ammAlice.expectLPTokens(carol, IOUAmount(beast::Zero()))); BEAST_EXPECT(expectHolding(env, carol, USD(30'000))); BEAST_EXPECT( - expectLedgerEntryRoot(env, carol, XRPAmount{30'000'000'000 - 2 * baseFee})); + expectLedgerEntryRoot(env, carol, XRPAmount{30'000'000'000 - (2 * baseFee)})); }); // Equal withdrawal by tokens 1000000, 10% @@ -2732,13 +2732,13 @@ private: // 10th Interval after close, price for 1st interval. env(ammAlice.bid({.account = carol})); - env.close(seconds(10 * AUCTION_SLOT_INTERVAL_DURATION + 1)); + env.close(seconds((10 * AUCTION_SLOT_INTERVAL_DURATION) + 1)); BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 10, IOUAmount{121'275, -3})); // 20th Interval (expired) after close, price for 10th interval. env(ammAlice.bid({.account = bob})); env.close( - seconds(AUCTION_SLOT_TIME_INTERVALS * AUCTION_SLOT_INTERVAL_DURATION + 1)); + seconds((AUCTION_SLOT_TIME_INTERVALS * AUCTION_SLOT_INTERVAL_DURATION) + 1)); BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt, IOUAmount{127'33875, -5})); // 0 Interval. @@ -4111,7 +4111,7 @@ private: fund(env, gw, {bob}, {EUR(400)}, Fund::IOUOnly); env(trust(alice, EUR(200))); for (int i = 0; i < 30; ++i) - env(offer(alice, EUR(1.0 + 0.01 * i), XRP(1))); + env(offer(alice, EUR(1.0 + (0.01 * i)), XRP(1))); // This is worse quality offer than 30 offers above. // It will not be consumed because of AMM offers limit. env(offer(alice, EUR(140), XRP(100))); @@ -4151,7 +4151,7 @@ private: fund(env, gw, {bob}, {EUR(400)}, Fund::IOUOnly); env(trust(alice, EUR(200))); for (int i = 0; i < 29; ++i) - env(offer(alice, EUR(1.0 + 0.01 * i), XRP(1))); + env(offer(alice, EUR(1.0 + (0.01 * i)), XRP(1))); // This is worse quality offer than 30 offers above. // It will not be consumed because of AMM offers limit. env(offer(alice, EUR(140), XRP(100))); @@ -4268,7 +4268,7 @@ private: env(ammAlice.bid({.account = carol, .bidMin = 100})); BEAST_EXPECT(ammAlice.expectLPTokens(carol, IOUAmount{4'999'900})); BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0, IOUAmount{100})); - BEAST_EXPECT(accountBalance(env, carol) == std::to_string(22500000000 - 4 * baseFee)); + BEAST_EXPECT(accountBalance(env, carol) == std::to_string(22500000000 - (4 * baseFee))); priceXRP = ammAssetOut( STAmount{XRPAmount{10'000'000'000}}, STAmount{token1, 9'999'900}, @@ -4276,7 +4276,7 @@ private: 0); // Carol withdraws ammAlice.withdrawAll(carol, XRP(0)); - BEAST_EXPECT(accountBalance(env, carol) == std::to_string(29999949999 - 5 * baseFee)); + BEAST_EXPECT(accountBalance(env, carol) == std::to_string(29999949999 - (5 * baseFee))); BEAST_EXPECT(ammAlice.expectBalances( XRPAmount{10'000'000'000} - priceXRP, USD(10'000), IOUAmount{5'000'000})); BEAST_EXPECT(ammAlice.expectLPTokens(alice, IOUAmount{5'000'000})); @@ -5040,7 +5040,7 @@ private: // 30,000 initial - (deposit+withdraw) * 10 BEAST_EXPECT( accountBalance(env, carol) == - std::to_string(30'000'000'000 - 20 * baseFee)); + std::to_string(30'000'000'000 - (20 * baseFee))); BEAST_EXPECT(accountBalance(env, ed) == xrpBalance); BEAST_EXPECT(accountBalance(env, paul) == xrpBalance); BEAST_EXPECT(accountBalance(env, natalie) == xrpBalance); @@ -5064,7 +5064,7 @@ private: BEAST_EXPECT(accountBalance(env, dan) == xrpBalanceText); BEAST_EXPECT( accountBalance(env, carol) == - std::to_string(30'000'000'000 - 20 * baseFee - 10)); + std::to_string(30'000'000'000 - (20 * baseFee) - 10)); BEAST_EXPECT(accountBalance(env, ed) == (xrpBalance + drops(2)).getText()); BEAST_EXPECT(accountBalance(env, paul) == (xrpBalance + drops(3)).getText()); BEAST_EXPECT(accountBalance(env, natalie) == (xrpBalance + drops(5)).getText()); @@ -5155,7 +5155,7 @@ private: all); fund(env, gw, {alice}, XRP(20'000), {USD(10'000)}); AMM amm(env, gw, XRP(10'000), USD(10'000)); - for (auto i = 0; i < maxDeletableAMMTrustLines * 2 + 10; ++i) + for (auto i = 0; i < (maxDeletableAMMTrustLines * 2) + 10; ++i) { Account const a{std::to_string(i)}; env.fund(XRP(1'000), a); diff --git a/src/test/app/AccountTxPaging_test.cpp b/src/test/app/AccountTxPaging_test.cpp index 5efe307812..09b517c37c 100644 --- a/src/test/app/AccountTxPaging_test.cpp +++ b/src/test/app/AccountTxPaging_test.cpp @@ -10,7 +10,7 @@ namespace xrpl { class AccountTxPaging_test : public beast::unit_test::suite { - bool + static bool checkTransaction(Json::Value const& tx, int sequence, int ledger) { return ( @@ -18,7 +18,7 @@ class AccountTxPaging_test : public beast::unit_test::suite tx[jss::tx][jss::ledger_index].asInt() == ledger); } - auto + static auto next( test::jtx::Env& env, test::jtx::Account const& account, diff --git a/src/test/app/AmendmentTable_test.cpp b/src/test/app/AmendmentTable_test.cpp index d8431e5696..39e516304b 100644 --- a/src/test/app/AmendmentTable_test.cpp +++ b/src/test/app/AmendmentTable_test.cpp @@ -439,7 +439,7 @@ public: // Make a list of trusted validators. // Register the validators with AmendmentTable and return the list. - std::vector> + static std::vector> makeValidators(int num, std::unique_ptr const& table) { std::vector> ret; @@ -462,7 +462,7 @@ public: } // Execute a pretend consensus round for a flag ledger - void + static void doRound( Rules const& rules, AmendmentTable& table, diff --git a/src/test/app/Batch_test.cpp b/src/test/app/Batch_test.cpp index ec12fbb21f..9fe9e9cd3a 100644 --- a/src/test/app/Batch_test.cpp +++ b/src/test/app/Batch_test.cpp @@ -35,7 +35,7 @@ class Batch_test : public beast::unit_test::suite std::string txHash; }; - Json::Value + static Json::Value getTxByIndex(Json::Value const& jrr, int const index) { for (auto const& txn : jrr[jss::result][jss::ledger][jss::transactions]) @@ -46,7 +46,7 @@ class Batch_test : public beast::unit_test::suite return {}; } - Json::Value + static Json::Value getLastLedger(jtx::Env& env) { Json::Value params; @@ -125,7 +125,7 @@ class Batch_test : public beast::unit_test::suite return p; } - auto + static auto openLedgerFee(jtx::Env& env, XRPAmount const& batchFee) { using namespace jtx; diff --git a/src/test/app/Credentials_test.cpp b/src/test/app/Credentials_test.cpp index d23431f68e..db09bfc0ca 100644 --- a/src/test/app/Credentials_test.cpp +++ b/src/test/app/Credentials_test.cpp @@ -522,6 +522,7 @@ struct Credentials_test : public beast::unit_test::suite directory::adjustOwnerNode); BEAST_EXPECT(res1); + // NOLINTNEXTLINE(readability-suspicious-call-argument) auto const jv = credentials::create(issuer, subject, credType); env(jv, ter(tecDIR_FULL)); // Free one directory entry by using a ticket diff --git a/src/test/app/DepositAuth_test.cpp b/src/test/app/DepositAuth_test.cpp index ad401499bc..7a8404aad8 100644 --- a/src/test/app/DepositAuth_test.cpp +++ b/src/test/app/DepositAuth_test.cpp @@ -304,9 +304,11 @@ struct DepositAuth_test : public beast::unit_test::suite auto const noRipplePrev = i & 0x1; auto const noRippleNext = i & 0x2; auto const withDepositAuth = i & 0x4; - testIssuer(testable_amendments(), noRipplePrev, noRippleNext, withDepositAuth); + testIssuer( + testable_amendments(), noRipplePrev != 0, noRippleNext != 0, withDepositAuth != 0); - testNonIssuer(testable_amendments(), noRipplePrev, noRippleNext, withDepositAuth); + testNonIssuer( + testable_amendments(), noRipplePrev != 0, noRippleNext != 0, withDepositAuth != 0); } } diff --git a/src/test/app/EscrowToken_test.cpp b/src/test/app/EscrowToken_test.cpp index 280356c494..ff537a2f5e 100644 --- a/src/test/app/EscrowToken_test.cpp +++ b/src/test/app/EscrowToken_test.cpp @@ -35,7 +35,7 @@ struct EscrowToken_test : public beast::unit_test::suite return 0; } - jtx::PrettyAmount + static jtx::PrettyAmount issuerBalance(jtx::Env& env, jtx::Account const& account, Issue const& issue) { Json::Value params; @@ -49,7 +49,7 @@ struct EscrowToken_test : public beast::unit_test::suite return {amount, account.name()}; } - jtx::PrettyAmount + static jtx::PrettyAmount issuerEscrowed(jtx::Env& env, jtx::Account const& account, Issue const& issue) { Json::Value params; diff --git a/src/test/app/FeeVote_test.cpp b/src/test/app/FeeVote_test.cpp index f0599b8771..923e7b58b2 100644 --- a/src/test/app/FeeVote_test.cpp +++ b/src/test/app/FeeVote_test.cpp @@ -642,7 +642,7 @@ class FeeVote_test : public beast::unit_test::suite v.setFieldAmount(sfReserveBaseDrops, XRPAmount{setup.account_reserve}); v.setFieldAmount(sfReserveIncrementDrops, XRPAmount{setup.owner_reserve}); }); - if (i % 2) + if ((i % 2) != 0) val->setTrusted(); validations.push_back(val); } diff --git a/src/test/app/FixNFTokenPageLinks_test.cpp b/src/test/app/FixNFTokenPageLinks_test.cpp index 8022c52a5d..25366534cd 100644 --- a/src/test/app/FixNFTokenPageLinks_test.cpp +++ b/src/test/app/FixNFTokenPageLinks_test.cpp @@ -62,7 +62,7 @@ class FixNFTokenPageLinks_test : public beast::unit_test::suite // 0, 3, 2, 5, 4, 7... // in sets of 16 NFTs we can get each page to be fully // populated. - std::uint32_t const intTaxon = (i / 16) + (i & 0b10000 ? 2 : 0); + std::uint32_t const intTaxon = (i / 16) + (((i & 0b10000) != 0u) ? 2 : 0); uint32_t const extTaxon = internalTaxon(owner, intTaxon); nfts.push_back(token::getNextID(env, owner, extTaxon, tfTransferable)); env(token::mint(owner, extTaxon), txflags(tfTransferable)); diff --git a/src/test/app/Flow_test.cpp b/src/test/app/Flow_test.cpp index 1e9514f756..473f8bce20 100644 --- a/src/test/app/Flow_test.cpp +++ b/src/test/app/Flow_test.cpp @@ -241,7 +241,7 @@ struct Flow_test : public beast::unit_test::suite env.require(balance(bob, USDA(10))); env(pay(bob, carol, USDA(5)), sendmax(USDA(10))); auto const effectiveQ = carolAliceQIn > 100 ? 1.0 : carolAliceQIn / 100.0; - env.require(balance(bob, USDA(10.0 - 5.0 / effectiveQ))); + env.require(balance(bob, USDA(10.0 - (5.0 / effectiveQ)))); } // bob -> alice -> carol; bobAliceQOut varies. diff --git a/src/test/app/Freeze_test.cpp b/src/test/app/Freeze_test.cpp index 6f89163c04..1dd0de578b 100644 --- a/src/test/app/Freeze_test.cpp +++ b/src/test/app/Freeze_test.cpp @@ -1907,13 +1907,13 @@ class Freeze_test : public beast::unit_test::suite } // Helper function that returns the index of the next check on account - uint256 + static uint256 getCheckIndex(AccountID const& account, std::uint32_t uSequence) { return keylet::check(account, uSequence).key; } - uint256 + static uint256 createNFTSellOffer( test::jtx::Env& env, test::jtx::Account const& account, diff --git a/src/test/app/HashRouter_test.cpp b/src/test/app/HashRouter_test.cpp index 58bace3ef2..a1601914cf 100644 --- a/src/test/app/HashRouter_test.cpp +++ b/src/test/app/HashRouter_test.cpp @@ -10,7 +10,7 @@ namespace test { class HashRouter_test : public beast::unit_test::suite { - HashRouter::Setup + static HashRouter::Setup getSetup(std::chrono::seconds hold, std::chrono::seconds relay) { HashRouter::Setup setup; diff --git a/src/test/app/Invariants_test.cpp b/src/test/app/Invariants_test.cpp index 8372bb340b..9653a36edf 100644 --- a/src/test/app/Invariants_test.cpp +++ b/src/test/app/Invariants_test.cpp @@ -1227,7 +1227,7 @@ class Invariants_test : public beast::unit_test::suite sle->setAccountID(sfOwner, A1); sle->setFieldU32(sfSequence, seq); - if (numCreds) + if (numCreds != 0u) { // This array is sorted naturally, but if you willing to change this // behavior don't forget to use credentials::makeSorted diff --git a/src/test/app/LedgerMaster_test.cpp b/src/test/app/LedgerMaster_test.cpp index b48579043e..3ea16b63eb 100644 --- a/src/test/app/LedgerMaster_test.cpp +++ b/src/test/app/LedgerMaster_test.cpp @@ -8,7 +8,7 @@ namespace test { class LedgerMaster_test : public beast::unit_test::suite { - std::unique_ptr + static std::unique_ptr makeNetworkConfig(uint32_t networkID) { using namespace jtx; diff --git a/src/test/app/LedgerReplay_test.cpp b/src/test/app/LedgerReplay_test.cpp index 54c12b465a..59304f1894 100644 --- a/src/test/app/LedgerReplay_test.cpp +++ b/src/test/app/LedgerReplay_test.cpp @@ -232,9 +232,7 @@ public: bool supportsFeature(ProtocolFeature f) const override { - if (f == ProtocolFeature::LedgerReplay && ledgerReplayEnabled_) - return true; - return false; + return f == ProtocolFeature::LedgerReplay && ledgerReplayEnabled_; } std::optional publisherListSequence(PublicKey const&) const override @@ -363,7 +361,7 @@ struct TestPeerSet : public PeerSet dropRate = 100; } - if ((rand() % 100 + 1) <= dropRate) + if (((rand() % 100) + 1) <= dropRate) return; switch (type) @@ -752,9 +750,7 @@ public: auto t = findTask(hash, totalReplay); if (!t) { - if (taskExpect == TaskStatus::NotExist) - return true; - return false; + return taskExpect == TaskStatus::NotExist; } return asExpected(t, taskExpect, skiplistExpect, deltaExpects); @@ -771,9 +767,7 @@ public: auto t = findTask(hash, totalReplay); if (!t) { - if (taskExpect == TaskStatus::NotExist) - return true; - return false; + return taskExpect == TaskStatus::NotExist; } return asExpected(t, taskExpect, skiplistExpect, deltaExpects); @@ -1066,10 +1060,7 @@ struct LedgerReplayer_test : public beast::unit_test::suite auto http_resp = xrpl::makeResponse( true, http_request, addr, addr, uint256{1}, 1, {1, 0}, serverEnv.app()); auto const clientResult = peerFeatureEnabled(http_resp, FEATURE_LEDGER_REPLAY, client); - if (clientResult != expecting) - return false; - - return true; + return clientResult == expecting; }; BEAST_EXPECT(handshake(false, false, false)); @@ -1301,7 +1292,7 @@ struct LedgerReplayer_test : public beast::unit_test::suite int totalReplay = 5; NetworkOfTwo net( *this, - {totalReplay * 3 + 1}, + {(totalReplay * 3) + 1}, PeerSetBehavior::Good, InboundLedgersBehavior::Good, PeerFeature::LedgerReplayEnabled); @@ -1348,11 +1339,11 @@ struct LedgerReplayer_test : public beast::unit_test::suite TaskStatus::Completed, deltaStatuses)); // deltaStatuses no change BEAST_EXPECT(net.client.waitForLedgers(finalHash_moreEarly, totalReplay)); - BEAST_EXPECT(net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2)); + BEAST_EXPECT(net.client.countsAsExpected(4, 3, (2 * (totalReplay - 1)) + 2)); // cover net.client.replayer.replay(InboundLedger::Reason::GENERIC, finalHash, totalReplay * 3); - deltaStatuses = std::vector(totalReplay * 3 - 1, TaskStatus::Completed); + deltaStatuses = std::vector((totalReplay * 3) - 1, TaskStatus::Completed); BEAST_EXPECT(net.client.waitAndCheckStatus( finalHash, totalReplay * 3, @@ -1360,7 +1351,7 @@ struct LedgerReplayer_test : public beast::unit_test::suite TaskStatus::Completed, deltaStatuses)); // deltaStatuses changed BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3)); - BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1)); + BEAST_EXPECT(net.client.countsAsExpected(5, 3, (totalReplay * 3) - 1)); // sweep net.client.replayer.sweep(); @@ -1464,7 +1455,7 @@ struct LedgerReplayerLong_test : public beast::unit_test::suite int rounds = 4; NetworkOfTwo net( *this, - {totalReplay * rounds + 1}, + {(totalReplay * rounds) + 1}, PeerSetBehavior::Good, InboundLedgersBehavior::Good, PeerFeature::LedgerReplayEnabled); diff --git a/src/test/app/Loan_test.cpp b/src/test/app/Loan_test.cpp index 171e2eddb5..fa7befd39e 100644 --- a/src/test/app/Loan_test.cpp +++ b/src/test/app/Loan_test.cpp @@ -388,7 +388,7 @@ protected: if (auto vaultSle = env.le(keylet::vault(brokerSle->at(sfVaultID))); env.test.BEAST_EXPECT(vaultSle)) { - if ((flags & lsfLoanImpaired) && !(flags & lsfLoanDefault)) + if (((flags & lsfLoanImpaired) != 0u) && ((flags & lsfLoanDefault) == 0u)) { env.test.BEAST_EXPECT( vaultSle->at(sfLossUnrealized) == @@ -746,7 +746,7 @@ protected: return std::make_tuple(broker, loanKeylet, pseudoAcct); } - void + static void topUpBorrower( jtx::Env& env, BrokerInfo const& broker, @@ -1439,7 +1439,7 @@ protected: // Either the borrower or the lender can delete the loan. Alternate // between who does it across tests. static unsigned deleteCounter = 0; - auto const deleter = ++deleteCounter % 2 ? lender : borrower; + auto const deleter = ((++deleteCounter % 2) != 0u) ? lender : borrower; env(del(deleter, keylet.key)); env.close(); @@ -1468,7 +1468,7 @@ protected: } } - std::string + static std::string getCurrencyLabel(Asset const& asset) { if (asset.native()) @@ -2149,7 +2149,7 @@ protected: state.totalValue = 0; state.managementFeeOutstanding = 0; state.previousPaymentDate = - state.nextPaymentDate + state.paymentInterval * (numPayments - 1); + state.nextPaymentDate + (state.paymentInterval * (numPayments - 1)); state.nextPaymentDate = 0; verifyLoanStatus(state); @@ -2983,7 +2983,7 @@ protected: BEAST_EXPECT(sleMPT1 == nullptr); // Burn some XRP - env(noop(borrower), fee(XRP(acctReserve * 2 + incReserve * 2))); + env(noop(borrower), fee(XRP((acctReserve * 2) + (incReserve * 2)))); env.close(); // Cannot create loan, not enough reserve to create MPToken @@ -3007,7 +3007,7 @@ protected: BEAST_EXPECT(sleMPT2 != nullptr); }, {}, - CaseArgs{.initialXRP = acctReserve * 2 + incReserve * 8 + 1}); + CaseArgs{.initialXRP = (acctReserve * 2) + (incReserve * 8) + 1}); testCase( {}, @@ -3029,7 +3029,7 @@ protected: BEAST_EXPECT(sleLine1 == nullptr); // Burn some XRP - env(noop(borrower), fee(XRP(acctReserve * 2 + incReserve * 2))); + env(noop(borrower), fee(XRP((acctReserve * 2) + (incReserve * 2)))); env.close(); // Cannot create loan, not enough reserve to create trust line @@ -3052,7 +3052,7 @@ protected: auto const sleLine2 = env.le(trustline); BEAST_EXPECT(sleLine2 != nullptr); }, - CaseArgs{.initialXRP = acctReserve * 2 + incReserve * 8 + 1}); + CaseArgs{.initialXRP = (acctReserve * 2) + (incReserve * 8) + 1}); testCase( [&, this](Env& env, BrokerInfo const& broker, MPTTester& mptt) { @@ -3102,7 +3102,7 @@ protected: BEAST_EXPECT(sleMPT3 != nullptr); }, {}, - CaseArgs{.initialXRP = acctReserve * 2 + incReserve * 8 + 1}); + CaseArgs{.initialXRP = (acctReserve * 2) + (incReserve * 8) + 1}); testCase( {}, @@ -3152,7 +3152,7 @@ protected: auto const sleLine3 = env.le(trustline); BEAST_EXPECT(sleLine3 != nullptr); }, - CaseArgs{.initialXRP = acctReserve * 2 + incReserve * 8 + 1}); + CaseArgs{.initialXRP = (acctReserve * 2) + (incReserve * 8) + 1}); testCase( [&, this](Env& env, BrokerInfo const& broker, MPTTester& mptt) { diff --git a/src/test/app/Manifest_test.cpp b/src/test/app/Manifest_test.cpp index 609b7bdb89..7039f8df4f 100644 --- a/src/test/app/Manifest_test.cpp +++ b/src/test/app/Manifest_test.cpp @@ -87,7 +87,7 @@ public: } } - std::string + static std::string makeManifestString( PublicKey const& pk, SecretKey const& sk, @@ -190,7 +190,7 @@ public: return *deserializeManifest(std::string{}); // Silence compiler warning. } - Manifest + static Manifest clone(Manifest const& m) { Manifest m2(m.serialized, m.masterKey, m.signingKey, m.sequence, m.domain); diff --git a/src/test/app/NFTokenAuth_test.cpp b/src/test/app/NFTokenAuth_test.cpp index b973530f41..59faeb1eeb 100644 --- a/src/test/app/NFTokenAuth_test.cpp +++ b/src/test/app/NFTokenAuth_test.cpp @@ -6,7 +6,7 @@ namespace xrpl { class NFTokenAuth_test : public beast::unit_test::suite { - auto + static auto mintAndOfferNFT( test::jtx::Env& env, test::jtx::Account const& account, diff --git a/src/test/app/NFTokenBurn_test.cpp b/src/test/app/NFTokenBurn_test.cpp index 25f5a0f880..b91b245a7f 100644 --- a/src/test/app/NFTokenBurn_test.cpp +++ b/src/test/app/NFTokenBurn_test.cpp @@ -23,7 +23,7 @@ class NFTokenBurn_test : public beast::unit_test::suite // Helper function that returns new nft id for an account and create // specified number of sell offers - uint256 + static uint256 createNftAndOffers( test::jtx::Env& env, test::jtx::Account const& owner, @@ -59,7 +59,7 @@ class NFTokenBurn_test : public beast::unit_test::suite noisy = true, }; - void + static void printNFTPages(test::jtx::Env& env, Volume vol) { Json::Value jvParams; diff --git a/src/test/app/NFTokenDir_test.cpp b/src/test/app/NFTokenDir_test.cpp index 73698f1f89..70514f497f 100644 --- a/src/test/app/NFTokenDir_test.cpp +++ b/src/test/app/NFTokenDir_test.cpp @@ -20,7 +20,7 @@ class NFTokenDir_test : public beast::unit_test::suite noisy = true, }; - void + static void printNFTPages(test::jtx::Env& env, Volume vol) { Json::Value jvParams; diff --git a/src/test/app/NFToken_test.cpp b/src/test/app/NFToken_test.cpp index ba61830758..40fb78bb20 100644 --- a/src/test/app/NFToken_test.cpp +++ b/src/test/app/NFToken_test.cpp @@ -53,7 +53,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite } // Helper function returns the close time of the parent ledger. - std::uint32_t + static std::uint32_t lastClose(test::jtx::Env& env) { return env.current()->header().parentCloseTime.time_since_epoch().count(); @@ -243,7 +243,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite { env(token::burn(alice, token::getID(env, alice, 0, seq++))); env.close(); - checkAliceOwnerMintedBurned((33 - seq) ? 1 : 0, 33, seq, __LINE__); + checkAliceOwnerMintedBurned(((33 - seq) != 0u) ? 1 : 0, 33, seq, __LINE__); } // alice burns a non-existent NFT. @@ -352,7 +352,8 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite { env(token::burn(minter, token::getID(env, alice, 0, nftSeq++))); env.close(); - checkMintersOwnerMintedBurned(0, 66, nftSeq, (65 - seq) ? 1 : 0, 0, 0, __LINE__); + checkMintersOwnerMintedBurned( + 0, 66, nftSeq, ((65 - seq) != 0u) ? 1 : 0, 0, 0, __LINE__); } // minter has one more NFT to burn. Should take her owner count to @@ -1529,7 +1530,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite env.close(); // becky attempts to sell the nft for AUD. - TER const createOfferTER = xferFee ? TER(tecNO_LINE) : TER(tesSUCCESS); + TER const createOfferTER = (xferFee != 0u) ? TER(tecNO_LINE) : TER(tesSUCCESS); uint256 const beckyOfferIndex = keylet::nftoffer(becky, env.seq(becky)).key; env(token::createOffer(becky, nftNoAutoTrustID, gwAUD(100)), txflags(tfSellNFToken), @@ -4532,7 +4533,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite }; // There are no sell offers. - checkOffers("nft_sell_offers", 0, false, __LINE__); + checkOffers("nft_sell_offers", 0, 0, __LINE__); // A lambda that generates sell offers. STAmount sellPrice = XRP(0); diff --git a/src/test/app/NetworkID_test.cpp b/src/test/app/NetworkID_test.cpp index a37f8342e1..17245f7ee5 100644 --- a/src/test/app/NetworkID_test.cpp +++ b/src/test/app/NetworkID_test.cpp @@ -18,7 +18,7 @@ public: testNetworkID(); } - std::unique_ptr + static std::unique_ptr makeNetworkConfig(uint32_t networkID) { using namespace jtx; diff --git a/src/test/app/Offer_test.cpp b/src/test/app/Offer_test.cpp index 62edc844c7..35146f5234 100644 --- a/src/test/app/Offer_test.cpp +++ b/src/test/app/Offer_test.cpp @@ -11,13 +11,13 @@ namespace test { class OfferBaseUtil_test : public beast::unit_test::suite { - XRPAmount + static XRPAmount reserve(jtx::Env& env, std::uint32_t count) { return env.current()->fees().accountReserve(count); } - std::uint32_t + static std::uint32_t lastClose(jtx::Env& env) { return env.current()->header().parentCloseTime.time_since_epoch().count(); @@ -2253,7 +2253,7 @@ public: // The gateway optionally creates an offer that would be crossed. auto const book = t.bookAmount; - if (book) + if (book != 0) env(offer(gw, XRP(book), USD(book))); env.close(); std::uint32_t const gwOfferSeq = env.seq(gw) - 1; @@ -2285,7 +2285,7 @@ public: auto acctOffers = offersOnAccount(env, acct); BEAST_EXPECT(acctOffers.size() == t.offers); - if (!acctOffers.empty() && t.offers) + if (!acctOffers.empty() && (t.offers != 0)) { auto const& acctOffer = *(acctOffers.front()); @@ -2296,7 +2296,7 @@ public: if (t.preTrust == noPreTrust) { - if (t.balanceUsd.value().signum()) + if (t.balanceUsd.value().signum() != 0) { // Verify the correct contents of the trustline verifyDefaultTrustline(env, acct, t.balanceUsd); @@ -2773,7 +2773,7 @@ public: env.require(offers(acct, t.offers)); env.require(owners(acct, t.owners)); - if (t.offers) + if (t.offers != 0) { auto const acctOffers = offersOnAccount(env, acct); if (!acctOffers.empty()) @@ -3875,10 +3875,10 @@ public: // clang-format off TestData const tests[]{ // btcStart --------------------- actor[0] --------------------- -------------------- actor[1] ------------------- - {0, 0, 1, BTC(20), {{"ann", 0, drops(3900000'000000 - 4 * baseFee), BTC(20.0), USD(3000)}, {"abe", 0, drops(4100000'000000 - 3 * baseFee), BTC( 0), USD(750)}}}, // no BTC xfer fee - {0, 1, 0, BTC(20), {{"bev", 0, drops(4100000'000000 - 4 * baseFee), BTC( 7.5), USD(2000)}, {"bob", 0, drops(3900000'000000 - 3 * baseFee), BTC(10), USD( 0)}}}, // no USD xfer fee - {0, 0, 0, BTC(20), {{"cam", 0, drops(4000000'000000 - 5 * baseFee), BTC(20.0), USD(2000)} }}, // no xfer fee - {0, 1, 0, BTC( 5), {{"deb", 1, drops(4040000'000000 - 4 * baseFee), BTC( 0.0), USD(2000)}, {"dan", 1, drops(3960000'000000 - 3 * baseFee), BTC( 4), USD( 0)}}}, // no USD xfer fee + {0, 0, 1, BTC(20), {{"ann", 0, drops(3900000'000000 - (4 * baseFee)), BTC(20.0), USD(3000)}, {"abe", 0, drops(4100000'000000 - (3 * baseFee)), BTC( 0), USD(750)}}}, // no BTC xfer fee + {0, 1, 0, BTC(20), {{"bev", 0, drops(4100000'000000 - (4 * baseFee)), BTC( 7.5), USD(2000)}, {"bob", 0, drops(3900000'000000 - (3 * baseFee)), BTC(10), USD( 0)}}}, // no USD xfer fee + {0, 0, 0, BTC(20), {{"cam", 0, drops(4000000'000000 - (5 * baseFee)), BTC(20.0), USD(2000)} }}, // no xfer fee + {0, 1, 0, BTC( 5), {{"deb", 1, drops(4040000'000000 - (4 * baseFee)), BTC( 0.0), USD(2000)}, {"dan", 1, drops(3960000'000000 - (3 * baseFee)), BTC( 4), USD( 0)}}}, // no USD xfer fee }; // clang-format on @@ -4026,8 +4026,8 @@ public: // clang-format off TestData const tests[]{ // btcStart ------------------- actor[0] -------------------- ------------------- actor[1] -------------------- - {0, 0, 1, BTC(5), {{"gay", 1, drops(3950000'000000 - 4 * baseFee), BTC(5), USD(2500)}, {"gar", 1, drops(4050000'000000 - 3 * baseFee), BTC(0), USD(1375)}}}, // no BTC xfer fee - {0, 0, 0, BTC(5), {{"hye", 2, drops(4000000'000000 - 5 * baseFee), BTC(5), USD(2000)} }} // no xfer fee + {0, 0, 1, BTC(5), {{"gay", 1, drops(3950000'000000 - (4 * baseFee)), BTC(5), USD(2500)}, {"gar", 1, drops(4050000'000000 - (3 * baseFee)), BTC(0), USD(1375)}}}, // no BTC xfer fee + {0, 0, 0, BTC(5), {{"hye", 2, drops(4000000'000000 - (5 * baseFee)), BTC(5), USD(2000)} }} // no xfer fee }; // clang-format on diff --git a/src/test/app/OversizeMeta_test.cpp b/src/test/app/OversizeMeta_test.cpp index 3831e45a78..d6305bedb6 100644 --- a/src/test/app/OversizeMeta_test.cpp +++ b/src/test/app/OversizeMeta_test.cpp @@ -9,7 +9,7 @@ namespace test { class PlumpBook_test : public beast::unit_test::suite { public: - void + static void createOffers(jtx::Env& env, jtx::IOU const& iou, std::size_t n) { using namespace jtx; @@ -64,7 +64,7 @@ BEAST_DEFINE_TESTSUITE(ThinBook, app, xrpl); class OversizeMeta_test : public beast::unit_test::suite { public: - void + static void createOffers(jtx::Env& env, jtx::IOU const& iou, std::size_t n) { using namespace jtx; @@ -130,7 +130,7 @@ public: return lo; } - void + static void createOffers(jtx::Env& env, jtx::IOU const& iou, std::size_t n) { using namespace jtx; diff --git a/src/test/app/Path_test.cpp b/src/test/app/Path_test.cpp index 9315370809..53da92ce1c 100644 --- a/src/test/app/Path_test.cpp +++ b/src/test/app/Path_test.cpp @@ -39,7 +39,7 @@ rpf(jtx::Account const& src, jtx::Account const& dst, std::uint32_t num_src) { auto& sc = (jv[jss::source_currencies] = Json::arrayValue); Json::Value j = Json::objectValue; - while (num_src--) + while ((num_src--) != 0u) { j[jss::currency] = std::to_string(num_src + 100); sc.append(j); diff --git a/src/test/app/PayChan_test.cpp b/src/test/app/PayChan_test.cpp index 5322349797..1150ae4d86 100644 --- a/src/test/app/PayChan_test.cpp +++ b/src/test/app/PayChan_test.cpp @@ -1096,7 +1096,7 @@ struct PayChan_test : public beast::unit_test::suite { auto leftToFind = bobsB58; auto const numFull = bobs.size() / limit; - auto const numNonFull = bobs.size() % limit ? 1 : 0; + auto const numNonFull = ((bobs.size() % limit) != 0u) ? 1 : 0; Json::Value marker = Json::nullValue; @@ -1122,7 +1122,7 @@ struct PayChan_test : public beast::unit_test::suite testIt(expectMarker, limit); } - if (numNonFull) + if (numNonFull != 0) { testIt(false, bobs.size() % limit); } diff --git a/src/test/app/PayStrand_test.cpp b/src/test/app/PayStrand_test.cpp index 70444637bf..d2e79a58f8 100644 --- a/src/test/app/PayStrand_test.cpp +++ b/src/test/app/PayStrand_test.cpp @@ -176,7 +176,7 @@ class ElementComboIter bool has(SB s) const { - return state_ & (1 << safe_cast(s)); + return (state_ & (1 << safe_cast(s))) != 0; } bool @@ -212,7 +212,7 @@ public: valid() const { return (allowCompound_ || !(has(SB::acc) && hasAny({SB::cur, SB::iss}))) && - (!hasAny({SB::prevAcc, SB::prevCur, SB::prevIss}) || prev_) && + (!hasAny({SB::prevAcc, SB::prevCur, SB::prevIss}) || (prev_ != nullptr)) && (!hasAny({SB::rootAcc, SB::sameAccIss, SB::existingAcc, SB::prevAcc}) || has(SB::acc)) && (!hasAny({SB::rootIss, SB::sameAccIss, SB::existingIss, SB::prevIss}) || diff --git a/src/test/app/PermissionedDEX_test.cpp b/src/test/app/PermissionedDEX_test.cpp index 2817bc0502..7b622a1256 100644 --- a/src/test/app/PermissionedDEX_test.cpp +++ b/src/test/app/PermissionedDEX_test.cpp @@ -34,13 +34,13 @@ using namespace jtx; class PermissionedDEX_test : public beast::unit_test::suite { - [[nodiscard]] bool + [[nodiscard]] static bool offerExists(Env const& env, Account const& account, std::uint32_t offerSeq) { return static_cast(env.le(keylet::offer(account.id(), offerSeq))); } - [[nodiscard]] bool + [[nodiscard]] static bool checkOffer( Env const& env, Account const& account, @@ -120,13 +120,13 @@ class PermissionedDEX_test : public beast::unit_test::suite return true; } - uint256 + static uint256 getBookDirKey(Book const& book, STAmount const& takerPays, STAmount const& takerGets) { return keylet::quality(keylet::book(book), getRate(takerGets, takerPays)).key; } - std::optional + static std::optional getDefaultOfferDirKey(Env const& env, Account const& account, std::uint32_t offerSeq) { if (auto const sle = env.le(keylet::offer(account.id(), offerSeq))) @@ -135,7 +135,7 @@ class PermissionedDEX_test : public beast::unit_test::suite return {}; } - [[nodiscard]] bool + [[nodiscard]] static bool checkDirectorySize(Env const& env, uint256 directory, std::uint32_t dirSize) { std::optional pageIndex{0}; @@ -151,7 +151,7 @@ class PermissionedDEX_test : public beast::unit_test::suite pageIndex = (*page)[~sfIndexNext]; dirCnt += (*page)[sfIndexes].size(); - } while (pageIndex.value_or(0)); + } while (pageIndex.value_or(0) != 0u); return dirCnt == dirSize; } diff --git a/src/test/app/PseudoTx_test.cpp b/src/test/app/PseudoTx_test.cpp index aa16df8e9c..79346a3fe1 100644 --- a/src/test/app/PseudoTx_test.cpp +++ b/src/test/app/PseudoTx_test.cpp @@ -11,7 +11,7 @@ namespace test { struct PseudoTx_test : public beast::unit_test::suite { - std::vector + static std::vector getPseudoTxs(Rules const& rules, std::uint32_t seq) { std::vector res; @@ -43,7 +43,7 @@ struct PseudoTx_test : public beast::unit_test::suite return res; } - std::vector + static std::vector getRealTxs() { std::vector res; diff --git a/src/test/app/RCLValidations_test.cpp b/src/test/app/RCLValidations_test.cpp index a7941ea64f..63f295e3b7 100644 --- a/src/test/app/RCLValidations_test.cpp +++ b/src/test/app/RCLValidations_test.cpp @@ -59,7 +59,7 @@ class RCLValidations_test : public beast::unit_test::suite auto prev = std::make_shared( create_genesis, config, std::vector{}, env.app().getNodeFamily()); history.push_back(prev); - for (auto i = 0; i < (2 * maxAncestors + 1); ++i) + for (auto i = 0; i < ((2 * maxAncestors) + 1); ++i) { auto next = std::make_shared(*prev, env.app().timeKeeper().closeTime()); next->updateSkipList(); diff --git a/src/test/app/ReducedOffer_test.cpp b/src/test/app/ReducedOffer_test.cpp index d0cf1b5324..46193a1544 100644 --- a/src/test/app/ReducedOffer_test.cpp +++ b/src/test/app/ReducedOffer_test.cpp @@ -491,7 +491,7 @@ public: } } - Amounts + static Amounts jsonOfferToAmounts(Json::Value const& json) { STAmount const in = amountFromJson(sfTakerPays, json[sfTakerPays.jsonName]); diff --git a/src/test/app/SHAMapStore_test.cpp b/src/test/app/SHAMapStore_test.cpp index d7d3e281f4..e5471ab74e 100644 --- a/src/test/app/SHAMapStore_test.cpp +++ b/src/test/app/SHAMapStore_test.cpp @@ -34,7 +34,7 @@ class SHAMapStore_test : public beast::unit_test::suite return cfg; } - bool + static bool goodLedger(jtx::Env& env, Json::Value const& json, std::string ledgerID, bool checkDB = false) { auto good = json.isMember(jss::result) && !RPC::contains_error(json[jss::result]) && @@ -73,7 +73,7 @@ class SHAMapStore_test : public beast::unit_test::suite outTxHash == ledger[jss::transaction_hash].asString(); } - bool + static bool bad(Json::Value const& json, error_code_i error = rpcLGR_NOT_FOUND) { return json.isMember(jss::result) && RPC::contains_error(json[jss::result]) && @@ -346,9 +346,9 @@ public: BEAST_EXPECT(lastRotated == store.getLastRotated()); // This does not kick off a cleanup - canDelete = env.rpc("can_delete", std::to_string(ledgerSeq + deleteInterval / 2)); + canDelete = env.rpc("can_delete", std::to_string(ledgerSeq + (deleteInterval / 2))); BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result])); - BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq + deleteInterval / 2); + BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq + (deleteInterval / 2)); store.rendezvous(); diff --git a/src/test/app/TrustSet_test.cpp b/src/test/app/TrustSet_test.cpp index 51828fa544..d359ba1f26 100644 --- a/src/test/app/TrustSet_test.cpp +++ b/src/test/app/TrustSet_test.cpp @@ -260,7 +260,7 @@ public: env.close(); } - Json::Value + static Json::Value trust_explicit_amt(jtx::Account const& a, STAmount const& amt) { Json::Value jv; @@ -287,7 +287,7 @@ public: for (std::uint64_t badFlag = 1u; badFlag <= std::numeric_limits::max(); badFlag *= 2) { - if (badFlag & tfTrustSetMask) + if ((badFlag & tfTrustSetMask) != 0u) { env(trust(alice, gw["USD"](100), static_cast(badFlag)), ter(temINVALID_FLAG)); diff --git a/src/test/app/TxQ_test.cpp b/src/test/app/TxQ_test.cpp index 59db7e0d5d..a758167319 100644 --- a/src/test/app/TxQ_test.cpp +++ b/src/test/app/TxQ_test.cpp @@ -24,7 +24,7 @@ class TxQPosNegFlows_test : public beast::unit_test::suite static constexpr FeeLevel64 baseFeeLevel{256}; static constexpr FeeLevel64 minEscalationFeeLevel = baseFeeLevel * 500; - void + static void fillQueue(jtx::Env& env, jtx::Account const& account) { auto metrics = env.app().getTxQ().getMetrics(*env.current()); @@ -32,7 +32,7 @@ class TxQPosNegFlows_test : public beast::unit_test::suite env(noop(account)); } - auto + static auto openLedgerCost(jtx::Env& env) { using namespace jtx; @@ -52,7 +52,7 @@ class TxQPosNegFlows_test : public beast::unit_test::suite // Get a fee level of a transaction made by an account // This fee level is used to ensure we can place transaction into TxQ - auto + static auto txFeeLevelByAccount(jtx::Env& env, jtx::Account const& account) { using namespace jtx; @@ -65,7 +65,7 @@ class TxQPosNegFlows_test : public beast::unit_test::suite // Calculating expected median fee level based on known fee levels of median // transaction levels. - auto + static auto calcMedFeeLevel(FeeLevel64 const feeLevel1, FeeLevel64 const feeLevel2) { FeeLevel64 const expectedMedFeeLevel = (feeLevel1 + feeLevel2 + FeeLevel64{1}) / 2; @@ -73,7 +73,7 @@ class TxQPosNegFlows_test : public beast::unit_test::suite return std::max(expectedMedFeeLevel, minEscalationFeeLevel).fee(); } - auto + static auto calcMedFeeLevel(FeeLevel64 const feeLevel) { return calcMedFeeLevel(feeLevel, feeLevel); @@ -551,16 +551,16 @@ public: // The lowest fee ticket is baseFee * 2.1, trying to replace it env(noop(alice), ticket::use(tkt1 + 18), - fee(baseFee * 2.1 * 1.25 - 1), + fee((baseFee * 2.1 * 1.25) - 1), ter(telCAN_NOT_QUEUE_FEE)); - env(noop(alice), ticket::use(tkt1 + 18), fee(baseFee * 2.1 * 1.25 + 1), queued); + env(noop(alice), ticket::use(tkt1 + 18), fee((baseFee * 2.1 * 1.25) + 1), queued); // New lowest fee ticket is baseFee * 2.2 env(noop(alice), ticket::use(tkt250 - 4), - fee(baseFee * 2.2 * 1.25 - 1), + fee((baseFee * 2.2 * 1.25) - 1), ter(telCAN_NOT_QUEUE_FEE)); - env(noop(alice), ticket::use(tkt250 - 4), fee(baseFee * 2.2 * 1.25 + 1), queued); + env(noop(alice), ticket::use(tkt250 - 4), fee((baseFee * 2.2 * 1.25) + 1), queued); env.close(); env.require(owners(alice, 227), tickets(alice, 227)); @@ -858,7 +858,7 @@ public: ++seqCarol; } // clang-format off - checkMetrics(*this, env, 6, 6, 4, 3, baseFeeLevel.fee() * aliceFeeMultiplier + 1); + checkMetrics(*this, env, 6, 6, 4, 3, (baseFeeLevel.fee() * aliceFeeMultiplier) + 1); // clang-format on // Carol submits high enough to beat Bob's average fee which kicks @@ -2632,7 +2632,7 @@ public: // Start by procuring tickets for alice to use to keep her queue full // without affecting the sequence gap that will appear later. - env(ticket::create(alice, 11), seq(aliceSeq + 0), fee(baseFee * 20 + 1), ter(terQUEUED)); + env(ticket::create(alice, 11), seq(aliceSeq + 0), fee((baseFee * 20) + 1), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 11), last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 12), last_ledger_seq(11), ter(terQUEUED)); env(noop(alice), seq(aliceSeq + 13), last_ledger_seq(11), ter(terQUEUED)); @@ -4083,7 +4083,7 @@ public: // Use fees to guarantee order int txFee{static_cast(baseFee * 9)}; auto prepareFee = [&](uint64_t multiplier) { - return fee(txFee - multiplier * baseFee / 10); + return fee(txFee - (multiplier * baseFee / 10)); }; uint64_t multiplier = 0; diff --git a/src/test/app/ValidatorList_test.cpp b/src/test/app/ValidatorList_test.cpp index 32e899ad95..c4229514a1 100644 --- a/src/test/app/ValidatorList_test.cpp +++ b/src/test/app/ValidatorList_test.cpp @@ -98,7 +98,7 @@ private: masterPublic, secret, signingKeys.first, signingKeys.second, 1))}; } - std::string + static std::string makeList( std::vector const& validators, std::size_t sequence, @@ -122,7 +122,7 @@ private: return base64_encode(data); } - std::string + static std::string signList(std::string const& blob, std::pair const& keys) { auto const data = base64_decode(blob); @@ -379,7 +379,7 @@ private: BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgPublishers)); for (auto const& key : keys) BEAST_EXPECT(trustedKeys->trustedPublisher(key)); - BEAST_EXPECT(trustedKeys->getListThreshold() == keys.size() / 2 + 1); + BEAST_EXPECT(trustedKeys->getListThreshold() == (keys.size() / 2) + 1); } { ManifestCache manifests; @@ -561,10 +561,10 @@ private: auto const manifest1 = base64_encode(makeManifestString( publisherPublic, publisherSecret, pubSigningKeys1.first, pubSigningKeys1.second, 1)); - std::vector cfgKeys1({strHex(publisherPublic)}); + std::vector cfgPublisherKeys({strHex(publisherPublic)}); std::vector emptyCfgKeys; - BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgKeys1)); + BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgPublisherKeys)); std::map> const lists = []() { auto constexpr listSize = 20; @@ -907,10 +907,10 @@ private: auto const manifest = base64_encode(makeManifestString( publisherPublic, publisherSecret, pubSigningKeys1.first, pubSigningKeys1.second, 1)); - std::vector cfgKeys1({strHex(publisherPublic)}); + std::vector cfgPublisherKeys({strHex(publisherPublic)}); std::vector emptyCfgKeys; - BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgKeys1)); + BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgPublisherKeys)); std::vector const list = []() { auto constexpr listSize = 20; @@ -1324,9 +1324,9 @@ private: pubSigningKeys.second, 1)); - std::vector cfgKeys({strHex(publisherKeys.first)}); + std::vector cfgPublisherKeys({strHex(publisherKeys.first)}); - BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgKeys)); + BEAST_EXPECT(trustedKeys->load({}, emptyCfgKeys, cfgPublisherKeys)); std::vector list({randomValidator(), randomValidator()}); hash_set activeValidators( diff --git a/src/test/app/ValidatorSite_test.cpp b/src/test/app/ValidatorSite_test.cpp index c47c93c426..f1e3b57b1e 100644 --- a/src/test/app/ValidatorSite_test.cpp +++ b/src/test/app/ValidatorSite_test.cpp @@ -240,7 +240,7 @@ private: sink.messages().str()); } - if (u.cfg.expectedRefreshMin) + if (u.cfg.expectedRefreshMin != 0) { BEAST_EXPECTS( myStatus[jss::refresh_interval_min].asInt() == u.cfg.expectedRefreshMin, diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index 27a8d3b2e0..fa935eba6e 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -1898,7 +1898,7 @@ class Vault_test : public beast::unit_test::suite env.close(); } }, - {.requireAuth = false, .initialXRP = acctReserve + incReserve * 4 + 1}); + {.requireAuth = false, .initialXRP = acctReserve + (incReserve * 4) + 1}); testCase([this]( Env& env, @@ -2745,7 +2745,7 @@ class Vault_test : public beast::unit_test::suite env(vault.withdraw( {.depositor = owner, .id = keylet.key, - .amount = asset(Number(1000 + 37 * 5, -1))})); + .amount = asset(Number(1000 + (37 * 5), -1))})); { BEAST_EXPECT(env.balance(owner, asset) == startingOwnerBalance.value()); @@ -2808,7 +2808,7 @@ class Vault_test : public beast::unit_test::suite env(tx); env.close(); }, - CaseArgs{.initialXRP = acctReserve + incReserve * 4 + 1}); + CaseArgs{.initialXRP = acctReserve + (incReserve * 4) + 1}); testCase( [&, this]( @@ -2843,7 +2843,7 @@ class Vault_test : public beast::unit_test::suite env(tx); env.close(); }, - CaseArgs{.initialXRP = acctReserve + incReserve * 4 + 1}); + CaseArgs{.initialXRP = acctReserve + (incReserve * 4) + 1}); testCase([&, this]( Env& env, diff --git a/src/test/app/XChain_test.cpp b/src/test/app/XChain_test.cpp index b90ff49a84..72f2597883 100644 --- a/src/test/app/XChain_test.cpp +++ b/src/test/app/XChain_test.cpp @@ -3856,7 +3856,7 @@ private: auto& c = counters[bridge]; auto& create_claims = claims.create_claims[c.claim_count]; auto num_attns = create_claims.size(); - if (num_attns) + if (num_attns != 0u) { c.num_create_attn_sent += sendCreateAttestations(i, bridge, create_claims); diff --git a/src/test/basics/Buffer_test.cpp b/src/test/basics/Buffer_test.cpp index f5f626133f..a329e527ba 100644 --- a/src/test/basics/Buffer_test.cpp +++ b/src/test/basics/Buffer_test.cpp @@ -9,8 +9,8 @@ namespace test { struct Buffer_test : beast::unit_test::suite { - bool - sane(Buffer const& b) const + static bool + sane(Buffer const& b) { if (b.empty()) return b.data() == nullptr; diff --git a/src/test/basics/Number_test.cpp b/src/test/basics/Number_test.cpp index fb434a0182..4676884660 100644 --- a/src/test/basics/Number_test.cpp +++ b/src/test/basics/Number_test.cpp @@ -279,7 +279,7 @@ public: {Number{Number::maxRep}, Number{6, -1}, Number{Number::maxRep - 1}}, {Number{false, Number::maxRep + 1, 0, Number::normalized{}}, Number{1, 0}, - Number{Number::maxRep / 10 + 1, 1}}, + Number{(Number::maxRep / 10) + 1, 1}}, {Number{false, Number::maxRep + 1, 0, Number::normalized{}}, Number{3, 0}, Number{Number::maxRep}}, @@ -456,7 +456,7 @@ public: // 99'999'999'999'999'999'800'000'000'000'000'000'100 {Number{false, maxMantissa, 0, Number::normalized{}}, Number{false, maxMantissa, 0, Number::normalized{}}, - Number{false, maxMantissa / 10 - 1, 20, Number::normalized{}}}, + Number{false, (maxMantissa / 10) - 1, 20, Number::normalized{}}}, // Maximum int64 range // 85'070'591'730'234'615'847'396'907'784'232'501'249 {Number{Number::maxRep, 0}, @@ -523,7 +523,7 @@ public: // 99'999'999'999'999'999'800'000'000'000'000'000'100 {Number{false, maxMantissa, 0, Number::normalized{}}, Number{false, maxMantissa, 0, Number::normalized{}}, - Number{false, maxMantissa / 10 - 1, 20, Number::normalized{}}}, + Number{false, (maxMantissa / 10) - 1, 20, Number::normalized{}}}, // Maximum int64 range // 85'070'591'730'234'615'847'396'907'784'232'501'249 {Number{Number::maxRep, 0}, @@ -1238,10 +1238,10 @@ public: auto const maxMantissa = Number::maxMantissa(); BEAST_EXPECT(maxMantissa == 9'999'999'999'999'999); test( - Number{false, maxMantissa * 1000 + 999, -3, Number::normalized()}, + Number{false, (maxMantissa * 1000) + 999, -3, Number::normalized()}, "9999999999999999"); test( - Number{true, maxMantissa * 1000 + 999, -3, Number::normalized()}, + Number{true, (maxMantissa * 1000) + 999, -3, Number::normalized()}, "-9999999999999999"); test(Number{std::numeric_limits::max(), -3}, "9223372036854775"); @@ -1537,7 +1537,7 @@ public: // 99'999'999'999'999'999'800'000'000'000'000'000'100 - also 38 // digits BEAST_EXPECT( - (power(max, 2) == Number{false, maxMantissa / 10 - 1, 20, Number::normalized{}})); + (power(max, 2) == Number{false, (maxMantissa / 10) - 1, 20, Number::normalized{}})); } } diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index ce0109c53d..1647ce241e 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -63,21 +63,21 @@ class PerfLog_test : public beast::unit_test::suite stopSignaled = true; } - path - logDir() const + static path + logDir() { using namespace boost::filesystem; return temp_directory_path() / "perf_log_test_dir"; } - path - logFile() const + static path + logFile() { return logDir() / "perf_log.txt"; } - std::chrono::milliseconds - logInterval() const + static std::chrono::milliseconds + logInterval() { return std::chrono::milliseconds{10}; } @@ -96,8 +96,8 @@ class PerfLog_test : public beast::unit_test::suite // Block until the log file has grown in size, indicating that the // PerfLog has written new values to the file and _should_ have the // latest update. - void - wait() const + static void + wait() { using namespace boost::filesystem; diff --git a/src/test/basics/base58_test.cpp b/src/test/basics/base58_test.cpp index ca62ac02ef..52d06b324d 100644 --- a/src/test/basics/base58_test.cpp +++ b/src/test/basics/base58_test.cpp @@ -162,7 +162,7 @@ class base58_test : public beast::unit_test::suite for (int i = 0; i < iters; ++i) { std::uint64_t const d = dist(eng); - if (!d) + if (d == 0u) continue; auto bigInt = multiprecision_utils::randomBigInt(); auto const boostBigInt = multiprecision_utils::toBoostMP( diff --git a/src/test/beast/aged_associative_container_test.cpp b/src/test/beast/aged_associative_container_test.cpp index 690f03cd49..22b677a7e5 100644 --- a/src/test/beast/aged_associative_container_test.cpp +++ b/src/test/beast/aged_associative_container_test.cpp @@ -523,7 +523,7 @@ public: testArrayCreate(); template - typename std::enable_if::type + typename std::enable_if::type testArrayCreate() { } diff --git a/src/test/consensus/Consensus_test.cpp b/src/test/consensus/Consensus_test.cpp index a096b82365..3550717a4d 100644 --- a/src/test/consensus/Consensus_test.cpp +++ b/src/test/consensus/Consensus_test.cpp @@ -1295,10 +1295,10 @@ public: for (int i = 0; i < 1; ++i) { - BEAST_EXPECT(!proposingTrue.updateVote(250 + 10 * i, true, p)); - BEAST_EXPECT(!proposingFalse.updateVote(250 + 10 * i, true, p)); - BEAST_EXPECT(!followingTrue.updateVote(250 + 10 * i, false, p)); - BEAST_EXPECT(!followingFalse.updateVote(250 + 10 * i, false, p)); + BEAST_EXPECT(!proposingTrue.updateVote(250 + (10 * i), true, p)); + BEAST_EXPECT(!proposingFalse.updateVote(250 + (10 * i), true, p)); + BEAST_EXPECT(!followingTrue.updateVote(250 + (10 * i), false, p)); + BEAST_EXPECT(!followingFalse.updateVote(250 + (10 * i), false, p)); BEAST_EXPECT(proposingTrue.getOurVote() == true); BEAST_EXPECT(proposingFalse.getOurVote() == false); @@ -1333,10 +1333,10 @@ public: } for (int i = 1; i < 3; ++i) { - BEAST_EXPECT(!proposingTrue.updateVote(250 + 10 * i, true, p)); - BEAST_EXPECT(!proposingFalse.updateVote(250 + 10 * i, true, p)); - BEAST_EXPECT(!followingTrue.updateVote(250 + 10 * i, false, p)); - BEAST_EXPECT(!followingFalse.updateVote(250 + 10 * i, false, p)); + BEAST_EXPECT(!proposingTrue.updateVote(250 + (10 * i), true, p)); + BEAST_EXPECT(!proposingFalse.updateVote(250 + (10 * i), true, p)); + BEAST_EXPECT(!followingTrue.updateVote(250 + (10 * i), false, p)); + BEAST_EXPECT(!followingFalse.updateVote(250 + (10 * i), false, p)); BEAST_EXPECT(proposingTrue.getOurVote() == true); BEAST_EXPECT(proposingFalse.getOurVote() == false); @@ -1369,10 +1369,10 @@ public: } for (int i = 3; i < 5; ++i) { - BEAST_EXPECT(!proposingTrue.updateVote(250 + 10 * i, true, p)); - BEAST_EXPECT(!proposingFalse.updateVote(250 + 10 * i, true, p)); - BEAST_EXPECT(!followingTrue.updateVote(250 + 10 * i, false, p)); - BEAST_EXPECT(!followingFalse.updateVote(250 + 10 * i, false, p)); + BEAST_EXPECT(!proposingTrue.updateVote(250 + (10 * i), true, p)); + BEAST_EXPECT(!proposingFalse.updateVote(250 + (10 * i), true, p)); + BEAST_EXPECT(!followingTrue.updateVote(250 + (10 * i), false, p)); + BEAST_EXPECT(!followingFalse.updateVote(250 + (10 * i), false, p)); BEAST_EXPECT(proposingTrue.getOurVote() == true); BEAST_EXPECT(proposingFalse.getOurVote() == false); diff --git a/src/test/consensus/NegativeUNL_test.cpp b/src/test/consensus/NegativeUNL_test.cpp index 46c6936809..019d8ee545 100644 --- a/src/test/consensus/NegativeUNL_test.cpp +++ b/src/test/consensus/NegativeUNL_test.cpp @@ -782,7 +782,7 @@ class NegativeUNLVoteInternal_test : public beast::unit_test::suite history.walkHistoryAndAddValidations( [&](std::shared_ptr const& l, std::size_t idx) -> bool { // skip half my validations. - return !(history.UNLNodeIDs[idx] == myId && l->seq() % 2 == 0); + return history.UNLNodeIDs[idx] != myId || l->seq() % 2 != 0; }); NegativeUNLVote vote(myId, history.env.journal); BEAST_EXPECT(!vote.buildScoreTable( @@ -890,7 +890,7 @@ class NegativeUNLVoteInternal_test : public beast::unit_test::suite * @param numReEnable number of ReEnable candidates expected * @return true if the number of candidates meets expectation */ - bool + static bool checkCandidateSizes( NegativeUNLVote& vote, hash_set const& unl, diff --git a/src/test/core/ClosureCounter_test.cpp b/src/test/core/ClosureCounter_test.cpp index fe3f0a219f..736b833d76 100644 --- a/src/test/core/ClosureCounter_test.cpp +++ b/src/test/core/ClosureCounter_test.cpp @@ -299,7 +299,7 @@ class ClosureCounter_test : public beast::unit_test::suite BEAST_EXPECT(voidCounter.count() == 0); // Wait for the thread to exit. - while (threadExited == false) + while (!threadExited) ; localThread.join(); } diff --git a/src/test/core/Config_test.cpp b/src/test/core/Config_test.cpp index e9f7354482..edcb67b767 100644 --- a/src/test/core/Config_test.cpp +++ b/src/test/core/Config_test.cpp @@ -358,8 +358,8 @@ port_wss_admin "/Users/dummy/xrpld/config/log/debug.log"); // Restore the environment variables. - h ? setenv("HOME", h, 1) : unsetenv("HOME"); - x ? setenv("XDG_CONFIG_HOME", x, 1) : unsetenv("XDG_CONFIG_HOME"); + (h != nullptr) ? setenv("HOME", h, 1) : unsetenv("HOME"); + (x != nullptr) ? setenv("XDG_CONFIG_HOME", x, 1) : unsetenv("XDG_CONFIG_HOME"); } // The XDG config directory is not set: the config file must be in a @@ -394,8 +394,8 @@ port_wss_admin "/Users/dummy/xrpld/config/log/debug.log"); // Restore the environment variables. - h ? setenv("HOME", h, 1) : unsetenv("HOME"); - if (x) + (h != nullptr) ? setenv("HOME", h, 1) : unsetenv("HOME"); + if (x != nullptr) setenv("XDG_CONFIG_HOME", x, 1); } } diff --git a/src/test/core/JobQueue_test.cpp b/src/test/core/JobQueue_test.cpp index bf6a5590e6..13142c299f 100644 --- a/src/test/core/JobQueue_test.cpp +++ b/src/test/core/JobQueue_test.cpp @@ -23,7 +23,7 @@ class JobQueue_test : public beast::unit_test::suite jQueue.addJob(jtCLIENT, "JobAddTest1", [&jobRan]() { jobRan = true; }) == true); // Wait for the Job to run. - while (jobRan == false) + while (!jobRan) ; } { diff --git a/src/test/csf/Sim.h b/src/test/csf/Sim.h index 3525258c59..e5f64cae1f 100644 --- a/src/test/csf/Sim.h +++ b/src/test/csf/Sim.h @@ -129,8 +129,8 @@ public: Nodes in the group are synchronized if they share the same last fully validated and last generated ledger. */ - bool - synchronized(PeerGroup const& g) const; + static bool + synchronized(PeerGroup const& g); /** Check whether all peers in the network are synchronized */ diff --git a/src/test/csf/impl/Sim.cpp b/src/test/csf/impl/Sim.cpp index 4fbee56f0f..a775dd30ff 100644 --- a/src/test/csf/impl/Sim.cpp +++ b/src/test/csf/impl/Sim.cpp @@ -33,7 +33,7 @@ Sim::synchronized() const } bool -Sim::synchronized(PeerGroup const& g) const +Sim::synchronized(PeerGroup const& g) { if (g.size() < 1) return true; diff --git a/src/test/csf/impl/ledgers.cpp b/src/test/csf/impl/ledgers.cpp index 33e9b123c5..2c5bf07880 100644 --- a/src/test/csf/impl/ledgers.cpp +++ b/src/test/csf/impl/ledgers.cpp @@ -123,7 +123,7 @@ LedgerOracle::lookup(Ledger::ID const& id) const } std::size_t -LedgerOracle::branches(std::set const& ledgers) const +LedgerOracle::branches(std::set const& ledgers) { // Tips always maintains the Ledgers with largest sequence number // along all known chains. diff --git a/src/test/csf/ledgers.h b/src/test/csf/ledgers.h index 9da1c2182a..6e50f3584b 100644 --- a/src/test/csf/ledgers.h +++ b/src/test/csf/ledgers.h @@ -278,8 +278,8 @@ public: O \--> B */ - std::size_t - branches(std::set const& ledgers) const; + static std::size_t + branches(std::set const& ledgers); }; /** Helper for writing unit tests with controlled ledger histories. diff --git a/src/test/jtx/AMMTest.h b/src/test/jtx/AMMTest.h index 78e26b9e40..dd18733ffd 100644 --- a/src/test/jtx/AMMTest.h +++ b/src/test/jtx/AMMTest.h @@ -96,11 +96,11 @@ protected: class AMMTest : public jtx::AMMTestBase { protected: - XRPAmount - reserve(jtx::Env& env, std::uint32_t count) const; + static XRPAmount + reserve(jtx::Env& env, std::uint32_t count); - XRPAmount - ammCrtFee(jtx::Env& env) const; + static XRPAmount + ammCrtFee(jtx::Env& env); /* Path_test */ /************************************************/ diff --git a/src/test/jtx/Env.h b/src/test/jtx/Env.h index 2ac0ca7435..a103d42ca3 100644 --- a/src/test/jtx/Env.h +++ b/src/test/jtx/Env.h @@ -510,6 +510,7 @@ public: */ // VFALCO NOTE This should return a unit-less amount PrettyAmount + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) balance(Account const& account, Asset const& asset) const; PrettyAmount diff --git a/src/test/jtx/Env_test.cpp b/src/test/jtx/Env_test.cpp index bd40ac9a81..51abac8101 100644 --- a/src/test/jtx/Env_test.cpp +++ b/src/test/jtx/Env_test.cpp @@ -28,7 +28,7 @@ public: } // Declarations in Account.h - void + static void testAccount() { using namespace jtx; diff --git a/src/test/jtx/impl/AMM.cpp b/src/test/jtx/impl/AMM.cpp index 6b2042efda..ccad604070 100644 --- a/src/test/jtx/impl/AMM.cpp +++ b/src/test/jtx/impl/AMM.cpp @@ -443,7 +443,7 @@ AMM::deposit( // If including asset1In and asset2In or tokens as // deposit min amounts then must set the flags // explicitly instead of relying on this logic. - if (!(jvFlags & tfDepositSubTx)) + if ((jvFlags & tfDepositSubTx) == 0u) { if (tokens && !asset1In) { @@ -573,7 +573,7 @@ AMM::withdraw( std::uint32_t jvFlags = 0; if (flags) jvFlags = *flags; - if (!(jvFlags & tfWithdrawSubTx)) + if ((jvFlags & tfWithdrawSubTx) == 0u) { if (tokens && !asset1Out) { diff --git a/src/test/jtx/impl/AMMTest.cpp b/src/test/jtx/impl/AMMTest.cpp index ab8c1578a3..6b8807076a 100644 --- a/src/test/jtx/impl/AMMTest.cpp +++ b/src/test/jtx/impl/AMMTest.cpp @@ -149,13 +149,13 @@ AMMTestBase::testAMM(std::function const& cb, TestAM } XRPAmount -AMMTest::reserve(jtx::Env& env, std::uint32_t count) const +AMMTest::reserve(jtx::Env& env, std::uint32_t count) { return env.current()->fees().accountReserve(count); } XRPAmount -AMMTest::ammCrtFee(jtx::Env& env) const +AMMTest::ammCrtFee(jtx::Env& env) { return env.current()->fees().increment; } diff --git a/src/test/jtx/impl/Env.cpp b/src/test/jtx/impl/Env.cpp index 3217f67cbe..6967b48518 100644 --- a/src/test/jtx/impl/Env.cpp +++ b/src/test/jtx/impl/Env.cpp @@ -76,7 +76,7 @@ Env::AppBundle::~AppBundle() client.reset(); // Make sure all jobs finish, otherwise tests // might not get the coverage they expect. - if (app) + if (app != nullptr) { app->getJobQueue().rendezvous(); app->signalStop("~AppBundle"); @@ -218,6 +218,7 @@ Env::balance(Account const& account, MPTIssue const& mptIssue) const } PrettyAmount +// NOLINTNEXTLINE(readability-convert-member-functions-to-static) Env::balance(Account const& account, Asset const& asset) const { return std::visit([&](auto const& issue) { return balance(account, issue); }, asset.value()); @@ -468,7 +469,7 @@ Env::postconditions( // we didn't get the expected result. return; } - if (trace_) + if (trace_ != 0) { if (trace_ > 0) --trace_; diff --git a/src/test/jtx/impl/Oracle.cpp b/src/test/jtx/impl/Oracle.cpp index 8bc456cd4e..0c9ddc8f0d 100644 --- a/src/test/jtx/impl/Oracle.cpp +++ b/src/test/jtx/impl/Oracle.cpp @@ -258,7 +258,7 @@ Oracle::set(UpdateArg const& arg) return s; assert(s.size() <= 20); // anything else must be 160-bit hex string - return strHex(s).append(40 - s.size() * 2, '0'); + return strHex(s).append(40 - (s.size() * 2), '0'); }; for (auto const& data : arg.series) { diff --git a/src/test/jtx/impl/mpt.cpp b/src/test/jtx/impl/mpt.cpp index a6283bb6f9..933aabce30 100644 --- a/src/test/jtx/impl/mpt.cpp +++ b/src/test/jtx/impl/mpt.cpp @@ -370,7 +370,7 @@ MPTTester::set(MPTSet const& arg) .metadata = arg.metadata, .delegate = arg.delegate, .domainID = arg.domainID}); - if (submit(arg, jv) == tesSUCCESS && (arg.flags.value_or(0) || arg.mutableFlags)) + if (submit(arg, jv) == tesSUCCESS && ((arg.flags.value_or(0) != 0u) || arg.mutableFlags)) { auto require = [&](std::optional const& holder, bool unchanged) { auto flags = getFlags(holder); diff --git a/src/test/jtx/impl/multisign.cpp b/src/test/jtx/impl/multisign.cpp index ae39382824..02550b803c 100644 --- a/src/test/jtx/impl/multisign.cpp +++ b/src/test/jtx/impl/multisign.cpp @@ -83,7 +83,7 @@ msig::operator()(Env& env, JTx& jt) const jo[sfTxnSignature.getJsonName()] = strHex(Slice{sig.data(), sig.size()}); } }; - if (!subField) + if (subField == nullptr) { jt.mainSigners.emplace_back(callback); } diff --git a/src/test/jtx/impl/offer.cpp b/src/test/jtx/impl/offer.cpp index 251b659f3b..5a2264601a 100644 --- a/src/test/jtx/impl/offer.cpp +++ b/src/test/jtx/impl/offer.cpp @@ -17,7 +17,7 @@ offer( jv[jss::Account] = account.human(); jv[jss::TakerPays] = takerPays.getJson(JsonOptions::none); jv[jss::TakerGets] = takerGets.getJson(JsonOptions::none); - if (flags) + if (flags != 0u) jv[jss::Flags] = flags; jv[jss::TransactionType] = jss::OfferCreate; return jv; diff --git a/src/test/jtx/impl/sig.cpp b/src/test/jtx/impl/sig.cpp index 850c5af781..1bdadc0bd3 100644 --- a/src/test/jtx/impl/sig.cpp +++ b/src/test/jtx/impl/sig.cpp @@ -10,7 +10,7 @@ sig::operator()(Env&, JTx& jt) const { if (!manual_) return; - if (!subField_) + if (subField_ == nullptr) jt.fill_sig = false; if (account_) { @@ -22,7 +22,7 @@ sig::operator()(Env&, JTx& jt) const jtx::sign(jtx.jv, account, sigObject); }; - if (!subField_) + if (subField_ == nullptr) { jt.mainSigners.emplace_back(callback); } diff --git a/src/test/jtx/vault.h b/src/test/jtx/vault.h index 43f975323a..748d3341a5 100644 --- a/src/test/jtx/vault.h +++ b/src/test/jtx/vault.h @@ -38,7 +38,7 @@ struct Vault uint256 id; }; - Json::Value + static Json::Value set(SetArgs const& args); struct DeleteArgs @@ -47,7 +47,7 @@ struct Vault uint256 id; }; - Json::Value + static Json::Value del(DeleteArgs const& args); struct DepositArgs @@ -57,7 +57,7 @@ struct Vault STAmount amount; }; - Json::Value + static Json::Value deposit(DepositArgs const& args); struct WithdrawArgs @@ -67,7 +67,7 @@ struct Vault STAmount amount; }; - Json::Value + static Json::Value withdraw(WithdrawArgs const& args); struct ClawbackArgs @@ -78,7 +78,7 @@ struct Vault std::optional amount{}; }; - Json::Value + static Json::Value clawback(ClawbackArgs const& args); }; diff --git a/src/test/ledger/Directory_test.cpp b/src/test/ledger/Directory_test.cpp index 18649a20a8..b08e7daaf6 100644 --- a/src/test/ledger/Directory_test.cpp +++ b/src/test/ledger/Directory_test.cpp @@ -37,7 +37,7 @@ struct Directory_test : public beast::unit_test::suite // Insert n empty pages, numbered [0, ... n - 1], in the // specified directory: - void + static void makePages(Sandbox& sb, uint256 const& base, std::uint64_t n) { for (std::uint64_t i = 0; i < n; ++i) @@ -274,7 +274,7 @@ struct Directory_test : public beast::unit_test::suite { for (int i = 0; i < dirNodeMaxEntries; ++i) { - env(offer_cancel(alice, firstOfferSeq + page * dirNodeMaxEntries + i)); + env(offer_cancel(alice, firstOfferSeq + (page * dirNodeMaxEntries) + i)); env.close(); } } diff --git a/src/test/nodestore/NuDBFactory_test.cpp b/src/test/nodestore/NuDBFactory_test.cpp index 9a9b7d83bd..0aa910ce01 100644 --- a/src/test/nodestore/NuDBFactory_test.cpp +++ b/src/test/nodestore/NuDBFactory_test.cpp @@ -17,7 +17,7 @@ class NuDBFactory_test : public TestBase { private: // Helper function to create a Section with specified parameters - Section + static Section createSection(std::string const& path, std::string const& blockSize = "") { Section params; diff --git a/src/test/nodestore/Timing_test.cpp b/src/test/nodestore/Timing_test.cpp index d5c89dbcc9..fc8c042252 100644 --- a/src/test/nodestore/Timing_test.cpp +++ b/src/test/nodestore/Timing_test.cpp @@ -111,7 +111,7 @@ public: { b.clear(); b.reserve(size); - while (size--) + while ((size--) != 0u) b.emplace_back(obj(n++)); } }; @@ -524,7 +524,7 @@ public: , seq1_(1) , gen_(id + 1) , rand_(0, 99) - , recent_(params.items, params.items * 2 - 1) + , recent_(params.items, (params.items * 2) - 1) , older_(0, params.items - 1) { } @@ -643,7 +643,7 @@ public: Params params{}; params.items = default_items; params.threads = threads; - for (auto i = default_repeat; i--;) + for (auto i = default_repeat; (i--) != 0u;) { beast::temp_dir tempDir; Section config = parse(config_string); diff --git a/src/test/nodestore/import_test.cpp b/src/test/nodestore/import_test.cpp index e5f281486b..54d55e5ad0 100644 --- a/src/test/nodestore/import_test.cpp +++ b/src/test/nodestore/import_test.cpp @@ -333,7 +333,7 @@ public: options.max_open_files = 2000; // 5000? rocksdb::DB* pdb = nullptr; rocksdb::Status status = rocksdb::DB::OpenForReadOnly(options, from_path, &pdb); - if (!status.ok() || !pdb) + if (!status.ok() || (pdb == nullptr)) Throw("Can't open '" + from_path + "': " + status.ToString()); db.reset(pdb); } @@ -458,7 +458,7 @@ public: // Create empty buckets for (std::size_t i = 0; i < bn; ++i) { - bucket b(kh.block_size, buf.get() + i * kh.block_size, empty); + bucket b(kh.block_size, buf.get() + (i * kh.block_size), empty); } // Insert all keys into buckets // Iterate Data File @@ -484,10 +484,10 @@ public: std::uint8_t const* const key = is.data(dh.key_size); auto const h = hash(key, kh.key_size, kh.salt); auto const n = bucket_index(h, kh.buckets, kh.modulus); - p(log, npass * df_size + r.offset()); + p(log, (npass * df_size) + r.offset()); if (n < b0 || n >= b1) continue; - bucket b(kh.block_size, buf.get() + (n - b0) * kh.block_size); + bucket b(kh.block_size, buf.get() + ((n - b0) * kh.block_size)); maybe_spill(b, dw, ec); if (ec) Throw(ec); diff --git a/src/test/overlay/TMGetObjectByHash_test.cpp b/src/test/overlay/TMGetObjectByHash_test.cpp index 0624c7b088..b899ceb084 100644 --- a/src/test/overlay/TMGetObjectByHash_test.cpp +++ b/src/test/overlay/TMGetObjectByHash_test.cpp @@ -121,7 +121,7 @@ class TMGetObjectByHash_test : public beast::unit_test::suite return peer; } - std::shared_ptr + static std::shared_ptr createRequest(size_t const numObjects, Env& env) { // Store objects in the NodeStore that will be found during the query diff --git a/src/test/overlay/cluster_test.cpp b/src/test/overlay/cluster_test.cpp index 6fa4604f78..59fa22a442 100644 --- a/src/test/overlay/cluster_test.cpp +++ b/src/test/overlay/cluster_test.cpp @@ -29,7 +29,7 @@ public: return cluster; } - PublicKey + static PublicKey randomNode() { return derivePublicKey(KeyType::secp256k1, randomSecretKey()); diff --git a/src/test/overlay/compression_test.cpp b/src/test/overlay/compression_test.cpp index f784a91350..38b60c2251 100644 --- a/src/test/overlay/compression_test.cpp +++ b/src/test/overlay/compression_test.cpp @@ -117,7 +117,7 @@ public: decompressed.begin())); } - std::shared_ptr + static std::shared_ptr buildManifests(int n) { auto manifests = std::make_shared(); @@ -143,7 +143,7 @@ public: return manifests; } - std::shared_ptr + static std::shared_ptr buildEndpoints(int n) { auto endpoints = std::make_shared(); @@ -196,7 +196,7 @@ public: return transaction; } - std::shared_ptr + static std::shared_ptr buildGetLedger() { auto getLedger = std::make_shared(); @@ -213,7 +213,7 @@ public: return getLedger; } - std::shared_ptr + static std::shared_ptr buildLedgerData(uint32_t n, Logs& logs) { auto ledgerData = std::make_shared(); @@ -251,7 +251,7 @@ public: return ledgerData; } - std::shared_ptr + static std::shared_ptr buildGetObjectByHash() { auto getObject = std::make_shared(); @@ -277,7 +277,7 @@ public: return getObject; } - std::shared_ptr + static std::shared_ptr buildValidatorList() { auto list = std::make_shared(); @@ -304,7 +304,7 @@ public: return list; } - std::shared_ptr + static std::shared_ptr buildValidatorListCollection() { auto list = std::make_shared(); diff --git a/src/test/overlay/reduce_relay_test.cpp b/src/test/overlay/reduce_relay_test.cpp index 8e50415aa9..b4a47bac53 100644 --- a/src/test/overlay/reduce_relay_test.cpp +++ b/src/test/overlay/reduce_relay_test.cpp @@ -362,7 +362,7 @@ public: { for (auto id : peers) { - assert(links_.find(id) != links_.end()); + assert(links_.contains(id)); f(*links_[id], message_); } } @@ -637,7 +637,7 @@ public: getSelectedPeer(PublicKey const& validator) { auto selected = slots_.getSelected(validator); - assert(selected.size()); + assert(!selected.empty()); return *selected.begin(); } @@ -785,7 +785,7 @@ public: } } - void + static void for_rand(std::uint32_t min, std::uint32_t max, std::function f) { auto size = max - min; @@ -879,14 +879,14 @@ protected: } /** Send squelch (if duration is set) or unsquelch (if duration not set) */ - Peer::id_t + static Peer::id_t sendSquelch( PublicKey const& validator, PeerWPtr const& peerPtr, std::optional duration) { protocol::TMSquelch squelch; - bool res = duration ? true : false; + bool res = static_cast(duration); squelch.set_squelch(res); squelch.set_validatorpubkey(validator.data(), validator.size()); if (res) @@ -1004,8 +1004,8 @@ protected: // take place because there is no peers in Squelched state in // any of the slots where the peer is in Selected state // (allCounting is true) - bool handled = (event.isSelected_ == false && !event.handled_) || - (event.isSelected_ == true && (event.handled_ || allCounting)); + bool handled = (!event.isSelected_ && !event.handled_) || + (event.isSelected_ && (event.handled_ || allCounting)); BEAST_EXPECT(handled); event.state_ = State::Off; event.isSelected_ = false; @@ -1499,7 +1499,7 @@ vp_base_squelch_max_selected_peers=2 { // make unique message hash to make the // slot's internal hash router accept the message - std::uint64_t mid = m * 1000 + peer; + std::uint64_t mid = (m * 1000) + peer; uint256 const message{mid}; slots.updateSlotAndSquelch( message, validator, peer, protocol::MessageType::mtVALIDATION); diff --git a/src/test/protocol/PublicKey_test.cpp b/src/test/protocol/PublicKey_test.cpp index 053e945a7b..79c1356bb4 100644 --- a/src/test/protocol/PublicKey_test.cpp +++ b/src/test/protocol/PublicKey_test.cpp @@ -46,7 +46,7 @@ public: } } - blob + static blob sig(std::string const& hex) { blob b; @@ -54,7 +54,7 @@ public: return b; } - bool + static bool check(std::optional answer, std::string const& s) { return ecdsaCanonicality(makeSlice(sig(s))) == answer; diff --git a/src/test/protocol/STAmount_test.cpp b/src/test/protocol/STAmount_test.cpp index c9382d508a..4f652dddd9 100644 --- a/src/test/protocol/STAmount_test.cpp +++ b/src/test/protocol/STAmount_test.cpp @@ -21,7 +21,7 @@ public: } //-------------------------------------------------------------------------- - STAmount + static STAmount roundSelf(STAmount const& amount) { if (amount.native()) diff --git a/src/test/protocol/STParsedJSON_test.cpp b/src/test/protocol/STParsedJSON_test.cpp index 18e695d25d..974975d05f 100644 --- a/src/test/protocol/STParsedJSON_test.cpp +++ b/src/test/protocol/STParsedJSON_test.cpp @@ -11,7 +11,7 @@ namespace xrpl { class STParsedJSON_test : public beast::unit_test::suite { - bool + static bool parseJSONString(std::string const& json, Json::Value& to) { Json::Reader reader; diff --git a/src/test/protocol/SeqProxy_test.cpp b/src/test/protocol/SeqProxy_test.cpp index 9096fe7daf..7e7a21ab6e 100644 --- a/src/test/protocol/SeqProxy_test.cpp +++ b/src/test/protocol/SeqProxy_test.cpp @@ -42,7 +42,7 @@ struct SeqProxy_test : public beast::unit_test::suite } // Verify streaming. - bool + static bool streamTest(SeqProxy seqProx) { std::string const type{seqProx.isSeq() ? "sequence" : "ticket"}; diff --git a/src/test/resource/Logic_test.cpp b/src/test/resource/Logic_test.cpp index c555b92860..6d412b000f 100644 --- a/src/test/resource/Logic_test.cpp +++ b/src/test/resource/Logic_test.cpp @@ -44,7 +44,7 @@ public: //-------------------------------------------------------------------------- - void + static void createGossip(Gossip& gossip) { std::uint8_t const v(10 + rand_int(9)); @@ -182,7 +182,7 @@ public: } } } - if (readmitted == false) + if (!readmitted) { fail("Dropped Consumer left on blacklist too long"); return; diff --git a/src/test/rpc/AccountObjects_test.cpp b/src/test/rpc/AccountObjects_test.cpp index 435bbd37d5..905f8f2bb7 100644 --- a/src/test/rpc/AccountObjects_test.cpp +++ b/src/test/rpc/AccountObjects_test.cpp @@ -1313,7 +1313,7 @@ public: auto resp = env.rpc("json", "account_objects", to_string(params)); auto& accountObjects = resp[jss::result][jss::account_objects]; BEAST_EXPECT(!resp[jss::result].isMember(jss::error)); - BEAST_EXPECT(accountObjects.size() == accountObjectSize - limit * 2); + BEAST_EXPECT(accountObjects.size() == accountObjectSize - (limit * 2)); BEAST_EXPECT(!resp[jss::result].isMember(jss::marker)); } diff --git a/src/test/rpc/Book_test.cpp b/src/test/rpc/Book_test.cpp index 8136af310a..41442edb06 100644 --- a/src/test/rpc/Book_test.cpp +++ b/src/test/rpc/Book_test.cpp @@ -15,7 +15,7 @@ namespace test { class Book_test : public beast::unit_test::suite { - std::string + static std::string getBookDir( jtx::Env& env, Issue const& in, @@ -1524,7 +1524,7 @@ public: auto USD = gw["USD"]; for (auto i = 0; i <= RPC::Tuning::bookOffers.rmax; i++) - env(offer(gw, XRP(50 + 1 * i), USD(1.0 + 0.1 * i))); + env(offer(gw, XRP(50 + (1 * i)), USD(1.0 + (0.1 * i)))); if (asAdmin) env.close(); diff --git a/src/test/rpc/DeliveredAmount_test.cpp b/src/test/rpc/DeliveredAmount_test.cpp index 00f8c54ee5..31b9b2aebf 100644 --- a/src/test/rpc/DeliveredAmount_test.cpp +++ b/src/test/rpc/DeliveredAmount_test.cpp @@ -76,7 +76,8 @@ public: bool checkExpectedCounters() const { - return !numExpectedAvailable_ && !numExpectedNotSet_ && !numExpectedSetUnavailable_; + return (numExpectedAvailable_ == 0) && (numExpectedNotSet_ == 0) && + (numExpectedSetUnavailable_ == 0); } // Check if the transaction has `delivered_amount` in the metaData as diff --git a/src/test/rpc/LedgerEntry_test.cpp b/src/test/rpc/LedgerEntry_test.cpp index eec114b71c..8f4a096e2a 100644 --- a/src/test/rpc/LedgerEntry_test.cpp +++ b/src/test/rpc/LedgerEntry_test.cpp @@ -131,7 +131,7 @@ class LedgerEntry_test : public beast::unit_test::suite } } - std::vector + static std::vector getBadValues(FieldType fieldType) { static Json::Value const injectObject = []() { @@ -225,7 +225,7 @@ class LedgerEntry_test : public beast::unit_test::suite } } - Json::Value + static Json::Value getCorrectValue(Json::StaticString fieldName) { static Json::Value const twoAccountArray = []() { diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index 2f4a63a090..8f965aa2cf 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -40,7 +40,7 @@ class LedgerRPC_test : public beast::unit_test::suite // Corrupt a valid address by replacing the 10th character with '!'. // '!' is not part of the ripple alphabet. - std::string + static std::string makeBadAddress(std::string good) { std::string ret = std::move(good); diff --git a/src/test/rpc/Roles_test.cpp b/src/test/rpc/Roles_test.cpp index a4f9de2284..e3d90a9c56 100644 --- a/src/test/rpc/Roles_test.cpp +++ b/src/test/rpc/Roles_test.cpp @@ -12,7 +12,7 @@ namespace test { class Roles_test : public beast::unit_test::suite { - bool + static bool isValidIpAddress(std::string const& addr) { boost::system::error_code ec; diff --git a/src/test/rpc/ServerInfo_test.cpp b/src/test/rpc/ServerInfo_test.cpp index 5bb2c31757..978b995ce8 100644 --- a/src/test/rpc/ServerInfo_test.cpp +++ b/src/test/rpc/ServerInfo_test.cpp @@ -93,7 +93,7 @@ admin = 127.0.0.1 Env env(*this); // Call NetworkOPs directly and set the admin flag to false. - auto const result = env.app().getOPs().getServerInfo(true, false, 0); + auto const result = env.app().getOPs().getServerInfo(true, false, false); // Expect that the admin ports are not included in the result. auto const& ports = result[jss::ports]; BEAST_EXPECT(ports.isArray() && ports.size() == 0); diff --git a/src/test/rpc/Simulate_test.cpp b/src/test/rpc/Simulate_test.cpp index 74f9b03111..e096b0479f 100644 --- a/src/test/rpc/Simulate_test.cpp +++ b/src/test/rpc/Simulate_test.cpp @@ -131,8 +131,8 @@ class Simulate_test : public beast::unit_test::suite BEAST_EXPECTS(env.current()->txCount() == 0, std::to_string(env.current()->txCount())); } - Json::Value - getJsonMetadata(Json::Value txResult) const + static Json::Value + getJsonMetadata(Json::Value txResult) { if (txResult.isMember(jss::meta_blob)) { diff --git a/src/test/rpc/Transaction_test.cpp b/src/test/rpc/Transaction_test.cpp index 2709900bf1..c53207e04d 100644 --- a/src/test/rpc/Transaction_test.cpp +++ b/src/test/rpc/Transaction_test.cpp @@ -19,7 +19,7 @@ namespace xrpl { class Transaction_test : public beast::unit_test::suite { - std::unique_ptr + static std::unique_ptr makeNetworkConfig(uint32_t networkID) { using namespace test::jtx; @@ -91,7 +91,7 @@ class Transaction_test : public beast::unit_test::suite result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND); - if (deltaEndSeq) + if (deltaEndSeq != 0) { BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool()); } @@ -332,7 +332,7 @@ class Transaction_test : public beast::unit_test::suite result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND); - if (deltaEndSeq) + if (deltaEndSeq != 0) { BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool()); } diff --git a/src/test/server/ServerStatus_test.cpp b/src/test/server/ServerStatus_test.cpp index 178b85b3e4..1a5da25d65 100644 --- a/src/test/server/ServerStatus_test.cpp +++ b/src/test/server/ServerStatus_test.cpp @@ -33,7 +33,7 @@ class ServerStatus_test : public beast::unit_test::suite, public beast::test::en { }; - auto + static auto makeConfig(std::string const& proto, bool admin = true, bool credentials = false) { auto const section_name = boost::starts_with(proto, "h") ? "port_rpc" : "port_ws"; @@ -69,7 +69,7 @@ class ServerStatus_test : public beast::unit_test::suite, public beast::test::en return p; } - auto + static auto makeWSUpgrade(std::string const& host, uint16_t port) { using namespace boost::asio; @@ -97,7 +97,7 @@ class ServerStatus_test : public beast::unit_test::suite, public beast::test::en return req; } - auto + static auto makeHTTPRequest( std::string const& host, uint16_t port, @@ -217,7 +217,7 @@ class ServerStatus_test : public beast::unit_test::suite, public beast::test::en return; } - auto + static auto makeAdminRequest( jtx::Env& env, std::string const& proto, diff --git a/src/test/server/Server_test.cpp b/src/test/server/Server_test.cpp index bce8bced60..b6ff180bd4 100644 --- a/src/test/server/Server_test.cpp +++ b/src/test/server/Server_test.cpp @@ -91,13 +91,13 @@ public: struct TestHandler { - bool + static bool onAccept(Session& session, boost::asio::ip::tcp::endpoint endpoint) { return true; } - Handoff + static Handoff onHandoff( Session& session, std::unique_ptr const& bundle, @@ -107,7 +107,7 @@ public: return Handoff{}; } - Handoff + static Handoff onHandoff( Session& session, http_request_type const& request, @@ -116,7 +116,7 @@ public: return Handoff{}; } - void + static void onRequest(Session& session) { session.write(std::string("Hello, world!\n")); @@ -303,13 +303,13 @@ public: testcase("stress test"); struct NullHandler { - bool + static bool onAccept(Session& session, boost::asio::ip::tcp::endpoint endpoint) { return true; } - Handoff + static Handoff onHandoff( Session& session, std::unique_ptr const& bundle, @@ -319,7 +319,7 @@ public: return Handoff{}; } - Handoff + static Handoff onHandoff( Session& session, http_request_type const& request, diff --git a/src/test/shamap/FetchPack_test.cpp b/src/test/shamap/FetchPack_test.cpp index 471ad91e95..ad86e066af 100644 --- a/src/test/shamap/FetchPack_test.cpp +++ b/src/test/shamap/FetchPack_test.cpp @@ -66,7 +66,7 @@ public: beast::Journal mJournal; }; - boost::intrusive_ptr + static boost::intrusive_ptr make_random_item(beast::xor_shift_engine& r) { Serializer s; @@ -75,10 +75,10 @@ public: return make_shamapitem(s.getSHA512Half(), s.slice()); } - void + static void add_random_items(std::size_t n, Table& t, beast::xor_shift_engine& r) { - while (n--) + while ((n--) != 0u) { auto const result(t.addItem(SHAMapNodeType::tnACCOUNT_STATE, make_random_item(r))); assert(result); diff --git a/src/tests/libxrpl/basics/RangeSet.cpp b/src/tests/libxrpl/basics/RangeSet.cpp index d0fc656368..41a33133f2 100644 --- a/src/tests/libxrpl/basics/RangeSet.cpp +++ b/src/tests/libxrpl/basics/RangeSet.cpp @@ -17,7 +17,7 @@ TEST(RangeSet, prevMissing) RangeSet set; for (std::uint32_t i = 0; i < 10; ++i) - set.insert(range(10 * i, 10 * i + 5)); + set.insert(range(10 * i, (10 * i) + 5)); for (std::uint32_t i = 1; i < 100; ++i) { diff --git a/src/tests/libxrpl/json/Value.cpp b/src/tests/libxrpl/json/Value.cpp index a7b7387ba1..943e517669 100644 --- a/src/tests/libxrpl/json/Value.cpp +++ b/src/tests/libxrpl/json/Value.cpp @@ -209,10 +209,10 @@ TEST(json_value, compare_strings) SCOPED_TRACE(line); EXPECT_EQ((lhs == rhs), lhsEqRhs); EXPECT_NE((lhs != rhs), lhsEqRhs); - EXPECT_EQ((lhs < rhs), (!(lhsEqRhs || !lhsLtRhs))); + EXPECT_EQ((lhs < rhs), (!lhsEqRhs && lhsLtRhs)); EXPECT_EQ((lhs <= rhs), (lhsEqRhs || lhsLtRhs)); EXPECT_EQ((lhs >= rhs), (lhsEqRhs || !lhsLtRhs)); - EXPECT_EQ((lhs > rhs), (!(lhsEqRhs || lhsLtRhs))); + EXPECT_EQ((lhs > rhs), (!lhsEqRhs && !lhsLtRhs)); }; Json::Value const null0; diff --git a/src/xrpld/app/consensus/RCLConsensus.cpp b/src/xrpld/app/consensus/RCLConsensus.cpp index 5a3d53dae0..315f9f2ab5 100644 --- a/src/xrpld/app/consensus/RCLConsensus.cpp +++ b/src/xrpld/app/consensus/RCLConsensus.cpp @@ -925,7 +925,7 @@ RCLConsensus::Adaptor::preStartRound(RCLCxLedger const& prevLgr, hash_set= LEDGER_RETRY_PASSES)) + if ((changes == 0) || (pass >= LEDGER_RETRY_PASSES)) certainRetry = false; } diff --git a/src/xrpld/app/ledger/detail/LedgerMaster.cpp b/src/xrpld/app/ledger/detail/LedgerMaster.cpp index 42d7f2ec6e..320c4bc722 100644 --- a/src/xrpld/app/ledger/detail/LedgerMaster.cpp +++ b/src/xrpld/app/ledger/detail/LedgerMaster.cpp @@ -195,7 +195,7 @@ LedgerMaster::isCaughtUp(std::string& reason) } std::uint32_t validClose = mValidLedgerSign.load(); std::uint32_t pubClose = mPubLedgerClose.load(); - if (!validClose || !pubClose) + if ((validClose == 0u) || (pubClose == 0u)) { reason = "No published ledger"; return false; @@ -514,7 +514,7 @@ LedgerMaster::getFullValidatedRange(std::uint32_t& minVal, std::uint32_t& maxVal // published ledger which is. maxVal = mPubLedgerSeq.load(); - if (!maxVal) + if (maxVal == 0u) return false; std::optional maybeMin; diff --git a/src/xrpld/app/ledger/detail/LedgerToJson.cpp b/src/xrpld/app/ledger/detail/LedgerToJson.cpp index ff8e7e55e9..a48756f9b6 100644 --- a/src/xrpld/app/ledger/detail/LedgerToJson.cpp +++ b/src/xrpld/app/ledger/detail/LedgerToJson.cpp @@ -18,19 +18,19 @@ namespace { bool isFull(LedgerFill const& fill) { - return fill.options & LedgerFill::full; + return (fill.options & LedgerFill::full) != 0; } bool isExpanded(LedgerFill const& fill) { - return isFull(fill) || (fill.options & LedgerFill::expand); + return isFull(fill) || ((fill.options & LedgerFill::expand) != 0); } bool isBinary(LedgerFill const& fill) { - return fill.options & LedgerFill::binary; + return (fill.options & LedgerFill::binary) != 0; } void @@ -173,7 +173,7 @@ fillJsonTx( } } - if ((fill.options & LedgerFill::ownerFunds) && txn->getTxnType() == ttOFFER_CREATE) + if (((fill.options & LedgerFill::ownerFunds) != 0) && txn->getTxnType() == ttOFFER_CREATE) { auto const account = txn->getAccountID(sfAccount); auto const amount = txn->getFieldAmount(sfTakerGets); @@ -216,7 +216,7 @@ fillJsonTx(Json::Value& json, LedgerFill const& fill) catch (std::exception const& ex) { // Nothing the user can do about this. - if (fill.context) + if (fill.context != nullptr) { JLOG(fill.context->j.error()) << "Exception in " << __func__ << ": " << ex.what(); } @@ -304,13 +304,14 @@ fillJson(Json::Value& json, LedgerFill const& fill) !fill.ledger.open(), fill.ledger.header(), bFull, - (fill.context ? fill.context->apiVersion : RPC::apiMaximumSupportedVersion)); + ((fill.context != nullptr) ? fill.context->apiVersion + : RPC::apiMaximumSupportedVersion)); } - if (bFull || fill.options & LedgerFill::dumpTxrp) + if (bFull || ((fill.options & LedgerFill::dumpTxrp) != 0)) fillJsonTx(json, fill); - if (bFull || fill.options & LedgerFill::dumpState) + if (bFull || ((fill.options & LedgerFill::dumpState) != 0)) fillJsonState(json, fill); } @@ -322,7 +323,7 @@ addJson(Json::Value& json, LedgerFill const& fill) auto& object = json[jss::ledger] = Json::objectValue; fillJson(object, fill); - if ((fill.options & LedgerFill::dumpQueue) && !fill.txQueue.empty()) + if (((fill.options & LedgerFill::dumpQueue) != 0) && !fill.txQueue.empty()) fillJsonQueue(json, fill); } diff --git a/src/xrpld/app/ledger/detail/TransactionMaster.cpp b/src/xrpld/app/ledger/detail/TransactionMaster.cpp index b45dbd5ba9..e3ebd443f1 100644 --- a/src/xrpld/app/ledger/detail/TransactionMaster.cpp +++ b/src/xrpld/app/ledger/detail/TransactionMaster.cpp @@ -110,7 +110,7 @@ TransactionMaster::fetch( } else { - if (uCommitLedger) + if (uCommitLedger != 0u) iTx->setStatus(COMMITTED, uCommitLedger); txn = iTx->getSTransaction(); diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index 048ef0d9b4..55ba09e49e 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -2127,7 +2127,7 @@ fixConfigPorts(Config& config, Endpoints const& endpoints) if (optPort) { std::uint16_t const port = beast::lexicalCast(*optPort); - if (!port) + if (port == 0u) section.set("port", std::to_string(ep.port())); } } diff --git a/src/xrpld/app/main/BasicApp.cpp b/src/xrpld/app/main/BasicApp.cpp index be0c158b85..2c5a2b0364 100644 --- a/src/xrpld/app/main/BasicApp.cpp +++ b/src/xrpld/app/main/BasicApp.cpp @@ -9,7 +9,7 @@ BasicApp::BasicApp(std::size_t numberOfThreads) work_.emplace(boost::asio::make_work_guard(io_context_)); threads_.reserve(numberOfThreads); - while (numberOfThreads--) + while ((numberOfThreads--) != 0u) { threads_.emplace_back([this, numberOfThreads]() { beast::setCurrentThreadName("io svc #" + std::to_string(numberOfThreads)); diff --git a/src/xrpld/app/main/Main.cpp b/src/xrpld/app/main/Main.cpp index 03f8076ed1..88a335f843 100644 --- a/src/xrpld/app/main/Main.cpp +++ b/src/xrpld/app/main/Main.cpp @@ -295,7 +295,7 @@ runUnitTests( try { c.wait(); - if (c.exit_code()) + if (c.exit_code() != 0) ++bad_child_exits; } catch (...) @@ -309,7 +309,7 @@ runUnitTests( parent_runner.add_failures(terminated_child_exits); anyMissing(parent_runner, multi_selector(pattern)); - if (parent_runner.any_failed() || bad_child_exits) + if (parent_runner.any_failed() || (bad_child_exits != 0)) return EXIT_FAILURE; return EXIT_SUCCESS; } diff --git a/src/xrpld/app/misc/NegativeUNLVote.h b/src/xrpld/app/misc/NegativeUNLVote.h index 601ac7d060..7ad460cbf1 100644 --- a/src/xrpld/app/misc/NegativeUNLVote.h +++ b/src/xrpld/app/misc/NegativeUNLVote.h @@ -140,7 +140,7 @@ private: * @param candidates the vector of candidates * @return the picked candidate */ - NodeID + static NodeID choose(uint256 const& randomPadData, std::vector const& candidates); /** diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index aabb53230f..5110534efc 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -1689,12 +1689,12 @@ NetworkOPsImp::getOwnerInfo(std::shared_ptr lpLedger, AccountID uNodeDir = sleNode->getFieldU64(sfIndexNext); - if (uNodeDir) + if (uNodeDir != 0u) { sleNode = lpLedger->read(keylet::page(root, uNodeDir)); XRPL_ASSERT(sleNode, "xrpl::NetworkOPsImp::getOwnerInfo : read next page"); } - } while (uNodeDir); + } while (uNodeDir != 0u); } return jvObjects; @@ -2532,7 +2532,7 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters) } } - if (warnings.size()) + if (warnings.size() != 0u) info[jss::warnings] = std::move(warnings); } @@ -4038,7 +4038,7 @@ bool NetworkOPsImp::unsubLedger(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sLedger].erase(uSeq); + return mStreamMaps[sLedger].erase(uSeq) != 0u; } // <-- bool: true=erased, false=was not there @@ -4046,7 +4046,7 @@ bool NetworkOPsImp::unsubBookChanges(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sBookChanges].erase(uSeq); + return mStreamMaps[sBookChanges].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4062,7 +4062,7 @@ bool NetworkOPsImp::unsubManifests(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sManifests].erase(uSeq); + return mStreamMaps[sManifests].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4095,7 +4095,7 @@ bool NetworkOPsImp::unsubServer(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sServer].erase(uSeq); + return mStreamMaps[sServer].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4111,7 +4111,7 @@ bool NetworkOPsImp::unsubTransactions(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sTransactions].erase(uSeq); + return mStreamMaps[sTransactions].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4127,7 +4127,7 @@ bool NetworkOPsImp::unsubRTTransactions(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sRTTransactions].erase(uSeq); + return mStreamMaps[sRTTransactions].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4149,7 +4149,7 @@ bool NetworkOPsImp::unsubValidations(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sValidations].erase(uSeq); + return mStreamMaps[sValidations].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4165,7 +4165,7 @@ bool NetworkOPsImp::unsubPeerStatus(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sPeerStatus].erase(uSeq); + return mStreamMaps[sPeerStatus].erase(uSeq) != 0u; } // <-- bool: true=added, false=already there @@ -4181,7 +4181,7 @@ bool NetworkOPsImp::unsubConsensus(std::uint64_t uSeq) { std::lock_guard sl(mSubLock); - return mStreamMaps[sConsensusPhase].erase(uSeq); + return mStreamMaps[sConsensusPhase].erase(uSeq) != 0u; } InfoSub::pointer @@ -4632,7 +4632,7 @@ NetworkOPsImp::StateAccounting::json(Json::Value& obj) const state[jss::duration_us] = std::to_string(counters[i].dur.count()); } obj[jss::server_state_duration_us] = std::to_string(current.count()); - if (initialSync) + if (initialSync != 0u) obj[jss::initial_sync_duration_us] = std::to_string(initialSync); } diff --git a/src/xrpld/app/misc/SHAMapStoreImp.cpp b/src/xrpld/app/misc/SHAMapStoreImp.cpp index 13746369f5..2865f964de 100644 --- a/src/xrpld/app/misc/SHAMapStoreImp.cpp +++ b/src/xrpld/app/misc/SHAMapStoreImp.cpp @@ -93,7 +93,7 @@ SHAMapStoreImp::SHAMapStoreImp( get_if_exists(section, "online_delete", deleteInterval_); - if (deleteInterval_) + if (deleteInterval_ != 0u) { // Configuration that affects the behavior of online delete get_if_exists(section, "delete_batch", deleteBatch_); @@ -138,7 +138,7 @@ SHAMapStoreImp::makeNodeStore(int readThreads) auto nscfg = app_.config().section(ConfigSection::nodeDatabase()); std::unique_ptr db; - if (deleteInterval_) + if (deleteInterval_ != 0u) { SavedState state = state_db_.getState(); auto writableBackend = makeBackendRotating(state.writableDb); @@ -209,7 +209,7 @@ SHAMapStoreImp::copyNode(std::uint64_t& nodeCount, SHAMapTreeNode const& node) // Copy a single record from node to dbRotating_ dbRotating_->fetchNodeObject( node.getHash().as_uint256(), 0, NodeStore::FetchType::synchronous, true); - if (!(++nodeCount % checkHealthInterval_)) + if ((++nodeCount % checkHealthInterval_) == 0u) { if (healthWait() == stopping) return false; @@ -254,7 +254,7 @@ SHAMapStoreImp::run() } LedgerIndex const validatedSeq = validatedLedger->header().seq; - if (!lastRotated) + if (lastRotated == 0u) { lastRotated = validatedSeq; state_db_.setLastRotated(lastRotated); @@ -386,15 +386,15 @@ SHAMapStoreImp::dbPaths() it != boost::filesystem::directory_iterator(); ++it) { - if (!state.writableDb.compare(it->path().string())) + if (state.writableDb.compare(it->path().string()) == 0) { writableDbExists = true; } - else if (!state.archiveDb.compare(it->path().string())) + else if (state.archiveDb.compare(it->path().string()) == 0) { archiveDbExists = true; } - else if (!dbPrefix_.compare(it->path().stem().string())) + else if (dbPrefix_.compare(it->path().stem().string()) == 0) { pathsToDelete.push_back(it->path()); } @@ -608,7 +608,7 @@ SHAMapStoreImp::minimumOnline() const { // minimumOnline_ with 0 value is equivalent to unknown/not set. // Don't attempt to acquire ledgers if that value is unknown. - if (deleteInterval_ && minimumOnline_) + if ((deleteInterval_ != 0u) && (minimumOnline_ != 0u)) return minimumOnline_.load(); return app_.getLedgerMaster().minSqlSeq(); } diff --git a/src/xrpld/app/misc/TxQ.h b/src/xrpld/app/misc/TxQ.h index 4f02d6d617..7c441867ea 100644 --- a/src/xrpld/app/misc/TxQ.h +++ b/src/xrpld/app/misc/TxQ.h @@ -693,12 +693,12 @@ private: }; // Helper function returns requiredFeeLevel. - FeeLevel64 + static FeeLevel64 getRequiredFeeLevel( OpenView& view, ApplyFlags flags, FeeMetrics::Snapshot const& metricsSnapshot, - std::lock_guard const& lock) const; + std::lock_guard const& lock); // Helper function for TxQ::apply. If a transaction's fee is high enough, // attempt to directly apply that transaction to the ledger. diff --git a/src/xrpld/app/misc/detail/AmendmentTable.cpp b/src/xrpld/app/misc/detail/AmendmentTable.cpp index 2b7005f4cc..7569fa13b5 100644 --- a/src/xrpld/app/misc/detail/AmendmentTable.cpp +++ b/src/xrpld/app/misc/detail/AmendmentTable.cpp @@ -675,7 +675,7 @@ AmendmentTableImpl::unVeto(uint256 const& amendment) std::lock_guard lock(mutex_); AmendmentState* const s = get(amendment, lock); - if (!s || s->vote != AmendmentVote::down) + if ((s == nullptr) || s->vote != AmendmentVote::down) return false; s->vote = AmendmentVote::up; persistVote(amendment, s->name, s->vote); @@ -707,7 +707,7 @@ AmendmentTableImpl::isEnabled(uint256 const& amendment) const { std::lock_guard lock(mutex_); AmendmentState const* s = get(amendment, lock); - return s && s->enabled; + return (s != nullptr) && s->enabled; } bool @@ -715,7 +715,7 @@ AmendmentTableImpl::isSupported(uint256 const& amendment) const { std::lock_guard lock(mutex_); AmendmentState const* s = get(amendment, lock); - return s && s->supported; + return (s != nullptr) && s->supported; } bool @@ -946,7 +946,7 @@ AmendmentTableImpl::injectJson( v[jss::count] = votesFor; v[jss::validations] = votesTotal; - if (votesNeeded) + if (votesNeeded != 0) v[jss::threshold] = votesNeeded; } } @@ -974,7 +974,7 @@ AmendmentTableImpl::getJson(uint256 const& amendmentID, bool isAdmin) const { std::lock_guard lock(mutex_); AmendmentState const* a = get(amendmentID, lock); - if (a) + if (a != nullptr) { Json::Value& jAmendment = (ret[to_string(amendmentID)] = Json::objectValue); injectJson(jAmendment, amendmentID, *a, isAdmin, lock); diff --git a/src/xrpld/app/misc/detail/Transaction.cpp b/src/xrpld/app/misc/detail/Transaction.cpp index 35b49504d5..6eefd08369 100644 --- a/src/xrpld/app/misc/detail/Transaction.cpp +++ b/src/xrpld/app/misc/detail/Transaction.cpp @@ -133,7 +133,7 @@ Transaction::getJson(JsonOptions options, bool binary) const Json::Value ret(mTransaction->getJson(options & ~JsonOptions::include_date, binary)); // NOTE Binary STTx::getJson output might not be a JSON object - if (ret.isObject() && mLedgerIndex) + if (ret.isObject() && (mLedgerIndex != 0u)) { if (!(options & JsonOptions::disable_API_prior_V2)) { diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index 020fa501d5..78e8ccdba5 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -121,7 +121,7 @@ TxQ::FeeMetrics::update( txnsExpected_ = std::min(next, maximumTxnCount_.value_or(next)); } - if (!size) + if (size == 0) { escalationMultiplier_ = setup.minimumEscalationMultiplier; } @@ -185,16 +185,16 @@ sumOfFirstSquares(std::size_t xIn) } // Unit tests for sumOfSquares() -static_assert(sumOfFirstSquares(1).first == true); +static_assert(sumOfFirstSquares(1).first); static_assert(sumOfFirstSquares(1).second == 1); -static_assert(sumOfFirstSquares(2).first == true); +static_assert(sumOfFirstSquares(2).first); static_assert(sumOfFirstSquares(2).second == 5); -static_assert(sumOfFirstSquares(0x1FFFFF).first == true, ""); +static_assert(sumOfFirstSquares(0x1FFFFF).first, ""); static_assert(sumOfFirstSquares(0x1FFFFF).second == 0x2AAAA8AAAAB00000ul, ""); -static_assert(sumOfFirstSquares(0x200000).first == false, ""); +static_assert(!sumOfFirstSquares(0x200000).first, ""); static_assert(sumOfFirstSquares(0x200000).second == std::numeric_limits::max(), ""); } // namespace detail @@ -308,10 +308,11 @@ TxQ::MaybeTx& TxQ::TxQAccount::add(MaybeTx&& txn) { auto const seqProx = txn.seqProxy; + [[maybe_unused]] auto const* txnPtr = &txn; auto result = transactions.emplace(seqProx, std::move(txn)); XRPL_ASSERT(result.second, "xrpl::TxQ::TxQAccount::add : emplace succeeded"); - XRPL_ASSERT(&result.first->second != &txn, "xrpl::TxQ::TxQAccount::add : transaction moved"); + XRPL_ASSERT(&result.first->second != txnPtr, "xrpl::TxQ::TxQAccount::add : transaction moved"); return result.first->second; } @@ -357,7 +358,7 @@ TxQ::canBeHeld( // queue yet, but should be added in the future. // tapFAIL_HARD transactions are never held if (tx.isFieldPresent(sfPreviousTxnID) || tx.isFieldPresent(sfAccountTxnID) || - (flags & tapFAIL_HARD)) + ((flags & tapFAIL_HARD) != 0u)) return telCAN_NOT_QUEUE; { @@ -1591,7 +1592,7 @@ TxQ::getRequiredFeeLevel( OpenView& view, ApplyFlags flags, FeeMetrics::Snapshot const& metricsSnapshot, - std::lock_guard const& lock) const + std::lock_guard const& lock) { return FeeMetrics::scaleFeeLevel(metricsSnapshot, view); } diff --git a/src/xrpld/app/misc/detail/ValidatorList.cpp b/src/xrpld/app/misc/detail/ValidatorList.cpp index 386b96387e..29c0e75c78 100644 --- a/src/xrpld/app/misc/detail/ValidatorList.cpp +++ b/src/xrpld/app/misc/detail/ValidatorList.cpp @@ -181,7 +181,7 @@ ValidatorList::load( { // Want truncated result when dividing an odd integer listThreshold_ = (publisherLists_.size() < 3) ? 1 // - : publisherLists_.size() / 2 + 1; + : (publisherLists_.size() / 2) + 1; JLOG(j_.debug()) << "Validator list threshold computed as " << listThreshold_; } @@ -699,11 +699,11 @@ ValidatorList::sendValidatorList( { messageVersion = 1; } - if (!messageVersion) + if (messageVersion == 0u) return; auto const [newPeerSequence, numVLs] = buildValidatorListMessages( messageVersion, peerSequence, maxSequence, rawVersion, rawManifest, blobInfos, messages); - if (newPeerSequence) + if (newPeerSequence != 0u) { XRPL_ASSERT( !messages.empty(), @@ -1256,7 +1256,7 @@ ValidatorList::loadLists() continue; auto size = file_size(fullPath, ec); - if (!ec && !size) + if (!ec && (size == 0u)) { // Treat an empty file as a missing file, because // nobody else is going to write it. @@ -1433,7 +1433,7 @@ bool ValidatorList::trustedPublisher(PublicKey const& identity) const { std::shared_lock read_lock{mutex_}; - return identity.size() && publisherLists_.contains(identity) && + return (identity.size() != 0u) && publisherLists_.contains(identity) && publisherLists_.at(identity).status < PublisherStatus::revoked; } @@ -1484,7 +1484,7 @@ ValidatorList::removePublisherList( std::size_t ValidatorList::count(ValidatorList::shared_lock const&) const { - return publisherLists_.size() + (!localPublisherList.list.empty()); + return publisherLists_.size() + static_cast(!localPublisherList.list.empty()); } std::size_t @@ -1649,7 +1649,7 @@ ValidatorList::getJson() const future.validFrom > timeKeeper_.now() + 600s, "xrpl::ValidatorList::getJson : minimum valid from"); } - if (remaining.size()) + if (remaining.size() != 0u) curr[jss::remaining] = std::move(remaining); } diff --git a/src/xrpld/app/paths/PathRequest.cpp b/src/xrpld/app/paths/PathRequest.cpp index f82a207552..0e895e66d4 100644 --- a/src/xrpld/app/paths/PathRequest.cpp +++ b/src/xrpld/app/paths/PathRequest.cpp @@ -191,7 +191,7 @@ PathRequest::isValid(std::shared_ptr const& crCache) } else { - bool const disallowXRP(sleDest->getFlags() & lsfDisallowXRP); + bool const disallowXRP((sleDest->getFlags() & lsfDisallowXRP) != 0u); auto usDestCurrID = accountDestCurrencies(*raDstAccount, crCache, !disallowXRP); @@ -609,7 +609,7 @@ PathRequest::findPaths( after four source currencies, 50 - (4 * 4) = 34. */ int const size = sourceCurrencies.size(); - consumer_.charge({std::clamp(size * size + 34, 50, 400), "path update"}); + consumer_.charge({std::clamp((size * size) + 34, 50, 400), "path update"}); return true; } diff --git a/src/xrpld/app/paths/Pathfinder.cpp b/src/xrpld/app/paths/Pathfinder.cpp index c777fcb2f7..10d69fc040 100644 --- a/src/xrpld/app/paths/Pathfinder.cpp +++ b/src/xrpld/app/paths/Pathfinder.cpp @@ -615,7 +615,7 @@ Pathfinder::getBestPaths( ++pathsIterator; auto iPathsLeft = maxPaths - bestPaths.size(); - if (!(iPathsLeft > 0 || fullLiquidityPath.empty())) + if (iPathsLeft <= 0 && !fullLiquidityPath.empty()) break; if (path.empty()) @@ -850,7 +850,7 @@ Pathfinder::isNoRipple( auto const flag((toAccount > fromAccount) ? lsfHighNoRipple : lsfLowNoRipple); - return sleRipple && (sleRipple->getFieldU32(sfFlags) & flag); + return sleRipple && ((sleRipple->getFieldU32(sfFlags) & flag) != 0u); } // Does this path end on an account-to-account link whose last account has @@ -864,7 +864,7 @@ Pathfinder::isNoRippleOut(STPath const& currentPath) // Last link must be an account. STPathElement const& endElement = currentPath.back(); - if (!(endElement.getNodeType() & STPathElement::typeAccount)) + if ((endElement.getNodeType() & STPathElement::typeAccount) == 0u) return false; // If there's only one item in the path, return true if that item specifies @@ -911,7 +911,7 @@ Pathfinder::addLink( << " completePaths size=" << mCompletePaths.size(); JLOG(j_.trace()) << currentPath.getJson(JsonOptions::none); - if (addFlags & afADD_ACCOUNTS) + if ((addFlags & afADD_ACCOUNTS) != 0u) { // add accounts if (bOnXRP) @@ -930,10 +930,10 @@ Pathfinder::addLink( if (sleEnd) { - bool const bRequireAuth(sleEnd->getFieldU32(sfFlags) & lsfRequireAuth); + bool const bRequireAuth((sleEnd->getFieldU32(sfFlags) & lsfRequireAuth) != 0u); bool const bIsEndCurrency(uEndCurrency == mDstAmount.getCurrency()); bool const bIsNoRippleOut(isNoRippleOut(currentPath)); - bool const bDestOnly(addFlags & afAC_LAST); + bool const bDestOnly((addFlags & afAC_LAST) != 0u); if (auto const lines = mRLCache->getRippleLines( uEndAccount, @@ -1012,7 +1012,7 @@ Pathfinder::addLink( bIsEndCurrency, mEffectiveDst, continueCallback); - if (out) + if (out != 0) candidates.push_back({out, acct}); } } @@ -1060,10 +1060,10 @@ Pathfinder::addLink( } } } - if (addFlags & afADD_BOOKS) + if ((addFlags & afADD_BOOKS) != 0u) { // add order books - if (addFlags & afOB_XRP) + if ((addFlags & afOB_XRP) != 0u) { // to XRP only if (!bOnXRP && app_.getOrderBookDB().isBookToXRP({uEndCurrency, uEndIssuer}, mDomain)) diff --git a/src/xrpld/app/paths/RippleLineCache.cpp b/src/xrpld/app/paths/RippleLineCache.cpp index ac3e28e579..c45c20aca8 100644 --- a/src/xrpld/app/paths/RippleLineCache.cpp +++ b/src/xrpld/app/paths/RippleLineCache.cpp @@ -84,7 +84,7 @@ RippleLineCache::getRippleLines(AccountID const& accountID, LineDirection direct } XRPL_ASSERT( - !it->second || (it->second->size() > 0), + !it->second || (!it->second->empty()), "xrpl::RippleLineCache::getRippleLines : null or nonempty lines"); auto const size = it->second ? it->second->size() : 0; JLOG(journal_.trace()) << "getRippleLines for ledger " << ledger_->header().seq << " found " diff --git a/src/xrpld/app/paths/detail/BookStep.cpp b/src/xrpld/app/paths/detail/BookStep.cpp index e0053956a8..df1e849b81 100644 --- a/src/xrpld/app/paths/detail/BookStep.cpp +++ b/src/xrpld/app/paths/detail/BookStep.cpp @@ -452,7 +452,7 @@ public: std::uint32_t getOfrInRate(Step const* prevStep, AccountID const& owner, std::uint32_t trIn) const { - auto const srcAcct = prevStep ? prevStep->directStepSrcAcct() : std::nullopt; + auto const srcAcct = (prevStep != nullptr) ? prevStep->directStepSrcAcct() : std::nullopt; return owner == srcAcct // If offer crossing && prevStep is DirectI ? QUALITY_ONE // && src is offer owner @@ -467,9 +467,9 @@ public: AccountID const& strandDst, std::uint32_t trOut) const { - return // If offer crossing - prevStep && prevStep->bookStepBook() && // && prevStep is BookStep - owner == strandDst // && dest is offer owner + return // If offer crossing + (prevStep != nullptr) && prevStep->bookStepBook() && // && prevStep is BookStep + owner == strandDst // && dest is offer owner ? QUALITY_ONE : trOut; // then rate = QUALITY_ONE } @@ -1260,13 +1260,14 @@ BookStep::check(StrandContext const& ctx) const // Do not allow two books to output the same issue. This may cause offers on // one step to unfund offers in another step. - if (!ctx.seenBookOuts.insert(book_.out).second || ctx.seenDirectIssues[0].count(book_.out)) + if (!ctx.seenBookOuts.insert(book_.out).second || + (ctx.seenDirectIssues[0].count(book_.out) != 0u)) { JLOG(j_.debug()) << "BookStep: loop detected: " << *this; return temBAD_PATH_LOOP; } - if (ctx.seenDirectIssues[1].count(book_.out)) + if (ctx.seenDirectIssues[1].count(book_.out) != 0u) { JLOG(j_.debug()) << "BookStep: loop detected: " << *this; return temBAD_PATH_LOOP; @@ -1282,7 +1283,7 @@ BookStep::check(StrandContext const& ctx) const return tecNO_ISSUER; } - if (ctx.prevStep) + if (ctx.prevStep != nullptr) { if (auto const prev = ctx.prevStep->directStepSrcAcct()) { @@ -1292,7 +1293,7 @@ BookStep::check(StrandContext const& ctx) const auto sle = view.read(keylet::line(*prev, cur, book_.in.currency)); if (!sle) return terNO_LINE; - if ((*sle)[sfFlags] & ((cur > *prev) ? lsfHighNoRipple : lsfLowNoRipple)) + if (((*sle)[sfFlags] & ((cur > *prev) ? lsfHighNoRipple : lsfLowNoRipple)) != 0u) return terNO_RIPPLE; } } diff --git a/src/xrpld/app/paths/detail/DirectStep.cpp b/src/xrpld/app/paths/detail/DirectStep.cpp index 0c8693eef4..d1d540eda5 100644 --- a/src/xrpld/app/paths/detail/DirectStep.cpp +++ b/src/xrpld/app/paths/detail/DirectStep.cpp @@ -224,15 +224,15 @@ public: using DirectStepI::check; - bool - verifyPrevStepDebtDirection(DebtDirection) const + static bool + verifyPrevStepDebtDirection(DebtDirection) { // A payment doesn't care whether or not prevStepRedeems. return true; } - bool - verifyDstQualityIn(std::uint32_t dstQIn) const + static bool + verifyDstQualityIn(std::uint32_t dstQIn) { // Payments have no particular expectations for what dstQIn will be. return true; @@ -275,8 +275,8 @@ public: using DirectStepI::check; - bool - verifyPrevStepDebtDirection(DebtDirection prevStepDir) const + static bool + verifyPrevStepDebtDirection(DebtDirection prevStepDir) { // During offer crossing we rely on the fact that prevStepRedeems // will *always* issue. That's because: @@ -288,16 +288,16 @@ public: return issues(prevStepDir); } - bool - verifyDstQualityIn(std::uint32_t dstQIn) const + static bool + verifyDstQualityIn(std::uint32_t dstQIn) { // Due to a couple of factors dstQIn is always QUALITY_ONE for // offer crossing. If that changes we need to know. return dstQIn == QUALITY_ONE; } - std::uint32_t - quality(ReadView const& sb, QualityDirection qDir) const; + static std::uint32_t + quality(ReadView const& sb, QualityDirection qDir); // Compute the maximum value that can flow from src->dst at // the best available quality. @@ -308,8 +308,8 @@ public: // Verify the consistency of the step. These checks are specific to // offer crossing and assume that general checks were already performed. - TER - check(StrandContext const& ctx, std::shared_ptr const& sleSrc) const; + static TER + check(StrandContext const& ctx, std::shared_ptr const& sleSrc); std::string logString() const override @@ -356,13 +356,13 @@ DirectIPaymentStep::quality(ReadView const& sb, QualityDirection qDir) const return QUALITY_ONE; auto const q = (*sle)[field]; - if (!q) + if (q == 0u) return QUALITY_ONE; return q; } std::uint32_t -DirectIOfferCrossingStep::quality(ReadView const&, QualityDirection qDir) const +DirectIOfferCrossingStep::quality(ReadView const&, QualityDirection qDir) { // If offer crossing then ignore trust line Quality fields. This // preserves a long-standing tradition. @@ -411,21 +411,21 @@ DirectIPaymentStep::check(StrandContext const& ctx, std::shared_ptr c auto const authField = (src_ > dst_) ? lsfHighAuth : lsfLowAuth; - if (((*sleSrc)[sfFlags] & lsfRequireAuth) && !((*sleLine)[sfFlags] & authField) && - (*sleLine)[sfBalance] == beast::zero) + if ((((*sleSrc)[sfFlags] & lsfRequireAuth) != 0u) && + (((*sleLine)[sfFlags] & authField) == 0u) && (*sleLine)[sfBalance] == beast::zero) { JLOG(j_.debug()) << "DirectStepI: can't receive IOUs from issuer without auth." << " src: " << src_; return terNO_AUTH; } - if (ctx.prevStep) + if (ctx.prevStep != nullptr) { if (ctx.prevStep->bookStepBook()) { auto const noRippleSrcToDst = ((*sleLine)[sfFlags] & ((src_ > dst_) ? lsfHighNoRipple : lsfLowNoRipple)); - if (noRippleSrcToDst) + if (noRippleSrcToDst != 0u) return terNO_RIPPLE; } } @@ -447,7 +447,7 @@ DirectIPaymentStep::check(StrandContext const& ctx, std::shared_ptr c } TER -DirectIOfferCrossingStep::check(StrandContext const&, std::shared_ptr const&) const +DirectIOfferCrossingStep::check(StrandContext const&, std::shared_ptr const&) { // The standard checks are all we can do because any remaining checks // require the existence of a trust line. Offer crossing does not @@ -714,7 +714,7 @@ template std::pair DirectStepI::qualitiesSrcRedeems(ReadView const& sb) const { - if (!prevStep_) + if (prevStep_ == nullptr) return {QUALITY_ONE, QUALITY_ONE}; auto const prevStepQIn = prevStep_->lineQualityIn(sb); @@ -829,7 +829,7 @@ DirectStepI::check(StrandContext const& ctx) const // If previous step was a direct step then we need to check // no ripple flags. - if (ctx.prevStep) + if (ctx.prevStep != nullptr) { if (auto prevSrc = ctx.prevStep->directStepSrcAcct()) { @@ -842,9 +842,9 @@ DirectStepI::check(StrandContext const& ctx) const Issue const srcIssue{currency_, src_}; Issue const dstIssue{currency_, dst_}; - if (ctx.seenBookOuts.count(srcIssue)) + if (ctx.seenBookOuts.count(srcIssue) != 0u) { - if (!ctx.prevStep) + if (ctx.prevStep == nullptr) { // LCOV_EXCL_START UNREACHABLE( @@ -905,7 +905,7 @@ make_DirectStepI( { TER ter = tefINTERNAL; std::unique_ptr r; - if (ctx.offerCrossing) + if (ctx.offerCrossing != 0u) { auto offerCrossingStep = std::make_unique(ctx, src, dst, c); ter = offerCrossingStep->check(ctx); diff --git a/src/xrpld/app/paths/detail/PaySteps.cpp b/src/xrpld/app/paths/detail/PaySteps.cpp index 9087647aeb..33b63f7714 100644 --- a/src/xrpld/app/paths/detail/PaySteps.cpp +++ b/src/xrpld/app/paths/detail/PaySteps.cpp @@ -55,8 +55,8 @@ toStep( { auto& j = ctx.j; - if (ctx.isFirst && e1->isAccount() && (e1->getNodeType() & STPathElement::typeCurrency) && - isXRP(e1->getCurrency())) + if (ctx.isFirst && e1->isAccount() && + ((e1->getNodeType() & STPathElement::typeCurrency) != 0u) && isXRP(e1->getCurrency())) { return make_XRPEndpointStep(ctx, e1->getAccountID()); } @@ -83,10 +83,12 @@ toStep( (e2->getNodeType() & STPathElement::typeCurrency) || (e2->getNodeType() & STPathElement::typeIssuer), "xrpl::toStep : currency or issuer"); - auto const outCurrency = - e2->getNodeType() & STPathElement::typeCurrency ? e2->getCurrency() : curIssue.currency; - auto const outIssuer = - e2->getNodeType() & STPathElement::typeIssuer ? e2->getIssuerID() : curIssue.account; + auto const outCurrency = ((e2->getNodeType() & STPathElement::typeCurrency) != 0u) + ? e2->getCurrency() + : curIssue.currency; + auto const outIssuer = ((e2->getNodeType() & STPathElement::typeIssuer) != 0u) + ? e2->getIssuerID() + : curIssue.account; if (isXRP(curIssue.currency) && isXRP(outCurrency)) { @@ -132,12 +134,12 @@ toStrand( { auto const t = pe.getNodeType(); - if ((t & ~STPathElement::typeAll) || !t) + if (((t & ~STPathElement::typeAll) != 0u) || (t == 0u)) return {temBAD_PATH, Strand{}}; - bool const hasAccount = t & STPathElement::typeAccount; - bool const hasIssuer = t & STPathElement::typeIssuer; - bool const hasCurrency = t & STPathElement::typeCurrency; + bool const hasAccount = (t & STPathElement::typeAccount) != 0u; + bool const hasIssuer = (t & STPathElement::typeIssuer) != 0u; + bool const hasCurrency = (t & STPathElement::typeCurrency) != 0u; if (hasAccount && (hasIssuer || hasCurrency)) return {temBAD_PATH, Strand{}}; @@ -192,7 +194,7 @@ toStrand( STPathElement const& lastCurrency = *std::find_if(normPath.rbegin(), normPath.rend(), hasCurrency); if ((lastCurrency.getCurrency() != deliver.currency) || - (offerCrossing && lastCurrency.getIssuerID() != deliver.account)) + ((offerCrossing != 0u) && lastCurrency.getIssuerID() != deliver.account)) { normPath.emplace_back(std::nullopt, deliver.currency, deliver.account); } diff --git a/src/xrpld/app/paths/detail/XRPEndpointStep.cpp b/src/xrpld/app/paths/detail/XRPEndpointStep.cpp index 620d901f22..8b1835069b 100644 --- a/src/xrpld/app/paths/detail/XRPEndpointStep.cpp +++ b/src/xrpld/app/paths/detail/XRPEndpointStep.cpp @@ -369,7 +369,7 @@ make_XRPEndpointStep(StrandContext const& ctx, AccountID const& acc) { TER ter = tefINTERNAL; std::unique_ptr r; - if (ctx.offerCrossing) + if (ctx.offerCrossing != 0u) { auto offerCrossingStep = std::make_unique(ctx, acc); ter = offerCrossingStep->check(ctx); diff --git a/src/xrpld/app/rdb/backend/detail/Node.cpp b/src/xrpld/app/rdb/backend/detail/Node.cpp index 09b4ebc241..317c4e77a1 100644 --- a/src/xrpld/app/rdb/backend/detail/Node.cpp +++ b/src/xrpld/app/rdb/backend/detail/Node.cpp @@ -674,13 +674,13 @@ transactionsSQL( std::string maxClause; std::string minClause; - if (options.maxLedger) + if (options.maxLedger != 0u) { maxClause = boost::str( boost::format("AND AccountTransactions.LedgerSeq <= '%u'") % options.maxLedger); } - if (options.minLedger) + if (options.minLedger != 0u) { minClause = boost::str( boost::format("AND AccountTransactions.LedgerSeq >= '%u'") % options.minLedger); diff --git a/src/xrpld/core/detail/Config.cpp b/src/xrpld/core/detail/Config.cpp index 52186ca9da..c7179c181b 100644 --- a/src/xrpld/core/detail/Config.cpp +++ b/src/xrpld/core/detail/Config.cpp @@ -204,13 +204,13 @@ getSingleSection( { auto const pmtEntries = getIniFileSection(secSource, strSection); - if (pmtEntries && pmtEntries->size() == 1) + if ((pmtEntries != nullptr) && pmtEntries->size() == 1) { strValue = (*pmtEntries)[0]; return true; } - if (pmtEntries) + if (pmtEntries != nullptr) { JLOG(j.warn()) << "Section '" << strSection << "': requires 1 line not " << pmtEntries->size() << " lines."; @@ -415,7 +415,7 @@ checkZeroPorts(Config const& config) if (optResult) { auto const port = beast::lexicalCast(*optResult); - if (!port) + if (port == 0u) { std::stringstream ss; ss << "Invalid value '" << *optResult << "' for key 'port' in [" << name << "]"; @@ -999,30 +999,30 @@ Config::loadFromString(std::string const& fileContents) auto entries = getIniFileSection(iniFile, SECTION_VALIDATORS); - if (entries) + if (entries != nullptr) section(SECTION_VALIDATORS).append(*entries); auto valKeyEntries = getIniFileSection(iniFile, SECTION_VALIDATOR_KEYS); - if (valKeyEntries) + if (valKeyEntries != nullptr) section(SECTION_VALIDATOR_KEYS).append(*valKeyEntries); auto valSiteEntries = getIniFileSection(iniFile, SECTION_VALIDATOR_LIST_SITES); - if (valSiteEntries) + if (valSiteEntries != nullptr) section(SECTION_VALIDATOR_LIST_SITES).append(*valSiteEntries); auto valListKeys = getIniFileSection(iniFile, SECTION_VALIDATOR_LIST_KEYS); - if (valListKeys) + if (valListKeys != nullptr) section(SECTION_VALIDATOR_LIST_KEYS).append(*valListKeys); auto valListThreshold = getIniFileSection(iniFile, SECTION_VALIDATOR_LIST_THRESHOLD); - if (valListThreshold) + if (valListThreshold != nullptr) section(SECTION_VALIDATOR_LIST_THRESHOLD).append(*valListThreshold); - if (!entries && !valKeyEntries && !valListKeys) + if ((entries == nullptr) && (valKeyEntries == nullptr) && (valListKeys == nullptr)) { Throw( "The file specified in [" SECTION_VALIDATORS_FILE @@ -1315,7 +1315,7 @@ setup_DatabaseCon(Config const& c, std::optional j) if (page_size < 512 || page_size > 65536) Throw("Invalid page_size. Must be between 512 and 65536."); - if (page_size & (page_size - 1)) + if ((page_size & (page_size - 1)) != 0) Throw("Invalid page_size. Must be a power of 2."); } diff --git a/src/xrpld/overlay/Message.h b/src/xrpld/overlay/Message.h index 30650d384c..df59656ac2 100644 --- a/src/xrpld/overlay/Message.h +++ b/src/xrpld/overlay/Message.h @@ -91,7 +91,7 @@ private: * currently LZ4 only. If None then the message is uncompressed. * @param uncompressedBytes Size of the uncompressed message */ - void + static void setHeader( std::uint8_t* in, std::uint32_t payloadBytes, @@ -112,8 +112,8 @@ private: * @param in Payload header pointer * @return Message type */ - int - getType(std::uint8_t const* in) const; + static int + getType(std::uint8_t const* in); }; } // namespace xrpl diff --git a/src/xrpld/overlay/detail/Message.cpp b/src/xrpld/overlay/detail/Message.cpp index 754545f04a..4d043500c7 100644 --- a/src/xrpld/overlay/detail/Message.cpp +++ b/src/xrpld/overlay/detail/Message.cpp @@ -103,6 +103,7 @@ Message::compress() if (compressedSize < (messageBytes - (headerBytesCompressed - headerBytes))) { bufferCompressed_.resize(headerBytesCompressed + compressedSize); + // NOLINTNEXTLINE(readability-suspicious-call-argument) setHeader(bufferCompressed_.data(), compressedSize, type, Algorithm::LZ4, messageBytes); } else @@ -199,7 +200,7 @@ Message::getBuffer(Compressed tryCompressed) } int -Message::getType(std::uint8_t const* in) const +Message::getType(std::uint8_t const* in) { int type = (static_cast(*(in + 4)) << 8) + *(in + 5); return type; diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index d9077686ec..57eddd8b2c 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -810,19 +810,19 @@ OverlayImpl::processCrawl(http_request_type const& req, Handoff& handoff) msg.insert("Connection", "close"); msg.body()["version"] = Json::Value(2u); - if (setup_.crawlOptions & CrawlOptions::Overlay) + if ((setup_.crawlOptions & CrawlOptions::Overlay) != 0u) { msg.body()["overlay"] = getOverlayInfo(); } - if (setup_.crawlOptions & CrawlOptions::ServerInfo) + if ((setup_.crawlOptions & CrawlOptions::ServerInfo) != 0u) { msg.body()["server"] = getServerInfo(); } - if (setup_.crawlOptions & CrawlOptions::ServerCounts) + if ((setup_.crawlOptions & CrawlOptions::ServerCounts) != 0u) { msg.body()["counts"] = getServerCounts(); } - if (setup_.crawlOptions & CrawlOptions::Unl) + if ((setup_.crawlOptions & CrawlOptions::Unl) != 0u) { msg.body()["unl"] = getUnlInfo(); } @@ -1222,7 +1222,7 @@ OverlayImpl::relay( // relay to all disabled and some randomly selected enabled that // do not have the transaction. auto const enabledTarget = app_.config().TX_REDUCE_RELAY_MIN_PEERS + - (total - minRelay) * app_.config().TX_RELAY_PERCENTAGE / 100; + ((total - minRelay) * app_.config().TX_RELAY_PERCENTAGE / 100); txMetrics_.addMetrics(enabledTarget, toSkip.size(), disabled); diff --git a/src/xrpld/overlay/detail/OverlayImpl.h b/src/xrpld/overlay/detail/OverlayImpl.h index b77b4e69aa..c816f24e0c 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.h +++ b/src/xrpld/overlay/detail/OverlayImpl.h @@ -429,7 +429,7 @@ private: http_request_type const& request, address_type remote_address); - std::shared_ptr + static std::shared_ptr makeErrorResponse( std::shared_ptr const& slot, http_request_type const& request, diff --git a/src/xrpld/overlay/detail/PeerImp.cpp b/src/xrpld/overlay/detail/PeerImp.cpp index 7ed8c45453..767e8bfd20 100644 --- a/src/xrpld/overlay/detail/PeerImp.cpp +++ b/src/xrpld/overlay/detail/PeerImp.cpp @@ -1509,7 +1509,7 @@ PeerImp::onMessage(std::shared_ptr const& m) } } else if ( - !m->has_ledgerhash() && !m->has_ledgerseq() && !(ltype && *ltype == protocol::ltCLOSED)) + !m->has_ledgerhash() && !m->has_ledgerseq() && (!ltype || *ltype != protocol::ltCLOSED)) { badData("Invalid request"); return; @@ -3376,7 +3376,7 @@ PeerImp::processLedgerRequest(std::shared_ptr const& m) } } - if (!map) + if (map == nullptr) { JLOG(p_journal_.warn()) << "processLedgerRequest: Unable to find map"; return; diff --git a/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp b/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp index cc74018fc0..4de03c6ca6 100644 --- a/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp +++ b/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp @@ -78,7 +78,7 @@ Config::makeConfig( // Servers with peer privacy don't want to allow incoming connections config.wantIncoming = (!config.peerPrivate) && (port != 0); - if (!cfg.PEERS_OUT_MAX && !cfg.PEERS_IN_MAX) + if ((cfg.PEERS_OUT_MAX == 0u) && (cfg.PEERS_IN_MAX == 0u)) { if (cfg.PEERS_MAX != 0) config.maxPeers = cfg.PEERS_MAX; diff --git a/src/xrpld/perflog/detail/PerfLogImp.cpp b/src/xrpld/perflog/detail/PerfLogImp.cpp index fc9ef70830..960fdcb3ac 100644 --- a/src/xrpld/perflog/detail/PerfLogImp.cpp +++ b/src/xrpld/perflog/detail/PerfLogImp.cpp @@ -70,8 +70,8 @@ PerfLogImp::Counters::countersJson() const Rpc value; { std::lock_guard lock(proc.second.mutex); - if (!proc.second.value.started && !proc.second.value.finished && - !proc.second.value.errored) + if ((proc.second.value.started == 0u) && (proc.second.value.finished == 0u) && + (proc.second.value.errored == 0u)) { continue; } @@ -90,7 +90,7 @@ PerfLogImp::Counters::countersJson() const rpcobj[proc.first] = p; } - if (totalRpc.started) + if (totalRpc.started != 0u) { Json::Value totalRpcJson(Json::objectValue); totalRpcJson[jss::started] = std::to_string(totalRpc.started); @@ -108,8 +108,8 @@ PerfLogImp::Counters::countersJson() const Jq value; { std::lock_guard lock(proc.second.mutex); - if (!proc.second.value.queued && !proc.second.value.started && - !proc.second.value.finished) + if ((proc.second.value.queued == 0u) && (proc.second.value.started == 0u) && + (proc.second.value.finished == 0u)) { continue; } @@ -130,7 +130,7 @@ PerfLogImp::Counters::countersJson() const jobQueueObj[JobTypes::name(proc.first)] = j; } - if (totalJq.queued) + if (totalJq.queued != 0u) { Json::Value totalJqJson(Json::objectValue); totalJqJson[jss::queued] = std::to_string(totalJq.queued); diff --git a/src/xrpld/rpc/detail/DeliveredAmount.cpp b/src/xrpld/rpc/detail/DeliveredAmount.cpp index 3e89edc1f9..e2f5bd8cd9 100644 --- a/src/xrpld/rpc/detail/DeliveredAmount.cpp +++ b/src/xrpld/rpc/detail/DeliveredAmount.cpp @@ -71,13 +71,8 @@ canHaveDeliveredAmount( TxType const tt{serializedTx->getTxnType()}; // Transaction type should be ttPAYMENT, ttACCOUNT_DELETE or ttCHECK_CASH // and if the transaction failed nothing could have been delivered. - if ((tt == ttPAYMENT || tt == ttCHECK_CASH || tt == ttACCOUNT_DELETE) && - transactionMeta.getResultTER() == tesSUCCESS) - { - return true; - } - - return false; + return (tt == ttPAYMENT || tt == ttCHECK_CASH || tt == ttACCOUNT_DELETE) && + transactionMeta.getResultTER() == tesSUCCESS; } void diff --git a/src/xrpld/rpc/detail/Handler.cpp b/src/xrpld/rpc/detail/Handler.cpp index 04cf0420b7..0f95e69d3f 100644 --- a/src/xrpld/rpc/detail/Handler.cpp +++ b/src/xrpld/rpc/detail/Handler.cpp @@ -150,7 +150,7 @@ private: // Use with equal_range to enforce that API range of a newly added handler // does not overlap with API range of an existing handler with same name - [[nodiscard]] bool + [[nodiscard]] static bool overlappingApiVersion( std::pair range, unsigned minVer, diff --git a/src/xrpld/rpc/detail/RPCCall.cpp b/src/xrpld/rpc/detail/RPCCall.cpp index cd36208294..c9d5d67cf3 100644 --- a/src/xrpld/rpc/detail/RPCCall.cpp +++ b/src/xrpld/rpc/detail/RPCCall.cpp @@ -149,6 +149,7 @@ private: using parseFuncPtr = Json::Value (RPCParser::*)(Json::Value const& jvParams); Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseAsIs(Json::Value const& jvParams) { Json::Value v(Json::objectValue); @@ -160,6 +161,7 @@ private: } Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseInternal(Json::Value const& jvParams) { Json::Value v(Json::objectValue); @@ -176,6 +178,7 @@ private: } Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseManifest(Json::Value const& jvParams) { if (jvParams.size() == 1) @@ -196,6 +199,7 @@ private: // fetch_info [clear] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseFetchInfo(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -286,6 +290,7 @@ private: // // Mnemonic: taker pays --> offer --> taker gets Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseBookOffers(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -335,7 +340,7 @@ private: try { int bProof = jvParams[5u].asInt(); - if (bProof) + if (bProof != 0) jvRequest[jss::proof] = true; } catch (std::exception const&) @@ -352,11 +357,12 @@ private: // can_delete [||now|always|never] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseCanDelete(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); - if (!jvParams.size()) + if (jvParams.size() == 0u) return jvRequest; std::string input = jvParams[0u].asString(); @@ -374,6 +380,7 @@ private: // connect [port] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseConnect(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -402,6 +409,7 @@ private: // deposit_authorized // [ [, ...]] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseDepositAuthorized(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -424,6 +432,7 @@ private: // Return an error for attempting to subscribe/unsubscribe via RPC. Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseEvented(Json::Value const& jvParams) { return rpcError(rpcNO_EVENTS); @@ -431,6 +440,7 @@ private: // feature [] [accept|reject] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseFeature(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -464,11 +474,12 @@ private: // get_counts [] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseGetCounts(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); - if (jvParams.size()) + if (jvParams.size() != 0u) jvRequest[jss::min_count] = jvParams[0u].asUInt(); return jvRequest; @@ -477,6 +488,7 @@ private: // sign_for offline // sign_for Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseSignFor(Json::Value const& jvParams) { bool const bOffline = 4 == jvParams.size() && jvParams[3u].asString() == "offline"; @@ -546,11 +558,9 @@ private: jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] == "2.0" && jv.isMember(jss::id) && jv.isMember(jss::method)) { - if (jv.isMember(jss::params) && - !(jv[jss::params].isNull() || jv[jss::params].isArray() || - jv[jss::params].isObject())) - return false; - return true; + return !jv.isMember(jss::params) || + (jv[jss::params].isNull() || jv[jss::params].isArray() || + jv[jss::params].isObject()); } } return false; @@ -608,11 +618,12 @@ private: // ledger [id|index|current|closed|validated] [full|tx] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseLedger(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); - if (!jvParams.size()) + if (jvParams.size() == 0u) { return jvRequest; } @@ -637,6 +648,7 @@ private: // ledger_header | Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseLedgerId(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -657,6 +669,7 @@ private: // ledger_entry [id] [] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseLedgerEntry(Json::Value const& jvParams) { Json::Value jvRequest{Json::objectValue}; @@ -674,6 +687,7 @@ private: // specified severity log_level : Set specified // partition to specified severity Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseLogLevel(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -722,6 +736,7 @@ private: // channel_authorize: [] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseChannelAuthorize(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -765,6 +780,7 @@ private: // channel_verify Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseChannelVerify(Json::Value const& jvParams) { std::string const strPk = jvParams[0u].asString(); @@ -793,6 +809,7 @@ private: } Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseAccountRaw2(Json::Value const& jvParams, char const* const acc2Field) { std::array accFields{{jss::account, acc2Field}}; @@ -830,6 +847,7 @@ private: // TODO: Get index from an alternate syntax: rXYZ: Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseAccountRaw1(Json::Value const& jvParams) { std::string strIdent = jvParams[0u].asString(); @@ -850,6 +868,7 @@ private: } Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseVault(Json::Value const& jvParams) { std::string strVaultID = jvParams[0u].asString(); @@ -868,6 +887,7 @@ private: // peer_reservations_add [] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parsePeerReservationsAdd(Json::Value const& jvParams) { Json::Value jvRequest; @@ -881,6 +901,7 @@ private: // peer_reservations_del Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parsePeerReservationsDel(Json::Value const& jvParams) { Json::Value jvRequest; @@ -916,6 +937,7 @@ private: // simulate [binary] // simulate [binary] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseSimulate(Json::Value const& jvParams) { Json::Value txJSON; @@ -947,6 +969,7 @@ private: // submit // submit Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseSignSubmit(Json::Value const& jvParams) { Json::Value txJSON; @@ -996,6 +1019,7 @@ private: // // submit_multisigned Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseSubmitMultiSigned(Json::Value const& jvParams) { if (1 == jvParams.size()) @@ -1015,6 +1039,7 @@ private: // transaction_entry Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseTransactionEntry(Json::Value const& jvParams) { // Parameter count should have already been verified. @@ -1040,6 +1065,7 @@ private: // tx Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseTx(Json::Value const& jvParams) { Json::Value jvRequest{Json::objectValue}; @@ -1072,6 +1098,7 @@ private: // tx_history Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseTxHistory(Json::Value const& jvParams) { Json::Value jvRequest{Json::objectValue}; @@ -1088,11 +1115,12 @@ private: // (e.g. .bash_history) and it may be leaked via the process status command // (i.e. ps). Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseValidationCreate(Json::Value const& jvParams) { Json::Value jvRequest{Json::objectValue}; - if (jvParams.size()) + if (jvParams.size() != 0u) jvRequest[jss::secret] = jvParams[0u].asString(); return jvRequest; @@ -1102,11 +1130,12 @@ private: // is only for testing. Master seeds should only be generated // randomly. Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseWalletPropose(Json::Value const& jvParams) { Json::Value jvRequest{Json::objectValue}; - if (jvParams.size()) + if (jvParams.size() != 0u) jvRequest[jss::passphrase] = jvParams[0u].asString(); return jvRequest; @@ -1117,6 +1146,7 @@ private: // ]] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseGatewayBalances(Json::Value const& jvParams) { unsigned int index = 0; @@ -1159,6 +1189,7 @@ private: // server_definitions [hash] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseServerDefinitions(Json::Value const& jvParams) { Json::Value jvRequest{Json::objectValue}; @@ -1173,6 +1204,7 @@ private: // server_info [counters] Json::Value + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) parseServerInfo(Json::Value const& jvParams) { Json::Value jvRequest(Json::objectValue); @@ -1542,8 +1574,8 @@ rpcClient( return jvRequest[jss::method].asString(); return jvRequest.isArray() ? "batch" : args[0]; }(), - jvParams, // Parsed, execute. - setup.client.secure != 0, // Use SSL + jvParams, // Parsed, execute. + static_cast(setup.client.secure) != 0, // Use SSL config.quiet(), logs, std::bind(RPCCallImp::callRPCHandler, &jvOutput, std::placeholders::_1), diff --git a/src/xrpld/rpc/detail/RPCHandler.cpp b/src/xrpld/rpc/detail/RPCHandler.cpp index 840ebd5946..eea24ab0c0 100644 --- a/src/xrpld/rpc/detail/RPCHandler.cpp +++ b/src/xrpld/rpc/detail/RPCHandler.cpp @@ -137,7 +137,7 @@ fillHandler(JsonContext& context, Handler const*& result) JLOG(context.j.trace()) << "REQUEST:" << context.params; auto handler = getHandler(context.apiVersion, context.app.config().BETA_RPC_API, strCommand); - if (!handler) + if (handler == nullptr) return rpcUNKNOWN_COMMAND; if (handler->role_ == Role::ADMIN && context.role != Role::ADMIN) @@ -228,7 +228,7 @@ roleRequired(unsigned int version, bool betaEnabled, std::string const& method) { auto handler = RPC::getHandler(version, betaEnabled, method); - if (!handler) + if (handler == nullptr) return Role::FORBID; return handler->role_; diff --git a/src/xrpld/rpc/detail/RPCHelpers.cpp b/src/xrpld/rpc/detail/RPCHelpers.cpp index 832ff778e1..dd363c6d76 100644 --- a/src/xrpld/rpc/detail/RPCHelpers.cpp +++ b/src/xrpld/rpc/detail/RPCHelpers.cpp @@ -100,7 +100,7 @@ readLimitField(unsigned int& limit, Tuning::LimitRange const& range, JsonContext return std::nullopt; auto const& jvLimit = context.params[jss::limit]; - if (!(jvLimit.isUInt() || (jvLimit.isInt() && jvLimit.asInt() >= 0))) + if (!jvLimit.isUInt() && (!jvLimit.isInt() || jvLimit.asInt() < 0)) return RPC::expected_field_error(jss::limit, "unsigned integer"); limit = jvLimit.asUInt(); diff --git a/src/xrpld/rpc/detail/RPCLedgerHelpers.cpp b/src/xrpld/rpc/detail/RPCLedgerHelpers.cpp index 54ff515894..0136d8af18 100644 --- a/src/xrpld/rpc/detail/RPCLedgerHelpers.cpp +++ b/src/xrpld/rpc/detail/RPCLedgerHelpers.cpp @@ -375,7 +375,7 @@ getOrAcquireLedger(RPC::JsonContext const& context) auto& ledgerMaster = context.app.getLedgerMaster(); LedgerHash ledgerHash; - if ((hasHash + hasIndex) != 1) + if ((static_cast(hasHash) + static_cast(hasIndex)) != 1) { return Unexpected( RPC::make_param_error( diff --git a/src/xrpld/rpc/detail/ServerHandler.cpp b/src/xrpld/rpc/detail/ServerHandler.cpp index f5187d6285..917a9b7609 100644 --- a/src/xrpld/rpc/detail/ServerHandler.cpp +++ b/src/xrpld/rpc/detail/ServerHandler.cpp @@ -126,14 +126,14 @@ ServerHandler::setup(Setup const& setup, beast::Journal journal) if (auto it = endpoints_.find(port.name); it != endpoints_.end()) { auto const endpointPort = it->second.port(); - if (!port.port) + if (port.port == 0u) port.port = endpointPort; - if (!setup_.client.port && + if ((setup_.client.port == 0u) && (port.protocol.count("http") > 0 || port.protocol.count("https") > 0)) setup_.client.port = endpointPort; - if (!setup_.overlay.port() && (port.protocol.count("peer") > 0)) + if ((setup_.overlay.port() == 0u) && (port.protocol.count("peer") > 0)) setup_.overlay.port(endpointPort); } } @@ -163,7 +163,7 @@ ServerHandler::onAccept(Session& session, boost::asio::ip::tcp::endpoint endpoin return ++count_[port]; }(); - if (port.limit && c >= port.limit) + if ((port.limit != 0) && c >= port.limit) { JLOG(m_journal.trace()) << port.name << " is full; dropping " << endpoint; return false; @@ -1135,7 +1135,7 @@ parse_Ports(Config const& config, std::ostream& log) // Remove the peer protocol, and if that would // leave the port empty, remove the port as well - if (p.erase("peer") && p.empty()) + if ((p.erase("peer") != 0u) && p.empty()) { it = result.erase(it); } diff --git a/src/xrpld/rpc/detail/TransactionSign.cpp b/src/xrpld/rpc/detail/TransactionSign.cpp index 80c608dbbf..73385f62ef 100644 --- a/src/xrpld/rpc/detail/TransactionSign.cpp +++ b/src/xrpld/rpc/detail/TransactionSign.cpp @@ -79,7 +79,7 @@ public: AccountID const& getSigner() const { - if (!multiSigningAcctID_) + if (multiSigningAcctID_ == nullptr) LogicError("Accessing unknown SigningForParams::getSigner()"); return *multiSigningAcctID_; } @@ -207,7 +207,7 @@ checkPayment( if (!dstAccountID) return RPC::invalid_field_error("tx_json.Destination"); - if (params.isMember(jss::build_path) && ((doPath == false) || amount.holds())) + if (params.isMember(jss::build_path) && ((!doPath) || amount.holds())) { return RPC::make_error( rpcINVALID_PARAMS, "Field 'build_path' not allowed in this context."); @@ -428,7 +428,7 @@ transactionPreProcessImpl( : nullptr; if (signatureTarget) { - if (!signatureTemplate) + if (signatureTemplate == nullptr) { // Invalid target field return RPC::make_error(rpcINVALID_PARAMS, signatureTarget->get().getName()); } diff --git a/src/xrpld/rpc/handlers/AccountInfo.cpp b/src/xrpld/rpc/handlers/AccountInfo.cpp index 15a6786e22..55f05ddcab 100644 --- a/src/xrpld/rpc/handlers/AccountInfo.cpp +++ b/src/xrpld/rpc/handlers/AccountInfo.cpp @@ -290,9 +290,9 @@ doAccountInfo(RPC::JsonContext& context) jvQueueTx.append(std::move(jvTx)); } - if (seqCount) + if (seqCount != 0u) jvQueueData[jss::sequence_count] = seqCount; - if (ticketCount) + if (ticketCount != 0u) jvQueueData[jss::ticket_count] = ticketCount; if (lowestSeq) jvQueueData[jss::lowest_sequence] = *lowestSeq; diff --git a/src/xrpld/rpc/handlers/CanDelete.cpp b/src/xrpld/rpc/handlers/CanDelete.cpp index 91466c2583..052ebdf745 100644 --- a/src/xrpld/rpc/handlers/CanDelete.cpp +++ b/src/xrpld/rpc/handlers/CanDelete.cpp @@ -49,7 +49,7 @@ doCanDelete(RPC::JsonContext& context) else if (canDeleteStr == "now") { canDeleteSeq = context.app.getSHAMapStore().getLastRotated(); - if (!canDeleteSeq) + if (canDeleteSeq == 0u) return RPC::make_error(rpcNOT_READY); } else if (uint256 lh; lh.parseHex(canDeleteStr)) diff --git a/src/xrpld/rpc/handlers/DepositAuthorized.cpp b/src/xrpld/rpc/handlers/DepositAuthorized.cpp index 080b136964..b2fc13415e 100644 --- a/src/xrpld/rpc/handlers/DepositAuthorized.cpp +++ b/src/xrpld/rpc/handlers/DepositAuthorized.cpp @@ -73,7 +73,7 @@ doDepositAuthorized(RPC::JsonContext& context) return result; } - bool const reqAuth = (sleDest->getFlags() & lsfDepositAuth) && (srcAcct != dstAcct); + bool const reqAuth = ((sleDest->getFlags() & lsfDepositAuth) != 0u) && (srcAcct != dstAcct); bool const credentialsPresent = params.isMember(jss::credentials); std::set> sorted; @@ -122,7 +122,7 @@ doDepositAuthorized(RPC::JsonContext& context) return result; } - if (!(sleCred->getFlags() & lsfAccepted)) + if ((sleCred->getFlags() & lsfAccepted) == 0u) { RPC::inject_error(rpcBAD_CREDENTIALS, "credentials aren't accepted", result); return result; diff --git a/src/xrpld/rpc/handlers/GetAggregatePrice.cpp b/src/xrpld/rpc/handlers/GetAggregatePrice.cpp index cf327258a3..4979c21f42 100644 --- a/src/xrpld/rpc/handlers/GetAggregatePrice.cpp +++ b/src/xrpld/rpc/handlers/GetAggregatePrice.cpp @@ -56,7 +56,7 @@ iteratePriceData( if (prevChain == chain) return; - if (!oracle || f(*oracle) || isNew) + if ((oracle == nullptr) || f(*oracle) || isNew) return; if (++history > maxHistory) diff --git a/src/xrpld/rpc/handlers/LedgerHandler.cpp b/src/xrpld/rpc/handlers/LedgerHandler.cpp index 43c9780bb0..cd70cb064a 100644 --- a/src/xrpld/rpc/handlers/LedgerHandler.cpp +++ b/src/xrpld/rpc/handlers/LedgerHandler.cpp @@ -103,7 +103,7 @@ LedgerHandler::writeResult(Json::Value& value) "and update your request. Field `type` is deprecated."; } - if (warnings.size()) + if (warnings.size() != 0u) value[jss::warnings] = std::move(warnings); } diff --git a/src/xrpld/rpc/handlers/NoRippleCheck.cpp b/src/xrpld/rpc/handlers/NoRippleCheck.cpp index 73f51fca1a..a0f797214d 100644 --- a/src/xrpld/rpc/handlers/NoRippleCheck.cpp +++ b/src/xrpld/rpc/handlers/NoRippleCheck.cpp @@ -107,16 +107,16 @@ doNoRippleCheck(RPC::JsonContext& context) Json::Value& problems = (result["problems"] = Json::arrayValue); - bool bDefaultRipple = sle->getFieldU32(sfFlags) & lsfDefaultRipple; + bool bDefaultRipple = (sle->getFieldU32(sfFlags) & lsfDefaultRipple) != 0u; - if (bDefaultRipple & !roleGateway) + if ((static_cast(bDefaultRipple) & static_cast(!roleGateway)) != 0) { problems.append( "You appear to have set your default ripple flag even though you " "are not a gateway. This is not recommended unless you are " "experimenting"); } - else if (roleGateway & !bDefaultRipple) + else if ((static_cast(roleGateway) & static_cast(!bDefaultRipple)) != 0) { problems.append("You should immediately set your default ripple flag"); if (transactions) diff --git a/src/xrpld/rpc/handlers/ServerDefinitions.cpp b/src/xrpld/rpc/handlers/ServerDefinitions.cpp index 24abd69a02..e4f08d6dec 100644 --- a/src/xrpld/rpc/handlers/ServerDefinitions.cpp +++ b/src/xrpld/rpc/handlers/ServerDefinitions.cpp @@ -24,7 +24,7 @@ namespace detail { class ServerDefinitions { private: - std::string + static std::string // translate e.g. STI_LEDGERENTRY to LedgerEntry translate(std::string const& inp); From f7bb4018fa4b6ecff199dd85718d9f6659b798a3 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 24 Mar 2026 11:53:49 -0700 Subject: [PATCH 06/10] fix: Assorted Vault fixes (#6607) --- src/libxrpl/ledger/View.cpp | 3 +-- src/libxrpl/ledger/helpers/VaultHelpers.cpp | 2 +- src/libxrpl/tx/transactors/vault/VaultDelete.cpp | 6 ++---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index ef6a66744d..227eafbec8 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -433,8 +433,7 @@ doWithdraw( j) < amount) { // LCOV_EXCL_START - JLOG(j.error()) << "LoanBrokerCoverWithdraw: negative balance of " - "broker cover assets."; + JLOG(j.error()) << "doWithdraw: negative balance of broker cover assets."; return tefINTERNAL; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/ledger/helpers/VaultHelpers.cpp b/src/libxrpl/ledger/helpers/VaultHelpers.cpp index 3ded720289..83a1b9fc4f 100644 --- a/src/libxrpl/ledger/helpers/VaultHelpers.cpp +++ b/src/libxrpl/ledger/helpers/VaultHelpers.cpp @@ -92,7 +92,7 @@ sharesToAssetsWithdraw( std::shared_ptr const& issuance, STAmount const& shares) { - XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); + XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsWithdraw : non-negative shares"); XRPL_ASSERT( shares.asset() == vault->at(sfShareMPTID), "xrpl::sharesToAssetsWithdraw : shares and vault match"); diff --git a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp index 1e2e46e165..5a60c0032c 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp @@ -55,7 +55,7 @@ VaultDelete::preclaim(PreclaimContext const& ctx) if (!sleMPT) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDeposit: missing issuance of vault shares."; + JLOG(ctx.j.error()) << "VaultDelete: missing issuance of vault shares."; return tecOBJECT_NOT_FOUND; // LCOV_EXCL_STOP } @@ -63,7 +63,7 @@ VaultDelete::preclaim(PreclaimContext const& ctx) if (sleMPT->at(sfIssuer) != vault->getAccountID(sfAccount)) { // LCOV_EXCL_START - JLOG(ctx.j.error()) << "VaultDeposit: invalid owner of vault shares."; + JLOG(ctx.j.error()) << "VaultDelete: invalid owner of vault shares."; return tecNO_PERMISSION; // LCOV_EXCL_STOP } @@ -200,8 +200,6 @@ VaultDelete::doApply() // Destroy the vault. view().erase(vault); - associateAsset(*vault, asset); - return tesSUCCESS; } From 85a4015a64b1c6246dbc44d7b828227f4f8b3f76 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 24 Mar 2026 11:53:57 -0700 Subject: [PATCH 07/10] fix: Assorted Permissioned Domain fixes (#6587) --- .../transactors/permissioned_domain/PermissionedDomainSet.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp index e8df51c9d9..30f24241aa 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp @@ -100,8 +100,6 @@ PermissionedDomainSet::doApply() Keylet const pdKeylet = keylet::permissionedDomain(account_, ctx_.tx.getFieldU32(sfSequence)); auto slePd = std::make_shared(pdKeylet); - if (!slePd) - return tefINTERNAL; // LCOV_EXCL_LINE slePd->setAccountID(sfOwner, account_); slePd->setFieldU32(sfSequence, ctx_.tx.getFieldU32(sfSequence)); From dda162087ff7bc3c88365739b4aee2cfd7b9b9c8 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Tue, 24 Mar 2026 21:18:03 +0000 Subject: [PATCH 08/10] docs: Add note about `clang-tidy` installation (#6634) --- CONTRIBUTING.md | 13 +++++++++++-- docs/build/environment.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 86bef765a5..8670b79db9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -259,6 +259,10 @@ There is a Continuous Integration job that runs clang-tidy on pull requests. The This ensures that configuration changes don't introduce new warnings across the codebase. +### Installing clang-tidy + +See the [environment setup guide](./docs/build/environment.md#clang-tidy) for platform-specific installation instructions. + ### Running clang-tidy locally Before running clang-tidy, you must build the project to generate required files (particularly protobuf headers). Refer to [`BUILD.md`](./BUILD.md) for build instructions. @@ -266,10 +270,15 @@ Before running clang-tidy, you must build the project to generate required files Then run clang-tidy on your local changes: ``` -run-clang-tidy -p build src tests +run-clang-tidy -p build src include tests ``` -This will check all source files in the `src` and `tests` directories using the compile commands from your `build` directory. +This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory. +If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix` to the above command: + +``` +run-clang-tidy -p build -fix src include tests +``` ## Contracts and instrumentation diff --git a/docs/build/environment.md b/docs/build/environment.md index c67877a082..66bed06c26 100644 --- a/docs/build/environment.md +++ b/docs/build/environment.md @@ -109,3 +109,32 @@ Install CMake with Homebrew too: ``` brew install cmake ``` + +## Clang-tidy + +Clang-tidy is required to run static analysis checks locally (see [CONTRIBUTING.md](../../CONTRIBUTING.md)). +It is not required to build the project. Currently this project uses clang-tidy version 21. + +### Linux + +LLVM 21 is not available in the default Debian 12 (Bookworm) repositories. +Install it using the official LLVM apt installer: + +``` +wget https://apt.llvm.org/llvm.sh +chmod +x llvm.sh +sudo ./llvm.sh 21 +sudo apt install --yes clang-tidy-21 +``` + +Then use `run-clang-tidy-21` when running clang-tidy locally. + +### macOS + +Install LLVM 21 via Homebrew: + +``` +brew install llvm@21 +``` + +Then use `run-clang-tidy` from the LLVM 21 Homebrew prefix when running clang-tidy locally. From 4096623ae163d6e1ef23795726b62cf220a80abb Mon Sep 17 00:00:00 2001 From: Jingchen Date: Tue, 24 Mar 2026 23:00:41 +0000 Subject: [PATCH 09/10] chore: Remove the forward declarations that cause build errors when unity build is enabled (#6633) Signed-off-by: JCW --- src/libxrpl/ledger/helpers/MPTokenHelpers.cpp | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp index cbf37a06a8..31c1d543f5 100644 --- a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp @@ -1,6 +1,7 @@ #include // #include +#include #include #include #include @@ -12,21 +13,6 @@ namespace xrpl { -// Forward declarations for functions that remain in View.h/cpp -bool -isVaultPseudoAccountFrozen( - ReadView const& view, - AccountID const& account, - MPTIssue const& mptShare, - int depth); - -[[nodiscard]] TER -dirLink( - ApplyView& view, - AccountID const& owner, - std::shared_ptr& object, - SF_UINT64 const& node = sfOwnerNode); - bool isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue) { @@ -83,7 +69,7 @@ transferRate(ReadView const& view, MPTID const& issuanceID) // which represents 50% of 1,000,000,000 if (auto const sle = view.read(keylet::mptIssuance(issuanceID)); sle && sle->isFieldPresent(sfTransferFee)) - return Rate{1'000'000'000u + 10'000 * sle->getFieldU16(sfTransferFee)}; + return Rate{1'000'000'000u + (10'000 * sle->getFieldU16(sfTransferFee))}; return parityRate; } @@ -149,7 +135,7 @@ authorizeMPToken( // When a holder wants to unauthorize/delete a MPT, the ledger must // - delete mptokenKey from owner directory // - delete the MPToken - if (flags & tfMPTUnauthorize) + if ((flags & tfMPTUnauthorize) != 0) { auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); auto const sleMpt = view.peek(mptokenKey); @@ -229,7 +215,7 @@ authorizeMPToken( // Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on // their MPToken - if (flags & tfMPTUnauthorize) + if ((flags & tfMPTUnauthorize) != 0) { flagsOut &= ~lsfMPTAuthorized; } @@ -490,7 +476,7 @@ canTransfer( if (!sleIssuance) return tecOBJECT_NOT_FOUND; - if (!(sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer)) + if (!sleIssuance->isFlag(lsfMPTCanTransfer)) { if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer]) return TER{tecNO_AUTH}; From 589c9c694ce2a7669c5bcac76e8f4de4c62e76ad Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Tue, 24 Mar 2026 23:18:41 +0000 Subject: [PATCH 10/10] chore: Update external dependencies due to upstream merge (#6630) --- conan.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/conan.lock b/conan.lock index 900d3526e1..291258441f 100644 --- a/conan.lock +++ b/conan.lock @@ -6,11 +6,11 @@ "sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926", "soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46", "snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878", - "secp256k1/0.7.1#3a61e95e220062ef32c48d019e9c81f7%1770306721.686", + "secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329", "rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86", - "re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103", + "re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1772560729.95", "protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038", - "openssl/3.5.5#05a4ac5b7323f7a329b2db1391d9941f%1769599205.414", + "openssl/3.5.5#e6399de266349245a4542fc5f6c71552%1774367199.56", "nudb/2.0.9#0432758a24204da08fee953ec9ea03cb%1769436073.32", "lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914", "libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492", @@ -18,27 +18,27 @@ "libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736", "jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244", "gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152", - "grpc/1.72.0#f244a57bff01e708c55a1100b12e1589%1765850193.734", + "grpc/1.72.0#500d27f2cbb105a0ffb708e64a0f1781%1774369626.679", "ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772", "date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772", "c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1765850144.336", "bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837", "boost/1.90.0#d5e8defe7355494953be18524a7f135b%1769454080.269", - "abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993" + "abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196" ], "build_requires": [ "zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075", "strawberryperl/5.32.1.1#707032463aa0620fa17ec0d887f5fe41%1765850165.196", "protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038", "nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707", - "msys2/cci.latest#eea83308ad7e9023f7318c60d5a9e6cb%1770199879.083", - "m4/1.4.19#70dc8bbb33e981d119d2acc0175cf381%1763158052.846", + "msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649", + "m4/1.4.19#5d7a4994e5875d76faf7acf3ed056036%1774365463.87", "cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1765850153.937", "cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479", "b2/5.3.3#107c15377719889654eb9a162a673975%1765850144.355", "automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56", "autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86", - "abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993" + "abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196" ], "python_requires": [], "overrides": { @@ -46,7 +46,7 @@ null, "boost/1.90.0" ], - "protobuf/5.27.0": [ + "protobuf/[>=5.27.0 <7]": [ "protobuf/6.32.1" ], "lz4/1.9.4": [