Merge remote-tracking branch 'origin/develop' into tapanito/lending-fix-amendment

# Conflicts:
#	include/xrpl/ledger/helpers/LendingHelpers.h
#	include/xrpl/protocol/STAmount.h
#	include/xrpl/protocol/detail/features.macro
#	include/xrpl/protocol/detail/transactions.macro
#	src/libxrpl/tx/invariants/VaultInvariant.cpp
#	src/test/app/Invariants_test.cpp
#	src/test/app/LoanBroker_test.cpp
#	src/test/app/Loan_test.cpp
#	src/test/app/Vault_test.cpp
This commit is contained in:
Vito
2026-06-08 11:28:35 +02:00
1813 changed files with 135635 additions and 75703 deletions

View File

@@ -2,27 +2,27 @@
#include <xrpl/basics/Number.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
namespace xrpl {
std::uint16_t constexpr TRADING_FEE_THRESHOLD = 1000; // 1%
constexpr std::uint16_t kTradingFeeThreshold = 1000; // 1%
// Auction slot
std::uint32_t constexpr TOTAL_TIME_SLOT_SECS = 24 * 3600;
std::uint16_t constexpr AUCTION_SLOT_TIME_INTERVALS = 20;
std::uint16_t constexpr AUCTION_SLOT_MAX_AUTH_ACCOUNTS = 4;
std::uint32_t constexpr AUCTION_SLOT_FEE_SCALE_FACTOR = 100000;
std::uint32_t constexpr AUCTION_SLOT_DISCOUNTED_FEE_FRACTION = 10;
std::uint32_t constexpr AUCTION_SLOT_MIN_FEE_FRACTION = 25;
std::uint32_t constexpr AUCTION_SLOT_INTERVAL_DURATION =
TOTAL_TIME_SLOT_SECS / AUCTION_SLOT_TIME_INTERVALS;
constexpr std::uint32_t kTotalTimeSlotSecs = 24 * 3600;
constexpr std::uint16_t kAuctionSlotTimeIntervals = 20;
constexpr std::uint16_t kAuctionSlotMaxAuthAccounts = 4;
constexpr std::uint32_t kAuctionSlotFeeScaleFactor = 100000;
constexpr std::uint32_t kAuctionSlotDiscountedFeeFraction = 10;
constexpr std::uint32_t kAuctionSlotMinFeeFraction = 25;
constexpr std::uint32_t kAuctionSlotIntervalDuration =
kTotalTimeSlotSecs / kAuctionSlotTimeIntervals;
// Votes
std::uint16_t constexpr VOTE_MAX_SLOTS = 8;
std::uint32_t constexpr VOTE_WEIGHT_SCALE_FACTOR = 100000;
constexpr std::uint16_t kVoteMaxSlots = 8;
constexpr std::uint32_t kVoteWeightScaleFactor = 100000;
class STObject;
class STAmount;
@@ -31,12 +31,12 @@ class Rules;
/** Calculate Liquidity Provider Token (LPT) Currency.
*/
Currency
ammLPTCurrency(Currency const& cur1, Currency const& cur2);
ammLPTCurrency(Asset const& asset1, Asset const& asset2);
/** Calculate LPT Issue from AMM asset pair.
*/
Issue
ammLPTIssue(Currency const& cur1, Currency const& cur2, AccountID const& ammAccountID);
ammLPTIssue(Asset const& asset1, Asset const& asset2, AccountID const& ammAccountID);
/** Validate the amount.
* If validZero is false and amount is beast::zero then invalid amount.
@@ -46,19 +46,19 @@ ammLPTIssue(Currency const& cur1, Currency const& cur2, AccountID const& ammAcco
NotTEC
invalidAMMAmount(
STAmount const& amount,
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt,
bool validZero = false);
NotTEC
invalidAMMAsset(
Issue const& issue,
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
Asset const& asset,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);
NotTEC
invalidAMMAssetPair(
Issue const& issue1,
Issue const& issue2,
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
Asset const& asset1,
Asset const& asset2,
std::optional<std::pair<Asset, Asset>> const& pair = std::nullopt);
/** Get time slot of the auction slot.
*/
@@ -77,7 +77,7 @@ ammEnabled(Rules const&);
inline Number
getFee(std::uint16_t tfee)
{
return Number{tfee} / AUCTION_SLOT_FEE_SCALE_FACTOR;
return Number{tfee} / kAuctionSlotFeeScaleFactor;
}
/** Get fee multiplier (1 - tfee)

View File

@@ -2,7 +2,7 @@
#include <xrpl/protocol/tokens.h>
// VFALCO Uncomment when the header issues are resolved
// #include <ripple/protocol/PublicKey.h>
// #include <xrpl/protocol/PublicKey.h>
#include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/json/json_value.h>
@@ -25,7 +25,7 @@ public:
} // namespace detail
/** A 160-bit unsigned that uniquely identifies an account. */
using AccountID = base_uint<160, detail::AccountIDTag>;
using AccountID = BaseUInt<160, detail::AccountIDTag>;
/** Convert AccountID to base58 checked string */
std::string
@@ -63,13 +63,13 @@ noAccount();
*/
// DEPRECATED
bool
to_issuer(AccountID&, std::string const&);
toIssuer(AccountID&, std::string const&);
// DEPRECATED Should be checking the currency or native flag
inline bool
isXRP(AccountID const& c)
{
return c == beast::zero;
return c == beast::kZero;
}
// DEPRECATED
@@ -105,10 +105,10 @@ initAccountIdCache(std::size_t count);
} // namespace xrpl
//------------------------------------------------------------------------------
namespace Json {
namespace json {
template <>
inline xrpl::AccountID
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
@@ -117,7 +117,7 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
return *r;
Throw<JsonTypeMismatchError>(field.getJsonName(), "AccountID");
}
} // namespace Json
} // namespace json
//------------------------------------------------------------------------------

View File

@@ -1,6 +1,7 @@
#pragma once
#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/XRPAmount.h>
@@ -9,11 +10,12 @@
namespace xrpl {
inline STAmount
toSTAmount(IOUAmount const& iou, Issue const& iss)
toSTAmount(IOUAmount const& iou, Asset const& asset)
{
XRPL_ASSERT(asset.holds<Issue>(), "xrpl::toSTAmount : is Issue");
bool const isNeg = iou.signum() < 0;
std::uint64_t const umant = isNeg ? -iou.mantissa() : iou.mantissa();
return STAmount(iss, umant, iou.exponent(), isNeg, STAmount::unchecked());
return STAmount(asset, umant, iou.exponent(), isNeg, STAmount::Unchecked());
}
inline STAmount
@@ -31,12 +33,25 @@ toSTAmount(XRPAmount const& xrp)
}
inline STAmount
toSTAmount(XRPAmount const& xrp, Issue const& iss)
toSTAmount(XRPAmount const& xrp, Asset const& asset)
{
XRPL_ASSERT(isXRP(iss.account) && isXRP(iss.currency), "xrpl::toSTAmount : is XRP");
XRPL_ASSERT(isXRP(asset), "xrpl::toSTAmount : is XRP");
return toSTAmount(xrp);
}
inline STAmount
toSTAmount(MPTAmount const& mpt)
{
return STAmount(mpt, noMPT());
}
inline STAmount
toSTAmount(MPTAmount const& mpt, Asset const& asset)
{
XRPL_ASSERT(asset.holds<MPTIssue>(), "xrpl::toSTAmount : is MPT");
return STAmount(mpt, asset.get<MPTIssue>());
}
template <class T>
T
toAmount(STAmount const& amt) = delete;
@@ -76,6 +91,21 @@ toAmount<XRPAmount>(STAmount const& amt)
return XRPAmount(sMant);
}
template <>
inline MPTAmount
toAmount<MPTAmount>(STAmount const& amt)
{
XRPL_ASSERT(
amt.holds<MPTIssue>() && amt.mantissa() <= kMaxMpTokenAmount && amt.exponent() == 0,
"xrpl::toAmount<MPTAmount> : maximum mantissa");
if (amt.mantissa() > kMaxMpTokenAmount || amt.exponent() != 0)
Throw<std::runtime_error>("toAmount<MPTAmount>: invalid mantissa or exponent");
bool const isNeg = amt.negative();
std::int64_t const sMant = isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
return MPTAmount(sMant);
}
template <class T>
T
toAmount(IOUAmount const& amt) = delete;
@@ -98,72 +128,113 @@ toAmount<XRPAmount>(XRPAmount const& amt)
return amt;
}
template <class T>
T
toAmount(MPTAmount const& amt) = delete;
template <>
inline MPTAmount
toAmount<MPTAmount>(MPTAmount const& amt)
{
return amt;
}
template <typename T>
T
toAmount(Issue const& issue, Number const& n, Number::rounding_mode mode = Number::getround())
toAmount(Asset const& asset, Number const& n, Number::RoundingMode mode = Number::getround())
{
saveNumberRoundMode rm(Number::getround());
if (isXRP(issue))
SaveNumberRoundMode const rm(Number::getround());
if (isXRP(asset))
Number::setround(mode);
if constexpr (std::is_same_v<IOUAmount, T>)
{
return IOUAmount(n);
}
else if constexpr (std::is_same_v<XRPAmount, T>)
{
return XRPAmount(static_cast<std::int64_t>(n));
}
else if constexpr (std::is_same_v<MPTAmount, T>)
{
return MPTAmount(static_cast<std::int64_t>(n));
}
else if constexpr (std::is_same_v<STAmount, T>)
{
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(n));
return STAmount(issue, n);
if (isXRP(asset))
return STAmount(asset, static_cast<std::int64_t>(n));
return STAmount(asset, n);
}
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
static_assert(alwaysFalse, "Unsupported type for toAmount");
static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for toAmount");
}
}
template <typename T>
T
toMaxAmount(Issue const& issue)
toMaxAmount(Asset const& asset)
{
if constexpr (std::is_same_v<IOUAmount, T>)
return IOUAmount(STAmount::cMaxValue, STAmount::cMaxOffset);
{
return IOUAmount(STAmount::kMaxValue, STAmount::kMaxOffset);
}
else if constexpr (std::is_same_v<XRPAmount, T>)
return XRPAmount(static_cast<std::int64_t>(STAmount::cMaxNativeN));
{
return XRPAmount(static_cast<std::int64_t>(STAmount::kMaxNativeN));
}
else if constexpr (std::is_same_v<MPTAmount, T>)
{
return MPTAmount(kMaxMpTokenAmount);
}
else if constexpr (std::is_same_v<STAmount, T>)
{
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(STAmount::cMaxNativeN));
return STAmount(issue, STAmount::cMaxValue, STAmount::cMaxOffset);
return asset.visit(
[](Issue const& issue) {
if (isXRP(issue))
return STAmount(issue, static_cast<std::int64_t>(STAmount::kMaxNativeN));
return STAmount(issue, STAmount::kMaxValue, STAmount::kMaxOffset);
},
[](MPTIssue const& issue) { return STAmount(issue, kMaxMpTokenAmount); });
}
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
static_assert(alwaysFalse, "Unsupported type for toMaxAmount");
static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for toMaxAmount");
}
}
inline STAmount
toSTAmount(Issue const& issue, Number const& n, Number::rounding_mode mode = Number::getround())
toSTAmount(Asset const& asset, Number const& n, Number::RoundingMode mode = Number::getround())
{
return toAmount<STAmount>(issue, n, mode);
return toAmount<STAmount>(asset, n, mode);
}
template <typename T>
Issue
getIssue(T const& amt)
Asset
getAsset(T const& amt)
{
if constexpr (std::is_same_v<IOUAmount, T>)
{
return noIssue();
}
else if constexpr (std::is_same_v<XRPAmount, T>)
{
return xrpIssue();
}
else if constexpr (std::is_same_v<MPTAmount, T>)
{
return noMPT();
}
else if constexpr (std::is_same_v<STAmount, T>)
return amt.issue();
{
return amt.asset();
}
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
static_assert(alwaysFalse, "Unsupported type for getIssue");
static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for getIssue");
}
}
@@ -172,15 +243,25 @@ constexpr T
get(STAmount const& a)
{
if constexpr (std::is_same_v<IOUAmount, T>)
{
return a.iou();
}
else if constexpr (std::is_same_v<XRPAmount, T>)
{
return a.xrp();
}
else if constexpr (std::is_same_v<MPTAmount, T>)
{
return a.mpt();
}
else if constexpr (std::is_same_v<STAmount, T>)
{
return a;
}
else
{
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
static_assert(alwaysFalse, "Unsupported type for get");
constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
static_assert(kAlwaysFalse, "Unsupported type for get");
}
}

View File

@@ -35,49 +35,49 @@ namespace xrpl {
namespace RPC {
template <unsigned int Version>
constexpr static std::integral_constant<unsigned, Version> apiVersion = {};
static constexpr std::integral_constant<unsigned, Version> kApiVersion = {};
constexpr static auto apiInvalidVersion = apiVersion<0>;
constexpr static auto apiMinimumSupportedVersion = apiVersion<1>;
constexpr static auto apiMaximumSupportedVersion = apiVersion<2>;
constexpr static auto apiVersionIfUnspecified = apiVersion<1>;
constexpr static auto apiCommandLineVersion = apiVersion<1>; // TODO Bump to 2 later
constexpr static auto apiBetaVersion = apiVersion<3>;
constexpr static auto apiMaximumValidVersion = apiBetaVersion;
static constexpr auto kApiInvalidVersion = kApiVersion<0>;
static constexpr auto kApiMinimumSupportedVersion = kApiVersion<1>;
static constexpr auto kApiMaximumSupportedVersion = kApiVersion<2>;
static constexpr auto kApiVersionIfUnspecified = kApiVersion<1>;
static constexpr auto kApiCommandLineVersion = kApiVersion<1>; // TODO Bump to 2 later
static constexpr auto kApiBetaVersion = kApiVersion<3>;
static constexpr auto kApiMaximumValidVersion = kApiBetaVersion;
static_assert(apiInvalidVersion < apiMinimumSupportedVersion);
static_assert(kApiInvalidVersion < kApiMinimumSupportedVersion);
static_assert(
apiVersionIfUnspecified >= apiMinimumSupportedVersion &&
apiVersionIfUnspecified <= apiMaximumSupportedVersion);
kApiVersionIfUnspecified >= kApiMinimumSupportedVersion &&
kApiVersionIfUnspecified <= kApiMaximumSupportedVersion);
static_assert(
apiCommandLineVersion >= apiMinimumSupportedVersion &&
apiCommandLineVersion <= apiMaximumSupportedVersion);
static_assert(apiMaximumSupportedVersion >= apiMinimumSupportedVersion);
static_assert(apiBetaVersion >= apiMaximumSupportedVersion);
static_assert(apiMaximumValidVersion >= apiMaximumSupportedVersion);
kApiCommandLineVersion >= kApiMinimumSupportedVersion &&
kApiCommandLineVersion <= kApiMaximumSupportedVersion);
static_assert(kApiMaximumSupportedVersion >= kApiMinimumSupportedVersion);
static_assert(kApiBetaVersion >= kApiMaximumSupportedVersion);
static_assert(kApiMaximumValidVersion >= kApiMaximumSupportedVersion);
inline void
setVersion(Json::Value& parent, unsigned int apiVersion, bool betaEnabled)
setVersion(json::Value& parent, unsigned int apiVersion, bool betaEnabled)
{
XRPL_ASSERT(apiVersion != apiInvalidVersion, "xrpl::RPC::setVersion : input is valid");
XRPL_ASSERT(apiVersion != kApiInvalidVersion, "xrpl::RPC::setVersion : input is valid");
auto& retObj = parent[jss::version] = Json::objectValue;
auto& retObj = parent[jss::version] = json::ValueType::Object;
if (apiVersion == apiVersionIfUnspecified)
if (apiVersion == kApiVersionIfUnspecified)
{
// API version numbers used in API version 1
static beast::SemanticVersion const firstVersion{"1.0.0"};
static beast::SemanticVersion const goodVersion{"1.0.0"};
static beast::SemanticVersion const lastVersion{"1.0.0"};
static beast::SemanticVersion const kFirstVersion{"1.0.0"};
static beast::SemanticVersion const kGoodVersion{"1.0.0"};
static beast::SemanticVersion const kLastVersion{"1.0.0"};
retObj[jss::first] = firstVersion.print();
retObj[jss::good] = goodVersion.print();
retObj[jss::last] = lastVersion.print();
retObj[jss::first] = kFirstVersion.print();
retObj[jss::good] = kGoodVersion.print();
retObj[jss::last] = kLastVersion.print();
}
else
{
retObj[jss::first] = apiMinimumSupportedVersion.value;
retObj[jss::last] = betaEnabled ? apiBetaVersion : apiMaximumSupportedVersion;
retObj[jss::first] = kApiMinimumSupportedVersion.value;
retObj[jss::last] = betaEnabled ? kApiBetaVersion : kApiMaximumSupportedVersion;
}
}
@@ -96,11 +96,11 @@ setVersion(Json::Value& parent, unsigned int apiVersion, bool betaEnabled)
* @return the api version number
*/
inline unsigned int
getAPIVersionNumber(Json::Value const& jv, bool betaEnabled)
getAPIVersionNumber(json::Value const& jv, bool betaEnabled)
{
static Json::Value const minVersion(RPC::apiMinimumSupportedVersion);
Json::Value const maxVersion(
betaEnabled ? RPC::apiBetaVersion : RPC::apiMaximumSupportedVersion);
static json::Value const kMinVersion(RPC::kApiMinimumSupportedVersion);
json::Value const maxVersion(
betaEnabled ? RPC::kApiBetaVersion : RPC::kApiMaximumSupportedVersion);
if (jv.isObject())
{
@@ -109,50 +109,52 @@ getAPIVersionNumber(Json::Value const& jv, bool betaEnabled)
auto const specifiedVersion = jv[jss::api_version];
if (!specifiedVersion.isInt() && !specifiedVersion.isUInt())
{
return RPC::apiInvalidVersion;
return RPC::kApiInvalidVersion;
}
auto const specifiedVersionInt = specifiedVersion.asInt();
if (specifiedVersionInt < minVersion || specifiedVersionInt > maxVersion)
if (specifiedVersionInt < kMinVersion || specifiedVersionInt > maxVersion)
{
return RPC::apiInvalidVersion;
return RPC::kApiInvalidVersion;
}
return specifiedVersionInt;
}
}
return RPC::apiVersionIfUnspecified;
return RPC::kApiVersionIfUnspecified;
}
} // namespace RPC
template <unsigned minVer, unsigned maxVer, typename Fn, typename... Args>
template <unsigned MinVer, unsigned MaxVer, typename Fn, typename... Args>
void
forApiVersions(Fn const& fn, Args&&... args)
requires //
(maxVer >= minVer) && //
(minVer >= RPC::apiMinimumSupportedVersion) && //
(RPC::apiMaximumValidVersion >= maxVer) && requires {
fn(std::integral_constant<unsigned int, minVer>{}, std::forward<Args>(args)...);
fn(std::integral_constant<unsigned int, maxVer>{}, std::forward<Args>(args)...);
requires //
(MaxVer >= MinVer) && //
(MinVer >= RPC::kApiMinimumSupportedVersion) && //
(RPC::kApiMaximumValidVersion >= MaxVer) && requires {
fn(std::integral_constant<unsigned int, MinVer>{}, std::forward<Args>(args)...);
fn(std::integral_constant<unsigned int, MaxVer>{}, std::forward<Args>(args)...);
}
{
constexpr auto size = maxVer + 1 - minVer;
[&]<std::size_t... offset>(std::index_sequence<offset...>) {
static constexpr auto kSize = MaxVer + 1 - MinVer;
[&]<std::size_t... Offset>(std::index_sequence<Offset...>) {
// NOLINTBEGIN(bugprone-use-after-move)
(((void)fn(
std::integral_constant<unsigned int, minVer + offset>{}, std::forward<Args>(args)...)),
std::integral_constant<unsigned int, MinVer + Offset>{}, std::forward<Args>(args)...)),
...);
}(std::make_index_sequence<size>{});
// NOLINTEND(bugprone-use-after-move)
}(std::make_index_sequence<kSize>{});
}
template <typename Fn, typename... Args>
void
forAllApiVersions(Fn const& fn, Args&&... args)
requires requires {
forApiVersions<RPC::apiMinimumSupportedVersion, RPC::apiMaximumValidVersion>(
forApiVersions<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>(
fn, std::forward<Args>(args)...);
}
{
forApiVersions<RPC::apiMinimumSupportedVersion, RPC::apiMaximumValidVersion>(
forApiVersions<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>(
fn, std::forward<Args>(args)...);
}

View File

@@ -2,20 +2,37 @@
#include <xrpl/basics/Number.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/Concepts.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/Rules.h>
namespace xrpl {
class Asset;
class STAmount;
template <typename TIss>
concept ValidIssueType = std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;
template <typename T>
requires(
std::is_same_v<T, XRPAmount> || std::is_same_v<T, IOUAmount> ||
std::is_same_v<T, MPTAmount>)
struct AmountType
{
using amount_type = T;
};
template <typename A>
concept AssetType = std::is_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
/* Used to check for an asset with either badCurrency()
* or MPT with 0 account.
*/
struct BadAsset
{
};
inline BadAsset const&
badAsset()
{
static BadAsset const kA;
return kA;
}
/* Asset is an abstraction of three different issue types: XRP, IOU, MPT.
* For historical reasons, two issue types XRP and IOU are wrapped in Issue
@@ -26,6 +43,9 @@ class Asset
{
public:
using value_type = std::variant<Issue, MPTIssue>;
using token_type = std::variant<Currency, MPTID>;
using AmtType =
std::variant<AmountType<XRPAmount>, AmountType<IOUAmount>, AmountType<MPTAmount>>;
private:
value_type issue_;
@@ -48,7 +68,7 @@ public:
{
}
AccountID const&
[[nodiscard]] AccountID const&
getIssuer() const;
template <ValidIssueType TIss>
@@ -60,45 +80,51 @@ public:
get();
template <ValidIssueType TIss>
constexpr bool
[[nodiscard]] constexpr bool
holds() const;
std::string
[[nodiscard]] std::string
getText() const;
constexpr value_type const&
[[nodiscard]] constexpr value_type const&
value() const;
[[nodiscard]] constexpr token_type
token() const;
void
setJson(Json::Value& jv) const;
setJson(json::Value& jv) const;
STAmount
operator()(Number const&) const;
bool
native() const
[[nodiscard]] constexpr AmtType
getAmountType() const;
// Custom, generic visit implementation
template <typename... Visitors>
constexpr auto
visit(Visitors&&... visitors) const -> decltype(auto)
{
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) {
if constexpr (std::is_same_v<TIss, Issue>)
return issue.native();
if constexpr (std::is_same_v<TIss, MPTIssue>)
return false;
},
issue_);
// Simple delegation to the reusable utility, passing the internal
// variant data.
return detail::visit(issue_, std::forward<Visitors>(visitors)...);
}
bool
[[nodiscard]] constexpr bool
native() const
{
return visit(
[&](Issue const& issue) { return issue.native(); },
[&](MPTIssue const&) { return false; });
}
[[nodiscard]] bool
integral() const
{
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) {
if constexpr (std::is_same_v<TIss, Issue>)
return issue.native();
if constexpr (std::is_same_v<TIss, MPTIssue>)
return true;
},
issue_);
return visit(
[&](Issue const& issue) { return issue.native(); },
[&](MPTIssue const&) { return true; });
}
friend constexpr bool
@@ -110,6 +136,10 @@ public:
friend constexpr bool
operator==(Currency const& lhs, Asset const& rhs);
// rhs is either badCurrency() or MPT issuer is 0
friend constexpr bool
operator==(BadAsset const& lhs, Asset const& rhs);
/** Return true if both assets refer to the same currency (regardless of
* issuer) or MPT issuance. Otherwise return false.
*/
@@ -117,10 +147,16 @@ public:
equalTokens(Asset const& lhs, Asset const& rhs);
};
inline Json::Value
to_json(Asset const& asset)
template <ValidIssueType TIss>
constexpr bool kIsIssueV = std::is_same_v<TIss, Issue>;
template <ValidIssueType TIss>
constexpr bool kIsMptissueV = std::is_same_v<TIss, MPTIssue>;
inline json::Value
toJson(Asset const& asset)
{
Json::Value jv;
json::Value jv;
asset.setJson(jv);
return jv;
}
@@ -133,7 +169,7 @@ Asset::holds() const
}
template <ValidIssueType TIss>
constexpr TIss const&
[[nodiscard]] constexpr TIss const&
Asset::get() const
{
if (!std::holds_alternative<TIss>(issue_))
@@ -156,15 +192,42 @@ Asset::value() const
return issue_;
}
constexpr Asset::token_type
Asset::token() const
{
return visit(
[&](Issue const& issue) -> Asset::token_type { return issue.currency; },
[&](MPTIssue const& issue) -> Asset::token_type { return issue.getMptID(); });
}
constexpr Asset::AmtType
Asset::getAmountType() const
{
return visit(
[&](Issue const& issue) -> Asset::AmtType {
constexpr AmountType<XRPAmount> kXRP;
constexpr AmountType<IOUAmount> kIOU;
return native() ? AmtType(kXRP) : AmtType(kIOU);
},
[&](MPTIssue const& issue) -> Asset::AmtType {
constexpr AmountType<MPTAmount> kMPT;
return AmtType(kMPT);
});
}
constexpr bool
operator==(Asset const& lhs, Asset const& rhs)
{
return std::visit(
[&]<typename TLhs, typename TRhs>(TLhs const& issLhs, TRhs const& issRhs) {
if constexpr (std::is_same_v<TLhs, TRhs>)
{
return issLhs == issRhs;
}
else
{
return false;
}
},
lhs.issue_,
rhs.issue_);
@@ -174,13 +237,19 @@ constexpr std::weak_ordering
operator<=>(Asset const& lhs, Asset const& rhs)
{
return std::visit(
[]<ValidIssueType TLhs, ValidIssueType TRhs>(TLhs const& lhs_, TRhs const& rhs_) {
[]<ValidIssueType TLhs, ValidIssueType TRhs>(TLhs const& lhs, TRhs const& rhs) {
if constexpr (std::is_same_v<TLhs, TRhs>)
return std::weak_ordering(lhs_ <=> rhs_);
else if constexpr (std::is_same_v<TLhs, Issue> && std::is_same_v<TRhs, MPTIssue>)
{
return std::weak_ordering(lhs <=> rhs);
}
else if constexpr (kIsIssueV<TLhs> && kIsMptissueV<TRhs>)
{
return std::weak_ordering::greater;
}
else
{
return std::weak_ordering::less;
}
},
lhs.issue_,
rhs.issue_);
@@ -189,7 +258,17 @@ operator<=>(Asset const& lhs, Asset const& rhs)
constexpr bool
operator==(Currency const& lhs, Asset const& rhs)
{
return rhs.holds<Issue>() && rhs.get<Issue>().currency == lhs;
return rhs.visit(
[&](Issue const& issue) { return issue.currency == lhs; },
[](MPTIssue const& issue) { return false; });
}
constexpr bool
operator==(BadAsset const&, Asset const& rhs)
{
return rhs.visit(
[](Issue const& issue) -> bool { return badCurrency() == issue.currency; },
[](MPTIssue const& issue) -> bool { return issue.getIssuer() == xrpAccount(); });
}
constexpr bool
@@ -198,11 +277,17 @@ equalTokens(Asset const& lhs, Asset const& rhs)
return std::visit(
[&]<typename TLhs, typename TRhs>(TLhs const& issLhs, TRhs const& issRhs) {
if constexpr (std::is_same_v<TLhs, Issue> && std::is_same_v<TRhs, Issue>)
{
return issLhs.currency == issRhs.currency;
}
else if constexpr (std::is_same_v<TLhs, MPTIssue> && std::is_same_v<TRhs, MPTIssue>)
{
return issLhs.getMptID() == issRhs.getMptID();
}
else
{
return false;
}
},
lhs.issue_,
rhs.issue_);
@@ -218,9 +303,38 @@ std::string
to_string(Asset const& asset);
bool
validJSONAsset(Json::Value const& jv);
validJSONAsset(json::Value const& jv);
Asset
assetFromJson(Json::Value const& jv);
assetFromJson(json::Value const& jv);
inline bool
isConsistent(Asset const& asset)
{
return asset.visit(
[](Issue const& issue) { return isConsistent(issue); },
[](MPTIssue const&) { return true; });
}
inline bool
validAsset(Asset const& asset)
{
return asset.visit(
[](Issue const& issue) { return isConsistent(issue) && issue.currency != badCurrency(); },
[](MPTIssue const& issue) { return issue.getIssuer() != xrpAccount(); });
}
template <class Hasher>
void
hash_append(Hasher& h, Asset const& r)
{
using beast::hash_append;
r.visit(
[&](Issue const& issue) { hash_append(h, issue); },
[&](MPTIssue const& issue) { hash_append(h, issue); });
}
std::ostream&
operator<<(std::ostream& os, Asset const& x);
} // namespace xrpl

View File

@@ -7,7 +7,7 @@ namespace xrpl {
inline void
serializeBatch(Serializer& msg, std::uint32_t const& flags, std::vector<uint256> const& txids)
{
msg.add32(HashPrefix::batch);
msg.add32(HashPrefix::Batch);
msg.add32(flags);
msg.add32(std::uint32_t(txids.size()));
for (auto const& txid : txids)

View File

@@ -2,7 +2,7 @@
#include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/Asset.h>
#include <boost/utility/base_from_member.hpp>
@@ -15,16 +15,14 @@ namespace xrpl {
class Book final : public CountedObject<Book>
{
public:
Issue in;
Issue out;
Asset in;
Asset out;
std::optional<uint256> domain;
Book()
{
}
Book() = default;
Book(Issue const& in_, Issue const& out_, std::optional<uint256> const& domain_)
: in(in_), out(out_), domain(domain_)
Book(Asset const& in, Asset const& out, std::optional<uint256> const& domain)
: in(in), out(out), domain(domain)
{
}
};
@@ -53,7 +51,7 @@ reversed(Book const& book);
/** Equality comparison. */
/** @{ */
[[nodiscard]] inline constexpr bool
[[nodiscard]] constexpr bool
operator==(Book const& lhs, Book const& rhs)
{
return (lhs.in == rhs.in) && (lhs.out == rhs.out) && (lhs.domain == rhs.domain);
@@ -62,7 +60,7 @@ operator==(Book const& lhs, Book const& rhs)
/** Strict weak ordering. */
/** @{ */
[[nodiscard]] inline constexpr std::weak_ordering
[[nodiscard]] constexpr std::weak_ordering
operator<=>(Book const& lhs, Book const& rhs)
{
if (auto const c{lhs.in <=> rhs.in}; c != 0)
@@ -112,17 +110,68 @@ public:
}
};
template <>
struct hash<xrpl::MPTIssue> : private boost::base_from_member<std::hash<xrpl::MPTID>, 0>
{
private:
using id_hash_type = boost::base_from_member<std::hash<xrpl::MPTID>, 0>;
public:
explicit hash() = default;
using value_type = std::size_t;
using argument_type = xrpl::MPTIssue;
value_type
operator()(argument_type const& value) const
{
value_type const result(id_hash_type::member(value.getMptID()));
return result;
}
};
template <>
struct hash<xrpl::Asset>
{
private:
using value_type = std::size_t;
using argument_type = xrpl::Asset;
using issue_hasher = std::hash<xrpl::Issue>;
using mptissue_hasher = std::hash<xrpl::MPTIssue>;
issue_hasher mIssueHasher_;
mptissue_hasher mMptissueHasher_;
public:
explicit hash() = default;
value_type
operator()(argument_type const& asset) const
{
return asset.visit(
[&](xrpl::Issue const& issue) {
value_type const result(mIssueHasher_(issue));
return result;
},
[&](xrpl::MPTIssue const& issue) {
value_type const result(mMptissueHasher_(issue));
return result;
});
}
};
//------------------------------------------------------------------------------
template <>
struct hash<xrpl::Book>
{
private:
using issue_hasher = std::hash<xrpl::Issue>;
using asset_hasher = std::hash<xrpl::Asset>;
using uint256_hasher = xrpl::uint256::hasher;
issue_hasher m_issue_hasher;
uint256_hasher m_uint256_hasher;
asset_hasher issueHasher_;
uint256_hasher uint256Hasher_;
public:
hash() = default;
@@ -133,11 +182,11 @@ public:
value_type
operator()(argument_type const& value) const
{
value_type result(m_issue_hasher(value.in));
boost::hash_combine(result, m_issue_hasher(value.out));
value_type result(issueHasher_(value.in));
boost::hash_combine(result, issueHasher_(value.out));
if (value.domain)
boost::hash_combine(result, m_uint256_hasher(*value.domain));
boost::hash_combine(result, uint256Hasher_(*value.domain));
return result;
}
@@ -159,6 +208,22 @@ struct hash<xrpl::Issue> : std::hash<xrpl::Issue>
// using Base::Base; // inherit ctors
};
template <>
struct hash<xrpl::MPTIssue> : std::hash<xrpl::MPTIssue>
{
explicit hash() = default;
using Base = std::hash<xrpl::MPTIssue>;
};
template <>
struct hash<xrpl::Asset> : std::hash<xrpl::Asset>
{
explicit hash() = default;
using Base = std::hash<xrpl::Asset>;
};
template <>
struct hash<xrpl::Book> : std::hash<xrpl::Book>
{

View File

@@ -3,11 +3,9 @@
#include <cstdint>
#include <string>
namespace xrpl {
/** Versioning information for this build. */
// VFALCO The namespace is deprecated
namespace BuildInfo {
namespace xrpl::BuildInfo {
/** Server version.
Follows the Semantic Versioning Specification:
@@ -33,7 +31,7 @@ getFullVersionString();
X: 16 bits identifying the particular implementation
Y: 48 bits of data specific to the implementation
The rippled-specific format (implementation ID is: 0x18 0x3B) is:
The xrpld-specific format (implementation ID is: 0x18 0x3B) is:
00011000-00111011-MMMMMMMM-mmmmmmmm-pppppppp-TTNNNNNN-00000000-00000000
@@ -55,27 +53,25 @@ encodeSoftwareVersion(std::string_view versionStr);
std::uint64_t
getEncodedVersion();
/** Check if the encoded software version is a rippled software version.
/** Check if the encoded software version is an xrpld software version.
@param version another node's encoded software version
@return true if the version is a rippled software version, false otherwise
@return true if the version is an xrpld software version, false otherwise
*/
bool
isRippledVersion(std::uint64_t version);
isXrpldVersion(std::uint64_t version);
/** Check if the version is newer than the local node's rippled software
/** Check if the version is newer than the local node's xrpld software
version.
@param version another node's encoded software version
@return true if the version is newer than the local node's rippled software
@return true if the version is newer than the local node's xrpld software
version, false otherwise.
@note This function only understands version numbers that are generated by
rippled. Please see the encodeSoftwareVersion() function for detail.
xrpld. Please see the encodeSoftwareVersion() function for detail.
*/
bool
isNewerVersion(std::uint64_t version);
} // namespace BuildInfo
} // namespace xrpl
} // namespace xrpl::BuildInfo

View File

@@ -0,0 +1,86 @@
#pragma once
#include <xrpl/protocol/UintTypes.h>
#include <type_traits>
namespace xrpl {
class STAmount;
class Asset;
class Issue;
class MPTIssue;
class IOUAmount;
class XRPAmount;
class MPTAmount;
template <typename A>
concept StepAmount =
std::is_same_v<A, XRPAmount> || std::is_same_v<A, IOUAmount> || std::is_same_v<A, MPTAmount>;
template <typename TIss>
concept ValidIssueType = std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;
template <typename A>
concept AssetType = std::is_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
template <typename T>
concept ValidPathAsset = (std::is_same_v<T, Currency> || std::is_same_v<T, MPTID>);
template <class TTakerPays, class TTakerGets>
concept ValidTaker =
((std::is_same_v<TTakerPays, IOUAmount> || std::is_same_v<TTakerPays, XRPAmount> ||
std::is_same_v<TTakerPays, MPTAmount>) &&
(std::is_same_v<TTakerGets, IOUAmount> || std::is_same_v<TTakerGets, XRPAmount> ||
std::is_same_v<TTakerGets, MPTAmount>) &&
(!std::is_same_v<TTakerPays, XRPAmount> || !std::is_same_v<TTakerGets, XRPAmount>));
namespace detail {
// This template combines multiple callable objects (lambdas) into a single
// object that std::visit can use for overload resolution.
template <typename... Ts>
struct CombineVisitors : Ts...
{
// Bring all operator() overloads from base classes into this scope.
// It's the mechanism that makes the CombineVisitors struct function
// as a single callable object with multiple overloads.
using Ts::operator()...;
// Perfect forwarding constructor to correctly initialize the base class
// lambdas
constexpr CombineVisitors(Ts&&... ts) : Ts(std::forward<Ts>(ts))...
{
}
};
// This function forces function template argument deduction, which is more
// robust than class template argument deduction (CTAD) via the deduction guide.
template <typename... Ts>
constexpr CombineVisitors<std::decay_t<Ts>...>
makeCombineVisitors(Ts&&... ts)
{
// std::decay_t<Ts> is used to remove references/constness from the lambda
// types before they are passed as template arguments to the CombineVisitors
// struct.
return CombineVisitors<std::decay_t<Ts>...>{std::forward<Ts>(ts)...};
}
// This function takes ANY variant and ANY number of visitors, and performs the
// visit. It is the reusable core logic.
template <typename Variant, typename... Visitors>
constexpr auto
visit(Variant&& v, Visitors&&... visitors) -> decltype(auto)
{
// Use the function template helper instead of raw CTAD.
auto visitorSet = makeCombineVisitors(std::forward<Visitors>(visitors)...);
// Delegate to std::visit, perfectly forwarding the variant and the visitor
// set.
return std::visit(visitorSet, std::forward<Variant>(v));
}
} // namespace detail
} // namespace xrpl

View File

@@ -17,144 +17,148 @@ namespace xrpl {
//
// Please only append to this table. Do not "fill-in" gaps and do not re-use
// or repurpose error code values.
enum error_code_i {
// Protocol-wide, 50+ files
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum ErrorCodeI {
// -1 represents codes not listed in this enumeration
rpcUNKNOWN = -1,
RpcUnknown = -1,
rpcSUCCESS = 0,
RpcSuccess = 0,
rpcBAD_SYNTAX = 1,
rpcJSON_RPC = 2,
rpcFORBIDDEN = 3,
RpcBadSyntax = 1,
RpcJsonRpc = 2,
RpcForbidden = 3,
rpcWRONG_NETWORK = 4,
RpcWrongNetwork = 4,
// Misc failure
// unused 5,
rpcNO_PERMISSION = 6,
rpcNO_EVENTS = 7,
RpcNoPermission = 6,
RpcNoEvents = 7,
// unused 8,
rpcTOO_BUSY = 9,
rpcSLOW_DOWN = 10,
rpcHIGH_FEE = 11,
rpcNOT_ENABLED = 12,
rpcNOT_READY = 13,
rpcAMENDMENT_BLOCKED = 14,
RpcTooBusy = 9,
RpcSlowDown = 10,
RpcHighFee = 11,
RpcNotEnabled = 12,
RpcNotReady = 13,
RpcAmendmentBlocked = 14,
// Networking
rpcNO_CLOSED = 15,
rpcNO_CURRENT = 16,
rpcNO_NETWORK = 17,
rpcNOT_SYNCED = 18,
RpcNoClosed = 15,
RpcNoCurrent = 16,
RpcNoNetwork = 17,
RpcNotSynced = 18,
// Ledger state
rpcACT_NOT_FOUND = 19,
RpcActNotFound = 19,
// unused 20,
rpcLGR_NOT_FOUND = 21,
rpcLGR_NOT_VALIDATED = 22,
rpcMASTER_DISABLED = 23,
RpcLgrNotFound = 21,
RpcLgrNotValidated = 22,
RpcMasterDisabled = 23,
// unused 24,
// unused 25,
// unused 26,
// unused 27,
// unused 28,
rpcTXN_NOT_FOUND = 29,
rpcINVALID_HOTWALLET = 30,
RpcTxnNotFound = 29,
RpcInvalidHotwallet = 30,
// Malformed command
rpcINVALID_PARAMS = 31,
rpcUNKNOWN_COMMAND = 32,
rpcNO_PF_REQUEST = 33,
RpcInvalidParams = 31,
RpcUnknownCommand = 32,
RpcNoPfRequest = 33,
// Bad parameter
// NOT USED DO NOT USE AGAIN rpcACT_BITCOIN = 34,
rpcACT_MALFORMED = 35,
rpcALREADY_MULTISIG = 36,
rpcALREADY_SINGLE_SIG = 37,
RpcActMalformed = 35,
RpcAlreadyMultisig = 36,
RpcAlreadySingleSig = 37,
// unused 38,
// unused 39,
rpcBAD_FEATURE = 40,
rpcBAD_ISSUER = 41,
rpcBAD_MARKET = 42,
rpcBAD_SECRET = 43,
rpcBAD_SEED = 44,
rpcCHANNEL_MALFORMED = 45,
rpcCHANNEL_AMT_MALFORMED = 46,
rpcCOMMAND_MISSING = 47,
rpcDST_ACT_MALFORMED = 48,
rpcDST_ACT_MISSING = 49,
rpcDST_ACT_NOT_FOUND = 50,
rpcDST_AMT_MALFORMED = 51,
rpcDST_AMT_MISSING = 52,
rpcDST_ISR_MALFORMED = 53,
RpcBadFeature = 40,
RpcBadIssuer = 41,
RpcBadMarket = 42,
RpcBadSecret = 43,
RpcBadSeed = 44,
RpcChannelMalformed = 45,
RpcChannelAmtMalformed = 46,
RpcCommandMissing = 47,
RpcDstActMalformed = 48,
RpcDstActMissing = 49,
RpcDstActNotFound = 50,
RpcDstAmtMalformed = 51,
RpcDstAmtMissing = 52,
RpcDstIsrMalformed = 53,
// unused 54,
// unused 55,
// unused 56,
rpcLGR_IDXS_INVALID = 57,
rpcLGR_IDX_MALFORMED = 58,
RpcLgrIdxsInvalid = 57,
RpcLgrIdxMalformed = 58,
// unused 59,
// unused 60,
// unused 61,
rpcPUBLIC_MALFORMED = 62,
rpcSIGNING_MALFORMED = 63,
rpcSENDMAX_MALFORMED = 64,
rpcSRC_ACT_MALFORMED = 65,
rpcSRC_ACT_MISSING = 66,
rpcSRC_ACT_NOT_FOUND = 67,
rpcDELEGATE_ACT_NOT_FOUND = 68,
rpcSRC_CUR_MALFORMED = 69,
rpcSRC_ISR_MALFORMED = 70,
rpcSTREAM_MALFORMED = 71,
rpcATX_DEPRECATED = 72,
RpcPublicMalformed = 62,
RpcSigningMalformed = 63,
RpcSendmaxMalformed = 64,
RpcSrcActMalformed = 65,
RpcSrcActMissing = 66,
RpcSrcActNotFound = 67,
RpcDelegateActNotFound = 68,
RpcSrcCurMalformed = 69,
RpcSrcIsrMalformed = 70,
RpcStreamMalformed = 71,
RpcAtxDeprecated = 72,
// Internal error (should never happen)
rpcINTERNAL = 73, // Generic internal error.
rpcNOT_IMPL = 74,
rpcNOT_SUPPORTED = 75,
rpcBAD_KEY_TYPE = 76,
rpcDB_DESERIALIZATION = 77,
rpcEXCESSIVE_LGR_RANGE = 78,
rpcINVALID_LGR_RANGE = 79,
rpcEXPIRED_VALIDATOR_LIST = 80,
RpcInternal = 73, // Generic internal error.
RpcNotImpl = 74,
RpcNotSupported = 75,
RpcBadKeyType = 76,
RpcDbDeserialization = 77,
RpcExcessiveLgrRange = 78,
RpcInvalidLgrRange = 79,
RpcExpiredValidatorList = 80,
// unused = 90,
// DEPRECATED. New code must not use this value.
rpcREPORTING_UNSUPPORTED = 91,
RpcReportingUnsupported = 91,
rpcOBJECT_NOT_FOUND = 92,
RpcObjectNotFound = 92,
// AMM
rpcISSUE_MALFORMED = 93,
RpcIssueMalformed = 93,
// Oracle
rpcORACLE_MALFORMED = 94,
RpcOracleMalformed = 94,
// deposit_authorized + credentials
rpcBAD_CREDENTIALS = 95,
RpcBadCredentials = 95,
// Simulate
rpcTX_SIGNED = 96,
RpcTxSigned = 96,
// Pathfinding
rpcDOMAIN_MALFORMED = 97,
RpcDomainMalformed = 97,
// ledger_entry
rpcENTRY_NOT_FOUND = 98,
rpcUNEXPECTED_LEDGER_TYPE = 99,
RpcEntryNotFound = 98,
RpcUnexpectedLedgerType = 99,
rpcLAST = rpcUNEXPECTED_LEDGER_TYPE // rpcLAST should always equal the last code.
RpcLast = RpcUnexpectedLedgerType // rpcLAST should always equal the last code.
};
/** Codes returned in the `warnings` array of certain RPC commands.
These values need to remain stable.
*/
enum warning_code_i {
warnRPC_UNSUPPORTED_MAJORITY = 1001,
warnRPC_AMENDMENT_BLOCKED = 1002,
warnRPC_EXPIRED_VALIDATOR_LIST = 1003,
// Protocol-wide, 50+ files
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum WarningCodeI {
WarnRpcUnsupportedMajority = 1001,
WarnRpcAmendmentBlocked = 1002,
WarnRpcExpiredValidatorList = 1003,
// unused = 1004
warnRPC_FIELDS_DEPRECATED = 2004, // rippled needs to maintain
// compatibility with Clio on this code.
WarnRpcFieldsDeprecated = 2004, // xrpld needs to maintain
// compatibility with Clio on this code.
};
//------------------------------------------------------------------------------
@@ -168,163 +172,159 @@ struct ErrorInfo
{
// Default ctor needed to produce an empty std::array during constexpr eval.
constexpr ErrorInfo()
: code(rpcUNKNOWN), token("unknown"), message("An unknown error code."), http_status(200)
: code(RpcUnknown), token("unknown"), message("An unknown error code."), httpStatus(200)
{
}
constexpr ErrorInfo(error_code_i code_, char const* token_, char const* message_)
: code(code_), token(token_), message(message_), http_status(200)
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message)
: code(code), token(token), message(message), httpStatus(200)
{
}
constexpr ErrorInfo(
error_code_i code_,
char const* token_,
char const* message_,
int http_status_)
: code(code_), token(token_), message(message_), http_status(http_status_)
constexpr ErrorInfo(ErrorCodeI code, char const* token, char const* message, int httpStatus)
: code(code), token(token), message(message), httpStatus(httpStatus)
{
}
error_code_i code;
Json::StaticString token;
Json::StaticString message;
int http_status;
ErrorCodeI code;
json::StaticString token;
json::StaticString message;
int httpStatus;
};
/** Returns an ErrorInfo that reflects the error code. */
ErrorInfo const&
get_error_info(error_code_i code);
getErrorInfo(ErrorCodeI code);
/** Add or update the json update to reflect the error code. */
/** @{ */
void
inject_error(error_code_i code, Json::Value& json);
injectError(ErrorCodeI code, json::Value& json);
void
inject_error(error_code_i code, std::string const& message, Json::Value& json);
injectError(ErrorCodeI code, std::string const& message, json::Value& json);
/** @} */
/** Returns a new json object that reflects the error code. */
/** @{ */
Json::Value
make_error(error_code_i code);
Json::Value
make_error(error_code_i code, std::string const& message);
json::Value
makeError(ErrorCodeI code);
json::Value
makeError(ErrorCodeI code, std::string const& message);
/** @} */
/** Returns a new json object that indicates invalid parameters. */
/** @{ */
inline Json::Value
make_param_error(std::string const& message)
inline json::Value
makeParamError(std::string const& message)
{
return make_error(rpcINVALID_PARAMS, message);
return makeError(RpcInvalidParams, message);
}
inline std::string
missing_field_message(std::string const& name)
missingFieldMessage(std::string const& name)
{
return "Missing field '" + name + "'.";
}
inline Json::Value
missing_field_error(std::string const& name)
inline json::Value
missingFieldError(std::string const& name)
{
return make_param_error(missing_field_message(name));
return makeParamError(missingFieldMessage(name));
}
inline Json::Value
missing_field_error(Json::StaticString name)
inline json::Value
missingFieldError(json::StaticString name)
{
return missing_field_error(std::string(name));
return missingFieldError(std::string(name));
}
inline std::string
object_field_message(std::string const& name)
objectFieldMessage(std::string const& name)
{
return "Invalid field '" + name + "', not object.";
}
inline Json::Value
object_field_error(std::string const& name)
inline json::Value
objectFieldError(std::string const& name)
{
return make_param_error(object_field_message(name));
return makeParamError(objectFieldMessage(name));
}
inline Json::Value
object_field_error(Json::StaticString name)
inline json::Value
objectFieldError(json::StaticString name)
{
return object_field_error(std::string(name));
return objectFieldError(std::string(name));
}
inline std::string
invalid_field_message(std::string const& name)
invalidFieldMessage(std::string const& name)
{
return "Invalid field '" + name + "'.";
}
inline std::string
invalid_field_message(Json::StaticString name)
invalidFieldMessage(json::StaticString name)
{
return invalid_field_message(std::string(name));
return invalidFieldMessage(std::string(name));
}
inline Json::Value
invalid_field_error(std::string const& name)
inline json::Value
invalidFieldError(std::string const& name)
{
return make_param_error(invalid_field_message(name));
return makeParamError(invalidFieldMessage(name));
}
inline Json::Value
invalid_field_error(Json::StaticString name)
inline json::Value
invalidFieldError(json::StaticString name)
{
return invalid_field_error(std::string(name));
return invalidFieldError(std::string(name));
}
inline std::string
expected_field_message(std::string const& name, std::string const& type)
expectedFieldMessage(std::string const& name, std::string const& type)
{
return "Invalid field '" + name + "', not " + type + ".";
}
inline std::string
expected_field_message(Json::StaticString name, std::string const& type)
expectedFieldMessage(json::StaticString name, std::string const& type)
{
return expected_field_message(std::string(name), type);
return expectedFieldMessage(std::string(name), type);
}
inline Json::Value
expected_field_error(std::string const& name, std::string const& type)
inline json::Value
expectedFieldError(std::string const& name, std::string const& type)
{
return make_param_error(expected_field_message(name, type));
return makeParamError(expectedFieldMessage(name, type));
}
inline Json::Value
expected_field_error(Json::StaticString name, std::string const& type)
inline json::Value
expectedFieldError(json::StaticString name, std::string const& type)
{
return expected_field_error(std::string(name), type);
return expectedFieldError(std::string(name), type);
}
inline Json::Value
not_validator_error()
inline json::Value
notValidatorError()
{
return make_param_error("not a validator");
return makeParamError("not a validator");
}
/** @} */
/** Returns `true` if the json contains an rpc error specification. */
bool
contains_error(Json::Value const& json);
containsError(json::Value const& json);
/** Returns http status that corresponds to the error code. */
int
error_code_http_status(error_code_i code);
errorCodeHttpStatus(ErrorCodeI code);
} // namespace RPC
/** Returns a single string with the contents of an RPC error. */
std::string
rpcErrorString(Json::Value const& jv);
rpcErrorString(json::Value const& jv);
} // namespace xrpl

View File

@@ -37,10 +37,10 @@
* 5) If a supported feature (`Supported::yes`) was _ever_ in a released
* version, it can never be changed back to `Supported::no`, because
* it _may_ still become enabled at any time. This would cause newer
* versions of `rippled` to become amendment blocked.
* versions of `xrpld` to become amendment blocked.
* Instead, to prevent newer versions from voting on the feature, use
* `VoteBehavior::Obsolete`. Obsolete features can not be voted for
* by any versions of `rippled` built with that setting, but will still
* by any versions of `xrpld` built with that setting, but will still
* work correctly if they get enabled. If a feature remains obsolete
* for long enough that _all_ clients that could vote for it are
* amendment blocked, the feature can be removed from the code
@@ -65,11 +65,11 @@
namespace xrpl {
// Feature names must not exceed this length (in characters, excluding the null terminator).
static constexpr std::size_t maxFeatureNameSize = 63;
static constexpr std::size_t kMaxFeatureNameSize = 63;
// Reserve this exact feature-name length (in characters/bytes, excluding the null terminator)
// so that a 32-byte uint256 (for example, in WASM or other interop contexts) can be used
// as a compact, fixed-size feature selector without conflicting with human-readable names.
static constexpr std::size_t reservedFeatureNameSize = 32;
static constexpr std::size_t kReservedFeatureNameSize = 32;
// Both validFeatureNameSize and validFeatureName are consteval functions that can be used in
// static_asserts to validate feature names at compile time. They are only used inside
@@ -79,27 +79,27 @@ static constexpr std::size_t reservedFeatureNameSize = 32;
consteval auto
validFeatureNameSize(auto fn) -> bool
{
constexpr char const* n = fn();
constexpr char const* kN = fn();
// Note, std::strlen is not constexpr, we need to implement our own here.
constexpr std::size_t N = [](auto n) {
constexpr std::size_t kLen = [](auto n) {
std::size_t ret = 0;
for (auto ptr = n; *ptr != '\0'; ret++, ++ptr)
;
return ret;
}(n);
return N != reservedFeatureNameSize && //
N <= maxFeatureNameSize;
}(kN);
return kLen != kReservedFeatureNameSize && //
kLen <= kMaxFeatureNameSize;
}
consteval auto
validFeatureName(auto fn) -> bool
{
constexpr char const* n = fn();
constexpr char const* kN = fn();
// Prevent the use of visually confusable characters and enforce that feature names
// are always valid ASCII. This is needed because C++ allows Unicode identifiers.
// Characters below 0x20 are nonprintable control characters, and characters with the 0x80 bit
// set are non-ASCII (e.g. UTF-8 encoding of Unicode), so both are disallowed.
for (auto ptr = n; *ptr != '\0'; ++ptr)
for (auto ptr = kN; *ptr != '\0'; ++ptr)
{
if (*ptr & 0x80 || *ptr < 0x20)
return false;
@@ -107,8 +107,8 @@ validFeatureName(auto fn) -> bool
return true;
}
enum class VoteBehavior : int { Obsolete = -1, DefaultNo = 0, DefaultYes };
enum class AmendmentSupport : int { Retired = -1, Supported = 0, Unsupported };
enum class VoteBehavior : int { Obsolete = -1, DefaultNo = 0, DefaultYes = 1 };
enum class AmendmentSupport : int { Retired = -1, Supported = 0, Unsupported = 1 };
/** All amendments libxrpl knows about. */
std::map<std::string, AmendmentSupport> const&
@@ -125,16 +125,18 @@ namespace detail {
#pragma push_macro("XRPL_RETIRE_FIX")
#undef XRPL_RETIRE_FIX
// NOLINTBEGIN(bugprone-macro-parentheses)
#define XRPL_FEATURE(name, supported, vote) +1
#define XRPL_FIX(name, supported, vote) +1
#define XRPL_RETIRE_FEATURE(name) +1
#define XRPL_RETIRE_FIX(name) +1
// NOLINTEND(bugprone-macro-parentheses)
// This value SHOULD be equal to the number of amendments registered in
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures =
static constexpr std::size_t kNumFeatures =
(0 +
#include <xrpl/protocol/detail/features.macro>
);
@@ -182,9 +184,9 @@ bitsetIndexToFeature(size_t i);
std::string
featureToName(uint256 const& f);
class FeatureBitset : private std::bitset<detail::numFeatures>
class FeatureBitset : private std::bitset<detail::kNumFeatures>
{
using base = std::bitset<detail::numFeatures>;
using base = std::bitset<detail::kNumFeatures>;
template <class... Fs>
void
@@ -373,8 +375,10 @@ void
foreachFeature(FeatureBitset bs, F&& f)
{
for (size_t i = 0; i < bs.size(); ++i)
{
if (bs[i])
f(bitsetIndexToFeature(i));
}
}
#pragma push_macro("XRPL_FEATURE")

View File

@@ -6,7 +6,7 @@ namespace xrpl {
// Deprecated constant for backwards compatibility with pre-XRPFees amendment.
// This was the reference fee units used in the old fee calculation.
inline constexpr std::uint32_t FEE_UNITS_DEPRECATED = 10;
inline constexpr std::uint32_t kFeeUnitsDeprecated = 10;
/** Reflects the fee settings for a particular ledger.
@@ -29,8 +29,8 @@ struct Fees
Fees&
operator=(Fees const&) = default;
Fees(XRPAmount base_, XRPAmount reserve_, XRPAmount increment_)
: base(base_), reserve(reserve_), increment(increment_)
Fees(XRPAmount base, XRPAmount reserve, XRPAmount increment)
: base(base), reserve(reserve), increment(increment)
{
}
@@ -39,7 +39,7 @@ struct Fees
The reserve is calculated as the reserve base plus
the reserve increment times the number of increments.
*/
XRPAmount
[[nodiscard]] XRPAmount
accountReserve(std::size_t ownerCount) const
{
return reserve + ownerCount * increment;

View File

@@ -9,7 +9,7 @@ namespace xrpl {
namespace detail {
constexpr std::uint32_t
make_hash_prefix(char a, char b, char c)
makeHashPrefix(char a, char b, char c)
{
return (static_cast<std::uint32_t>(a) << 24) + (static_cast<std::uint32_t>(b) << 16) +
(static_cast<std::uint32_t>(c) << 8);
@@ -33,40 +33,40 @@ make_hash_prefix(char a, char b, char c)
*/
enum class HashPrefix : std::uint32_t {
/** transaction plus signature to give transaction ID */
transactionID = detail::make_hash_prefix('T', 'X', 'N'),
TransactionId = detail::makeHashPrefix('T', 'X', 'N'),
/** transaction plus metadata */
txNode = detail::make_hash_prefix('S', 'N', 'D'),
TxNode = detail::makeHashPrefix('S', 'N', 'D'),
/** account state */
leafNode = detail::make_hash_prefix('M', 'L', 'N'),
LeafNode = detail::makeHashPrefix('M', 'L', 'N'),
/** inner node in V1 tree */
innerNode = detail::make_hash_prefix('M', 'I', 'N'),
InnerNode = detail::makeHashPrefix('M', 'I', 'N'),
/** ledger master data for signing */
ledgerMaster = detail::make_hash_prefix('L', 'W', 'R'),
LedgerMaster = detail::makeHashPrefix('L', 'W', 'R'),
/** inner transaction to sign */
txSign = detail::make_hash_prefix('S', 'T', 'X'),
TxSign = detail::makeHashPrefix('S', 'T', 'X'),
/** inner transaction to multi-sign */
txMultiSign = detail::make_hash_prefix('S', 'M', 'T'),
TxMultiSign = detail::makeHashPrefix('S', 'M', 'T'),
/** validation for signing */
validation = detail::make_hash_prefix('V', 'A', 'L'),
Validation = detail::makeHashPrefix('V', 'A', 'L'),
/** proposal for signing */
proposal = detail::make_hash_prefix('P', 'R', 'P'),
Proposal = detail::makeHashPrefix('P', 'R', 'P'),
/** Manifest */
manifest = detail::make_hash_prefix('M', 'A', 'N'),
Manifest = detail::makeHashPrefix('M', 'A', 'N'),
/** Payment Channel Claim */
paymentChannelClaim = detail::make_hash_prefix('C', 'L', 'M'),
PaymentChannelClaim = detail::makeHashPrefix('C', 'L', 'M'),
/** Batch */
batch = detail::make_hash_prefix('B', 'C', 'H'),
Batch = detail::makeHashPrefix('B', 'C', 'H'),
};
template <class Hasher>

View File

@@ -26,8 +26,8 @@ class IOUAmount : private boost::totally_ordered<IOUAmount>, private boost::addi
private:
using mantissa_type = std::int64_t;
using exponent_type = int;
mantissa_type mantissa_;
exponent_type exponent_;
mantissa_type mantissa_{};
exponent_type exponent_{};
/** Adjusts the mantissa and exponent to the proper range.
@@ -71,13 +71,13 @@ public:
operator bool() const noexcept;
/** Return the sign of the amount */
int
[[nodiscard]] int
signum() const noexcept;
exponent_type
[[nodiscard]] exponent_type
exponent() const noexcept;
mantissa_type
[[nodiscard]] mantissa_type
mantissa() const noexcept;
static IOUAmount
@@ -92,7 +92,7 @@ public:
inline IOUAmount::IOUAmount(beast::Zero)
{
*this = beast::zero;
*this = beast::kZero;
}
inline IOUAmount::IOUAmount(mantissa_type mantissa, exponent_type exponent)
@@ -151,7 +151,9 @@ operator bool() const noexcept
inline int
IOUAmount::signum() const noexcept
{
return (mantissa_ < 0) ? -1 : (mantissa_ ? 1 : 0);
if (mantissa_ < 0)
return -1;
return (mantissa_ != 0) ? 1 : 0;
}
inline IOUAmount::exponent_type

View File

@@ -75,14 +75,14 @@ Keylet const&
negativeUNL() noexcept;
/** The beginning of an order book */
struct book_t
struct BookT
{
explicit book_t() = default;
explicit BookT() = default;
Keylet
operator()(Book const& b) const;
};
static book_t const book{};
static BookT const kBook{};
/** The index of a trust line for a given currency
@@ -119,19 +119,19 @@ Keylet
quality(Keylet const& k, std::uint64_t q) noexcept;
/** The directory for the next lower quality */
struct next_t
struct NextT
{
explicit next_t() = default;
explicit NextT() = default;
Keylet
operator()(Keylet const& k) const;
};
static next_t const next{};
static NextT const kNext{};
/** A ticket belonging to an account */
struct ticket_t
struct TicketT
{
explicit ticket_t() = default;
explicit TicketT() = default;
Keylet
operator()(AccountID const& id, std::uint32_t ticketSeq) const;
@@ -145,7 +145,7 @@ struct ticket_t
return {ltTICKET, key};
}
};
static ticket_t const ticket{};
static TicketT const kTicket{};
/** A SignerList */
Keylet
@@ -221,11 +221,11 @@ payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept;
/** @{ */
/** A keylet for the owner's first possible NFT page. */
Keylet
nftpage_min(AccountID const& owner);
nftpageMin(AccountID const& owner);
/** A keylet for the owner's last possible NFT page. */
Keylet
nftpage_max(AccountID const& owner);
nftpageMax(AccountID const& owner);
Keylet
nftpage(Keylet const& k, uint256 const& token);
@@ -243,11 +243,11 @@ nftoffer(uint256 const& offer)
/** The directory of buy offers for the specified NFT */
Keylet
nft_buys(uint256 const& id) noexcept;
nftBuys(uint256 const& id) noexcept;
/** The directory of sell offers for the specified NFT */
Keylet
nft_sells(uint256 const& id) noexcept;
nftSells(uint256 const& id) noexcept;
/** AMM entry */
Keylet
@@ -362,25 +362,26 @@ getTicketIndex(AccountID const& account, std::uint32_t uSequence);
uint256
getTicketIndex(AccountID const& account, SeqProxy ticketSeq);
template <class... keyletParams>
struct keyletDesc
template <class... KeyletParams>
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
struct KeyletDesc
{
std::function<Keylet(keyletParams...)> function;
Json::StaticString expectedLEName;
bool includeInTests;
std::function<Keylet(KeyletParams...)> function;
json::StaticString expectedLEName;
bool includeInTests{};
};
// This list should include all of the keylet functions that take a single
// AccountID parameter.
std::array<keyletDesc<AccountID const&>, 6> const directAccountKeylets{
{{&keylet::account, jss::AccountRoot, false},
{&keylet::ownerDir, jss::DirectoryNode, true},
{&keylet::signers, jss::SignerList, true},
std::array<KeyletDesc<AccountID const&>, 6> const kDirectAccountKeylets{
{{.function = &keylet::account, .expectedLEName = jss::AccountRoot, .includeInTests = false},
{.function = &keylet::ownerDir, .expectedLEName = jss::DirectoryNode, .includeInTests = true},
{.function = &keylet::signers, .expectedLEName = jss::SignerList, .includeInTests = true},
// It's normally impossible to create an item at nftpage_min, but
// test it anyway, since the invariant checks for it.
{&keylet::nftpage_min, jss::NFTokenPage, true},
{&keylet::nftpage_max, jss::NFTokenPage, true},
{&keylet::did, jss::DID, true}}};
{.function = &keylet::nftpageMin, .expectedLEName = jss::NFTokenPage, .includeInTests = true},
{.function = &keylet::nftpageMax, .expectedLEName = jss::NFTokenPage, .includeInTests = true},
{.function = &keylet::did, .expectedLEName = jss::DID, .includeInTests = true}}};
MPTID
makeMptID(std::uint32_t sequence, AccountID const& account);

View File

@@ -18,7 +18,7 @@ public:
static InnerObjectFormats const&
getInstance();
SOTemplate const*
[[nodiscard]] SOTemplate const*
findSOTemplateBySField(SField const& sField) const;
};

View File

@@ -12,8 +12,8 @@ namespace xrpl {
class Issue
{
public:
Currency currency{};
AccountID account{};
Currency currency;
AccountID account;
Issue() = default;
@@ -21,22 +21,22 @@ public:
{
}
AccountID const&
[[nodiscard]] AccountID const&
getIssuer() const
{
return account;
}
std::string
[[nodiscard]] std::string
getText() const;
void
setJson(Json::Value& jv) const;
setJson(json::Value& jv) const;
bool
[[nodiscard]] bool
native() const;
bool
[[nodiscard]] bool
integral() const;
friend constexpr std::weak_ordering
@@ -49,11 +49,11 @@ isConsistent(Issue const& ac);
std::string
to_string(Issue const& ac);
Json::Value
to_json(Issue const& is);
json::Value
toJson(Issue const& is);
Issue
issueFromJson(Json::Value const& v);
issueFromJson(json::Value const& v);
std::ostream&
operator<<(std::ostream& os, Issue const& x);
@@ -68,7 +68,7 @@ hash_append(Hasher& h, Issue const& r)
/** Equality comparison. */
/** @{ */
[[nodiscard]] inline constexpr bool
[[nodiscard]] constexpr bool
operator==(Issue const& lhs, Issue const& rhs)
{
return (lhs.currency == rhs.currency) && (isXRP(lhs.currency) || lhs.account == rhs.account);
@@ -96,16 +96,16 @@ operator<=>(Issue const& lhs, Issue const& rhs)
inline Issue const&
xrpIssue()
{
static Issue issue{xrpCurrency(), xrpAccount()};
return issue;
static Issue const kIssue{xrpCurrency(), xrpAccount()};
return kIssue;
}
/** Returns an asset specifier that represents no account and currency. */
inline Issue const&
noIssue()
{
static Issue issue{noCurrency(), noAccount()};
return issue;
static Issue const kIssue{noCurrency(), noAccount()};
return kIssue;
}
inline bool

View File

@@ -6,18 +6,18 @@
namespace xrpl {
enum class KeyType {
secp256k1 = 0,
ed25519 = 1,
Secp256k1 = 0,
Ed25519 = 1,
};
inline std::optional<KeyType>
keyTypeFromString(std::string const& s)
{
if (s == "secp256k1")
return KeyType::secp256k1;
return KeyType::Secp256k1;
if (s == "ed25519")
return KeyType::ed25519;
return KeyType::Ed25519;
return {};
}
@@ -25,10 +25,10 @@ keyTypeFromString(std::string const& s)
inline char const*
to_string(KeyType type)
{
if (type == KeyType::secp256k1)
if (type == KeyType::Secp256k1)
return "secp256k1";
if (type == KeyType::ed25519)
if (type == KeyType::Ed25519)
return "ed25519";
return "INVALID";

View File

@@ -20,12 +20,12 @@ struct Keylet
uint256 key;
LedgerEntryType type;
Keylet(LedgerEntryType type_, uint256 const& key_) : key(key_), type(type_)
Keylet(LedgerEntryType type, uint256 const& key) : key(key), type(type)
{
}
/** Returns true if the SLE matches the type */
bool
[[nodiscard]] bool
check(STLedgerEntry const&) const;
};

View File

@@ -38,13 +38,13 @@ public:
{
// Verify that KeyType is appropriate.
static_assert(
std::is_enum<KeyType>::value || std::is_integral<KeyType>::value,
std::is_enum_v<KeyType> || std::is_integral_v<KeyType>,
"KnownFormats KeyType must be integral or enum.");
}
/** Retrieve the name of the format.
*/
std::string const&
[[nodiscard]] std::string const&
getName() const
{
return name_;
@@ -52,13 +52,13 @@ public:
/** Retrieve the transaction type this format represents.
*/
KeyType
[[nodiscard]] KeyType
getType() const
{
return type_;
}
SOTemplate const&
[[nodiscard]] SOTemplate const&
getSOTemplate() const
{
return soTemplate_;
@@ -74,10 +74,12 @@ public:
Derived classes will load the object with all the known formats.
*/
KnownFormats() : name_(beast::type_name<Derived>())
private:
KnownFormats() : name_(beast::typeName<Derived>())
{
}
public:
/** Destroy the known formats object.
The defined formats are deleted.
@@ -94,7 +96,7 @@ public:
@param name The name of the type.
@return The type.
*/
KeyType
[[nodiscard]] KeyType
findTypeByName(std::string const& name) const
{
if (auto const result = findByName(name))
@@ -106,7 +108,7 @@ public:
/** Retrieve a format based on its type.
*/
Item const*
[[nodiscard]] Item const*
findByType(KeyType type) const
{
auto const itr = types_.find(type);
@@ -116,13 +118,13 @@ public:
}
// begin() and end() are provided for testing purposes.
typename std::forward_list<Item>::const_iterator
[[nodiscard]] typename std::forward_list<Item>::const_iterator
begin() const
{
return formats_.begin();
}
typename std::forward_list<Item>::const_iterator
[[nodiscard]] typename std::forward_list<Item>::const_iterator
end() const
{
return formats_.end();
@@ -131,7 +133,7 @@ public:
protected:
/** Retrieve a format based on its name.
*/
Item const*
[[nodiscard]] Item const*
findByName(std::string const& name) const
{
auto const itr = names_.find(name);
@@ -157,7 +159,7 @@ protected:
{
if (auto const item = findByType(type))
{
LogicError(
logicError(
std::string("Duplicate key for item '") + name + "': already maps to " +
item->getName());
}
@@ -177,10 +179,11 @@ private:
// One of the situations where a std::forward_list is useful. We want to
// store each Item in a place where its address won't change. So a node-
// based container is appropriate. But we don't need searchability.
std::forward_list<Item> formats_;
std::forward_list<Item> formats_{};
boost::container::flat_map<std::string, Item const*> names_;
boost::container::flat_map<KeyType, Item const*> types_;
boost::container::flat_map<std::string, Item const*> names_{};
boost::container::flat_map<KeyType, Item const*> types_{};
friend Derived;
};
} // namespace xrpl

View File

@@ -1,5 +1,7 @@
#pragma once
// NOLINTBEGIN(readability-identifier-naming)
#include <xrpl/protocol/KnownFormats.h>
#include <map>
@@ -29,6 +31,8 @@ namespace xrpl {
@ingroup protocol
*/
// Protocol-critical, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum LedgerEntryType : std::uint16_t {
#pragma push_macro("LEDGER_ENTRY")
@@ -187,7 +191,8 @@ enum LedgerEntryType : std::uint16_t {
\
LEDGER_OBJECT(MPToken, \
LSF_FLAG2(lsfMPTLocked, 0x00000001) \
LSF_FLAG(lsfMPTAuthorized, 0x00000002)) \
LSF_FLAG(lsfMPTAuthorized, 0x00000002) \
LSF_FLAG(lsfMPTAMM, 0x00000004)) \
\
LEDGER_OBJECT(Credential, \
LSF_FLAG(lsfAccepted, 0x00010000)) \
@@ -210,9 +215,11 @@ enum LedgerEntryType : std::uint16_t {
// lsfRequireDestTag = 0x00020000,
// ...
// };
#define TO_VALUE(name, value) name = value,
#define TO_VALUE(name, value) name = (value),
#define NULL_NAME(name, values) values
#define NULL_OUTPUT(name, value)
// Bitwise flag enum
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum LedgerSpecificFlags : std::uint32_t { XMACRO(NULL_NAME, TO_VALUE, NULL_OUTPUT) };
// Create getter functions for each set of flags using Meyer's singleton pattern.
@@ -293,3 +300,5 @@ public:
};
} // namespace xrpl
// NOLINTEND(readability-identifier-naming)

View File

@@ -19,19 +19,19 @@ struct LedgerHeader
//
LedgerIndex seq = 0;
NetClock::time_point parentCloseTime = {};
NetClock::time_point parentCloseTime;
//
// For closed ledgers
//
// Closed means "tx set already determined"
uint256 hash = beast::zero;
uint256 txHash = beast::zero;
uint256 accountHash = beast::zero;
uint256 parentHash = beast::zero;
uint256 hash = beast::kZero;
uint256 txHash = beast::kZero;
uint256 accountHash = beast::kZero;
uint256 parentHash = beast::kZero;
XRPAmount drops = beast::zero;
XRPAmount drops = beast::kZero;
// If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time.
@@ -49,16 +49,16 @@ struct LedgerHeader
// closed. For open ledgers, the time the ledger
// will close if there's no transactions.
//
NetClock::time_point closeTime = {};
NetClock::time_point closeTime;
};
// ledger close flags
static std::uint32_t const sLCF_NoConsensusTime = 0x01;
static std::uint32_t const kSLcfNoConsensusTime = 0x01;
inline bool
getCloseAgree(LedgerHeader const& info)
{
return (info.closeFlags & sLCF_NoConsensusTime) == 0;
return (info.closeFlags & kSLcfNoConsensusTime) == 0;
}
void

View File

@@ -22,11 +22,12 @@ public:
using value_type = std::int64_t;
protected:
value_type value_;
value_type value_{};
public:
MPTAmount() = default;
constexpr MPTAmount(MPTAmount const& other) = default;
constexpr MPTAmount(beast::Zero);
constexpr MPTAmount&
operator=(MPTAmount const& other) = default;
@@ -67,14 +68,14 @@ public:
}
/** Return the sign of the amount */
constexpr int
[[nodiscard]] constexpr int
signum() const noexcept;
/** Returns the underlying value. Code SHOULD NOT call this
function unless the type has been abstracted away,
e.g. in a templated function.
*/
constexpr value_type
[[nodiscard]] constexpr value_type
value() const;
static MPTAmount
@@ -85,6 +86,11 @@ constexpr MPTAmount::MPTAmount(value_type value) : value_(value)
{
}
constexpr MPTAmount::MPTAmount(beast::Zero)
{
*this = beast::kZero;
}
constexpr MPTAmount&
MPTAmount::operator=(beast::Zero)
{
@@ -103,7 +109,9 @@ operator bool() const noexcept
constexpr int
MPTAmount::signum() const noexcept
{
return (value_ < 0) ? -1 : (value_ ? 1 : 0);
if (value_ < 0)
return -1;
return (value_ != 0) ? 1 : 0;
}
/** Returns the underlying value. Code SHOULD NOT call this
@@ -116,6 +124,14 @@ MPTAmount::value() const
return value_;
}
// Output MPTAmount as just the value.
template <class Char, class Traits>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os, MPTAmount const& q)
{
return os << q.value();
}
inline std::string
to_string(MPTAmount const& amount)
{
@@ -127,7 +143,7 @@ mulRatio(MPTAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
{
using namespace boost::multiprecision;
if (!den)
if (den == 0u)
Throw<std::runtime_error>("division by zero");
int128_t const amt128(amt.value());

View File

@@ -17,22 +17,29 @@ private:
public:
MPTIssue() = default;
explicit MPTIssue(MPTID const& issuanceID);
MPTIssue(MPTID const& issuanceID);
AccountID const&
MPTIssue(std::uint32_t sequence, AccountID const& account);
operator MPTID const&() const
{
return mptID_;
}
[[nodiscard]] AccountID const&
getIssuer() const;
constexpr MPTID const&
[[nodiscard]] constexpr MPTID const&
getMptID() const
{
return mptID_;
}
std::string
[[nodiscard]] std::string
getText() const;
void
setJson(Json::Value& jv) const;
setJson(json::Value& jv) const;
friend constexpr bool
operator==(MPTIssue const& lhs, MPTIssue const& rhs);
@@ -40,14 +47,14 @@ public:
friend constexpr std::weak_ordering
operator<=>(MPTIssue const& lhs, MPTIssue const& rhs);
bool
native() const
static bool
native()
{
return false;
}
bool
integral() const
static bool
integral()
{
return true;
}
@@ -73,13 +80,67 @@ isXRP(MPTID const&)
return false;
}
Json::Value
to_json(MPTIssue const& mptIssue);
inline AccountID
getMPTIssuer(MPTID const& mptid)
{
static_assert(sizeof(MPTID) == (sizeof(std::uint32_t) + sizeof(AccountID)));
// Extract the 20 bytes for the AccountID
std::array<std::uint8_t, sizeof(AccountID)> bytes{};
std::copy_n(mptid.data() + sizeof(std::uint32_t), sizeof(AccountID), bytes.begin());
// bit_cast is a "magic" compiler intrinsic that is
// usually optimized away to nothing in the final assembly.
return std::bit_cast<AccountID>(bytes);
}
// Disallow temporary
AccountID const&
getMPTIssuer(MPTID const&&) = delete;
AccountID const&
getMPTIssuer(MPTID&&) = delete;
inline MPTID
noMPT()
{
static MPTIssue const kMPT{0, noAccount()};
return kMPT.getMptID();
}
inline MPTID
badMPT()
{
static MPTIssue const kMPT{0, xrpAccount()};
return kMPT.getMptID();
}
template <class Hasher>
void
hash_append(Hasher& h, MPTIssue const& r)
{
using beast::hash_append;
hash_append(h, r.getMptID());
}
json::Value
toJson(MPTIssue const& mptIssue);
std::string
to_string(MPTIssue const& mptIssue);
MPTIssue
mptIssueFromJson(Json::Value const& jv);
mptIssueFromJson(json::Value const& jv);
std::ostream&
operator<<(std::ostream& os, MPTIssue const& x);
} // namespace xrpl
namespace std {
template <>
struct hash<xrpl::MPTID> : xrpl::MPTID::hasher
{
explicit hash() = default;
};
} // namespace std

View File

@@ -15,16 +15,16 @@ namespace xrpl {
namespace detail {
template <typename T>
constexpr bool is_integral_constant = false;
constexpr bool kIsIntegralConstant = false;
template <typename I, auto A>
constexpr bool is_integral_constant<std::integral_constant<I, A>&> = true;
constexpr bool kIsIntegralConstant<std::integral_constant<I, A>&> = true;
template <typename I, auto A>
constexpr bool is_integral_constant<std::integral_constant<I, A> const&> = true;
constexpr bool kIsIntegralConstant<std::integral_constant<I, A> const&> = true;
template <typename T>
concept some_integral_constant = detail::is_integral_constant<T&>;
concept some_integral_constant = detail::kIsIntegralConstant<T&>;
// This class is designed to wrap a collection of _almost_ identical Json::Value
// This class is designed to wrap a collection of _almost_ identical json::Value
// objects, indexed by version (i.e. there is some mapping of version to object
// index). It is used e.g. when we need to publish JSON data to users supporting
// different API versions. We allow manipulation and inspection of all objects
@@ -47,12 +47,12 @@ struct MultiApiJson
return (v < MinVer) ? 0 : static_cast<std::size_t>(v - MinVer);
}
constexpr static std::size_t size = MaxVer + 1 - MinVer;
std::array<Json::Value, size> val = {};
static constexpr std::size_t kSize = MaxVer + 1 - MinVer;
std::array<json::Value, kSize> val = {};
explicit MultiApiJson(Json::Value const& init = {})
explicit MultiApiJson(json::Value const& init = {})
{
if (init == Json::Value{})
if (init == json::Value{})
return; // All elements are already default-initialized
for (auto& v : val)
v = init;
@@ -60,27 +60,30 @@ struct MultiApiJson
void
set(char const* key, auto const& v)
requires std::constructible_from<Json::Value, decltype(v)>
requires std::constructible_from<json::Value, decltype(v)>
{
for (auto& a : this->val)
a[key] = v;
}
// Intentionally not using class enum here, MultivarJson is scope enough
enum IsMemberResult : int { none = 0, some, all };
enum class IsMemberResult : int { None = 0, Some, All };
[[nodiscard]] IsMemberResult
isMember(char const* key) const
{
int count = 0;
for (auto& a : this->val)
{
if (a.isMember(key))
count += 1;
}
return (count == 0 ? none : (count < size ? some : all));
if (count == 0)
return IsMemberResult::None;
return count < kSize ? IsMemberResult::Some : IsMemberResult::All;
}
static constexpr struct visitor_t final
static constexpr struct VisitorT final
{
// integral_constant version, extra arguments
template <typename Json, unsigned int Version, typename... Args, typename Fn>
@@ -97,7 +100,7 @@ struct MultiApiJson
std::integral_constant<unsigned int, Version>,
Args&&...>
{
static_assert(valid(Version) && index(Version) >= 0 && index(Version) < size);
static_assert(valid(Version) && index(Version) >= 0 && index(Version) < kSize);
return std::invoke(fn, json.val[index(Version)], version, std::forward<Args>(args)...);
}
@@ -108,7 +111,7 @@ struct MultiApiJson
operator()(Json& json, std::integral_constant<unsigned int, Version> const, Fn fn) const
-> std::invoke_result_t<Fn, decltype(json.val[0])>
{
static_assert(valid(Version) && index(Version) >= 0 && index(Version) < size);
static_assert(valid(Version) && index(Version) >= 0 && index(Version) < kSize);
return std::invoke(fn, json.val[index(Version)]);
}
@@ -121,8 +124,8 @@ struct MultiApiJson
-> std::invoke_result_t<Fn, decltype(json.val[0]), Version, Args&&...>
{
XRPL_ASSERT(
valid(version) && index(version) >= 0 && index(version) < size,
"xrpl::detail::MultiApiJson::operator<Args...>() : valid "
valid(version) && index(version) >= 0 && index(version) < kSize,
"xrpl::detail::MultiApijson::operator<Args...>() : valid "
"version");
return std::invoke(fn, json.val[index(version)], version, std::forward<Args>(args)...);
}
@@ -136,48 +139,48 @@ struct MultiApiJson
-> std::invoke_result_t<Fn, decltype(json.val[0])>
{
XRPL_ASSERT(
valid(version) && index(version) >= 0 && index(version) < size,
"xrpl::detail::MultiApiJson::operator() : valid version");
valid(version) && index(version) >= 0 && index(version) < kSize,
"xrpl::detail::MultiApijson::operator() : valid version");
return std::invoke(fn, json.val[index(version)]);
}
} visitor = {};
} kVisitor = {};
auto
visit()
{
return [self = this](auto... args)
requires requires {
visitor(std::declval<MultiApiJson&>(), std::declval<decltype(args)>()...);
kVisitor(std::declval<MultiApiJson&>(), std::declval<decltype(args)>()...);
}
{ return visitor(*self, std::forward<decltype(args)>(args)...); };
{ return kVisitor(*self, std::forward<decltype(args)>(args)...); };
}
auto
[[nodiscard]] auto
visit() const
{
return [self = this](auto... args)
requires requires {
visitor(std::declval<MultiApiJson const&>(), std::declval<decltype(args)>()...);
kVisitor(std::declval<MultiApiJson const&>(), std::declval<decltype(args)>()...);
}
{ return visitor(*self, std::forward<decltype(args)>(args)...); };
{ return kVisitor(*self, std::forward<decltype(args)>(args)...); };
}
template <typename... Args>
auto
visit(Args... args) -> std::invoke_result_t<visitor_t, MultiApiJson&, Args...>
visit(Args... args) -> std::invoke_result_t<VisitorT, MultiApiJson&, Args...>
requires(sizeof...(args) > 0) &&
requires { visitor(*this, std::forward<decltype(args)>(args)...); }
requires { kVisitor(*this, std::forward<decltype(args)>(args)...); }
{
return visitor(*this, std::forward<decltype(args)>(args)...);
return kVisitor(*this, std::forward<decltype(args)>(args)...);
}
template <typename... Args>
auto
visit(Args... args) const -> std::invoke_result_t<visitor_t, MultiApiJson const&, Args...>
[[nodiscard]] auto
visit(Args... args) const -> std::invoke_result_t<VisitorT, MultiApiJson const&, Args...>
requires(sizeof...(args) > 0) &&
requires { visitor(*this, std::forward<decltype(args)>(args)...); }
requires { kVisitor(*this, std::forward<decltype(args)>(args)...); }
{
return visitor(*this, std::forward<decltype(args)>(args)...);
return kVisitor(*this, std::forward<decltype(args)>(args)...);
}
};
@@ -185,6 +188,6 @@ struct MultiApiJson
// Wrapper for Json for all supported API versions.
using MultiApiJson =
detail::MultiApiJson<RPC::apiMinimumSupportedVersion, RPC::apiMaximumValidVersion>;
detail::MultiApiJson<RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion>;
} // namespace xrpl

View File

@@ -6,9 +6,7 @@
#include <memory>
namespace xrpl {
namespace RPC {
namespace xrpl::RPC {
/**
Adds common synthetic fields to transaction-related JSON responses
@@ -16,8 +14,7 @@ namespace RPC {
@{
*/
void
insertNFTSyntheticInJson(Json::Value&, std::shared_ptr<STTx const> const&, TxMeta const&);
insertNFTSyntheticInJson(json::Value&, std::shared_ptr<STTx const> const&, TxMeta const&);
/** @} */
} // namespace RPC
} // namespace xrpl
} // namespace xrpl::RPC

View File

@@ -30,7 +30,7 @@ getNFTokenIDFromDeletedOffer(TxMeta const& transactionMeta);
void
insertNFTokenID(
Json::Value& response,
json::Value& response,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta);
/** @} */

View File

@@ -27,7 +27,7 @@ getOfferIDFromCreatedOffer(TxMeta const& transactionMeta);
void
insertNFTokenOfferID(
Json::Value& response,
json::Value& response,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta);
/** @} */

View File

@@ -0,0 +1,134 @@
#pragma once
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Concepts.h>
namespace xrpl {
/* Represent STPathElement's asset, which can be Currency or MPTID.
*/
class PathAsset
{
private:
std::variant<Currency, MPTID> easset_;
public:
PathAsset() = default;
// Enables comparing Asset and PathAsset
PathAsset(Asset const& asset);
PathAsset(Currency const& currency) : easset_(currency)
{
}
PathAsset(MPTID const& mpt) : easset_(mpt)
{
}
template <ValidPathAsset T>
[[nodiscard]] constexpr bool
holds() const;
[[nodiscard]] constexpr bool
isXRP() const;
template <ValidPathAsset T>
T const&
get() const;
[[nodiscard]] constexpr std::variant<Currency, MPTID> const&
value() const;
// Custom, generic visit implementation
template <typename... Visitors>
constexpr auto
visit(Visitors&&... visitors) const -> decltype(auto)
{
// Simple delegation to the reusable utility, passing the internal
// variant data.
return detail::visit(easset_, std::forward<Visitors>(visitors)...);
}
friend constexpr bool
operator==(PathAsset const& lhs, PathAsset const& rhs);
};
template <ValidPathAsset PA>
constexpr bool kIsCurrencyV = std::is_same_v<PA, Currency>;
template <ValidPathAsset PA>
constexpr bool kIsMptidV = std::is_same_v<PA, MPTID>;
inline PathAsset::PathAsset(Asset const& asset)
{
asset.visit(
[&](Issue const& issue) { easset_ = issue.currency; },
[&](MPTIssue const& issue) { easset_ = issue.getMptID(); });
}
template <ValidPathAsset T>
constexpr bool
PathAsset::holds() const
{
return std::holds_alternative<T>(easset_);
}
template <ValidPathAsset T>
[[nodiscard]] [[nodiscard]] T const&
PathAsset::get() const
{
if (!holds<T>())
Throw<std::runtime_error>("PathAsset doesn't hold requested asset.");
return std::get<T>(easset_);
}
constexpr std::variant<Currency, MPTID> const&
PathAsset::value() const
{
return easset_;
}
constexpr bool
PathAsset::isXRP() const
{
return visit(
[&](Currency const& currency) { return xrpl::isXRP(currency); },
[](MPTID const&) { return false; });
}
constexpr bool
operator==(PathAsset const& lhs, PathAsset const& rhs)
{
return std::visit(
[]<ValidPathAsset TLhs, ValidPathAsset TRhs>(TLhs const& lhs, TRhs const& rhs) {
if constexpr (std::is_same_v<TLhs, TRhs>)
{
return lhs == rhs;
}
else
{
return false;
}
},
lhs.value(),
rhs.value());
}
template <typename Hasher>
void
hash_append(Hasher& h, PathAsset const& pathAsset)
{
std::visit([&]<ValidPathAsset T>(T const& e) { hash_append(h, e); }, pathAsset.value());
}
inline bool
isXRP(PathAsset const& asset)
{
return asset.isXRP();
}
std::string
to_string(PathAsset const& asset);
std::ostream&
operator<<(std::ostream& os, PathAsset const& x);
} // namespace xrpl

View File

@@ -10,7 +10,7 @@ namespace xrpl {
inline void
serializePayChanAuthorization(Serializer& msg, uint256 const& key, XRPAmount const& amt)
{
msg.add32(HashPrefix::paymentChannelClaim);
msg.add32(HashPrefix::PaymentChannelClaim);
msg.addBitString(key);
msg.add64(amt.drops());
}

View File

@@ -16,11 +16,13 @@ namespace xrpl {
* conflicts with TxType, the GranularPermissionType is always set to a value
* greater than the maximum value of uint16.
*/
// Macro-generated, complex
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum GranularPermissionType : std::uint32_t {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) type = value,
#define PERMISSION(type, txType, value) type = (value),
#include <xrpl/protocol/detail/permissions.macro>
@@ -28,7 +30,10 @@ enum GranularPermissionType : std::uint32_t {
#pragma pop_macro("PERMISSION")
};
enum Delegation { delegable, notDelegable };
// Injected bare enumerators (xrpl::delegable / xrpl::notDelegable) are required by preprocessor
// tricks in tests and macro-generated code; enum class would break that.
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum Delegation { Delegable, NotDelegable };
class Permission
{
@@ -53,22 +58,22 @@ public:
Permission&
operator=(Permission const&) = delete;
std::optional<std::string>
[[nodiscard]] std::optional<std::string>
getPermissionName(std::uint32_t const value) const;
std::optional<std::uint32_t>
[[nodiscard]] std::optional<std::uint32_t>
getGranularValue(std::string const& name) const;
std::optional<std::string>
[[nodiscard]] std::optional<std::string>
getGranularName(GranularPermissionType const& value) const;
std::optional<TxType>
[[nodiscard]] std::optional<TxType>
getGranularTxType(GranularPermissionType const& gpType) const;
std::optional<std::reference_wrapper<uint256 const>>
[[nodiscard]] std::optional<std::reference_wrapper<uint256 const>>
getTxFeature(TxType txType) const;
bool
[[nodiscard]] bool
isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const;
// for tx level permission, permission value is equal to tx type plus one

View File

@@ -19,40 +19,40 @@ namespace xrpl {
@ingroup protocol
*/
/** Smallest legal byte size of a transaction. */
std::size_t constexpr txMinSizeBytes = 32;
constexpr std::size_t kTxMinSizeBytes = 32;
/** Largest legal byte size of a transaction. */
std::size_t constexpr txMaxSizeBytes = megabytes(1);
constexpr std::size_t kTxMaxSizeBytes = megabytes(1);
/** The maximum number of unfunded offers to delete at once */
std::size_t constexpr unfundedOfferRemoveLimit = 1000;
constexpr std::size_t kUnfundedOfferRemoveLimit = 1000;
/** The maximum number of expired offers to delete at once */
std::size_t constexpr expiredOfferRemoveLimit = 256;
constexpr std::size_t kExpiredOfferRemoveLimit = 256;
/** The maximum number of metadata entries allowed in one transaction */
std::size_t constexpr oversizeMetaDataCap = 5200;
constexpr std::size_t kOversizeMetaDataCap = 5200;
/** The maximum number of entries per directory page */
std::size_t constexpr dirNodeMaxEntries = 32;
constexpr std::size_t kDirNodeMaxEntries = 32;
/** The maximum number of pages allowed in a directory
Made obsolete by fixDirectoryLimit amendment.
*/
std::uint64_t constexpr dirNodeMaxPages = 262144;
constexpr std::uint64_t kDirNodeMaxPages = 262144;
/** The maximum number of items in an NFT page */
std::size_t constexpr dirMaxTokensPerPage = 32;
constexpr std::size_t kDirMaxTokensPerPage = 32;
/** The maximum number of owner directory entries for account to be deletable */
std::size_t constexpr maxDeletableDirEntries = 1000;
constexpr std::size_t kMaxDeletableDirEntries = 1000;
/** The maximum number of token offers that can be canceled at once */
std::size_t constexpr maxTokenOfferCancelCount = 500;
constexpr std::size_t kMaxTokenOfferCancelCount = 500;
/** The maximum number of offers in an offer directory for NFT to be burnable */
std::size_t constexpr maxDeletableTokenOfferEntries = 500;
constexpr std::size_t kMaxDeletableTokenOfferEntries = 500;
/** The maximum token transfer fee allowed.
@@ -63,7 +63,7 @@ std::size_t constexpr maxDeletableTokenOfferEntries = 500;
Note that for extremely low transfer fees values, it is possible that the
calculated fee will be 0.
*/
std::uint16_t constexpr maxTransferFee = 50000;
constexpr std::uint16_t kMaxTransferFee = 50000;
/** There are 10,000 basis points (bips) in 100%.
*
@@ -81,32 +81,32 @@ std::uint16_t constexpr maxTransferFee = 50000;
*
* Example: 50% is 0.50 * bipsPerUnity = 5,000 bps.
*/
Bips32 constexpr bipsPerUnity(100 * 100);
static_assert(bipsPerUnity == Bips32{10'000});
TenthBips32 constexpr tenthBipsPerUnity(bipsPerUnity.value() * 10);
static_assert(tenthBipsPerUnity == TenthBips32(100'000));
constexpr Bips32 kBipsPerUnity(100 * 100);
static_assert(kBipsPerUnity == Bips32{10'000});
constexpr TenthBips32 kTenthBipsPerUnity(kBipsPerUnity.value() * 10);
static_assert(kTenthBipsPerUnity == TenthBips32(100'000));
constexpr Bips32
percentageToBips(std::uint32_t percentage)
{
return Bips32(percentage * bipsPerUnity.value() / 100);
return Bips32(percentage * kBipsPerUnity.value() / 100);
}
constexpr TenthBips32
percentageToTenthBips(std::uint32_t percentage)
{
return TenthBips32(percentage * tenthBipsPerUnity.value() / 100);
return TenthBips32(percentage * kTenthBipsPerUnity.value() / 100);
}
template <typename T, class TBips>
constexpr T
bipsOfValue(T value, Bips<TBips> bips)
{
return value * bips.value() / bipsPerUnity.value();
return value * bips.value() / kBipsPerUnity.value();
}
template <typename T, class TBips>
constexpr T
tenthBipsOfValue(T value, TenthBips<TBips> bips)
{
return value * bips.value() / tenthBipsPerUnity.value();
return value * bips.value() / kTenthBipsPerUnity.value();
}
namespace Lending {
@@ -114,54 +114,54 @@ namespace Lending {
Valid values are between 0 and 10% inclusive.
*/
TenthBips16 constexpr maxManagementFeeRate(
unsafe_cast<std::uint16_t>(percentageToTenthBips(10).value()));
static_assert(maxManagementFeeRate == TenthBips16(std::uint16_t(10'000u)));
constexpr TenthBips16 kMaxManagementFeeRate(
unsafeCast<std::uint16_t>(percentageToTenthBips(10).value()));
static_assert(kMaxManagementFeeRate == TenthBips16(std::uint16_t(10'000u)));
/** The maximum coverage rate required of a loan broker in 1/10 bips.
Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxCoverRate = percentageToTenthBips(100);
static_assert(maxCoverRate == TenthBips32(100'000u));
constexpr TenthBips32 kMaxCoverRate = percentageToTenthBips(100);
static_assert(kMaxCoverRate == TenthBips32(100'000u));
/** The maximum overpayment fee on a loan in 1/10 bips.
*
Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxOverpaymentFee = percentageToTenthBips(100);
static_assert(maxOverpaymentFee == TenthBips32(100'000u));
constexpr TenthBips32 kMaxOverpaymentFee = percentageToTenthBips(100);
static_assert(kMaxOverpaymentFee == TenthBips32(100'000u));
/** Annualized interest rate of the Loan in 1/10 bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxInterestRate = percentageToTenthBips(100);
static_assert(maxInterestRate == TenthBips32(100'000u));
constexpr TenthBips32 kMaxInterestRate = percentageToTenthBips(100);
static_assert(kMaxInterestRate == TenthBips32(100'000u));
/** The maximum premium added to the interest rate for late payments on a loan
* in 1/10 bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxLateInterestRate = percentageToTenthBips(100);
static_assert(maxLateInterestRate == TenthBips32(100'000u));
constexpr TenthBips32 kMaxLateInterestRate = percentageToTenthBips(100);
static_assert(kMaxLateInterestRate == TenthBips32(100'000u));
/** The maximum close interest rate charged for repaying a loan early in 1/10
* bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxCloseInterestRate = percentageToTenthBips(100);
static_assert(maxCloseInterestRate == TenthBips32(100'000u));
constexpr TenthBips32 kMaxCloseInterestRate = percentageToTenthBips(100);
static_assert(kMaxCloseInterestRate == TenthBips32(100'000u));
/** The maximum overpayment interest rate charged on loan overpayments in 1/10
* bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxOverpaymentInterestRate = percentageToTenthBips(100);
static_assert(maxOverpaymentInterestRate == TenthBips32(100'000u));
constexpr TenthBips32 kMaxOverpaymentInterestRate = percentageToTenthBips(100);
static_assert(kMaxOverpaymentInterestRate == TenthBips32(100'000u));
/** LoanPay transaction cost will be one base fee per X combined payments
*
@@ -172,7 +172,7 @@ static_assert(maxOverpaymentInterestRate == TenthBips32(100'000u));
* This number was chosen arbitrarily, but should not be changed once released
* without an amendment
*/
static constexpr int loanPaymentsPerFeeIncrement = 5;
static constexpr int kLoanPaymentsPerFeeIncrement = 5;
/** Maximum number of combined payments that a LoanPay transaction will process
*
@@ -196,65 +196,65 @@ static constexpr int loanPaymentsPerFeeIncrement = 5;
* This number was chosen arbitrarily, but should not be changed once released
* without an amendment
*/
static constexpr int loanMaximumPaymentsPerTransaction = 100;
static constexpr int kLoanMaximumPaymentsPerTransaction = 100;
} // namespace Lending
/** The maximum length of a URI inside an NFT */
std::size_t constexpr maxTokenURILength = 256;
constexpr std::size_t kMaxTokenUriLength = 256;
/** The maximum length of a Data element inside a DID */
std::size_t constexpr maxDIDDocumentLength = 256;
constexpr std::size_t kMaxDidDocumentLength = 256;
/** The maximum length of a URI inside a DID */
std::size_t constexpr maxDIDURILength = 256;
constexpr std::size_t kMaxDidUriLength = 256;
/** The maximum length of an Attestation inside a DID */
std::size_t constexpr maxDIDDataLength = 256;
constexpr std::size_t kMaxDidDataLength = 256;
/** The maximum length of a domain */
std::size_t constexpr maxDomainLength = 256;
constexpr std::size_t kMaxDomainLength = 256;
/** The maximum length of a URI inside a Credential */
std::size_t constexpr maxCredentialURILength = 256;
constexpr std::size_t kMaxCredentialUriLength = 256;
/** The maximum length of a CredentialType inside a Credential */
std::size_t constexpr maxCredentialTypeLength = 64;
constexpr std::size_t kMaxCredentialTypeLength = 64;
/** The maximum number of credentials can be passed in array */
std::size_t constexpr maxCredentialsArraySize = 8;
constexpr std::size_t kMaxCredentialsArraySize = 8;
/** The maximum number of credentials can be passed in array for permissioned
* domain */
std::size_t constexpr maxPermissionedDomainCredentialsArraySize = 10;
constexpr std::size_t kMaxPermissionedDomainCredentialsArraySize = 10;
/** The maximum length of MPTokenMetadata */
std::size_t constexpr maxMPTokenMetadataLength = 1024;
constexpr std::size_t kMaxMpTokenMetadataLength = 1024;
/** The maximum amount of MPTokenIssuance */
std::uint64_t constexpr maxMPTokenAmount = 0x7FFF'FFFF'FFFF'FFFFull;
static_assert(Number::maxRep >= maxMPTokenAmount);
constexpr std::uint64_t kMaxMpTokenAmount = 0x7FFF'FFFF'FFFF'FFFFull;
static_assert(Number::kMaxRep >= kMaxMpTokenAmount);
/** The maximum length of Data payload */
std::size_t constexpr maxDataPayloadLength = 256;
constexpr std::size_t kMaxDataPayloadLength = 256;
/** Vault withdrawal policies */
std::uint8_t constexpr vaultStrategyFirstComeFirstServe = 1;
constexpr std::uint8_t kVaultStrategyFirstComeFirstServe = 1;
/** Default IOU scale factor for a Vault */
std::uint8_t constexpr vaultDefaultIOUScale = 6;
constexpr std::uint8_t kVaultDefaultIouScale = 6;
/** Maximum scale factor for a Vault. The number is chosen to ensure that
1 IOU can be always converted to shares.
10^19 > maxMPTokenAmount (2^64-1) > 10^18 */
std::uint8_t constexpr vaultMaximumIOUScale = 18;
constexpr std::uint8_t kVaultMaximumIouScale = 18;
/** Maximum recursion depth for vault shares being put as an asset inside
* another vault; counted from 0 */
std::uint8_t constexpr maxAssetCheckDepth = 5;
constexpr std::uint8_t kMaxAssetCheckDepth = 5;
/** A ledger index. */
using LedgerIndex = std::uint32_t;
std::uint32_t constexpr FLAG_LEDGER_INTERVAL = 256;
constexpr std::uint32_t kFlagLedgerInterval = 256;
/** Returns true if the given ledgerIndex is a voting ledgerIndex */
bool
@@ -273,38 +273,38 @@ using TxID = uint256;
/** The maximum number of trustlines to delete as part of AMM account
* deletion cleanup.
*/
std::uint16_t constexpr maxDeletableAMMTrustLines = 512;
constexpr std::uint16_t kMaxDeletableAmmTrustLines = 512;
/** The maximum length of a URI inside an Oracle */
std::size_t constexpr maxOracleURI = 256;
constexpr std::size_t kMaxOracleUri = 256;
/** The maximum length of a Provider inside an Oracle */
std::size_t constexpr maxOracleProvider = 256;
constexpr std::size_t kMaxOracleProvider = 256;
/** The maximum size of a data series array inside an Oracle */
std::size_t constexpr maxOracleDataSeries = 10;
constexpr std::size_t kMaxOracleDataSeries = 10;
/** The maximum length of a SymbolClass inside an Oracle */
std::size_t constexpr maxOracleSymbolClass = 16;
constexpr std::size_t kMaxOracleSymbolClass = 16;
/** The maximum allowed time difference between lastUpdateTime and the time
of the last closed ledger
*/
std::size_t constexpr maxLastUpdateTimeDelta = 300;
constexpr std::size_t kMaxLastUpdateTimeDelta = 300;
/** The maximum price scaling factor
*/
std::size_t constexpr maxPriceScale = 20;
constexpr std::size_t kMaxPriceScale = 20;
/** The maximum percentage of outliers to trim
*/
std::size_t constexpr maxTrim = 25;
constexpr std::size_t kMaxTrim = 25;
/** The maximum number of delegate permissions an account can grant
*/
std::size_t constexpr permissionMaxSize = 10;
constexpr std::size_t kPermissionMaxSize = 10;
/** The maximum number of transactions that can be in a batch. */
std::size_t constexpr maxBatchTxCount = 8;
constexpr std::size_t kMaxBatchTxCount = 8;
} // namespace xrpl

View File

@@ -21,7 +21,7 @@ namespace xrpl {
Public keys are used in the public-key cryptography
system used to verify signatures attached to messages.
The format of the public key is Ripple specific,
The format of the public key is XRPL specific,
information needed to determine the cryptosystem
parameters used is stored inside the key.
@@ -43,8 +43,8 @@ class PublicKey
protected:
// All the constructed public keys are valid, non-empty and contain 33
// bytes of data.
static constexpr std::size_t size_ = 33;
std::uint8_t buf_[size_]{}; // should be large enough
static constexpr std::size_t kSize = 33;
std::uint8_t buf_[kSize]{}; // should be large enough
public:
using const_iterator = std::uint8_t const*;
@@ -63,46 +63,46 @@ public:
*/
explicit PublicKey(Slice const& slice);
std::uint8_t const*
[[nodiscard]] std::uint8_t const*
data() const noexcept
{
return buf_;
}
std::size_t
size() const noexcept
static std::size_t
size() noexcept
{
return size_;
return kSize;
}
const_iterator
[[nodiscard]] const_iterator
begin() const noexcept
{
return buf_;
}
const_iterator
[[nodiscard]] const_iterator
cbegin() const noexcept
{
return buf_;
}
const_iterator
[[nodiscard]] const_iterator
end() const noexcept
{
return buf_ + size_;
return buf_ + kSize;
}
const_iterator
[[nodiscard]] const_iterator
cend() const noexcept
{
return buf_ + size_;
return buf_ + kSize;
}
Slice
[[nodiscard]] Slice
slice() const noexcept
{
return {buf_, size_};
return {buf_, kSize};
}
operator Slice() const noexcept
@@ -168,7 +168,7 @@ template <>
std::optional<PublicKey>
parseBase58(TokenType type, std::string const& s);
enum class ECDSACanonicality { canonical, fullyCanonical };
enum class ECDSACanonicality { Canonical, FullyCanonical };
/** Determines the canonicality of a signature.
@@ -260,14 +260,15 @@ getFingerprint(
//------------------------------------------------------------------------------
namespace Json {
namespace json {
template <>
inline xrpl::PublicKey
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
std::string const b58 = getOrThrow<std::string>(v, field);
if (auto pubKeyBlob = strUnHex(b58); publicKeyType(makeSlice(*pubKeyBlob)))
if (auto pubKeyBlob = strUnHex(b58);
pubKeyBlob.has_value() && publicKeyType(makeSlice(*pubKeyBlob)))
{
return PublicKey{makeSlice(*pubKeyBlob)};
}
@@ -278,4 +279,4 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
}
Throw<JsonTypeMismatchError>(field.getJsonName(), "PublicKey");
}
} // namespace Json
} // namespace json

View File

@@ -8,6 +8,7 @@
#include <algorithm>
#include <cstdint>
#include <ostream>
#include <utility>
namespace xrpl {
@@ -25,19 +26,19 @@ struct TAmounts
{
TAmounts() = default;
TAmounts(beast::Zero, beast::Zero) : in(beast::zero), out(beast::zero)
TAmounts(beast::Zero, beast::Zero) : in(beast::kZero), out(beast::kZero)
{
}
TAmounts(In const& in_, Out const& out_) : in(in_), out(out_)
TAmounts(In in, Out out) : in(std::move(in)), out(std::move(out))
{
}
/** Returns `true` if either quantity is not positive. */
bool
[[nodiscard]] bool
empty() const noexcept
{
return in <= beast::zero || out <= beast::zero;
return in <= beast::kZero || out <= beast::kZero;
}
TAmounts&
@@ -56,8 +57,8 @@ struct TAmounts
return *this;
}
In in;
Out out;
In in{};
Out out{};
};
using Amounts = TAmounts<STAmount, STAmount>;
@@ -78,7 +79,7 @@ operator!=(TAmounts<In, Out> const& lhs, TAmounts<In, Out> const& rhs) noexcept
//------------------------------------------------------------------------------
// Ripple specific constant used for parsing qualities and other things
// XRPL specific constant used for parsing qualities and other things
#define QUALITY_ONE 1'000'000'000
/** Represents the logical ratio of output currency to input currency.
@@ -93,15 +94,15 @@ public:
// have lower unsigned integer representations.
using value_type = std::uint64_t;
static int const minTickSize = 3;
static int const maxTickSize = 16;
static int const kMinTickSize = 3;
static int const kMaxTickSize = 16;
private:
// This has the same representation as STAmount, see the comment on the
// STAmount. However, this class does not always use the canonical
// representation. In particular, the increment and decrement operators may
// cause a non-canonical representation.
value_type m_value;
value_type value_;
public:
Quality() = default;
@@ -144,16 +145,16 @@ public:
/** @} */
/** Returns the quality as STAmount. */
STAmount
[[nodiscard]] STAmount
rate() const
{
return amountFromQuality(m_value);
return amountFromQuality(value_);
}
/** Returns the quality rounded up to the specified number
of decimal digits.
*/
Quality
[[nodiscard]] Quality
round(int tickSize) const;
/** Returns the scaled amount with in capped.
@@ -161,42 +162,42 @@ public:
to prevent money creation.
*/
[[nodiscard]] Amounts
ceil_in(Amounts const& amount, STAmount const& limit) const;
ceilIn(Amounts const& amount, STAmount const& limit) const;
template <class In, class Out>
[[nodiscard]] TAmounts<In, Out>
ceil_in(TAmounts<In, Out> const& amount, In const& limit) const;
ceilIn(TAmounts<In, Out> const& amount, In const& limit) const;
// Some of the underlying rounding functions called by ceil_in() ignored
// low order bits that could influence rounding decisions. This "strict"
// method uses underlying functions that pay attention to all the bits.
[[nodiscard]] Amounts
ceil_in_strict(Amounts const& amount, STAmount const& limit, bool roundUp) const;
ceilInStrict(Amounts const& amount, STAmount const& limit, bool roundUp) const;
template <class In, class Out>
[[nodiscard]] TAmounts<In, Out>
ceil_in_strict(TAmounts<In, Out> const& amount, In const& limit, bool roundUp) const;
ceilInStrict(TAmounts<In, Out> const& amount, In const& limit, bool roundUp) const;
/** Returns the scaled amount with out capped.
Math is avoided if the result is exact. The input is clamped
to prevent money creation.
*/
[[nodiscard]] Amounts
ceil_out(Amounts const& amount, STAmount const& limit) const;
ceilOut(Amounts const& amount, STAmount const& limit) const;
template <class In, class Out>
[[nodiscard]] TAmounts<In, Out>
ceil_out(TAmounts<In, Out> const& amount, Out const& limit) const;
ceilOut(TAmounts<In, Out> const& amount, Out const& limit) const;
// Some of the underlying rounding functions called by ceil_out() ignored
// low order bits that could influence rounding decisions. This "strict"
// method uses underlying functions that pay attention to all the bits.
[[nodiscard]] Amounts
ceil_out_strict(Amounts const& amount, STAmount const& limit, bool roundUp) const;
ceilOutStrict(Amounts const& amount, STAmount const& limit, bool roundUp) const;
template <class In, class Out>
[[nodiscard]] TAmounts<In, Out>
ceil_out_strict(TAmounts<In, Out> const& amount, Out const& limit, bool roundUp) const;
ceilOutStrict(TAmounts<In, Out> const& amount, Out const& limit, bool roundUp) const;
private:
// The ceil_in and ceil_out methods that deal in TAmount all convert
@@ -204,11 +205,11 @@ private:
// This helper function takes care of all the conversion operations.
template <class In, class Out, class Lim, typename FnPtr, std::same_as<bool>... Round>
[[nodiscard]] TAmounts<In, Out>
ceil_TAmounts_helper(
ceilTAmountsHelper(
TAmounts<In, Out> const& amount,
Lim const& limit,
Lim const& limit_cmp,
FnPtr ceil_function,
Lim const& limitCmp,
FnPtr ceilFunction,
Round... round) const;
public:
@@ -219,13 +220,13 @@ public:
friend bool
operator<(Quality const& lhs, Quality const& rhs) noexcept
{
return lhs.m_value > rhs.m_value;
return lhs.value_ > rhs.value_;
}
friend bool
operator>(Quality const& lhs, Quality const& rhs) noexcept
{
return lhs.m_value < rhs.m_value;
return lhs.value_ < rhs.value_;
}
friend bool
@@ -243,7 +244,7 @@ public:
friend bool
operator==(Quality const& lhs, Quality const& rhs) noexcept
{
return lhs.m_value == rhs.m_value;
return lhs.value_ == rhs.value_;
}
friend bool
@@ -255,7 +256,7 @@ public:
friend std::ostream&
operator<<(std::ostream& os, Quality const& quality)
{
os << quality.m_value;
os << quality.value_;
return os;
}
@@ -265,12 +266,12 @@ public:
relativeDistance(Quality const& q1, Quality const& q2)
{
XRPL_ASSERT(
q1.m_value > 0 && q2.m_value > 0, "xrpl::Quality::relativeDistance : minimum inputs");
q1.value_ > 0 && q2.value_ > 0, "xrpl::Quality::relativeDistance : minimum inputs");
if (q1.m_value == q2.m_value) // make expected common case fast
if (q1.value_ == q2.value_) // make expected common case fast
return 0;
auto const [minV, maxV] = std::minmax(q1.m_value, q2.m_value);
auto const [minV, maxV] = std::minmax(q1.value_, q2.value_);
auto mantissa = [](std::uint64_t rate) { return rate & ~(255ull << (64 - 8)); };
auto exponent = [](std::uint64_t rate) { return static_cast<int>(rate >> (64 - 8)) - 100; };
@@ -281,7 +282,7 @@ public:
double const minVD = static_cast<double>(minVMantissa);
double const maxVD =
expDiff ? maxVMantissa * pow(10, expDiff) : static_cast<double>(maxVMantissa);
(expDiff != 0) ? maxVMantissa * pow(10, expDiff) : static_cast<double>(maxVMantissa);
// maxVD and minVD are scaled so they have the same exponents. Dividing
// cancels out the exponents, so we only need to deal with the (scaled)
@@ -292,66 +293,66 @@ public:
template <class In, class Out, class Lim, typename FnPtr, std::same_as<bool>... Round>
TAmounts<In, Out>
Quality::ceil_TAmounts_helper(
Quality::ceilTAmountsHelper(
TAmounts<In, Out> const& amount,
Lim const& limit,
Lim const& limit_cmp,
FnPtr ceil_function,
Lim const& limitCmp,
FnPtr ceilFunction,
Round... roundUp) const
{
if (limit_cmp <= limit)
if (limitCmp <= limit)
return amount;
// Use the existing STAmount implementation for now, but consider
// replacing with code specific to IOUAMount and XRPAmount
Amounts stAmt(toSTAmount(amount.in), toSTAmount(amount.out));
STAmount stLim(toSTAmount(limit));
Amounts const stRes = ((*this).*ceil_function)(stAmt, stLim, roundUp...);
Amounts const stAmt(toSTAmount(amount.in), toSTAmount(amount.out));
STAmount const stLim(toSTAmount(limit));
Amounts const stRes = ((*this).*ceilFunction)(stAmt, stLim, roundUp...);
return TAmounts<In, Out>(toAmount<In>(stRes.in), toAmount<Out>(stRes.out));
}
template <class In, class Out>
TAmounts<In, Out>
Quality::ceil_in(TAmounts<In, Out> const& amount, In const& limit) const
Quality::ceilIn(TAmounts<In, Out> const& amount, In const& limit) const
{
// Construct a function pointer to the function we want to call.
static constexpr Amounts (Quality::*ceil_in_fn_ptr)(Amounts const&, STAmount const&) const =
&Quality::ceil_in;
static constexpr Amounts (Quality::*kCeilInFnPtr)(Amounts const&, STAmount const&) const =
&Quality::ceilIn;
return ceil_TAmounts_helper(amount, limit, amount.in, ceil_in_fn_ptr);
return ceilTAmountsHelper(amount, limit, amount.in, kCeilInFnPtr);
}
template <class In, class Out>
TAmounts<In, Out>
Quality::ceil_in_strict(TAmounts<In, Out> const& amount, In const& limit, bool roundUp) const
Quality::ceilInStrict(TAmounts<In, Out> const& amount, In const& limit, bool roundUp) const
{
// Construct a function pointer to the function we want to call.
static constexpr Amounts (Quality::*ceil_in_fn_ptr)(Amounts const&, STAmount const&, bool)
const = &Quality::ceil_in_strict;
static constexpr Amounts (Quality::*kCeilInFnPtr)(Amounts const&, STAmount const&, bool) const =
&Quality::ceilInStrict;
return ceil_TAmounts_helper(amount, limit, amount.in, ceil_in_fn_ptr, roundUp);
return ceilTAmountsHelper(amount, limit, amount.in, kCeilInFnPtr, roundUp);
}
template <class In, class Out>
TAmounts<In, Out>
Quality::ceil_out(TAmounts<In, Out> const& amount, Out const& limit) const
Quality::ceilOut(TAmounts<In, Out> const& amount, Out const& limit) const
{
// Construct a function pointer to the function we want to call.
static constexpr Amounts (Quality::*ceil_out_fn_ptr)(Amounts const&, STAmount const&) const =
&Quality::ceil_out;
static constexpr Amounts (Quality::*kCeilOutFnPtr)(Amounts const&, STAmount const&) const =
&Quality::ceilOut;
return ceil_TAmounts_helper(amount, limit, amount.out, ceil_out_fn_ptr);
return ceil_TAmounts_helper(amount, limit, amount.out, kCeilOutFnPtr);
}
template <class In, class Out>
TAmounts<In, Out>
Quality::ceil_out_strict(TAmounts<In, Out> const& amount, Out const& limit, bool roundUp) const
Quality::ceilOutStrict(TAmounts<In, Out> const& amount, Out const& limit, bool roundUp) const
{
// Construct a function pointer to the function we want to call.
static constexpr Amounts (Quality::*ceil_out_fn_ptr)(Amounts const&, STAmount const&, bool)
const = &Quality::ceil_out_strict;
static constexpr Amounts (Quality::*kCeilOutFnPtr)(Amounts const&, STAmount const&, bool)
const = &Quality::ceilOutStrict;
return ceil_TAmounts_helper(amount, limit, amount.out, ceil_out_fn_ptr, roundUp);
return ceilTAmountsHelper(amount, limit, amount.out, kCeilOutFnPtr, roundUp);
}
/** Calculate the quality of a two-hop path given the two hops.
@@ -359,6 +360,6 @@ Quality::ceil_out_strict(TAmounts<In, Out> const& amount, Out const& limit, bool
@param rhs The second leg of the path: intermediate to output.
*/
Quality
composed_quality(Quality const& lhs, Quality const& rhs);
composedQuality(Quality const& lhs, Quality const& rhs);
} // namespace xrpl

View File

@@ -53,13 +53,13 @@ public:
/** Return true if the quality function is constant
*/
bool
[[nodiscard]] bool
isConst() const
{
return quality_.has_value();
}
std::optional<Quality> const&
[[nodiscard]] std::optional<Quality> const&
quality() const
{
return quality_;
@@ -72,7 +72,7 @@ QualityFunction::QualityFunction(
std::uint32_t tfee,
QualityFunction::AMMTag)
{
if (amounts.in <= beast::zero || amounts.out <= beast::zero)
if (amounts.in <= beast::kZero || amounts.out <= beast::kZero)
Throw<std::runtime_error>("QualityFunction amounts are 0.");
Number const cfee = feeMult(tfee);
m_ = -cfee / amounts.in;

View File

@@ -22,7 +22,7 @@ optional fields easier to read:
- The operation `x[~sfFoo]` means "return the value of 'Foo'
if it exists, or nothing if it doesn't." This usage of the
tilde/bitwise NOT operator is not standard outside of the
`rippled` codebase.
`xrpld` codebase.
- As a consequence of this, `x[~sfFoo] = y[~sfFoo]`
assigns the value of Foo from y to x, including omitting
Foo from x if it doesn't exist in y.
@@ -33,7 +33,7 @@ or may not hold a value. For things not guaranteed to exist,
you use `x[~sfFoo]` because you want such a container. It
avoids having to look something up twice, once just to see if
it exists and a second time to get/set its value.
([Real example](https://github.com/ripple/rippled/blob/35f4698aed5dce02f771b34cfbb690495cb5efcc/src/ripple/app/tx/impl/PayChan.cpp#L229-L236))
([Real example](https://github.com/XRPLF/rippled/blob/35f4698aed5dce02f771b34cfbb690495cb5efcc/src/ripple/app/tx/impl/PayChan.cpp#L229-L236))
The source of this "type magic" is in
[SField.h](./SField.h#L296-L302).

View File

@@ -1,13 +1,14 @@
#pragma once
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/ErrorCodes.h>
namespace xrpl {
// VFALCO NOTE these are deprecated
bool
isRpcError(Json::Value jvResult);
Json::Value
rpcError(error_code_i iError);
isRpcError(json::Value jvResult);
json::Value
rpcError(ErrorCodeI iError);
} // namespace xrpl

View File

@@ -72,6 +72,6 @@ transferFeeAsRate(std::uint16_t fee);
} // namespace nft
/** A transfer rate signifying a 1:1 exchange */
extern Rate const parityRate;
extern Rate const kParityRate;
} // namespace xrpl

View File

@@ -6,4 +6,4 @@ namespace xrpl {
using LedgerHash = uint256;
}
} // namespace xrpl

View File

@@ -8,6 +8,21 @@
namespace xrpl {
/** Check whether a feature is enabled in the current ledger rules
*
* @param feature The feature to be tested.
* @param resultIfNoRules What to return if called from outside a Transactor context.
*/
bool
isFeatureEnabled(uint256 const& feature, bool resultIfNoRules);
/** Check whether a feature is enabled in the current ledger rules
*
* @param feature The feature to be tested.
*
* Returns false if no global Rules object is available. i.e. Outside of
* a Transactor context
*/
bool
isFeatureEnabled(uint256 const& feature);
@@ -41,7 +56,7 @@ public:
These are the rules reflected by
the genesis ledger.
*/
explicit Rules(std::unordered_set<uint256, beast::uhash<>> const& presets);
explicit Rules(std::unordered_set<uint256, beast::Uhash<>> const& presets);
private:
// Allow a friend function to construct Rules.
@@ -51,19 +66,19 @@ private:
friend Rules
makeRulesGivenLedger(
DigestAwareReadView const& ledger,
std::unordered_set<uint256, beast::uhash<>> const& presets);
std::unordered_set<uint256, beast::Uhash<>> const& presets);
Rules(
std::unordered_set<uint256, beast::uhash<>> const& presets,
std::unordered_set<uint256, beast::Uhash<>> const& presets,
std::optional<uint256> const& digest,
STVector256 const& amendments);
std::unordered_set<uint256, beast::uhash<>> const&
[[nodiscard]] std::unordered_set<uint256, beast::Uhash<>> const&
presets() const;
public:
/** Returns `true` if a feature is enabled. */
bool
[[nodiscard]] bool
enabled(uint256 const& feature) const;
/** Returns `true` if two rule sets are identical.
@@ -107,4 +122,17 @@ private:
std::optional<Rules> saved_;
};
class NumberSO;
class NumberMantissaScaleGuard;
bool
useRulesGuards(Rules const& rules);
void
createGuards(
Rules const& rules,
std::optional<NumberSO>& stNumberSO,
std::optional<CurrentTransactionRulesGuard>& rulesGuard,
std::optional<NumberMantissaScaleGuard>& mantissaScaleGuard);
} // namespace xrpl

View File

@@ -34,6 +34,7 @@ class STXChainBridge;
class STVector256;
class STCurrency;
// NOLINTBEGIN(readability-identifier-naming)
#pragma push_macro("XMACRO")
#undef XMACRO
@@ -84,12 +85,14 @@ class STCurrency;
#pragma push_macro("TO_MAP")
#undef TO_MAP
#define TO_ENUM(name, value) name = value,
#define TO_ENUM(name, value) name = (value),
#define TO_MAP(name, value) {#name, value},
// Protocol infrastructure, 39+ files
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum SerializedTypeID { XMACRO(TO_ENUM) };
static std::map<std::string, int> const sTypeMap = {XMACRO(TO_MAP)};
static std::map<std::string, int> const kSTypeMap = {XMACRO(TO_MAP)};
#undef XMACRO
#undef TO_ENUM
@@ -97,17 +100,18 @@ static std::map<std::string, int> const sTypeMap = {XMACRO(TO_MAP)};
#pragma pop_macro("XMACRO")
#pragma pop_macro("TO_ENUM")
#pragma pop_macro("TO_MAP")
// NOLINTEND(readability-identifier-naming)
// constexpr
inline int
field_code(SerializedTypeID id, int index)
fieldCode(SerializedTypeID id, int index)
{
return (safe_cast<int>(id) << 16) | index;
return (safeCast<int>(id) << 16) | index;
}
// constexpr
inline int
field_code(int id, int index)
fieldCode(int id, int index)
{
return (id << 16) | index;
}
@@ -125,33 +129,32 @@ field_code(int id, int index)
class SField
{
public:
enum {
sMD_Never = 0x00,
sMD_ChangeOrig = 0x01, // original value when it changes
sMD_ChangeNew = 0x02, // new value when it changes
sMD_DeleteFinal = 0x04, // final value when it is deleted
sMD_Create = 0x08, // value when it's created
sMD_Always = 0x10, // value when node containing it is affected at all
sMD_BaseTen = 0x20, // value is treated as base 10, overriding behavior
sMD_PseudoAccount = 0x40, // if this field is set in an ACCOUNT_ROOT
// _only_, then it is a pseudo-account
sMD_NeedsAsset = 0x80, // This field needs to be associated with an
// asset before it is serialized as a ledger
// object. Intended for STNumber.
sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create
};
static constexpr auto kSmdNever = 0x00;
static constexpr auto kSmdChangeOrig = 0x01; // original value when it changes
static constexpr auto kSmdChangeNew = 0x02; // new value when it changes
static constexpr auto kSmdDeleteFinal = 0x04; // final value when it is deleted
static constexpr auto kSmdCreate = 0x08; // value when it's created
static constexpr auto kSmdAlways = 0x10; // value when node containing it is affected at all
static constexpr auto kSmdBaseTen = 0x20; // value is treated as base 10, overriding behavior
static constexpr auto kSmdPseudoAccount = 0x40; // if this field is set in an ACCOUNT_ROOT
// _only_, then it is a pseudo-account
static constexpr auto kSmdNeedsAsset = 0x80; // This field needs to be associated with an
// asset before it is serialized as a ledger
// object. Intended for STNumber.
static constexpr auto kSmdDefault =
kSmdChangeOrig | kSmdChangeNew | kSmdDeleteFinal | kSmdCreate;
enum class IsSigning : unsigned char { no, yes };
static IsSigning const notSigning = IsSigning::no;
enum class IsSigning : unsigned char { No, Yes };
static IsSigning const kNotSigning = IsSigning::No;
int const fieldCode; // (type<<16)|index
int const fieldCodeMem; // (type<<16)|index // TODO: rename, clashes with function
SerializedTypeID const fieldType; // STI_*
int const fieldValue; // Code number for protocol
std::string const fieldName;
int const fieldMeta;
int const fieldNum;
IsSigning const signingField;
Json::StaticString const jsonName;
json::StaticString const jsonName;
SField(SField const&) = delete;
SField&
@@ -161,17 +164,17 @@ public:
operator=(SField&&) = delete;
public:
struct private_access_tag_t; // public, but still an implementation detail
struct PrivateAccessTagT; // public, but still an implementation detail
// These constructors can only be called from SField.cpp
SField(
private_access_tag_t,
PrivateAccessTagT,
SerializedTypeID tid,
int fv,
char const* fn,
int meta = sMD_Default,
IsSigning signing = IsSigning::yes);
explicit SField(private_access_tag_t, int fc, char const* fn);
int meta = kSmdDefault,
IsSigning signing = IsSigning::Yes);
explicit SField(PrivateAccessTagT, int fc, char const* fn);
static SField const&
getField(int fieldCode);
@@ -180,51 +183,51 @@ public:
static SField const&
getField(int type, int value)
{
return getField(field_code(type, value));
return getField(fieldCode(type, value));
}
static SField const&
getField(SerializedTypeID type, int value)
{
return getField(field_code(type, value));
return getField(fieldCode(type, value));
}
std::string const&
[[nodiscard]] std::string const&
getName() const
{
return fieldName;
}
bool
[[nodiscard]] bool
hasName() const
{
return fieldCode > 0;
return fieldCodeMem > 0;
}
Json::StaticString const&
[[nodiscard]] json::StaticString const&
getJsonName() const
{
return jsonName;
}
operator Json::StaticString const&() const
operator json::StaticString const&() const
{
return jsonName;
}
bool
[[nodiscard]] bool
isInvalid() const
{
return fieldCode == -1;
return fieldCodeMem == -1;
}
bool
[[nodiscard]] bool
isUseful() const
{
return fieldCode > 0;
return fieldCodeMem > 0;
}
bool
[[nodiscard]] bool
isBinary() const
{
return fieldValue < 256;
@@ -234,18 +237,18 @@ public:
// should be discarded during serialization,like 'hash'.
// You cannot serialize an object's hash inside that object,
// but you can have it in the JSON representation.
bool
[[nodiscard]] bool
isDiscardable() const
{
return fieldValue > 256;
}
int
[[nodiscard]] int
getCode() const
{
return fieldCode;
return fieldCodeMem;
}
int
[[nodiscard]] int
getNum() const
{
return fieldNum;
@@ -256,28 +259,28 @@ public:
return num;
}
bool
[[nodiscard]] bool
shouldMeta(int c) const
{
return (fieldMeta & c) != 0;
}
bool
[[nodiscard]] bool
shouldInclude(bool withSigningField) const
{
return (fieldValue < 256) && (withSigningField || (signingField == IsSigning::yes));
return (fieldValue < 256) && (withSigningField || (signingField == IsSigning::Yes));
}
bool
operator==(SField const& f) const
{
return fieldCode == f.fieldCode;
return fieldCodeMem == f.fieldCodeMem;
}
bool
operator!=(SField const& f) const
{
return fieldCode != f.fieldCode;
return fieldCodeMem != f.fieldCodeMem;
}
static int
@@ -302,7 +305,7 @@ struct TypedField : SField
using type = T;
template <class... Args>
explicit TypedField(private_access_tag_t pat, Args&&... args);
explicit TypedField(PrivateAccessTagT pat, Args&&... args);
};
/** Indicate std::optional field semantics. */
@@ -311,7 +314,7 @@ struct OptionaledField
{
TypedField<T> const* f;
explicit OptionaledField(TypedField<T> const& f_) : f(&f_)
explicit OptionaledField(TypedField<T> const& f) : f(&f)
{
}
};
@@ -362,8 +365,8 @@ using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
#define UNTYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) extern SField const sfName;
#define TYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) extern SF_##stiSuffix const sfName;
extern SField const sfInvalid;
extern SField const sfGeneric;
extern SField const sfInvalid; // NOLINT(readability-identifier-naming)
extern SField const sfGeneric; // NOLINT(readability-identifier-naming)
#include <xrpl/protocol/detail/sfields.macro>

View File

@@ -11,17 +11,21 @@
namespace xrpl {
/** Kind of element in each entry of an SOTemplate. */
// 2026 usages, 129 files
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum SOEStyle {
soeINVALID = -1,
soeREQUIRED = 0, // required
soeOPTIONAL = 1, // optional, may be present with default value
soeDEFAULT = 2, // optional, if present, must not have default value
SoeInvalid = -1,
SoeRequired = 0, // required
SoeOptional = 1, // optional, may be present with default value
SoeDefault = 2, // optional, if present, must not have default value
// inner object with the default fields has to be
// constructed with STObject::makeInnerObject()
};
// Part of a Python-parsed DSL (transactions.macro); bare enumerator names required by the parser
/** Amount fields that can support MPT */
enum SOETxMPTIssue { soeMPTNone, soeMPTSupported, soeMPTNotSupported };
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum SOETxMPTIssue { SoeMptNone, SoeMptSupported, SoeMptNotSupported };
//------------------------------------------------------------------------------
@@ -31,7 +35,7 @@ class SOElement
// Use std::reference_wrapper so SOElement can be stored in a std::vector.
std::reference_wrapper<SField const> sField_;
SOEStyle style_;
SOETxMPTIssue supportMpt_ = soeMPTNone;
SOETxMPTIssue supportMpt_ = SoeMptNone;
private:
void
@@ -57,25 +61,25 @@ public:
SOElement(
TypedField<T> const& fieldName,
SOEStyle style,
SOETxMPTIssue supportMpt = soeMPTNotSupported)
SOETxMPTIssue supportMpt = SoeMptNotSupported)
: sField_(fieldName), style_(style), supportMpt_(supportMpt)
{
init(fieldName);
}
SField const&
[[nodiscard]] SField const&
sField() const
{
return sField_.get();
}
SOEStyle
[[nodiscard]] SOEStyle
style() const
{
return style_;
}
SOETxMPTIssue
[[nodiscard]] SOETxMPTIssue
supportMPT() const
{
return supportMpt_;
@@ -110,42 +114,42 @@ public:
std::initializer_list<SOElement> commonFields = {});
/* Provide for the enumeration of fields */
std::vector<SOElement>::const_iterator
[[nodiscard]] std::vector<SOElement>::const_iterator
begin() const
{
return elements_.cbegin();
}
std::vector<SOElement>::const_iterator
[[nodiscard]] std::vector<SOElement>::const_iterator
cbegin() const
{
return begin();
}
std::vector<SOElement>::const_iterator
[[nodiscard]] std::vector<SOElement>::const_iterator
end() const
{
return elements_.cend();
}
std::vector<SOElement>::const_iterator
[[nodiscard]] std::vector<SOElement>::const_iterator
cend() const
{
return end();
}
/** The number of entries in this template */
std::size_t
[[nodiscard]] std::size_t
size() const
{
return elements_.size();
}
/** Retrieve the position of a named field. */
int
[[nodiscard]] int
getIndex(SField const&) const;
SOEStyle
[[nodiscard]] SOEStyle
style(SField const& sf) const
{
return elements_[indices_[sf.getNum()]].style();

View File

@@ -13,7 +13,7 @@ class STAccount final : public STBase, public CountedObject<STAccount>
private:
// The original implementation of STAccount kept the value in an STBlob.
// But an STAccount is always 160 bits, so we can store it with less
// overhead in a xrpl::uint160. However, so the serialized format of the
// overhead in an xrpl::uint160. However, so the serialized format of the
// STAccount stays unchanged, we serialize and deserialize like an STBlob.
AccountID value_;
bool default_;
@@ -28,25 +28,25 @@ public:
STAccount(SerialIter& sit, SField const& name);
STAccount(SField const& n, AccountID const& v);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getText() const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
STAccount&
operator=(AccountID const& value);
AccountID const&
[[nodiscard]] AccountID const&
value() const noexcept;
void

View File

@@ -3,11 +3,13 @@
#include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/LocalValue.h>
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTAmount.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/Serializer.h>
@@ -34,39 +36,39 @@ public:
using rep = std::pair<mantissa_type, exponent_type>;
private:
Asset mAsset;
mantissa_type mValue;
exponent_type mOffset;
bool mIsNegative;
Asset asset_;
mantissa_type value_{};
exponent_type offset_;
bool isNegative_{};
public:
using value_type = STAmount;
static int constexpr cMinOffset = -96;
static int constexpr cMaxOffset = 80;
static constexpr int kMinOffset = -96;
static constexpr int kMaxOffset = 80;
// Maximum native value supported by the code
constexpr static std::uint64_t cMinValue = 1'000'000'000'000'000ull;
static_assert(isPowerOfTen(cMinValue));
constexpr static std::uint64_t cMaxValue = cMinValue * 10 - 1;
static_assert(cMaxValue == 9'999'999'999'999'999ull);
constexpr static std::uint64_t cMaxNative = 9'000'000'000'000'000'000ull;
static constexpr std::uint64_t kMinValue = 1'000'000'000'000'000ull;
static_assert(isPowerOfTen(kMinValue));
static constexpr std::uint64_t kMaxValue = (kMinValue * 10) - 1;
static_assert(kMaxValue == 9'999'999'999'999'999ull);
static constexpr std::uint64_t kMaxNative = 9'000'000'000'000'000'000ull;
// Max native value on network.
constexpr static std::uint64_t cMaxNativeN = 100'000'000'000'000'000ull;
constexpr static std::uint64_t cIssuedCurrency = 0x8'000'000'000'000'000ull;
constexpr static std::uint64_t cPositive = 0x4'000'000'000'000'000ull;
constexpr static std::uint64_t cMPToken = 0x2'000'000'000'000'000ull;
constexpr static std::uint64_t cValueMask = ~(cPositive | cMPToken);
static constexpr std::uint64_t kMaxNativeN = 100'000'000'000'000'000ull;
static constexpr std::uint64_t kIssuedCurrency = 0x8'000'000'000'000'000ull;
static constexpr std::uint64_t kPositive = 0x4'000'000'000'000'000ull;
static constexpr std::uint64_t kMpToken = 0x2'000'000'000'000'000ull;
static constexpr std::uint64_t kValueMask = ~(kPositive | kMpToken);
static std::uint64_t const uRateOne;
static std::uint64_t const kURateOne;
//--------------------------------------------------------------------------
STAmount(SerialIter& sit, SField const& name);
struct unchecked
struct Unchecked
{
explicit unchecked() = default;
explicit Unchecked() = default;
};
// Do not call canonicalize
@@ -77,7 +79,7 @@ public:
mantissa_type mantissa,
exponent_type exponent,
bool negative,
unchecked);
Unchecked);
template <AssetType A>
STAmount(
@@ -85,7 +87,7 @@ public:
mantissa_type mantissa,
exponent_type exponent,
bool negative,
unchecked);
Unchecked);
// Call canonicalize
template <AssetType A>
@@ -106,7 +108,7 @@ public:
template <AssetType A>
STAmount(A const& asset, std::uint64_t mantissa = 0, int exponent = 0, bool negative = false)
: mAsset(asset), mValue(mantissa), mOffset(exponent), mIsNegative(negative)
: asset_(asset), value_(mantissa), offset_(exponent), isNegative_(negative)
{
canonicalize();
}
@@ -138,55 +140,69 @@ public:
//
//--------------------------------------------------------------------------
int
[[nodiscard]] int
exponent() const noexcept;
bool
[[nodiscard]] bool
integral() const noexcept;
bool
[[nodiscard]] bool
native() const noexcept;
template <ValidIssueType TIss>
constexpr bool
[[nodiscard]] constexpr bool
holds() const noexcept;
bool
[[nodiscard]] bool
negative() const noexcept;
std::uint64_t
[[nodiscard]] std::uint64_t
mantissa() const noexcept;
Asset const&
[[nodiscard]] Asset const&
asset() const;
template <ValidIssueType TIss>
constexpr TIss const&
get() const;
Issue const&
issue() const;
template <ValidIssueType TIss>
TIss&
get();
// These three are deprecated
Currency const&
getCurrency() const;
AccountID const&
[[nodiscard]] AccountID const&
getIssuer() const;
int
[[nodiscard]] int
signum() const noexcept;
/** Returns a zero value with the same issuer and currency. */
STAmount
[[nodiscard]] STAmount
zeroed() const;
void
setJson(Json::Value&) const;
setJson(json::Value&) const;
STAmount const&
[[nodiscard]] STAmount const&
value() const noexcept;
/**
* Checks if this amount evaluates to zero when constrained to a specific
* accounting scale.
* For XRP and MPT `roundToScale` is a no-op, returns true only when the amount itself is zero.
* The `scale` argument is ignored in that case.
* For IOU, the amount is rounded to the given scale using Number::RoundingMode::ToNearest mode
* and the result is checked for zero; if `scale <= exponent()`, `roundToScale` short-circuits
* and returns the value unchanged, so this returns false for any non-zero amount.
*
* @param scale The target accounting scale to evaluate against.
* @return `true` if this amount rounds to zero at the given scale, `false` otherwise.
*
* @see roundToScale
*/
[[nodiscard]] bool
isZeroAtScale(int scale) const;
//--------------------------------------------------------------------------
//
// Operators
@@ -225,9 +241,6 @@ public:
void
clear(Asset const& asset);
void
setIssuer(AccountID const& uIssuer);
/** Set the Issue for this amount. */
void
setIssue(Asset const& asset);
@@ -238,31 +251,31 @@ public:
//
//--------------------------------------------------------------------------
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getFullText() const override;
std::string
[[nodiscard]] std::string
getText() const override;
Json::Value getJson(JsonOptions = JsonOptions::none) const override;
[[nodiscard]] json::Value getJson(JsonOptions = JsonOptions::Values::None) const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
XRPAmount
[[nodiscard]] XRPAmount
xrp() const;
IOUAmount
[[nodiscard]] IOUAmount
iou() const;
MPTAmount
[[nodiscard]] MPTAmount
mpt() const;
private:
@@ -299,8 +312,8 @@ STAmount::STAmount(
mantissa_type mantissa,
exponent_type exponent,
bool negative,
unchecked)
: STBase(name), mAsset(asset), mValue(mantissa), mOffset(exponent), mIsNegative(negative)
Unchecked)
: STBase(name), asset_(asset), value_(mantissa), offset_(exponent), isNegative_(negative)
{
}
@@ -310,8 +323,8 @@ STAmount::STAmount(
mantissa_type mantissa,
exponent_type exponent,
bool negative,
unchecked)
: mAsset(asset), mValue(mantissa), mOffset(exponent), mIsNegative(negative)
Unchecked)
: asset_(asset), value_(mantissa), offset_(exponent), isNegative_(negative)
{
}
@@ -322,19 +335,19 @@ STAmount::STAmount(
std::uint64_t mantissa,
int exponent,
bool negative)
: STBase(name), mAsset(asset), mValue(mantissa), mOffset(exponent), mIsNegative(negative)
: STBase(name), asset_(asset), value_(mantissa), offset_(exponent), isNegative_(negative)
{
// mValue is uint64, but needs to fit in the range of int64
if (Number::getMantissaScale() == MantissaRange::small)
// value_ is uint64, but needs to fit in the range of int64
if (Number::getMantissaScale() == MantissaRange::MantissaScale::Small)
{
XRPL_ASSERT(
mValue <= std::numeric_limits<std::int64_t>::max(),
value_ <= std::numeric_limits<std::int64_t>::max(),
"xrpl::STAmount::STAmount(SField, A, std::uint64_t, int, bool) : "
"maximum mantissa input");
}
else
{
if (integral() && mValue > std::numeric_limits<std::int64_t>::max())
if (integral() && value_ > std::numeric_limits<std::int64_t>::max())
throw std::overflow_error("STAmount mantissa is too large " + std::to_string(mantissa));
}
canonicalize();
@@ -342,7 +355,7 @@ STAmount::STAmount(
template <AssetType A>
STAmount::STAmount(A const& asset, std::int64_t mantissa, int exponent)
: mAsset(asset), mOffset(exponent)
: asset_(asset), offset_(exponent)
{
set(mantissa);
canonicalize();
@@ -350,35 +363,43 @@ STAmount::STAmount(A const& asset, std::int64_t mantissa, int exponent)
template <AssetType A>
STAmount::STAmount(A const& asset, std::uint32_t mantissa, int exponent, bool negative)
: STAmount(asset, safe_cast<std::uint64_t>(mantissa), exponent, negative)
: STAmount(asset, safeCast<std::uint64_t>(mantissa), exponent, negative)
{
}
template <AssetType A>
STAmount::STAmount(A const& asset, int mantissa, int exponent)
: STAmount(asset, safe_cast<std::int64_t>(mantissa), exponent)
: STAmount(asset, safeCast<std::int64_t>(mantissa), exponent)
{
}
// Legacy support for new-style amounts
inline STAmount::STAmount(IOUAmount const& amount, Issue const& issue)
: mAsset(issue), mOffset(amount.exponent()), mIsNegative(amount < beast::zero)
: asset_(issue), offset_(amount.exponent()), isNegative_(amount < beast::kZero)
{
if (mIsNegative)
mValue = unsafe_cast<std::uint64_t>(-amount.mantissa());
if (isNegative_)
{
value_ = unsafeCast<std::uint64_t>(-amount.mantissa());
}
else
mValue = unsafe_cast<std::uint64_t>(amount.mantissa());
{
value_ = unsafeCast<std::uint64_t>(amount.mantissa());
}
canonicalize();
}
inline STAmount::STAmount(MPTAmount const& amount, MPTIssue const& mptIssue)
: mAsset(mptIssue), mOffset(0), mIsNegative(amount < beast::zero)
: asset_(mptIssue), offset_(0), isNegative_(amount < beast::kZero)
{
if (mIsNegative)
mValue = unsafe_cast<std::uint64_t>(-amount.value());
if (isNegative_)
{
value_ = unsafeCast<std::uint64_t>(-amount.value());
}
else
mValue = unsafe_cast<std::uint64_t>(amount.value());
{
value_ = unsafeCast<std::uint64_t>(amount.value());
}
canonicalize();
}
@@ -397,17 +418,17 @@ STAmount
amountFromString(Asset const& asset, std::string const& amount);
STAmount
amountFromJson(SField const& name, Json::Value const& v);
amountFromJson(SField const& name, json::Value const& v);
bool
amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource);
amountFromJsonNoThrow(STAmount& result, json::Value const& jvSource);
// IOUAmount and XRPAmount define toSTAmount, defining this
// trivial conversion here makes writing generic code easier
inline STAmount const&
toSTAmount(STAmount const& a)
{
return a;
return a; // NOLINT(bugprone-return-const-ref-from-parameter)
}
//------------------------------------------------------------------------------
@@ -419,97 +440,96 @@ toSTAmount(STAmount const& a)
inline int
STAmount::exponent() const noexcept
{
return mOffset;
return offset_;
}
inline bool
STAmount::integral() const noexcept
{
return mAsset.integral();
return asset_.integral();
}
inline bool
STAmount::native() const noexcept
{
return mAsset.native();
return asset_.native();
}
template <ValidIssueType TIss>
constexpr bool
STAmount::holds() const noexcept
{
return mAsset.holds<TIss>();
return asset_.holds<TIss>();
}
inline bool
STAmount::negative() const noexcept
{
return mIsNegative;
return isNegative_;
}
inline std::uint64_t
STAmount::mantissa() const noexcept
{
return mValue;
return value_;
}
inline Asset const&
STAmount::asset() const
{
return mAsset;
return asset_;
}
template <ValidIssueType TIss>
constexpr TIss const&
[[nodiscard]] constexpr TIss const&
STAmount::get() const
{
return mAsset.get<TIss>();
return asset_.get<TIss>();
}
inline Issue const&
STAmount::issue() const
template <ValidIssueType TIss>
TIss&
STAmount::get()
{
return get<Issue>();
}
inline Currency const&
STAmount::getCurrency() const
{
return mAsset.get<Issue>().currency;
return asset_.get<TIss>();
}
inline AccountID const&
STAmount::getIssuer() const
{
return mAsset.getIssuer();
return asset_.getIssuer();
}
inline int
STAmount::signum() const noexcept
{
return mValue ? (mIsNegative ? -1 : 1) : 0;
if (value_ == 0u)
return 0;
return isNegative_ ? -1 : 1;
}
inline STAmount
STAmount::zeroed() const
{
return STAmount(mAsset);
return STAmount(asset_);
}
inline STAmount::
operator bool() const noexcept
{
return *this != beast::zero;
return *this != beast::kZero;
}
inline STAmount::
operator Number() const
{
if (native())
return xrp();
if (mAsset.holds<MPTIssue>())
return mpt();
return iou();
return asset().visit(
[&](Issue const& issue) -> Number {
if (issue.native())
return xrp();
return iou();
},
[&](MPTIssue const&) -> Number { return mpt(); });
}
inline STAmount&
@@ -532,14 +552,14 @@ STAmount::fromNumber(A const& a, Number const& number)
{
bool const negative = number.mantissa() < 0;
Number const working{negative ? -number : number};
Asset asset{a};
Asset const asset{a};
if (asset.integral())
{
std::uint64_t const intValue = static_cast<std::int64_t>(working);
return STAmount{asset, intValue, 0, negative};
}
auto const [mantissa, exponent] = working.normalizeToRange(cMinValue, cMaxValue);
auto const [mantissa, exponent] = working.normalizeToRange<kMinValue, kMaxValue>();
return STAmount{asset, mantissa, exponent, negative};
}
@@ -547,8 +567,8 @@ STAmount::fromNumber(A const& a, Number const& number)
inline void
STAmount::negate()
{
if (*this != beast::zero)
mIsNegative = !mIsNegative;
if (*this != beast::kZero)
isNegative_ = !isNegative_;
}
inline void
@@ -556,9 +576,9 @@ STAmount::clear()
{
// The -100 is used to allow 0 to sort less than a small positive values
// which have a negative exponent.
mOffset = integral() ? 0 : -100;
mValue = 0;
mIsNegative = false;
offset_ = integral() ? 0 : -100;
value_ = 0;
isNegative_ = false;
}
inline void
@@ -568,24 +588,31 @@ STAmount::clear(Asset const& asset)
clear();
}
inline void
STAmount::setIssuer(AccountID const& uIssuer)
{
mAsset.get<Issue>().account = uIssuer;
}
inline STAmount const&
STAmount::value() const noexcept
{
return *this;
}
inline bool
[[nodiscard]] inline bool
isLegalNet(STAmount const& value)
{
return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
return !value.native() || (value.mantissa() <= STAmount::kMaxNativeN);
}
[[nodiscard]] inline bool
isLegalMPT(STAmount const& value)
{
return !value.holds<MPTIssue>() ||
(!value.negative() && value.exponent() == 0 && value.mantissa() <= kMaxMpTokenAmount);
}
/* Check recursively if an object has invalid MPTAmount or XRPAmount in STAmount field.
* Calls isLegalNet() and isLegalMPT().
*/
[[nodiscard]] bool
hasInvalidAmount(STBase const& field, beast::Journal j);
//------------------------------------------------------------------------------
//
// Operators
@@ -679,7 +706,7 @@ getRate(STAmount const& offerOut, STAmount const& offerIn);
roundToScale(
STAmount const& value,
std::int32_t scale,
Number::rounding_mode rounding = Number::getround());
Number::RoundingMode rounding = Number::getround());
/** Round an arbitrary precision Number IN PLACE to the precision of a given
* Asset.
@@ -714,9 +741,9 @@ roundToAsset(
A const& asset,
Number const& value,
std::int32_t scale,
Number::rounding_mode rounding = Number::getround())
Number::RoundingMode rounding = Number::getround())
{
NumberRoundModeGuard mg(rounding);
NumberRoundModeGuard const mg(rounding);
STAmount const ret{asset, value};
if (ret.integral())
return ret;
@@ -757,16 +784,16 @@ scale(Number const& number, Asset const& asset)
} // namespace xrpl
//------------------------------------------------------------------------------
namespace Json {
namespace json {
template <>
inline xrpl::STAmount
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
Json::StaticString const& key = field.getJsonName();
json::StaticString const& key = field.getJsonName();
if (!v.isMember(key))
Throw<JsonMissingKeyError>(key);
Json::Value const& inner = v[key];
json::Value const& inner = v[key];
return amountFromJson(field, inner);
}
} // namespace Json
} // namespace json

View File

@@ -53,18 +53,33 @@ public:
STObject&
back();
STObject const&
[[nodiscard]] STObject const&
back() const;
template <class... Args>
void
emplace_back(Args&&... args);
emplaceBack(Args&&... args);
void
push_back(STObject const& object);
pushBack(STObject const& object);
void
push_back(STObject&& object);
pushBack(STObject&& object);
// STL-compatible alias required by std::back_insert_iterator
void
// NOLINTNEXTLINE(readability-identifier-naming)
push_back(STObject const& object)
{
pushBack(object);
}
void
// NOLINTNEXTLINE(readability-identifier-naming)
push_back(STObject&& object)
{
pushBack(std::move(object));
}
iterator
begin();
@@ -72,16 +87,16 @@ public:
iterator
end();
const_iterator
[[nodiscard]] const_iterator
begin() const;
const_iterator
[[nodiscard]] const_iterator
end() const;
size_type
[[nodiscard]] size_type
size() const;
bool
[[nodiscard]] bool
empty() const;
void
@@ -93,13 +108,13 @@ public:
void
swap(STArray& a) noexcept;
std::string
[[nodiscard]] std::string
getFullText() const override;
std::string
[[nodiscard]] std::string
getText() const override;
Json::Value
[[nodiscard]] json::Value
getJson(JsonOptions index) const override;
void
@@ -126,13 +141,13 @@ public:
iterator
erase(const_iterator first, const_iterator last);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
private:
@@ -180,19 +195,19 @@ STArray::back() const
template <class... Args>
inline void
STArray::emplace_back(Args&&... args)
STArray::emplaceBack(Args&&... args)
{
v_.emplace_back(std::forward<Args>(args)...);
}
inline void
STArray::push_back(STObject const& object)
STArray::pushBack(STObject const& object)
{
v_.push_back(object);
}
inline void
STArray::push_back(STObject&& object)
STArray::pushBack(STObject&& object)
{
v_.push_back(std::move(object));
}

View File

@@ -18,21 +18,23 @@ struct JsonOptions
using underlying_t = unsigned int;
underlying_t value;
enum values : underlying_t {
// clang-format off
none = 0b0000'0000,
include_date = 0b0000'0001,
disable_API_prior_V2 = 0b0000'0010,
enum class Values : underlying_t {
None = 0b0000'0000,
IncludeDate = 0b0000'0001,
DisableApiPriorV2 = 0b0000'0010,
// IMPORTANT `_all` must be union of all of the above; see also operator~
_all = 0b0000'0011
// clang-format on
// IMPORTANT `All` must be union of all of the above; see also operator~
All = IncludeDate | DisableApiPriorV2 // 0b0000'0011
};
constexpr JsonOptions(underlying_t v) noexcept : value(v)
{
}
constexpr JsonOptions(Values v) noexcept : value(static_cast<JsonOptions::underlying_t>(v))
{
}
[[nodiscard]] constexpr explicit
operator underlying_t() const noexcept
{
@@ -63,27 +65,27 @@ struct JsonOptions
}
/// Returns JsonOptions binary negation, can be used with & (above) for set
/// difference e.g. `(options & ~JsonOptions::include_date)`
/// difference e.g. `(options & ~JsonOptions::kIncludeDate)`
[[nodiscard]] constexpr JsonOptions friend
operator~(JsonOptions v) noexcept
{
return {~v.value & static_cast<underlying_t>(_all)};
return {~v.value & static_cast<underlying_t>(Values::All)};
}
};
template <typename T>
requires requires(T const& t) {
{ t.getJson(JsonOptions::none) } -> std::convertible_to<Json::Value>;
{ t.getJson(JsonOptions::Values::None) } -> std::convertible_to<json::Value>;
}
Json::Value
to_json(T const& t)
json::Value
toJson(T const& t)
{
return t.getJson(JsonOptions::none);
return t.getJson(JsonOptions::Values::None);
}
namespace detail {
class STVar;
}
} // namespace detail
// VFALCO TODO fix this restriction on copy assignment.
//
@@ -113,7 +115,7 @@ class STVar;
*/
class STBase
{
SField const* fName;
SField const* fName_;
public:
virtual ~STBase() = default;
@@ -137,24 +139,24 @@ public:
D const&
downcast() const;
virtual SerializedTypeID
[[nodiscard]] virtual SerializedTypeID
getSType() const;
virtual std::string
[[nodiscard]] virtual std::string
getFullText() const;
virtual std::string
[[nodiscard]] virtual std::string
getText() const;
virtual Json::Value getJson(JsonOptions = JsonOptions::none) const;
[[nodiscard]] virtual json::Value getJson(JsonOptions = JsonOptions::Values::None) const;
virtual void
add(Serializer& s) const;
virtual bool
[[nodiscard]] virtual bool
isEquivalent(STBase const& t) const;
virtual bool
[[nodiscard]] virtual bool
isDefault() const;
/** A STBase is a field.
@@ -163,7 +165,7 @@ public:
void
setFName(SField const& n);
SField const&
[[nodiscard]] SField const&
getFName() const;
void
@@ -199,7 +201,7 @@ STBase::downcast()
}
template <class D>
D const&
[[nodiscard]] D const&
STBase::downcast() const
{
D const* ptr = dynamic_cast<D const*>(this);

View File

@@ -16,10 +16,10 @@ class STBitString final : public STBase, public CountedObject<STBitString<Bits>>
static_assert(Bits > 0, "Number of bits must be positive");
public:
using value_type = base_uint<Bits>;
using value_type = BaseUInt<Bits>;
private:
value_type value_;
value_type value_{};
public:
STBitString() = default;
@@ -29,26 +29,26 @@ public:
STBitString(SField const& n, value_type const& v);
STBitString(SerialIter& sit, SField const& name);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getText() const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isDefault() const override;
template <typename Tag>
void
setValue(base_uint<Bits, Tag> const& v);
setValue(BaseUInt<Bits, Tag> const& v);
value_type const&
[[nodiscard]] value_type const&
value() const;
operator value_type() const;
@@ -157,7 +157,7 @@ STBitString<Bits>::add(Serializer& s) const
template <int Bits>
template <typename Tag>
void
STBitString<Bits>::setValue(base_uint<Bits, Tag> const& v)
STBitString<Bits>::setValue(BaseUInt<Bits, Tag> const& v)
{
value_ = v;
}
@@ -180,7 +180,7 @@ template <int Bits>
bool
STBitString<Bits>::isDefault() const
{
return value_ == beast::zero;
return value_ == beast::kZero;
}
} // namespace xrpl

View File

@@ -26,31 +26,31 @@ public:
STBlob(SField const& n);
STBlob(SerialIter&, SField const& name = sfGeneric);
std::size_t
[[nodiscard]] std::size_t
size() const;
std::uint8_t const*
[[nodiscard]] std::uint8_t const*
data() const;
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getText() const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
STBlob&
operator=(Slice const& slice);
value_type
[[nodiscard]] value_type
value() const noexcept;
STBlob&
@@ -95,7 +95,7 @@ STBlob::size() const
inline std::uint8_t const*
STBlob::data() const
{
return reinterpret_cast<std::uint8_t const*>(value_.data());
return value_.data();
}
inline STBlob&

View File

@@ -11,7 +11,7 @@ namespace xrpl {
class STCurrency final : public STBase
{
private:
Currency currency_{};
Currency currency_;
public:
using value_type = Currency;
@@ -24,30 +24,30 @@ public:
explicit STCurrency(SField const& name);
Currency const&
[[nodiscard]] Currency const&
currency() const;
Currency const&
[[nodiscard]] Currency const&
value() const noexcept;
void
setCurrency(Currency const& currency);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getText() const override;
Json::Value getJson(JsonOptions) const override;
[[nodiscard]] json::Value getJson(JsonOptions) const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
private:
@@ -63,7 +63,7 @@ private:
};
STCurrency
currencyFromJson(SField const& name, Json::Value const& v);
currencyFromJson(SField const& name, json::Value const& v);
inline Currency const&
STCurrency::currency() const

View File

@@ -123,7 +123,7 @@ template <class U, class T>
void
set(STObject& st, TypedField<U> const& f, T&& t)
{
st.set(STExchange<U, typename std::decay<T>::type>::set(f, std::forward<T>(t)));
st.set(STExchange<U, std::decay_t<T>>::set(f, std::forward<T>(t)));
}
/** Set a blob field using an init function. */

View File

@@ -19,27 +19,27 @@ public:
STInteger(SField const& n, Integer v = 0);
STInteger(SerialIter& sit, SField const& name);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
Json::Value getJson(JsonOptions) const override;
[[nodiscard]] json::Value getJson(JsonOptions) const override;
std::string
[[nodiscard]] std::string
getText() const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isDefault() const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
STInteger&
operator=(value_type const& v);
value_type
[[nodiscard]] value_type
value() const noexcept;
void

View File

@@ -34,30 +34,30 @@ public:
get() const;
template <ValidIssueType TIss>
bool
[[nodiscard]] bool
holds() const;
value_type const&
[[nodiscard]] value_type const&
value() const noexcept;
void
setIssue(Asset const& issue);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getText() const override;
Json::Value getJson(JsonOptions) const override;
[[nodiscard]] json::Value getJson(JsonOptions) const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
friend constexpr bool
@@ -89,7 +89,7 @@ STIssue::STIssue(SField const& name, A const& asset) : STBase{name}, asset_{asse
}
STIssue
issueFromJson(SField const& name, Json::Value const& v);
issueFromJson(SField const& name, json::Value const& v);
template <ValidIssueType TIss>
bool

View File

@@ -8,7 +8,7 @@ namespace xrpl {
class Rules;
namespace test {
class Invariants_test;
}
} // namespace test
class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
{
@@ -28,30 +28,30 @@ public:
STLedgerEntry(SerialIter&& sit, uint256 const& index);
STLedgerEntry(STObject const& object, uint256 const& index);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getFullText() const override;
std::string
[[nodiscard]] std::string
getText() const override;
Json::Value
getJson(JsonOptions options = JsonOptions::none) const override;
[[nodiscard]] json::Value
getJson(JsonOptions options = JsonOptions::Values::None) const override;
/** Returns the 'key' (or 'index') of this item.
The key identifies this entry's position in
the SHAMap associative container.
*/
uint256 const&
[[nodiscard]] uint256 const&
key() const;
LedgerEntryType
[[nodiscard]] LedgerEntryType
getType() const;
// is this a ledger entry that can be threaded
bool
[[nodiscard]] bool
isThreadedType(Rules const& rules) const;
bool
@@ -86,7 +86,9 @@ inline STLedgerEntry::STLedgerEntry(LedgerEntryType type, uint256 const& key)
{
}
inline STLedgerEntry::STLedgerEntry(SerialIter&& sit, uint256 const& index)
inline STLedgerEntry::STLedgerEntry(
SerialIter&& sit, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
uint256 const& index)
: STLedgerEntry(sit, index)
{
}

View File

@@ -43,14 +43,14 @@ public:
explicit STNumber(SField const& field, Number const& value = Number());
STNumber(SerialIter& sit, SField const& field);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
std::string
[[nodiscard]] std::string
getText() const override;
void
add(Serializer& s) const override;
Number const&
[[nodiscard]] Number const&
value() const;
void
setValue(Number const& v);
@@ -62,9 +62,9 @@ public:
return *this;
}
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
void
@@ -96,6 +96,6 @@ NumberParts
partsFromString(std::string const& number);
STNumber
numberFromJson(SField const& field, Json::Value const& value);
numberFromJson(SField const& field, json::Value const& value);
} // namespace xrpl

View File

@@ -57,12 +57,12 @@ class STObject : public STBase, public CountedObject<STObject>
using list_type = std::vector<detail::STVar>;
list_type v_;
SOTemplate const* mType{};
SOTemplate const* type_{};
public:
using iterator = boost::transform_iterator<Transform, STObject::list_type::const_iterator>;
virtual ~STObject() = default;
~STObject() override = default;
STObject(STObject const&) = default;
template <typename F>
@@ -86,13 +86,13 @@ public:
static STObject
makeInnerObject(SField const& name);
iterator
[[nodiscard]] iterator
begin() const;
iterator
[[nodiscard]] iterator
end() const;
bool
[[nodiscard]] bool
empty() const;
void
@@ -104,7 +104,7 @@ public:
void
applyTemplateFromSField(SField const&);
bool
[[nodiscard]] bool
isFree() const;
void
@@ -113,81 +113,81 @@ public:
bool
set(SerialIter& u, int depth = 0);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
void
add(Serializer& s) const override;
std::string
[[nodiscard]] std::string
getFullText() const override;
std::string
[[nodiscard]] std::string
getText() const override;
// TODO(tom): options should be an enum.
Json::Value getJson(JsonOptions = JsonOptions::none) const override;
[[nodiscard]] json::Value getJson(JsonOptions = JsonOptions::Values::None) const override;
void
addWithoutSigningFields(Serializer& s) const;
Serializer
[[nodiscard]] Serializer
getSerializer() const;
template <class... Args>
std::size_t
emplace_back(Args&&... args);
emplaceBack(Args&&... args);
int
[[nodiscard]] int
getCount() const;
bool
setFlag(std::uint32_t);
bool
clearFlag(std::uint32_t);
bool
[[nodiscard]] bool
isFlag(std::uint32_t) const;
std::uint32_t
[[nodiscard]] std::uint32_t
getFlags() const;
uint256
[[nodiscard]] uint256
getHash(HashPrefix prefix) const;
uint256
[[nodiscard]] uint256
getSigningHash(HashPrefix prefix) const;
STBase const&
[[nodiscard]] STBase const&
peekAtIndex(int offset) const;
STBase&
getIndex(int offset);
STBase const*
[[nodiscard]] STBase const*
peekAtPIndex(int offset) const;
STBase*
getPIndex(int offset);
int
[[nodiscard]] int
getFieldIndex(SField const& field) const;
SField const&
[[nodiscard]] SField const&
getFieldSType(int index) const;
STBase const&
[[nodiscard]] STBase const&
peekAtField(SField const& field) const;
STBase&
getField(SField const& field);
STBase const*
[[nodiscard]] STBase const*
peekAtPField(SField const& field) const;
STBase*
@@ -195,44 +195,44 @@ public:
// these throw if the field type doesn't match, or return default values
// if the field is optional but not present
unsigned char
[[nodiscard]] unsigned char
getFieldU8(SField const& field) const;
std::uint16_t
[[nodiscard]] std::uint16_t
getFieldU16(SField const& field) const;
std::uint32_t
[[nodiscard]] std::uint32_t
getFieldU32(SField const& field) const;
std::uint64_t
[[nodiscard]] std::uint64_t
getFieldU64(SField const& field) const;
uint128
[[nodiscard]] uint128
getFieldH128(SField const& field) const;
uint160
[[nodiscard]] uint160
getFieldH160(SField const& field) const;
uint192
[[nodiscard]] uint192
getFieldH192(SField const& field) const;
uint256
[[nodiscard]] uint256
getFieldH256(SField const& field) const;
std::int32_t
[[nodiscard]] std::int32_t
getFieldI32(SField const& field) const;
AccountID
[[nodiscard]] AccountID
getAccountID(SField const& field) const;
Blob
[[nodiscard]] Blob
getFieldVL(SField const& field) const;
STAmount const&
[[nodiscard]] STAmount const&
getFieldAmount(SField const& field) const;
STPathSet const&
[[nodiscard]] STPathSet const&
getFieldPathSet(SField const& field) const;
STVector256 const&
[[nodiscard]] STVector256 const&
getFieldV256(SField const& field) const;
// If not found, returns an object constructed with the given field
STObject
[[nodiscard]] STObject
getFieldObject(SField const& field) const;
STArray const&
[[nodiscard]] STArray const&
getFieldArray(SField const& field) const;
STCurrency const&
[[nodiscard]] STCurrency const&
getFieldCurrency(SField const& field) const;
STNumber const&
[[nodiscard]] STNumber const&
getFieldNumber(SField const& field) const;
/** Get the value of a field.
@@ -290,7 +290,7 @@ public:
@throws STObject::FieldErr if the field is not present.
*/
template <class T>
typename T::value_type
[[nodiscard]] typename T::value_type
at(TypedField<T> const& f) const;
/** Get the value of a field as std::optional
@@ -302,7 +302,7 @@ public:
the specified field.
*/
template <class T>
std::optional<std::decay_t<typename T::value_type>>
[[nodiscard]] std::optional<std::decay_t<typename T::value_type>>
at(OptionaledField<T> const& of) const;
/** Get a modifiable field value.
@@ -349,6 +349,8 @@ public:
void
setFieldH128(SField const& field, uint128 const&);
void
setFieldH192(SField const& field, uint192 const&);
void
setFieldH256(SField const& field, uint256 const&);
void
setFieldI32(SField const& field, std::int32_t);
@@ -379,14 +381,14 @@ public:
template <class Tag>
void
setFieldH160(SField const& field, base_uint<160, Tag> const& v);
setFieldH160(SField const& field, BaseUInt<160, Tag> const& v);
STObject&
peekFieldObject(SField const& field);
STArray&
peekFieldArray(SField const& field);
bool
[[nodiscard]] bool
isFieldPresent(SField const& field) const;
STBase*
makeFieldPresent(SField const& field);
@@ -397,10 +399,10 @@ public:
void
delField(int index);
SOEStyle
[[nodiscard]] SOEStyle
getStyle(SField const& field) const;
bool
[[nodiscard]] bool
hasMatchingEntry(STBase const&) const;
bool
@@ -411,11 +413,11 @@ public:
class FieldErr;
private:
enum WhichFields : bool {
enum class WhichFields : bool {
// These values are carefully chosen to do the right thing if passed
// to SField::shouldInclude (bool)
omitSigningFields = false,
withAllFields = true
OmitSigningFields = false,
WithAllFields = true
};
void
@@ -434,8 +436,7 @@ private:
// by value.
template <
typename T,
typename V = typename std::remove_cv<
typename std::remove_reference<decltype(std::declval<T>().value())>::type>::type>
typename V = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<T>().value())>>>
V
getFieldByValue(SField const& field) const;
@@ -479,7 +480,7 @@ class STObject::Proxy
public:
using value_type = typename T::value_type;
value_type
[[nodiscard]] value_type
value() const;
value_type
@@ -499,7 +500,7 @@ protected:
Proxy(STObject* st, TypedField<T> const* f);
T const*
[[nodiscard]] T const*
find() const;
template <class U>
@@ -577,7 +578,7 @@ class STObject::OptionalProxy : public Proxy<T>
private:
using value_type = typename T::value_type;
using optional_type = std::optional<typename std::decay<value_type>::type>;
using optional_type = std::optional<std::decay_t<value_type>>;
public:
OptionalProxy(OptionalProxy const&) = default;
@@ -665,13 +666,13 @@ public:
}
// Emulate std::optional::value_or
value_type
value_or(value_type val) const;
[[nodiscard]] value_type
valueOr(value_type val) const;
OptionalProxy&
operator=(std::nullopt_t const&);
OptionalProxy&
operator=(optional_type&& v);
operator=(optional_type&& v); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
OptionalProxy&
operator=(optional_type const& v);
@@ -684,14 +685,14 @@ private:
OptionalProxy(STObject* st, TypedField<T> const* f);
bool
[[nodiscard]] bool
engaged() const noexcept;
void
disengage();
optional_type
optional_value() const;
[[nodiscard]] optional_type
optionalValue() const;
};
class STObject::FieldErr : public std::runtime_error
@@ -702,16 +703,16 @@ class STObject::FieldErr : public std::runtime_error
template <class T>
STObject::Proxy<T>::Proxy(STObject* st, TypedField<T> const* f) : st_(st), f_(f)
{
if (st_->mType)
if (st_->type_ != nullptr)
{
// STObject has associated template
if (!st_->peekAtPField(*f_))
Throw<STObject::FieldErr>("Template field error '" + this->f_->getName() + "'");
style_ = st_->mType->style(*f_);
style_ = st_->type_->style(*f_);
}
else
{
style_ = soeINVALID;
style_ = SoeInvalid;
}
}
@@ -722,11 +723,11 @@ STObject::Proxy<T>::value() const -> value_type
auto const t = find();
if (t)
return t->value();
if (style_ == soeINVALID)
if (style_ == SoeInvalid)
{
Throw<STObject::FieldErr>("Value requested from invalid STObject.");
}
if (style_ != soeDEFAULT)
if (style_ != SoeDefault)
{
Throw<STObject::FieldErr>("Missing field '" + this->f_->getName() + "'");
}
@@ -761,16 +762,20 @@ template <class U>
void
STObject::Proxy<T>::assign(U&& u)
{
if (style_ == soeDEFAULT && u == value_type{})
if (style_ == SoeDefault && u == value_type{})
{
st_->makeFieldAbsent(*f_);
return;
}
T* t;
if (style_ == soeINVALID)
T* t = nullptr;
if (style_ == SoeInvalid)
{
t = dynamic_cast<T*>(st_->getPField(*f_, true));
}
else
{
t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
}
XRPL_ASSERT(t, "xrpl::STObject::Proxy::assign : type cast succeeded");
*t = std::forward<U>(u);
}
@@ -831,14 +836,14 @@ template <class T>
STObject::OptionalProxy<T>::
operator typename STObject::OptionalProxy<T>::optional_type() const
{
return optional_value();
return optionalValue();
}
template <class T>
typename STObject::OptionalProxy<T>::optional_type
STObject::OptionalProxy<T>::operator~() const
{
return optional_value();
return optionalValue();
}
template <class T>
@@ -851,12 +856,18 @@ STObject::OptionalProxy<T>::operator=(std::nullopt_t const&) -> OptionalProxy&
template <class T>
auto
STObject::OptionalProxy<T>::operator=(optional_type&& v) -> OptionalProxy&
STObject::OptionalProxy<T>::operator=(
optional_type&& v) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
-> OptionalProxy&
{
if (v)
{
this->assign(std::move(*v));
}
else
{
disengage();
}
return *this;
}
@@ -865,9 +876,13 @@ auto
STObject::OptionalProxy<T>::operator=(optional_type const& v) -> OptionalProxy&
{
if (v)
{
this->assign(*v);
}
else
{
disengage();
}
return *this;
}
@@ -889,24 +904,28 @@ template <class T>
bool
STObject::OptionalProxy<T>::engaged() const noexcept
{
return this->style_ == soeDEFAULT || this->find() != nullptr;
return this->style_ == SoeDefault || this->find() != nullptr;
}
template <class T>
void
STObject::OptionalProxy<T>::disengage()
{
if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
if (this->style_ == SoeRequired || this->style_ == SoeDefault)
Throw<STObject::FieldErr>("Template field error '" + this->f_->getName() + "'");
if (this->style_ == soeINVALID)
if (this->style_ == SoeInvalid)
{
this->st_->delField(*this->f_);
}
else
{
this->st_->makeFieldAbsent(*this->f_);
}
}
template <class T>
auto
STObject::OptionalProxy<T>::optional_value() const -> optional_type
STObject::OptionalProxy<T>::optionalValue() const -> optional_type
{
if (!engaged())
return std::nullopt;
@@ -915,7 +934,7 @@ STObject::OptionalProxy<T>::optional_value() const -> optional_type
template <class T>
typename STObject::OptionalProxy<T>::value_type
STObject::OptionalProxy<T>::value_or(value_type val) const
STObject::OptionalProxy<T>::valueOr(value_type val) const
{
return engaged() ? this->value() : val;
}
@@ -930,6 +949,7 @@ STObject::Transform::operator()(detail::STVar const& e) const
//------------------------------------------------------------------------------
// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
inline STObject::STObject(SerialIter&& sit, SField const& name) : STObject(sit, name)
{
}
@@ -961,13 +981,13 @@ STObject::reserve(std::size_t n)
inline bool
STObject::isFree() const
{
return mType == nullptr;
return type_ == nullptr;
}
inline void
STObject::addWithoutSigningFields(Serializer& s) const
{
add(s, omitSigningFields);
add(s, WhichFields::OmitSigningFields);
}
// VFALCO NOTE does this return an expensive copy of an object with a
@@ -977,13 +997,13 @@ inline Serializer
STObject::getSerializer() const
{
Serializer s;
add(s, withAllFields);
add(s, WhichFields::WithAllFields);
return s;
}
template <class... Args>
inline std::size_t
STObject::emplace_back(Args&&... args)
STObject::emplaceBack(Args&&... args)
{
v_.emplace_back(std::forward<Args>(args)...);
return v_.size() - 1;
@@ -1048,37 +1068,39 @@ STObject::operator[](OptionaledField<T> const& of) -> OptionalProxy<T>
}
template <class T>
typename T::value_type
[[nodiscard]] typename T::value_type
STObject::at(TypedField<T> const& f) const
{
auto const b = peekAtPField(f);
if (!b)
{
// This is a free object (no constraints)
// with no template
Throw<STObject::FieldErr>("Missing field: " + f.getName());
}
if (auto const u = dynamic_cast<T const*>(b))
return u->value();
XRPL_ASSERT(mType, "xrpl::STObject::at(TypedField auto) : field template non-null");
XRPL_ASSERT(type_, "xrpl::STObject::at(TypedField auto) : field template non-null");
XRPL_ASSERT(
b->getSType() == STI_NOTPRESENT, "xrpl::STObject::at(TypedField auto) : type not present");
if (mType->style(f) == soeOPTIONAL)
if (type_->style(f) == SoeOptional)
Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
XRPL_ASSERT(
mType->style(f) == soeDEFAULT,
type_->style(f) == SoeDefault,
"xrpl::STObject::at(TypedField auto) : template style is default");
// Used to help handle the case where value_type is a const reference,
// otherwise we would return the address of a temporary.
static std::decay_t<typename T::value_type> const dv{};
return dv;
static std::decay_t<typename T::value_type> const kDV{};
return kDV;
}
template <class T>
std::optional<std::decay_t<typename T::value_type>>
[[nodiscard]] std::optional<std::decay_t<typename T::value_type>>
STObject::at(OptionaledField<T> const& of) const
{
auto const b = peekAtPField(*of.f);
@@ -1088,16 +1110,16 @@ STObject::at(OptionaledField<T> const& of) const
if (!u)
{
XRPL_ASSERT(
mType,
type_,
"xrpl::STObject::at(OptionaledField auto) : field template "
"non-null");
XRPL_ASSERT(
b->getSType() == STI_NOTPRESENT,
"xrpl::STObject::at(OptionaledField auto) : type not present");
if (mType->style(*of.f) == soeOPTIONAL)
if (type_->style(*of.f) == SoeOptional)
return std::nullopt;
XRPL_ASSERT(
mType->style(*of.f) == soeDEFAULT,
type_->style(*of.f) == SoeDefault,
"xrpl::STObject::at(OptionaledField auto) : template style is "
"default");
return typename T::value_type{};
@@ -1121,7 +1143,7 @@ STObject::at(OptionaledField<T> const& of) -> OptionalProxy<T>
template <class Tag>
void
STObject::setFieldH160(SField const& field, base_uint<160, Tag> const& v)
STObject::setFieldH160(SField const& field, BaseUInt<160, Tag> const& v)
{
STBase* rf = getPField(field, true);
@@ -1133,9 +1155,13 @@ STObject::setFieldH160(SField const& field, base_uint<160, Tag> const& v)
using Bits = STBitString<160>;
if (auto cf = dynamic_cast<Bits*>(rf))
{
cf->setValue(v);
}
else
{
Throw<std::runtime_error>("Wrong field type");
}
}
inline bool
@@ -1153,7 +1179,7 @@ STObject::getFieldByValue(SField const& field) const
if (!rf)
throwFieldNotFound(field);
SerializedTypeID id = rf->getSType();
SerializedTypeID const id = rf->getSType();
if (id == STI_NOTPRESENT)
return V(); // optional field not present
@@ -1180,10 +1206,13 @@ STObject::getFieldByConstRef(SField const& field, V const& empty) const
if (!rf)
throwFieldNotFound(field);
SerializedTypeID id = rf->getSType();
SerializedTypeID const id = rf->getSType();
if (id == STI_NOTPRESENT)
{
// NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
return empty; // optional field not present
}
T const* cf = dynamic_cast<T const*>(rf);
@@ -1198,7 +1227,7 @@ template <typename T, typename V>
void
STObject::setFieldUsingSetValue(SField const& field, V value)
{
static_assert(!std::is_lvalue_reference<V>::value, "");
static_assert(!std::is_lvalue_reference_v<V>, "");
STBase* rf = getPField(field, true);

View File

@@ -6,6 +6,13 @@
namespace xrpl {
/** Maximum JSON object nesting depth permitted during parsing. */
inline constexpr std::size_t kMaxParsedJsonDepth = 64;
/** Maximum number of elements permitted in any JSON array field during parsing.
Requests exceeding this limit are rejected with an invalidParams error. */
inline constexpr std::size_t kMaxParsedJsonArraySize = 512;
/** Holds the serialized result of parsing an input JSON object.
This does validation and checking on the provided JSON.
*/
@@ -19,7 +26,7 @@ public:
@param name The name of the JSON field, used in diagnostics.
@param json The JSON-RPC to parse.
*/
STParsedJSONObject(std::string const& name, Json::Value const& json);
STParsedJSONObject(std::string const& name, json::Value const& json);
STParsedJSONObject() = delete;
STParsedJSONObject(STParsedJSONObject const&) = delete;
@@ -31,7 +38,7 @@ public:
std::optional<STObject> object;
/** On failure, an appropriate set of error values. */
Json::Value error;
json::Value error;
};
} // namespace xrpl

View File

@@ -3,6 +3,8 @@
#include <xrpl/basics/CountedObject.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/PathAsset.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/UintTypes.h>
@@ -14,22 +16,26 @@ namespace xrpl {
class STPathElement final : public CountedObject<STPathElement>
{
unsigned int mType;
AccountID mAccountID;
Currency mCurrencyID;
AccountID mIssuerID;
unsigned int type_;
AccountID accountID_;
PathAsset assetID_;
AccountID issuerID_;
bool is_offer_;
std::size_t hash_value_;
bool isOffer_;
std::size_t hashValue_;
public:
// Bitwise values (typeCurrency | typeMPT)
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum Type {
typeNone = 0x00,
typeAccount = 0x01, // Rippling through an account (vs taking an offer).
typeCurrency = 0x10, // Currency follows.
typeIssuer = 0x20, // Issuer follows.
typeBoundary = 0xFF, // Boundary between alternate paths.
typeAll = typeAccount | typeCurrency | typeIssuer,
TypeNone = 0x00,
TypeAccount = 0x01, // Rippling through an account (vs taking an offer).
TypeCurrency = 0x10, // Currency follows.
TypeIssuer = 0x20, // Issuer follows.
TypeMpt = 0x40, // MPT follows.
TypeBoundary = 0xFF, // Boundary between alternate paths.
TypeAsset = TypeCurrency | TypeMpt,
TypeAll = TypeAccount | TypeCurrency | TypeIssuer | TypeMpt,
// Combination of all types.
};
@@ -40,50 +46,65 @@ public:
STPathElement(
std::optional<AccountID> const& account,
std::optional<Currency> const& currency,
std::optional<PathAsset> const& asset,
std::optional<AccountID> const& issuer);
STPathElement(
AccountID const& account,
Currency const& currency,
PathAsset const& asset,
AccountID const& issuer,
bool forceCurrency = false);
bool forceAsset = false);
STPathElement(
unsigned int uType,
AccountID const& account,
Currency const& currency,
PathAsset const& asset,
AccountID const& issuer);
auto
[[nodiscard]] auto
getNodeType() const;
bool
[[nodiscard]] bool
isOffer() const;
bool
[[nodiscard]] bool
isAccount() const;
bool
[[nodiscard]] bool
hasIssuer() const;
bool
[[nodiscard]] bool
hasCurrency() const;
bool
[[nodiscard]] bool
hasMPT() const;
[[nodiscard]] bool
hasAsset() const;
[[nodiscard]] bool
isNone() const;
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
// class of offers.
AccountID const&
[[nodiscard]] AccountID const&
getAccountID() const;
Currency const&
[[nodiscard]] PathAsset const&
getPathAsset() const;
[[nodiscard]] Currency const&
getCurrency() const;
AccountID const&
[[nodiscard]] MPTID const&
getMPTID() const;
[[nodiscard]] AccountID const&
getIssuerID() const;
[[nodiscard]] bool
isType(Type const& pe) const;
bool
operator==(STPathElement const& t) const;
@@ -92,49 +113,49 @@ public:
private:
static std::size_t
get_hash(STPathElement const& element);
getHash(STPathElement const& element);
};
class STPath final : public CountedObject<STPath>
{
std::vector<STPathElement> mPath;
std::vector<STPathElement> path_;
public:
STPath() = default;
STPath(std::vector<STPathElement> p);
std::vector<STPathElement>::size_type
[[nodiscard]] std::vector<STPathElement>::size_type
size() const;
bool
[[nodiscard]] bool
empty() const;
void
push_back(STPathElement const& e);
pushBack(STPathElement const& e);
template <typename... Args>
void
emplace_back(Args&&... args);
emplaceBack(Args&&... args);
bool
hasSeen(AccountID const& account, Currency const& currency, AccountID const& issuer) const;
[[nodiscard]] bool
hasSeen(AccountID const& account, PathAsset const& asset, AccountID const& issuer) const;
Json::Value getJson(JsonOptions) const;
[[nodiscard]] json::Value getJson(JsonOptions) const;
std::vector<STPathElement>::const_iterator
[[nodiscard]] std::vector<STPathElement>::const_iterator
begin() const;
std::vector<STPathElement>::const_iterator
[[nodiscard]] std::vector<STPathElement>::const_iterator
end() const;
bool
operator==(STPath const& t) const;
std::vector<STPathElement>::const_reference
[[nodiscard]] std::vector<STPathElement>::const_reference
back() const;
std::vector<STPathElement>::const_reference
[[nodiscard]] std::vector<STPathElement>::const_reference
front() const;
STPathElement&
@@ -152,7 +173,7 @@ public:
// A set of zero or more payment paths
class STPathSet final : public STBase, public CountedObject<STPathSet>
{
std::vector<STPath> value;
std::vector<STPath> value_;
public:
STPathSet() = default;
@@ -163,18 +184,18 @@ public:
void
add(Serializer& s) const override;
Json::Value getJson(JsonOptions) const override;
[[nodiscard]] json::Value getJson(JsonOptions) const override;
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
bool
assembleAdd(STPath const& base, STPathElement const& tail);
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
// std::vector like interface:
@@ -184,24 +205,24 @@ public:
std::vector<STPath>::reference
operator[](std::vector<STPath>::size_type n);
std::vector<STPath>::const_iterator
[[nodiscard]] std::vector<STPath>::const_iterator
begin() const;
std::vector<STPath>::const_iterator
[[nodiscard]] std::vector<STPath>::const_iterator
end() const;
std::vector<STPath>::size_type
[[nodiscard]] std::vector<STPath>::size_type
size() const;
bool
[[nodiscard]] bool
empty() const;
void
push_back(STPath const& e);
pushBack(STPath const& e);
template <typename... Args>
void
emplace_back(Args&&... args);
emplaceBack(Args&&... args);
private:
STBase*
@@ -214,93 +235,96 @@ private:
// ------------ STPathElement ------------
inline STPathElement::STPathElement() : mType(typeNone), is_offer_(true)
inline STPathElement::STPathElement() : type_(TypeNone), isOffer_(true)
{
hash_value_ = get_hash(*this);
hashValue_ = getHash(*this);
}
inline STPathElement::STPathElement(
std::optional<AccountID> const& account,
std::optional<Currency> const& currency,
std::optional<PathAsset> const& asset,
std::optional<AccountID> const& issuer)
: mType(typeNone)
: type_(TypeNone)
{
if (!account)
{
is_offer_ = true;
isOffer_ = true;
}
else
{
is_offer_ = false;
mAccountID = *account;
mType |= typeAccount;
isOffer_ = false;
accountID_ = *account;
type_ |= TypeAccount;
XRPL_ASSERT(
mAccountID != noAccount(), "xrpl::STPathElement::STPathElement : account is set");
accountID_ != noAccount(), "xrpl::STPathElement::STPathElement : account is set");
}
if (currency)
if (asset)
{
mCurrencyID = *currency;
mType |= typeCurrency;
assetID_ = *asset;
type_ |= assetID_.holds<Currency>() ? TypeCurrency : TypeMpt;
}
if (issuer)
{
mIssuerID = *issuer;
mType |= typeIssuer;
XRPL_ASSERT(mIssuerID != noAccount(), "xrpl::STPathElement::STPathElement : issuer is set");
issuerID_ = *issuer;
type_ |= TypeIssuer;
XRPL_ASSERT(issuerID_ != noAccount(), "xrpl::STPathElement::STPathElement : issuer is set");
}
hash_value_ = get_hash(*this);
hashValue_ = getHash(*this);
}
inline STPathElement::STPathElement(
AccountID const& account,
Currency const& currency,
PathAsset const& asset,
AccountID const& issuer,
bool forceCurrency)
: mType(typeNone)
, mAccountID(account)
, mCurrencyID(currency)
, mIssuerID(issuer)
, is_offer_(isXRP(mAccountID))
bool forceAsset)
: type_(TypeNone)
, accountID_(account)
, assetID_(asset)
, issuerID_(issuer)
, isOffer_(isXRP(accountID_))
{
if (!is_offer_)
mType |= typeAccount;
if (!isOffer_)
type_ |= TypeAccount;
if (forceCurrency || !isXRP(currency))
mType |= typeCurrency;
if (forceAsset || !isXRP(assetID_))
type_ |= asset.holds<Currency>() ? TypeCurrency : TypeMpt;
if (!isXRP(issuer))
mType |= typeIssuer;
type_ |= TypeIssuer;
hash_value_ = get_hash(*this);
hashValue_ = getHash(*this);
}
inline STPathElement::STPathElement(
unsigned int uType,
AccountID const& account,
Currency const& currency,
PathAsset const& asset,
AccountID const& issuer)
: mType(uType)
, mAccountID(account)
, mCurrencyID(currency)
, mIssuerID(issuer)
, is_offer_(isXRP(mAccountID))
: type_(uType)
, accountID_(account)
, assetID_(asset)
, issuerID_(issuer)
, isOffer_(isXRP(accountID_))
{
hash_value_ = get_hash(*this);
assetID_.visit(
[&](Currency const&) { type_ = type_ & (~Type::TypeMpt); },
[&](MPTID const&) { type_ = type_ & (~Type::TypeCurrency); });
hashValue_ = getHash(*this);
}
inline auto
STPathElement::getNodeType() const
{
return mType;
return type_;
}
inline bool
STPathElement::isOffer() const
{
return is_offer_;
return isOffer_;
}
inline bool
@@ -309,22 +333,40 @@ STPathElement::isAccount() const
return !isOffer();
}
inline bool
STPathElement::isType(Type const& pe) const
{
return (type_ & pe) != 0u;
}
inline bool
STPathElement::hasIssuer() const
{
return getNodeType() & STPathElement::typeIssuer;
return isType(STPathElement::TypeIssuer);
}
inline bool
STPathElement::hasCurrency() const
{
return getNodeType() & STPathElement::typeCurrency;
return isType(STPathElement::TypeCurrency);
}
inline bool
STPathElement::hasMPT() const
{
return isType(STPathElement::TypeMpt);
}
inline bool
STPathElement::hasAsset() const
{
return isType(STPathElement::TypeAsset);
}
inline bool
STPathElement::isNone() const
{
return getNodeType() == STPathElement::typeNone;
return getNodeType() == STPathElement::TypeNone;
}
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
@@ -332,26 +374,38 @@ STPathElement::isNone() const
inline AccountID const&
STPathElement::getAccountID() const
{
return mAccountID;
return accountID_;
}
inline PathAsset const&
STPathElement::getPathAsset() const
{
return assetID_;
}
inline Currency const&
STPathElement::getCurrency() const
{
return mCurrencyID;
return assetID_.get<Currency>();
}
inline MPTID const&
STPathElement::getMPTID() const
{
return assetID_.get<MPTID>();
}
inline AccountID const&
STPathElement::getIssuerID() const
{
return mIssuerID;
return issuerID_;
}
inline bool
STPathElement::operator==(STPathElement const& t) const
{
return (mType & typeAccount) == (t.mType & typeAccount) && hash_value_ == t.hash_value_ &&
mAccountID == t.mAccountID && mCurrencyID == t.mCurrencyID && mIssuerID == t.mIssuerID;
return (type_ & TypeAccount) == (t.type_ & TypeAccount) && hashValue_ == t.hashValue_ &&
accountID_ == t.accountID_ && assetID_ == t.assetID_ && issuerID_ == t.issuerID_;
}
inline bool
@@ -362,81 +416,81 @@ STPathElement::operator!=(STPathElement const& t) const
// ------------ STPath ------------
inline STPath::STPath(std::vector<STPathElement> p) : mPath(std::move(p))
inline STPath::STPath(std::vector<STPathElement> p) : path_(std::move(p))
{
}
inline std::vector<STPathElement>::size_type
STPath::size() const
{
return mPath.size();
return path_.size();
}
inline bool
STPath::empty() const
{
return mPath.empty();
return path_.empty();
}
inline void
STPath::push_back(STPathElement const& e)
STPath::pushBack(STPathElement const& e)
{
mPath.push_back(e);
path_.push_back(e);
}
template <typename... Args>
inline void
STPath::emplace_back(Args&&... args)
STPath::emplaceBack(Args&&... args)
{
mPath.emplace_back(std::forward<Args>(args)...);
path_.emplace_back(std::forward<Args>(args)...);
}
inline std::vector<STPathElement>::const_iterator
STPath::begin() const
{
return mPath.begin();
return path_.begin();
}
inline std::vector<STPathElement>::const_iterator
STPath::end() const
{
return mPath.end();
return path_.end();
}
inline bool
STPath::operator==(STPath const& t) const
{
return mPath == t.mPath;
return path_ == t.path_;
}
inline std::vector<STPathElement>::const_reference
STPath::back() const
{
return mPath.back();
return path_.back();
}
inline std::vector<STPathElement>::const_reference
STPath::front() const
{
return mPath.front();
return path_.front();
}
inline STPathElement&
STPath::operator[](int i)
{
return mPath[i];
return path_[i];
}
inline STPathElement const&
STPath::operator[](int i) const
{
return mPath[i];
return path_[i];
}
inline void
STPath::reserve(size_t s)
{
mPath.reserve(s);
path_.reserve(s);
}
// ------------ STPathSet ------------
@@ -449,50 +503,50 @@ inline STPathSet::STPathSet(SField const& n) : STBase(n)
inline std::vector<STPath>::const_reference
STPathSet::operator[](std::vector<STPath>::size_type n) const
{
return value[n];
return value_[n];
}
inline std::vector<STPath>::reference
STPathSet::operator[](std::vector<STPath>::size_type n)
{
return value[n];
return value_[n];
}
inline std::vector<STPath>::const_iterator
STPathSet::begin() const
{
return value.begin();
return value_.begin();
}
inline std::vector<STPath>::const_iterator
STPathSet::end() const
{
return value.end();
return value_.end();
}
inline std::vector<STPath>::size_type
STPathSet::size() const
{
return value.size();
return value_.size();
}
inline bool
STPathSet::empty() const
{
return value.empty();
return value_.empty();
}
inline void
STPathSet::push_back(STPath const& e)
STPathSet::pushBack(STPath const& e)
{
value.push_back(e);
value_.push_back(e);
}
template <typename... Args>
inline void
STPathSet::emplace_back(Args&&... args)
STPathSet::emplaceBack(Args&&... args)
{
value.emplace_back(std::forward<Args>(args)...);
value_.emplace_back(std::forward<Args>(args)...);
}
} // namespace xrpl

View File

@@ -16,22 +16,22 @@
namespace xrpl {
enum class TxnSql : char {
txnSqlNew = 'N',
txnSqlConflict = 'C',
txnSqlHeld = 'H',
txnSqlValidated = 'V',
txnSqlIncluded = 'I',
txnSqlUnknown = 'U'
New = 'N',
Conflict = 'C',
Held = 'H',
Validated = 'V',
Included = 'I',
Unknown = 'U'
};
class STTx final : public STObject, public CountedObject<STTx>
{
uint256 tid_;
TxType tx_type_;
TxType txType_;
public:
static constexpr std::size_t minMultiSigners = 1;
static constexpr std::size_t maxMultiSigners = 32;
static constexpr std::size_t kMinMultiSigners = 1;
static constexpr std::size_t kMaxMultiSigners = 32;
STTx() = delete;
STTx(STTx const& other) = default;
@@ -92,10 +92,10 @@ public:
uint256
getTransactionID() const;
Json::Value
json::Value
getJson(JsonOptions options) const override;
Json::Value
json::Value
getJson(JsonOptions options, bool binary) const;
void
@@ -179,14 +179,15 @@ sterilize(STTx const& stx);
bool
isPseudoTx(STObject const& tx);
inline STTx::STTx(SerialIter&& sit) : STTx(sit)
inline STTx::STTx(SerialIter&& sit) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
: STTx(sit)
{
}
inline TxType
STTx::getTxnType() const
{
return tx_type_;
return txType_;
}
inline Blob

View File

@@ -16,14 +16,14 @@ namespace xrpl {
// Validation flags
// This is a full (as opposed to a partial) validation
constexpr std::uint32_t vfFullValidation = 0x00000001;
constexpr std::uint32_t kVfFullValidation = 0x00000001;
// The signature is fully canonical
constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
constexpr std::uint32_t kVfFullyCanonicalSig = 0x80000000;
class STValidation final : public STObject, public CountedObject<STValidation>
{
bool mTrusted = false;
bool trusted_ = false;
// Determines the validity of the signature in this validation; unseated
// optional if we haven't yet checked it, a boolean otherwise.
@@ -36,7 +36,7 @@ class STValidation final : public STObject, public CountedObject<STValidation>
// that use manifests this will be derived from the master public key.
NodeID const nodeID_;
NetClock::time_point seenTime_ = {};
NetClock::time_point seenTime_;
public:
/** Construct a STValidation from a peer from serialized data.
@@ -151,7 +151,7 @@ STValidation::STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, bool ch
, signingPubKey_([this]() {
auto const spk = getFieldVL(sfSigningPubKey);
if (publicKeyType(makeSlice(spk)) != KeyType::secp256k1)
if (publicKeyType(makeSlice(spk)) != KeyType::Secp256k1)
Throw<std::runtime_error>("Invalid public key in validation");
return PublicKey{makeSlice(spk)};
@@ -161,7 +161,7 @@ STValidation::STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, bool ch
if (checkSignature && !isValid())
{
JLOG(debugLog().error()) << "Invalid signature in validation: "
<< getJson(JsonOptions::none);
<< getJson(JsonOptions::Values::None);
Throw<std::runtime_error>("Invalid signature in validation");
}
@@ -194,8 +194,8 @@ STValidation::STValidation(
"node");
// First, set our own public key:
if (publicKeyType(pk) != KeyType::secp256k1)
LogicError("We can only use secp256k1 keys for signing validations");
if (publicKeyType(pk) != KeyType::Secp256k1)
logicError("We can only use secp256k1 keys for signing validations");
setFieldVL(sfSigningPubKey, pk.slice());
setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
@@ -204,15 +204,15 @@ STValidation::STValidation(
f(*this);
// Finally, sign the validation and mark it as trusted:
setFlag(vfFullyCanonicalSig);
setFlag(kVfFullyCanonicalSig);
setFieldVL(sfSignature, signDigest(pk, sk, getSigningHash()));
setTrusted();
// Check to ensure that all required fields are present.
for (auto const& e : validationFormat())
{
if (e.style() == soeREQUIRED && !isFieldPresent(e.sField()))
LogicError("Required field '" + e.sField().getName() + "' missing from validation.");
if (e.style() == SoeRequired && !isFieldPresent(e.sField()))
logicError("Required field '" + e.sField().getName() + "' missing from validation.");
}
// We just signed this, so it should be valid.
@@ -234,19 +234,19 @@ STValidation::getNodeID() const noexcept
inline bool
STValidation::isTrusted() const noexcept
{
return mTrusted;
return trusted_;
}
inline void
STValidation::setTrusted()
{
mTrusted = true;
trusted_ = true;
}
inline void
STValidation::setUntrusted()
{
mTrusted = false;
trusted_ = false;
}
inline void

View File

@@ -9,7 +9,7 @@ namespace xrpl {
class STVector256 : public STBase, public CountedObject<STVector256>
{
std::vector<uint256> mValue;
std::vector<uint256> value_;
public:
using value_type = std::vector<uint256> const&;
@@ -21,18 +21,18 @@ public:
STVector256(SField const& n, std::vector<uint256> const& vector);
STVector256(SerialIter& sit, SField const& name);
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
void
add(Serializer& s) const override;
Json::Value getJson(JsonOptions) const override;
[[nodiscard]] json::Value getJson(JsonOptions) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
STVector256&
@@ -48,13 +48,13 @@ public:
explicit
operator std::vector<uint256>() const;
std::size_t
[[nodiscard]] std::size_t
size() const;
void
resize(std::size_t n);
bool
[[nodiscard]] bool
empty() const;
std::vector<uint256>::reference
@@ -63,25 +63,25 @@ public:
std::vector<uint256>::const_reference
operator[](std::vector<uint256>::size_type n) const;
std::vector<uint256> const&
[[nodiscard]] std::vector<uint256> const&
value() const;
std::vector<uint256>::iterator
insert(std::vector<uint256>::const_iterator pos, uint256 const& value);
void
push_back(uint256 const& v);
pushBack(uint256 const& v);
std::vector<uint256>::iterator
begin();
std::vector<uint256>::const_iterator
[[nodiscard]] std::vector<uint256>::const_iterator
begin() const;
std::vector<uint256>::iterator
end();
std::vector<uint256>::const_iterator
[[nodiscard]] std::vector<uint256>::const_iterator
end() const;
std::vector<uint256>::iterator
@@ -103,124 +103,124 @@ inline STVector256::STVector256(SField const& n) : STBase(n)
{
}
inline STVector256::STVector256(std::vector<uint256> const& vector) : mValue(vector)
inline STVector256::STVector256(std::vector<uint256> const& vector) : value_(vector)
{
}
inline STVector256::STVector256(SField const& n, std::vector<uint256> const& vector)
: STBase(n), mValue(vector)
: STBase(n), value_(vector)
{
}
inline STVector256&
STVector256::operator=(std::vector<uint256> const& v)
{
mValue = v;
value_ = v;
return *this;
}
inline STVector256&
STVector256::operator=(std::vector<uint256>&& v)
{
mValue = std::move(v);
value_ = std::move(v);
return *this;
}
inline void
STVector256::setValue(STVector256 const& v)
{
mValue = v.mValue;
value_ = v.value_;
}
/** Retrieve a copy of the vector we contain */
inline STVector256::
operator std::vector<uint256>() const
{
return mValue;
return value_;
}
inline std::size_t
STVector256::size() const
{
return mValue.size();
return value_.size();
}
inline void
STVector256::resize(std::size_t n)
{
return mValue.resize(n);
value_.resize(n);
}
inline bool
STVector256::empty() const
{
return mValue.empty();
return value_.empty();
}
inline std::vector<uint256>::reference
STVector256::operator[](std::vector<uint256>::size_type n)
{
return mValue[n];
return value_[n];
}
inline std::vector<uint256>::const_reference
STVector256::operator[](std::vector<uint256>::size_type n) const
{
return mValue[n];
return value_[n];
}
inline std::vector<uint256> const&
STVector256::value() const
{
return mValue;
return value_;
}
inline std::vector<uint256>::iterator
STVector256::insert(std::vector<uint256>::const_iterator pos, uint256 const& value)
{
return mValue.insert(pos, value);
return value_.insert(pos, value);
}
inline void
STVector256::push_back(uint256 const& v)
STVector256::pushBack(uint256 const& v)
{
mValue.push_back(v);
value_.push_back(v);
}
inline std::vector<uint256>::iterator
STVector256::begin()
{
return mValue.begin();
return value_.begin();
}
inline std::vector<uint256>::const_iterator
STVector256::begin() const
{
return mValue.begin();
return value_.begin();
}
inline std::vector<uint256>::iterator
STVector256::end()
{
return mValue.end();
return value_.end();
}
inline std::vector<uint256>::const_iterator
STVector256::end() const
{
return mValue.end();
return value_.end();
}
inline std::vector<uint256>::iterator
STVector256::erase(std::vector<uint256>::iterator position)
{
return mValue.erase(position);
return value_.erase(position);
}
inline void
STVector256::clear() noexcept
{
return mValue.clear();
value_.clear();
}
} // namespace xrpl

View File

@@ -20,7 +20,7 @@ class STXChainBridge final : public STBase, public CountedObject<STXChainBridge>
public:
using value_type = STXChainBridge;
enum class ChainType { locking, issuing };
enum class ChainType { Locking, Issuing };
static ChainType
otherChain(ChainType ct);
@@ -45,54 +45,54 @@ public:
AccountID const& dstChainDoor,
Issue const& dstChainIssue);
explicit STXChainBridge(Json::Value const& v);
explicit STXChainBridge(json::Value const& v);
explicit STXChainBridge(SField const& name, Json::Value const& v);
explicit STXChainBridge(SField const& name, json::Value const& v);
explicit STXChainBridge(SerialIter& sit, SField const& name);
STXChainBridge&
operator=(STXChainBridge const& rhs) = default;
std::string
[[nodiscard]] std::string
getText() const override;
STObject
[[nodiscard]] STObject
toSTObject() const;
AccountID const&
[[nodiscard]] AccountID const&
lockingChainDoor() const;
Issue const&
[[nodiscard]] Issue const&
lockingChainIssue() const;
AccountID const&
[[nodiscard]] AccountID const&
issuingChainDoor() const;
Issue const&
[[nodiscard]] Issue const&
issuingChainIssue() const;
AccountID const&
[[nodiscard]] AccountID const&
door(ChainType ct) const;
Issue const&
[[nodiscard]] Issue const&
issue(ChainType ct) const;
SerializedTypeID
[[nodiscard]] SerializedTypeID
getSType() const override;
Json::Value getJson(JsonOptions) const override;
[[nodiscard]] json::Value getJson(JsonOptions) const override;
void
add(Serializer& s) const override;
bool
[[nodiscard]] bool
isEquivalent(STBase const& t) const override;
bool
[[nodiscard]] bool
isDefault() const override;
value_type const&
[[nodiscard]] value_type const&
value() const noexcept;
private:
@@ -174,7 +174,7 @@ STXChainBridge::value() const noexcept
inline AccountID const&
STXChainBridge::door(ChainType ct) const
{
if (ct == ChainType::locking)
if (ct == ChainType::Locking)
return lockingChainDoor();
return issuingChainDoor();
}
@@ -182,7 +182,7 @@ STXChainBridge::door(ChainType ct) const
inline Issue const&
STXChainBridge::issue(ChainType ct) const
{
if (ct == ChainType::locking)
if (ct == ChainType::Locking)
return lockingChainIssue();
return issuingChainIssue();
}
@@ -190,25 +190,25 @@ STXChainBridge::issue(ChainType ct) const
inline STXChainBridge::ChainType
STXChainBridge::otherChain(ChainType ct)
{
if (ct == ChainType::locking)
return ChainType::issuing;
return ChainType::locking;
if (ct == ChainType::Locking)
return ChainType::Issuing;
return ChainType::Locking;
}
inline STXChainBridge::ChainType
STXChainBridge::srcChain(bool wasLockingChainSend)
{
if (wasLockingChainSend)
return ChainType::locking;
return ChainType::issuing;
return ChainType::Locking;
return ChainType::Issuing;
}
inline STXChainBridge::ChainType
STXChainBridge::dstChain(bool wasLockingChainSend)
{
if (wasLockingChainSend)
return ChainType::issuing;
return ChainType::locking;
return ChainType::Issuing;
return ChainType::Locking;
}
} // namespace xrpl

View File

@@ -17,10 +17,10 @@ namespace xrpl {
class SecretKey
{
public:
static constexpr std::size_t size_ = 32;
static constexpr std::size_t kSize = 32;
private:
std::uint8_t buf_[size_]{};
std::uint8_t buf_[kSize]{};
public:
using const_iterator = std::uint8_t const*;
@@ -37,16 +37,16 @@ public:
~SecretKey();
SecretKey(std::array<std::uint8_t, size_> const& data);
SecretKey(std::array<std::uint8_t, kSize> const& data);
SecretKey(Slice const& slice);
std::uint8_t const*
[[nodiscard]] std::uint8_t const*
data() const
{
return buf_;
}
std::size_t
[[nodiscard]] std::size_t
size() const
{
return sizeof(buf_);
@@ -57,38 +57,38 @@ public:
@note The operator<< function is deliberately omitted
to avoid accidental exposure of secret key material.
*/
std::string
to_string() const;
[[nodiscard]] std::string
toString() const;
const_iterator
[[nodiscard]] const_iterator
begin() const noexcept
{
return buf_;
}
const_iterator
[[nodiscard]] const_iterator
cbegin() const noexcept
{
return buf_;
}
const_iterator
[[nodiscard]] const_iterator
end() const noexcept
{
return buf_ + sizeof(buf_);
}
const_iterator
[[nodiscard]] const_iterator
cend() const noexcept
{
return buf_ + sizeof(buf_);
}
};
inline bool
bool
operator==(SecretKey const& lhs, SecretKey const& rhs) = delete;
inline bool
bool
operator!=(SecretKey const& lhs, SecretKey const& rhs) = delete;
//------------------------------------------------------------------------------
@@ -118,7 +118,7 @@ derivePublicKey(KeyType type, SecretKey const& sk);
/** Generate a key pair deterministically.
This algorithm is specific to Ripple:
This algorithm is specific to the XRPL:
For secp256k1 key pairs, the seed is converted
to a Generator and used to compute the key pair

View File

@@ -35,37 +35,37 @@ public:
explicit Seed(uint128 const& seed);
/** @} */
std::uint8_t const*
[[nodiscard]] std::uint8_t const*
data() const
{
return buf_.data();
}
std::size_t
[[nodiscard]] std::size_t
size() const
{
return buf_.size();
}
const_iterator
[[nodiscard]] const_iterator
begin() const noexcept
{
return buf_.begin();
}
const_iterator
[[nodiscard]] const_iterator
cbegin() const noexcept
{
return buf_.cbegin();
}
const_iterator
[[nodiscard]] const_iterator
end() const noexcept
{
return buf_.end();
}
const_iterator
[[nodiscard]] const_iterator
cend() const noexcept
{
return buf_.cend();
@@ -80,7 +80,7 @@ randomSeed();
/** Generate a seed deterministically.
The algorithm is specific to Ripple:
The algorithm is specific to the XRPL:
The seed is calculated as the first 128 bits
of the SHA512-Half of the string text excluding

View File

@@ -35,7 +35,7 @@ namespace xrpl {
class SeqProxy
{
public:
enum Type : std::uint8_t { seq = 0, ticket };
enum class Type : std::uint8_t { Seq = 0, Ticket };
private:
std::uint32_t value_;
@@ -55,25 +55,25 @@ public:
static constexpr SeqProxy
sequence(std::uint32_t v)
{
return SeqProxy{Type::seq, v};
return SeqProxy{Type::Seq, v};
}
constexpr std::uint32_t
[[nodiscard]] constexpr std::uint32_t
value() const
{
return value_;
}
constexpr bool
[[nodiscard]] constexpr bool
isSeq() const
{
return type_ == seq;
return type_ == Type::Seq;
}
constexpr bool
[[nodiscard]] constexpr bool
isTicket() const
{
return type_ == ticket;
return type_ == Type::Ticket;
}
// Occasionally it is convenient to be able to increase the value_

View File

@@ -21,41 +21,41 @@ class Serializer
{
private:
// DEPRECATED
Blob mData;
Blob data_;
public:
explicit Serializer(int n = 256)
{
mData.reserve(n);
data_.reserve(n);
}
Serializer(void const* data, std::size_t size)
{
mData.resize(size);
data_.resize(size);
if (size)
if (size != 0u)
{
XRPL_ASSERT(data, "xrpl::Serializer::Serializer(void const*) : non-null input");
std::memcpy(mData.data(), data, size);
std::memcpy(data_.data(), data, size);
}
}
Slice
[[nodiscard]] Slice
slice() const noexcept
{
return Slice(mData.data(), mData.size());
return Slice(data_.data(), data_.size());
}
std::size_t
[[nodiscard]] std::size_t
size() const noexcept
{
return mData.size();
return data_.size();
}
void const*
[[nodiscard]] void const*
data() const noexcept
{
return mData.data();
return data_.data();
}
// assemble functions
@@ -69,11 +69,11 @@ public:
int
add32(T i)
{
int ret = mData.size();
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
mData.push_back(static_cast<unsigned char>(i & 0xff));
int const ret = data_.size();
data_.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
data_.push_back(static_cast<unsigned char>(i & 0xff));
return ret;
}
@@ -85,15 +85,15 @@ public:
int
add64(T i)
{
int ret = mData.size();
mData.push_back(static_cast<unsigned char>((i >> 56) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 48) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 40) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 32) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
mData.push_back(static_cast<unsigned char>(i & 0xff));
int const ret = data_.size();
data_.push_back(static_cast<unsigned char>((i >> 56) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 48) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 40) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 32) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
data_.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
data_.push_back(static_cast<unsigned char>(i & 0xff));
return ret;
}
@@ -102,7 +102,7 @@ public:
template <std::size_t Bits, class Tag>
int
addBitString(base_uint<Bits, Tag> const& v)
addBitString(BaseUInt<Bits, Tag> const& v)
{
return addRaw(v.data(), v.size());
}
@@ -134,13 +134,13 @@ public:
bool
getInteger(Integer& number, int offset)
{
static auto const bytes = sizeof(Integer);
if ((offset + bytes) > mData.size())
static auto const kBytes = sizeof(Integer);
if ((offset + kBytes) > data_.size())
return false;
number = 0;
auto ptr = &mData[offset];
for (auto i = 0; i < bytes; ++i)
auto ptr = &data_[offset];
for (auto i = 0; i < kBytes; ++i)
{
if (i)
number <<= 8;
@@ -151,11 +151,11 @@ public:
template <std::size_t Bits, typename Tag = void>
bool
getBitString(base_uint<Bits, Tag>& data, int offset) const
getBitString(BaseUInt<Bits, Tag>& data, int offset) const
{
auto success = (offset + (Bits / 8)) <= mData.size();
auto success = (offset + (Bits / 8)) <= data_.size();
if (success)
memcpy(data.begin(), &(mData.front()) + offset, (Bits / 8));
memcpy(data.begin(), &(data_.front()) + offset, (Bits / 8));
return success;
}
@@ -164,51 +164,51 @@ public:
int
addFieldID(SerializedTypeID type, int name)
{
return addFieldID(safe_cast<int>(type), name);
return addFieldID(safeCast<int>(type), name);
}
// DEPRECATED
uint256
[[nodiscard]] uint256
getSHA512Half() const;
// totality functions
Blob const&
[[nodiscard]] Blob const&
peekData() const
{
return mData;
return data_;
}
Blob
[[nodiscard]] Blob
getData() const
{
return mData;
return data_;
}
Blob&
modData()
{
return mData;
return data_;
}
int
[[nodiscard]] int
getDataLength() const
{
return mData.size();
return data_.size();
}
void const*
[[nodiscard]] void const*
getDataPtr() const
{
return mData.data();
return data_.data();
}
void*
getDataPtr()
{
return mData.data();
return data_.data();
}
int
[[nodiscard]] int
getLength() const
{
return mData.size();
return data_.size();
}
std::string
[[nodiscard]] std::string
getString() const
{
return std::string(static_cast<char const*>(getDataPtr()), size());
@@ -216,7 +216,7 @@ public:
void
erase()
{
mData.clear();
data_.clear();
}
bool
chop(int num);
@@ -225,58 +225,58 @@ public:
Blob ::iterator
begin()
{
return mData.begin();
return data_.begin();
}
Blob ::iterator
end()
{
return mData.end();
return data_.end();
}
Blob ::const_iterator
[[nodiscard]] Blob ::const_iterator
begin() const
{
return mData.begin();
return data_.begin();
}
Blob ::const_iterator
[[nodiscard]] Blob ::const_iterator
end() const
{
return mData.end();
return data_.end();
}
void
reserve(size_t n)
{
mData.reserve(n);
data_.reserve(n);
}
void
resize(size_t n)
{
mData.resize(n);
data_.resize(n);
}
size_t
[[nodiscard]] size_t
capacity() const
{
return mData.capacity();
return data_.capacity();
}
bool
operator==(Blob const& v) const
{
return v == mData;
return v == data_;
}
bool
operator!=(Blob const& v) const
{
return v != mData;
return v != data_;
}
bool
operator==(Serializer const& v) const
{
return v.mData == mData;
return v.data_ == data_;
}
bool
operator!=(Serializer const& v) const
{
return v.mData != mData;
return v.data_ != data_;
}
static int
@@ -299,7 +299,7 @@ template <class Iter>
int
Serializer::addVL(Iter begin, Iter end, int len)
{
int ret = addEncoded(len);
int const ret = addEncoded(len);
for (; begin != end; ++begin)
{
addRaw(begin->data(), begin->size());
@@ -345,7 +345,7 @@ public:
void
reset() noexcept;
int
[[nodiscard]] int
getBytesLeft() const noexcept
{
return static_cast<int>(remain_);
@@ -369,7 +369,7 @@ public:
geti64();
template <std::size_t Bits, class Tag = void>
base_uint<Bits, Tag>
BaseUInt<Bits, Tag>
getBitString();
uint128
@@ -428,7 +428,7 @@ public:
};
template <std::size_t Bits, class Tag>
base_uint<Bits, Tag>
BaseUInt<Bits, Tag>
SerialIter::getBitString()
{
auto const n = Bits / 8;
@@ -442,7 +442,7 @@ SerialIter::getBitString()
used_ += n;
remain_ -= n;
return base_uint<Bits, Tag>::fromVoid(x);
return BaseUInt<Bits, Tag>::fromVoid(x);
}
} // namespace xrpl

View File

@@ -14,22 +14,22 @@ namespace xrpl {
static inline std::string const&
systemName()
{
static std::string const name = "xrpld";
return name;
static std::string const kName = "xrpld";
return kName;
}
/** Configure the native currency. */
/** Number of drops in the genesis account. */
constexpr XRPAmount INITIAL_XRP{100'000'000'000 * DROPS_PER_XRP};
static_assert(INITIAL_XRP.drops() == 100'000'000'000'000'000);
static_assert(Number::maxRep >= INITIAL_XRP.drops());
constexpr XRPAmount kInitialXrp{100'000'000'000 * kDropsPerXrp};
static_assert(kInitialXrp.drops() == 100'000'000'000'000'000);
static_assert(Number::kMaxRep >= kInitialXrp.drops());
/** Returns true if the amount does not exceed the initial XRP in existence. */
inline bool
isLegalAmount(XRPAmount const& amount)
{
return amount <= INITIAL_XRP;
return amount <= kInitialXrp;
}
/** Returns true if the absolute value of the amount does not exceed the initial
@@ -37,31 +37,31 @@ isLegalAmount(XRPAmount const& amount)
inline bool
isLegalAmountSigned(XRPAmount const& amount)
{
return amount >= -INITIAL_XRP && amount <= INITIAL_XRP;
return amount >= -kInitialXrp && amount <= kInitialXrp;
}
/* The currency code for the native currency. */
static inline std::string const&
systemCurrencyCode()
{
static std::string const code = "XRP";
return code;
static std::string const kCode = "XRP";
return kCode;
}
/** The XRP ledger network's earliest allowed sequence */
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_SEQ{32570u};
static constexpr std::uint32_t kXrpLedgerEarliestSeq{32570u};
/** The XRP Ledger mainnet's earliest ledger with a FeeSettings object. Only
* used in asserts and tests. */
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES{562177u};
static constexpr std::uint32_t kXrpLedgerEarliestFees{562177u};
/** The minimum amount of support an amendment should have. */
constexpr std::ratio<80, 100> amendmentMajorityCalcThreshold;
constexpr std::ratio<80, 100> kAmendmentMajorityCalcThreshold;
/** The minimum amount of time an amendment must hold a majority */
constexpr std::chrono::seconds const defaultAmendmentMajorityTime = weeks{2};
constexpr std::chrono::seconds const kDefaultAmendmentMajorityTime = weeks{2};
} // namespace xrpl
/** Default peer port (IANA registered) */
inline std::uint16_t constexpr DEFAULT_PEER_PORT{2459};
inline constexpr std::uint16_t kDefaultPeerPort{2459};

View File

@@ -1,5 +1,7 @@
#pragma once
// NOLINTBEGIN(readability-identifier-naming)
#include <xrpl/basics/safe_cast.h>
#include <xrpl/json/json_value.h>
@@ -19,6 +21,8 @@ using TERUnderlyingType = int;
//------------------------------------------------------------------------------
// Protocol-critical, mixed with custom TER wrapper type, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TELcodes : TERUnderlyingType {
// Note: Range is stable.
// Exact numbers are used in ripple-binary-codec:
@@ -50,6 +54,8 @@ enum TELcodes : TERUnderlyingType {
//------------------------------------------------------------------------------
// Protocol-critical, mixed with custom TER wrapper type, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TEMcodes : TERUnderlyingType {
// Note: Range is stable.
// Exact numbers are used in ripple-binary-codec:
@@ -121,10 +127,13 @@ enum TEMcodes : TERUnderlyingType {
temARRAY_TOO_LARGE,
temBAD_TRANSFER_FEE,
temINVALID_INNER_BATCH,
temBAD_MPT,
};
//------------------------------------------------------------------------------
// Protocol-critical, mixed with custom TER wrapper type, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TEFcodes : TERUnderlyingType {
// Note: Range is stable.
// Exact numbers are used in ripple-binary-codec:
@@ -169,6 +178,8 @@ enum TEFcodes : TERUnderlyingType {
//------------------------------------------------------------------------------
// Protocol-critical, mixed with custom TER wrapper type, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TERcodes : TERUnderlyingType {
// Note: Range is stable.
// Exact numbers are used in ripple-binary-codec:
@@ -208,10 +219,13 @@ enum TERcodes : TERUnderlyingType {
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
// create a pseudo-account
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
terLOCKED, // MPT is locked
};
//------------------------------------------------------------------------------
// Protocol-critical, mixed with custom TER wrapper type, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TEScodes : TERUnderlyingType {
// Note: Exact number must stay stable. This code is stored by value
// in metadata for historic transactions.
@@ -227,6 +241,8 @@ enum TEScodes : TERUnderlyingType {
//------------------------------------------------------------------------------
// Protocol-critical, mixed with custom TER wrapper type, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TECcodes : TERUnderlyingType {
// Note: Exact numbers must stay stable. These codes are stored by
// value in metadata for historic transactions.
@@ -342,10 +358,6 @@ enum TECcodes : TERUnderlyingType {
tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196,
tecPRECISION_LOSS = 197,
// DEPRECATED: This error code tecNO_DELEGATE_PERMISSION is reserved for
// backward compatibility with historical data on non-prod networks, can be
// reclaimed after those networks reset.
tecNO_DELEGATE_PERMISSION = 198,
};
//------------------------------------------------------------------------------
@@ -354,37 +366,37 @@ enum TECcodes : TERUnderlyingType {
constexpr TERUnderlyingType
TERtoInt(TELcodes v)
{
return safe_cast<TERUnderlyingType>(v);
return safeCast<TERUnderlyingType>(v);
}
constexpr TERUnderlyingType
TERtoInt(TEMcodes v)
{
return safe_cast<TERUnderlyingType>(v);
return safeCast<TERUnderlyingType>(v);
}
constexpr TERUnderlyingType
TERtoInt(TEFcodes v)
{
return safe_cast<TERUnderlyingType>(v);
return safeCast<TERUnderlyingType>(v);
}
constexpr TERUnderlyingType
TERtoInt(TERcodes v)
{
return safe_cast<TERUnderlyingType>(v);
return safeCast<TERUnderlyingType>(v);
}
constexpr TERUnderlyingType
TERtoInt(TEScodes v)
{
return safe_cast<TERUnderlyingType>(v);
return safeCast<TERUnderlyingType>(v);
}
constexpr TERUnderlyingType
TERtoInt(TECcodes v)
{
return safe_cast<TERUnderlyingType>(v);
return safeCast<TERUnderlyingType>(v);
}
//------------------------------------------------------------------------------
@@ -445,11 +457,11 @@ public:
return code_ != tesSUCCESS;
}
// Conversion to Json::Value allows assignment to Json::Objects
// Conversion to json::Value allows assignment to json::Objects
// without casting.
operator Json::Value() const
operator json::Value() const
{
return Json::Value{code_};
return json::Value{code_};
}
// Streaming operator.
@@ -487,8 +499,7 @@ public:
template <typename L, typename R>
constexpr auto
operator==(L const& lhs, R const& rhs) -> std::enable_if_t<
std::is_same<decltype(TERtoInt(lhs)), int>::value &&
std::is_same<decltype(TERtoInt(rhs)), int>::value,
std::is_same_v<decltype(TERtoInt(lhs)), int> && std::is_same_v<decltype(TERtoInt(rhs)), int>,
bool>
{
return TERtoInt(lhs) == TERtoInt(rhs);
@@ -497,8 +508,7 @@ operator==(L const& lhs, R const& rhs) -> std::enable_if_t<
template <typename L, typename R>
constexpr auto
operator!=(L const& lhs, R const& rhs) -> std::enable_if_t<
std::is_same<decltype(TERtoInt(lhs)), int>::value &&
std::is_same<decltype(TERtoInt(rhs)), int>::value,
std::is_same_v<decltype(TERtoInt(lhs)), int> && std::is_same_v<decltype(TERtoInt(rhs)), int>,
bool>
{
return TERtoInt(lhs) != TERtoInt(rhs);
@@ -507,8 +517,7 @@ operator!=(L const& lhs, R const& rhs) -> std::enable_if_t<
template <typename L, typename R>
constexpr auto
operator<(L const& lhs, R const& rhs) -> std::enable_if_t<
std::is_same<decltype(TERtoInt(lhs)), int>::value &&
std::is_same<decltype(TERtoInt(rhs)), int>::value,
std::is_same_v<decltype(TERtoInt(lhs)), int> && std::is_same_v<decltype(TERtoInt(rhs)), int>,
bool>
{
return TERtoInt(lhs) < TERtoInt(rhs);
@@ -517,8 +526,7 @@ operator<(L const& lhs, R const& rhs) -> std::enable_if_t<
template <typename L, typename R>
constexpr auto
operator<=(L const& lhs, R const& rhs) -> std::enable_if_t<
std::is_same<decltype(TERtoInt(lhs)), int>::value &&
std::is_same<decltype(TERtoInt(rhs)), int>::value,
std::is_same_v<decltype(TERtoInt(lhs)), int> && std::is_same_v<decltype(TERtoInt(rhs)), int>,
bool>
{
return TERtoInt(lhs) <= TERtoInt(rhs);
@@ -527,8 +535,7 @@ operator<=(L const& lhs, R const& rhs) -> std::enable_if_t<
template <typename L, typename R>
constexpr auto
operator>(L const& lhs, R const& rhs) -> std::enable_if_t<
std::is_same<decltype(TERtoInt(lhs)), int>::value &&
std::is_same<decltype(TERtoInt(rhs)), int>::value,
std::is_same_v<decltype(TERtoInt(lhs)), int> && std::is_same_v<decltype(TERtoInt(rhs)), int>,
bool>
{
return TERtoInt(lhs) > TERtoInt(rhs);
@@ -537,8 +544,7 @@ operator>(L const& lhs, R const& rhs) -> std::enable_if_t<
template <typename L, typename R>
constexpr auto
operator>=(L const& lhs, R const& rhs) -> std::enable_if_t<
std::is_same<decltype(TERtoInt(lhs)), int>::value &&
std::is_same<decltype(TERtoInt(rhs)), int>::value,
std::is_same_v<decltype(TERtoInt(lhs)), int> && std::is_same_v<decltype(TERtoInt(rhs)), int>,
bool>
{
return TERtoInt(lhs) >= TERtoInt(rhs);
@@ -676,3 +682,5 @@ std::optional<TER>
transCode(std::string const& token);
} // namespace xrpl
// NOLINTEND(readability-identifier-naming)

View File

@@ -1,5 +1,7 @@
#pragma once
// NOLINTBEGIN(readability-identifier-naming)
#include <xrpl/protocol/LedgerFormats.h>
#include <cstdint>
@@ -235,7 +237,7 @@ XMACRO(NULL_NAME, TO_VALUE, NULL_OUTPUT, NULL_MASK_ADJ)
// The mask adjustment (maskAdj) allows adding flags back to the mask, making them invalid.
// For example, Batch uses MASK_ADJ(tfInnerBatchTxn) to reject tfInnerBatchTxn on outer Batch.
#define TO_MASK(name, values, maskAdj) \
inline constexpr FlagValue tf##name##Mask = ~(tfUniversal values) | maskAdj;
inline constexpr FlagValue tf##name##Mask = ~(tfUniversal values) | (maskAdj);
#define VALUE_TO_MASK(name, value) | name
#define MASK_ADJ_TO_MASK(value) value
XMACRO(TO_MASK, VALUE_TO_MASK, VALUE_TO_MASK, MASK_ADJ_TO_MASK)
@@ -444,3 +446,5 @@ getAsfFlagMap()
#pragma pop_macro("ACCOUNTSET_FLAGS")
} // namespace xrpl
// NOLINTEND(readability-identifier-naming)

View File

@@ -35,6 +35,8 @@ namespace xrpl {
@ingroup protocol
*/
// clang-format off
// Protocol-critical, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TxType : std::uint16_t
{
@@ -49,16 +51,16 @@ enum TxType : std::uint16_t
#pragma pop_macro("TRANSACTION")
/** This transaction type is deprecated; it is retained for historical purposes. */
ttNICKNAME_SET [[deprecated("This transaction type is not supported and should not be used.")]] = 6,
TtNicknameSet [[deprecated("This transaction type is not supported and should not be used.")]] = 6,
/** This transaction type is deprecated; it is retained for historical purposes. */
ttCONTRACT [[deprecated("This transaction type is not supported and should not be used.")]] = 9,
TtContract [[deprecated("This transaction type is not supported and should not be used.")]] = 9,
/** This identifier was never used, but the slot is reserved for historical purposes. */
ttSPINAL_TAP [[deprecated("This transaction type is not supported and should not be used.")]] = 11,
TtSpinalTap [[deprecated("This transaction type is not supported and should not be used.")]] = 11,
/** This transaction type installs a hook. */
ttHOOK_SET [[maybe_unused]] = 22,
TtHookSet [[maybe_unused]] = 22,
};
// clang-format on

View File

@@ -18,27 +18,27 @@ public:
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
uint256 const&
[[nodiscard]] uint256 const&
getTxID() const
{
return transactionID_;
}
std::uint32_t
[[nodiscard]] std::uint32_t
getLgrSeq() const
{
return ledgerSeq_;
}
int
[[nodiscard]] int
getResult() const
{
return result_;
}
TER
[[nodiscard]] TER
getResultTER() const
{
return TER::fromInt(result_);
}
std::uint32_t
[[nodiscard]] std::uint32_t
getIndex() const
{
return index_;
@@ -52,10 +52,10 @@ public:
getAffectedNode(uint256 const&);
/** Return a list of accounts affected by this transaction */
boost::container::flat_set<AccountID>
[[nodiscard]] boost::container::flat_set<AccountID>
getAffectedAccounts() const;
Json::Value
[[nodiscard]] json::Value
getJson(JsonOptions p) const
{
return getAsObject().getJson(p);
@@ -63,14 +63,14 @@ public:
void
addRaw(Serializer&, TER, std::uint32_t index);
STObject
[[nodiscard]] STObject
getAsObject() const;
STArray&
getNodes()
{
return nodes_;
}
STArray const&
[[nodiscard]] STArray const&
getNodes() const
{
return nodes_;
@@ -86,7 +86,7 @@ public:
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
}
std::optional<STAmount> const&
[[nodiscard]] std::optional<STAmount> const&
getDeliveredAmount() const
{
return deliveredAmount_;

View File

@@ -4,4 +4,4 @@ namespace xrpl {
enum class TxSearched { All, Some, Unknown };
}
} // namespace xrpl

View File

@@ -30,21 +30,21 @@ public:
/** Directory is an index into the directory of offer books.
The last 64 bits of this are the quality. */
using Directory = base_uint<256, detail::DirectoryTag>;
using Directory = BaseUInt<256, detail::DirectoryTag>;
/** Currency is a hash representing a specific currency. */
using Currency = base_uint<160, detail::CurrencyTag>;
using Currency = BaseUInt<160, detail::CurrencyTag>;
/** NodeID is a 160-bit hash representing one node. */
using NodeID = base_uint<160, detail::NodeIDTag>;
using NodeID = BaseUInt<160, detail::NodeIDTag>;
/** MPTID is a 192-bit value representing MPT Issuance ID,
* which is a concatenation of a 32-bit sequence (big endian)
* and a 160-bit account */
using MPTID = base_uint<192>;
using MPTID = BaseUInt<192>;
/** Domain is a 256-bit hash representing a specific domain. */
using Domain = base_uint<256>;
using Domain = BaseUInt<256>;
/** XRP currency. */
Currency const&
@@ -62,7 +62,7 @@ badCurrency();
inline bool
isXRP(Currency const& c)
{
return c == beast::zero;
return c == beast::kZero;
}
/** Returns "", "XRP", or three letter ISO code. */
@@ -77,7 +77,7 @@ to_string(Currency const& c);
to rewrite some unit test code.
*/
bool
to_currency(Currency&, std::string const&);
toCurrency(Currency&, std::string const&);
/** Tries to convert a string to a Currency, returns noCurrency() on failure.
@@ -86,7 +86,7 @@ to_currency(Currency&, std::string const&);
everywhere and may mean having to rewrite some unit test code.
*/
Currency
to_currency(std::string const&);
toCurrency(std::string const&);
inline std::ostream&
operator<<(std::ostream& os, Currency const& x)

View File

@@ -21,7 +21,7 @@ namespace unit {
struct dropTag;
/** "fee levels" are used by the transaction queue to compare the relative
cost of transactions that require different levels of effort to process.
See also: src/ripple/app/misc/FeeEscalation.md#fee-level */
See also: src/xrpld/app/misc/FeeEscalation.md#fee-level */
struct feelevelTag;
/** unitless values are plain scalars wrapped in a ValueUnit. They are
used for calculations in this header. */
@@ -117,7 +117,7 @@ public:
template <Compatible<ValueUnit> Other>
constexpr ValueUnit(ValueUnit<unit_type, Other> const& value)
requires SafeToCast<Other, value_type>
: ValueUnit(safe_cast<value_type>(value.value()))
: ValueUnit(safeCast<value_type>(value.value()))
{
}
@@ -209,7 +209,7 @@ public:
return *this;
}
template <Integral transparent = value_type>
template <Integral Transparent = value_type>
ValueUnit&
operator%=(value_type const& rhs)
{
@@ -264,22 +264,24 @@ public:
}
/** Return the sign of the amount */
constexpr int
[[nodiscard]] constexpr int
signum() const noexcept
{
return (value_ < 0) ? -1 : (value_ ? 1 : 0);
if (value_ < 0)
return -1;
return value_ ? 1 : 0;
}
/** Returns the number of drops */
// TODO: Move this to a new class, maybe with the old "TaggedFee" name
constexpr value_type
[[nodiscard]] constexpr value_type
fee() const
{
return value_;
}
template <class Other>
constexpr double
[[nodiscard]] constexpr double
decimalFromReference(ValueUnit<unit_type, Other> reference) const
{
return static_cast<double>(value_) / reference.value();
@@ -289,22 +291,22 @@ public:
// known valid type tags can be converted to JSON. At the time
// of implementation, that includes all known tags, but more may
// be added in the future.
Json::Value
[[nodiscard]] json::Value
jsonClipped() const
requires Usable<ValueUnit>
{
if constexpr (std::is_integral_v<value_type>)
{
using jsontype =
std::conditional_t<std::is_signed_v<value_type>, Json::Int, Json::UInt>;
std::conditional_t<std::is_signed_v<value_type>, json::Int, json::UInt>;
constexpr auto min = std::numeric_limits<jsontype>::min();
constexpr auto max = std::numeric_limits<jsontype>::max();
constexpr auto kMin = std::numeric_limits<jsontype>::min();
constexpr auto kMax = std::numeric_limits<jsontype>::max();
if (value_ < min)
return min;
if (value_ > max)
return max;
if (value_ < kMin)
return kMin;
if (value_ > kMax)
return kMax;
return static_cast<jsontype>(value_);
}
else
@@ -317,7 +319,7 @@ public:
function unless the type has been abstracted away,
e.g. in a templated function.
*/
constexpr value_type
[[nodiscard]] constexpr value_type
value() const
{
return value_;
@@ -390,14 +392,14 @@ mulDivU(Source1 value, Dest mul, Source2 div)
}
using desttype = typename Dest::value_type;
constexpr auto max = std::numeric_limits<desttype>::max();
constexpr auto kMax = std::numeric_limits<desttype>::max();
// Shortcuts, since these happen a lot in the real world
if (value == div)
return mul;
if (mul.value() == div.value())
{
if (value.value() > max)
if (value.value() > kMax)
return std::nullopt;
return Dest{static_cast<desttype>(value.value())};
}
@@ -412,7 +414,7 @@ mulDivU(Source1 value, Dest mul, Source2 div)
auto quotient = product / div.value();
if (quotient > max)
if (quotient > kMax)
return std::nullopt;
return Dest{static_cast<desttype>(quotient)};
@@ -492,34 +494,34 @@ mulDiv(std::uint64_t value, Source1 mul, Source2 div)
template <unit::IntegralValue Dest, unit::CastableValue<Dest> Src>
constexpr Dest
safe_cast(Src s) noexcept
safeCast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s.value())};
return Dest{safeCast<typename Dest::value_type>(s.value())};
}
template <unit::IntegralValue Dest, unit::Integral Src>
constexpr Dest
safe_cast(Src s) noexcept
safeCast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s)};
return Dest{safeCast<typename Dest::value_type>(s)};
}
template <unit::IntegralValue Dest, unit::CastableValue<Dest> Src>
constexpr Dest
unsafe_cast(Src s) noexcept
unsafeCast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
return Dest{unsafeCast<typename Dest::value_type>(s.value())};
}
template <unit::IntegralValue Dest, unit::Integral Src>
constexpr Dest
unsafe_cast(Src s) noexcept
unsafeCast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{unsafe_cast<typename Dest::value_type>(s)};
return Dest{unsafeCast<typename Dest::value_type>(s)};
}
} // namespace xrpl

View File

@@ -15,6 +15,7 @@
#include <boost/container/vector.hpp>
#include <cstddef>
#include <utility>
#include <vector>
namespace xrpl {
@@ -41,13 +42,13 @@ struct AttestationBase
bool wasLockingChainSend;
explicit AttestationBase(
AccountID attestationSignerAccount_,
PublicKey const& publicKey_,
Buffer signature_,
AccountID const& sendingAccount_,
STAmount const& sendingAmount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_);
AccountID attestationSignerAccount,
PublicKey const& publicKey,
Buffer signature,
AccountID const& sendingAccount,
STAmount sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend);
AttestationBase(AttestationBase const&) = default;
@@ -57,12 +58,12 @@ struct AttestationBase
operator=(AttestationBase const&) = default;
// verify that the signature attests to the data.
bool
[[nodiscard]] bool
verify(STXChainBridge const& bridge) const;
protected:
explicit AttestationBase(STObject const& o);
explicit AttestationBase(Json::Value const& v);
explicit AttestationBase(json::Value const& v);
[[nodiscard]] static bool
equalHelper(AttestationBase const& lhs, AttestationBase const& rhs);
@@ -85,30 +86,30 @@ struct AttestationClaim : AttestationBase
std::optional<AccountID> dst;
explicit AttestationClaim(
AccountID attestationSignerAccount_,
PublicKey const& publicKey_,
Buffer signature_,
AccountID const& sendingAccount_,
STAmount const& sendingAmount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_,
std::uint64_t claimID_,
std::optional<AccountID> const& dst_);
AccountID attestationSignerAccount,
PublicKey const& publicKey,
Buffer signature,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimId,
std::optional<AccountID> const& dst);
explicit AttestationClaim(
STXChainBridge const& bridge,
AccountID attestationSignerAccount_,
PublicKey const& publicKey_,
SecretKey const& secretKey_,
AccountID const& sendingAccount_,
STAmount const& sendingAmount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_,
std::uint64_t claimID_,
std::optional<AccountID> const& dst_);
AccountID attestationSignerAccount,
PublicKey const& publicKey,
SecretKey const& secretKey,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t claimId,
std::optional<AccountID> const& dst);
explicit AttestationClaim(STObject const& o);
explicit AttestationClaim(Json::Value const& v);
explicit AttestationClaim(json::Value const& v);
[[nodiscard]] STObject
toSTObject() const;
@@ -161,32 +162,32 @@ struct AttestationCreateAccount : AttestationBase
explicit AttestationCreateAccount(STObject const& o);
explicit AttestationCreateAccount(Json::Value const& v);
explicit AttestationCreateAccount(json::Value const& v);
explicit AttestationCreateAccount(
AccountID attestationSignerAccount_,
PublicKey const& publicKey_,
Buffer signature_,
AccountID const& sendingAccount_,
STAmount const& sendingAmount_,
STAmount const& rewardAmount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_,
std::uint64_t createCount_,
AccountID const& toCreate_);
AccountID attestationSignerAccount,
PublicKey const& publicKey,
Buffer signature,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STAmount rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
AccountID const& toCreate);
explicit AttestationCreateAccount(
STXChainBridge const& bridge,
AccountID attestationSignerAccount_,
PublicKey const& publicKey_,
SecretKey const& secretKey_,
AccountID const& sendingAccount_,
STAmount const& sendingAmount_,
STAmount const& rewardAmount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_,
std::uint64_t createCount_,
AccountID const& toCreate_);
AccountID attestationSignerAccount,
PublicKey const& publicKey,
SecretKey const& secretKey,
AccountID const& sendingAccount,
STAmount const& sendingAmount,
STAmount const& rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::uint64_t createCount,
AccountID const& toCreate);
[[nodiscard]] STObject
toSTObject() const;
@@ -231,17 +232,17 @@ struct CmpByCreateCount
// Result when checking when two attestation match.
enum class AttestationMatch {
// One of the fields doesn't match, and it isn't the dst field
nonDstMismatch,
NonDstMismatch,
// all of the fields match, except the dst field
matchExceptDst,
MatchExceptDst,
// all of the fields match
match
Match
};
struct XChainClaimAttestation
{
using TSignedAttestation = Attestations::AttestationClaim;
static SField const& ArrayFieldName;
static SField const& arrayFieldName;
AccountID keyAccount;
PublicKey publicKey;
@@ -256,35 +257,35 @@ struct XChainClaimAttestation
bool wasLockingChainSend;
std::optional<AccountID> dst;
MatchFields(TSignedAttestation const& att);
MatchFields(STAmount const& a, bool b, std::optional<AccountID> const& d)
: amount{a}, wasLockingChainSend{b}, dst{d}
MatchFields(STAmount a, bool b, std::optional<AccountID> const& d)
: amount{std::move(a)}, wasLockingChainSend{b}, dst{d}
{
}
};
explicit XChainClaimAttestation(
AccountID const& keyAccount_,
PublicKey const& publicKey_,
STAmount const& amount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_,
AccountID const& keyAccount,
PublicKey const& publicKey,
STAmount const& amount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
std::optional<AccountID> const& dst);
explicit XChainClaimAttestation(
STAccount const& keyAccount_,
PublicKey const& publicKey_,
STAmount const& amount_,
STAccount const& rewardAccount_,
bool wasLockingChainSend_,
STAccount const& keyAccount,
PublicKey const& publicKey,
STAmount const& amount,
STAccount const& rewardAccount,
bool wasLockingChainSend,
std::optional<STAccount> const& dst);
explicit XChainClaimAttestation(TSignedAttestation const& claimAtt);
explicit XChainClaimAttestation(STObject const& o);
explicit XChainClaimAttestation(Json::Value const& v);
explicit XChainClaimAttestation(json::Value const& v);
AttestationMatch
[[nodiscard]] AttestationMatch
match(MatchFields const& rhs) const;
[[nodiscard]] STObject
@@ -297,7 +298,7 @@ struct XChainClaimAttestation
struct XChainCreateAccountAttestation
{
using TSignedAttestation = Attestations::AttestationCreateAccount;
static SField const& ArrayFieldName;
static SField const& arrayFieldName;
AccountID keyAccount;
PublicKey publicKey;
@@ -318,24 +319,24 @@ struct XChainCreateAccountAttestation
};
explicit XChainCreateAccountAttestation(
AccountID const& keyAccount_,
PublicKey const& publicKey_,
STAmount const& amount_,
STAmount const& rewardAmount_,
AccountID const& rewardAccount_,
bool wasLockingChainSend_,
AccountID const& dst_);
AccountID const& keyAccount,
PublicKey const& publicKey,
STAmount const& amount,
STAmount const& rewardAmount,
AccountID const& rewardAccount,
bool wasLockingChainSend,
AccountID const& dst);
explicit XChainCreateAccountAttestation(TSignedAttestation const& claimAtt);
explicit XChainCreateAccountAttestation(STObject const& o);
explicit XChainCreateAccountAttestation(Json::Value const& v);
explicit XChainCreateAccountAttestation(json::Value const& v);
[[nodiscard]] STObject
toSTObject() const;
AttestationMatch
[[nodiscard]] AttestationMatch
match(MatchFields const& rhs) const;
friend bool
@@ -356,7 +357,7 @@ private:
// Set a max number of allowed attestations to limit the amount of memory
// allocated and processing time. This number is much larger than the actual
// number of attestation a server would ever expect.
static constexpr std::uint32_t maxAttestations = 256;
static constexpr std::uint32_t kMaxAttestations = 256;
AttCollection attestations_;
protected:
@@ -371,17 +372,17 @@ public:
explicit XChainAttestationsBase(AttCollection&& sigs);
explicit XChainAttestationsBase(Json::Value const& v);
explicit XChainAttestationsBase(json::Value const& v);
explicit XChainAttestationsBase(STArray const& arr);
[[nodiscard]] STArray
toSTArray() const;
typename AttCollection::const_iterator
[[nodiscard]] typename AttCollection::const_iterator
begin() const;
typename AttCollection::const_iterator
[[nodiscard]] typename AttCollection::const_iterator
end() const;
typename AttCollection::iterator
@@ -392,20 +393,20 @@ public:
template <class F>
std::size_t
erase_if(F&& f);
eraseIf(F&& f);
std::size_t
[[nodiscard]] std::size_t
size() const;
bool
[[nodiscard]] bool
empty() const;
AttCollection const&
[[nodiscard]] AttCollection const&
attestations() const;
template <class T>
void
emplace_back(T&& att);
emplaceBack(T&& att);
};
template <class TAttestation>
@@ -427,7 +428,7 @@ XChainAttestationsBase<TAttestation>::attestations() const
template <class TAttestation>
template <class T>
inline void
XChainAttestationsBase<TAttestation>::emplace_back(T&& att)
XChainAttestationsBase<TAttestation>::emplaceBack(T&& att)
{
attestations_.emplace_back(std::forward<T>(att));
};
@@ -435,7 +436,7 @@ XChainAttestationsBase<TAttestation>::emplace_back(T&& att)
template <class TAttestation>
template <class F>
inline std::size_t
XChainAttestationsBase<TAttestation>::erase_if(F&& f)
XChainAttestationsBase<TAttestation>::eraseIf(F&& f)
{
return std::erase_if(attestations_, std::forward<F>(f));
}

View File

@@ -146,24 +146,26 @@ public:
}
/** Return the sign of the amount */
constexpr int
[[nodiscard]] constexpr int
signum() const noexcept
{
return (drops_ < 0) ? -1 : (drops_ ? 1 : 0);
if (drops_ < 0)
return -1;
return (drops_ != 0) ? 1 : 0;
}
/** Returns the number of drops */
constexpr value_type
[[nodiscard]] constexpr value_type
drops() const
{
return drops_;
}
constexpr double
[[nodiscard]] constexpr double
decimalXRP() const;
template <class Dest>
std::optional<Dest>
[[nodiscard]] std::optional<Dest>
dropsAs() const
{
if ((drops_ > std::numeric_limits<Dest>::max()) ||
@@ -183,7 +185,7 @@ public:
}
template <class Dest>
Dest
[[nodiscard]] Dest
dropsAs(XRPAmount defaultValue) const
{
return dropsAs<Dest>().value_or(defaultValue.drops());
@@ -193,28 +195,28 @@ public:
* in contexts that don't expect the value to ever approach
* the 32-bit limits (i.e. fees and reserves).
*/
Json::Value
[[nodiscard]] json::Value
jsonClipped() const
{
static_assert(
std::is_signed_v<value_type> && std::is_integral_v<value_type>,
"Expected XRPAmount to be a signed integral type");
constexpr auto min = std::numeric_limits<Json::Int>::min();
constexpr auto max = std::numeric_limits<Json::Int>::max();
constexpr auto kMin = std::numeric_limits<json::Int>::min();
constexpr auto kMax = std::numeric_limits<json::Int>::max();
if (drops_ < min)
return min;
if (drops_ > max)
return max;
return static_cast<Json::Int>(drops_);
if (drops_ < kMin)
return kMin;
if (drops_ > kMax)
return kMax;
return static_cast<json::Int>(drops_);
}
/** Returns the underlying value. Code SHOULD NOT call this
function unless the type has been abstracted away,
e.g. in a templated function.
*/
constexpr value_type
[[nodiscard]] constexpr value_type
value() const
{
return drops_;
@@ -235,12 +237,12 @@ public:
};
/** Number of drops per 1 XRP */
constexpr XRPAmount DROPS_PER_XRP{1'000'000};
constexpr XRPAmount kDropsPerXrp{1'000'000};
constexpr double
XRPAmount::decimalXRP() const
{
return static_cast<double>(drops_) / DROPS_PER_XRP.drops();
return static_cast<double>(drops_) / kDropsPerXrp.drops();
}
// Output XRPAmount as just the drops value.
@@ -262,7 +264,7 @@ mulRatio(XRPAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
{
using namespace boost::multiprecision;
if (!den)
if (den == 0u)
Throw<std::runtime_error>("division by zero");
int128_t const amt128(amt.drops());

View File

@@ -7,34 +7,27 @@
#include <cstddef>
#include <type_traits>
namespace xrpl {
namespace detail {
namespace xrpl::detail {
struct defaultObject_t
struct DefaultObjectT
{
explicit defaultObject_t() = default;
explicit DefaultObjectT() = default;
};
struct nonPresentObject_t
struct NonPresentObjectT
{
explicit nonPresentObject_t() = default;
explicit NonPresentObjectT() = default;
};
extern defaultObject_t defaultObject;
extern nonPresentObject_t nonPresentObject;
extern DefaultObjectT gDefaultObject;
extern NonPresentObjectT gNonPresentObject;
// Concept to constrain STVar constructors, which
// instantiate ST* types from SerializedTypeID
// clang-format off
template <typename... Args>
concept ValidConstructSTArgs =
(std::is_same_v<
std::tuple<std::remove_cvref_t<Args>...>,
std::tuple<SField>> ||
std::is_same_v<
std::tuple<std::remove_cvref_t<Args>...>,
std::tuple<SerialIter, SField>>);
// clang-format on
(std::is_same_v<std::tuple<std::remove_cvref_t<Args>...>, std::tuple<SField>> ||
std::is_same_v<std::tuple<std::remove_cvref_t<Args>...>, std::tuple<SerialIter, SField>>);
// "variant" that can hold any type of serialized object
// and includes a small-object allocation optimization.
@@ -42,9 +35,9 @@ class STVar
{
private:
// The largest "small object" we can accommodate
static std::size_t constexpr max_size = 72;
static constexpr std::size_t kMaxSize = 72;
std::aligned_storage<max_size>::type d_ = {};
std::aligned_storage<kMaxSize>::type d_ = {};
STBase* p_ = nullptr;
public:
@@ -56,18 +49,18 @@ public:
STVar&
operator=(STVar&& rhs);
STVar(STBase&& t)
STVar(STBase&& t) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
{
p_ = t.move(max_size, &d_);
p_ = t.move(kMaxSize, &d_);
}
STVar(STBase const& t)
{
p_ = t.copy(max_size, &d_);
p_ = t.copy(kMaxSize, &d_);
}
STVar(defaultObject_t, SField const& name);
STVar(nonPresentObject_t, SField const& name);
STVar(DefaultObjectT, SField const& name);
STVar(NonPresentObjectT, SField const& name);
STVar(SerialIter& sit, SField const& name, int depth = 0);
STBase&
@@ -85,7 +78,7 @@ public:
{
return &get();
}
STBase const&
[[nodiscard]] STBase const&
get() const
{
return *p_;
@@ -103,7 +96,7 @@ public:
template <class T, class... Args>
friend STVar
make_stvar(Args&&... args);
makeStvar(Args&&... args);
private:
STVar() = default;
@@ -117,10 +110,14 @@ private:
void
construct(Args&&... args)
{
if constexpr (sizeof(T) > max_size)
if constexpr (sizeof(T) > kMaxSize)
{
p_ = new T(std::forward<Args>(args)...);
}
else
{
p_ = new (&d_) T(std::forward<Args>(args)...);
}
}
/** Construct requested Serializable Type according to id.
@@ -132,8 +129,8 @@ private:
void
constructST(SerializedTypeID id, int depth, Args&&... arg);
bool
on_heap() const
[[nodiscard]] bool
onHeap() const
{
return static_cast<void const*>(p_) != static_cast<void const*>(&d_);
}
@@ -141,7 +138,7 @@ private:
template <class T, class... Args>
inline STVar
make_stvar(Args&&... args)
makeStvar(Args&&... args)
{
STVar st;
st.construct<T>(std::forward<Args>(args)...);
@@ -160,5 +157,4 @@ operator!=(STVar const& lhs, STVar const& rhs)
return !(lhs == rhs);
}
} // namespace detail
} // namespace xrpl
} // namespace xrpl::detail

View File

@@ -17,28 +17,28 @@ template <class T>
using Result = boost::outcome_v2::result<T, std::error_code>;
#ifndef _MSC_VER
namespace b58_fast {
namespace detail {
namespace b58_fast::detail {
// This optimizes to what hand written asm would do (single divide)
[[nodiscard]] inline std::tuple<std::uint64_t, std::uint64_t>
div_rem(std::uint64_t a, std::uint64_t b)
divRem(std::uint64_t a, std::uint64_t b)
{
return {a / b, a % b};
}
// This optimizes to what hand written asm would do (single multiply)
[[nodiscard]] inline std::tuple<std::uint64_t, std::uint64_t>
carrying_mul(std::uint64_t a, std::uint64_t b, std::uint64_t carry)
carryingMul(std::uint64_t a, std::uint64_t b, std::uint64_t carry)
{
unsigned __int128 const x = a;
unsigned __int128 const y = b;
unsigned __int128 const c = x * y + carry;
unsigned __int128 const c = (x * y) + carry;
return {c & 0xffff'ffff'ffff'ffff, c >> 64};
}
[[nodiscard]] inline std::tuple<std::uint64_t, std::uint64_t>
carrying_add(std::uint64_t a, std::uint64_t b)
carryingAdd(std::uint64_t a, std::uint64_t b)
{
unsigned __int128 const x = a;
unsigned __int128 const y = b;
@@ -52,126 +52,126 @@ carrying_add(std::uint64_t a, std::uint64_t b)
// panics if overflows (this is a specialized adder for b58 decoding.
// it should never overflow).
[[nodiscard]] inline TokenCodecErrc
inplace_bigint_add(std::span<std::uint64_t> a, std::uint64_t b)
inplaceBigintAdd(std::span<std::uint64_t> a, std::uint64_t b)
{
if (a.size() <= 1)
{
return TokenCodecErrc::inputTooSmall;
}
std::uint64_t carry;
std::tie(a[0], carry) = carrying_add(a[0], b);
for (auto& v : a.subspan(1))
{
if (!carry)
{
return TokenCodecErrc::success;
}
std::tie(v, carry) = carrying_add(v, 1);
}
if (carry)
{
return TokenCodecErrc::overflowAdd;
}
return TokenCodecErrc::success;
}
[[nodiscard]] inline TokenCodecErrc
inplace_bigint_mul(std::span<std::uint64_t> a, std::uint64_t b)
{
if (a.empty())
{
return TokenCodecErrc::inputTooSmall;
}
auto const last_index = a.size() - 1;
if (a[last_index] != 0)
{
return TokenCodecErrc::inputTooLarge;
return TokenCodecErrc::InputTooSmall;
}
std::uint64_t carry = 0;
for (auto& coeff : a.subspan(0, last_index))
std::tie(a[0], carry) = carryingAdd(a[0], b);
for (auto& v : a.subspan(1))
{
std::tie(coeff, carry) = carrying_mul(coeff, b, carry);
if (carry == 0u)
{
return TokenCodecErrc::Success;
}
std::tie(v, carry) = carryingAdd(v, 1);
}
a[last_index] = carry;
return TokenCodecErrc::success;
if (carry != 0u)
{
return TokenCodecErrc::OverflowAdd;
}
return TokenCodecErrc::Success;
}
[[nodiscard]] inline TokenCodecErrc
inplaceBigintMul(std::span<std::uint64_t> a, std::uint64_t b)
{
if (a.empty())
{
return TokenCodecErrc::InputTooSmall;
}
auto const lastIndex = a.size() - 1;
if (a[lastIndex] != 0)
{
return TokenCodecErrc::InputTooLarge;
}
std::uint64_t carry = 0;
for (auto& coeff : a.subspan(0, lastIndex))
{
std::tie(coeff, carry) = carryingMul(coeff, b, carry);
}
a[lastIndex] = carry;
return TokenCodecErrc::Success;
}
// divide a "big uint" value inplace and return the mod
// numerator is stored so smallest coefficients come first
[[nodiscard]] inline std::uint64_t
inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
inplaceBigintDivRem(std::span<uint64_t> numerator, std::uint64_t divisor)
{
if (numerator.size() == 0)
if (numerator.empty())
{
// should never happen, but if it does then it seems natural to define
// the a null set of numbers to be zero, so the remainder is also zero.
// LCOV_EXCL_START
UNREACHABLE(
"xrpl::b58_fast::detail::inplace_bigint_div_rem : empty "
"xrpl::b58_fast::detail::inplaceBigintDivRem : empty "
"numerator");
return 0;
// LCOV_EXCL_STOP
}
auto to_u128 = [](std::uint64_t high, std::uint64_t low) -> unsigned __int128 {
auto toU128 = [](std::uint64_t high, std::uint64_t low) -> unsigned __int128 {
unsigned __int128 const high128 = high;
unsigned __int128 const low128 = low;
return ((high128 << 64) | low128);
};
auto div_rem_64 = [](unsigned __int128 num,
std::uint64_t denom) -> std::tuple<std::uint64_t, std::uint64_t> {
auto divRe64 = [](unsigned __int128 num,
std::uint64_t denom) -> std::tuple<std::uint64_t, std::uint64_t> {
unsigned __int128 const denom128 = denom;
unsigned __int128 const d = num / denom128;
unsigned __int128 const r = num - (denom128 * d);
XRPL_ASSERT(
d >> 64 == 0,
"xrpl::b58_fast::detail::inplace_bigint_div_rem::div_rem_64 : "
"xrpl::b58_fast::detail::inplaceBigintDivRem::divRe64 : "
"valid division result");
XRPL_ASSERT(
r >> 64 == 0,
"xrpl::b58_fast::detail::inplace_bigint_div_rem::div_rem_64 : "
"xrpl::b58_fast::detail::inplaceBigintDivRem::divRe64 : "
"valid remainder");
return {static_cast<std::uint64_t>(d), static_cast<std::uint64_t>(r)};
};
std::uint64_t prev_rem = 0;
int const last_index = numerator.size() - 1;
std::tie(numerator[last_index], prev_rem) = div_rem(numerator[last_index], divisor);
for (int i = last_index - 1; i >= 0; --i)
std::uint64_t prevRem = 0;
int const lastIndex = numerator.size() - 1;
std::tie(numerator[lastIndex], prevRem) = divRem(numerator[lastIndex], divisor);
for (int i = lastIndex - 1; i >= 0; --i)
{
unsigned __int128 const cur_num = to_u128(prev_rem, numerator[i]);
std::tie(numerator[i], prev_rem) = div_rem_64(cur_num, divisor);
unsigned __int128 const curNum = toU128(prevRem, numerator[i]);
std::tie(numerator[i], prevRem) = divRe64(curNum, divisor);
}
return prev_rem;
return prevRem;
}
// convert from base 58^10 to base 58
// put largest coeffs first
// the `_be` suffix stands for "big endian"
[[nodiscard]] inline std::array<std::uint8_t, 10>
b58_10_to_b58_be(std::uint64_t input)
b5810ToB58Be(std::uint64_t input)
{
[[maybe_unused]] static constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
XRPL_ASSERT(input < B_58_10, "xrpl::b58_fast::detail::b58_10_to_b58_be : valid input");
constexpr std::size_t resultSize = 10;
std::array<std::uint8_t, resultSize> result{};
[[maybe_unused]] static constexpr std::uint64_t kB5810 = 430804206899405824; // 58^10;
XRPL_ASSERT(input < kB5810, "xrpl::b58_fast::detail::b5810ToB58Be : valid input");
static constexpr std::size_t kResultSize = 10;
std::array<std::uint8_t, kResultSize> result{};
int i = 0;
while (input > 0)
{
std::uint64_t rem;
std::tie(input, rem) = div_rem(input, 58);
result[resultSize - 1 - i] = rem;
std::uint64_t rem = 0;
std::tie(input, rem) = divRem(input, 58);
result[kResultSize - 1 - i] = rem;
i += 1;
}
return result;
}
} // namespace detail
} // namespace b58_fast
} // namespace b58_fast::detail
#endif
} // namespace xrpl

View File

@@ -11,67 +11,63 @@
#error "undefined macro: XRPL_RETIRE_FIX"
#endif
// clang-format off
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FIX (Security3_1_3, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocolV1_1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PermissionedDomainInvariant, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (DirectoryLimit, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (IncludeKeyletFields, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PriceOracleOrder, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (MPTDeliveredAmount, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_2_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(LendingProtocolV1_1, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (BatchInnerSigs, Supported::No, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegationV1_1, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (DirectoryLimit, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (IncludeKeyletFields, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicMPT, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (TokenEscrowV1, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (PriceOracleOrder, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (MPTDeliveredAmount, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMClawbackRounding, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(TokenEscrow, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_3, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionedDEX, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::No, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::Yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (FrozenLPTokenTransfer, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DeepFreeze, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionedDomains, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicNFT, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Credentials, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMMClawback, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV1, Supported::yes, VoteBehavior::DefaultNo)
// InvariantsV1_1 will be changes to Supported::yes when all the
// invariants expected to be included under it are complete.
XRPL_FEATURE(InvariantsV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (NFTokenPageLinks, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (InnerObjTemplate2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustline, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (ReducedOffersV2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(NFTokenMintOffer, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PreviousTxnID, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (XChainRewardRounding, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (EmptyDID, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PriceOracle, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMOverflowOffer, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (InnerObjTemplate, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (NFTokenReserve, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (FillOrKill, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DID, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XChainBridge, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Clawback, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (UniversalNumber, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (InvalidTxFlags, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (FrozenLPTokenTransfer, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DeepFreeze, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionedDomains, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicNFT, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Credentials, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMMClawback, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_2, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV1, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (NFTokenPageLinks, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (InnerObjTemplate2, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustline, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (ReducedOffersV2, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(NFTokenMintOffer, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_1, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (PreviousTxnID, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (XChainRewardRounding, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (EmptyDID, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PriceOracle, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMOverflowOffer, Supported::Yes, VoteBehavior::DefaultYes)
XRPL_FIX (InnerObjTemplate, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (NFTokenReserve, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (FillOrKill, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DID, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (DisallowIncomingV1, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XChainBridge, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMM, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Clawback, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (UniversalNumber, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XRPFees, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::Yes, VoteBehavior::DefaultYes)
// The following amendments are obsolete, but must remain supported
// because they could potentially get enabled.
@@ -145,5 +141,3 @@ XRPL_RETIRE_FEATURE(SortedDirectories)
XRPL_RETIRE_FEATURE(TicketBatch)
XRPL_RETIRE_FEATURE(TickSize)
XRPL_RETIRE_FEATURE(TrustSetAuth)
// clang-format on

View File

@@ -24,15 +24,15 @@
\sa keylet::nftoffer
*/
LEDGER_ENTRY(ltNFTOKEN_OFFER, 0x0037, NFTokenOffer, nft_offer, ({
{sfOwner, soeREQUIRED},
{sfNFTokenID, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfNFTokenOfferNode, soeREQUIRED},
{sfDestination, soeOPTIONAL},
{sfExpiration, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwner, SoeRequired},
{sfNFTokenID, SoeRequired},
{sfAmount, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfNFTokenOfferNode, SoeRequired},
{sfDestination, SoeOptional},
{sfExpiration, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which describes a check.
@@ -40,18 +40,18 @@ LEDGER_ENTRY(ltNFTOKEN_OFFER, 0x0037, NFTokenOffer, nft_offer, ({
\sa keylet::check
*/
LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, ({
{sfAccount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfSendMax, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfDestinationNode, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfInvoiceID, soeOPTIONAL},
{sfSourceTag, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfDestination, SoeRequired},
{sfSendMax, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfDestinationNode, SoeRequired},
{sfExpiration, SoeOptional},
{sfInvoiceID, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** The ledger object which tracks the DID.
@@ -59,13 +59,13 @@ LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, ({
\sa keylet::did
*/
LEDGER_ENTRY(ltDID, 0x0049, DID, did, ({
{sfAccount, soeREQUIRED},
{sfDIDDocument, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfData, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfDIDDocument, SoeOptional},
{sfURI, SoeOptional},
{sfData, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** The ledger object which tracks the current negative UNL state.
@@ -75,51 +75,51 @@ LEDGER_ENTRY(ltDID, 0x0049, DID, did, ({
\sa keylet::negativeUNL
*/
LEDGER_ENTRY(ltNEGATIVE_UNL, 0x004e, NegativeUNL, nunl, ({
{sfDisabledValidators, soeOPTIONAL},
{sfValidatorToDisable, soeOPTIONAL},
{sfValidatorToReEnable, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfDisabledValidators, SoeOptional},
{sfValidatorToDisable, SoeOptional},
{sfValidatorToReEnable, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
}))
/** A ledger object which contains a list of NFTs
\sa keylet::nftpage_min, keylet::nftpage_max, keylet::nftpage
\sa keylet::nftpageMin, keylet::nftpageMax, keylet::nftpage
*/
LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
{sfPreviousPageMin, soeOPTIONAL},
{sfNextPageMin, soeOPTIONAL},
{sfNFTokens, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfPreviousPageMin, SoeOptional},
{sfNextPageMin, SoeOptional},
{sfNFTokens, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which contains a signer list for an account.
\sa keylet::signers
*/
// All fields are soeREQUIRED because there is always a SignerEntries.
// All fields are SoeRequired because there is always a SignerEntries.
// If there are no SignerEntries the node is deleted.
LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, ({
{sfOwner, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfSignerQuorum, soeREQUIRED},
{sfSignerEntries, soeREQUIRED},
{sfSignerListID, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwner, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfSignerQuorum, SoeRequired},
{sfSignerEntries, SoeRequired},
{sfSignerListID, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which describes a ticket.
\sa keylet::ticket
\sa keylet::kTicket
*/
LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, ({
{sfAccount, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfTicketSequence, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfTicketSequence, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which describes an account.
@@ -127,29 +127,29 @@ LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, ({
\sa keylet::account
*/
LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfAccount, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfBalance, soeREQUIRED},
{sfOwnerCount, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccountTxnID, soeOPTIONAL},
{sfRegularKey, soeOPTIONAL},
{sfEmailHash, soeOPTIONAL},
{sfWalletLocator, soeOPTIONAL},
{sfWalletSize, soeOPTIONAL},
{sfMessageKey, soeOPTIONAL},
{sfTransferRate, soeOPTIONAL},
{sfDomain, soeOPTIONAL},
{sfTickSize, soeOPTIONAL},
{sfTicketCount, soeOPTIONAL},
{sfNFTokenMinter, soeOPTIONAL},
{sfMintedNFTokens, soeDEFAULT},
{sfBurnedNFTokens, soeDEFAULT},
{sfFirstNFTokenSequence, soeOPTIONAL},
{sfAMMID, soeOPTIONAL}, // pseudo-account designator
{sfVaultID, soeOPTIONAL}, // pseudo-account designator
{sfLoanBrokerID, soeOPTIONAL}, // pseudo-account designator
{sfAccount, SoeRequired},
{sfSequence, SoeRequired},
{sfBalance, SoeRequired},
{sfOwnerCount, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAccountTxnID, SoeOptional},
{sfRegularKey, SoeOptional},
{sfEmailHash, SoeOptional},
{sfWalletLocator, SoeOptional},
{sfWalletSize, SoeOptional},
{sfMessageKey, SoeOptional},
{sfTransferRate, SoeOptional},
{sfDomain, SoeOptional},
{sfTickSize, SoeOptional},
{sfTicketCount, SoeOptional},
{sfNFTokenMinter, SoeOptional},
{sfMintedNFTokens, SoeDefault},
{sfBurnedNFTokens, SoeDefault},
{sfFirstNFTokenSequence, SoeOptional},
{sfAMMID, SoeOptional}, // pseudo-account designator
{sfVaultID, SoeOptional}, // pseudo-account designator
{sfLoanBrokerID, SoeOptional}, // pseudo-account designator
}))
/** A ledger object which contains a list of object identifiers.
@@ -158,20 +158,22 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
keylet::ownerDir
*/
LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
{sfOwner, soeOPTIONAL}, // for owner directories
{sfTakerPaysCurrency, soeOPTIONAL}, // order book directories
{sfTakerPaysIssuer, soeOPTIONAL}, // order book directories
{sfTakerGetsCurrency, soeOPTIONAL}, // order book directories
{sfTakerGetsIssuer, soeOPTIONAL}, // order book directories
{sfExchangeRate, soeOPTIONAL}, // order book directories
{sfIndexes, soeREQUIRED},
{sfRootIndex, soeREQUIRED},
{sfIndexNext, soeOPTIONAL},
{sfIndexPrevious, soeOPTIONAL},
{sfNFTokenID, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfDomainID, soeOPTIONAL} // order book directories
{sfOwner, SoeOptional}, // for owner directories
{sfTakerPaysCurrency, SoeOptional}, // order book directories
{sfTakerPaysIssuer, SoeOptional}, // order book directories
{sfTakerPaysMPT, SoeOptional}, // order book directories
{sfTakerGetsCurrency, SoeOptional}, // order book directories
{sfTakerGetsIssuer, SoeOptional}, // order book directories
{sfTakerGetsMPT, SoeOptional}, // order book directories
{sfExchangeRate, SoeOptional}, // order book directories
{sfIndexes, SoeRequired},
{sfRootIndex, SoeRequired},
{sfIndexNext, SoeOptional},
{sfIndexPrevious, SoeOptional},
{sfNFTokenID, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
{sfDomainID, SoeOptional} // order book directories
}))
/** The ledger object which lists details about amendments on the network.
@@ -181,10 +183,10 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
\sa keylet::amendments
*/
LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, ({
{sfAmendments, soeOPTIONAL}, // Enabled
{sfMajorities, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfAmendments, SoeOptional}, // Enabled
{sfMajorities, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
}))
/** A ledger object that contains a list of ledger hashes.
@@ -196,9 +198,9 @@ LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, ({
\sa keylet::skip
*/
LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, ({
{sfFirstLedgerSequence, soeOPTIONAL},
{sfLastLedgerSequence, soeOPTIONAL},
{sfHashes, soeREQUIRED},
{sfFirstLedgerSequence, SoeOptional},
{sfLastLedgerSequence, SoeOptional},
{sfHashes, SoeRequired},
}))
/** The ledger object which lists details about sidechains.
@@ -206,16 +208,16 @@ LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, ({
\sa keylet::bridge
*/
LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, ({
{sfAccount, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfMinAccountCreateAmount, soeOPTIONAL},
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfXChainAccountCreateCount, soeREQUIRED},
{sfXChainAccountClaimCount, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfSignatureReward, SoeRequired},
{sfMinAccountCreateAmount, SoeOptional},
{sfXChainBridge, SoeRequired},
{sfXChainClaimID, SoeRequired},
{sfXChainAccountCreateCount, SoeRequired},
{sfXChainAccountClaimCount, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which describes an offer on the DEX.
@@ -223,18 +225,18 @@ LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, ({
\sa keylet::offer
*/
LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, ({
{sfAccount, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfTakerPays, soeREQUIRED},
{sfTakerGets, soeREQUIRED},
{sfBookDirectory, soeREQUIRED},
{sfBookNode, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfDomainID, soeOPTIONAL},
{sfAdditionalBooks, soeOPTIONAL},
{sfAccount, SoeRequired},
{sfSequence, SoeRequired},
{sfTakerPays, SoeRequired},
{sfTakerGets, SoeRequired},
{sfBookDirectory, SoeRequired},
{sfBookNode, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfExpiration, SoeOptional},
{sfDomainID, SoeOptional},
{sfAdditionalBooks, SoeOptional},
}))
/** A ledger object which describes a deposit pre-authorization.
@@ -242,12 +244,12 @@ LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, ({
\sa keylet::depositPreauth
*/
LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preauth, ({
{sfAccount, soeREQUIRED},
{sfAuthorize, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAuthorizeCredentials, soeOPTIONAL},
{sfAccount, SoeRequired},
{sfAuthorize, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfAuthorizeCredentials, SoeOptional},
}))
/** A claim id for a cross chain transaction.
@@ -255,15 +257,15 @@ LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preaut
\sa keylet::xChainClaimID
*/
LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_claim_id, ({
{sfAccount, soeREQUIRED},
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfOtherChainSource, soeREQUIRED},
{sfXChainClaimAttestations, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfXChainBridge, SoeRequired},
{sfXChainClaimID, SoeRequired},
{sfOtherChainSource, SoeRequired},
{sfXChainClaimAttestations, SoeRequired},
{sfSignatureReward, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which describes a bidirectional trust line.
@@ -273,17 +275,17 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_c
\sa keylet::line
*/
LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
{sfBalance, soeREQUIRED},
{sfLowLimit, soeREQUIRED},
{sfHighLimit, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfLowNode, soeOPTIONAL},
{sfLowQualityIn, soeOPTIONAL},
{sfLowQualityOut, soeOPTIONAL},
{sfHighNode, soeOPTIONAL},
{sfHighQualityIn, soeOPTIONAL},
{sfHighQualityOut, soeOPTIONAL},
{sfBalance, SoeRequired},
{sfLowLimit, SoeRequired},
{sfHighLimit, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfLowNode, SoeOptional},
{sfLowQualityIn, SoeOptional},
{sfLowQualityOut, SoeOptional},
{sfHighNode, SoeOptional},
{sfHighQualityIn, SoeOptional},
{sfHighQualityOut, SoeOptional},
}))
/** The ledger object which lists the network's fee settings.
@@ -294,16 +296,16 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
*/
LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
// Old version uses raw numbers
{sfBaseFee, soeOPTIONAL},
{sfReferenceFeeUnits, soeOPTIONAL},
{sfReserveBase, soeOPTIONAL},
{sfReserveIncrement, soeOPTIONAL},
{sfBaseFee, SoeOptional},
{sfReferenceFeeUnits, SoeOptional},
{sfReserveBase, SoeOptional},
{sfReserveIncrement, SoeOptional},
// New version uses Amounts
{sfBaseFeeDrops, soeOPTIONAL},
{sfReserveBaseDrops, soeOPTIONAL},
{sfReserveIncrementDrops, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
}))
/** A claim id for a cross chain create account transaction.
@@ -311,13 +313,13 @@ LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
\sa keylet::xChainCreateAccountClaimID
*/
LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAccountClaimID, xchain_owned_create_account_claim_id, ({
{sfAccount, soeREQUIRED},
{sfXChainBridge, soeREQUIRED},
{sfXChainAccountCreateCount, soeREQUIRED},
{sfXChainCreateAccountAttestations, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfXChainBridge, SoeRequired},
{sfXChainAccountCreateCount, SoeRequired},
{sfXChainCreateAccountAttestations, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object describing a single escrow.
@@ -325,21 +327,21 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAc
\sa keylet::escrow
*/
LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfAccount, soeREQUIRED},
{sfSequence, soeOPTIONAL},
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfCondition, soeOPTIONAL},
{sfCancelAfter, soeOPTIONAL},
{sfFinishAfter, soeOPTIONAL},
{sfSourceTag, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDestinationNode, soeOPTIONAL},
{sfTransferRate, soeOPTIONAL},
{sfIssuerNode, soeOPTIONAL},
{sfAccount, SoeRequired},
{sfSequence, SoeOptional},
{sfDestination, SoeRequired},
{sfAmount, SoeRequired},
{sfCondition, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfFinishAfter, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfDestinationNode, SoeOptional},
{sfTransferRate, SoeOptional},
{sfIssuerNode, SoeOptional},
}))
/** A ledger object describing a single unidirectional XRP payment channel.
@@ -347,21 +349,21 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
\sa keylet::payChan
*/
LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
{sfAccount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfSequence, soeOPTIONAL},
{sfAmount, soeREQUIRED},
{sfBalance, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
{sfSettleDelay, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfCancelAfter, soeOPTIONAL},
{sfSourceTag, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDestinationNode, soeOPTIONAL},
{sfAccount, SoeRequired},
{sfDestination, SoeRequired},
{sfSequence, SoeOptional},
{sfAmount, SoeRequired},
{sfBalance, SoeRequired},
{sfPublicKey, SoeRequired},
{sfSettleDelay, SoeRequired},
{sfExpiration, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfDestinationNode, SoeOptional},
}))
/** The ledger object which tracks the AMM.
@@ -369,124 +371,126 @@ LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
\sa keylet::amm
*/
LEDGER_ENTRY(ltAMM, 0x0079, AMM, amm, ({
{sfAccount, soeREQUIRED},
{sfTradingFee, soeDEFAULT},
{sfVoteSlots, soeOPTIONAL},
{sfAuctionSlot, soeOPTIONAL},
{sfLPTokenBalance, soeREQUIRED},
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfAccount, SoeRequired},
{sfTradingFee, SoeDefault},
{sfVoteSlots, SoeOptional},
{sfAuctionSlot, SoeOptional},
{sfLPTokenBalance, SoeRequired},
{sfAsset, SoeRequired},
{sfAsset2, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
}))
/** A ledger object which tracks MPTokenIssuance
\sa keylet::mptIssuance
*/
LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
{sfIssuer, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfTransferFee, soeDEFAULT},
{sfOwnerNode, soeREQUIRED},
{sfAssetScale, soeDEFAULT},
{sfMaximumAmount, soeOPTIONAL},
{sfOutstandingAmount, soeREQUIRED},
{sfLockedAmount, soeOPTIONAL},
{sfMPTokenMetadata, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDomainID, soeOPTIONAL},
{sfMutableFlags, soeDEFAULT},
{sfIssuer, SoeRequired},
{sfSequence, SoeRequired},
{sfTransferFee, SoeDefault},
{sfOwnerNode, SoeRequired},
{sfAssetScale, SoeDefault},
{sfMaximumAmount, SoeOptional},
{sfOutstandingAmount, SoeRequired},
{sfLockedAmount, SoeOptional},
{sfMPTokenMetadata, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfDomainID, SoeOptional},
{sfMutableFlags, SoeDefault},
{sfReferenceHolding, SoeOptional},
}))
/** A ledger object which tracks MPToken
\sa keylet::mptoken
*/
LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
{sfAccount, soeREQUIRED},
{sfMPTokenIssuanceID, soeREQUIRED},
{sfMPTAmount, soeDEFAULT},
{sfLockedAmount, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfMPTokenIssuanceID, SoeRequired},
{sfMPTAmount, SoeDefault},
{sfLockedAmount, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which tracks Oracle
\sa keylet::oracle
*/
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
{sfOwner, soeREQUIRED},
{sfOracleDocumentID, soeOPTIONAL},
{sfProvider, soeREQUIRED},
{sfPriceDataSeries, soeREQUIRED},
{sfAssetClass, soeREQUIRED},
{sfLastUpdateTime, soeREQUIRED},
{sfURI, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwner, SoeRequired},
{sfOracleDocumentID, SoeOptional},
{sfProvider, SoeRequired},
{sfPriceDataSeries, SoeRequired},
{sfAssetClass, SoeRequired},
{sfLastUpdateTime, SoeRequired},
{sfURI, SoeOptional},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which tracks Credential
\sa keylet::credential
*/
LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, ({
{sfSubject, soeREQUIRED},
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfIssuerNode, soeREQUIRED},
{sfSubjectNode, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSubject, SoeRequired},
{sfIssuer, SoeRequired},
{sfCredentialType, SoeRequired},
{sfExpiration, SoeOptional},
{sfURI, SoeOptional},
{sfIssuerNode, SoeRequired},
{sfSubjectNode, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object which tracks PermissionedDomain
\sa keylet::permissionedDomain
*/
LEDGER_ENTRY(ltPERMISSIONED_DOMAIN, 0x0082, PermissionedDomain, permissioned_domain, ({
{sfOwner, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfAcceptedCredentials, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwner, SoeRequired},
{sfSequence, SoeRequired},
{sfAcceptedCredentials, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object representing permissions an account has delegated to another account.
\sa keylet::delegate
*/
LEDGER_ENTRY(ltDELEGATE, 0x0083, Delegate, delegate, ({
{sfAccount, soeREQUIRED},
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccount, SoeRequired},
{sfAuthorize, SoeRequired},
{sfPermissions, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfDestinationNode, SoeOptional},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
}))
/** A ledger object representing a single asset vault.
\sa keylet::vault
*/
LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfOwner, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfData, soeOPTIONAL},
{sfAsset, soeREQUIRED},
{sfAssetsTotal, soeDEFAULT},
{sfAssetsAvailable, soeDEFAULT},
{sfAssetsMaximum, soeDEFAULT},
{sfLossUnrealized, soeDEFAULT},
{sfShareMPTID, soeREQUIRED},
{sfWithdrawalPolicy, soeREQUIRED},
{sfScale, soeDEFAULT},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfOwner, SoeRequired},
{sfAccount, SoeRequired},
{sfData, SoeOptional},
{sfAsset, SoeRequired},
{sfAssetsTotal, SoeDefault},
{sfAssetsAvailable, SoeDefault},
{sfAssetsMaximum, SoeDefault},
{sfLossUnrealized, SoeDefault},
{sfShareMPTID, SoeRequired},
{sfWithdrawalPolicy, SoeRequired},
{sfScale, SoeDefault},
// no SharesTotal ever (use MPTIssuance.sfOutstandingAmount)
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))
@@ -498,23 +502,23 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
\sa keylet::loanbroker
*/
LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfVaultNode, soeREQUIRED},
{sfVaultID, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfOwner, soeREQUIRED},
{sfLoanSequence, soeREQUIRED},
{sfData, soeDEFAULT},
{sfManagementFeeRate, soeDEFAULT},
{sfOwnerCount, soeDEFAULT},
{sfDebtTotal, soeDEFAULT},
{sfDebtMaximum, soeDEFAULT},
{sfCoverAvailable, soeDEFAULT},
{sfCoverRateMinimum, soeDEFAULT},
{sfCoverRateLiquidation, soeDEFAULT},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfSequence, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfVaultNode, SoeRequired},
{sfVaultID, SoeRequired},
{sfAccount, SoeRequired},
{sfOwner, SoeRequired},
{sfLoanSequence, SoeRequired},
{sfData, SoeDefault},
{sfManagementFeeRate, SoeDefault},
{sfOwnerCount, SoeDefault},
{sfDebtTotal, SoeDefault},
{sfDebtMaximum, SoeDefault},
{sfCoverAvailable, SoeDefault},
{sfCoverRateMinimum, SoeDefault},
{sfCoverRateLiquidation, SoeDefault},
}))
/** A ledger object representing a loan between a Borrower and a Loan Broker
@@ -522,27 +526,27 @@ LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
\sa keylet::loan
*/
LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfLoanBrokerNode, soeREQUIRED},
{sfLoanBrokerID, soeREQUIRED},
{sfLoanSequence, soeREQUIRED},
{sfBorrower, soeREQUIRED},
{sfLoanOriginationFee, soeDEFAULT},
{sfLoanServiceFee, soeDEFAULT},
{sfLatePaymentFee, soeDEFAULT},
{sfClosePaymentFee, soeDEFAULT},
{sfOverpaymentFee, soeDEFAULT},
{sfInterestRate, soeDEFAULT},
{sfLateInterestRate, soeDEFAULT},
{sfCloseInterestRate, soeDEFAULT},
{sfOverpaymentInterestRate, soeDEFAULT},
{sfStartDate, soeREQUIRED},
{sfPaymentInterval, soeREQUIRED},
{sfGracePeriod, soeDEFAULT},
{sfPreviousPaymentDueDate, soeDEFAULT},
{sfNextPaymentDueDate, soeDEFAULT},
{sfPreviousTxnID, SoeRequired},
{sfPreviousTxnLgrSeq, SoeRequired},
{sfOwnerNode, SoeRequired},
{sfLoanBrokerNode, SoeRequired},
{sfLoanBrokerID, SoeRequired},
{sfLoanSequence, SoeRequired},
{sfBorrower, SoeRequired},
{sfLoanOriginationFee, SoeDefault},
{sfLoanServiceFee, SoeDefault},
{sfLatePaymentFee, SoeDefault},
{sfClosePaymentFee, SoeDefault},
{sfOverpaymentFee, SoeDefault},
{sfInterestRate, SoeDefault},
{sfLateInterestRate, SoeDefault},
{sfCloseInterestRate, SoeDefault},
{sfOverpaymentInterestRate, SoeDefault},
{sfStartDate, SoeRequired},
{sfPaymentInterval, SoeRequired},
{sfGracePeriod, SoeDefault},
{sfPreviousPaymentDueDate, SoeDefault},
{sfNextPaymentDueDate, SoeDefault},
// The loan object tracks these values:
//
// - PaymentRemaining: The number of payments left in the loan. When it
@@ -578,7 +582,7 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
// The unrounded true total value of the loan.
//
// - TrueTotalPrincipalOutstanding can be computed using the algorithm
// in the ripple::detail::loanPrincipalFromPeriodicPayment function.
// in the xrpl::detail::loanPrincipalFromPeriodicPayment function.
//
// - TrueTotalInterestOutstanding = TrueTotalLoanValue -
// TrueTotalPrincipalOutstanding
@@ -588,19 +592,19 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
// LoanBroker.ManagementFeeRate
// The unrounded true total fee still owed to the broker.
//
// Note the the "True" values may differ significantly from the tracked
// Note the "True" values may differ significantly from the tracked
// rounded values.
{sfPaymentRemaining, soeDEFAULT},
{sfPeriodicPayment, soeREQUIRED},
{sfPrincipalOutstanding, soeDEFAULT},
{sfTotalValueOutstanding, soeDEFAULT},
{sfManagementFeeOutstanding, soeDEFAULT},
{sfPaymentRemaining, SoeDefault},
{sfPeriodicPayment, SoeRequired},
{sfPrincipalOutstanding, SoeDefault},
{sfTotalValueOutstanding, SoeDefault},
{sfManagementFeeOutstanding, SoeDefault},
// Based on the computed total value at creation, used for
// rounding calculated values so they are all on a
// consistent scale - that is, they all have the same
// number of digits after the decimal point (excluding
// trailing zeros).
{sfLoanScale, soeDEFAULT},
{sfLoanScale, SoeDefault},
}))
#undef EXPAND

View File

@@ -8,20 +8,20 @@ template <class = void>
secp256k1_context const*
secp256k1Context()
{
struct holder
struct Holder
{
secp256k1_context* impl;
holder() : impl(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN))
Holder() : impl(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN))
{
}
~holder()
~Holder()
{
secp256k1_context_destroy(impl);
}
};
static holder const h;
return h.impl;
static Holder const kH;
return kH.impl;
}
} // namespace xrpl

View File

@@ -5,7 +5,6 @@
#error "undefined macro: TYPED_SFIELD"
#endif
// clang-format off
// untyped
UNTYPED_SFIELD(sfLedgerEntry, LEDGERENTRY, 257)
@@ -28,7 +27,7 @@ TYPED_SFIELD(sfWasLockingChainSend, UINT8, 19)
TYPED_SFIELD(sfWithdrawalPolicy, UINT8, 20)
// 16-bit integers (common)
TYPED_SFIELD(sfLedgerEntryType, UINT16, 1, SField::sMD_Never)
TYPED_SFIELD(sfLedgerEntryType, UINT16, 1, SField::kSmdNever)
TYPED_SFIELD(sfTransactionType, UINT16, 2)
TYPED_SFIELD(sfSignerWeight, UINT16, 3)
TYPED_SFIELD(sfTransferFee, UINT16, 4)
@@ -49,7 +48,7 @@ TYPED_SFIELD(sfNetworkID, UINT32, 1)
TYPED_SFIELD(sfFlags, UINT32, 2)
TYPED_SFIELD(sfSourceTag, UINT32, 3)
TYPED_SFIELD(sfSequence, UINT32, 4)
TYPED_SFIELD(sfPreviousTxnLgrSeq, UINT32, 5, SField::sMD_DeleteFinal)
TYPED_SFIELD(sfPreviousTxnLgrSeq, UINT32, 5, SField::kSmdDeleteFinal)
TYPED_SFIELD(sfLedgerSequence, UINT32, 6)
TYPED_SFIELD(sfCloseTime, UINT32, 7)
TYPED_SFIELD(sfParentCloseTime, UINT32, 8)
@@ -139,12 +138,12 @@ TYPED_SFIELD(sfXChainClaimID, UINT64, 20)
TYPED_SFIELD(sfXChainAccountCreateCount, UINT64, 21)
TYPED_SFIELD(sfXChainAccountClaimCount, UINT64, 22)
TYPED_SFIELD(sfAssetPrice, UINT64, 23)
TYPED_SFIELD(sfMaximumAmount, UINT64, 24, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfOutstandingAmount, UINT64, 25, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfMaximumAmount, UINT64, 24, SField::kSmdBaseTen|SField::kSmdDefault)
TYPED_SFIELD(sfOutstandingAmount, UINT64, 25, SField::kSmdBaseTen|SField::kSmdDefault)
TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::kSmdBaseTen|SField::kSmdDefault)
TYPED_SFIELD(sfIssuerNode, UINT64, 27)
TYPED_SFIELD(sfSubjectNode, UINT64, 28)
TYPED_SFIELD(sfLockedAmount, UINT64, 29, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfLockedAmount, UINT64, 29, SField::kSmdBaseTen|SField::kSmdDefault)
TYPED_SFIELD(sfVaultNode, UINT64, 30)
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 31)
@@ -160,23 +159,25 @@ TYPED_SFIELD(sfTakerGetsIssuer, UINT160, 4)
// 192-bit (common)
TYPED_SFIELD(sfMPTokenIssuanceID, UINT192, 1)
TYPED_SFIELD(sfShareMPTID, UINT192, 2)
TYPED_SFIELD(sfTakerPaysMPT, UINT192, 3)
TYPED_SFIELD(sfTakerGetsMPT, UINT192, 4)
// 256-bit (common)
TYPED_SFIELD(sfLedgerHash, UINT256, 1)
TYPED_SFIELD(sfParentHash, UINT256, 2)
TYPED_SFIELD(sfTransactionHash, UINT256, 3)
TYPED_SFIELD(sfAccountHash, UINT256, 4)
TYPED_SFIELD(sfPreviousTxnID, UINT256, 5, SField::sMD_DeleteFinal)
TYPED_SFIELD(sfPreviousTxnID, UINT256, 5, SField::kSmdDeleteFinal)
TYPED_SFIELD(sfLedgerIndex, UINT256, 6)
TYPED_SFIELD(sfWalletLocator, UINT256, 7)
TYPED_SFIELD(sfRootIndex, UINT256, 8, SField::sMD_Always)
TYPED_SFIELD(sfRootIndex, UINT256, 8, SField::kSmdAlways)
TYPED_SFIELD(sfAccountTxnID, UINT256, 9)
TYPED_SFIELD(sfNFTokenID, UINT256, 10)
TYPED_SFIELD(sfEmitParentTxnID, UINT256, 11)
TYPED_SFIELD(sfEmitNonce, UINT256, 12)
TYPED_SFIELD(sfEmitHookHash, UINT256, 13)
TYPED_SFIELD(sfAMMID, UINT256, 14,
SField::sMD_PseudoAccount | SField::sMD_Default)
SField::kSmdPseudoAccount | SField::kSmdDefault)
// 256-bit (uncommon)
TYPED_SFIELD(sfBookDirectory, UINT256, 16)
@@ -199,30 +200,31 @@ TYPED_SFIELD(sfHookNamespace, UINT256, 32)
TYPED_SFIELD(sfHookSetTxnID, UINT256, 33)
TYPED_SFIELD(sfDomainID, UINT256, 34)
TYPED_SFIELD(sfVaultID, UINT256, 35,
SField::sMD_PseudoAccount | SField::sMD_Default)
SField::kSmdPseudoAccount | SField::kSmdDefault)
TYPED_SFIELD(sfParentBatchID, UINT256, 36)
TYPED_SFIELD(sfLoanBrokerID, UINT256, 37,
SField::sMD_PseudoAccount | SField::sMD_Default)
SField::kSmdPseudoAccount | SField::kSmdDefault)
TYPED_SFIELD(sfLoanID, UINT256, 38)
TYPED_SFIELD(sfReferenceHolding, UINT256, 39)
// number (common)
TYPED_SFIELD(sfNumber, NUMBER, 1)
TYPED_SFIELD(sfAssetsAvailable, NUMBER, 2, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfDebtTotal, NUMBER, 6, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfDebtMaximum, NUMBER, 7, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfCoverAvailable, NUMBER, 8, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfAssetsAvailable, NUMBER, 2, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfDebtTotal, NUMBER, 6, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfDebtMaximum, NUMBER, 7, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfCoverAvailable, NUMBER, 8, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfLoanOriginationFee, NUMBER, 9)
TYPED_SFIELD(sfLoanServiceFee, NUMBER, 10)
TYPED_SFIELD(sfLatePaymentFee, NUMBER, 11)
TYPED_SFIELD(sfClosePaymentFee, NUMBER, 12)
TYPED_SFIELD(sfPrincipalOutstanding, NUMBER, 13, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfPrincipalOutstanding, NUMBER, 13, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfPrincipalRequested, NUMBER, 14)
TYPED_SFIELD(sfTotalValueOutstanding, NUMBER, 15, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfTotalValueOutstanding, NUMBER, 15, SField::kSmdNeedsAsset | SField::kSmdDefault)
TYPED_SFIELD(sfPeriodicPayment, NUMBER, 16)
TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17, SField::kSmdNeedsAsset | SField::kSmdDefault)
// int32
TYPED_SFIELD(sfLoanScale, INT32, 1)
@@ -268,9 +270,9 @@ TYPED_SFIELD(sfLPTokenBalance, AMOUNT, 31)
TYPED_SFIELD(sfPublicKey, VL, 1)
TYPED_SFIELD(sfMessageKey, VL, 2)
TYPED_SFIELD(sfSigningPubKey, VL, 3)
TYPED_SFIELD(sfTxnSignature, VL, 4, SField::sMD_Default, SField::notSigning)
TYPED_SFIELD(sfTxnSignature, VL, 4, SField::kSmdDefault, SField::kNotSigning)
TYPED_SFIELD(sfURI, VL, 5)
TYPED_SFIELD(sfSignature, VL, 6, SField::sMD_Default, SField::notSigning)
TYPED_SFIELD(sfSignature, VL, 6, SField::kSmdDefault, SField::kNotSigning)
TYPED_SFIELD(sfDomain, VL, 7)
TYPED_SFIELD(sfFundCode, VL, 8)
TYPED_SFIELD(sfRemoveCode, VL, 9)
@@ -283,7 +285,7 @@ TYPED_SFIELD(sfMemoFormat, VL, 14)
// variable length (uncommon)
TYPED_SFIELD(sfFulfillment, VL, 16)
TYPED_SFIELD(sfCondition, VL, 17)
TYPED_SFIELD(sfMasterSignature, VL, 18, SField::sMD_Default, SField::notSigning)
TYPED_SFIELD(sfMasterSignature, VL, 18, SField::kSmdDefault, SField::kNotSigning)
TYPED_SFIELD(sfUNLModifyValidator, VL, 19)
TYPED_SFIELD(sfValidatorToDisable, VL, 20)
TYPED_SFIELD(sfValidatorToReEnable, VL, 21)
@@ -325,7 +327,7 @@ TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
// vector of 256-bit
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::kSmdNever)
TYPED_SFIELD(sfHashes, VECTOR256, 2)
TYPED_SFIELD(sfAmendments, VECTOR256, 3)
TYPED_SFIELD(sfNFTokenOffers, VECTOR256, 4)
@@ -386,13 +388,13 @@ UNTYPED_SFIELD(sfCredential, OBJECT, 33)
UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
UNTYPED_SFIELD(sfBook, OBJECT, 36)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::sMD_Default, SField::notSigning)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::kSmdDefault, SField::kNotSigning)
// array of objects (common)
// ARRAY/1 is reserved for end of array
// sfSigningAccounts has never been used.
//UNTYPED_SFIELD(sfSigningAccounts, ARRAY, 2)
UNTYPED_SFIELD(sfSigners, ARRAY, 3, SField::sMD_Default, SField::notSigning)
UNTYPED_SFIELD(sfSigners, ARRAY, 3, SField::kSmdDefault, SField::kNotSigning)
UNTYPED_SFIELD(sfSignerEntries, ARRAY, 4)
UNTYPED_SFIELD(sfTemplate, ARRAY, 5)
UNTYPED_SFIELD(sfNecessary, ARRAY, 6)
@@ -420,6 +422,4 @@ UNTYPED_SFIELD(sfUnauthorizeCredentials, ARRAY, 27)
UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)
UNTYPED_SFIELD(sfRawTransactions, ARRAY, 30)
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::sMD_Default, SField::notSigning)
// clang-format on
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::kSmdDefault, SField::kNotSigning)

View File

@@ -4,18 +4,18 @@
namespace xrpl {
enum class TokenCodecErrc {
success = 0,
inputTooLarge,
inputTooSmall,
badB58Character,
outputTooSmall,
mismatchedTokenType,
mismatchedChecksum,
invalidEncodingChar,
overflowAdd,
unknown,
Success = 0,
InputTooLarge,
InputTooSmall,
BadB58Character,
OutputTooSmall,
MismatchedTokenType,
MismatchedChecksum,
InvalidEncodingChar,
OverflowAdd,
Unknown,
};
}
} // namespace xrpl
namespace std {
template <>
@@ -30,34 +30,34 @@ class TokenCodecErrcCategory : public std::error_category
{
public:
// Return a short descriptive name for the category
virtual char const*
name() const noexcept override final
[[nodiscard]] char const*
name() const noexcept final
{
return "TokenCodecError";
}
// Return what each enum means in text
virtual std::string
message(int c) const override final
[[nodiscard]] std::string
message(int c) const final
{
switch (static_cast<TokenCodecErrc>(c))
{
case TokenCodecErrc::success:
case TokenCodecErrc::Success:
return "conversion successful";
case TokenCodecErrc::inputTooLarge:
case TokenCodecErrc::InputTooLarge:
return "input too large";
case TokenCodecErrc::inputTooSmall:
case TokenCodecErrc::InputTooSmall:
return "input too small";
case TokenCodecErrc::badB58Character:
case TokenCodecErrc::BadB58Character:
return "bad base 58 character";
case TokenCodecErrc::outputTooSmall:
case TokenCodecErrc::OutputTooSmall:
return "output too small";
case TokenCodecErrc::mismatchedTokenType:
case TokenCodecErrc::MismatchedTokenType:
return "mismatched token type";
case TokenCodecErrc::mismatchedChecksum:
case TokenCodecErrc::MismatchedChecksum:
return "mismatched checksum";
case TokenCodecErrc::invalidEncodingChar:
case TokenCodecErrc::InvalidEncodingChar:
return "invalid encoding char";
case TokenCodecErrc::unknown:
case TokenCodecErrc::Unknown:
return "unknown";
default:
return "unknown";
@@ -67,15 +67,15 @@ public:
} // namespace detail
inline xrpl::detail::TokenCodecErrcCategory const&
TokenCodecErrcCategory()
tokenCodecErrcCategory()
{
static xrpl::detail::TokenCodecErrcCategory c;
return c;
static xrpl::detail::TokenCodecErrcCategory const kC;
return kC;
}
inline std::error_code
make_error_code(xrpl::TokenCodecErrc e)
{
return {static_cast<int>(e), TokenCodecErrcCategory()};
return {static_cast<int>(e), tokenCodecErrcCategory()};
}
} // namespace xrpl

File diff suppressed because it is too large Load Diff

View File

@@ -24,14 +24,14 @@ namespace xrpl {
@note This uses the OpenSSL implementation
*/
struct openssl_ripemd160_hasher
struct OpensslRipemd160Hasher
{
public:
static constexpr auto const endian = boost::endian::order::native;
static constexpr auto kEndian = boost::endian::order::native;
using result_type = std::array<std::uint8_t, 20>;
openssl_ripemd160_hasher();
OpensslRipemd160Hasher();
void
operator()(void const* data, std::size_t size) noexcept;
@@ -47,14 +47,14 @@ private:
@note This uses the OpenSSL implementation
*/
struct openssl_sha512_hasher
struct OpensslSha512Hasher
{
public:
static constexpr auto const endian = boost::endian::order::native;
static constexpr auto kEndian = boost::endian::order::native;
using result_type = std::array<std::uint8_t, 64>;
openssl_sha512_hasher();
OpensslSha512Hasher();
void
operator()(void const* data, std::size_t size) noexcept;
@@ -70,14 +70,14 @@ private:
@note This uses the OpenSSL implementation
*/
struct openssl_sha256_hasher
struct OpensslSha256Hasher
{
public:
static constexpr auto const endian = boost::endian::order::native;
static constexpr auto kEndian = boost::endian::order::native;
using result_type = std::array<std::uint8_t, 32>;
openssl_sha256_hasher();
OpensslSha256Hasher();
void
operator()(void const* data, std::size_t size) noexcept;
@@ -91,16 +91,16 @@ private:
//------------------------------------------------------------------------------
using ripemd160_hasher = openssl_ripemd160_hasher;
using sha256_hasher = openssl_sha256_hasher;
using sha512_hasher = openssl_sha512_hasher;
using ripemd160_hasher = OpensslRipemd160Hasher;
using sha256_hasher = OpensslSha256Hasher;
using sha512_hasher = OpensslSha512Hasher;
//------------------------------------------------------------------------------
/** Returns the RIPEMD-160 digest of the SHA256 hash of the message.
This operation is used to compute the 160-bit identifier
representing a Ripple account, from a message. Typically the
representing an XRPL account, from a message. Typically the
message is the public key of the account - which is not
stored in the account root.
@@ -112,13 +112,13 @@ using sha512_hasher = openssl_sha512_hasher;
Meets the requirements of Hasher (in hash_append)
*/
struct ripesha_hasher
struct RipeshaHasher
{
private:
sha256_hasher h_;
public:
static constexpr auto const endian = boost::endian::order::native;
static constexpr auto kEndian = boost::endian::order::native;
using result_type = std::array<std::uint8_t, 20>;
@@ -148,17 +148,17 @@ namespace detail {
SHA-512 digest of the message.
*/
template <bool Secure>
struct basic_sha512_half_hasher
struct BasicSha512HalfHasher
{
private:
sha512_hasher h_;
public:
static constexpr auto const endian = boost::endian::order::big;
static constexpr auto kEndian = boost::endian::order::big;
using result_type = uint256;
~basic_sha512_half_hasher()
~BasicSha512HalfHasher()
{
erase(std::integral_constant<bool, Secure>{});
}
@@ -177,24 +177,24 @@ public:
}
private:
inline void
void
erase(std::false_type)
{
}
inline void
void
erase(std::true_type)
{
secure_erase(&h_, sizeof(h_));
secureErase(&h_, sizeof(h_));
}
};
} // namespace detail
using sha512_half_hasher = detail::basic_sha512_half_hasher<false>;
using sha512_half_hasher = detail::BasicSha512HalfHasher<false>;
// secure version
using sha512_half_hasher_s = detail::basic_sha512_half_hasher<true>;
using sha512_half_hasher_s = detail::BasicSha512HalfHasher<true>;
//------------------------------------------------------------------------------
@@ -217,7 +217,7 @@ sha512Half(Args const&... args)
*/
template <class... Args>
sha512_half_hasher_s::result_type
sha512Half_s(Args const&... args)
sha512HalfS(Args const&... args)
{
sha512_half_hasher_s h;
using beast::hash_append;

View File

@@ -10,12 +10,12 @@
#include <exception>
#include <optional>
namespace Json {
namespace json {
struct JsonMissingKeyError : std::exception
{
char const* const key;
mutable std::string msg;
JsonMissingKeyError(Json::StaticString const& k) : key{k.c_str()}
JsonMissingKeyError(json::StaticString const& k) : key{k.cStr()}
{
}
char const*
@@ -34,8 +34,8 @@ struct JsonTypeMismatchError : std::exception
char const* const key;
std::string const expectedType;
mutable std::string msg;
JsonTypeMismatchError(Json::StaticString const& k, std::string et)
: key{k.c_str()}, expectedType{std::move(et)}
JsonTypeMismatchError(json::StaticString const& k, std::string et)
: key{k.cStr()}, expectedType{std::move(et)}
{
}
char const*
@@ -52,21 +52,21 @@ struct JsonTypeMismatchError : std::exception
template <class T>
T
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
static_assert(sizeof(T) == -1, "This function must be specialized");
}
template <>
inline std::string
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
Json::StaticString const& key = field.getJsonName();
json::StaticString const& key = field.getJsonName();
if (!v.isMember(key))
Throw<JsonMissingKeyError>(key);
Json::Value const& inner = v[key];
json::Value const& inner = v[key];
if (!inner.isString())
Throw<JsonTypeMismatchError>(key, "string");
return inner.asString();
@@ -75,13 +75,13 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
// Note, this allows integer numeric fields to act as bools
template <>
inline bool
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
Json::StaticString const& key = field.getJsonName();
json::StaticString const& key = field.getJsonName();
if (!v.isMember(key))
Throw<JsonMissingKeyError>(key);
Json::Value const& inner = v[key];
json::Value const& inner = v[key];
if (inner.isBool())
return inner.asBool();
if (!inner.isIntegral())
@@ -92,13 +92,13 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
template <>
inline std::uint64_t
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
Json::StaticString const& key = field.getJsonName();
json::StaticString const& key = field.getJsonName();
if (!v.isMember(key))
Throw<JsonMissingKeyError>(key);
Json::Value const& inner = v[key];
json::Value const& inner = v[key];
if (inner.isUInt())
return inner.asUInt();
if (inner.isInt())
@@ -112,7 +112,7 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
{
auto const s = inner.asString();
// parse as hex
std::uint64_t val;
std::uint64_t val = 0;
auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val, 16);
@@ -125,7 +125,7 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
template <>
inline xrpl::Buffer
getOrThrow(Json::Value const& v, xrpl::SField const& field)
getOrThrow(json::Value const& v, xrpl::SField const& field)
{
using namespace xrpl;
std::string const hex = getOrThrow<std::string>(v, field);
@@ -140,16 +140,16 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field)
// This function may be used by external projects (like the witness server).
template <class T>
std::optional<T>
getOptional(Json::Value const& v, xrpl::SField const& field)
getOptional(json::Value const& v, xrpl::SField const& field)
{
try
{
return getOrThrow<T>(v, field);
}
catch (...)
catch (...) // NOLINT(bugprone-empty-catch)
{
}
return {};
}
} // namespace Json
} // namespace json

File diff suppressed because it is too large Load Diff

View File

@@ -9,14 +9,13 @@
#include <cstdint>
#include <cstring>
namespace xrpl {
namespace nft {
namespace xrpl::nft {
// Separate taxons from regular integers.
struct TaxonTag
{
};
using Taxon = tagged_integer<std::uint32_t, TaxonTag>;
using Taxon = TaggedInteger<std::uint32_t, TaxonTag>;
inline Taxon
toTaxon(std::uint32_t i)
@@ -30,16 +29,16 @@ toUInt32(Taxon t)
return static_cast<std::uint32_t>(t);
}
constexpr std::uint16_t const flagBurnable = 0x0001;
constexpr std::uint16_t const flagOnlyXRP = 0x0002;
constexpr std::uint16_t const flagCreateTrustLines = 0x0004;
constexpr std::uint16_t const flagTransferable = 0x0008;
constexpr std::uint16_t const flagMutable = 0x0010;
constexpr std::uint16_t const kFlagBurnable = 0x0001;
constexpr std::uint16_t const kFlagOnlyXrp = 0x0002;
constexpr std::uint16_t const kFlagCreateTrustLines = 0x0004;
constexpr std::uint16_t const kFlagTransferable = 0x0008;
constexpr std::uint16_t const kFlagMutable = 0x0010;
inline std::uint16_t
getFlags(uint256 const& id)
{
std::uint16_t flags;
std::uint16_t flags = 0;
memcpy(&flags, id.begin(), 2);
return boost::endian::big_to_native(flags);
}
@@ -47,7 +46,7 @@ getFlags(uint256 const& id)
inline std::uint16_t
getTransferFee(uint256 const& id)
{
std::uint16_t fee;
std::uint16_t fee = 0;
memcpy(&fee, id.begin() + 2, 2);
return boost::endian::big_to_native(fee);
}
@@ -55,7 +54,7 @@ getTransferFee(uint256 const& id)
inline std::uint32_t
getSerial(uint256 const& id)
{
std::uint32_t seq;
std::uint32_t seq = 0;
memcpy(&seq, id.begin() + 28, 4);
return boost::endian::big_to_native(seq);
}
@@ -87,7 +86,7 @@ cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
inline Taxon
getTaxon(uint256 const& id)
{
std::uint32_t taxon;
std::uint32_t taxon = 0;
memcpy(&taxon, id.begin() + 24, 4);
taxon = boost::endian::big_to_native(taxon);
@@ -102,5 +101,4 @@ getIssuer(uint256 const& id)
return AccountID::fromVoid(id.data() + 4);
}
} // namespace nft
} // namespace xrpl
} // namespace xrpl::nft

View File

@@ -4,13 +4,11 @@
#include <string_view>
namespace xrpl {
namespace nft {
namespace xrpl::nft {
// NFT directory pages order their contents based only on the low 96 bits of
// the NFToken value. This mask provides easy access to the necessary mask.
uint256 constexpr pageMask(
constexpr uint256 kPageMask(
std::string_view("0000000000000000000000000000000000000000ffffffffffffffffffffffff"));
} // namespace nft
} // namespace xrpl
} // namespace xrpl::nft

View File

@@ -62,7 +62,7 @@ decodeBase58Token(std::string const& s, TokenType type);
namespace detail {
// Expose detail functions for unit tests only
std::string
encodeBase58(void const* message, std::size_t size, void* temp, std::size_t temp_size);
encodeBase58(void const* message, std::size_t size, void* temp, std::size_t tempSize);
std::string
decodeBase58(std::string const& s);
@@ -75,7 +75,7 @@ namespace b58_fast {
// particular)
[[nodiscard]] B58Result<std::span<std::uint8_t>>
encodeBase58Token(
TokenType token_type,
TokenType tokenType,
std::span<std::uint8_t const> input,
std::span<std::uint8_t> out);
@@ -93,10 +93,10 @@ decodeBase58Token(std::string const& s, TokenType type);
namespace detail {
// Expose detail functions for unit tests only
B58Result<std::span<std::uint8_t>>
b256_to_b58_be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out);
b256ToB58Be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out);
B58Result<std::span<std::uint8_t>>
b58_to_b256_be(std::string_view input, std::span<std::uint8_t> out);
b58ToB256Be(std::string_view input, std::span<std::uint8_t> out);
} // namespace detail
} // namespace b58_fast