mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Rearrange sources
This commit is contained in:
134
include/xrpl/protocol/AMMCore.h
Normal file
134
include/xrpl/protocol/AMMCore.h
Normal file
@@ -0,0 +1,134 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_AMMCORE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_AMMCORE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Number.h>
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
#include <ripple/protocol/Issue.h>
|
||||
#include <ripple/protocol/TER.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
std::uint16_t constexpr TRADING_FEE_THRESHOLD = 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;
|
||||
|
||||
// Votes
|
||||
std::uint16_t constexpr VOTE_MAX_SLOTS = 8;
|
||||
std::uint32_t constexpr VOTE_WEIGHT_SCALE_FACTOR = 100000;
|
||||
|
||||
class STObject;
|
||||
class STAmount;
|
||||
class Rules;
|
||||
|
||||
/** Calculate AMM account ID.
|
||||
*/
|
||||
AccountID
|
||||
ammAccountID(
|
||||
std::uint16_t prefix,
|
||||
uint256 const& parentHash,
|
||||
uint256 const& ammID);
|
||||
|
||||
/** Calculate Liquidity Provider Token (LPT) Currency.
|
||||
*/
|
||||
Currency
|
||||
ammLPTCurrency(Currency const& cur1, Currency const& cur2);
|
||||
|
||||
/** Calculate LPT Issue from AMM asset pair.
|
||||
*/
|
||||
Issue
|
||||
ammLPTIssue(
|
||||
Currency const& cur1,
|
||||
Currency const& cur2,
|
||||
AccountID const& ammAccountID);
|
||||
|
||||
/** Validate the amount.
|
||||
* If validZero is false and amount is beast::zero then invalid amount.
|
||||
* Return error code if invalid amount.
|
||||
* If pair then validate amount's issue matches one of the pair's issue.
|
||||
*/
|
||||
NotTEC
|
||||
invalidAMMAmount(
|
||||
STAmount const& amount,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt,
|
||||
bool validZero = false);
|
||||
|
||||
NotTEC
|
||||
invalidAMMAsset(
|
||||
Issue const& issue,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
|
||||
|
||||
NotTEC
|
||||
invalidAMMAssetPair(
|
||||
Issue const& issue1,
|
||||
Issue const& issue2,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair = std::nullopt);
|
||||
|
||||
/** Get time slot of the auction slot.
|
||||
*/
|
||||
std::optional<std::uint8_t>
|
||||
ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot);
|
||||
|
||||
/** Return true if required AMM amendments are enabled
|
||||
*/
|
||||
bool
|
||||
ammEnabled(Rules const&);
|
||||
|
||||
/** Convert to the fee from the basis points
|
||||
* @param tfee trading fee in {0, 1000}
|
||||
* 1 = 1/10bps or 0.001%, 1000 = 1%
|
||||
*/
|
||||
inline Number
|
||||
getFee(std::uint16_t tfee)
|
||||
{
|
||||
return Number{tfee} / AUCTION_SLOT_FEE_SCALE_FACTOR;
|
||||
}
|
||||
|
||||
/** Get fee multiplier (1 - tfee)
|
||||
* @tfee trading fee in basis points
|
||||
*/
|
||||
inline Number
|
||||
feeMult(std::uint16_t tfee)
|
||||
{
|
||||
return 1 - getFee(tfee);
|
||||
}
|
||||
|
||||
/** Get fee multiplier (1 - tfee / 2)
|
||||
* @tfee trading fee in basis points
|
||||
*/
|
||||
inline Number
|
||||
feeMultHalf(std::uint16_t tfee)
|
||||
{
|
||||
return 1 - getFee(tfee) / 2;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif // RIPPLE_PROTOCOL_AMMCORE_H_INCLUDED
|
||||
157
include/xrpl/protocol/AccountID.h
Normal file
157
include/xrpl/protocol/AccountID.h
Normal file
@@ -0,0 +1,157 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2014 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_ACCOUNTID_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_ACCOUNTID_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/tokens.h>
|
||||
// VFALCO Uncomment when the header issues are resolved
|
||||
//#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/basics/UnorderedContainers.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/json_get_or_throw.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class AccountIDTag
|
||||
{
|
||||
public:
|
||||
explicit AccountIDTag() = default;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** A 160-bit unsigned that uniquely identifies an account. */
|
||||
using AccountID = base_uint<160, detail::AccountIDTag>;
|
||||
|
||||
/** Convert AccountID to base58 checked string */
|
||||
std::string
|
||||
toBase58(AccountID const& v);
|
||||
|
||||
/** Parse AccountID from checked, base58 string.
|
||||
@return std::nullopt if a parse error occurs
|
||||
*/
|
||||
template <>
|
||||
std::optional<AccountID>
|
||||
parseBase58(std::string const& s);
|
||||
|
||||
/** Compute AccountID from public key.
|
||||
|
||||
The account ID is computed as the 160-bit hash of the
|
||||
public key data. This excludes the version byte and
|
||||
guard bytes included in the base58 representation.
|
||||
|
||||
*/
|
||||
// VFALCO In PublicKey.h for now
|
||||
// AccountID
|
||||
// calcAccountID (PublicKey const& pk);
|
||||
|
||||
/** A special account that's used as the "issuer" for XRP. */
|
||||
AccountID const&
|
||||
xrpAccount();
|
||||
|
||||
/** A placeholder for empty accounts. */
|
||||
AccountID const&
|
||||
noAccount();
|
||||
|
||||
/** Convert hex or base58 string to AccountID.
|
||||
|
||||
@return `true` if the parsing was successful.
|
||||
*/
|
||||
// DEPRECATED
|
||||
bool
|
||||
to_issuer(AccountID&, std::string const&);
|
||||
|
||||
// DEPRECATED Should be checking the currency or native flag
|
||||
inline bool
|
||||
isXRP(AccountID const& c)
|
||||
{
|
||||
return c == beast::zero;
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
inline std::string
|
||||
to_string(AccountID const& account)
|
||||
{
|
||||
return toBase58(account);
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, AccountID const& x)
|
||||
{
|
||||
os << to_string(x);
|
||||
return os;
|
||||
}
|
||||
|
||||
/** Initialize the global cache used to map AccountID to base58 conversions.
|
||||
|
||||
The cache is optional and need not be initialized. But because conversion
|
||||
is expensive (it requires a SHA-256 operation) in most cases the overhead
|
||||
of the cache is worth the benefit.
|
||||
|
||||
@param count The number of entries the cache should accomodate. Zero will
|
||||
disable the cache, releasing any memory associated with it.
|
||||
|
||||
@note The function will only initialize the cache the first time it is
|
||||
invoked. Subsequent invocations do nothing.
|
||||
*/
|
||||
void
|
||||
initAccountIdCache(std::size_t count);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
namespace Json {
|
||||
template <>
|
||||
inline ripple::AccountID
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
|
||||
std::string const b58 = getOrThrow<std::string>(v, field);
|
||||
if (auto const r = parseBase58<AccountID>(b58))
|
||||
return *r;
|
||||
Throw<JsonTypeMismatchError>(field.getJsonName(), "AccountID");
|
||||
}
|
||||
} // namespace Json
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace std {
|
||||
|
||||
// DEPRECATED
|
||||
// VFALCO Use beast::uhash or a hardened container
|
||||
template <>
|
||||
struct hash<ripple::AccountID> : ripple::AccountID::hasher
|
||||
{
|
||||
explicit hash() = default;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
220
include/xrpl/protocol/AmountConversions.h
Normal file
220
include/xrpl/protocol/AmountConversions.h
Normal file
@@ -0,0 +1,220 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_AMOUNTCONVERSION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_AMOUNTCONVERSION_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/IOUAmount.h>
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(IOUAmount const& iou, Issue const& iss)
|
||||
{
|
||||
bool const isNeg = iou.signum() < 0;
|
||||
std::uint64_t const umant = isNeg ? -iou.mantissa() : iou.mantissa();
|
||||
return STAmount(
|
||||
iss,
|
||||
umant,
|
||||
iou.exponent(),
|
||||
/*native*/ false,
|
||||
isNeg,
|
||||
STAmount::unchecked());
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(IOUAmount const& iou)
|
||||
{
|
||||
return toSTAmount(iou, noIssue());
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(XRPAmount const& xrp)
|
||||
{
|
||||
bool const isNeg = xrp.signum() < 0;
|
||||
std::uint64_t const umant = isNeg ? -xrp.drops() : xrp.drops();
|
||||
return STAmount(umant, isNeg);
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(XRPAmount const& xrp, Issue const& iss)
|
||||
{
|
||||
assert(isXRP(iss.account) && isXRP(iss.currency));
|
||||
return toSTAmount(xrp);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
toAmount(STAmount const& amt) = delete;
|
||||
|
||||
template <>
|
||||
inline STAmount
|
||||
toAmount<STAmount>(STAmount const& amt)
|
||||
{
|
||||
return amt;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline IOUAmount
|
||||
toAmount<IOUAmount>(STAmount const& amt)
|
||||
{
|
||||
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max());
|
||||
bool const isNeg = amt.negative();
|
||||
std::int64_t const sMant =
|
||||
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
|
||||
|
||||
assert(!isXRP(amt));
|
||||
return IOUAmount(sMant, amt.exponent());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline XRPAmount
|
||||
toAmount<XRPAmount>(STAmount const& amt)
|
||||
{
|
||||
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max());
|
||||
bool const isNeg = amt.negative();
|
||||
std::int64_t const sMant =
|
||||
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
|
||||
|
||||
assert(isXRP(amt));
|
||||
return XRPAmount(sMant);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
toAmount(IOUAmount const& amt) = delete;
|
||||
|
||||
template <>
|
||||
inline IOUAmount
|
||||
toAmount<IOUAmount>(IOUAmount const& amt)
|
||||
{
|
||||
return amt;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
toAmount(XRPAmount const& amt) = delete;
|
||||
|
||||
template <>
|
||||
inline XRPAmount
|
||||
toAmount<XRPAmount>(XRPAmount const& amt)
|
||||
{
|
||||
return amt;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
toAmount(
|
||||
Issue const& issue,
|
||||
Number const& n,
|
||||
Number::rounding_mode mode = Number::getround())
|
||||
{
|
||||
saveNumberRoundMode rm(Number::getround());
|
||||
if (isXRP(issue))
|
||||
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<STAmount, T>)
|
||||
{
|
||||
if (isXRP(issue))
|
||||
return STAmount(issue, static_cast<std::int64_t>(n));
|
||||
return STAmount(issue, n.mantissa(), n.exponent());
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
|
||||
static_assert(alwaysFalse, "Unsupported type for toAmount");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
toMaxAmount(Issue const& issue)
|
||||
{
|
||||
if constexpr (std::is_same_v<IOUAmount, T>)
|
||||
return IOUAmount(STAmount::cMaxValue, STAmount::cMaxOffset);
|
||||
else if constexpr (std::is_same_v<XRPAmount, T>)
|
||||
return XRPAmount(static_cast<std::int64_t>(STAmount::cMaxNativeN));
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
|
||||
static_assert(alwaysFalse, "Unsupported type for toMaxAmount");
|
||||
}
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
toSTAmount(
|
||||
Issue const& issue,
|
||||
Number const& n,
|
||||
Number::rounding_mode mode = Number::getround())
|
||||
{
|
||||
return toAmount<STAmount>(issue, n, mode);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Issue
|
||||
getIssue(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<STAmount, T>)
|
||||
return amt.issue();
|
||||
else
|
||||
{
|
||||
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
|
||||
static_assert(alwaysFalse, "Unsupported type for getIssue");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<STAmount, T>)
|
||||
return a;
|
||||
else
|
||||
{
|
||||
constexpr bool alwaysFalse = !std::is_same_v<T, T>;
|
||||
static_assert(alwaysFalse, "Unsupported type for get");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
119
include/xrpl/protocol/ApiVersion.h
Normal file
119
include/xrpl/protocol/ApiVersion.h
Normal file
@@ -0,0 +1,119 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_APIVERSION_H_INCLUDED
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
* API version numbers used in later API versions
|
||||
*
|
||||
* Requests with a version number in the range
|
||||
* [apiMinimumSupportedVersion, apiMaximumSupportedVersion]
|
||||
* are supported.
|
||||
*
|
||||
* If [beta_rpc_api] is enabled in config, the version numbers
|
||||
* in the range [apiMinimumSupportedVersion, apiBetaVersion]
|
||||
* are supported.
|
||||
*
|
||||
* Network Requests without explicit version numbers use
|
||||
* apiVersionIfUnspecified. apiVersionIfUnspecified is 1,
|
||||
* because all the RPC requests with a version >= 2 must
|
||||
* explicitly specify the version in the requests.
|
||||
* Note that apiVersionIfUnspecified will be lower than
|
||||
* apiMinimumSupportedVersion when we stop supporting API
|
||||
* version 1.
|
||||
*
|
||||
* Command line Requests use apiCommandLineVersion.
|
||||
*/
|
||||
|
||||
namespace RPC {
|
||||
|
||||
template <unsigned int Version>
|
||||
constexpr static std::integral_constant<unsigned, Version> apiVersion = {};
|
||||
|
||||
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_assert(apiInvalidVersion < apiMinimumSupportedVersion);
|
||||
static_assert(
|
||||
apiVersionIfUnspecified >= apiMinimumSupportedVersion &&
|
||||
apiVersionIfUnspecified <= apiMaximumSupportedVersion);
|
||||
static_assert(
|
||||
apiCommandLineVersion >= apiMinimumSupportedVersion &&
|
||||
apiCommandLineVersion <= apiMaximumSupportedVersion);
|
||||
static_assert(apiMaximumSupportedVersion >= apiMinimumSupportedVersion);
|
||||
static_assert(apiBetaVersion >= apiMaximumSupportedVersion);
|
||||
static_assert(apiMaximumValidVersion >= apiMaximumSupportedVersion);
|
||||
|
||||
} // namespace RPC
|
||||
|
||||
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)...);
|
||||
}
|
||||
{
|
||||
constexpr auto size = maxVer + 1 - minVer;
|
||||
[&]<std::size_t... offset>(std::index_sequence<offset...>)
|
||||
{
|
||||
(((void)fn(
|
||||
std::integral_constant<unsigned int, minVer + offset>{},
|
||||
std::forward<Args>(args)...)),
|
||||
...);
|
||||
}
|
||||
(std::make_index_sequence<size>{});
|
||||
}
|
||||
|
||||
template <typename Fn, typename... Args>
|
||||
void
|
||||
forAllApiVersions(Fn const& fn, Args&&... args) requires requires
|
||||
{
|
||||
forApiVersions<
|
||||
RPC::apiMinimumSupportedVersion,
|
||||
RPC::apiMaximumValidVersion>(fn, std::forward<Args>(args)...);
|
||||
}
|
||||
{
|
||||
forApiVersions<
|
||||
RPC::apiMinimumSupportedVersion,
|
||||
RPC::apiMaximumValidVersion>(fn, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
175
include/xrpl/protocol/Book.h
Normal file
175
include/xrpl/protocol/Book.h
Normal file
@@ -0,0 +1,175 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_BOOK_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_BOOK_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/Issue.h>
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Specifies an order book.
|
||||
The order book is a pair of Issues called in and out.
|
||||
@see Issue.
|
||||
*/
|
||||
class Book final : public CountedObject<Book>
|
||||
{
|
||||
public:
|
||||
Issue in;
|
||||
Issue out;
|
||||
|
||||
Book()
|
||||
{
|
||||
}
|
||||
|
||||
Book(Issue const& in_, Issue const& out_) : in(in_), out(out_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
isConsistent(Book const& book);
|
||||
|
||||
std::string
|
||||
to_string(Book const& book);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, Book const& x);
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, Book const& b)
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append(h, b.in, b.out);
|
||||
}
|
||||
|
||||
Book
|
||||
reversed(Book const& book);
|
||||
|
||||
/** Equality comparison. */
|
||||
/** @{ */
|
||||
[[nodiscard]] inline constexpr bool
|
||||
operator==(Book const& lhs, Book const& rhs)
|
||||
{
|
||||
return (lhs.in == rhs.in) && (lhs.out == rhs.out);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Strict weak ordering. */
|
||||
/** @{ */
|
||||
[[nodiscard]] inline constexpr std::weak_ordering
|
||||
operator<=>(Book const& lhs, Book const& rhs)
|
||||
{
|
||||
if (auto const c{lhs.in <=> rhs.in}; c != 0)
|
||||
return c;
|
||||
return lhs.out <=> rhs.out;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<ripple::Issue>
|
||||
: private boost::base_from_member<std::hash<ripple::Currency>, 0>,
|
||||
private boost::base_from_member<std::hash<ripple::AccountID>, 1>
|
||||
{
|
||||
private:
|
||||
using currency_hash_type =
|
||||
boost::base_from_member<std::hash<ripple::Currency>, 0>;
|
||||
using issuer_hash_type =
|
||||
boost::base_from_member<std::hash<ripple::AccountID>, 1>;
|
||||
|
||||
public:
|
||||
explicit hash() = default;
|
||||
|
||||
using value_type = std::size_t;
|
||||
using argument_type = ripple::Issue;
|
||||
|
||||
value_type
|
||||
operator()(argument_type const& value) const
|
||||
{
|
||||
value_type result(currency_hash_type::member(value.currency));
|
||||
if (!isXRP(value.currency))
|
||||
boost::hash_combine(
|
||||
result, issuer_hash_type::member(value.account));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
struct hash<ripple::Book>
|
||||
{
|
||||
private:
|
||||
using hasher = std::hash<ripple::Issue>;
|
||||
|
||||
hasher m_hasher;
|
||||
|
||||
public:
|
||||
explicit hash() = default;
|
||||
|
||||
using value_type = std::size_t;
|
||||
using argument_type = ripple::Book;
|
||||
|
||||
value_type
|
||||
operator()(argument_type const& value) const
|
||||
{
|
||||
value_type result(m_hasher(value.in));
|
||||
boost::hash_combine(result, m_hasher(value.out));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <>
|
||||
struct hash<ripple::Issue> : std::hash<ripple::Issue>
|
||||
{
|
||||
explicit hash() = default;
|
||||
|
||||
using Base = std::hash<ripple::Issue>;
|
||||
// VFALCO NOTE broken in vs2012
|
||||
// using Base::Base; // inherit ctors
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<ripple::Book> : std::hash<ripple::Book>
|
||||
{
|
||||
explicit hash() = default;
|
||||
|
||||
using Base = std::hash<ripple::Book>;
|
||||
// VFALCO NOTE broken in vs2012
|
||||
// using Base::Base; // inherit ctors
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
103
include/xrpl/protocol/BuildInfo.h
Normal file
103
include/xrpl/protocol/BuildInfo.h
Normal file
@@ -0,0 +1,103 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_BUILDINFO_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_BUILDINFO_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Versioning information for this build. */
|
||||
// VFALCO The namespace is deprecated
|
||||
namespace BuildInfo {
|
||||
|
||||
/** Server version.
|
||||
Follows the Semantic Versioning Specification:
|
||||
http://semver.org/
|
||||
*/
|
||||
std::string const&
|
||||
getVersionString();
|
||||
|
||||
/** Full server version string.
|
||||
This includes the name of the server. It is used in the peer
|
||||
protocol hello message and also the headers of some HTTP replies.
|
||||
*/
|
||||
std::string const&
|
||||
getFullVersionString();
|
||||
|
||||
/** Encode an arbitrary server software version in a 64-bit integer.
|
||||
|
||||
The general format is:
|
||||
|
||||
........-........-........-........-........-........-........-........
|
||||
XXXXXXXX-XXXXXXXX-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY-YYYYYYYY
|
||||
|
||||
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:
|
||||
|
||||
00011000-00111011-MMMMMMMM-mmmmmmmm-pppppppp-TTNNNNNN-00000000-00000000
|
||||
|
||||
M: 8-bit major version (0-255)
|
||||
m: 8-bit minor version (0-255)
|
||||
p: 8-bit patch version (0-255)
|
||||
T: 11 if neither an RC nor a beta
|
||||
10 if an RC
|
||||
01 if a beta
|
||||
N: 6-bit rc/beta number (1-63)
|
||||
|
||||
@param the version string
|
||||
@return the encoded version in a 64-bit integer
|
||||
*/
|
||||
std::uint64_t
|
||||
encodeSoftwareVersion(char const* versionStr);
|
||||
|
||||
/** Returns this server's version packed in a 64-bit integer. */
|
||||
std::uint64_t
|
||||
getEncodedVersion();
|
||||
|
||||
/** Check if the encoded software version is a rippled software version.
|
||||
|
||||
@param version another node's encoded software version
|
||||
@return true if the version is a rippled software version, false otherwise
|
||||
*/
|
||||
bool
|
||||
isRippledVersion(std::uint64_t version);
|
||||
|
||||
/** Check if the version is newer than the local node's rippled software
|
||||
version.
|
||||
|
||||
@param version another node's encoded software version
|
||||
@return true if the version is newer than the local node's rippled software
|
||||
version, false otherwise.
|
||||
|
||||
@note This function only understands version numbers that are generated by
|
||||
rippled. Please see the encodeSoftwareVersion() function for detail.
|
||||
*/
|
||||
bool
|
||||
isNewerVersion(std::uint64_t version);
|
||||
|
||||
} // namespace BuildInfo
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
372
include/xrpl/protocol/ErrorCodes.h
Normal file
372
include/xrpl/protocol/ErrorCodes.h
Normal file
@@ -0,0 +1,372 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012 - 2019 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_ERRORCODES_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_ERRORCODES_H_INCLUDED
|
||||
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// VFALCO NOTE These are outside the RPC namespace
|
||||
|
||||
// NOTE: Although the precise numeric values of these codes were never
|
||||
// intended to be stable, several API endpoints include the numeric values.
|
||||
// Some users came to rely on the values, meaning that renumbering would be
|
||||
// a breaking change for those users.
|
||||
//
|
||||
// We therefore treat the range of values as stable although they are not
|
||||
// and are subject to change.
|
||||
//
|
||||
// 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 {
|
||||
// -1 represents codes not listed in this enumeration
|
||||
rpcUNKNOWN = -1,
|
||||
|
||||
rpcSUCCESS = 0,
|
||||
|
||||
rpcBAD_SYNTAX = 1,
|
||||
rpcJSON_RPC = 2,
|
||||
rpcFORBIDDEN = 3,
|
||||
|
||||
rpcWRONG_NETWORK = 4,
|
||||
// Misc failure
|
||||
// unused 5,
|
||||
rpcNO_PERMISSION = 6,
|
||||
rpcNO_EVENTS = 7,
|
||||
// unused 8,
|
||||
rpcTOO_BUSY = 9,
|
||||
rpcSLOW_DOWN = 10,
|
||||
rpcHIGH_FEE = 11,
|
||||
rpcNOT_ENABLED = 12,
|
||||
rpcNOT_READY = 13,
|
||||
rpcAMENDMENT_BLOCKED = 14,
|
||||
|
||||
// Networking
|
||||
rpcNO_CLOSED = 15,
|
||||
rpcNO_CURRENT = 16,
|
||||
rpcNO_NETWORK = 17,
|
||||
rpcNOT_SYNCED = 18,
|
||||
|
||||
// Ledger state
|
||||
rpcACT_NOT_FOUND = 19,
|
||||
rpcNAMESPACE_NOT_FOUND = 20,
|
||||
|
||||
rpcLGR_NOT_FOUND = 21,
|
||||
rpcLGR_NOT_VALIDATED = 22,
|
||||
rpcMASTER_DISABLED = 23,
|
||||
// unused 24,
|
||||
// unused 25,
|
||||
// unused 26,
|
||||
// unused 27,
|
||||
// unused 28,
|
||||
rpcTXN_NOT_FOUND = 29,
|
||||
rpcINVALID_HOTWALLET = 30,
|
||||
|
||||
// Malformed command
|
||||
rpcINVALID_PARAMS = 31,
|
||||
rpcUNKNOWN_COMMAND = 32,
|
||||
rpcNO_PF_REQUEST = 33,
|
||||
|
||||
// Bad parameter
|
||||
// NOT USED DO NOT USE AGAIN rpcACT_BITCOIN = 34,
|
||||
rpcACT_MALFORMED = 35,
|
||||
rpcALREADY_MULTISIG = 36,
|
||||
rpcALREADY_SINGLE_SIG = 37,
|
||||
rpcNAMESPACE_MALFORMED = 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,
|
||||
// unused 54,
|
||||
// unused 55,
|
||||
// unused 56,
|
||||
rpcLGR_IDXS_INVALID = 57,
|
||||
rpcLGR_IDX_MALFORMED = 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,
|
||||
// unused 68,
|
||||
rpcSRC_CUR_MALFORMED = 69,
|
||||
rpcSRC_ISR_MALFORMED = 70,
|
||||
rpcSTREAM_MALFORMED = 71,
|
||||
rpcATX_DEPRECATED = 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,
|
||||
|
||||
// Reporting
|
||||
rpcFAILED_TO_FORWARD = 90,
|
||||
rpcREPORTING_UNSUPPORTED = 91,
|
||||
|
||||
rpcOBJECT_NOT_FOUND = 92,
|
||||
|
||||
rpcLEDGER_MISSING = 93,
|
||||
|
||||
// AMM
|
||||
rpcISSUE_MALFORMED = 94,
|
||||
|
||||
// Oracle
|
||||
rpcORACLE_MALFORMED = 95,
|
||||
|
||||
rpcLAST =
|
||||
rpcORACLE_MALFORMED // 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,
|
||||
warnRPC_REPORTING = 1004
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// VFALCO NOTE these should probably not be in the RPC namespace.
|
||||
|
||||
namespace RPC {
|
||||
|
||||
/** Maps an rpc error code to its token, default message, and HTTP status. */
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr ErrorInfo(
|
||||
error_code_i code_,
|
||||
char const* token_,
|
||||
char const* message_)
|
||||
: code(code_), token(token_), message(message_), http_status(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_)
|
||||
{
|
||||
}
|
||||
|
||||
error_code_i code;
|
||||
Json::StaticString token;
|
||||
Json::StaticString message;
|
||||
int http_status;
|
||||
};
|
||||
|
||||
/** Returns an ErrorInfo that reflects the error code. */
|
||||
ErrorInfo const&
|
||||
get_error_info(error_code_i code);
|
||||
|
||||
/** Add or update the json update to reflect the error code. */
|
||||
/** @{ */
|
||||
template <class JsonValue>
|
||||
void
|
||||
inject_error(error_code_i code, JsonValue& json)
|
||||
{
|
||||
ErrorInfo const& info(get_error_info(code));
|
||||
json[jss::error] = info.token;
|
||||
json[jss::error_code] = info.code;
|
||||
json[jss::error_message] = info.message;
|
||||
}
|
||||
|
||||
template <class JsonValue>
|
||||
void
|
||||
inject_error(int code, JsonValue& json)
|
||||
{
|
||||
inject_error(error_code_i(code), json);
|
||||
}
|
||||
|
||||
template <class JsonValue>
|
||||
void
|
||||
inject_error(error_code_i code, std::string const& message, JsonValue& json)
|
||||
{
|
||||
ErrorInfo const& info(get_error_info(code));
|
||||
json[jss::error] = info.token;
|
||||
json[jss::error_code] = info.code;
|
||||
json[jss::error_message] = message;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** 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);
|
||||
/** @} */
|
||||
|
||||
/** Returns a new json object that indicates invalid parameters. */
|
||||
/** @{ */
|
||||
inline Json::Value
|
||||
make_param_error(std::string const& message)
|
||||
{
|
||||
return make_error(rpcINVALID_PARAMS, message);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
missing_field_message(std::string const& name)
|
||||
{
|
||||
return "Missing field '" + name + "'.";
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
missing_field_error(std::string const& name)
|
||||
{
|
||||
return make_param_error(missing_field_message(name));
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
missing_field_error(Json::StaticString name)
|
||||
{
|
||||
return missing_field_error(std::string(name));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
object_field_message(std::string const& name)
|
||||
{
|
||||
return "Invalid field '" + name + "', not object.";
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
object_field_error(std::string const& name)
|
||||
{
|
||||
return make_param_error(object_field_message(name));
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
object_field_error(Json::StaticString name)
|
||||
{
|
||||
return object_field_error(std::string(name));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
invalid_field_message(std::string const& name)
|
||||
{
|
||||
return "Invalid field '" + name + "'.";
|
||||
}
|
||||
|
||||
inline std::string
|
||||
invalid_field_message(Json::StaticString name)
|
||||
{
|
||||
return invalid_field_message(std::string(name));
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
invalid_field_error(std::string const& name)
|
||||
{
|
||||
return make_param_error(invalid_field_message(name));
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
invalid_field_error(Json::StaticString name)
|
||||
{
|
||||
return invalid_field_error(std::string(name));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
expected_field_message(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)
|
||||
{
|
||||
return expected_field_message(std::string(name), type);
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
expected_field_error(std::string const& name, std::string const& type)
|
||||
{
|
||||
return make_param_error(expected_field_message(name, type));
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
expected_field_error(Json::StaticString name, std::string const& type)
|
||||
{
|
||||
return expected_field_error(std::string(name), type);
|
||||
}
|
||||
|
||||
inline Json::Value
|
||||
not_validator_error()
|
||||
{
|
||||
return make_param_error("not a validator");
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Returns `true` if the json contains an rpc error specification. */
|
||||
bool
|
||||
contains_error(Json::Value const& json);
|
||||
|
||||
/** Returns http status that corresponds to the error code. */
|
||||
int
|
||||
error_code_http_status(error_code_i code);
|
||||
|
||||
} // namespace RPC
|
||||
|
||||
/** Returns a single string with the contents of an RPC error. */
|
||||
std::string
|
||||
rpcErrorString(Json::Value const& jv);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
399
include/xrpl/protocol/Feature.h
Normal file
399
include/xrpl/protocol/Feature.h
Normal file
@@ -0,0 +1,399 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_FEATURE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_FEATURE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @page Feature How to add new features
|
||||
*
|
||||
* Steps required to add new features to the code:
|
||||
*
|
||||
* 1) In this file, increment `numFeatures` and add a uint256 declaration
|
||||
* for the feature at the bottom
|
||||
* 2) Add a uint256 definition for the feature to the corresponding source
|
||||
* file (Feature.cpp). Use `registerFeature` to create the feature with
|
||||
* the feature's name, `Supported::no`, and `VoteBehavior::DefaultNo`. This
|
||||
* should be the only place the feature's name appears in code as a string.
|
||||
* 3) Use the uint256 as the parameter to `view.rules.enabled()` to
|
||||
* control flow into new code that this feature limits.
|
||||
* 4) If the feature development is COMPLETE, and the feature is ready to be
|
||||
* SUPPORTED, change the `registerFeature` parameter to Supported::yes.
|
||||
* 5) When the feature is ready to be ENABLED, change the `registerFeature`
|
||||
* parameter to `VoteBehavior::DefaultYes`.
|
||||
* In general, any newly supported amendments (`Supported::yes`) should have
|
||||
* a `VoteBehavior::DefaultNo` for at least one full release cycle. High
|
||||
* priority bug fixes can be an exception to this rule of thumb.
|
||||
*
|
||||
* When a feature has been enabled for several years, the conditional code
|
||||
* may be removed, and the feature "retired". To retire a feature:
|
||||
* 1) Remove the uint256 declaration from this file.
|
||||
* 2) MOVE the uint256 definition in Feature.cpp to the "retired features"
|
||||
* section at the end of the file.
|
||||
* 3) CHANGE the name of the variable to start with "retired".
|
||||
* 4) CHANGE the parameters of the `registerFeature` call to `Supported::yes`
|
||||
* and `VoteBehavior::DefaultNo`.
|
||||
* The feature must remain registered and supported indefinitely because it
|
||||
* still exists in the ledger, but there is no need to vote for it because
|
||||
* there's nothing to vote for. If it is removed completely from the code, any
|
||||
* instances running that code will get amendment blocked. Removing the
|
||||
* feature from the ledger is beyond the scope of these instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ripple {
|
||||
|
||||
enum class VoteBehavior : int { Obsolete = -1, DefaultNo = 0, DefaultYes };
|
||||
enum class AmendmentSupport : int { Retired = -1, Supported = 0, Unsupported };
|
||||
|
||||
/** All amendments libxrpl knows about. */
|
||||
std::map<std::string, AmendmentSupport> const&
|
||||
allAmendments();
|
||||
|
||||
namespace detail {
|
||||
|
||||
// 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 = 99;
|
||||
|
||||
/** Amendments that this server supports and the default voting behavior.
|
||||
Whether they are enabled depends on the Rules defined in the validated
|
||||
ledger */
|
||||
std::map<std::string, VoteBehavior> const&
|
||||
supportedAmendments();
|
||||
|
||||
/** Amendments that this server won't vote for by default.
|
||||
|
||||
This function is only used in unit tests.
|
||||
*/
|
||||
std::size_t
|
||||
numDownVotedAmendments();
|
||||
|
||||
/** Amendments that this server will vote for by default.
|
||||
|
||||
This function is only used in unit tests.
|
||||
*/
|
||||
std::size_t
|
||||
numUpVotedAmendments();
|
||||
|
||||
} // namespace detail
|
||||
|
||||
std::optional<uint256>
|
||||
getRegisteredFeature(std::string const& name);
|
||||
|
||||
size_t
|
||||
featureToBitsetIndex(uint256 const& f);
|
||||
|
||||
uint256
|
||||
bitsetIndexToFeature(size_t i);
|
||||
|
||||
std::string
|
||||
featureToName(uint256 const& f);
|
||||
|
||||
class FeatureBitset : private std::bitset<detail::numFeatures>
|
||||
{
|
||||
using base = std::bitset<detail::numFeatures>;
|
||||
|
||||
template <class... Fs>
|
||||
void
|
||||
initFromFeatures(uint256 const& f, Fs&&... fs)
|
||||
{
|
||||
set(f);
|
||||
if constexpr (sizeof...(fs) > 0)
|
||||
initFromFeatures(std::forward<Fs>(fs)...);
|
||||
}
|
||||
|
||||
public:
|
||||
using base::bitset;
|
||||
using base::operator==;
|
||||
|
||||
using base::all;
|
||||
using base::any;
|
||||
using base::count;
|
||||
using base::flip;
|
||||
using base::none;
|
||||
using base::reset;
|
||||
using base::set;
|
||||
using base::size;
|
||||
using base::test;
|
||||
using base::operator[];
|
||||
using base::to_string;
|
||||
using base::to_ullong;
|
||||
using base::to_ulong;
|
||||
|
||||
FeatureBitset() = default;
|
||||
|
||||
explicit FeatureBitset(base const& b) : base(b)
|
||||
{
|
||||
assert(b.count() == count());
|
||||
}
|
||||
|
||||
template <class... Fs>
|
||||
explicit FeatureBitset(uint256 const& f, Fs&&... fs)
|
||||
{
|
||||
initFromFeatures(f, std::forward<Fs>(fs)...);
|
||||
assert(count() == (sizeof...(fs) + 1));
|
||||
}
|
||||
|
||||
template <class Col>
|
||||
explicit FeatureBitset(Col const& fs)
|
||||
{
|
||||
for (auto const& f : fs)
|
||||
set(featureToBitsetIndex(f));
|
||||
assert(fs.size() == count());
|
||||
}
|
||||
|
||||
auto
|
||||
operator[](uint256 const& f)
|
||||
{
|
||||
return base::operator[](featureToBitsetIndex(f));
|
||||
}
|
||||
|
||||
auto
|
||||
operator[](uint256 const& f) const
|
||||
{
|
||||
return base::operator[](featureToBitsetIndex(f));
|
||||
}
|
||||
|
||||
FeatureBitset&
|
||||
set(uint256 const& f, bool value = true)
|
||||
{
|
||||
base::set(featureToBitsetIndex(f), value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FeatureBitset&
|
||||
reset(uint256 const& f)
|
||||
{
|
||||
base::reset(featureToBitsetIndex(f));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FeatureBitset&
|
||||
flip(uint256 const& f)
|
||||
{
|
||||
base::flip(featureToBitsetIndex(f));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FeatureBitset&
|
||||
operator&=(FeatureBitset const& rhs)
|
||||
{
|
||||
base::operator&=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FeatureBitset&
|
||||
operator|=(FeatureBitset const& rhs)
|
||||
{
|
||||
base::operator|=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FeatureBitset
|
||||
operator~() const
|
||||
{
|
||||
return FeatureBitset{base::operator~()};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator&(FeatureBitset const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{
|
||||
static_cast<base const&>(lhs) & static_cast<base const&>(rhs)};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator&(FeatureBitset const& lhs, uint256 const& rhs)
|
||||
{
|
||||
return lhs & FeatureBitset{rhs};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator&(uint256 const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{lhs} & rhs;
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator|(FeatureBitset const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{
|
||||
static_cast<base const&>(lhs) | static_cast<base const&>(rhs)};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator|(FeatureBitset const& lhs, uint256 const& rhs)
|
||||
{
|
||||
return lhs | FeatureBitset{rhs};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator|(uint256 const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{lhs} | rhs;
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator^(FeatureBitset const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{
|
||||
static_cast<base const&>(lhs) ^ static_cast<base const&>(rhs)};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator^(FeatureBitset const& lhs, uint256 const& rhs)
|
||||
{
|
||||
return lhs ^ FeatureBitset { rhs };
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator^(uint256 const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{lhs} ^ rhs;
|
||||
}
|
||||
|
||||
// set difference
|
||||
friend FeatureBitset
|
||||
operator-(FeatureBitset const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return lhs & ~rhs;
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator-(FeatureBitset const& lhs, uint256 const& rhs)
|
||||
{
|
||||
return lhs - FeatureBitset{rhs};
|
||||
}
|
||||
|
||||
friend FeatureBitset
|
||||
operator-(uint256 const& lhs, FeatureBitset const& rhs)
|
||||
{
|
||||
return FeatureBitset{lhs} - rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <class F>
|
||||
void
|
||||
foreachFeature(FeatureBitset bs, F&& f)
|
||||
{
|
||||
for (size_t i = 0; i < bs.size(); ++i)
|
||||
if (bs[i])
|
||||
f(bitsetIndexToFeature(i));
|
||||
}
|
||||
|
||||
extern uint256 const featureOwnerPaysFee;
|
||||
extern uint256 const featureFlow;
|
||||
extern uint256 const featureFlowCross;
|
||||
extern uint256 const featureCryptoConditionsSuite;
|
||||
extern uint256 const fix1513;
|
||||
extern uint256 const featureDepositAuth;
|
||||
extern uint256 const featureChecks;
|
||||
extern uint256 const fix1571;
|
||||
extern uint256 const fix1543;
|
||||
extern uint256 const fix1623;
|
||||
extern uint256 const featureDepositPreauth;
|
||||
extern uint256 const fix1515;
|
||||
extern uint256 const fix1578;
|
||||
extern uint256 const featureMultiSignReserve;
|
||||
extern uint256 const fixTakerDryOfferRemoval;
|
||||
extern uint256 const fixMasterKeyAsRegularKey;
|
||||
extern uint256 const fixCheckThreading;
|
||||
extern uint256 const fixPayChanRecipientOwnerDir;
|
||||
extern uint256 const featureDeletableAccounts;
|
||||
extern uint256 const fixQualityUpperBound;
|
||||
extern uint256 const featureRequireFullyCanonicalSig;
|
||||
extern uint256 const fix1781;
|
||||
extern uint256 const featureHardenedValidations;
|
||||
extern uint256 const fixAmendmentMajorityCalc;
|
||||
extern uint256 const featureNegativeUNL;
|
||||
extern uint256 const featureTicketBatch;
|
||||
extern uint256 const featureFlowSortStrands;
|
||||
extern uint256 const fixSTAmountCanonicalize;
|
||||
extern uint256 const fixRmSmallIncreasedQOffers;
|
||||
extern uint256 const featureCheckCashMakesTrustLine;
|
||||
extern uint256 const featureHooks;
|
||||
extern uint256 const featureExpandedSignerList;
|
||||
extern uint256 const featureNonFungibleTokensV1;
|
||||
extern uint256 const fixNFTokenDirV1;
|
||||
extern uint256 const fixNFTokenNegOffer;
|
||||
extern uint256 const featureNonFungibleTokensV1_1;
|
||||
extern uint256 const fixTrustLinesToSelf;
|
||||
extern uint256 const featureBalanceRewards;
|
||||
extern uint256 const featureDisallowIncoming;
|
||||
extern uint256 const fixRemoveNFTokenAutoTrustLine;
|
||||
extern uint256 const featureImmediateOfferKilled;
|
||||
extern uint256 const featureDisallowIncoming;
|
||||
extern uint256 const featurePaychanAndEscrowForTokens;
|
||||
extern uint256 const featureURIToken;
|
||||
extern uint256 const featureXRPFees;
|
||||
extern uint256 const fixUniversalNumber;
|
||||
extern uint256 const fixNonFungibleTokensV1_2;
|
||||
extern uint256 const fixNFTokenRemint;
|
||||
extern uint256 const featureImport;
|
||||
extern uint256 const featureXahauGenesis;
|
||||
extern uint256 const featureHooksUpdate1;
|
||||
extern uint256 const fixXahauV1;
|
||||
extern uint256 const fixXahauV2;
|
||||
extern uint256 const featureRemit;
|
||||
extern uint256 const featureZeroB2M;
|
||||
extern uint256 const fixNSDelete;
|
||||
extern uint256 const fix240819;
|
||||
extern uint256 const fixPageCap;
|
||||
extern uint256 const fix240911;
|
||||
extern uint256 const fixFloatDivide;
|
||||
extern uint256 const featureRemarks;
|
||||
extern uint256 const featureTouch;
|
||||
extern uint256 const fixReduceImport;
|
||||
extern uint256 const fixXahauV3;
|
||||
extern uint256 const fix20250131;
|
||||
extern uint256 const featureHookCanEmit;
|
||||
extern uint256 const fixRewardClaimFlags;
|
||||
extern uint256 const fixReducedOffersV1;
|
||||
extern uint256 const featureClawback;
|
||||
extern uint256 const featureAMM;
|
||||
extern uint256 const featureXChainBridge;
|
||||
extern uint256 const fixDisallowIncomingV1;
|
||||
extern uint256 const featureDID;
|
||||
extern uint256 const fixFillOrKill;
|
||||
extern uint256 const fixNFTokenReserve;
|
||||
extern uint256 const fixInnerObjTemplate;
|
||||
extern uint256 const fixAMMOverflowOffer;
|
||||
extern uint256 const featurePriceOracle;
|
||||
extern uint256 const fixEmptyDID;
|
||||
extern uint256 const fixXChainRewardRounding;
|
||||
extern uint256 const fixPreviousTxnID;
|
||||
extern uint256 const fixAMMv1_1;
|
||||
extern uint256 const featureNFTokenMintOffer;
|
||||
extern uint256 const fixReducedOffersV2;
|
||||
extern uint256 const fixEnforceNFTokenTrustline;
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
57
include/xrpl/protocol/Fees.h
Normal file
57
include/xrpl/protocol/Fees.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_FEES_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_FEES_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Reflects the fee settings for a particular ledger.
|
||||
|
||||
The fees are always the same for any transactions applied
|
||||
to a ledger. Changes to fees occur in between ledgers.
|
||||
*/
|
||||
struct Fees
|
||||
{
|
||||
XRPAmount base{0}; // Reference tx cost (drops)
|
||||
XRPAmount reserve{0}; // Reserve base (drops)
|
||||
XRPAmount increment{0}; // Reserve increment (drops)
|
||||
|
||||
explicit Fees() = default;
|
||||
Fees(Fees const&) = default;
|
||||
Fees&
|
||||
operator=(Fees const&) = default;
|
||||
|
||||
/** Returns the account reserve given the owner count, in drops.
|
||||
|
||||
The reserve is calculated as the reserve base plus
|
||||
the reserve increment times the number of increments.
|
||||
*/
|
||||
XRPAmount
|
||||
accountReserve(std::size_t ownerCount) const
|
||||
{
|
||||
return reserve + ownerCount * increment;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
111
include/xrpl/protocol/HashPrefix.h
Normal file
111
include/xrpl/protocol/HashPrefix.h
Normal file
@@ -0,0 +1,111 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_HASHPREFIX_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_HASHPREFIX_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail {
|
||||
|
||||
constexpr std::uint32_t
|
||||
make_hash_prefix(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);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** Prefix for hashing functions.
|
||||
|
||||
These prefixes are inserted before the source material used to generate
|
||||
various hashes. This is done to put each hash in its own "space." This way,
|
||||
two different types of objects with the same binary data will produce
|
||||
different hashes.
|
||||
|
||||
Each prefix is a 4-byte value with the last byte set to zero and the first
|
||||
three bytes formed from the ASCII equivalent of some arbitrary string. For
|
||||
example "TXN".
|
||||
|
||||
@note Hash prefixes are part of the protocol; you cannot, arbitrarily,
|
||||
change the type or the value of any of these without causing breakage.
|
||||
*/
|
||||
enum class HashPrefix : std::uint32_t {
|
||||
/** transaction plus signature to give transaction ID */
|
||||
transactionID = detail::make_hash_prefix('T', 'X', 'N'),
|
||||
|
||||
/** transaction plus metadata */
|
||||
txNode = detail::make_hash_prefix('S', 'N', 'D'),
|
||||
|
||||
/** account state */
|
||||
leafNode = detail::make_hash_prefix('M', 'L', 'N'),
|
||||
|
||||
/** inner node in V1 tree */
|
||||
innerNode = detail::make_hash_prefix('M', 'I', 'N'),
|
||||
|
||||
/** ledger master data for signing */
|
||||
ledgerMaster = detail::make_hash_prefix('L', 'W', 'R'),
|
||||
|
||||
/** inner transaction to sign */
|
||||
txSign = detail::make_hash_prefix('S', 'T', 'X'),
|
||||
|
||||
/** inner transaction to multi-sign */
|
||||
txMultiSign = detail::make_hash_prefix('S', 'M', 'T'),
|
||||
|
||||
/** validation for signing */
|
||||
validation = detail::make_hash_prefix('V', 'A', 'L'),
|
||||
|
||||
/** proposal for signing */
|
||||
proposal = detail::make_hash_prefix('P', 'R', 'P'),
|
||||
|
||||
/** Manifest */
|
||||
manifest = detail::make_hash_prefix('M', 'A', 'N'),
|
||||
|
||||
/** Payment Channel Claim */
|
||||
paymentChannelClaim = detail::make_hash_prefix('C', 'L', 'M'),
|
||||
|
||||
/** shard info for signing */
|
||||
shardInfo = detail::make_hash_prefix('S', 'H', 'D'),
|
||||
|
||||
/** Emit Transaction Nonce */
|
||||
emitTxnNonce = detail::make_hash_prefix('E', 'T', 'X'),
|
||||
|
||||
/** Random entropy for hook developers to use */
|
||||
hookNonce = detail::make_hash_prefix('N', 'C', 'E'),
|
||||
|
||||
/* Hash of a Hook's actual code */
|
||||
hookDefinition = detail::make_hash_prefix('W', 'S', 'M')
|
||||
};
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, HashPrefix const& hp) noexcept
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append(h, static_cast<std::uint32_t>(hp));
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
470
include/xrpl/protocol/Import.h
Normal file
470
include/xrpl/protocol/Import.h
Normal file
@@ -0,0 +1,470 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_IMPORT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_IMPORT_H_INCLUDED
|
||||
|
||||
// #include <ripple/basics/Log.h>
|
||||
#include <ripple/app/misc/Manifest.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/base64.h>
|
||||
#include <ripple/json/json_reader.h>
|
||||
#include <charconv>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
inline bool
|
||||
isHex(std::string const& str)
|
||||
{
|
||||
return str.find_first_not_of("0123456789abcdefABCDEF") == std::string::npos;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isBase58(std::string const& str)
|
||||
{
|
||||
return str.find_first_not_of(
|
||||
"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz") ==
|
||||
std::string::npos;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isBase64(std::string const& str)
|
||||
{
|
||||
return str.find_first_not_of(
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+"
|
||||
"/=") == std::string::npos;
|
||||
}
|
||||
|
||||
inline std::optional<uint64_t>
|
||||
parse_uint64(std::string const& str)
|
||||
{
|
||||
uint64_t result;
|
||||
auto [ptr, ec] =
|
||||
std::from_chars(str.data(), str.data() + str.size(), result);
|
||||
|
||||
if (ec == std::errc())
|
||||
return result;
|
||||
return {};
|
||||
}
|
||||
|
||||
inline bool
|
||||
syntaxCheckProof(
|
||||
Json::Value const& proof,
|
||||
beast::Journal const& j,
|
||||
int depth = 0)
|
||||
{
|
||||
if (depth > 64)
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.transaction.proof list should be less than 64 entries";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (proof.isArray())
|
||||
{
|
||||
// List form
|
||||
if (proof.size() != 16)
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.transaction.proof list should be exactly 16 entries";
|
||||
return false;
|
||||
}
|
||||
for (const auto& entry : proof)
|
||||
{
|
||||
if (entry.isString())
|
||||
{
|
||||
if (!isHex(entry.asString()) || entry.asString().size() != 64)
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.transaction.proof list entry missing "
|
||||
"or wrong format "
|
||||
<< "(should be hex string with 64 characters)";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (entry.isArray())
|
||||
{
|
||||
if (!syntaxCheckProof(entry, j, depth + 1))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.transaction.proof list entry has wrong format";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (proof.isObject())
|
||||
{
|
||||
// Tree form
|
||||
if (depth == 0) // root is special case
|
||||
{
|
||||
if (!proof["hash"].isString() ||
|
||||
proof["hash"].asString().size() != 64 ||
|
||||
!proof["key"].isString() ||
|
||||
proof["key"].asString().size() != 64 ||
|
||||
!proof["children"].isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction.proof tree node has wrong "
|
||||
"format (root)";
|
||||
return false;
|
||||
}
|
||||
|
||||
return syntaxCheckProof(proof["children"], j, depth + 1);
|
||||
}
|
||||
|
||||
for (const auto& branch : proof.getMemberNames())
|
||||
{
|
||||
if (branch.size() != 1 || !isHex(branch))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.transaction.proof child node was not 0-F "
|
||||
"hex nibble";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& node = proof[branch];
|
||||
if (!node.isObject() || !node["hash"].isString() ||
|
||||
node["hash"].asString().size() != 64 ||
|
||||
!node["key"].isString() ||
|
||||
node["key"].asString().size() != 64 ||
|
||||
!node["children"].isObject())
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.transaction.proof tree node has wrong format";
|
||||
return false;
|
||||
}
|
||||
if (!syntaxCheckProof(node["children"], j, depth + 1))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction.proof bad children format";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction.proof has wrong format (should be "
|
||||
"array or object)";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// does not check signature etc
|
||||
inline std::optional<Json::Value>
|
||||
syntaxCheckXPOP(Blob const& blob, beast::Journal const& j)
|
||||
{
|
||||
if (blob.empty())
|
||||
return {};
|
||||
|
||||
std::string strJson(blob.begin(), blob.end());
|
||||
if (strJson.empty())
|
||||
return {};
|
||||
|
||||
try
|
||||
{
|
||||
Json::Value xpop;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(strJson, xpop))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP failed to parse string json";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop.isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP is not a JSON object";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"].isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger is not a JSON object";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["transaction"].isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction is not a JSON object";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["validation"].isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation is not a JSON object";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["acroot"].isString() ||
|
||||
xpop["ledger"]["acroot"].asString().size() != 64 ||
|
||||
!isHex(xpop["ledger"]["acroot"].asString()))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.ledger.acroot missing or wrong format (should "
|
||||
"be hex string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["txroot"].isString() ||
|
||||
xpop["ledger"]["txroot"].asString().size() != 64 ||
|
||||
!isHex(xpop["ledger"]["txroot"].asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.txroot missing or wrong format "
|
||||
"(should be hex string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["phash"].isString() ||
|
||||
xpop["ledger"]["phash"].asString().size() != 64 ||
|
||||
!isHex(xpop["ledger"]["phash"].asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.phash missing or wrong format "
|
||||
"(should be hex string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["close"].isInt())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.close missing or wrong format "
|
||||
"(should be int)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (xpop["ledger"]["coins"].isInt())
|
||||
{
|
||||
// pass
|
||||
}
|
||||
else if (xpop["ledger"]["coins"].isString())
|
||||
{
|
||||
if (!parse_uint64(xpop["ledger"]["coins"].asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.coins missing or wrong format "
|
||||
"(should be int or string)";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.coins missing or wrong format "
|
||||
"(should be int or string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["cres"].isInt())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.cres missing or wrong format "
|
||||
"(should be int)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["index"].isInt())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.index missing or wrong format "
|
||||
"(should be int)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["flags"].isInt())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.flags missing or wrong format "
|
||||
"(should be int)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["ledger"]["pclose"].isInt())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.ledger.pclose missing or wrong format "
|
||||
"(should be int)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["transaction"]["blob"].isString() ||
|
||||
!isHex(xpop["transaction"]["blob"].asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction.blob missing or wrong format "
|
||||
"(should be hex string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["transaction"]["meta"].isString() ||
|
||||
!isHex(xpop["transaction"]["meta"].asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction.meta missing or wrong format "
|
||||
"(should be hex string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!syntaxCheckProof(xpop["transaction"]["proof"], j))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.transaction.proof failed syntax check "
|
||||
"(tree/list form)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["validation"]["data"].isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation.data missing or wrong format "
|
||||
"(should be JSON object)";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!xpop["validation"]["unl"].isObject())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation.unl missing or wrong format "
|
||||
"(should be JSON object)";
|
||||
return {};
|
||||
}
|
||||
|
||||
for (const auto& key : xpop["validation"]["data"].getMemberNames())
|
||||
{
|
||||
const auto& value = xpop["validation"]["data"][key];
|
||||
if (!isBase58(key) || !value.isString() || !isHex(value.asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation.data entry has wrong format "
|
||||
<< "(key should be base58 string and value "
|
||||
"should be hex string)";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t found = 0;
|
||||
for (const auto& key : xpop["validation"]["unl"].getMemberNames())
|
||||
{
|
||||
const auto& value = xpop["validation"]["unl"][key];
|
||||
if (key == "public_key")
|
||||
{
|
||||
if (!value.isString() || !isHex(value.asString()))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.validation.unl.public_key missing or "
|
||||
"wrong format (should be hex string)";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pk = strUnHex(value.asString());
|
||||
|
||||
if (!publicKeyType(makeSlice(*pk)))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.validation.unl.public_key invalid key type.";
|
||||
return {};
|
||||
}
|
||||
found |= 1;
|
||||
}
|
||||
else if (key == "manifest")
|
||||
{
|
||||
if (!value.isString() || !isBase64(value.asString()))
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation.unl.manifest missing or "
|
||||
"wrong format (should be string)";
|
||||
return {};
|
||||
}
|
||||
found |= 2;
|
||||
}
|
||||
else if (key == "blob")
|
||||
{
|
||||
if (!value.isString() || !isBase64(value.asString()))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.validation.unl.blob missing or wrong "
|
||||
"format (should be base64 string)";
|
||||
return {};
|
||||
}
|
||||
found |= 4;
|
||||
}
|
||||
else if (key == "signature")
|
||||
{
|
||||
if (!value.isString() || !isHex(value.asString()))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.validation.unl.signature missing or wrong "
|
||||
"format (should be hex string)";
|
||||
return {};
|
||||
}
|
||||
found |= 8;
|
||||
}
|
||||
else if (key == "version")
|
||||
{
|
||||
if (!value.isInt())
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation.unl.version missing or "
|
||||
"wrong format (should be int)";
|
||||
return {};
|
||||
}
|
||||
found |= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!value.isObject() && !value.isString())
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "XPOP.validation.unl entry has wrong format";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found != 0b11111)
|
||||
{
|
||||
JLOG(j.warn()) << "XPOP.validation.unl entry has wrong format "
|
||||
"(missing field/s)";
|
||||
return {};
|
||||
}
|
||||
|
||||
return xpop;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
JLOG(j.warn()) << "An exception occurred during XPOP validation";
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// <sequence, master key>
|
||||
inline std::optional<std::pair<uint32_t, PublicKey>>
|
||||
getVLInfo(Json::Value const& xpop, beast::Journal const& j)
|
||||
{
|
||||
auto const data =
|
||||
base64_decode(xpop[jss::validation][jss::unl][jss::blob].asString());
|
||||
Json::Reader r;
|
||||
Json::Value list;
|
||||
if (!r.parse(data, list))
|
||||
{
|
||||
JLOG(j.warn())
|
||||
<< "Import: unl blob was not valid json (after base64 decoding)";
|
||||
return {};
|
||||
}
|
||||
auto const sequence = list[jss::sequence].asUInt();
|
||||
auto const m = deserializeManifest(base64_decode(
|
||||
xpop[jss::validation][jss::unl][jss::manifest].asString()));
|
||||
if (!m)
|
||||
{
|
||||
JLOG(j.warn()) << "Import: failed to deserialize manifest";
|
||||
return {};
|
||||
}
|
||||
return {{sequence, m->masterKey}};
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
345
include/xrpl/protocol/Indexes.h
Normal file
345
include/xrpl/protocol/Indexes.h
Normal file
@@ -0,0 +1,345 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_INDEXES_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_INDEXES_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/protocol/Book.h>
|
||||
#include <ripple/protocol/Keylet.h>
|
||||
#include <ripple/protocol/LedgerFormats.h>
|
||||
#include <ripple/protocol/Protocol.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/STXChainBridge.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
using UInt32or256 = std::variant<uint32_t, uint256>;
|
||||
|
||||
class SeqProxy;
|
||||
/** Keylet computation funclets.
|
||||
|
||||
Entries in the ledger are located using 256-bit locators. The locators are
|
||||
calculated using a wide range of parameters specific to the entry whose
|
||||
locator we are calculating (e.g. an account's locator is derived from the
|
||||
account's address, whereas the locator for an offer is derived from the
|
||||
account and the offer sequence.)
|
||||
|
||||
To enhance type safety during lookup and make the code more robust, we use
|
||||
keylets, which contain not only the locator of the object but also the type
|
||||
of the object being referenced.
|
||||
|
||||
These functions each return a type-specific keylet.
|
||||
*/
|
||||
namespace keylet {
|
||||
|
||||
/** The (fixed) index of the object containing the emitted txns for the ledger.
|
||||
*/
|
||||
Keylet const&
|
||||
emittedDir() noexcept;
|
||||
|
||||
Keylet
|
||||
emittedTxn(uint256 const& id) noexcept;
|
||||
|
||||
Keylet
|
||||
hookDefinition(uint256 const& hash) noexcept;
|
||||
|
||||
Keylet
|
||||
hook(AccountID const& id) noexcept;
|
||||
|
||||
Keylet
|
||||
hookState(AccountID const& id, uint256 const& key, uint256 const& ns) noexcept;
|
||||
|
||||
Keylet
|
||||
hookStateDir(AccountID const& id, uint256 const& ns) noexcept;
|
||||
|
||||
/** AccountID root */
|
||||
Keylet
|
||||
account(AccountID const& id) noexcept;
|
||||
|
||||
/** The index of the amendment table */
|
||||
Keylet const&
|
||||
amendments() noexcept;
|
||||
|
||||
/** Any item that can be in an owner dir. */
|
||||
Keylet
|
||||
child(uint256 const& key) noexcept;
|
||||
|
||||
/** The index of the "short" skip list
|
||||
|
||||
The "short" skip list is a node (at a fixed index) that holds the hashes
|
||||
of ledgers since the last flag ledger. It will contain, at most, 256 hashes.
|
||||
*/
|
||||
Keylet const&
|
||||
skip() noexcept;
|
||||
|
||||
/** The index of the long skip for a particular ledger range.
|
||||
|
||||
The "long" skip list is a node that holds the hashes of (up to) 256 flag
|
||||
ledgers.
|
||||
|
||||
It can be used to efficiently skip back to any ledger using only two hops:
|
||||
the first hop gets the "long" skip list for the ledger it wants to retrieve
|
||||
and uses it to get the hash of the flag ledger whose short skip list will
|
||||
contain the hash of the requested ledger.
|
||||
*/
|
||||
Keylet
|
||||
skip(LedgerIndex ledger) noexcept;
|
||||
|
||||
/** The (fixed) index of the object containing the ledger fees. */
|
||||
Keylet const&
|
||||
fees() noexcept;
|
||||
|
||||
/** The (fixed) index of the object containing the ledger negativeUNL. */
|
||||
Keylet const&
|
||||
negativeUNL() noexcept;
|
||||
|
||||
Keylet const&
|
||||
UNLReport() noexcept;
|
||||
|
||||
/** The beginning of an order book */
|
||||
struct book_t
|
||||
{
|
||||
explicit book_t() = default;
|
||||
|
||||
Keylet
|
||||
operator()(Book const& b) const;
|
||||
};
|
||||
static book_t const book{};
|
||||
|
||||
/** The index of a trust line for a given currency
|
||||
|
||||
Note that a trustline is *shared* between two accounts (commonly referred
|
||||
to as the issuer and the holder); if Alice sets up a trust line to Bob for
|
||||
BTC, and Bob trusts Alice for BTC, here is only a single BTC trust line
|
||||
between them.
|
||||
*/
|
||||
/** @{ */
|
||||
Keylet
|
||||
line(
|
||||
AccountID const& id0,
|
||||
AccountID const& id1,
|
||||
Currency const& currency) noexcept;
|
||||
|
||||
inline Keylet
|
||||
line(AccountID const& id, Issue const& issue) noexcept
|
||||
{
|
||||
return line(id, issue.account, issue.currency);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** An offer from an account */
|
||||
/** @{ */
|
||||
Keylet
|
||||
offer(AccountID const& id, UInt32or256 const& seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
offer(uint256 const& key) noexcept
|
||||
{
|
||||
return {ltOFFER, key};
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** The initial directory page for a specific quality */
|
||||
Keylet
|
||||
quality(Keylet const& k, std::uint64_t q) noexcept;
|
||||
|
||||
/** The directory for the next lower quality */
|
||||
struct next_t
|
||||
{
|
||||
explicit next_t() = default;
|
||||
|
||||
Keylet
|
||||
operator()(Keylet const& k) const;
|
||||
};
|
||||
static next_t const next{};
|
||||
|
||||
/** A ticket belonging to an account */
|
||||
struct ticket_t
|
||||
{
|
||||
explicit ticket_t() = default;
|
||||
|
||||
Keylet
|
||||
operator()(AccountID const& id, std::uint32_t ticketSeq) const;
|
||||
|
||||
Keylet
|
||||
operator()(AccountID const& id, SeqProxy ticketSeq) const;
|
||||
|
||||
Keylet
|
||||
operator()(uint256 const& key) const
|
||||
{
|
||||
return {ltTICKET, key};
|
||||
}
|
||||
};
|
||||
static ticket_t const ticket{};
|
||||
|
||||
/** A SignerList */
|
||||
Keylet
|
||||
signers(AccountID const& account) noexcept;
|
||||
|
||||
/** A Check */
|
||||
/** @{ */
|
||||
Keylet
|
||||
check(AccountID const& id, UInt32or256 const& seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
check(uint256 const& key) noexcept
|
||||
{
|
||||
return {ltCHECK, key};
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** A DepositPreauth */
|
||||
/** @{ */
|
||||
Keylet
|
||||
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept;
|
||||
|
||||
inline Keylet
|
||||
depositPreauth(uint256 const& key) noexcept
|
||||
{
|
||||
return {ltDEPOSIT_PREAUTH, key};
|
||||
}
|
||||
/** @} */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Any ledger entry */
|
||||
Keylet
|
||||
unchecked(uint256 const& key) noexcept;
|
||||
|
||||
/** The root page of an account's directory */
|
||||
Keylet
|
||||
ownerDir(AccountID const& id) noexcept;
|
||||
|
||||
/** A page in a directory */
|
||||
/** @{ */
|
||||
Keylet
|
||||
page(uint256 const& root, std::uint64_t index = 0) noexcept;
|
||||
|
||||
inline Keylet
|
||||
page(Keylet const& root, std::uint64_t index = 0) noexcept
|
||||
{
|
||||
assert(root.type == ltDIR_NODE);
|
||||
return page(root.key, index);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** An escrow entry */
|
||||
Keylet
|
||||
escrow(AccountID const& src, UInt32or256 const& seq) noexcept;
|
||||
|
||||
/** A PaymentChannel */
|
||||
Keylet
|
||||
payChan(
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
UInt32or256 const& seq) noexcept;
|
||||
|
||||
/** NFT page keylets
|
||||
|
||||
Unlike objects whose ledger identifiers are produced by hashing data,
|
||||
NFT page identifiers are composite identifiers, consisting of the owner's
|
||||
160-bit AccountID, followed by a 96-bit value that determines which NFT
|
||||
tokens are candidates for that page.
|
||||
*/
|
||||
/** @{ */
|
||||
/** A keylet for the owner's first possible NFT page. */
|
||||
Keylet
|
||||
nftpage_min(AccountID const& owner);
|
||||
|
||||
/** A keylet for the owner's last possible NFT page. */
|
||||
Keylet
|
||||
nftpage_max(AccountID const& owner);
|
||||
|
||||
Keylet
|
||||
nftpage(Keylet const& k, uint256 const& token);
|
||||
/** @} */
|
||||
|
||||
/** An offer from an account to buy or sell an NFT */
|
||||
Keylet
|
||||
nftoffer(AccountID const& owner, UInt32or256 const& seq);
|
||||
|
||||
inline Keylet
|
||||
nftoffer(uint256 const& offer)
|
||||
{
|
||||
return {ltNFTOKEN_OFFER, offer};
|
||||
}
|
||||
|
||||
/** The directory of buy offers for the specified NFT */
|
||||
Keylet
|
||||
nft_buys(uint256 const& id) noexcept;
|
||||
|
||||
/** The directory of sell offers for the specified NFT */
|
||||
Keylet
|
||||
nft_sells(uint256 const& id) noexcept;
|
||||
|
||||
Keylet
|
||||
import_vlseq(PublicKey const& key) noexcept;
|
||||
|
||||
Keylet
|
||||
uritoken(AccountID const& issuer, Blob const& uri);
|
||||
|
||||
/** AMM entry */
|
||||
Keylet
|
||||
amm(Issue const& issue1, Issue const& issue2) noexcept;
|
||||
|
||||
Keylet
|
||||
amm(uint256 const& amm) noexcept;
|
||||
|
||||
Keylet
|
||||
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
|
||||
|
||||
Keylet
|
||||
xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq);
|
||||
|
||||
Keylet
|
||||
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq);
|
||||
|
||||
Keylet
|
||||
did(AccountID const& account) noexcept;
|
||||
|
||||
Keylet
|
||||
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept;
|
||||
|
||||
} // namespace keylet
|
||||
|
||||
// Everything below is deprecated and should be removed in favor of keylets:
|
||||
|
||||
uint256
|
||||
getBookBase(Book const& book);
|
||||
|
||||
uint256
|
||||
getQualityNext(uint256 const& uBase);
|
||||
|
||||
// VFALCO This name could be better
|
||||
std::uint64_t
|
||||
getQuality(uint256 const& uBase);
|
||||
|
||||
uint256
|
||||
getTicketIndex(AccountID const& account, std::uint32_t uSequence);
|
||||
|
||||
uint256
|
||||
getTicketIndex(AccountID const& account, SeqProxy ticketSeq);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
47
include/xrpl/protocol/InnerObjectFormats.h
Normal file
47
include/xrpl/protocol/InnerObjectFormats.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_INNER_OBJECT_FORMATS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_INNER_OBJECT_FORMATS_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/KnownFormats.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Manages the list of known inner object formats.
|
||||
*/
|
||||
class InnerObjectFormats : public KnownFormats<int, InnerObjectFormats>
|
||||
{
|
||||
private:
|
||||
/** Create the object.
|
||||
This will load the object with all the known inner object formats.
|
||||
*/
|
||||
InnerObjectFormats();
|
||||
|
||||
public:
|
||||
static InnerObjectFormats const&
|
||||
getInstance();
|
||||
|
||||
SOTemplate const*
|
||||
findSOTemplateBySField(SField const& sField) const;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
121
include/xrpl/protocol/Issue.h
Normal file
121
include/xrpl/protocol/Issue.h
Normal file
@@ -0,0 +1,121 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
|
||||
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** A currency issued by an account.
|
||||
@see Currency, AccountID, Issue, Book
|
||||
*/
|
||||
class Issue
|
||||
{
|
||||
public:
|
||||
Currency currency{};
|
||||
AccountID account{};
|
||||
|
||||
Issue()
|
||||
{
|
||||
}
|
||||
|
||||
Issue(Currency const& c, AccountID const& a) : currency(c), account(a)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
getText() const;
|
||||
};
|
||||
|
||||
bool
|
||||
isConsistent(Issue const& ac);
|
||||
|
||||
std::string
|
||||
to_string(Issue const& ac);
|
||||
|
||||
Json::Value
|
||||
to_json(Issue const& is);
|
||||
|
||||
Issue
|
||||
issueFromJson(Json::Value const& v);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, Issue const& x);
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, Issue const& r)
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append(h, r.currency, r.account);
|
||||
}
|
||||
|
||||
/** Equality comparison. */
|
||||
/** @{ */
|
||||
[[nodiscard]] inline constexpr bool
|
||||
operator==(Issue const& lhs, Issue const& rhs)
|
||||
{
|
||||
return (lhs.currency == rhs.currency) &&
|
||||
(isXRP(lhs.currency) || lhs.account == rhs.account);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Strict weak ordering. */
|
||||
/** @{ */
|
||||
[[nodiscard]] inline constexpr std::weak_ordering
|
||||
operator<=>(Issue const& lhs, Issue const& rhs)
|
||||
{
|
||||
if (auto const c{lhs.currency <=> rhs.currency}; c != 0)
|
||||
return c;
|
||||
|
||||
if (isXRP(lhs.currency))
|
||||
return std::weak_ordering::equivalent;
|
||||
|
||||
return (lhs.account <=> rhs.account);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Returns an asset specifier that represents XRP. */
|
||||
inline Issue const&
|
||||
xrpIssue()
|
||||
{
|
||||
static Issue issue{xrpCurrency(), xrpAccount()};
|
||||
return issue;
|
||||
}
|
||||
|
||||
/** Returns an asset specifier that represents no account and currency. */
|
||||
inline Issue const&
|
||||
noIssue()
|
||||
{
|
||||
static Issue issue{noCurrency(), noAccount()};
|
||||
return issue;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
66
include/xrpl/protocol/KeyType.h
Normal file
66
include/xrpl/protocol/KeyType.h
Normal file
@@ -0,0 +1,66 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_KEYTYPE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_KEYTYPE_H_INCLUDED
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
enum class KeyType {
|
||||
secp256k1 = 0,
|
||||
ed25519 = 1,
|
||||
};
|
||||
|
||||
inline std::optional<KeyType>
|
||||
keyTypeFromString(std::string const& s)
|
||||
{
|
||||
if (s == "secp256k1")
|
||||
return KeyType::secp256k1;
|
||||
|
||||
if (s == "ed25519")
|
||||
return KeyType::ed25519;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
inline char const*
|
||||
to_string(KeyType type)
|
||||
{
|
||||
if (type == KeyType::secp256k1)
|
||||
return "secp256k1";
|
||||
|
||||
if (type == KeyType::ed25519)
|
||||
return "ed25519";
|
||||
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
template <class Stream>
|
||||
inline Stream&
|
||||
operator<<(Stream& s, KeyType type)
|
||||
{
|
||||
return s << to_string(type);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
54
include/xrpl/protocol/Keylet.h
Normal file
54
include/xrpl/protocol/Keylet.h
Normal file
@@ -0,0 +1,54 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_KEYLET_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_KEYLET_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/protocol/LedgerFormats.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class STLedgerEntry;
|
||||
|
||||
/** A pair of SHAMap key and LedgerEntryType.
|
||||
|
||||
A Keylet identifies both a key in the state map
|
||||
and its ledger entry type.
|
||||
|
||||
@note Keylet is a portmanteau of the words key
|
||||
and LET, an acronym for LedgerEntryType.
|
||||
*/
|
||||
struct Keylet
|
||||
{
|
||||
uint256 key;
|
||||
LedgerEntryType type;
|
||||
|
||||
Keylet(LedgerEntryType type_, uint256 const& key_) : key(key_), type(type_)
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns true if the SLE matches the type */
|
||||
bool
|
||||
check(STLedgerEntry const&) const;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
205
include/xrpl/protocol/KnownFormats.h
Normal file
205
include/xrpl/protocol/KnownFormats.h
Normal file
@@ -0,0 +1,205 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_KNOWNFORMATS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_KNOWNFORMATS_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/beast/type_name.h>
|
||||
#include <ripple/protocol/SOTemplate.h>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <algorithm>
|
||||
#include <forward_list>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Manages a list of known formats.
|
||||
|
||||
Each format has a name, an associated KeyType (typically an enumeration),
|
||||
and a predefined @ref SOElement.
|
||||
|
||||
@tparam KeyType The type of key identifying the format.
|
||||
*/
|
||||
template <class KeyType, class Derived>
|
||||
class KnownFormats
|
||||
{
|
||||
public:
|
||||
/** A known format.
|
||||
*/
|
||||
class Item
|
||||
{
|
||||
public:
|
||||
Item(
|
||||
char const* name,
|
||||
KeyType type,
|
||||
std::initializer_list<SOElement> uniqueFields,
|
||||
std::initializer_list<SOElement> commonFields)
|
||||
: soTemplate_(uniqueFields, commonFields), name_(name), type_(type)
|
||||
{
|
||||
// Verify that KeyType is appropriate.
|
||||
static_assert(
|
||||
std::is_enum<KeyType>::value ||
|
||||
std::is_integral<KeyType>::value,
|
||||
"KnownFormats KeyType must be integral or enum.");
|
||||
}
|
||||
|
||||
/** Retrieve the name of the format.
|
||||
*/
|
||||
std::string const&
|
||||
getName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
/** Retrieve the transaction type this format represents.
|
||||
*/
|
||||
KeyType
|
||||
getType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
SOTemplate const&
|
||||
getSOTemplate() const
|
||||
{
|
||||
return soTemplate_;
|
||||
}
|
||||
|
||||
private:
|
||||
SOTemplate soTemplate_;
|
||||
std::string const name_;
|
||||
KeyType const type_;
|
||||
};
|
||||
|
||||
/** Create the known formats object.
|
||||
|
||||
Derived classes will load the object with all the known formats.
|
||||
*/
|
||||
KnownFormats() : name_(beast::type_name<Derived>())
|
||||
{
|
||||
}
|
||||
|
||||
/** Destroy the known formats object.
|
||||
|
||||
The defined formats are deleted.
|
||||
*/
|
||||
virtual ~KnownFormats() = default;
|
||||
KnownFormats(KnownFormats const&) = delete;
|
||||
KnownFormats&
|
||||
operator=(KnownFormats const&) = delete;
|
||||
|
||||
/** Retrieve the type for a format specified by name.
|
||||
|
||||
If the format name is unknown, an exception is thrown.
|
||||
|
||||
@param name The name of the type.
|
||||
@return The type.
|
||||
*/
|
||||
KeyType
|
||||
findTypeByName(std::string const& name) const
|
||||
{
|
||||
if (auto const result = findByName(name))
|
||||
return result->getType();
|
||||
Throw<std::runtime_error>(
|
||||
name_ + ": Unknown format name '" +
|
||||
name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
|
||||
}
|
||||
|
||||
/** Retrieve a format based on its type.
|
||||
*/
|
||||
Item const*
|
||||
findByType(KeyType type) const
|
||||
{
|
||||
auto const itr = types_.find(type);
|
||||
if (itr == types_.end())
|
||||
return nullptr;
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
// begin() and end() are provided for testing purposes.
|
||||
typename std::forward_list<Item>::const_iterator
|
||||
begin() const
|
||||
{
|
||||
return formats_.begin();
|
||||
}
|
||||
|
||||
typename std::forward_list<Item>::const_iterator
|
||||
end() const
|
||||
{
|
||||
return formats_.end();
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Retrieve a format based on its name.
|
||||
*/
|
||||
Item const*
|
||||
findByName(std::string const& name) const
|
||||
{
|
||||
auto const itr = names_.find(name);
|
||||
if (itr == names_.end())
|
||||
return nullptr;
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
/** Add a new format.
|
||||
|
||||
@param name The name of this format.
|
||||
@param type The type of this format.
|
||||
@param uniqueFields An std::initializer_list of unique fields
|
||||
@param commonFields An std::initializer_list of common fields
|
||||
|
||||
@return The created format.
|
||||
*/
|
||||
Item const&
|
||||
add(char const* name,
|
||||
KeyType type,
|
||||
std::initializer_list<SOElement> uniqueFields,
|
||||
std::initializer_list<SOElement> commonFields = {})
|
||||
{
|
||||
if (auto const item = findByType(type))
|
||||
{
|
||||
LogicError(
|
||||
std::string("Duplicate key for item '") + name +
|
||||
"': already maps to " + item->getName());
|
||||
}
|
||||
|
||||
formats_.emplace_front(name, type, uniqueFields, commonFields);
|
||||
Item const& item{formats_.front()};
|
||||
|
||||
names_[name] = &item;
|
||||
types_[type] = &item;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
|
||||
// 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_;
|
||||
|
||||
boost::container::flat_map<std::string, Item const*> names_;
|
||||
boost::container::flat_map<KeyType, Item const*> types_;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
383
include/xrpl/protocol/LedgerFormats.h
Normal file
383
include/xrpl/protocol/LedgerFormats.h
Normal file
@@ -0,0 +1,383 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_LEDGERFORMATS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_LEDGERFORMATS_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/KnownFormats.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Identifiers for on-ledger objects.
|
||||
|
||||
Each ledger object requires a unique type identifier, which is stored
|
||||
within the object itself; this makes it possible to iterate the entire
|
||||
ledger and determine each object's type and verify that the object you
|
||||
retrieved from a given hash matches the expected type.
|
||||
|
||||
@warning Since these values are stored inside objects stored on the ledger
|
||||
they are part of the protocol. **Changing them should be avoided
|
||||
because without special handling, this will result in a hard
|
||||
fork.**
|
||||
|
||||
@note Values outside this range may be used internally by the code for
|
||||
various purposes, but attempting to use such values to identify
|
||||
on-ledger objects will results in an invariant failure.
|
||||
|
||||
@note When retiring types, the specific values should not be removed but
|
||||
should be marked as [[deprecated]]. This is to avoid accidental
|
||||
reuse of identifiers.
|
||||
|
||||
@todo The C++ language does not enable checking for duplicate values
|
||||
here. If it becomes possible then we should do this.
|
||||
|
||||
@ingroup protocol
|
||||
*/
|
||||
// clang-format off
|
||||
enum LedgerEntryType : std::uint16_t
|
||||
{
|
||||
/** A ledger object which describes an account.
|
||||
|
||||
\sa keylet::account
|
||||
*/
|
||||
ltACCOUNT_ROOT = 0x0061,
|
||||
|
||||
/** A ledger object which contains a list of object identifiers.
|
||||
|
||||
\sa keylet::page, keylet::quality, keylet::book, keylet::next and
|
||||
keylet::ownerDir
|
||||
*/
|
||||
ltDIR_NODE = 0x0064,
|
||||
|
||||
/** A ledger object which describes a bidirectional trust line.
|
||||
|
||||
@note Per Vinnie Falco this should be renamed to ltTRUST_LINE
|
||||
|
||||
\sa keylet::line
|
||||
*/
|
||||
ltRIPPLE_STATE = 0x0072,
|
||||
|
||||
/** A ledger object which describes a ticket.
|
||||
|
||||
\sa keylet::ticket
|
||||
*/
|
||||
ltTICKET = 0x0054,
|
||||
|
||||
/** A ledger object which contains a signer list for an account.
|
||||
|
||||
\sa keylet::signers
|
||||
*/
|
||||
ltSIGNER_LIST = 0x0053,
|
||||
|
||||
/** A ledger object which describes an offer on the DEX.
|
||||
|
||||
\sa keylet::offer
|
||||
*/
|
||||
ltOFFER = 0x006f,
|
||||
|
||||
|
||||
/** The ledger object which lists details about sidechains.
|
||||
|
||||
\sa keylet::bridge
|
||||
*/
|
||||
ltBRIDGE = 0x0069,
|
||||
|
||||
/** A ledger object that contains a list of ledger hashes.
|
||||
|
||||
This type is used to store the ledger hashes which the protocol uses
|
||||
to implement skip lists that allow for efficient backwards (and, in
|
||||
theory, forward) forward iteration across large ledger ranges.
|
||||
|
||||
\sa keylet::skip
|
||||
*/
|
||||
ltLEDGER_HASHES = 0x0068,
|
||||
|
||||
/** The ledger object which lists details about amendments on the network.
|
||||
|
||||
\note This is a singleton: only one such object exists in the ledger.
|
||||
|
||||
\sa keylet::amendments
|
||||
*/
|
||||
ltAMENDMENTS = 0x0066,
|
||||
|
||||
/** A claim id for a cross chain transaction.
|
||||
|
||||
\sa keylet::xChainClaimID
|
||||
*/
|
||||
ltXCHAIN_OWNED_CLAIM_ID = 0x0071,
|
||||
|
||||
/** A claim id for a cross chain create account transaction.
|
||||
|
||||
\sa keylet::xChainCreateAccountClaimID
|
||||
*/
|
||||
ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID = 0x0074,
|
||||
|
||||
/** The ledger object which lists the network's fee settings.
|
||||
|
||||
\note This is a singleton: only one such object exists in the ledger.
|
||||
|
||||
\sa keylet::fees
|
||||
*/
|
||||
ltFEE_SETTINGS = 0x0073,
|
||||
|
||||
/** The ledger object which records the last (and largest) sequence for a validator list key
|
||||
* as used in the Import amendment
|
||||
*/
|
||||
ltIMPORT_VLSEQ = 0x0049,
|
||||
|
||||
/** A ledger object describing a single escrow.
|
||||
|
||||
\sa keylet::escrow
|
||||
*/
|
||||
ltESCROW = 0x0075,
|
||||
|
||||
/** A ledger object describing a single unidirectional XRP payment channel.
|
||||
|
||||
\sa keylet::payChan
|
||||
*/
|
||||
ltPAYCHAN = 0x0078,
|
||||
|
||||
/** A ledger object which describes a check.
|
||||
|
||||
\sa keylet::check
|
||||
*/
|
||||
ltCHECK = 0x0043,
|
||||
|
||||
/** A ledger object which describes a deposit preauthorization.
|
||||
|
||||
\sa keylet::depositPreauth
|
||||
*/
|
||||
ltDEPOSIT_PREAUTH = 0x0070,
|
||||
|
||||
/** The ledger object which tracks the current negative UNL state.
|
||||
|
||||
\note This is a singleton: only one such object exists in the ledger.
|
||||
|
||||
\sa keylet::negativeUNL
|
||||
*/
|
||||
ltNEGATIVE_UNL = 0x004e,
|
||||
|
||||
/** A ledger object which contains a list of NFTs
|
||||
|
||||
\sa keylet::nftpage_min, keylet::nftpage_max, keylet::nftpage
|
||||
*/
|
||||
ltNFTOKEN_PAGE = 0x0050,
|
||||
|
||||
/** A ledger object which identifies an offer to buy or sell an NFT.
|
||||
|
||||
\sa keylet::nftoffer
|
||||
*/
|
||||
ltNFTOKEN_OFFER = 0x0037,
|
||||
|
||||
/** A unique ledger object which contains an up to 256 byte URI
|
||||
|
||||
\sa keylet::uritoken
|
||||
*/
|
||||
ltURI_TOKEN = 0x0055,
|
||||
|
||||
/** A ledger object that reports on the active dUNL validators
|
||||
* that were validating for more than 240 of the last 256 ledgers
|
||||
*
|
||||
* \sa keylet::UNLReport
|
||||
*/
|
||||
ltUNL_REPORT = 0x0052,
|
||||
|
||||
/** The ledger object which tracks the AMM.
|
||||
|
||||
\sa keylet::amm
|
||||
*/
|
||||
ltAMM = 0x0079,
|
||||
|
||||
/** The ledger object which tracks the DID.
|
||||
|
||||
\sa keylet::did
|
||||
*/
|
||||
ltDID = 0x4449,
|
||||
|
||||
/** A ledger object which tracks Oracle
|
||||
\sa keylet::oracle
|
||||
*/
|
||||
ltORACLE = 0x0080,
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** A special type, matching any ledger entry type.
|
||||
|
||||
The value does not represent a concrete type, but rather is used in
|
||||
contexts where the specific type of a ledger object is unimportant,
|
||||
unknown or unavailable.
|
||||
|
||||
Objects with this special type cannot be created or stored on the
|
||||
ledger.
|
||||
|
||||
\sa keylet::unchecked
|
||||
*/
|
||||
ltANY = 0,
|
||||
|
||||
/** A special type, matching any ledger type except directory nodes.
|
||||
|
||||
The value does not represent a concrete type, but rather is used in
|
||||
contexts where the ledger object must not be a directory node but
|
||||
its specific type is otherwise unimportant, unknown or unavailable.
|
||||
|
||||
Objects with this special type cannot be created or stored on the
|
||||
ledger.
|
||||
|
||||
\sa keylet::child
|
||||
*/
|
||||
ltCHILD = 0x1CD2,
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** A legacy, deprecated type.
|
||||
|
||||
\deprecated **This object type is not supported and should not be used.**
|
||||
Support for this type of object was never implemented.
|
||||
No objects of this type were ever created.
|
||||
*/
|
||||
ltNICKNAME [[deprecated("This object type is not supported and should not be used.")]] = 0x006e,
|
||||
|
||||
/** A legacy, deprecated type.
|
||||
|
||||
\deprecated **This object type is not supported and should not be used.**
|
||||
Support for this type of object was never implemented.
|
||||
No objects of this type were ever created.
|
||||
*/
|
||||
ltCONTRACT [[deprecated("This object type is not supported and should not be used.")]] = 0x0063,
|
||||
|
||||
|
||||
/** A legacy, deprecated type.
|
||||
\deprecated **This object type is not supported and should not be used.**
|
||||
Support for this type of object was never implemented.
|
||||
No objects of this type were ever created.
|
||||
*/
|
||||
ltGENERATOR_MAP [[deprecated("This object type is not supported and should not be used.")]] = 0x0067,
|
||||
|
||||
/** A ledger object which describes an installed hook on an account.
|
||||
|
||||
\sa keylet::hook
|
||||
*/
|
||||
ltHOOK ='H',
|
||||
|
||||
/** A ledger object which describes a stored value (from a k-v pair) for an installed hook.
|
||||
|
||||
\sa keylet::hookState
|
||||
*/
|
||||
ltHOOK_STATE ='v',
|
||||
|
||||
/** A reference-counted ledger object which stores the web assembly bytecode of a hook.
|
||||
|
||||
\sa keylet::hookDefinition
|
||||
*/
|
||||
ltHOOK_DEFINITION = 'D',
|
||||
|
||||
/** A ledger object containing a hook-emitted transaction from a previous hook execution.
|
||||
|
||||
\sa keylet::emitted
|
||||
*/
|
||||
ltEMITTED_TXN = 'E',
|
||||
};
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
@ingroup protocol
|
||||
*/
|
||||
enum LedgerSpecificFlags {
|
||||
// ltACCOUNT_ROOT
|
||||
lsfPasswordSpent = 0x00010000, // True, if password set fee is spent.
|
||||
lsfRequireDestTag =
|
||||
0x00020000, // True, to require a DestinationTag for payments.
|
||||
lsfRequireAuth =
|
||||
0x00040000, // True, to require a authorization to hold IOUs.
|
||||
lsfDisallowXRP = 0x00080000, // True, to disallow sending XRP.
|
||||
lsfDisableMaster = 0x00100000, // True, force regular key
|
||||
lsfNoFreeze = 0x00200000, // True, cannot freeze ripple states
|
||||
lsfGlobalFreeze = 0x00400000, // True, all assets frozen
|
||||
lsfDefaultRipple =
|
||||
0x00800000, // True, trust lines allow rippling by default
|
||||
lsfDepositAuth = 0x01000000, // True, all deposits require authorization
|
||||
lsfTshCollect = 0x02000000, // True, allow TSH collect-calls to acc hooks
|
||||
lsfDisallowIncomingNFTokenOffer =
|
||||
0x04000000, // True, reject new incoming NFT offers
|
||||
lsfDisallowIncomingCheck =
|
||||
0x08000000, // True, reject new checks
|
||||
lsfDisallowIncomingPayChan =
|
||||
0x10000000, // True, reject new paychans
|
||||
lsfDisallowIncomingTrustline =
|
||||
0x20000000, // True, reject new trustlines (only if no issued assets)
|
||||
lsfURITokenIssuer =
|
||||
0x40000000, // True, has minted tokens in the past
|
||||
lsfDisallowIncomingRemit = // True, no remits allowed to this account
|
||||
0x80000000,
|
||||
// 0x0004000 is available
|
||||
lsfAllowTrustLineClawback =
|
||||
0x00008000, // True, enable clawback
|
||||
|
||||
// ltOFFER
|
||||
lsfPassive = 0x00010000,
|
||||
lsfSell = 0x00020000, // True, offer was placed as a sell.
|
||||
|
||||
// ltRIPPLE_STATE
|
||||
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
|
||||
lsfHighReserve = 0x00020000,
|
||||
lsfLowAuth = 0x00040000,
|
||||
lsfHighAuth = 0x00080000,
|
||||
lsfLowNoRipple = 0x00100000,
|
||||
lsfHighNoRipple = 0x00200000,
|
||||
lsfLowFreeze = 0x00400000, // True, low side has set freeze flag
|
||||
lsfHighFreeze = 0x00800000, // True, high side has set freeze flag
|
||||
lsfAMMNode = 0x01000000, // True, trust line to AMM. Used by client
|
||||
// apps to identify payments via AMM.
|
||||
|
||||
// ltSIGNER_LIST
|
||||
lsfOneOwnerCount = 0x00010000, // True, uses only one OwnerCount
|
||||
|
||||
// ltDIR_NODE
|
||||
lsfNFTokenBuyOffers = 0x00000001,
|
||||
lsfNFTokenSellOffers = 0x00000002,
|
||||
lsfEmittedDir = 0x00000004,
|
||||
|
||||
// ltNFTOKEN_OFFER
|
||||
lsfSellNFToken = 0x00000001,
|
||||
|
||||
// ltURI_TOKEN
|
||||
lsfBurnable = 0x00000001, // True, issuer can burn the token
|
||||
|
||||
// remarks
|
||||
lsfImmutable = 1,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Holds the list of known ledger entry formats.
|
||||
*/
|
||||
class LedgerFormats : public KnownFormats<LedgerEntryType, LedgerFormats>
|
||||
{
|
||||
private:
|
||||
/** Create the object.
|
||||
This will load the object with all the known ledger formats.
|
||||
*/
|
||||
LedgerFormats();
|
||||
|
||||
public:
|
||||
static LedgerFormats const&
|
||||
getInstance();
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
103
include/xrpl/protocol/LedgerHeader.h
Normal file
103
include/xrpl/protocol/LedgerHeader.h
Normal file
@@ -0,0 +1,103 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_LEDGERHEADER_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_LEDGERHEADER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/protocol/Protocol.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Information about the notional ledger backing the view. */
|
||||
struct LedgerHeader
|
||||
{
|
||||
explicit LedgerHeader() = default;
|
||||
|
||||
//
|
||||
// For all ledgers
|
||||
//
|
||||
|
||||
LedgerIndex seq = 0;
|
||||
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;
|
||||
|
||||
XRPAmount drops = beast::zero;
|
||||
|
||||
// If validated is false, it means "not yet validated."
|
||||
// Once validated is true, it will never be set false at a later time.
|
||||
// VFALCO TODO Make this not mutable
|
||||
bool mutable validated = false;
|
||||
bool accepted = false;
|
||||
|
||||
// flags indicating how this ledger close took place
|
||||
int closeFlags = 0;
|
||||
|
||||
// the resolution for this ledger close time (2-120 seconds)
|
||||
NetClock::duration closeTimeResolution = {};
|
||||
|
||||
// For closed ledgers, the time the ledger
|
||||
// closed. For open ledgers, the time the ledger
|
||||
// will close if there's no transactions.
|
||||
//
|
||||
NetClock::time_point closeTime = {};
|
||||
};
|
||||
|
||||
// We call them "headers" in conversation
|
||||
// but "info" in code. Unintuitive.
|
||||
// This alias lets us give the "correct" name to the class
|
||||
// without yet disturbing existing uses.
|
||||
using LedgerInfo = LedgerHeader;
|
||||
|
||||
// ledger close flags
|
||||
static std::uint32_t const sLCF_NoConsensusTime = 0x01;
|
||||
|
||||
inline bool
|
||||
getCloseAgree(LedgerHeader const& info)
|
||||
{
|
||||
return (info.closeFlags & sLCF_NoConsensusTime) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
addRaw(LedgerHeader const&, Serializer&, bool includeHash = false);
|
||||
|
||||
/** Deserialize a ledger header from a byte array. */
|
||||
LedgerHeader
|
||||
deserializeHeader(Slice data, bool hasHash = false);
|
||||
|
||||
/** Deserialize a ledger header (prefixed with 4 bytes) from a byte array. */
|
||||
LedgerHeader
|
||||
deserializePrefixedHeader(Slice data, bool hasHash = false);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
247
include/xrpl/protocol/MultiApiJson.h
Normal file
247
include/xrpl/protocol/MultiApiJson.h
Normal file
@@ -0,0 +1,247 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_JSON_MULTIAPIJSON_H_INCLUDED
|
||||
#define RIPPLE_JSON_MULTIAPIJSON_H_INCLUDED
|
||||
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/ApiVersion.h>
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
constexpr bool is_integral_constant = false;
|
||||
template <typename I, auto A>
|
||||
constexpr bool is_integral_constant<std::integral_constant<I, A>&> = true;
|
||||
template <typename I, auto A>
|
||||
constexpr bool is_integral_constant<std::integral_constant<I, A> const&> = true;
|
||||
|
||||
template <typename T>
|
||||
concept some_integral_constant = detail::is_integral_constant<T&>;
|
||||
|
||||
// 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
|
||||
// at once with `isMember` and `set`, and also individual inspection and updates
|
||||
// of an object selected by the user by version, using `visitor_t` nested type.
|
||||
template <unsigned MinVer, unsigned MaxVer>
|
||||
struct MultiApiJson
|
||||
{
|
||||
static_assert(MinVer <= MaxVer);
|
||||
|
||||
static constexpr auto
|
||||
valid(unsigned int v) noexcept -> bool
|
||||
{
|
||||
return v >= MinVer && v <= MaxVer;
|
||||
}
|
||||
|
||||
static constexpr auto
|
||||
index(unsigned int v) noexcept -> std::size_t
|
||||
{
|
||||
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 = {};
|
||||
|
||||
explicit MultiApiJson(Json::Value const& init = {})
|
||||
{
|
||||
if (init == Json::Value{})
|
||||
return; // All elements are already default-initialized
|
||||
for (auto& v : val)
|
||||
v = init;
|
||||
}
|
||||
|
||||
void
|
||||
set(const char* key,
|
||||
auto const&
|
||||
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 };
|
||||
|
||||
[[nodiscard]] IsMemberResult
|
||||
isMember(const char* key) const
|
||||
{
|
||||
int count = 0;
|
||||
for (auto& a : this->val)
|
||||
if (a.isMember(key))
|
||||
count += 1;
|
||||
|
||||
return (count == 0 ? none : (count < size ? some : all));
|
||||
}
|
||||
|
||||
static constexpr struct visitor_t final
|
||||
{
|
||||
// integral_constant version, extra arguments
|
||||
template <
|
||||
typename Json,
|
||||
unsigned int Version,
|
||||
typename... Args,
|
||||
typename Fn>
|
||||
requires std::same_as<std::remove_cvref_t<Json>, MultiApiJson> auto
|
||||
operator()(
|
||||
Json& json,
|
||||
std::integral_constant<unsigned int, Version> const version,
|
||||
Fn fn,
|
||||
Args&&... args) const
|
||||
-> std::invoke_result_t<
|
||||
Fn,
|
||||
decltype(json.val[0]),
|
||||
std::integral_constant<unsigned int, Version>,
|
||||
Args&&...>
|
||||
{
|
||||
static_assert(
|
||||
valid(Version) && index(Version) >= 0 && index(Version) < size);
|
||||
return std::invoke(
|
||||
fn,
|
||||
json.val[index(Version)],
|
||||
version,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// integral_constant version, Json only
|
||||
template <typename Json, unsigned int Version, typename Fn>
|
||||
requires std::same_as<std::remove_cvref_t<Json>, MultiApiJson> auto
|
||||
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);
|
||||
return std::invoke(fn, json.val[index(Version)]);
|
||||
}
|
||||
|
||||
// unsigned int version, extra arguments
|
||||
template <
|
||||
typename Json,
|
||||
typename Version,
|
||||
typename... Args,
|
||||
typename Fn>
|
||||
requires(!some_integral_constant<Version>) &&
|
||||
std::convertible_to<Version, unsigned>&& std::same_as<
|
||||
std::remove_cvref_t<Json>,
|
||||
MultiApiJson> auto
|
||||
operator()(Json& json, Version version, Fn fn, Args&&... args) const
|
||||
-> std::
|
||||
invoke_result_t<Fn, decltype(json.val[0]), Version, Args&&...>
|
||||
{
|
||||
assert(
|
||||
valid(version) && index(version) >= 0 && index(version) < size);
|
||||
return std::invoke(
|
||||
fn,
|
||||
json.val[index(version)],
|
||||
version,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// unsigned int version, Json only
|
||||
template <typename Json, typename Version, typename Fn>
|
||||
requires(!some_integral_constant<Version>) &&
|
||||
std::convertible_to<Version, unsigned>&& std::
|
||||
same_as<std::remove_cvref_t<Json>, MultiApiJson> auto
|
||||
operator()(Json& json, Version version, Fn fn) const
|
||||
-> std::invoke_result_t<Fn, decltype(json.val[0])>
|
||||
{
|
||||
assert(
|
||||
valid(version) && index(version) >= 0 && index(version) < size);
|
||||
return std::invoke(fn, json.val[index(version)]);
|
||||
}
|
||||
} visitor = {};
|
||||
|
||||
auto
|
||||
visit()
|
||||
{
|
||||
return [self = this](auto... args) requires requires
|
||||
{
|
||||
visitor(
|
||||
std::declval<MultiApiJson&>(),
|
||||
std::declval<decltype(args)>()...);
|
||||
}
|
||||
{
|
||||
return visitor(*self, std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
auto
|
||||
visit() const
|
||||
{
|
||||
return [self = this](auto... args) requires requires
|
||||
{
|
||||
visitor(
|
||||
std::declval<MultiApiJson const&>(),
|
||||
std::declval<decltype(args)>()...);
|
||||
}
|
||||
{
|
||||
return visitor(*self, std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto
|
||||
visit(Args... args)
|
||||
-> std::invoke_result_t<visitor_t, MultiApiJson&, Args...> requires(
|
||||
sizeof...(args) > 0) &&
|
||||
requires
|
||||
{
|
||||
visitor(*this, std::forward<decltype(args)>(args)...);
|
||||
}
|
||||
{
|
||||
return visitor(*this, std::forward<decltype(args)>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto
|
||||
visit(Args... args) const -> std::
|
||||
invoke_result_t<visitor_t, MultiApiJson const&, Args...> requires(
|
||||
sizeof...(args) > 0) &&
|
||||
requires
|
||||
{
|
||||
visitor(*this, std::forward<decltype(args)>(args)...);
|
||||
}
|
||||
{
|
||||
return visitor(*this, std::forward<decltype(args)>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Wrapper for Json for all supported API versions.
|
||||
using MultiApiJson = detail::
|
||||
MultiApiJson<RPC::apiMinimumSupportedVersion, RPC::apiMaximumValidVersion>;
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
45
include/xrpl/protocol/NFTSyntheticSerializer.h
Normal file
45
include/xrpl/protocol/NFTSyntheticSerializer.h
Normal file
@@ -0,0 +1,45 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_NFTSYNTHETICSERIALIZER_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_NFTSYNTHETICSERIALIZER_H_INCLUDED
|
||||
|
||||
#include <ripple/json/json_forwards.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/TxMeta.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
Adds common synthetic fields to transaction-related JSON responses
|
||||
|
||||
@{
|
||||
*/
|
||||
void
|
||||
insertNFTSyntheticInJson(
|
||||
Json::Value&,
|
||||
std::shared_ptr<STTx const> const&,
|
||||
TxMeta const&);
|
||||
/** @} */
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
62
include/xrpl/protocol/NFTokenID.h
Normal file
62
include/xrpl/protocol/NFTokenID.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_NFTOKENID_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_NFTOKENID_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/json/json_forwards.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/TxMeta.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
Add a `nftoken_ids` field to the `meta` output parameter.
|
||||
The field is only added to successful NFTokenMint, NFTokenAcceptOffer,
|
||||
and NFTokenCancelOffer transactions.
|
||||
|
||||
Helper functions are not static because they can be used by Clio.
|
||||
@{
|
||||
*/
|
||||
bool
|
||||
canHaveNFTokenID(
|
||||
std::shared_ptr<STTx const> const& serializedTx,
|
||||
TxMeta const& transactionMeta);
|
||||
|
||||
std::optional<uint256>
|
||||
getNFTokenIDFromPage(TxMeta const& transactionMeta);
|
||||
|
||||
std::vector<uint256>
|
||||
getNFTokenIDFromDeletedOffer(TxMeta const& transactionMeta);
|
||||
|
||||
void
|
||||
insertNFTokenID(
|
||||
Json::Value& response,
|
||||
std::shared_ptr<STTx const> const& transaction,
|
||||
TxMeta const& transactionMeta);
|
||||
/** @} */
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
57
include/xrpl/protocol/NFTokenOfferID.h
Normal file
57
include/xrpl/protocol/NFTokenOfferID.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_NFTOKENOFFERID_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_NFTOKENOFFERID_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/json/json_forwards.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/TxMeta.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
Add an `offer_id` field to the `meta` output parameter.
|
||||
The field is only added to successful NFTokenCreateOffer transactions.
|
||||
|
||||
Helper functions are not static because they can be used by Clio.
|
||||
@{
|
||||
*/
|
||||
bool
|
||||
canHaveNFTokenOfferID(
|
||||
std::shared_ptr<STTx const> const& serializedTx,
|
||||
TxMeta const& transactionMeta);
|
||||
|
||||
std::optional<uint256>
|
||||
getOfferIDFromCreatedOffer(TxMeta const& transactionMeta);
|
||||
|
||||
void
|
||||
insertNFTokenOfferID(
|
||||
Json::Value& response,
|
||||
std::shared_ptr<STTx const> const& transaction,
|
||||
TxMeta const& transactionMeta);
|
||||
/** @} */
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
69
include/xrpl/protocol/PayChan.h
Normal file
69
include/xrpl/protocol/PayChan.h
Normal file
@@ -0,0 +1,69 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_PAYCHAN_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_PAYCHAN_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/protocol/HashPrefix.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
inline void
|
||||
serializePayChanAuthorization(
|
||||
Serializer& msg,
|
||||
uint256 const& key,
|
||||
XRPAmount const& amt)
|
||||
{
|
||||
msg.add32(HashPrefix::paymentChannelClaim);
|
||||
msg.addBitString(key);
|
||||
msg.add64(amt.drops());
|
||||
}
|
||||
|
||||
inline void
|
||||
serializePayChanAuthorization(
|
||||
Serializer& msg,
|
||||
uint256 const& key,
|
||||
IOUAmount const& amt,
|
||||
Currency const& cur,
|
||||
AccountID const& iss)
|
||||
{
|
||||
msg.add32(HashPrefix::paymentChannelClaim);
|
||||
msg.addBitString(key);
|
||||
if (amt == beast::zero)
|
||||
msg.add64(STAmount::cNotNative);
|
||||
else if (amt.signum() == -1) // 512 = not native
|
||||
msg.add64(
|
||||
amt.mantissa() |
|
||||
(static_cast<std::uint64_t>(amt.exponent() + 512 + 97)
|
||||
<< (64 - 10)));
|
||||
else // 256 = positive
|
||||
msg.add64(
|
||||
amt.mantissa() |
|
||||
(static_cast<std::uint64_t>(amt.exponent() + 512 + 256 + 97)
|
||||
<< (64 - 10)));
|
||||
msg.addBitString(cur);
|
||||
msg.addBitString(iss);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
139
include/xrpl/protocol/Protocol.h
Normal file
139
include/xrpl/protocol/Protocol.h
Normal file
@@ -0,0 +1,139 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_PROTOCOL_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_PROTOCOL_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/ByteUtilities.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Protocol specific constants.
|
||||
|
||||
This information is, implicitly, part of the protocol.
|
||||
|
||||
@note Changing these values without adding code to the
|
||||
server to detect "pre-change" and "post-change"
|
||||
will result in a hard fork.
|
||||
|
||||
@ingroup protocol
|
||||
*/
|
||||
/** Smallest legal byte size of a transaction. */
|
||||
std::size_t constexpr txMinSizeBytes = 10;
|
||||
|
||||
/** Largest legal byte size of a transaction. */
|
||||
std::size_t constexpr txMaxSizeBytes = megabytes(1);
|
||||
|
||||
/** The maximum number of unfunded offers to delete at once */
|
||||
std::size_t constexpr unfundedOfferRemoveLimit = 1000;
|
||||
|
||||
/** The maximum number of expired offers to delete at once */
|
||||
std::size_t constexpr expiredOfferRemoveLimit = 256;
|
||||
|
||||
/** The maximum number of metadata entries allowed in one transaction */
|
||||
std::size_t constexpr oversizeMetaDataCap = 5200;
|
||||
|
||||
/** The maximum number of entries per directory page */
|
||||
std::size_t constexpr dirNodeMaxEntries = 32;
|
||||
|
||||
/** The maximum number of pages allowed in a directory */
|
||||
std::uint64_t constexpr dirNodeMaxPages = 262144;
|
||||
|
||||
/** The maximum number of items in an NFT page */
|
||||
std::size_t constexpr dirMaxTokensPerPage = 32;
|
||||
|
||||
/** The maximum number of owner directory entries for account to be deletable */
|
||||
std::size_t constexpr maxDeletableDirEntries = 1000;
|
||||
|
||||
/** The maximum number of token offers that can be canceled at once */
|
||||
std::size_t constexpr maxTokenOfferCancelCount = 500;
|
||||
|
||||
/** The maximum number of offers in an offer directory for NFT to be burnable */
|
||||
std::size_t constexpr maxDeletableTokenOfferEntries = 500;
|
||||
|
||||
/** The maximum token transfer fee allowed.
|
||||
|
||||
Token transfer fees can range from 0% to 50% and are specified in tenths of
|
||||
a basis point; that is a value of 1000 represents a transfer fee of 1% and
|
||||
a value of 10000 represents a transfer fee of 10%.
|
||||
|
||||
Note that for extremely low transfer fees values, it is possible that the
|
||||
calculated fee will be 0.
|
||||
*/
|
||||
std::uint16_t constexpr maxTransferFee = 50000;
|
||||
|
||||
/** The maximum length of a URI inside an NFT */
|
||||
std::size_t constexpr maxTokenURILength = 256;
|
||||
|
||||
/** The maximum length of a Data element inside a DID */
|
||||
std::size_t constexpr maxDIDDocumentLength = 256;
|
||||
|
||||
/** The maximum length of a URI inside a DID */
|
||||
std::size_t constexpr maxDIDURILength = 256;
|
||||
|
||||
/** The maximum length of an Attestation inside a DID */
|
||||
std::size_t constexpr maxDIDAttestationLength = 256;
|
||||
|
||||
/** The maximum length of a domain */
|
||||
std::size_t constexpr maxDomainLength = 256;
|
||||
|
||||
/** A ledger index. */
|
||||
using LedgerIndex = std::uint32_t;
|
||||
|
||||
/** A transaction identifier.
|
||||
The value is computed as the hash of the
|
||||
canonicalized, serialized transaction object.
|
||||
*/
|
||||
using TxID = uint256;
|
||||
|
||||
/** The maximum number of trustlines to delete as part of AMM account
|
||||
* deletion cleanup.
|
||||
*/
|
||||
std::uint16_t constexpr maxDeletableAMMTrustLines = 512;
|
||||
|
||||
/** The maximum length of a URI inside an Oracle */
|
||||
std::size_t constexpr maxOracleURI = 256;
|
||||
|
||||
/** The maximum length of a Provider inside an Oracle */
|
||||
std::size_t constexpr maxOracleProvider = 256;
|
||||
|
||||
/** The maximum size of a data series array inside an Oracle */
|
||||
std::size_t constexpr maxOracleDataSeries = 10;
|
||||
|
||||
/** The maximum length of a SymbolClass inside an Oracle */
|
||||
std::size_t constexpr maxOracleSymbolClass = 16;
|
||||
|
||||
/** The maximum allowed time difference between lastUpdateTime and the time
|
||||
of the last closed ledger
|
||||
*/
|
||||
std::size_t constexpr maxLastUpdateTimeDelta = 300;
|
||||
|
||||
/** The maximum price scaling factor
|
||||
*/
|
||||
std::size_t constexpr maxPriceScale = 20;
|
||||
|
||||
/** The maximum percentage of outliers to trim
|
||||
*/
|
||||
std::size_t constexpr maxTrim = 25;
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
293
include/xrpl/protocol/PublicKey.h
Normal file
293
include/xrpl/protocol/PublicKey.h
Normal file
@@ -0,0 +1,293 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/protocol/KeyType.h>
|
||||
#include <ripple/protocol/STExchange.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <ripple/protocol/json_get_or_throw.h>
|
||||
#include <ripple/protocol/tokens.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** A public key.
|
||||
|
||||
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,
|
||||
information needed to determine the cryptosystem
|
||||
parameters used is stored inside the key.
|
||||
|
||||
As of this writing two systems are supported:
|
||||
|
||||
secp256k1
|
||||
ed25519
|
||||
|
||||
secp256k1 public keys consist of a 33 byte
|
||||
compressed public key, with the lead byte equal
|
||||
to 0x02 or 0x03.
|
||||
|
||||
The ed25519 public keys consist of a 1 byte
|
||||
prefix constant 0xED, followed by 32 bytes of
|
||||
public key data.
|
||||
*/
|
||||
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
|
||||
|
||||
public:
|
||||
using const_iterator = std::uint8_t const*;
|
||||
|
||||
public:
|
||||
PublicKey() = delete;
|
||||
|
||||
PublicKey(PublicKey const& other);
|
||||
PublicKey&
|
||||
operator=(PublicKey const& other);
|
||||
|
||||
/** Create a public key.
|
||||
|
||||
Preconditions:
|
||||
publicKeyType(slice) != std::nullopt
|
||||
*/
|
||||
explicit PublicKey(Slice const& slice);
|
||||
|
||||
std::uint8_t const*
|
||||
data() const noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return buf_ + size_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return buf_ + size_;
|
||||
}
|
||||
|
||||
Slice
|
||||
slice() const noexcept
|
||||
{
|
||||
return {buf_, size_};
|
||||
}
|
||||
|
||||
operator Slice() const noexcept
|
||||
{
|
||||
return slice();
|
||||
}
|
||||
};
|
||||
|
||||
/** Print the public key to a stream.
|
||||
*/
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, PublicKey const& pk);
|
||||
|
||||
inline bool
|
||||
operator==(PublicKey const& lhs, PublicKey const& rhs)
|
||||
{
|
||||
return std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(PublicKey const& lhs, PublicKey const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare(
|
||||
lhs.data(),
|
||||
lhs.data() + lhs.size(),
|
||||
rhs.data(),
|
||||
rhs.data() + rhs.size());
|
||||
}
|
||||
|
||||
template <class Hasher>
|
||||
void
|
||||
hash_append(Hasher& h, PublicKey const& pk)
|
||||
{
|
||||
h(pk.data(), pk.size());
|
||||
}
|
||||
|
||||
template <>
|
||||
struct STExchange<STBlob, PublicKey>
|
||||
{
|
||||
explicit STExchange() = default;
|
||||
|
||||
using value_type = PublicKey;
|
||||
|
||||
static void
|
||||
get(std::optional<value_type>& t, STBlob const& u)
|
||||
{
|
||||
t.emplace(Slice(u.data(), u.size()));
|
||||
}
|
||||
|
||||
static std::unique_ptr<STBlob>
|
||||
set(SField const& f, PublicKey const& t)
|
||||
{
|
||||
return std::make_unique<STBlob>(f, t.data(), t.size());
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline std::string
|
||||
toBase58(TokenType type, PublicKey const& pk)
|
||||
{
|
||||
return encodeBase58Token(type, pk.data(), pk.size());
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PublicKey>
|
||||
parseBase58(TokenType type, std::string const& s);
|
||||
|
||||
enum class ECDSACanonicality { canonical, fullyCanonical };
|
||||
|
||||
/** Determines the canonicality of a signature.
|
||||
|
||||
A canonical signature is in its most reduced form.
|
||||
For example the R and S components do not contain
|
||||
additional leading zeroes. However, even in
|
||||
canonical form, (R,S) and (R,G-S) are both
|
||||
valid signatures for message M.
|
||||
|
||||
Therefore, to prevent malleability attacks we
|
||||
define a fully canonical signature as one where:
|
||||
|
||||
R < G - S
|
||||
|
||||
where G is the curve order.
|
||||
|
||||
This routine returns std::nullopt if the format
|
||||
of the signature is invalid (for example, the
|
||||
points are encoded incorrectly).
|
||||
|
||||
@return std::nullopt if the signature fails
|
||||
validity checks.
|
||||
|
||||
@note Only the format of the signature is checked,
|
||||
no verification cryptography is performed.
|
||||
*/
|
||||
std::optional<ECDSACanonicality>
|
||||
ecdsaCanonicality(Slice const& sig);
|
||||
|
||||
/** Returns the type of public key.
|
||||
|
||||
@return std::nullopt If the public key does not
|
||||
represent a known type.
|
||||
*/
|
||||
/** @{ */
|
||||
[[nodiscard]] std::optional<KeyType>
|
||||
publicKeyType(Slice const& slice);
|
||||
|
||||
[[nodiscard]] inline std::optional<KeyType>
|
||||
publicKeyType(PublicKey const& publicKey)
|
||||
{
|
||||
return publicKeyType(publicKey.slice());
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Verify a secp256k1 signature on the digest of a message. */
|
||||
[[nodiscard]] bool
|
||||
verifyDigest(
|
||||
PublicKey const& publicKey,
|
||||
uint256 const& digest,
|
||||
Slice const& sig,
|
||||
bool mustBeFullyCanonical = true) noexcept;
|
||||
|
||||
/** Verify a signature on a message.
|
||||
With secp256k1 signatures, the data is first hashed with
|
||||
SHA512-Half, and the resulting digest is signed.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
verify(
|
||||
PublicKey const& publicKey,
|
||||
Slice const& m,
|
||||
Slice const& sig,
|
||||
bool mustBeFullyCanonical = true) noexcept;
|
||||
|
||||
/** Calculate the 160-bit node ID from a node public key. */
|
||||
NodeID
|
||||
calcNodeID(PublicKey const&);
|
||||
|
||||
// VFALCO This belongs in AccountID.h but
|
||||
// is here because of header issues
|
||||
AccountID
|
||||
calcAccountID(PublicKey const& pk);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Json {
|
||||
template <>
|
||||
inline ripple::PublicKey
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
std::string const b58 = getOrThrow<std::string>(v, field);
|
||||
if (auto pubKeyBlob = strUnHex(b58); publicKeyType(makeSlice(*pubKeyBlob)))
|
||||
{
|
||||
return PublicKey{makeSlice(*pubKeyBlob)};
|
||||
}
|
||||
for (auto const tokenType :
|
||||
{TokenType::NodePublic, TokenType::AccountPublic})
|
||||
{
|
||||
if (auto const pk = parseBase58<PublicKey>(tokenType, b58))
|
||||
return *pk;
|
||||
}
|
||||
Throw<JsonTypeMismatchError>(field.getJsonName(), "PublicKey");
|
||||
}
|
||||
} // namespace Json
|
||||
|
||||
#endif
|
||||
417
include/xrpl/protocol/Quality.h
Normal file
417
include/xrpl/protocol/Quality.h
Normal file
@@ -0,0 +1,417 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_QUALITY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_QUALITY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/IOUAmount.h>
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
#include <ripple/protocol/AmountConversions.h>
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Represents a pair of input and output currencies.
|
||||
|
||||
The input currency can be converted to the output
|
||||
currency by multiplying by the rate, represented by
|
||||
Quality.
|
||||
|
||||
For offers, "in" is always TakerPays and "out" is
|
||||
always TakerGets.
|
||||
*/
|
||||
template <class In, class Out>
|
||||
struct TAmounts
|
||||
{
|
||||
TAmounts() = default;
|
||||
|
||||
TAmounts(beast::Zero, beast::Zero) : in(beast::zero), out(beast::zero)
|
||||
{
|
||||
}
|
||||
|
||||
TAmounts(In const& in_, Out const& out_) : in(in_), out(out_)
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns `true` if either quantity is not positive. */
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return in <= beast::zero || out <= beast::zero;
|
||||
}
|
||||
|
||||
TAmounts&
|
||||
operator+=(TAmounts const& rhs)
|
||||
{
|
||||
in += rhs.in;
|
||||
out += rhs.out;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TAmounts&
|
||||
operator-=(TAmounts const& rhs)
|
||||
{
|
||||
in -= rhs.in;
|
||||
out -= rhs.out;
|
||||
return *this;
|
||||
}
|
||||
|
||||
In in;
|
||||
Out out;
|
||||
};
|
||||
|
||||
using Amounts = TAmounts<STAmount, STAmount>;
|
||||
|
||||
template <class In, class Out>
|
||||
bool
|
||||
operator==(TAmounts<In, Out> const& lhs, TAmounts<In, Out> const& rhs) noexcept
|
||||
{
|
||||
return lhs.in == rhs.in && lhs.out == rhs.out;
|
||||
}
|
||||
|
||||
template <class In, class Out>
|
||||
bool
|
||||
operator!=(TAmounts<In, Out> const& lhs, TAmounts<In, Out> const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Ripple 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.
|
||||
Internally this is stored using a custom floating point representation,
|
||||
as the inverse of the ratio, so that quality will be descending in
|
||||
a sequence of actual values that represent qualities.
|
||||
*/
|
||||
class Quality
|
||||
{
|
||||
public:
|
||||
// Type of the internal representation. Higher qualities
|
||||
// have lower unsigned integer representations.
|
||||
using value_type = std::uint64_t;
|
||||
|
||||
static const int minTickSize = 3;
|
||||
static const int maxTickSize = 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;
|
||||
|
||||
public:
|
||||
Quality() = default;
|
||||
|
||||
/** Create a quality from the integer encoding of an STAmount */
|
||||
explicit Quality(std::uint64_t value);
|
||||
|
||||
/** Create a quality from the ratio of two amounts. */
|
||||
explicit Quality(Amounts const& amount);
|
||||
|
||||
/** Create a quality from the ratio of two amounts. */
|
||||
template <class In, class Out>
|
||||
explicit Quality(TAmounts<In, Out> const& amount)
|
||||
: Quality(Amounts(toSTAmount(amount.in), toSTAmount(amount.out)))
|
||||
{
|
||||
}
|
||||
|
||||
/** Create a quality from the ratio of two amounts. */
|
||||
template <class In, class Out>
|
||||
Quality(Out const& out, In const& in)
|
||||
: Quality(Amounts(toSTAmount(in), toSTAmount(out)))
|
||||
{
|
||||
}
|
||||
|
||||
/** Advances to the next higher quality level. */
|
||||
/** @{ */
|
||||
Quality&
|
||||
operator++();
|
||||
|
||||
Quality
|
||||
operator++(int);
|
||||
/** @} */
|
||||
|
||||
/** Advances to the next lower quality level. */
|
||||
/** @{ */
|
||||
Quality&
|
||||
operator--();
|
||||
|
||||
Quality
|
||||
operator--(int);
|
||||
/** @} */
|
||||
|
||||
/** Returns the quality as STAmount. */
|
||||
STAmount
|
||||
rate() const
|
||||
{
|
||||
return amountFromQuality(m_value);
|
||||
}
|
||||
|
||||
/** Returns the quality rounded up to the specified number
|
||||
of decimal digits.
|
||||
*/
|
||||
Quality
|
||||
round(int tickSize) const;
|
||||
|
||||
/** Returns the scaled amount with in capped.
|
||||
Math is avoided if the result is exact. The output is clamped
|
||||
to prevent money creation.
|
||||
*/
|
||||
[[nodiscard]] Amounts
|
||||
ceil_in(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;
|
||||
|
||||
// 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;
|
||||
|
||||
template <class In, class Out>
|
||||
[[nodiscard]] TAmounts<In, Out>
|
||||
ceil_in_strict(
|
||||
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;
|
||||
|
||||
template <class In, class Out>
|
||||
[[nodiscard]] TAmounts<In, Out>
|
||||
ceil_out(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;
|
||||
|
||||
template <class In, class Out>
|
||||
[[nodiscard]] TAmounts<In, Out>
|
||||
ceil_out_strict(
|
||||
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
|
||||
// their arguments to STAoumout and convert the result back to TAmount.
|
||||
// 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(
|
||||
TAmounts<In, Out> const& amount,
|
||||
Lim const& limit,
|
||||
Lim const& limit_cmp,
|
||||
FnPtr ceil_function,
|
||||
Round... round) const;
|
||||
|
||||
public:
|
||||
/** Returns `true` if lhs is lower quality than `rhs`.
|
||||
Lower quality means the taker receives a worse deal.
|
||||
Higher quality is better for the taker.
|
||||
*/
|
||||
friend bool
|
||||
operator<(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return lhs.m_value > rhs.m_value;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator>(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return lhs.m_value < rhs.m_value;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator<=(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator>=(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator==(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return lhs.m_value == rhs.m_value;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, Quality const& quality)
|
||||
{
|
||||
os << quality.m_value;
|
||||
return os;
|
||||
}
|
||||
|
||||
// return the relative distance (relative error) between two qualities. This
|
||||
// is used for testing only. relative distance is abs(a-b)/min(a,b)
|
||||
friend double
|
||||
relativeDistance(Quality const& q1, Quality const& q2)
|
||||
{
|
||||
assert(q1.m_value > 0 && q2.m_value > 0);
|
||||
|
||||
if (q1.m_value == q2.m_value) // make expected common case fast
|
||||
return 0;
|
||||
|
||||
auto const [minV, maxV] = std::minmax(q1.m_value, q2.m_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;
|
||||
};
|
||||
|
||||
auto const minVMantissa = mantissa(minV);
|
||||
auto const maxVMantissa = mantissa(maxV);
|
||||
auto const expDiff = exponent(maxV) - exponent(minV);
|
||||
|
||||
double const minVD = static_cast<double>(minVMantissa);
|
||||
double const maxVD = expDiff ? 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)
|
||||
// mantissas
|
||||
return (maxVD - minVD) / minVD;
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
class In,
|
||||
class Out,
|
||||
class Lim,
|
||||
typename FnPtr,
|
||||
std::same_as<bool>... Round>
|
||||
TAmounts<In, Out>
|
||||
Quality::ceil_TAmounts_helper(
|
||||
TAmounts<In, Out> const& amount,
|
||||
Lim const& limit,
|
||||
Lim const& limit_cmp,
|
||||
FnPtr ceil_function,
|
||||
Round... roundUp) const
|
||||
{
|
||||
if (limit_cmp <= 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...);
|
||||
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
|
||||
{
|
||||
// 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;
|
||||
|
||||
return ceil_TAmounts_helper(amount, limit, amount.in, ceil_in_fn_ptr);
|
||||
}
|
||||
|
||||
template <class In, class Out>
|
||||
TAmounts<In, Out>
|
||||
Quality::ceil_in_strict(
|
||||
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;
|
||||
|
||||
return ceil_TAmounts_helper(
|
||||
amount, limit, amount.in, ceil_in_fn_ptr, roundUp);
|
||||
}
|
||||
|
||||
template <class In, class Out>
|
||||
TAmounts<In, Out>
|
||||
Quality::ceil_out(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;
|
||||
|
||||
return ceil_TAmounts_helper(amount, limit, amount.out, ceil_out_fn_ptr);
|
||||
}
|
||||
|
||||
template <class In, class Out>
|
||||
TAmounts<In, Out>
|
||||
Quality::ceil_out_strict(
|
||||
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;
|
||||
|
||||
return ceil_TAmounts_helper(
|
||||
amount, limit, amount.out, ceil_out_fn_ptr, roundUp);
|
||||
}
|
||||
|
||||
/** Calculate the quality of a two-hop path given the two hops.
|
||||
@param lhs The first leg of the path: input to intermediate.
|
||||
@param rhs The second leg of the path: intermediate to output.
|
||||
*/
|
||||
Quality
|
||||
composed_quality(Quality const& lhs, Quality const& rhs);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
107
include/xrpl/protocol/QualityFunction.h
Normal file
107
include/xrpl/protocol/QualityFunction.h
Normal file
@@ -0,0 +1,107 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_QUALITYFUNCTION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_QUALITYFUNCTION_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Number.h>
|
||||
#include <ripple/protocol/AMMCore.h>
|
||||
#include <ripple/protocol/Quality.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Average quality of a path as a function of `out`: q(out) = m * out + b,
|
||||
* where m = -1 / poolGets, b = poolPays / poolGets. If CLOB offer then
|
||||
* `m` is equal to 0 `b` is equal to the offer's quality. The function
|
||||
* is derived by substituting `in` in q = out / in with the swap out formula
|
||||
* for `in`:
|
||||
* in = [(poolGets * poolPays) / (poolGets - out) - poolPays] / (1 - tfee)
|
||||
* and combining the function for multiple steps. The function is used
|
||||
* to limit required output amount when quality limit is provided in one
|
||||
* path optimization.
|
||||
*/
|
||||
class QualityFunction
|
||||
{
|
||||
private:
|
||||
// slope
|
||||
Number m_;
|
||||
// intercept
|
||||
Number b_;
|
||||
// seated if QF is for CLOB offer.
|
||||
std::optional<Quality> quality_;
|
||||
|
||||
public:
|
||||
struct AMMTag
|
||||
{
|
||||
};
|
||||
// AMMOffer for multi-path is like CLOB, i.e. the offer size
|
||||
// changes proportionally to its quality.
|
||||
struct CLOBLikeTag
|
||||
{
|
||||
};
|
||||
QualityFunction(Quality const& quality, CLOBLikeTag);
|
||||
template <typename TIn, typename TOut>
|
||||
QualityFunction(
|
||||
TAmounts<TIn, TOut> const& amounts,
|
||||
std::uint32_t tfee,
|
||||
AMMTag);
|
||||
|
||||
/** Combines QF with the next step QF
|
||||
*/
|
||||
void
|
||||
combine(QualityFunction const& qf);
|
||||
|
||||
/** Find output to produce the requested
|
||||
* average quality.
|
||||
* @param quality requested average quality (quality limit)
|
||||
*/
|
||||
std::optional<Number>
|
||||
outFromAvgQ(Quality const& quality);
|
||||
|
||||
/** Return true if the quality function is constant
|
||||
*/
|
||||
bool
|
||||
isConst() const
|
||||
{
|
||||
return quality_.has_value();
|
||||
}
|
||||
|
||||
std::optional<Quality> const&
|
||||
quality() const
|
||||
{
|
||||
return quality_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TIn, typename TOut>
|
||||
QualityFunction::QualityFunction(
|
||||
TAmounts<TIn, TOut> const& amounts,
|
||||
std::uint32_t tfee,
|
||||
QualityFunction::AMMTag)
|
||||
{
|
||||
if (amounts.in <= beast::zero || amounts.out <= beast::zero)
|
||||
Throw<std::runtime_error>("QualityFunction amounts are 0.");
|
||||
Number const cfee = feeMult(tfee);
|
||||
m_ = -cfee / amounts.in;
|
||||
b_ = amounts.out * cfee / amounts.in;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif // RIPPLE_PROTOCOL_QUALITYFUNCTION_H_INCLUDED
|
||||
44
include/xrpl/protocol/README.md
Normal file
44
include/xrpl/protocol/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# protocol
|
||||
|
||||
Classes and functions for handling data and
|
||||
values associated with the XRP Ledger protocol.
|
||||
|
||||
## Serialized Objects
|
||||
|
||||
Objects transmitted over the network must be
|
||||
serialized into a canonical format. The prefix "ST" refers
|
||||
to classes that deal with the serialized format.
|
||||
|
||||
The term "Tx" or "tx" is an abbreviation for "Transaction",
|
||||
a commonly occurring object type.
|
||||
|
||||
### Optional Fields
|
||||
|
||||
Our serialized fields have some "type magic" to make
|
||||
optional fields easier to read:
|
||||
|
||||
- The operation `x[sfFoo]` means "return the value of 'Foo'
|
||||
if it exists, or the default value if it doesn't."
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
Typically, for things that are guaranteed to exist, you use
|
||||
`x[sfFoo]` and avoid having to deal with a container that may
|
||||
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))
|
||||
|
||||
The source of this "type magic" is in
|
||||
[SField.h](./SField.h#L296-L302).
|
||||
|
||||
### Related Resources
|
||||
|
||||
- [ripple-binary-codec SField enums](https://github.com/XRPLF/xrpl.js/tree/main/packages/ripple-binary-codec/src/enums)
|
||||
- [SFCode Registry Tables](https://github.com/XRPLF/sFieldRegistry)
|
||||
35
include/xrpl/protocol/RPCErr.h
Normal file
35
include/xrpl/protocol/RPCErr.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_NET_RPCERR_H_INCLUDED
|
||||
#define RIPPLE_NET_RPCERR_H_INCLUDED
|
||||
|
||||
#include <ripple/json/json_value.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// VFALCO NOTE these are deprecated
|
||||
bool
|
||||
isRpcError(Json::Value jvResult);
|
||||
Json::Value
|
||||
rpcError(int iError, std::string msg = "");
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
105
include/xrpl/protocol/Rate.h
Normal file
105
include/xrpl/protocol/Rate.h
Normal file
@@ -0,0 +1,105 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_RATE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_RATE_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
#include <boost/operators.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Represents a transfer rate
|
||||
|
||||
Transfer rates are specified as fractions of 1 billion.
|
||||
For example, a transfer rate of 1% is represented as
|
||||
1,010,000,000.
|
||||
*/
|
||||
struct Rate : private boost::totally_ordered<Rate>
|
||||
{
|
||||
std::uint32_t value;
|
||||
|
||||
Rate() = delete;
|
||||
|
||||
explicit Rate(std::uint32_t rate) : value(rate)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(Rate const& lhs, Rate const& rhs) noexcept
|
||||
{
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(Rate const& lhs, Rate const& rhs) noexcept
|
||||
{
|
||||
return lhs.value < rhs.value;
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, Rate const& rate)
|
||||
{
|
||||
os << rate.value;
|
||||
return os;
|
||||
}
|
||||
|
||||
STAmount
|
||||
multiply(STAmount const& amount, Rate const& rate);
|
||||
|
||||
STAmount
|
||||
multiplyRound(STAmount const& amount, Rate const& rate, bool roundUp);
|
||||
|
||||
STAmount
|
||||
multiplyRound(
|
||||
STAmount const& amount,
|
||||
Rate const& rate,
|
||||
Issue const& issue,
|
||||
bool roundUp);
|
||||
|
||||
STAmount
|
||||
divide(STAmount const& amount, Rate const& rate);
|
||||
|
||||
STAmount
|
||||
divideRound(STAmount const& amount, Rate const& rate, bool roundUp);
|
||||
|
||||
STAmount
|
||||
divideRound(
|
||||
STAmount const& amount,
|
||||
Rate const& rate,
|
||||
Issue const& issue,
|
||||
bool roundUp);
|
||||
|
||||
namespace nft {
|
||||
/** Given a transfer fee (in basis points) convert it to a transfer rate. */
|
||||
Rate
|
||||
transferFeeAsRate(std::uint16_t fee);
|
||||
|
||||
} // namespace nft
|
||||
|
||||
/** A transfer rate signifying a 1:1 exchange */
|
||||
extern Rate const parityRate;
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
31
include/xrpl/protocol/RippleLedgerHash.h
Normal file
31
include/xrpl/protocol/RippleLedgerHash.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_RIPPLELEDGERHASH_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_RIPPLELEDGERHASH_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
using LedgerHash = uint256;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
132
include/xrpl/protocol/Rules.h
Normal file
132
include/xrpl/protocol/Rules.h
Normal file
@@ -0,0 +1,132 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_LEDGER_RULES_H_INCLUDED
|
||||
#define RIPPLE_LEDGER_RULES_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/beast/hash/uhash.h>
|
||||
#include <ripple/protocol/STVector256.h>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class DigestAwareReadView;
|
||||
|
||||
/** Rules controlling protocol behavior. */
|
||||
class Rules
|
||||
{
|
||||
private:
|
||||
class Impl;
|
||||
|
||||
// Carrying impl by shared_ptr makes Rules comparatively cheap to pass
|
||||
// by value.
|
||||
std::shared_ptr<Impl const> impl_;
|
||||
|
||||
public:
|
||||
Rules(Rules const&) = default;
|
||||
|
||||
Rules(Rules&&) = default;
|
||||
|
||||
Rules&
|
||||
operator=(Rules const&) = default;
|
||||
|
||||
Rules&
|
||||
operator=(Rules&&) = default;
|
||||
|
||||
Rules() = delete;
|
||||
|
||||
/** Construct an empty rule set.
|
||||
|
||||
These are the rules reflected by
|
||||
the genesis ledger.
|
||||
*/
|
||||
explicit Rules(std::unordered_set<uint256, beast::uhash<>> const& presets);
|
||||
|
||||
private:
|
||||
// Allow a friend function to construct Rules.
|
||||
friend Rules
|
||||
makeRulesGivenLedger(
|
||||
DigestAwareReadView const& ledger,
|
||||
Rules const& current);
|
||||
|
||||
friend Rules
|
||||
makeRulesGivenLedger(
|
||||
DigestAwareReadView const& ledger,
|
||||
std::unordered_set<uint256, beast::uhash<>> const& presets);
|
||||
|
||||
public:
|
||||
Rules(
|
||||
std::unordered_set<uint256, beast::uhash<>> const& presets,
|
||||
std::optional<uint256> const& digest,
|
||||
STVector256 const& amendments);
|
||||
|
||||
std::unordered_set<uint256, beast::uhash<>> const&
|
||||
presets() const;
|
||||
|
||||
public:
|
||||
/** Returns `true` if a feature is enabled. */
|
||||
bool
|
||||
enabled(uint256 const& feature) const;
|
||||
|
||||
/** Returns `true` if two rule sets are identical.
|
||||
|
||||
@note This is for diagnostics.
|
||||
*/
|
||||
bool
|
||||
operator==(Rules const&) const;
|
||||
|
||||
bool
|
||||
operator!=(Rules const& other) const;
|
||||
};
|
||||
|
||||
std::optional<Rules> const&
|
||||
getCurrentTransactionRules();
|
||||
|
||||
void
|
||||
setCurrentTransactionRules(std::optional<Rules> r);
|
||||
|
||||
/** RAII class to set and restore the current transaction rules
|
||||
*/
|
||||
class CurrentTransactionRulesGuard
|
||||
{
|
||||
public:
|
||||
explicit CurrentTransactionRulesGuard(Rules r)
|
||||
: saved_(getCurrentTransactionRules())
|
||||
{
|
||||
setCurrentTransactionRules(std::move(r));
|
||||
}
|
||||
|
||||
~CurrentTransactionRulesGuard()
|
||||
{
|
||||
setCurrentTransactionRules(saved_);
|
||||
}
|
||||
|
||||
CurrentTransactionRulesGuard() = delete;
|
||||
CurrentTransactionRulesGuard(CurrentTransactionRulesGuard const&) = delete;
|
||||
CurrentTransactionRulesGuard&
|
||||
operator=(CurrentTransactionRulesGuard const&) = delete;
|
||||
|
||||
private:
|
||||
std::optional<Rules> saved_;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
#endif
|
||||
721
include/xrpl/protocol/SField.h
Normal file
721
include/xrpl/protocol/SField.h
Normal file
@@ -0,0 +1,721 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SFIELD_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SFIELD_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/safe_cast.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/*
|
||||
|
||||
Some fields have a different meaning for their
|
||||
default value versus not present.
|
||||
Example:
|
||||
QualityIn on a TrustLine
|
||||
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Forwards
|
||||
class STAccount;
|
||||
class STAmount;
|
||||
class STIssue;
|
||||
class STBlob;
|
||||
template <int>
|
||||
class STBitString;
|
||||
template <class>
|
||||
class STInteger;
|
||||
class STXChainBridge;
|
||||
class STVector256;
|
||||
class STCurrency;
|
||||
class Definitions;
|
||||
|
||||
#pragma push_macro("XMACRO")
|
||||
#undef XMACRO
|
||||
|
||||
#define XMACRO(STYPE) \
|
||||
/* special types */ \
|
||||
STYPE(STI_UNKNOWN, -2) \
|
||||
STYPE(STI_NOTPRESENT, 0) \
|
||||
STYPE(STI_UINT16, 1) \
|
||||
\
|
||||
/* types (common) */ \
|
||||
STYPE(STI_UINT32, 2) \
|
||||
STYPE(STI_UINT64, 3) \
|
||||
STYPE(STI_UINT128, 4) \
|
||||
STYPE(STI_UINT256, 5) \
|
||||
STYPE(STI_AMOUNT, 6) \
|
||||
STYPE(STI_VL, 7) \
|
||||
STYPE(STI_ACCOUNT, 8) \
|
||||
\
|
||||
/* 9-13 are reserved */ \
|
||||
STYPE(STI_OBJECT, 14) \
|
||||
STYPE(STI_ARRAY, 15) \
|
||||
\
|
||||
/* types (uncommon) */ \
|
||||
STYPE(STI_UINT8, 16) \
|
||||
STYPE(STI_UINT160, 17) \
|
||||
STYPE(STI_PATHSET, 18) \
|
||||
STYPE(STI_VECTOR256, 19) \
|
||||
STYPE(STI_UINT96, 20) \
|
||||
STYPE(STI_UINT192, 21) \
|
||||
STYPE(STI_UINT384, 22) \
|
||||
STYPE(STI_UINT512, 23) \
|
||||
STYPE(STI_ISSUE, 24) \
|
||||
STYPE(STI_XCHAIN_BRIDGE, 25) \
|
||||
STYPE(STI_CURRENCY, 26) \
|
||||
\
|
||||
/* high-level types */ \
|
||||
/* cannot be serialized inside other types */ \
|
||||
STYPE(STI_TRANSACTION, 10001) \
|
||||
STYPE(STI_LEDGERENTRY, 10002) \
|
||||
STYPE(STI_VALIDATION, 10003) \
|
||||
STYPE(STI_METADATA, 10004)
|
||||
|
||||
#pragma push_macro("TO_ENUM")
|
||||
#undef TO_ENUM
|
||||
#pragma push_macro("TO_MAP")
|
||||
#undef TO_MAP
|
||||
|
||||
#define TO_ENUM(name, value) name = value,
|
||||
#define TO_MAP(name, value) {#name, value},
|
||||
|
||||
enum SerializedTypeID { XMACRO(TO_ENUM) };
|
||||
|
||||
static std::map<std::string, int> const sTypeMap = {XMACRO(TO_MAP)};
|
||||
|
||||
#undef XMACRO
|
||||
#undef TO_ENUM
|
||||
|
||||
#pragma pop_macro("XMACRO")
|
||||
#pragma pop_macro("TO_ENUM")
|
||||
#pragma pop_macro("TO_MAP")
|
||||
|
||||
// constexpr
|
||||
inline int
|
||||
field_code(SerializedTypeID id, int index)
|
||||
{
|
||||
return (safe_cast<int>(id) << 16) | index;
|
||||
}
|
||||
|
||||
// constexpr
|
||||
inline int
|
||||
field_code(int id, int index)
|
||||
{
|
||||
return (id << 16) | index;
|
||||
}
|
||||
|
||||
/** Identifies fields.
|
||||
|
||||
Fields are necessary to tag data in signed transactions so that
|
||||
the binary format of the transaction can be canonicalized. All
|
||||
SFields are created at compile time.
|
||||
|
||||
Each SField, once constructed, lives until program termination, and there
|
||||
is only one instance per fieldType/fieldValue pair which serves the entire
|
||||
application.
|
||||
*/
|
||||
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_Default =
|
||||
sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create
|
||||
};
|
||||
|
||||
enum class IsSigning : unsigned char { no, yes };
|
||||
static IsSigning const notSigning = IsSigning::no;
|
||||
|
||||
int const fieldCode; // (type<<16)|index
|
||||
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;
|
||||
|
||||
SField(SField const&) = delete;
|
||||
SField&
|
||||
operator=(SField const&) = delete;
|
||||
SField(SField&&) = delete;
|
||||
SField&
|
||||
operator=(SField&&) = delete;
|
||||
|
||||
public:
|
||||
struct private_access_tag_t; // public, but still an implementation detail
|
||||
|
||||
// These constructors can only be called from SField.cpp
|
||||
SField(
|
||||
private_access_tag_t,
|
||||
SerializedTypeID tid,
|
||||
int fv,
|
||||
const char* fn,
|
||||
int meta = sMD_Default,
|
||||
IsSigning signing = IsSigning::yes);
|
||||
explicit SField(private_access_tag_t, int fc);
|
||||
|
||||
static const SField&
|
||||
getField(int fieldCode);
|
||||
static const SField&
|
||||
getField(std::string const& fieldName);
|
||||
static const SField&
|
||||
getField(int type, int value)
|
||||
{
|
||||
return getField(field_code(type, value));
|
||||
}
|
||||
|
||||
static const SField&
|
||||
getField(SerializedTypeID type, int value)
|
||||
{
|
||||
return getField(field_code(type, value));
|
||||
}
|
||||
|
||||
std::string const&
|
||||
getName() const
|
||||
{
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
bool
|
||||
hasName() const
|
||||
{
|
||||
return fieldCode > 0;
|
||||
}
|
||||
|
||||
Json::StaticString const&
|
||||
getJsonName() const
|
||||
{
|
||||
return jsonName;
|
||||
}
|
||||
|
||||
bool
|
||||
isInvalid() const
|
||||
{
|
||||
return fieldCode == -1;
|
||||
}
|
||||
|
||||
bool
|
||||
isUseful() const
|
||||
{
|
||||
return fieldCode > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
isBinary() const
|
||||
{
|
||||
return fieldValue < 256;
|
||||
}
|
||||
|
||||
// A discardable field is one that cannot be serialized, and
|
||||
// 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
|
||||
isDiscardable() const
|
||||
{
|
||||
return fieldValue > 256;
|
||||
}
|
||||
|
||||
int
|
||||
getCode() const
|
||||
{
|
||||
return fieldCode;
|
||||
}
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return fieldNum;
|
||||
}
|
||||
static int
|
||||
getNumFields()
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldMeta(int c) const
|
||||
{
|
||||
return (fieldMeta & c) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldInclude(bool withSigningField) const
|
||||
{
|
||||
return (fieldValue < 256) &&
|
||||
(withSigningField || (signingField == IsSigning::yes));
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const SField& f) const
|
||||
{
|
||||
return fieldCode == f.fieldCode;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const SField& f) const
|
||||
{
|
||||
return fieldCode != f.fieldCode;
|
||||
}
|
||||
|
||||
static int
|
||||
compare(const SField& f1, const SField& f2);
|
||||
|
||||
static std::map<int, SField const*> knownCodeToField;
|
||||
|
||||
private:
|
||||
static int num;
|
||||
};
|
||||
|
||||
/** A field with a type known at compile time. */
|
||||
template <class T>
|
||||
struct TypedField : SField
|
||||
{
|
||||
using type = T;
|
||||
|
||||
template <class... Args>
|
||||
explicit TypedField(private_access_tag_t pat, Args&&... args);
|
||||
};
|
||||
|
||||
/** Indicate std::optional field semantics. */
|
||||
template <class T>
|
||||
struct OptionaledField
|
||||
{
|
||||
TypedField<T> const* f;
|
||||
|
||||
explicit OptionaledField(TypedField<T> const& f_) : f(&f_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline OptionaledField<T>
|
||||
operator~(TypedField<T> const& f)
|
||||
{
|
||||
return OptionaledField<T>(f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using SF_UINT8 = TypedField<STInteger<std::uint8_t>>;
|
||||
using SF_UINT16 = TypedField<STInteger<std::uint16_t>>;
|
||||
using SF_UINT32 = TypedField<STInteger<std::uint32_t>>;
|
||||
using SF_UINT64 = TypedField<STInteger<std::uint64_t>>;
|
||||
using SF_UINT96 = TypedField<STBitString<96>>;
|
||||
using SF_UINT128 = TypedField<STBitString<128>>;
|
||||
using SF_UINT160 = TypedField<STBitString<160>>;
|
||||
using SF_UINT192 = TypedField<STBitString<192>>;
|
||||
using SF_UINT256 = TypedField<STBitString<256>>;
|
||||
using SF_UINT384 = TypedField<STBitString<384>>;
|
||||
using SF_UINT512 = TypedField<STBitString<512>>;
|
||||
|
||||
using SF_ACCOUNT = TypedField<STAccount>;
|
||||
using SF_AMOUNT = TypedField<STAmount>;
|
||||
using SF_ISSUE = TypedField<STIssue>;
|
||||
using SF_CURRENCY = TypedField<STCurrency>;
|
||||
using SF_VL = TypedField<STBlob>;
|
||||
using SF_VECTOR256 = TypedField<STVector256>;
|
||||
using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern SField const sfInvalid;
|
||||
extern SField const sfGeneric;
|
||||
extern SField const sfLedgerEntry;
|
||||
extern SField const sfTransaction;
|
||||
extern SField const sfValidation;
|
||||
extern SField const sfMetadata;
|
||||
|
||||
// 8-bit integers (common)
|
||||
extern SF_UINT8 const sfCloseResolution;
|
||||
extern SF_UINT8 const sfMethod;
|
||||
extern SF_UINT8 const sfTransactionResult;
|
||||
extern SF_UINT8 const sfWasLockingChainSend;
|
||||
extern SF_UINT8 const sfScale;
|
||||
|
||||
// 8-bit integers (uncommon)
|
||||
extern SF_UINT8 const sfTickSize;
|
||||
extern SF_UINT8 const sfUNLModifyDisabling;
|
||||
extern SF_UINT8 const sfHookResult;
|
||||
|
||||
// 16-bit integers (common)
|
||||
extern SF_UINT16 const sfLedgerEntryType;
|
||||
extern SF_UINT16 const sfTransactionType;
|
||||
extern SF_UINT16 const sfSignerWeight;
|
||||
extern SF_UINT16 const sfTransferFee;
|
||||
extern SF_UINT16 const sfTradingFee;
|
||||
|
||||
// 16-bit integers (uncommon)
|
||||
extern SF_UINT16 const sfVersion;
|
||||
extern SF_UINT16 const sfHookStateChangeCount;
|
||||
extern SF_UINT16 const sfHookEmitCount;
|
||||
extern SF_UINT16 const sfHookExecutionIndex;
|
||||
extern SF_UINT16 const sfHookApiVersion;
|
||||
extern SF_UINT16 const sfDiscountedFee;
|
||||
|
||||
// 32-bit integers (common)
|
||||
extern SF_UINT32 const sfNetworkID;
|
||||
extern SF_UINT32 const sfFlags;
|
||||
extern SF_UINT32 const sfSourceTag;
|
||||
extern SF_UINT32 const sfSequence;
|
||||
extern SF_UINT32 const sfPreviousTxnLgrSeq;
|
||||
extern SF_UINT32 const sfLedgerSequence;
|
||||
extern SF_UINT32 const sfCloseTime;
|
||||
extern SF_UINT32 const sfParentCloseTime;
|
||||
extern SF_UINT32 const sfSigningTime;
|
||||
extern SF_UINT32 const sfExpiration;
|
||||
extern SF_UINT32 const sfTransferRate;
|
||||
extern SF_UINT32 const sfWalletSize;
|
||||
extern SF_UINT32 const sfOwnerCount;
|
||||
extern SF_UINT32 const sfDestinationTag;
|
||||
extern SF_UINT32 const sfLastUpdateTime;
|
||||
|
||||
// 32-bit integers (uncommon)
|
||||
extern SF_UINT32 const sfHighQualityIn;
|
||||
extern SF_UINT32 const sfHighQualityOut;
|
||||
extern SF_UINT32 const sfLowQualityIn;
|
||||
extern SF_UINT32 const sfLowQualityOut;
|
||||
extern SF_UINT32 const sfQualityIn;
|
||||
extern SF_UINT32 const sfQualityOut;
|
||||
extern SF_UINT32 const sfStampEscrow;
|
||||
extern SF_UINT32 const sfBondAmount;
|
||||
extern SF_UINT32 const sfLoadFee;
|
||||
extern SF_UINT32 const sfOfferSequence;
|
||||
extern SF_UINT32 const sfFirstLedgerSequence;
|
||||
extern SF_UINT32 const sfLastLedgerSequence;
|
||||
extern SF_UINT32 const sfTransactionIndex;
|
||||
extern SF_UINT32 const sfOperationLimit;
|
||||
extern SF_UINT32 const sfReferenceFeeUnits;
|
||||
extern SF_UINT32 const sfReserveBase;
|
||||
extern SF_UINT32 const sfReserveIncrement;
|
||||
extern SF_UINT32 const sfSetFlag;
|
||||
extern SF_UINT32 const sfClearFlag;
|
||||
extern SF_UINT32 const sfSignerQuorum;
|
||||
extern SF_UINT32 const sfCancelAfter;
|
||||
extern SF_UINT32 const sfFinishAfter;
|
||||
extern SF_UINT32 const sfSignerListID;
|
||||
extern SF_UINT32 const sfSettleDelay;
|
||||
extern SF_UINT32 const sfTicketCount;
|
||||
extern SF_UINT32 const sfTicketSequence;
|
||||
extern SF_UINT32 const sfNFTokenTaxon;
|
||||
extern SF_UINT32 const sfMintedNFTokens;
|
||||
extern SF_UINT32 const sfBurnedNFTokens;
|
||||
extern SF_UINT32 const sfHookStateCount;
|
||||
extern SF_UINT32 const sfEmitGeneration;
|
||||
extern SF_UINT32 const sfVoteWeight;
|
||||
extern SF_UINT32 const sfLockCount;
|
||||
extern SF_UINT32 const sfRewardTime;
|
||||
extern SF_UINT32 const sfRewardLgrFirst;
|
||||
extern SF_UINT32 const sfRewardLgrLast;
|
||||
extern SF_UINT32 const sfFirstNFTokenSequence;
|
||||
extern SF_UINT32 const sfImportSequence;
|
||||
extern SF_UINT32 const sfXahauActivationLgrSeq;
|
||||
extern SF_UINT32 const sfOracleDocumentID;
|
||||
|
||||
// 64-bit integers (common)
|
||||
extern SF_UINT64 const sfIndexNext;
|
||||
extern SF_UINT64 const sfIndexPrevious;
|
||||
extern SF_UINT64 const sfBookNode;
|
||||
extern SF_UINT64 const sfOwnerNode;
|
||||
extern SF_UINT64 const sfBaseFee;
|
||||
extern SF_UINT64 const sfExchangeRate;
|
||||
extern SF_UINT64 const sfLowNode;
|
||||
extern SF_UINT64 const sfHighNode;
|
||||
extern SF_UINT64 const sfDestinationNode;
|
||||
extern SF_UINT64 const sfCookie;
|
||||
extern SF_UINT64 const sfServerVersion;
|
||||
extern SF_UINT64 const sfEmitBurden;
|
||||
extern SF_UINT64 const sfNFTokenOfferNode;
|
||||
|
||||
// 64-bit integers (uncommon)
|
||||
extern SF_UINT64 const sfHookInstructionCount;
|
||||
extern SF_UINT64 const sfHookReturnCode;
|
||||
extern SF_UINT64 const sfReferenceCount;
|
||||
extern SF_UINT64 const sfRewardAccumulator;
|
||||
extern SF_UINT64 const sfAccountCount;
|
||||
extern SF_UINT64 const sfAccountIndex;
|
||||
extern SF_UINT64 const sfTouchCount;
|
||||
extern SF_UINT64 const sfXChainClaimID;
|
||||
extern SF_UINT64 const sfXChainAccountCreateCount;
|
||||
extern SF_UINT64 const sfXChainAccountClaimCount;
|
||||
extern SF_UINT64 const sfAssetPrice;
|
||||
|
||||
// 128-bit
|
||||
extern SF_UINT128 const sfEmailHash;
|
||||
|
||||
// 160-bit (common)
|
||||
extern SF_UINT160 const sfTakerPaysCurrency;
|
||||
extern SF_UINT160 const sfTakerPaysIssuer;
|
||||
extern SF_UINT160 const sfTakerGetsCurrency;
|
||||
extern SF_UINT160 const sfTakerGetsIssuer;
|
||||
|
||||
// 256-bit (common)
|
||||
extern SF_UINT256 const sfLedgerHash;
|
||||
extern SF_UINT256 const sfParentHash;
|
||||
extern SF_UINT256 const sfTransactionHash;
|
||||
extern SF_UINT256 const sfAccountHash;
|
||||
extern SF_UINT256 const sfHookOn;
|
||||
extern SF_UINT256 const sfHookCanEmit;
|
||||
extern SF_UINT256 const sfPreviousTxnID;
|
||||
extern SF_UINT256 const sfLedgerIndex;
|
||||
extern SF_UINT256 const sfWalletLocator;
|
||||
extern SF_UINT256 const sfRootIndex;
|
||||
extern SF_UINT256 const sfAccountTxnID;
|
||||
extern SF_UINT256 const sfNFTokenID;
|
||||
extern SF_UINT256 const sfEmitParentTxnID;
|
||||
extern SF_UINT256 const sfEmitNonce;
|
||||
extern SF_UINT256 const sfEmitHookHash;
|
||||
extern SF_UINT256 const sfObjectID;
|
||||
extern SF_UINT256 const sfAMMID;
|
||||
|
||||
// 256-bit (uncommon)
|
||||
extern SF_UINT256 const sfBookDirectory;
|
||||
extern SF_UINT256 const sfInvoiceID;
|
||||
extern SF_UINT256 const sfNickname;
|
||||
extern SF_UINT256 const sfAmendment;
|
||||
extern SF_UINT256 const sfDigest;
|
||||
extern SF_UINT256 const sfChannel;
|
||||
extern SF_UINT256 const sfConsensusHash;
|
||||
extern SF_UINT256 const sfCheckID;
|
||||
extern SF_UINT256 const sfValidatedHash;
|
||||
extern SF_UINT256 const sfPreviousPageMin;
|
||||
extern SF_UINT256 const sfNextPageMin;
|
||||
extern SF_UINT256 const sfNFTokenBuyOffer;
|
||||
extern SF_UINT256 const sfNFTokenSellOffer;
|
||||
extern SF_UINT256 const sfHookStateKey;
|
||||
extern SF_UINT256 const sfHookHash;
|
||||
extern SF_UINT256 const sfHookNamespace;
|
||||
extern SF_UINT256 const sfHookSetTxnID;
|
||||
extern SF_UINT256 const sfOfferID;
|
||||
extern SF_UINT256 const sfEscrowID;
|
||||
extern SF_UINT256 const sfURITokenID;
|
||||
extern SF_UINT256 const sfGovernanceFlags;
|
||||
extern SF_UINT256 const sfGovernanceMarks;
|
||||
extern SF_UINT256 const sfEmittedTxnID;
|
||||
|
||||
// currency amount (common)
|
||||
extern SF_AMOUNT const sfAmount;
|
||||
extern SF_AMOUNT const sfBalance;
|
||||
extern SF_AMOUNT const sfLimitAmount;
|
||||
extern SF_AMOUNT const sfTakerPays;
|
||||
extern SF_AMOUNT const sfTakerGets;
|
||||
extern SF_AMOUNT const sfLowLimit;
|
||||
extern SF_AMOUNT const sfHighLimit;
|
||||
extern SF_AMOUNT const sfFee;
|
||||
extern SF_AMOUNT const sfSendMax;
|
||||
extern SF_AMOUNT const sfDeliverMin;
|
||||
extern SF_AMOUNT const sfLockedBalance;
|
||||
extern SF_AMOUNT const sfAmount2;
|
||||
extern SF_AMOUNT const sfEPrice;
|
||||
extern SF_AMOUNT const sfBidMin;
|
||||
extern SF_AMOUNT const sfBidMax;
|
||||
extern SF_AMOUNT const sfPrice;
|
||||
extern SF_AMOUNT const sfLPTokenBalance;
|
||||
|
||||
// currency amount (uncommon)
|
||||
extern SF_AMOUNT const sfMinimumOffer;
|
||||
extern SF_AMOUNT const sfRippleEscrow;
|
||||
extern SF_AMOUNT const sfDeliveredAmount;
|
||||
extern SF_AMOUNT const sfNFTokenBrokerFee;
|
||||
extern SF_AMOUNT const sfHookCallbackFee;
|
||||
extern SF_AMOUNT const sfLPTokenOut;
|
||||
extern SF_AMOUNT const sfLPTokenIn;
|
||||
|
||||
// currency amount (fees)
|
||||
extern SF_AMOUNT const sfBaseFeeDrops;
|
||||
extern SF_AMOUNT const sfReserveBaseDrops;
|
||||
extern SF_AMOUNT const sfReserveIncrementDrops;
|
||||
extern SF_AMOUNT const sfSignatureReward;
|
||||
extern SF_AMOUNT const sfMinAccountCreateAmount;
|
||||
|
||||
// variable length (common)
|
||||
extern SF_VL const sfPublicKey;
|
||||
extern SF_VL const sfMessageKey;
|
||||
extern SF_VL const sfSigningPubKey;
|
||||
extern SF_VL const sfTxnSignature;
|
||||
extern SF_VL const sfURI;
|
||||
extern SF_VL const sfSignature;
|
||||
extern SF_VL const sfDomain;
|
||||
extern SF_VL const sfFundCode;
|
||||
extern SF_VL const sfRemoveCode;
|
||||
extern SF_VL const sfExpireCode;
|
||||
extern SF_VL const sfCreateCode;
|
||||
extern SF_VL const sfMemoType;
|
||||
extern SF_VL const sfMemoData;
|
||||
extern SF_VL const sfMemoFormat;
|
||||
extern SF_VL const sfDIDDocument;
|
||||
extern SF_VL const sfData;
|
||||
extern SF_VL const sfAssetClass;
|
||||
extern SF_VL const sfProvider;
|
||||
|
||||
// variable length (uncommon)
|
||||
extern SF_VL const sfFulfillment;
|
||||
extern SF_VL const sfCondition;
|
||||
extern SF_VL const sfMasterSignature;
|
||||
extern SF_VL const sfUNLModifyValidator;
|
||||
extern SF_VL const sfValidatorToDisable;
|
||||
extern SF_VL const sfValidatorToReEnable;
|
||||
extern SF_VL const sfHookStateData;
|
||||
extern SF_VL const sfHookReturnString;
|
||||
extern SF_VL const sfHookParameterName;
|
||||
extern SF_VL const sfHookParameterValue;
|
||||
extern SF_VL const sfBlob;
|
||||
extern SF_VL const sfRemarkName;
|
||||
extern SF_VL const sfRemarkValue;
|
||||
|
||||
// account
|
||||
extern SF_ACCOUNT const sfAccount;
|
||||
extern SF_ACCOUNT const sfOwner;
|
||||
extern SF_ACCOUNT const sfDestination;
|
||||
extern SF_ACCOUNT const sfIssuer;
|
||||
extern SF_ACCOUNT const sfAuthorize;
|
||||
extern SF_ACCOUNT const sfUnauthorize;
|
||||
extern SF_ACCOUNT const sfRegularKey;
|
||||
extern SF_ACCOUNT const sfNFTokenMinter;
|
||||
extern SF_ACCOUNT const sfEmitCallback;
|
||||
|
||||
// account (uncommon)
|
||||
extern SF_ACCOUNT const sfHookAccount;
|
||||
extern SF_ACCOUNT const sfNFTokenMinter;
|
||||
extern SF_ACCOUNT const sfInform;
|
||||
extern SF_ACCOUNT const sfOtherChainSource;
|
||||
extern SF_ACCOUNT const sfOtherChainDestination;
|
||||
extern SF_ACCOUNT const sfAttestationSignerAccount;
|
||||
extern SF_ACCOUNT const sfAttestationRewardAccount;
|
||||
extern SF_ACCOUNT const sfLockingChainDoor;
|
||||
extern SF_ACCOUNT const sfIssuingChainDoor;
|
||||
|
||||
// path set
|
||||
extern SField const sfPaths;
|
||||
|
||||
// currency
|
||||
extern SF_CURRENCY const sfBaseAsset;
|
||||
extern SF_CURRENCY const sfQuoteAsset;
|
||||
|
||||
// issue
|
||||
extern SF_ISSUE const sfAsset;
|
||||
extern SF_ISSUE const sfAsset2;
|
||||
extern SF_ISSUE const sfLockingChainIssue;
|
||||
extern SF_ISSUE const sfIssuingChainIssue;
|
||||
|
||||
// bridge
|
||||
extern SF_XCHAIN_BRIDGE const sfXChainBridge;
|
||||
|
||||
// vector of 256-bit
|
||||
extern SF_VECTOR256 const sfIndexes;
|
||||
extern SF_VECTOR256 const sfHashes;
|
||||
extern SF_VECTOR256 const sfAmendments;
|
||||
extern SF_VECTOR256 const sfNFTokenOffers;
|
||||
extern SF_VECTOR256 const sfHookNamespaces;
|
||||
extern SF_VECTOR256 const sfURITokenIDs;
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
extern SField const sfTransactionMetaData;
|
||||
extern SField const sfCreatedNode;
|
||||
extern SField const sfDeletedNode;
|
||||
extern SField const sfModifiedNode;
|
||||
extern SField const sfPreviousFields;
|
||||
extern SField const sfFinalFields;
|
||||
extern SField const sfNewFields;
|
||||
extern SField const sfTemplateEntry;
|
||||
extern SField const sfMemo;
|
||||
extern SField const sfSignerEntry;
|
||||
extern SField const sfNFToken;
|
||||
extern SField const sfEmitDetails;
|
||||
extern SField const sfHook;
|
||||
extern SField const sfVoteEntry;
|
||||
extern SField const sfAuctionSlot;
|
||||
extern SField const sfAuthAccount;
|
||||
extern SField const sfPriceData;
|
||||
|
||||
extern SField const sfSigner;
|
||||
extern SField const sfMajority;
|
||||
extern SField const sfDisabledValidator;
|
||||
extern SField const sfEmittedTxn;
|
||||
extern SField const sfHookExecution;
|
||||
extern SField const sfHookDefinition;
|
||||
extern SField const sfHookParameter;
|
||||
extern SField const sfHookGrant;
|
||||
extern SField const sfActiveValidator;
|
||||
extern SField const sfImportVLKey;
|
||||
extern SField const sfHookEmission;
|
||||
extern SField const sfMintURIToken;
|
||||
extern SField const sfAmountEntry;
|
||||
extern SField const sfRemark;
|
||||
extern SField const sfXChainClaimProofSig;
|
||||
extern SField const sfXChainCreateAccountProofSig;
|
||||
extern SField const sfXChainClaimAttestationCollectionElement;
|
||||
extern SField const sfXChainCreateAccountAttestationCollectionElement;
|
||||
|
||||
// array of objects (common)
|
||||
// ARRAY/1 is reserved for end of array
|
||||
// extern SField const sfSigningAccounts; // Never been used.
|
||||
extern SField const sfSigners;
|
||||
extern SField const sfSignerEntries;
|
||||
extern SField const sfTemplate;
|
||||
extern SField const sfNecessary;
|
||||
extern SField const sfSufficient;
|
||||
extern SField const sfAffectedNodes;
|
||||
extern SField const sfMemos;
|
||||
extern SField const sfNFTokens;
|
||||
extern SField const sfHooks;
|
||||
extern SField const sfGenesisMint;
|
||||
extern SField const sfVoteSlots;
|
||||
extern SField const sfAuthAccounts;
|
||||
extern SField const sfPriceDataSeries;
|
||||
|
||||
// array of objects (uncommon)
|
||||
extern SField const sfMajorities;
|
||||
extern SField const sfDisabledValidators;
|
||||
extern SField const sfHookExecutions;
|
||||
extern SField const sfHookExecution;
|
||||
extern SField const sfHookParameters;
|
||||
extern SField const sfHooks;
|
||||
extern SField const sfHookGrants;
|
||||
extern SField const sfGenesisMints;
|
||||
extern SField const sfActiveValidators;
|
||||
extern SField const sfImportVLKeys;
|
||||
extern SField const sfHookEmissions;
|
||||
extern SField const sfAmounts;
|
||||
extern SField const sfRemarks;
|
||||
extern SField const sfXChainClaimAttestations;
|
||||
extern SField const sfXChainCreateAccountAttestations;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
150
include/xrpl/protocol/SOTemplate.h
Normal file
150
include/xrpl/protocol/SOTemplate.h
Normal file
@@ -0,0 +1,150 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SOTEMPLATE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SOTEMPLATE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Kind of element in each entry of an SOTemplate. */
|
||||
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
|
||||
// inner object with the default fields has to be
|
||||
// constructed with STObject::makeInnerObject()
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** An element in a SOTemplate. */
|
||||
class SOElement
|
||||
{
|
||||
// Use std::reference_wrapper so SOElement can be stored in a std::vector.
|
||||
std::reference_wrapper<SField const> sField_;
|
||||
SOEStyle style_;
|
||||
|
||||
public:
|
||||
SOElement(SField const& fieldName, SOEStyle style)
|
||||
: sField_(fieldName), style_(style)
|
||||
{
|
||||
if (!sField_.get().isUseful())
|
||||
{
|
||||
auto nm = std::to_string(fieldName.getCode());
|
||||
if (fieldName.hasName())
|
||||
nm += ": '" + fieldName.getName() + "'";
|
||||
Throw<std::runtime_error>(
|
||||
"SField (" + nm + ") in SOElement must be useful.");
|
||||
}
|
||||
}
|
||||
|
||||
SField const&
|
||||
sField() const
|
||||
{
|
||||
return sField_.get();
|
||||
}
|
||||
|
||||
SOEStyle
|
||||
style() const
|
||||
{
|
||||
return style_;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Defines the fields and their attributes within a STObject.
|
||||
Each subclass of SerializedObject will provide its own template
|
||||
describing the available fields and their metadata attributes.
|
||||
*/
|
||||
class SOTemplate
|
||||
{
|
||||
public:
|
||||
// Copying vectors is expensive. Make this a move-only type until
|
||||
// there is motivation to change that.
|
||||
SOTemplate(SOTemplate&& other) = default;
|
||||
SOTemplate&
|
||||
operator=(SOTemplate&& other) = default;
|
||||
|
||||
/** Create a template populated with all fields.
|
||||
After creating the template fields cannot be
|
||||
added, modified, or removed.
|
||||
*/
|
||||
SOTemplate(
|
||||
std::initializer_list<SOElement> uniqueFields,
|
||||
std::initializer_list<SOElement> commonFields = {});
|
||||
|
||||
/* Provide for the enumeration of fields */
|
||||
std::vector<SOElement>::const_iterator
|
||||
begin() const
|
||||
{
|
||||
return elements_.cbegin();
|
||||
}
|
||||
|
||||
std::vector<SOElement>::const_iterator
|
||||
cbegin() const
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
|
||||
std::vector<SOElement>::const_iterator
|
||||
end() const
|
||||
{
|
||||
return elements_.cend();
|
||||
}
|
||||
|
||||
std::vector<SOElement>::const_iterator
|
||||
cend() const
|
||||
{
|
||||
return end();
|
||||
}
|
||||
|
||||
/** The number of entries in this template */
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return elements_.size();
|
||||
}
|
||||
|
||||
/** Retrieve the position of a named field. */
|
||||
int
|
||||
getIndex(SField const&) const;
|
||||
|
||||
SOEStyle
|
||||
style(SField const& sf) const
|
||||
{
|
||||
return elements_[indices_[sf.getNum()]].style();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<SOElement> elements_;
|
||||
std::vector<int> indices_; // field num -> index
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
136
include/xrpl/protocol/STAccount.h
Normal file
136
include/xrpl/protocol/STAccount.h
Normal file
@@ -0,0 +1,136 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STACCOUNT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STACCOUNT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
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 ripple::uint160. However, so the serialized format of the
|
||||
// STAccount stays unchanged, we serialize and deserialize like an STBlob.
|
||||
AccountID value_;
|
||||
bool default_;
|
||||
|
||||
public:
|
||||
using value_type = AccountID;
|
||||
|
||||
STAccount();
|
||||
|
||||
STAccount(SField const& n);
|
||||
STAccount(SField const& n, Buffer&& v);
|
||||
STAccount(SerialIter& sit, SField const& name);
|
||||
STAccount(SField const& n, AccountID const& v);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
STAccount&
|
||||
operator=(AccountID const& value);
|
||||
|
||||
AccountID const&
|
||||
value() const noexcept;
|
||||
|
||||
void
|
||||
setValue(AccountID const& v);
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
inline STAccount&
|
||||
STAccount::operator=(AccountID const& value)
|
||||
{
|
||||
setValue(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STAccount::value() const noexcept
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline void
|
||||
STAccount::setValue(AccountID const& v)
|
||||
{
|
||||
value_ = v;
|
||||
default_ = false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STAccount const& lhs, STAccount const& rhs)
|
||||
{
|
||||
return lhs.value() == rhs.value();
|
||||
}
|
||||
|
||||
inline auto
|
||||
operator<(STAccount const& lhs, STAccount const& rhs)
|
||||
{
|
||||
return lhs.value() < rhs.value();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STAccount const& lhs, AccountID const& rhs)
|
||||
{
|
||||
return lhs.value() == rhs;
|
||||
}
|
||||
|
||||
inline auto
|
||||
operator<(STAccount const& lhs, AccountID const& rhs)
|
||||
{
|
||||
return lhs.value() < rhs;
|
||||
}
|
||||
|
||||
inline auto
|
||||
operator<(AccountID const& lhs, STAccount const& rhs)
|
||||
{
|
||||
return lhs < rhs.value();
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
653
include/xrpl/protocol/STAmount.h
Normal file
653
include/xrpl/protocol/STAmount.h
Normal file
@@ -0,0 +1,653 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STAMOUNT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STAMOUNT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/basics/IOUAmount.h>
|
||||
#include <ripple/basics/LocalValue.h>
|
||||
#include <ripple/basics/Number.h>
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
#include <ripple/protocol/Issue.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <ripple/protocol/json_get_or_throw.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// Internal form:
|
||||
// 1: If amount is zero, then value is zero and offset is -100
|
||||
// 2: Otherwise:
|
||||
// legal offset range is -96 to +80 inclusive
|
||||
// value range is 10^15 to (10^16 - 1) inclusive
|
||||
// amount = value * [10 ^ offset]
|
||||
|
||||
// Wire form:
|
||||
// High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
|
||||
// Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
|
||||
class STAmount final : public STBase, public CountedObject<STAmount>
|
||||
{
|
||||
public:
|
||||
using mantissa_type = std::uint64_t;
|
||||
using exponent_type = int;
|
||||
using rep = std::pair<mantissa_type, exponent_type>;
|
||||
|
||||
private:
|
||||
Issue mIssue;
|
||||
mantissa_type mValue;
|
||||
exponent_type mOffset;
|
||||
bool mIsNative; // A shorthand for isXRP(mIssue).
|
||||
bool mIsNegative;
|
||||
|
||||
public:
|
||||
using value_type = STAmount;
|
||||
|
||||
static const int cMinOffset = -96;
|
||||
static const int cMaxOffset = 80;
|
||||
|
||||
// Maximum native value supported by the code
|
||||
static const std::uint64_t cMinValue = 1000000000000000ull;
|
||||
static const std::uint64_t cMaxValue = 9999999999999999ull;
|
||||
static const std::uint64_t cMaxNative = 9000000000000000000ull;
|
||||
|
||||
// Max native value on network.
|
||||
static const std::uint64_t cMaxNativeN = 100000000000000000ull;
|
||||
static const std::uint64_t cNotNative = 0x8000000000000000ull;
|
||||
static const std::uint64_t cPosNative = 0x4000000000000000ull;
|
||||
|
||||
static std::uint64_t const uRateOne;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
STAmount(SerialIter& sit, SField const& name);
|
||||
|
||||
struct unchecked
|
||||
{
|
||||
explicit unchecked() = default;
|
||||
};
|
||||
|
||||
// Do not call canonicalize
|
||||
STAmount(
|
||||
SField const& name,
|
||||
Issue const& issue,
|
||||
mantissa_type mantissa,
|
||||
exponent_type exponent,
|
||||
bool native,
|
||||
bool negative,
|
||||
unchecked);
|
||||
|
||||
STAmount(
|
||||
Issue const& issue,
|
||||
mantissa_type mantissa,
|
||||
exponent_type exponent,
|
||||
bool native,
|
||||
bool negative,
|
||||
unchecked);
|
||||
|
||||
// Call canonicalize
|
||||
STAmount(
|
||||
SField const& name,
|
||||
Issue const& issue,
|
||||
mantissa_type mantissa,
|
||||
exponent_type exponent,
|
||||
bool native,
|
||||
bool negative);
|
||||
|
||||
STAmount(SField const& name, std::int64_t mantissa);
|
||||
|
||||
STAmount(
|
||||
SField const& name,
|
||||
std::uint64_t mantissa = 0,
|
||||
bool negative = false);
|
||||
|
||||
STAmount(
|
||||
SField const& name,
|
||||
Issue const& issue,
|
||||
std::uint64_t mantissa = 0,
|
||||
int exponent = 0,
|
||||
bool negative = false);
|
||||
|
||||
explicit STAmount(std::uint64_t mantissa = 0, bool negative = false);
|
||||
|
||||
explicit STAmount(SField const& name, STAmount const& amt);
|
||||
|
||||
STAmount(
|
||||
Issue const& issue,
|
||||
std::uint64_t mantissa = 0,
|
||||
int exponent = 0,
|
||||
bool negative = false);
|
||||
|
||||
// VFALCO Is this needed when we have the previous signature?
|
||||
STAmount(
|
||||
Issue const& issue,
|
||||
std::uint32_t mantissa,
|
||||
int exponent = 0,
|
||||
bool negative = false);
|
||||
|
||||
STAmount(Issue const& issue, std::int64_t mantissa, int exponent = 0);
|
||||
|
||||
STAmount(Issue const& issue, int mantissa, int exponent = 0);
|
||||
|
||||
// Legacy support for new-style amounts
|
||||
STAmount(IOUAmount const& amount, Issue const& issue);
|
||||
STAmount(XRPAmount const& amount);
|
||||
operator Number() const;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Observers
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
int
|
||||
exponent() const noexcept;
|
||||
|
||||
bool
|
||||
native() const noexcept;
|
||||
|
||||
bool
|
||||
negative() const noexcept;
|
||||
|
||||
std::uint64_t
|
||||
mantissa() const noexcept;
|
||||
|
||||
Issue const&
|
||||
issue() const;
|
||||
|
||||
// These three are deprecated
|
||||
Currency const&
|
||||
getCurrency() const;
|
||||
|
||||
AccountID const&
|
||||
getIssuer() const;
|
||||
|
||||
int
|
||||
signum() const noexcept;
|
||||
|
||||
/** Returns a zero value with the same issuer and currency. */
|
||||
STAmount
|
||||
zeroed() const;
|
||||
|
||||
void
|
||||
setJson(Json::Value&) const;
|
||||
|
||||
STAmount const&
|
||||
value() const noexcept;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Operators
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
STAmount&
|
||||
operator+=(STAmount const&);
|
||||
STAmount&
|
||||
operator-=(STAmount const&);
|
||||
|
||||
STAmount& operator=(beast::Zero);
|
||||
|
||||
STAmount&
|
||||
operator=(XRPAmount const& amount);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Modification
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
negate();
|
||||
|
||||
void
|
||||
clear();
|
||||
|
||||
// Zero while copying currency and issuer.
|
||||
void
|
||||
clear(STAmount const& saTmpl);
|
||||
|
||||
void
|
||||
clear(Issue const& issue);
|
||||
|
||||
void
|
||||
setIssuer(AccountID const& uIssuer);
|
||||
|
||||
/** Set the Issue for this amount and update mIsNative. */
|
||||
void
|
||||
setIssue(Issue const& issue);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// STBase
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getFullText() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
XRPAmount
|
||||
xrp() const;
|
||||
IOUAmount
|
||||
iou() const;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<STAmount>
|
||||
construct(SerialIter&, SField const& name);
|
||||
|
||||
void
|
||||
set(std::int64_t v);
|
||||
void
|
||||
canonicalize();
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
STAmount&
|
||||
operator=(IOUAmount const& iou);
|
||||
|
||||
friend class detail::STVar;
|
||||
|
||||
friend STAmount
|
||||
operator+(STAmount const& v1, STAmount const& v2);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Creation
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// VFALCO TODO The parameter type should be Quality not uint64_t
|
||||
STAmount
|
||||
amountFromQuality(std::uint64_t rate);
|
||||
|
||||
STAmount
|
||||
amountFromString(Issue const& issue, std::string const& amount);
|
||||
|
||||
STAmount
|
||||
amountFromJson(SField const& name, Json::Value const& v);
|
||||
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Observers
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline int
|
||||
STAmount::exponent() const noexcept
|
||||
{
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STAmount::native() const noexcept
|
||||
{
|
||||
return mIsNative;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STAmount::negative() const noexcept
|
||||
{
|
||||
return mIsNegative;
|
||||
}
|
||||
|
||||
inline std::uint64_t
|
||||
STAmount::mantissa() const noexcept
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
inline Issue const&
|
||||
STAmount::issue() const
|
||||
{
|
||||
return mIssue;
|
||||
}
|
||||
|
||||
inline Currency const&
|
||||
STAmount::getCurrency() const
|
||||
{
|
||||
return mIssue.currency;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STAmount::getIssuer() const
|
||||
{
|
||||
return mIssue.account;
|
||||
}
|
||||
|
||||
inline int
|
||||
STAmount::signum() const noexcept
|
||||
{
|
||||
return mValue ? (mIsNegative ? -1 : 1) : 0;
|
||||
}
|
||||
|
||||
inline STAmount
|
||||
STAmount::zeroed() const
|
||||
{
|
||||
return STAmount(mIssue);
|
||||
}
|
||||
|
||||
inline STAmount::operator bool() const noexcept
|
||||
{
|
||||
return *this != beast::zero;
|
||||
}
|
||||
|
||||
inline STAmount::operator Number() const
|
||||
{
|
||||
if (mIsNative)
|
||||
return xrp();
|
||||
return iou();
|
||||
}
|
||||
|
||||
inline STAmount& STAmount::operator=(beast::Zero)
|
||||
{
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline STAmount&
|
||||
STAmount::operator=(XRPAmount const& amount)
|
||||
{
|
||||
*this = STAmount(amount);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void
|
||||
STAmount::negate()
|
||||
{
|
||||
if (*this != beast::zero)
|
||||
mIsNegative = !mIsNegative;
|
||||
}
|
||||
|
||||
inline void
|
||||
STAmount::clear()
|
||||
{
|
||||
// The -100 is used to allow 0 to sort less than a small positive values
|
||||
// which have a negative exponent.
|
||||
mOffset = mIsNative ? 0 : -100;
|
||||
mValue = 0;
|
||||
mIsNegative = false;
|
||||
}
|
||||
|
||||
// Zero while copying currency and issuer.
|
||||
inline void
|
||||
STAmount::clear(STAmount const& saTmpl)
|
||||
{
|
||||
clear(saTmpl.mIssue);
|
||||
}
|
||||
|
||||
inline void
|
||||
STAmount::clear(Issue const& issue)
|
||||
{
|
||||
setIssue(issue);
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void
|
||||
STAmount::setIssuer(AccountID const& uIssuer)
|
||||
{
|
||||
mIssue.account = uIssuer;
|
||||
setIssue(mIssue);
|
||||
}
|
||||
|
||||
inline STAmount const&
|
||||
STAmount::value() const noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isLegalNet(STAmount const& value)
|
||||
{
|
||||
return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Operators
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
operator==(STAmount const& lhs, STAmount const& rhs);
|
||||
bool
|
||||
operator<(STAmount const& lhs, STAmount const& rhs);
|
||||
|
||||
inline bool
|
||||
operator!=(STAmount const& lhs, STAmount const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(STAmount const& lhs, STAmount const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(STAmount const& lhs, STAmount const& rhs)
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>=(STAmount const& lhs, STAmount const& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
STAmount
|
||||
operator-(STAmount const& value);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Arithmetic
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
STAmount
|
||||
operator+(STAmount const& v1, STAmount const& v2);
|
||||
STAmount
|
||||
operator-(STAmount const& v1, STAmount const& v2);
|
||||
|
||||
STAmount
|
||||
divide(STAmount const& v1, STAmount const& v2, Issue const& issue);
|
||||
|
||||
STAmount
|
||||
multiply(STAmount const& v1, STAmount const& v2, Issue const& issue);
|
||||
|
||||
// multiply rounding result in specified direction
|
||||
STAmount
|
||||
mulRound(
|
||||
STAmount const& v1,
|
||||
STAmount const& v2,
|
||||
Issue const& issue,
|
||||
bool roundUp);
|
||||
|
||||
// multiply following the rounding directions more precisely.
|
||||
STAmount
|
||||
mulRoundStrict(
|
||||
STAmount const& v1,
|
||||
STAmount const& v2,
|
||||
Issue const& issue,
|
||||
bool roundUp);
|
||||
|
||||
// divide rounding result in specified direction
|
||||
STAmount
|
||||
divRound(
|
||||
STAmount const& v1,
|
||||
STAmount const& v2,
|
||||
Issue const& issue,
|
||||
bool roundUp);
|
||||
|
||||
// divide following the rounding directions more precisely.
|
||||
STAmount
|
||||
divRoundStrict(
|
||||
STAmount const& v1,
|
||||
STAmount const& v2,
|
||||
Issue const& issue,
|
||||
bool roundUp);
|
||||
|
||||
// Someone is offering X for Y, what is the rate?
|
||||
// Rate: smaller is better, the taker wants the most out: in/out
|
||||
// VFALCO TODO Return a Quality object
|
||||
std::uint64_t
|
||||
getRate(STAmount const& offerOut, STAmount const& offerIn);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline bool
|
||||
isXRP(STAmount const& amount)
|
||||
{
|
||||
return isXRP(amount.issue().currency);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isBadCurrency(STAmount const& amount)
|
||||
{
|
||||
if (amount.native())
|
||||
return false;
|
||||
|
||||
return isBadCurrency(amount.issue().currency);
|
||||
}
|
||||
|
||||
/** returns true iff adding or subtracting results in less than or equal to
|
||||
* 0.01% precision loss **/
|
||||
inline bool
|
||||
isAddable(STAmount const& amt1, STAmount const& amt2)
|
||||
{
|
||||
// special case: adding anything to zero is always fine
|
||||
if (amt1 == beast::zero || amt2 == beast::zero)
|
||||
return true;
|
||||
|
||||
// special case: adding two xrp amounts together.
|
||||
// this is just an overflow check
|
||||
if (isXRP(amt1) && isXRP(amt2))
|
||||
{
|
||||
XRPAmount A = (amt1.signum() == -1 ? -(amt1.xrp()) : amt1.xrp());
|
||||
XRPAmount B = (amt2.signum() == -1 ? -(amt2.xrp()) : amt2.xrp());
|
||||
|
||||
XRPAmount finalAmt = A + B;
|
||||
return (finalAmt >= A && finalAmt >= B);
|
||||
}
|
||||
|
||||
static const STAmount one{IOUAmount{1, 0}, noIssue()};
|
||||
static const STAmount maxLoss{IOUAmount{1, -4}, noIssue()};
|
||||
|
||||
STAmount A = amt1;
|
||||
STAmount B = amt2;
|
||||
|
||||
if (isXRP(A))
|
||||
A = STAmount{IOUAmount{A.xrp().drops(), -6}, noIssue()};
|
||||
|
||||
if (isXRP(B))
|
||||
B = STAmount{IOUAmount{B.xrp().drops(), -6}, noIssue()};
|
||||
|
||||
A.setIssue(noIssue());
|
||||
B.setIssue(noIssue());
|
||||
|
||||
STAmount lhs = divide((A - B) + B, A, noIssue()) - one;
|
||||
STAmount rhs = divide((B - A) + A, B, noIssue()) - one;
|
||||
|
||||
return ((rhs.negative() ? -rhs : rhs) + (lhs.negative() ? -lhs : lhs)) <=
|
||||
maxLoss;
|
||||
}
|
||||
|
||||
// Since `canonicalize` does not have access to a ledger, this is needed to put
|
||||
// the low-level routine stAmountCanonicalize on an amendment switch. Only
|
||||
// transactions need to use this switchover. Outside of a transaction it's safe
|
||||
// to unconditionally use the new behavior.
|
||||
|
||||
bool
|
||||
getSTAmountCanonicalizeSwitchover();
|
||||
|
||||
void
|
||||
setSTAmountCanonicalizeSwitchover(bool v);
|
||||
|
||||
/** RAII class to set and restore the STAmount canonicalize switchover.
|
||||
*/
|
||||
|
||||
class STAmountSO
|
||||
{
|
||||
public:
|
||||
explicit STAmountSO(bool v) : saved_(getSTAmountCanonicalizeSwitchover())
|
||||
{
|
||||
setSTAmountCanonicalizeSwitchover(v);
|
||||
}
|
||||
|
||||
~STAmountSO()
|
||||
{
|
||||
setSTAmountCanonicalizeSwitchover(saved_);
|
||||
}
|
||||
|
||||
private:
|
||||
bool saved_;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
namespace Json {
|
||||
template <>
|
||||
inline ripple::STAmount
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
Json::StaticString const& key = field.getJsonName();
|
||||
if (!v.isMember(key))
|
||||
Throw<JsonMissingKeyError>(key);
|
||||
Json::Value const& inner = v[key];
|
||||
return amountFromJson(field, inner);
|
||||
}
|
||||
} // namespace Json
|
||||
#endif
|
||||
318
include/xrpl/protocol/STArray.h
Normal file
318
include/xrpl/protocol/STArray.h
Normal file
@@ -0,0 +1,318 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STARRAY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STARRAY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class STArray final : public STBase, public CountedObject<STArray>
|
||||
{
|
||||
private:
|
||||
using list_type = std::vector<STObject>;
|
||||
|
||||
list_type v_;
|
||||
|
||||
public:
|
||||
using value_type = STObject;
|
||||
using size_type = list_type::size_type;
|
||||
using iterator = list_type::iterator;
|
||||
using const_iterator = list_type::const_iterator;
|
||||
|
||||
// RH NOTE: please don't delete this constructor
|
||||
STArray(std::vector<STObject> const& v, SField const& f);
|
||||
|
||||
STArray() = default;
|
||||
STArray(STArray const&) = default;
|
||||
|
||||
template <
|
||||
class Iter,
|
||||
class = std::enable_if_t<std::is_convertible_v<
|
||||
typename std::iterator_traits<Iter>::reference,
|
||||
STObject>>>
|
||||
explicit STArray(Iter first, Iter last);
|
||||
|
||||
template <
|
||||
class Iter,
|
||||
class = std::enable_if_t<std::is_convertible_v<
|
||||
typename std::iterator_traits<Iter>::reference,
|
||||
STObject>>>
|
||||
STArray(SField const& f, Iter first, Iter last);
|
||||
|
||||
STArray&
|
||||
operator=(STArray const&) = default;
|
||||
STArray(STArray&&);
|
||||
STArray&
|
||||
operator=(STArray&&);
|
||||
|
||||
STArray(SField const& f, std::size_t n);
|
||||
STArray(SerialIter& sit, SField const& f, int depth = 0);
|
||||
explicit STArray(int n);
|
||||
explicit STArray(SField const& f);
|
||||
|
||||
STObject&
|
||||
operator[](std::size_t j);
|
||||
|
||||
STObject const&
|
||||
operator[](std::size_t j) const;
|
||||
|
||||
STObject&
|
||||
back();
|
||||
|
||||
STObject const&
|
||||
back() const;
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
emplace_back(Args&&... args);
|
||||
|
||||
void
|
||||
push_back(STObject const& object);
|
||||
|
||||
void
|
||||
push_back(STObject&& object);
|
||||
|
||||
iterator
|
||||
begin();
|
||||
|
||||
iterator
|
||||
end();
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
size_type
|
||||
size() const;
|
||||
|
||||
bool
|
||||
empty() const;
|
||||
|
||||
void
|
||||
clear();
|
||||
|
||||
void
|
||||
reserve(std::size_t n);
|
||||
|
||||
void
|
||||
swap(STArray& a) noexcept;
|
||||
|
||||
std::string
|
||||
getFullText() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value
|
||||
getJson(JsonOptions index) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
void
|
||||
sort(bool (*compare)(const STObject& o1, const STObject& o2));
|
||||
|
||||
bool
|
||||
operator==(const STArray& s) const;
|
||||
|
||||
bool
|
||||
operator!=(const STArray& s) const;
|
||||
|
||||
iterator
|
||||
erase(iterator pos);
|
||||
|
||||
iterator
|
||||
erase(const_iterator pos);
|
||||
|
||||
iterator
|
||||
erase(iterator first, iterator last);
|
||||
|
||||
iterator
|
||||
erase(const_iterator first, const_iterator last);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
template <class Iter, class>
|
||||
STArray::STArray(Iter first, Iter last) : v_(first, last)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Iter, class>
|
||||
STArray::STArray(SField const& f, Iter first, Iter last)
|
||||
: STBase(f), v_(first, last)
|
||||
{
|
||||
}
|
||||
|
||||
inline STObject&
|
||||
STArray::operator[](std::size_t j)
|
||||
{
|
||||
return v_[j];
|
||||
}
|
||||
|
||||
inline STObject const&
|
||||
STArray::operator[](std::size_t j) const
|
||||
{
|
||||
return v_[j];
|
||||
}
|
||||
|
||||
inline STObject&
|
||||
STArray::back()
|
||||
{
|
||||
return v_.back();
|
||||
}
|
||||
|
||||
inline STObject const&
|
||||
STArray::back() const
|
||||
{
|
||||
return v_.back();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
inline void
|
||||
STArray::emplace_back(Args&&... args)
|
||||
{
|
||||
v_.emplace_back(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline void
|
||||
STArray::push_back(STObject const& object)
|
||||
{
|
||||
v_.push_back(object);
|
||||
}
|
||||
|
||||
inline void
|
||||
STArray::push_back(STObject&& object)
|
||||
{
|
||||
v_.push_back(std::move(object));
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::begin()
|
||||
{
|
||||
return v_.begin();
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::end()
|
||||
{
|
||||
return v_.end();
|
||||
}
|
||||
|
||||
inline STArray::const_iterator
|
||||
STArray::begin() const
|
||||
{
|
||||
return v_.begin();
|
||||
}
|
||||
|
||||
inline STArray::const_iterator
|
||||
STArray::end() const
|
||||
{
|
||||
return v_.end();
|
||||
}
|
||||
|
||||
inline STArray::size_type
|
||||
STArray::size() const
|
||||
{
|
||||
return v_.size();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STArray::empty() const
|
||||
{
|
||||
return v_.empty();
|
||||
}
|
||||
|
||||
inline void
|
||||
STArray::clear()
|
||||
{
|
||||
v_.clear();
|
||||
}
|
||||
|
||||
inline void
|
||||
STArray::reserve(std::size_t n)
|
||||
{
|
||||
v_.reserve(n);
|
||||
}
|
||||
|
||||
inline void
|
||||
STArray::swap(STArray& a) noexcept
|
||||
{
|
||||
v_.swap(a.v_);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STArray::operator==(const STArray& s) const
|
||||
{
|
||||
return v_ == s.v_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STArray::operator!=(const STArray& s) const
|
||||
{
|
||||
return v_ != s.v_;
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::erase(iterator pos)
|
||||
{
|
||||
return v_.erase(pos);
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::erase(const_iterator pos)
|
||||
{
|
||||
return v_.erase(pos);
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::erase(iterator first, iterator last)
|
||||
{
|
||||
return v_.erase(first, last);
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
return v_.erase(first, last);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
230
include/xrpl/protocol/STBase.h
Normal file
230
include/xrpl/protocol/STBase.h
Normal file
@@ -0,0 +1,230 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STBASE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STBASE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
namespace ripple {
|
||||
|
||||
/// Note, should be treated as flags that can be | and &
|
||||
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,
|
||||
|
||||
// IMPORTANT `_all` must be union of all of the above; see also operator~
|
||||
_all = 0b0000'0011
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
constexpr JsonOptions(underlying_t v) noexcept : value(v)
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr explicit operator underlying_t() const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
[[nodiscard]] constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return value != 0u;
|
||||
}
|
||||
[[nodiscard]] constexpr auto friend
|
||||
operator==(JsonOptions lh, JsonOptions rh) noexcept -> bool = default;
|
||||
[[nodiscard]] constexpr auto friend
|
||||
operator!=(JsonOptions lh, JsonOptions rh) noexcept -> bool = default;
|
||||
|
||||
/// Returns JsonOptions union of lh and rh
|
||||
[[nodiscard]] constexpr JsonOptions friend
|
||||
operator|(JsonOptions lh, JsonOptions rh) noexcept
|
||||
{
|
||||
return {lh.value | rh.value};
|
||||
}
|
||||
|
||||
/// Returns JsonOptions intersection of lh and rh
|
||||
[[nodiscard]] constexpr JsonOptions friend
|
||||
operator&(JsonOptions lh, JsonOptions rh) noexcept
|
||||
{
|
||||
return {lh.value & rh.value};
|
||||
}
|
||||
|
||||
/// Returns JsonOptions binary negation, can be used with & (above) for set
|
||||
/// difference e.g. `(options & ~JsonOptions::include_date)`
|
||||
[[nodiscard]] constexpr JsonOptions friend
|
||||
operator~(JsonOptions v) noexcept
|
||||
{
|
||||
return {~v.value & static_cast<underlying_t>(_all)};
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
class STVar;
|
||||
}
|
||||
|
||||
// VFALCO TODO fix this restriction on copy assignment.
|
||||
//
|
||||
// CAUTION: Do not create a vector (or similar container) of any object derived
|
||||
// from STBase. Use Boost ptr_* containers. The copy assignment operator
|
||||
// of STBase has semantics that will cause contained types to change
|
||||
// their names when an object is deleted because copy assignment is used to
|
||||
// "slide down" the remaining types and this will not copy the field
|
||||
// name. Changing the copy assignment operator to copy the field name breaks the
|
||||
// use of copy assignment just to copy values, which is used in the transaction
|
||||
// engine code.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A type which can be exported to a well known binary format.
|
||||
|
||||
A STBase:
|
||||
- Always a field
|
||||
- Can always go inside an eligible enclosing STBase
|
||||
(such as STArray)
|
||||
- Has a field name
|
||||
|
||||
Like JSON, a SerializedObject is a basket which has rules
|
||||
on what it can hold.
|
||||
|
||||
@note "ST" stands for "Serialized Type."
|
||||
*/
|
||||
class STBase
|
||||
{
|
||||
SField const* fName;
|
||||
|
||||
public:
|
||||
virtual ~STBase() = default;
|
||||
STBase();
|
||||
STBase(const STBase&) = default;
|
||||
STBase&
|
||||
operator=(const STBase& t);
|
||||
|
||||
explicit STBase(SField const& n);
|
||||
|
||||
bool
|
||||
operator==(const STBase& t) const;
|
||||
bool
|
||||
operator!=(const STBase& t) const;
|
||||
|
||||
template <class D>
|
||||
D&
|
||||
downcast();
|
||||
|
||||
template <class D>
|
||||
D const&
|
||||
downcast() const;
|
||||
|
||||
virtual SerializedTypeID
|
||||
getSType() const;
|
||||
|
||||
virtual std::string
|
||||
getFullText() const;
|
||||
|
||||
virtual std::string
|
||||
getText() const;
|
||||
|
||||
virtual Json::Value getJson(JsonOptions /*options*/) const;
|
||||
|
||||
virtual void
|
||||
add(Serializer& s) const;
|
||||
|
||||
virtual bool
|
||||
isEquivalent(STBase const& t) const;
|
||||
|
||||
virtual bool
|
||||
isDefault() const;
|
||||
|
||||
/** A STBase is a field.
|
||||
This sets the name.
|
||||
*/
|
||||
void
|
||||
setFName(SField const& n);
|
||||
|
||||
SField const&
|
||||
getFName() const;
|
||||
|
||||
void
|
||||
addFieldID(Serializer& s) const;
|
||||
|
||||
protected:
|
||||
template <class T>
|
||||
static STBase*
|
||||
emplace(std::size_t n, void* buf, T&& val);
|
||||
|
||||
private:
|
||||
virtual STBase*
|
||||
copy(std::size_t n, void* buf) const;
|
||||
virtual STBase*
|
||||
move(std::size_t n, void* buf);
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, const STBase& t);
|
||||
|
||||
template <class D>
|
||||
D&
|
||||
STBase::downcast()
|
||||
{
|
||||
D* ptr = dynamic_cast<D*>(this);
|
||||
if (ptr == nullptr)
|
||||
Throw<std::bad_cast>();
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <class D>
|
||||
D const&
|
||||
STBase::downcast() const
|
||||
{
|
||||
D const* ptr = dynamic_cast<D const*>(this);
|
||||
if (ptr == nullptr)
|
||||
Throw<std::bad_cast>();
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
STBase*
|
||||
STBase::emplace(std::size_t n, void* buf, T&& val)
|
||||
{
|
||||
using U = std::decay_t<T>;
|
||||
if (sizeof(U) > n)
|
||||
return new U(std::forward<T>(val));
|
||||
return new (buf) U(std::forward<T>(val));
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
200
include/xrpl/protocol/STBitString.h
Normal file
200
include/xrpl/protocol/STBitString.h
Normal file
@@ -0,0 +1,200 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STBITSTRING_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STBITSTRING_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/beast/utility/Zero.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// The template parameter could be an unsigned type, however there's a bug in
|
||||
// gdb (last checked in gdb 12.1) that prevents gdb from finding the RTTI
|
||||
// information of a template parameterized by an unsigned type. This RTTI
|
||||
// information is needed to write gdb pretty printers.
|
||||
template <int Bits>
|
||||
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>;
|
||||
|
||||
private:
|
||||
value_type value_;
|
||||
|
||||
public:
|
||||
STBitString() = default;
|
||||
|
||||
STBitString(SField const& n);
|
||||
STBitString(const value_type& v);
|
||||
STBitString(SField const& n, const value_type& v);
|
||||
STBitString(SerialIter& sit, SField const& name);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
template <typename Tag>
|
||||
void
|
||||
setValue(base_uint<Bits, Tag> const& v);
|
||||
|
||||
value_type const&
|
||||
value() const;
|
||||
|
||||
operator value_type() const;
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
using STUInt128 = STBitString<128>;
|
||||
using STUInt160 = STBitString<160>;
|
||||
using STUInt256 = STBitString<256>;
|
||||
|
||||
template <int Bits>
|
||||
inline STBitString<Bits>::STBitString(SField const& n) : STBase(n)
|
||||
{
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
inline STBitString<Bits>::STBitString(const value_type& v) : value_(v)
|
||||
{
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
inline STBitString<Bits>::STBitString(SField const& n, const value_type& v)
|
||||
: STBase(n), value_(v)
|
||||
{
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
inline STBitString<Bits>::STBitString(SerialIter& sit, SField const& name)
|
||||
: STBitString(name, sit.getBitString<Bits>())
|
||||
{
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
STBase*
|
||||
STBitString<Bits>::copy(std::size_t n, void* buf) const
|
||||
{
|
||||
return emplace(n, buf, *this);
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
STBase*
|
||||
STBitString<Bits>::move(std::size_t n, void* buf)
|
||||
{
|
||||
return emplace(n, buf, std::move(*this));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline SerializedTypeID
|
||||
STUInt128::getSType() const
|
||||
{
|
||||
return STI_UINT128;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline SerializedTypeID
|
||||
STUInt160::getSType() const
|
||||
{
|
||||
return STI_UINT160;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline SerializedTypeID
|
||||
STUInt256::getSType() const
|
||||
{
|
||||
return STI_UINT256;
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
std::string
|
||||
STBitString<Bits>::getText() const
|
||||
{
|
||||
return to_string(value_);
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
bool
|
||||
STBitString<Bits>::isEquivalent(const STBase& t) const
|
||||
{
|
||||
const STBitString* v = dynamic_cast<const STBitString*>(&t);
|
||||
return v && (value_ == v->value_);
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
void
|
||||
STBitString<Bits>::add(Serializer& s) const
|
||||
{
|
||||
assert(getFName().isBinary());
|
||||
assert(getFName().fieldType == getSType());
|
||||
s.addBitString<Bits>(value_);
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
template <typename Tag>
|
||||
void
|
||||
STBitString<Bits>::setValue(base_uint<Bits, Tag> const& v)
|
||||
{
|
||||
value_ = v;
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
typename STBitString<Bits>::value_type const&
|
||||
STBitString<Bits>::value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
STBitString<Bits>::operator value_type() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
template <int Bits>
|
||||
bool
|
||||
STBitString<Bits>::isDefault() const
|
||||
{
|
||||
return value_ == beast::zero;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
151
include/xrpl/protocol/STBlob.h
Normal file
151
include/xrpl/protocol/STBlob.h
Normal file
@@ -0,0 +1,151 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STBLOB_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STBLOB_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// variable length byte string
|
||||
class STBlob : public STBase, public CountedObject<STBlob>
|
||||
{
|
||||
Buffer value_;
|
||||
|
||||
public:
|
||||
using value_type = Slice;
|
||||
|
||||
STBlob() = default;
|
||||
STBlob(STBlob const& rhs);
|
||||
|
||||
STBlob(SField const& f, void const* data, std::size_t size);
|
||||
STBlob(SField const& f, Buffer&& b);
|
||||
STBlob(SField const& n);
|
||||
STBlob(SerialIter&, SField const& name = sfGeneric);
|
||||
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
std::uint8_t const*
|
||||
data() const;
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
STBlob&
|
||||
operator=(Slice const& slice);
|
||||
|
||||
value_type
|
||||
value() const noexcept;
|
||||
|
||||
STBlob&
|
||||
operator=(Buffer&& buffer);
|
||||
|
||||
void
|
||||
setValue(Buffer&& b);
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
inline STBlob::STBlob(STBlob const& rhs)
|
||||
: STBase(rhs), CountedObject<STBlob>(rhs), value_(rhs.data(), rhs.size())
|
||||
{
|
||||
}
|
||||
|
||||
inline STBlob::STBlob(SField const& f, void const* data, std::size_t size)
|
||||
: STBase(f), value_(data, size)
|
||||
{
|
||||
}
|
||||
|
||||
inline STBlob::STBlob(SField const& f, Buffer&& b)
|
||||
: STBase(f), value_(std::move(b))
|
||||
{
|
||||
}
|
||||
|
||||
inline STBlob::STBlob(SField const& n) : STBase(n)
|
||||
{
|
||||
}
|
||||
|
||||
inline std::size_t
|
||||
STBlob::size() const
|
||||
{
|
||||
return value_.size();
|
||||
}
|
||||
|
||||
inline std::uint8_t const*
|
||||
STBlob::data() const
|
||||
{
|
||||
return reinterpret_cast<std::uint8_t const*>(value_.data());
|
||||
}
|
||||
|
||||
inline STBlob&
|
||||
STBlob::operator=(Slice const& slice)
|
||||
{
|
||||
value_ = Buffer(slice.data(), slice.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline STBlob::value_type
|
||||
STBlob::value() const noexcept
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline STBlob&
|
||||
STBlob::operator=(Buffer&& buffer)
|
||||
{
|
||||
value_ = std::move(buffer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void
|
||||
STBlob::setValue(Buffer&& b)
|
||||
{
|
||||
value_ = std::move(b);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
138
include/xrpl/protocol/STCurrency.h
Normal file
138
include/xrpl/protocol/STCurrency.h
Normal file
@@ -0,0 +1,138 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STCURRENCY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STCURRENCY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class STCurrency final : public STBase
|
||||
{
|
||||
private:
|
||||
Currency currency_{};
|
||||
|
||||
public:
|
||||
using value_type = Currency;
|
||||
|
||||
STCurrency() = default;
|
||||
|
||||
explicit STCurrency(SerialIter& sit, SField const& name);
|
||||
|
||||
explicit STCurrency(SField const& name, Currency const& currency);
|
||||
|
||||
explicit STCurrency(SField const& name);
|
||||
|
||||
Currency const&
|
||||
currency() const;
|
||||
|
||||
Currency const&
|
||||
value() const noexcept;
|
||||
|
||||
void
|
||||
setCurrency(Currency const& currency);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<STCurrency>
|
||||
construct(SerialIter&, SField const& name);
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
STCurrency
|
||||
currencyFromJson(SField const& name, Json::Value const& v);
|
||||
|
||||
inline Currency const&
|
||||
STCurrency::currency() const
|
||||
{
|
||||
return currency_;
|
||||
}
|
||||
|
||||
inline Currency const&
|
||||
STCurrency::value() const noexcept
|
||||
{
|
||||
return currency_;
|
||||
}
|
||||
|
||||
inline void
|
||||
STCurrency::setCurrency(Currency const& currency)
|
||||
{
|
||||
currency_ = currency;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STCurrency const& lhs, STCurrency const& rhs)
|
||||
{
|
||||
return lhs.currency() == rhs.currency();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(STCurrency const& lhs, STCurrency const& rhs)
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STCurrency const& lhs, STCurrency const& rhs)
|
||||
{
|
||||
return lhs.currency() < rhs.currency();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STCurrency const& lhs, Currency const& rhs)
|
||||
{
|
||||
return lhs.currency() == rhs;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STCurrency const& lhs, Currency const& rhs)
|
||||
{
|
||||
return lhs.currency() < rhs;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
178
include/xrpl/protocol/STExchange.h
Normal file
178
include/xrpl/protocol/STExchange.h
Normal file
@@ -0,0 +1,178 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STEXCHANGE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STEXCHANGE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBlob.h>
|
||||
#include <ripple/protocol/STInteger.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Convert between serialized type U and C++ type T. */
|
||||
template <class U, class T>
|
||||
struct STExchange;
|
||||
|
||||
template <class U, class T>
|
||||
struct STExchange<STInteger<U>, T>
|
||||
{
|
||||
explicit STExchange() = default;
|
||||
|
||||
using value_type = U;
|
||||
|
||||
static void
|
||||
get(std::optional<T>& t, STInteger<U> const& u)
|
||||
{
|
||||
t = u.value();
|
||||
}
|
||||
|
||||
static std::unique_ptr<STInteger<U>>
|
||||
set(SField const& f, T const& t)
|
||||
{
|
||||
return std::make_unique<STInteger<U>>(f, t);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct STExchange<STBlob, Slice>
|
||||
{
|
||||
explicit STExchange() = default;
|
||||
|
||||
using value_type = Slice;
|
||||
|
||||
static void
|
||||
get(std::optional<value_type>& t, STBlob const& u)
|
||||
{
|
||||
t.emplace(u.data(), u.size());
|
||||
}
|
||||
|
||||
static std::unique_ptr<STBlob>
|
||||
set(TypedField<STBlob> const& f, Slice const& t)
|
||||
{
|
||||
return std::make_unique<STBlob>(f, t.data(), t.size());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct STExchange<STBlob, Buffer>
|
||||
{
|
||||
explicit STExchange() = default;
|
||||
|
||||
using value_type = Buffer;
|
||||
|
||||
static void
|
||||
get(std::optional<Buffer>& t, STBlob const& u)
|
||||
{
|
||||
t.emplace(u.data(), u.size());
|
||||
}
|
||||
|
||||
static std::unique_ptr<STBlob>
|
||||
set(TypedField<STBlob> const& f, Buffer const& t)
|
||||
{
|
||||
return std::make_unique<STBlob>(f, t.data(), t.size());
|
||||
}
|
||||
|
||||
static std::unique_ptr<STBlob>
|
||||
set(TypedField<STBlob> const& f, Buffer&& t)
|
||||
{
|
||||
return std::make_unique<STBlob>(f, std::move(t));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Return the value of a field in an STObject as a given type. */
|
||||
/** @{ */
|
||||
template <class T, class U>
|
||||
std::optional<T>
|
||||
get(STObject const& st, TypedField<U> const& f)
|
||||
{
|
||||
std::optional<T> t;
|
||||
STBase const* const b = st.peekAtPField(f);
|
||||
if (!b)
|
||||
return t;
|
||||
auto const id = b->getSType();
|
||||
if (id == STI_NOTPRESENT)
|
||||
return t;
|
||||
auto const u = dynamic_cast<U const*>(b);
|
||||
// This should never happen
|
||||
if (!u)
|
||||
Throw<std::runtime_error>("Wrong field type");
|
||||
STExchange<U, T>::get(t, *u);
|
||||
return t;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
std::optional<typename STExchange<U, typename U::value_type>::value_type>
|
||||
get(STObject const& st, TypedField<U> const& f)
|
||||
{
|
||||
return get<typename U::value_type>(st, f);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Set a field value in an STObject. */
|
||||
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)));
|
||||
}
|
||||
|
||||
/** Set a blob field using an init function. */
|
||||
template <class Init>
|
||||
void
|
||||
set(STObject& st, TypedField<STBlob> const& f, std::size_t size, Init&& init)
|
||||
{
|
||||
st.set(std::make_unique<STBlob>(f, size, init));
|
||||
}
|
||||
|
||||
/** Set a blob field from data. */
|
||||
template <class = void>
|
||||
void
|
||||
set(STObject& st,
|
||||
TypedField<STBlob> const& f,
|
||||
void const* data,
|
||||
std::size_t size)
|
||||
{
|
||||
st.set(std::make_unique<STBlob>(f, data, size));
|
||||
}
|
||||
|
||||
/** Remove a field in an STObject. */
|
||||
template <class U>
|
||||
void
|
||||
erase(STObject& st, TypedField<U> const& f)
|
||||
{
|
||||
st.makeFieldAbsent(f);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
163
include/xrpl/protocol/STInteger.h
Normal file
163
include/xrpl/protocol/STInteger.h
Normal file
@@ -0,0 +1,163 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STINTEGER_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STINTEGER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <typename Integer>
|
||||
class STInteger : public STBase, public CountedObject<STInteger<Integer>>
|
||||
{
|
||||
public:
|
||||
using value_type = Integer;
|
||||
|
||||
private:
|
||||
Integer value_;
|
||||
|
||||
public:
|
||||
explicit STInteger(Integer v);
|
||||
STInteger(SField const& n, Integer v = 0);
|
||||
STInteger(SerialIter& sit, SField const& name);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
STInteger&
|
||||
operator=(value_type const& v);
|
||||
|
||||
value_type
|
||||
value() const noexcept;
|
||||
|
||||
void
|
||||
setValue(Integer v);
|
||||
|
||||
operator Integer() const;
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class ripple::detail::STVar;
|
||||
};
|
||||
|
||||
using STUInt8 = STInteger<unsigned char>;
|
||||
using STUInt16 = STInteger<std::uint16_t>;
|
||||
using STUInt32 = STInteger<std::uint32_t>;
|
||||
using STUInt64 = STInteger<std::uint64_t>;
|
||||
|
||||
template <typename Integer>
|
||||
inline STInteger<Integer>::STInteger(Integer v) : value_(v)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline STInteger<Integer>::STInteger(SField const& n, Integer v)
|
||||
: STBase(n), value_(v)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline STBase*
|
||||
STInteger<Integer>::copy(std::size_t n, void* buf) const
|
||||
{
|
||||
return emplace(n, buf, *this);
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline STBase*
|
||||
STInteger<Integer>::move(std::size_t n, void* buf)
|
||||
{
|
||||
return emplace(n, buf, std::move(*this));
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline void
|
||||
STInteger<Integer>::add(Serializer& s) const
|
||||
{
|
||||
assert(getFName().isBinary());
|
||||
assert(getFName().fieldType == getSType());
|
||||
s.addInteger(value_);
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline bool
|
||||
STInteger<Integer>::isDefault() const
|
||||
{
|
||||
return value_ == 0;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline bool
|
||||
STInteger<Integer>::isEquivalent(const STBase& t) const
|
||||
{
|
||||
const STInteger* v = dynamic_cast<const STInteger*>(&t);
|
||||
return v && (value_ == v->value_);
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline STInteger<Integer>&
|
||||
STInteger<Integer>::operator=(value_type const& v)
|
||||
{
|
||||
value_ = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline typename STInteger<Integer>::value_type
|
||||
STInteger<Integer>::value() const noexcept
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline void
|
||||
STInteger<Integer>::setValue(Integer v)
|
||||
{
|
||||
value_ = v;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline STInteger<Integer>::operator Integer() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
136
include/xrpl/protocol/STIssue.h
Normal file
136
include/xrpl/protocol/STIssue.h
Normal file
@@ -0,0 +1,136 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STISSUE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STISSUE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/Issue.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class STIssue final : public STBase, CountedObject<STIssue>
|
||||
{
|
||||
private:
|
||||
Issue issue_{xrpIssue()};
|
||||
|
||||
public:
|
||||
using value_type = Issue;
|
||||
|
||||
STIssue() = default;
|
||||
|
||||
explicit STIssue(SerialIter& sit, SField const& name);
|
||||
|
||||
explicit STIssue(SField const& name, Issue const& issue);
|
||||
|
||||
explicit STIssue(SField const& name);
|
||||
|
||||
Issue const&
|
||||
issue() const;
|
||||
|
||||
Issue const&
|
||||
value() const noexcept;
|
||||
|
||||
void
|
||||
setIssue(Issue const& issue);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
STIssue
|
||||
issueFromJson(SField const& name, Json::Value const& v);
|
||||
|
||||
inline Issue const&
|
||||
STIssue::issue() const
|
||||
{
|
||||
return issue_;
|
||||
}
|
||||
|
||||
inline Issue const&
|
||||
STIssue::value() const noexcept
|
||||
{
|
||||
return issue_;
|
||||
}
|
||||
|
||||
inline void
|
||||
STIssue::setIssue(Issue const& issue)
|
||||
{
|
||||
if (isXRP(issue_.currency) != isXRP(issue_.account))
|
||||
Throw<std::runtime_error>(
|
||||
"invalid issue: currency and account native mismatch");
|
||||
|
||||
issue_ = issue;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STIssue const& lhs, STIssue const& rhs)
|
||||
{
|
||||
return lhs.issue() == rhs.issue();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(STIssue const& lhs, STIssue const& rhs)
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STIssue const& lhs, STIssue const& rhs)
|
||||
{
|
||||
return lhs.issue() < rhs.issue();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STIssue const& lhs, Issue const& rhs)
|
||||
{
|
||||
return lhs.issue() == rhs;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STIssue const& lhs, Issue const& rhs)
|
||||
{
|
||||
return lhs.issue() < rhs;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
127
include/xrpl/protocol/STLedgerEntry.h
Normal file
127
include/xrpl/protocol/STLedgerEntry.h
Normal file
@@ -0,0 +1,127 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STLEDGERENTRY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STLEDGERENTRY_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Rules;
|
||||
class Invariants_test;
|
||||
|
||||
class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
|
||||
{
|
||||
uint256 key_;
|
||||
LedgerEntryType type_;
|
||||
|
||||
public:
|
||||
using pointer = std::shared_ptr<STLedgerEntry>;
|
||||
using ref = const std::shared_ptr<STLedgerEntry>&;
|
||||
|
||||
/** Create an empty object with the given key and type. */
|
||||
explicit STLedgerEntry(Keylet const& k);
|
||||
STLedgerEntry(LedgerEntryType type, uint256 const& key);
|
||||
STLedgerEntry(SerialIter& sit, uint256 const& index);
|
||||
STLedgerEntry(SerialIter&& sit, uint256 const& index);
|
||||
STLedgerEntry(STObject const& object, uint256 const& index);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getFullText() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value
|
||||
getJson(JsonOptions options) const override;
|
||||
|
||||
/** Returns the 'key' (or 'index') of this item.
|
||||
The key identifies this entry's position in
|
||||
the SHAMap associative container.
|
||||
*/
|
||||
uint256 const&
|
||||
key() const;
|
||||
|
||||
LedgerEntryType
|
||||
getType() const;
|
||||
|
||||
// is this a ledger entry that can be threaded
|
||||
bool
|
||||
isThreadedType(Rules const& rules) const;
|
||||
|
||||
bool
|
||||
thread(
|
||||
uint256 const& txID,
|
||||
std::uint32_t ledgerSeq,
|
||||
uint256& prevTxID,
|
||||
std::uint32_t& prevLedgerID);
|
||||
|
||||
private:
|
||||
/* Make STObject comply with the template for this SLE type
|
||||
Can throw
|
||||
*/
|
||||
void
|
||||
setSLEType();
|
||||
|
||||
friend Invariants_test; // this test wants access to the private type_
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
using SLE = STLedgerEntry;
|
||||
|
||||
inline STLedgerEntry::STLedgerEntry(LedgerEntryType type, uint256 const& key)
|
||||
: STLedgerEntry(Keylet(type, key))
|
||||
{
|
||||
}
|
||||
|
||||
inline STLedgerEntry::STLedgerEntry(SerialIter&& sit, uint256 const& index)
|
||||
: STLedgerEntry(sit, index)
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns the 'key' (or 'index') of this item.
|
||||
The key identifies this entry's position in
|
||||
the SHAMap associative container.
|
||||
*/
|
||||
inline uint256 const&
|
||||
STLedgerEntry::key() const
|
||||
{
|
||||
return key_;
|
||||
}
|
||||
|
||||
inline LedgerEntryType
|
||||
STLedgerEntry::getType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
1186
include/xrpl/protocol/STObject.h
Normal file
1186
include/xrpl/protocol/STObject.h
Normal file
File diff suppressed because it is too large
Load Diff
86
include/xrpl/protocol/STParsedJSON.h
Normal file
86
include/xrpl/protocol/STParsedJSON.h
Normal file
@@ -0,0 +1,86 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STPARSEDJSON_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STPARSEDJSON_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/STArray.h>
|
||||
#include <optional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Holds the serialized result of parsing an input JSON object.
|
||||
This does validation and checking on the provided JSON.
|
||||
*/
|
||||
class STParsedJSONObject
|
||||
{
|
||||
public:
|
||||
/** Parses and creates an STParsedJSON object.
|
||||
The result of the parsing is stored in object and error.
|
||||
Exceptions:
|
||||
Does not throw.
|
||||
@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() = delete;
|
||||
STParsedJSONObject(STParsedJSONObject const&) = delete;
|
||||
STParsedJSONObject&
|
||||
operator=(STParsedJSONObject const&) = delete;
|
||||
~STParsedJSONObject() = default;
|
||||
|
||||
/** The STObject if the parse was successful. */
|
||||
std::optional<STObject> object;
|
||||
|
||||
/** On failure, an appropriate set of error values. */
|
||||
Json::Value error;
|
||||
};
|
||||
|
||||
/** Holds the serialized result of parsing an input JSON array.
|
||||
This does validation and checking on the provided JSON.
|
||||
*/
|
||||
class STParsedJSONArray
|
||||
{
|
||||
public:
|
||||
/** Parses and creates an STParsedJSON array.
|
||||
The result of the parsing is stored in array and error.
|
||||
Exceptions:
|
||||
Does not throw.
|
||||
@param name The name of the JSON field, used in diagnostics.
|
||||
@param json The JSON-RPC to parse.
|
||||
*/
|
||||
STParsedJSONArray(std::string const& name, Json::Value const& json);
|
||||
|
||||
STParsedJSONArray() = delete;
|
||||
STParsedJSONArray(STParsedJSONArray const&) = delete;
|
||||
STParsedJSONArray&
|
||||
operator=(STParsedJSONArray const&) = delete;
|
||||
~STParsedJSONArray() = default;
|
||||
|
||||
/** The STArray if the parse was successful. */
|
||||
std::optional<STArray> array;
|
||||
|
||||
/** On failure, an appropriate set of error values. */
|
||||
Json::Value error;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
523
include/xrpl/protocol/STPathSet.h
Normal file
523
include/xrpl/protocol/STPathSet.h
Normal file
@@ -0,0 +1,523 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STPATHSET_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STPATHSET_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class STPathElement final : public CountedObject<STPathElement>
|
||||
{
|
||||
unsigned int mType;
|
||||
AccountID mAccountID;
|
||||
Currency mCurrencyID;
|
||||
AccountID mIssuerID;
|
||||
|
||||
bool is_offer_;
|
||||
std::size_t hash_value_;
|
||||
|
||||
public:
|
||||
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,
|
||||
// Combination of all types.
|
||||
};
|
||||
|
||||
STPathElement();
|
||||
STPathElement(STPathElement const&) = default;
|
||||
STPathElement&
|
||||
operator=(STPathElement const&) = default;
|
||||
|
||||
STPathElement(
|
||||
std::optional<AccountID> const& account,
|
||||
std::optional<Currency> const& currency,
|
||||
std::optional<AccountID> const& issuer);
|
||||
|
||||
STPathElement(
|
||||
AccountID const& account,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer,
|
||||
bool forceCurrency = false);
|
||||
|
||||
STPathElement(
|
||||
unsigned int uType,
|
||||
AccountID const& account,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer);
|
||||
|
||||
auto
|
||||
getNodeType() const;
|
||||
|
||||
bool
|
||||
isOffer() const;
|
||||
|
||||
bool
|
||||
isAccount() const;
|
||||
|
||||
bool
|
||||
hasIssuer() const;
|
||||
|
||||
bool
|
||||
hasCurrency() const;
|
||||
|
||||
bool
|
||||
isNone() const;
|
||||
|
||||
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
|
||||
// class of offers.
|
||||
AccountID const&
|
||||
getAccountID() const;
|
||||
|
||||
Currency const&
|
||||
getCurrency() const;
|
||||
|
||||
AccountID const&
|
||||
getIssuerID() const;
|
||||
|
||||
bool
|
||||
operator==(const STPathElement& t) const;
|
||||
|
||||
bool
|
||||
operator!=(const STPathElement& t) const;
|
||||
|
||||
private:
|
||||
static std::size_t
|
||||
get_hash(STPathElement const& element);
|
||||
};
|
||||
|
||||
class STPath final : public CountedObject<STPath>
|
||||
{
|
||||
std::vector<STPathElement> mPath;
|
||||
|
||||
public:
|
||||
STPath() = default;
|
||||
|
||||
STPath(std::vector<STPathElement> p);
|
||||
|
||||
std::vector<STPathElement>::size_type
|
||||
size() const;
|
||||
|
||||
bool
|
||||
empty() const;
|
||||
|
||||
void
|
||||
push_back(STPathElement const& e);
|
||||
|
||||
template <typename... Args>
|
||||
void
|
||||
emplace_back(Args&&... args);
|
||||
|
||||
bool
|
||||
hasSeen(
|
||||
AccountID const& account,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer) const;
|
||||
|
||||
Json::Value getJson(JsonOptions) const;
|
||||
|
||||
std::vector<STPathElement>::const_iterator
|
||||
begin() const;
|
||||
|
||||
std::vector<STPathElement>::const_iterator
|
||||
end() const;
|
||||
|
||||
bool
|
||||
operator==(STPath const& t) const;
|
||||
|
||||
std::vector<STPathElement>::const_reference
|
||||
back() const;
|
||||
|
||||
std::vector<STPathElement>::const_reference
|
||||
front() const;
|
||||
|
||||
STPathElement&
|
||||
operator[](int i);
|
||||
|
||||
const STPathElement&
|
||||
operator[](int i) const;
|
||||
|
||||
void
|
||||
reserve(size_t s);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// A set of zero or more payment paths
|
||||
class STPathSet final : public STBase, public CountedObject<STPathSet>
|
||||
{
|
||||
std::vector<STPath> value;
|
||||
|
||||
public:
|
||||
STPathSet() = default;
|
||||
|
||||
STPathSet(SField const& n);
|
||||
STPathSet(SerialIter& sit, SField const& name);
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
bool
|
||||
assembleAdd(STPath const& base, STPathElement const& tail);
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
// std::vector like interface:
|
||||
std::vector<STPath>::const_reference
|
||||
operator[](std::vector<STPath>::size_type n) const;
|
||||
|
||||
std::vector<STPath>::reference
|
||||
operator[](std::vector<STPath>::size_type n);
|
||||
|
||||
std::vector<STPath>::const_iterator
|
||||
begin() const;
|
||||
|
||||
std::vector<STPath>::const_iterator
|
||||
end() const;
|
||||
|
||||
std::vector<STPath>::size_type
|
||||
size() const;
|
||||
|
||||
bool
|
||||
empty() const;
|
||||
|
||||
void
|
||||
push_back(STPath const& e);
|
||||
|
||||
template <typename... Args>
|
||||
void
|
||||
emplace_back(Args&&... args);
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
// ------------ STPathElement ------------
|
||||
|
||||
inline STPathElement::STPathElement() : mType(typeNone), is_offer_(true)
|
||||
{
|
||||
hash_value_ = get_hash(*this);
|
||||
}
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
std::optional<AccountID> const& account,
|
||||
std::optional<Currency> const& currency,
|
||||
std::optional<AccountID> const& issuer)
|
||||
: mType(typeNone)
|
||||
{
|
||||
if (!account)
|
||||
{
|
||||
is_offer_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_offer_ = false;
|
||||
mAccountID = *account;
|
||||
mType |= typeAccount;
|
||||
assert(mAccountID != noAccount());
|
||||
}
|
||||
|
||||
if (currency)
|
||||
{
|
||||
mCurrencyID = *currency;
|
||||
mType |= typeCurrency;
|
||||
}
|
||||
|
||||
if (issuer)
|
||||
{
|
||||
mIssuerID = *issuer;
|
||||
mType |= typeIssuer;
|
||||
assert(mIssuerID != noAccount());
|
||||
}
|
||||
|
||||
hash_value_ = get_hash(*this);
|
||||
}
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
AccountID const& account,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer,
|
||||
bool forceCurrency)
|
||||
: mType(typeNone)
|
||||
, mAccountID(account)
|
||||
, mCurrencyID(currency)
|
||||
, mIssuerID(issuer)
|
||||
, is_offer_(isXRP(mAccountID))
|
||||
{
|
||||
if (!is_offer_)
|
||||
mType |= typeAccount;
|
||||
|
||||
if (forceCurrency || !isXRP(currency))
|
||||
mType |= typeCurrency;
|
||||
|
||||
if (!isXRP(issuer))
|
||||
mType |= typeIssuer;
|
||||
|
||||
hash_value_ = get_hash(*this);
|
||||
}
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
unsigned int uType,
|
||||
AccountID const& account,
|
||||
Currency const& currency,
|
||||
AccountID const& issuer)
|
||||
: mType(uType)
|
||||
, mAccountID(account)
|
||||
, mCurrencyID(currency)
|
||||
, mIssuerID(issuer)
|
||||
, is_offer_(isXRP(mAccountID))
|
||||
{
|
||||
hash_value_ = get_hash(*this);
|
||||
}
|
||||
|
||||
inline auto
|
||||
STPathElement::getNodeType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isOffer() const
|
||||
{
|
||||
return is_offer_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isAccount() const
|
||||
{
|
||||
return !isOffer();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasIssuer() const
|
||||
{
|
||||
return getNodeType() & STPathElement::typeIssuer;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasCurrency() const
|
||||
{
|
||||
return getNodeType() & STPathElement::typeCurrency;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isNone() const
|
||||
{
|
||||
return getNodeType() == STPathElement::typeNone;
|
||||
}
|
||||
|
||||
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
|
||||
// class of offers.
|
||||
inline AccountID const&
|
||||
STPathElement::getAccountID() const
|
||||
{
|
||||
return mAccountID;
|
||||
}
|
||||
|
||||
inline Currency const&
|
||||
STPathElement::getCurrency() const
|
||||
{
|
||||
return mCurrencyID;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STPathElement::getIssuerID() const
|
||||
{
|
||||
return mIssuerID;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::operator==(const STPathElement& t) const
|
||||
{
|
||||
return (mType & typeAccount) == (t.mType & typeAccount) &&
|
||||
hash_value_ == t.hash_value_ && mAccountID == t.mAccountID &&
|
||||
mCurrencyID == t.mCurrencyID && mIssuerID == t.mIssuerID;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::operator!=(const STPathElement& t) const
|
||||
{
|
||||
return !operator==(t);
|
||||
}
|
||||
|
||||
// ------------ STPath ------------
|
||||
|
||||
inline STPath::STPath(std::vector<STPathElement> p) : mPath(std::move(p))
|
||||
{
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::size_type
|
||||
STPath::size() const
|
||||
{
|
||||
return mPath.size();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPath::empty() const
|
||||
{
|
||||
return mPath.empty();
|
||||
}
|
||||
|
||||
inline void
|
||||
STPath::push_back(STPathElement const& e)
|
||||
{
|
||||
mPath.push_back(e);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void
|
||||
STPath::emplace_back(Args&&... args)
|
||||
{
|
||||
mPath.emplace_back(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::const_iterator
|
||||
STPath::begin() const
|
||||
{
|
||||
return mPath.begin();
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::const_iterator
|
||||
STPath::end() const
|
||||
{
|
||||
return mPath.end();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPath::operator==(STPath const& t) const
|
||||
{
|
||||
return mPath == t.mPath;
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::const_reference
|
||||
STPath::back() const
|
||||
{
|
||||
return mPath.back();
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::const_reference
|
||||
STPath::front() const
|
||||
{
|
||||
return mPath.front();
|
||||
}
|
||||
|
||||
inline STPathElement&
|
||||
STPath::operator[](int i)
|
||||
{
|
||||
return mPath[i];
|
||||
}
|
||||
|
||||
inline const STPathElement&
|
||||
STPath::operator[](int i) const
|
||||
{
|
||||
return mPath[i];
|
||||
}
|
||||
|
||||
inline void
|
||||
STPath::reserve(size_t s)
|
||||
{
|
||||
mPath.reserve(s);
|
||||
}
|
||||
|
||||
// ------------ STPathSet ------------
|
||||
|
||||
inline STPathSet::STPathSet(SField const& n) : STBase(n)
|
||||
{
|
||||
}
|
||||
|
||||
// std::vector like interface:
|
||||
inline std::vector<STPath>::const_reference
|
||||
STPathSet::operator[](std::vector<STPath>::size_type n) const
|
||||
{
|
||||
return value[n];
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::reference
|
||||
STPathSet::operator[](std::vector<STPath>::size_type n)
|
||||
{
|
||||
return value[n];
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::const_iterator
|
||||
STPathSet::begin() const
|
||||
{
|
||||
return value.begin();
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::const_iterator
|
||||
STPathSet::end() const
|
||||
{
|
||||
return value.end();
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::size_type
|
||||
STPathSet::size() const
|
||||
{
|
||||
return value.size();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathSet::empty() const
|
||||
{
|
||||
return value.empty();
|
||||
}
|
||||
|
||||
inline void
|
||||
STPathSet::push_back(STPath const& e)
|
||||
{
|
||||
value.push_back(e);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void
|
||||
STPathSet::emplace_back(Args&&... args)
|
||||
{
|
||||
value.emplace_back(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
200
include/xrpl/protocol/STTx.h
Normal file
200
include/xrpl/protocol/STTx.h
Normal file
@@ -0,0 +1,200 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STTX_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STTX_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Expected.h>
|
||||
#include <ripple/protocol/Feature.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/Rules.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <ripple/protocol/SeqProxy.h>
|
||||
#include <ripple/protocol/TxFormats.h>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
enum TxnSql : char {
|
||||
txnSqlNew = 'N',
|
||||
txnSqlConflict = 'C',
|
||||
txnSqlHeld = 'H',
|
||||
txnSqlValidated = 'V',
|
||||
txnSqlIncluded = 'I',
|
||||
txnSqlUnknown = 'U'
|
||||
};
|
||||
|
||||
class STTx final : public STObject, public CountedObject<STTx>
|
||||
{
|
||||
uint256 tid_;
|
||||
TxType tx_type_;
|
||||
|
||||
public:
|
||||
static std::size_t const minMultiSigners = 1;
|
||||
|
||||
// if rules are not supplied then the largest possible value is returned
|
||||
static std::size_t
|
||||
maxMultiSigners(Rules const* rules = 0)
|
||||
{
|
||||
if (rules && !rules->enabled(featureExpandedSignerList))
|
||||
return 8;
|
||||
|
||||
return 32;
|
||||
}
|
||||
|
||||
STTx() = delete;
|
||||
STTx(STTx const& other) = default;
|
||||
STTx&
|
||||
operator=(STTx const& other) = delete;
|
||||
|
||||
explicit STTx(SerialIter& sit);
|
||||
explicit STTx(SerialIter&& sit);
|
||||
explicit STTx(STObject&& object);
|
||||
|
||||
/** Constructs a transaction.
|
||||
|
||||
The returned transaction will have the specified type and
|
||||
any fields that the callback function adds to the object
|
||||
that's passed in.
|
||||
*/
|
||||
STTx(TxType type, std::function<void(STObject&)> assembler);
|
||||
|
||||
// STObject functions.
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getFullText() const override;
|
||||
|
||||
// Outer transaction functions / signature functions.
|
||||
Blob
|
||||
getSignature() const;
|
||||
|
||||
uint256
|
||||
getSigningHash() const;
|
||||
|
||||
TxType
|
||||
getTxnType() const;
|
||||
|
||||
Blob
|
||||
getSigningPubKey() const;
|
||||
|
||||
SeqProxy
|
||||
getSeqProxy() const;
|
||||
|
||||
boost::container::flat_set<AccountID>
|
||||
getMentionedAccounts() const;
|
||||
|
||||
uint256
|
||||
getTransactionID() const;
|
||||
|
||||
Json::Value
|
||||
getJson(JsonOptions options) const override;
|
||||
|
||||
Json::Value
|
||||
getJson(JsonOptions options, bool binary) const;
|
||||
|
||||
void
|
||||
sign(PublicKey const& publicKey, SecretKey const& secretKey);
|
||||
|
||||
/** Check the signature.
|
||||
@return `true` if valid signature. If invalid, the error message string.
|
||||
*/
|
||||
enum class RequireFullyCanonicalSig : bool { no, yes };
|
||||
Expected<void, std::string>
|
||||
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
|
||||
const;
|
||||
|
||||
// SQL Functions with metadata.
|
||||
static std::string const&
|
||||
getMetaSQLInsertReplaceHeader();
|
||||
|
||||
std::string
|
||||
getMetaSQL(std::uint32_t inLedger, std::string const& escapedMetaData)
|
||||
const;
|
||||
|
||||
std::string
|
||||
getMetaSQL(
|
||||
Serializer rawTxn,
|
||||
std::uint32_t inLedger,
|
||||
char status,
|
||||
std::string const& escapedMetaData) const;
|
||||
|
||||
private:
|
||||
Expected<void, std::string>
|
||||
checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
|
||||
|
||||
Expected<void, std::string>
|
||||
checkMultiSign(
|
||||
RequireFullyCanonicalSig requireCanonicalSig,
|
||||
Rules const& rules) const;
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
bool
|
||||
passesLocalChecks(STObject const& st, std::string&);
|
||||
|
||||
/** Sterilize a transaction.
|
||||
|
||||
The transaction is serialized and then deserialized,
|
||||
ensuring that all equivalent transactions are in canonical
|
||||
form. This also ensures that program metadata such as
|
||||
the transaction's digest, are all computed.
|
||||
*/
|
||||
std::shared_ptr<STTx const>
|
||||
sterilize(STTx const& stx);
|
||||
|
||||
/** Check whether a transaction is a pseudo-transaction */
|
||||
bool
|
||||
isPseudoTx(STObject const& tx);
|
||||
|
||||
inline STTx::STTx(SerialIter&& sit) : STTx(sit)
|
||||
{
|
||||
}
|
||||
|
||||
inline TxType
|
||||
STTx::getTxnType() const
|
||||
{
|
||||
return tx_type_;
|
||||
}
|
||||
|
||||
inline Blob
|
||||
STTx::getSigningPubKey() const
|
||||
{
|
||||
return getFieldVL(sfSigningPubKey);
|
||||
}
|
||||
|
||||
inline uint256
|
||||
STTx::getTransactionID() const
|
||||
{
|
||||
return tid_;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
270
include/xrpl/protocol/STValidation.h
Normal file
270
include/xrpl/protocol/STValidation.h
Normal file
@@ -0,0 +1,270 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STVALIDATION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STVALIDATION_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/FeeUnits.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// Validation flags
|
||||
|
||||
// This is a full (as opposed to a partial) validation
|
||||
constexpr std::uint32_t vfFullValidation = 0x00000001;
|
||||
|
||||
// The signature is fully canonical
|
||||
constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
|
||||
|
||||
class STValidation final : public STObject, public CountedObject<STValidation>
|
||||
{
|
||||
bool mTrusted = false;
|
||||
|
||||
// Determines the validity of the signature in this validation; unseated
|
||||
// optional if we haven't yet checked it, a boolean otherwise.
|
||||
mutable std::optional<bool> valid_;
|
||||
|
||||
// The public key associated with the key used to sign this validation
|
||||
PublicKey const signingPubKey_;
|
||||
|
||||
// The ID of the validator that issued this validation. For validators
|
||||
// that use manifests this will be derived from the master public key.
|
||||
NodeID const nodeID_;
|
||||
|
||||
NetClock::time_point seenTime_ = {};
|
||||
|
||||
public:
|
||||
/** Construct a STValidation from a peer from serialized data.
|
||||
|
||||
@param sit Iterator over serialized data
|
||||
@param lookupNodeID Invocable with signature
|
||||
NodeID(PublicKey const&)
|
||||
used to find the Node ID based on the public key
|
||||
that signed the validation. For manifest based
|
||||
validators, this should be the NodeID of the master
|
||||
public key.
|
||||
@param checkSignature Whether to verify the data was signed properly
|
||||
|
||||
@note Throws if the object is not valid
|
||||
*/
|
||||
template <class LookupNodeID>
|
||||
STValidation(
|
||||
SerialIter& sit,
|
||||
LookupNodeID&& lookupNodeID,
|
||||
bool checkSignature);
|
||||
|
||||
/** Construct, sign and trust a new STValidation issued by this node.
|
||||
|
||||
@param signTime When the validation is signed
|
||||
@param publicKey The current signing public key
|
||||
@param secretKey The current signing secret key
|
||||
@param nodeID ID corresponding to node's public master key
|
||||
@param f callback function to "fill" the validation with necessary data
|
||||
*/
|
||||
template <typename F>
|
||||
STValidation(
|
||||
NetClock::time_point signTime,
|
||||
PublicKey const& pk,
|
||||
SecretKey const& sk,
|
||||
NodeID const& nodeID,
|
||||
F&& f);
|
||||
|
||||
// Hash of the validated ledger
|
||||
uint256
|
||||
getLedgerHash() const;
|
||||
|
||||
// Hash of consensus transaction set used to generate ledger
|
||||
uint256
|
||||
getConsensusHash() const;
|
||||
|
||||
NetClock::time_point
|
||||
getSignTime() const;
|
||||
|
||||
NetClock::time_point
|
||||
getSeenTime() const noexcept;
|
||||
|
||||
PublicKey const&
|
||||
getSignerPublic() const noexcept;
|
||||
|
||||
NodeID const&
|
||||
getNodeID() const noexcept;
|
||||
|
||||
bool
|
||||
isValid() const noexcept;
|
||||
|
||||
bool
|
||||
isFull() const noexcept;
|
||||
|
||||
bool
|
||||
isTrusted() const noexcept;
|
||||
|
||||
uint256
|
||||
getSigningHash() const;
|
||||
|
||||
void
|
||||
setTrusted();
|
||||
|
||||
void
|
||||
setUntrusted();
|
||||
|
||||
void
|
||||
setSeen(NetClock::time_point s);
|
||||
|
||||
Blob
|
||||
getSerialized() const;
|
||||
|
||||
Blob
|
||||
getSignature() const;
|
||||
|
||||
private:
|
||||
static SOTemplate const&
|
||||
validationFormat();
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
template <class LookupNodeID>
|
||||
STValidation::STValidation(
|
||||
SerialIter& sit,
|
||||
LookupNodeID&& lookupNodeID,
|
||||
bool checkSignature)
|
||||
: STObject(validationFormat(), sit, sfValidation)
|
||||
, signingPubKey_([this]() {
|
||||
auto const spk = getFieldVL(sfSigningPubKey);
|
||||
|
||||
if (publicKeyType(makeSlice(spk)) != KeyType::secp256k1)
|
||||
Throw<std::runtime_error>("Invalid public key in validation");
|
||||
|
||||
return PublicKey{makeSlice(spk)};
|
||||
}())
|
||||
, nodeID_(lookupNodeID(signingPubKey_))
|
||||
{
|
||||
if (checkSignature && !isValid())
|
||||
{
|
||||
JLOG(debugLog().error()) << "Invalid signature in validation: "
|
||||
<< getJson(JsonOptions::none);
|
||||
Throw<std::runtime_error>("Invalid signature in validation");
|
||||
}
|
||||
|
||||
assert(nodeID_.isNonZero());
|
||||
}
|
||||
|
||||
/** Construct, sign and trust a new STValidation issued by this node.
|
||||
|
||||
@param signTime When the validation is signed
|
||||
@param publicKey The current signing public key
|
||||
@param secretKey The current signing secret key
|
||||
@param nodeID ID corresponding to node's public master key
|
||||
@param f callback function to "fill" the validation with necessary data
|
||||
*/
|
||||
template <typename F>
|
||||
STValidation::STValidation(
|
||||
NetClock::time_point signTime,
|
||||
PublicKey const& pk,
|
||||
SecretKey const& sk,
|
||||
NodeID const& nodeID,
|
||||
F&& f)
|
||||
: STObject(validationFormat(), sfValidation)
|
||||
, signingPubKey_(pk)
|
||||
, nodeID_(nodeID)
|
||||
, seenTime_(signTime)
|
||||
{
|
||||
assert(nodeID_.isNonZero());
|
||||
|
||||
// First, set our own public key:
|
||||
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());
|
||||
|
||||
// Perform additional initialization
|
||||
f(*this);
|
||||
|
||||
// Finally, sign the validation and mark it as trusted:
|
||||
setFlag(vfFullyCanonicalSig);
|
||||
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.");
|
||||
}
|
||||
|
||||
// We just signed this, so it should be valid.
|
||||
valid_ = true;
|
||||
}
|
||||
|
||||
inline PublicKey const&
|
||||
STValidation::getSignerPublic() const noexcept
|
||||
{
|
||||
return signingPubKey_;
|
||||
}
|
||||
|
||||
inline NodeID const&
|
||||
STValidation::getNodeID() const noexcept
|
||||
{
|
||||
return nodeID_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STValidation::isTrusted() const noexcept
|
||||
{
|
||||
return mTrusted;
|
||||
}
|
||||
|
||||
inline void
|
||||
STValidation::setTrusted()
|
||||
{
|
||||
mTrusted = true;
|
||||
}
|
||||
|
||||
inline void
|
||||
STValidation::setUntrusted()
|
||||
{
|
||||
mTrusted = false;
|
||||
}
|
||||
|
||||
inline void
|
||||
STValidation::setSeen(NetClock::time_point s)
|
||||
{
|
||||
seenTime_ = s;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
260
include/xrpl/protocol/STVector256.h
Normal file
260
include/xrpl/protocol/STVector256.h
Normal file
@@ -0,0 +1,260 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STVECTOR256_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STVECTOR256_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/STBitString.h>
|
||||
#include <ripple/protocol/STInteger.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class STVector256 : public STBase, public CountedObject<STVector256>
|
||||
{
|
||||
std::vector<uint256> mValue;
|
||||
|
||||
public:
|
||||
using value_type = std::vector<uint256> const&;
|
||||
|
||||
STVector256() = default;
|
||||
|
||||
explicit STVector256(SField const& n);
|
||||
explicit STVector256(std::vector<uint256> const& vector);
|
||||
STVector256(SField const& n, std::vector<uint256> const& vector);
|
||||
STVector256(SerialIter& sit, SField const& name);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
STVector256&
|
||||
operator=(std::vector<uint256> const& v);
|
||||
|
||||
STVector256&
|
||||
operator=(std::vector<uint256>&& v);
|
||||
|
||||
void
|
||||
setValue(const STVector256& v);
|
||||
|
||||
/** Retrieve a copy of the vector we contain */
|
||||
explicit operator std::vector<uint256>() const;
|
||||
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
void
|
||||
resize(std::size_t n);
|
||||
|
||||
bool
|
||||
empty() const;
|
||||
|
||||
std::vector<uint256>::reference
|
||||
operator[](std::vector<uint256>::size_type n);
|
||||
|
||||
std::vector<uint256>::const_reference
|
||||
operator[](std::vector<uint256>::size_type n) const;
|
||||
|
||||
std::vector<uint256> const&
|
||||
value() const;
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
insert(std::vector<uint256>::const_iterator pos, uint256 const& value);
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
insert(std::vector<uint256>::const_iterator pos, uint256&& value);
|
||||
|
||||
void
|
||||
push_back(uint256 const& v);
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
begin();
|
||||
|
||||
std::vector<uint256>::const_iterator
|
||||
begin() const;
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
end();
|
||||
|
||||
std::vector<uint256>::const_iterator
|
||||
end() const;
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
erase(std::vector<uint256>::iterator position);
|
||||
|
||||
void
|
||||
clear() noexcept;
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
inline STVector256::STVector256(SField const& n) : STBase(n)
|
||||
{
|
||||
}
|
||||
|
||||
inline STVector256::STVector256(std::vector<uint256> const& vector)
|
||||
: mValue(vector)
|
||||
{
|
||||
}
|
||||
|
||||
inline STVector256::STVector256(
|
||||
SField const& n,
|
||||
std::vector<uint256> const& vector)
|
||||
: STBase(n), mValue(vector)
|
||||
{
|
||||
}
|
||||
|
||||
inline STVector256&
|
||||
STVector256::operator=(std::vector<uint256> const& v)
|
||||
{
|
||||
mValue = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline STVector256&
|
||||
STVector256::operator=(std::vector<uint256>&& v)
|
||||
{
|
||||
mValue = std::move(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void
|
||||
STVector256::setValue(const STVector256& v)
|
||||
{
|
||||
mValue = v.mValue;
|
||||
}
|
||||
|
||||
/** Retrieve a copy of the vector we contain */
|
||||
inline STVector256::operator std::vector<uint256>() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
inline std::size_t
|
||||
STVector256::size() const
|
||||
{
|
||||
return mValue.size();
|
||||
}
|
||||
|
||||
inline void
|
||||
STVector256::resize(std::size_t n)
|
||||
{
|
||||
return mValue.resize(n);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STVector256::empty() const
|
||||
{
|
||||
return mValue.empty();
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::reference
|
||||
STVector256::operator[](std::vector<uint256>::size_type n)
|
||||
{
|
||||
return mValue[n];
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::const_reference
|
||||
STVector256::operator[](std::vector<uint256>::size_type n) const
|
||||
{
|
||||
return mValue[n];
|
||||
}
|
||||
|
||||
inline std::vector<uint256> const&
|
||||
STVector256::value() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::iterator
|
||||
STVector256::insert(
|
||||
std::vector<uint256>::const_iterator pos,
|
||||
uint256 const& value)
|
||||
{
|
||||
return mValue.insert(pos, value);
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::iterator
|
||||
STVector256::insert(std::vector<uint256>::const_iterator pos, uint256&& value)
|
||||
{
|
||||
return mValue.insert(pos, std::move(value));
|
||||
}
|
||||
|
||||
inline void
|
||||
STVector256::push_back(uint256 const& v)
|
||||
{
|
||||
mValue.push_back(v);
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::iterator
|
||||
STVector256::begin()
|
||||
{
|
||||
return mValue.begin();
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::const_iterator
|
||||
STVector256::begin() const
|
||||
{
|
||||
return mValue.begin();
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::iterator
|
||||
STVector256::end()
|
||||
{
|
||||
return mValue.end();
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::const_iterator
|
||||
STVector256::end() const
|
||||
{
|
||||
return mValue.end();
|
||||
}
|
||||
|
||||
inline std::vector<uint256>::iterator
|
||||
STVector256::erase(std::vector<uint256>::iterator position)
|
||||
{
|
||||
return mValue.erase(position);
|
||||
}
|
||||
|
||||
inline void
|
||||
STVector256::clear() noexcept
|
||||
{
|
||||
return mValue.clear();
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
236
include/xrpl/protocol/STXChainBridge.h
Normal file
236
include/xrpl/protocol/STXChainBridge.h
Normal file
@@ -0,0 +1,236 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2022 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STXCHAINBRIDGE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STXCHAINBRIDGE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/STAccount.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/STIssue.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Serializer;
|
||||
class STObject;
|
||||
|
||||
class STXChainBridge final : public STBase, public CountedObject<STXChainBridge>
|
||||
{
|
||||
STAccount lockingChainDoor_{sfLockingChainDoor};
|
||||
STIssue lockingChainIssue_{sfLockingChainIssue};
|
||||
STAccount issuingChainDoor_{sfIssuingChainDoor};
|
||||
STIssue issuingChainIssue_{sfIssuingChainIssue};
|
||||
|
||||
public:
|
||||
using value_type = STXChainBridge;
|
||||
|
||||
enum class ChainType { locking, issuing };
|
||||
|
||||
static ChainType
|
||||
otherChain(ChainType ct);
|
||||
|
||||
static ChainType
|
||||
srcChain(bool wasLockingChainSend);
|
||||
|
||||
static ChainType
|
||||
dstChain(bool wasLockingChainSend);
|
||||
|
||||
STXChainBridge();
|
||||
|
||||
explicit STXChainBridge(SField const& name);
|
||||
|
||||
STXChainBridge(STXChainBridge const& rhs) = default;
|
||||
|
||||
STXChainBridge(STObject const& o);
|
||||
|
||||
STXChainBridge(
|
||||
AccountID const& srcChainDoor,
|
||||
Issue const& srcChainIssue,
|
||||
AccountID const& dstChainDoor,
|
||||
Issue const& dstChainIssue);
|
||||
|
||||
explicit STXChainBridge(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
|
||||
getText() const override;
|
||||
|
||||
STObject
|
||||
toSTObject() const;
|
||||
|
||||
AccountID const&
|
||||
lockingChainDoor() const;
|
||||
|
||||
Issue const&
|
||||
lockingChainIssue() const;
|
||||
|
||||
AccountID const&
|
||||
issuingChainDoor() const;
|
||||
|
||||
Issue const&
|
||||
issuingChainIssue() const;
|
||||
|
||||
AccountID const&
|
||||
door(ChainType ct) const;
|
||||
|
||||
Issue const&
|
||||
issue(ChainType ct) const;
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(const STBase& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
value_type const&
|
||||
value() const noexcept;
|
||||
|
||||
private:
|
||||
static std::unique_ptr<STXChainBridge>
|
||||
construct(SerialIter&, SField const& name);
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend bool
|
||||
operator==(STXChainBridge const& lhs, STXChainBridge const& rhs);
|
||||
|
||||
friend bool
|
||||
operator<(STXChainBridge const& lhs, STXChainBridge const& rhs);
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(STXChainBridge const& lhs, STXChainBridge const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.lockingChainDoor_,
|
||||
lhs.lockingChainIssue_,
|
||||
lhs.issuingChainDoor_,
|
||||
lhs.issuingChainIssue_) ==
|
||||
std::tie(
|
||||
rhs.lockingChainDoor_,
|
||||
rhs.lockingChainIssue_,
|
||||
rhs.issuingChainDoor_,
|
||||
rhs.issuingChainIssue_);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STXChainBridge const& lhs, STXChainBridge const& rhs)
|
||||
{
|
||||
return std::tie(
|
||||
lhs.lockingChainDoor_,
|
||||
lhs.lockingChainIssue_,
|
||||
lhs.issuingChainDoor_,
|
||||
lhs.issuingChainIssue_) <
|
||||
std::tie(
|
||||
rhs.lockingChainDoor_,
|
||||
rhs.lockingChainIssue_,
|
||||
rhs.issuingChainDoor_,
|
||||
rhs.issuingChainIssue_);
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STXChainBridge::lockingChainDoor() const
|
||||
{
|
||||
return lockingChainDoor_.value();
|
||||
};
|
||||
|
||||
inline Issue const&
|
||||
STXChainBridge::lockingChainIssue() const
|
||||
{
|
||||
return lockingChainIssue_.value();
|
||||
};
|
||||
|
||||
inline AccountID const&
|
||||
STXChainBridge::issuingChainDoor() const
|
||||
{
|
||||
return issuingChainDoor_.value();
|
||||
};
|
||||
|
||||
inline Issue const&
|
||||
STXChainBridge::issuingChainIssue() const
|
||||
{
|
||||
return issuingChainIssue_.value();
|
||||
};
|
||||
|
||||
inline STXChainBridge::value_type const&
|
||||
STXChainBridge::value() const noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STXChainBridge::door(ChainType ct) const
|
||||
{
|
||||
if (ct == ChainType::locking)
|
||||
return lockingChainDoor();
|
||||
return issuingChainDoor();
|
||||
}
|
||||
|
||||
inline Issue const&
|
||||
STXChainBridge::issue(ChainType ct) const
|
||||
{
|
||||
if (ct == ChainType::locking)
|
||||
return lockingChainIssue();
|
||||
return issuingChainIssue();
|
||||
}
|
||||
|
||||
inline STXChainBridge::ChainType
|
||||
STXChainBridge::otherChain(ChainType ct)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
inline STXChainBridge::ChainType
|
||||
STXChainBridge::dstChain(bool wasLockingChainSend)
|
||||
{
|
||||
if (wasLockingChainSend)
|
||||
return ChainType::issuing;
|
||||
return ChainType::locking;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
185
include/xrpl/protocol/SecretKey.h
Normal file
185
include/xrpl/protocol/SecretKey.h
Normal file
@@ -0,0 +1,185 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SECRETKEY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SECRETKEY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/protocol/KeyType.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/Seed.h>
|
||||
#include <ripple/protocol/tokens.h>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** A secret key. */
|
||||
class SecretKey
|
||||
{
|
||||
private:
|
||||
std::uint8_t buf_[32];
|
||||
|
||||
public:
|
||||
using const_iterator = std::uint8_t const*;
|
||||
|
||||
SecretKey() = delete;
|
||||
SecretKey(SecretKey const&) = default;
|
||||
SecretKey&
|
||||
operator=(SecretKey const&) = default;
|
||||
|
||||
~SecretKey();
|
||||
|
||||
SecretKey(std::array<std::uint8_t, 32> const& data);
|
||||
SecretKey(Slice const& slice);
|
||||
|
||||
std::uint8_t const*
|
||||
data() const
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return sizeof(buf_);
|
||||
}
|
||||
|
||||
/** Convert the secret key to a hexadecimal string.
|
||||
|
||||
@note The operator<< function is deliberately omitted
|
||||
to avoid accidental exposure of secret key material.
|
||||
*/
|
||||
std::string
|
||||
to_string() const;
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return buf_ + sizeof(buf_);
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return buf_ + sizeof(buf_);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(SecretKey const& lhs, SecretKey const& rhs)
|
||||
{
|
||||
return lhs.size() == rhs.size() &&
|
||||
std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(SecretKey const& lhs, SecretKey const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Parse a secret key */
|
||||
template <>
|
||||
std::optional<SecretKey>
|
||||
parseBase58(TokenType type, std::string const& s);
|
||||
|
||||
inline std::string
|
||||
toBase58(TokenType type, SecretKey const& sk)
|
||||
{
|
||||
return encodeBase58Token(type, sk.data(), sk.size());
|
||||
}
|
||||
|
||||
/** Create a secret key using secure random numbers. */
|
||||
SecretKey
|
||||
randomSecretKey();
|
||||
|
||||
/** Generate a new secret key deterministically. */
|
||||
SecretKey
|
||||
generateSecretKey(KeyType type, Seed const& seed);
|
||||
|
||||
/** Derive the public key from a secret key. */
|
||||
PublicKey
|
||||
derivePublicKey(KeyType type, SecretKey const& sk);
|
||||
|
||||
/** Generate a key pair deterministically.
|
||||
|
||||
This algorithm is specific to Ripple:
|
||||
|
||||
For secp256k1 key pairs, the seed is converted
|
||||
to a Generator and used to compute the key pair
|
||||
corresponding to ordinal 0 for the generator.
|
||||
*/
|
||||
std::pair<PublicKey, SecretKey>
|
||||
generateKeyPair(KeyType type, Seed const& seed);
|
||||
|
||||
/** Create a key pair using secure random numbers. */
|
||||
std::pair<PublicKey, SecretKey>
|
||||
randomKeyPair(KeyType type);
|
||||
|
||||
/** Generate a signature for a message digest.
|
||||
This can only be used with secp256k1 since Ed25519's
|
||||
security properties come, in part, from how the message
|
||||
is hashed.
|
||||
*/
|
||||
/** @{ */
|
||||
Buffer
|
||||
signDigest(PublicKey const& pk, SecretKey const& sk, uint256 const& digest);
|
||||
|
||||
inline Buffer
|
||||
signDigest(KeyType type, SecretKey const& sk, uint256 const& digest)
|
||||
{
|
||||
return signDigest(derivePublicKey(type, sk), sk, digest);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Generate a signature for a message.
|
||||
With secp256k1 signatures, the data is first hashed with
|
||||
SHA512-Half, and the resulting digest is signed.
|
||||
*/
|
||||
/** @{ */
|
||||
Buffer
|
||||
sign(PublicKey const& pk, SecretKey const& sk, Slice const& message);
|
||||
|
||||
inline Buffer
|
||||
sign(KeyType type, SecretKey const& sk, Slice const& message)
|
||||
{
|
||||
return sign(derivePublicKey(type, sk), sk, message);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
140
include/xrpl/protocol/Seed.h
Normal file
140
include/xrpl/protocol/Seed.h
Normal file
@@ -0,0 +1,140 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SEED_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SEED_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/protocol/tokens.h>
|
||||
#include <array>
|
||||
#include <optional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Seeds are used to generate deterministic secret keys. */
|
||||
class Seed
|
||||
{
|
||||
private:
|
||||
std::array<uint8_t, 16> buf_;
|
||||
|
||||
public:
|
||||
using const_iterator = std::array<uint8_t, 16>::const_iterator;
|
||||
|
||||
Seed() = delete;
|
||||
|
||||
Seed(Seed const&) = default;
|
||||
Seed&
|
||||
operator=(Seed const&) = default;
|
||||
|
||||
/** Destroy the seed.
|
||||
The buffer will first be securely erased.
|
||||
*/
|
||||
~Seed();
|
||||
|
||||
/** Construct a seed */
|
||||
/** @{ */
|
||||
explicit Seed(Slice const& slice);
|
||||
explicit Seed(uint128 const& seed);
|
||||
/** @} */
|
||||
|
||||
std::uint8_t const*
|
||||
data() const
|
||||
{
|
||||
return buf_.data();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return buf_.size();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return buf_.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return buf_.cbegin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return buf_.end();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return buf_.cend();
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Create a seed using secure random numbers. */
|
||||
Seed
|
||||
randomSeed();
|
||||
|
||||
/** Generate a seed deterministically.
|
||||
|
||||
The algorithm is specific to Ripple:
|
||||
|
||||
The seed is calculated as the first 128 bits
|
||||
of the SHA512-Half of the string text excluding
|
||||
any terminating null.
|
||||
|
||||
@note This will not attempt to determine the format of
|
||||
the string (e.g. hex or base58).
|
||||
*/
|
||||
Seed
|
||||
generateSeed(std::string const& passPhrase);
|
||||
|
||||
/** Parse a Base58 encoded string into a seed */
|
||||
template <>
|
||||
std::optional<Seed>
|
||||
parseBase58(std::string const& s);
|
||||
|
||||
/** Attempt to parse a string as a seed.
|
||||
|
||||
@param str the string to parse
|
||||
@param rfc1751 true if we should attempt RFC1751 style parsing (deprecated)
|
||||
* */
|
||||
std::optional<Seed>
|
||||
parseGenericSeed(std::string const& str, bool rfc1751 = true);
|
||||
|
||||
/** Encode a Seed in RFC1751 format */
|
||||
std::string
|
||||
seedAs1751(Seed const& seed);
|
||||
|
||||
/** Format a seed as a Base58 string */
|
||||
inline std::string
|
||||
toBase58(Seed const& seed)
|
||||
{
|
||||
return encodeBase58Token(TokenType::FamilySeed, seed.data(), seed.size());
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
170
include/xrpl/protocol/SeqProxy.h
Normal file
170
include/xrpl/protocol/SeqProxy.h
Normal file
@@ -0,0 +1,170 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2018 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SEQ_PROXY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SEQ_PROXY_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** A type that represents either a sequence value or a ticket value.
|
||||
|
||||
We use the value() of a SeqProxy in places where a sequence was used
|
||||
before. An example of this is the sequence of an Offer stored in the
|
||||
ledger. We do the same thing with the in-ledger identifier of a
|
||||
Check, Payment Channel, and Escrow.
|
||||
|
||||
Why is this safe? If we use the SeqProxy::value(), how do we know that
|
||||
each ledger entry will be unique?
|
||||
|
||||
There are two components that make this safe:
|
||||
|
||||
1. A "TicketCreate" transaction carefully avoids creating a ticket
|
||||
that corresponds with an already used Sequence or Ticket value.
|
||||
The transactor does this by referring to the account root's
|
||||
sequence number. Creating the ticket advances the account root's
|
||||
sequence number so the same ticket (or sequence) value cannot be
|
||||
used again.
|
||||
|
||||
2. When a "TicketCreate" transaction creates a batch of tickets it advances
|
||||
the account root sequence to one past the largest created ticket.
|
||||
|
||||
Therefore all tickets in a batch other than the first may never have
|
||||
the same value as a sequence on that same account. And since a ticket
|
||||
may only be used once there will never be any duplicates within this
|
||||
account.
|
||||
*/
|
||||
class SeqProxy
|
||||
{
|
||||
public:
|
||||
enum Type : std::uint8_t { seq = 0, ticket };
|
||||
|
||||
private:
|
||||
std::uint32_t value_;
|
||||
Type type_;
|
||||
|
||||
public:
|
||||
constexpr explicit SeqProxy(Type t, std::uint32_t v) : value_{v}, type_{t}
|
||||
{
|
||||
}
|
||||
|
||||
SeqProxy(SeqProxy const& other) = default;
|
||||
|
||||
SeqProxy&
|
||||
operator=(SeqProxy const& other) = default;
|
||||
|
||||
/** Factory function to return a sequence-based SeqProxy */
|
||||
static constexpr SeqProxy
|
||||
sequence(std::uint32_t v)
|
||||
{
|
||||
return SeqProxy{Type::seq, v};
|
||||
}
|
||||
|
||||
constexpr std::uint32_t
|
||||
value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
isSeq() const
|
||||
{
|
||||
return type_ == seq;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
isTicket() const
|
||||
{
|
||||
return type_ == ticket;
|
||||
}
|
||||
|
||||
// Occasionally it is convenient to be able to increase the value_
|
||||
// of a SeqProxy. But it's unusual. So, rather than putting in an
|
||||
// addition operator, you must invoke the method by name. That makes
|
||||
// if more difficult to invoke accidentally.
|
||||
SeqProxy&
|
||||
advanceBy(std::uint32_t amount)
|
||||
{
|
||||
value_ += amount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
//
|
||||
// The comparison is designed specifically so _all_ Sequence
|
||||
// representations sort in front of Ticket representations. This
|
||||
// is true even if the Ticket value() is less that the Sequence
|
||||
// value().
|
||||
//
|
||||
// This somewhat surprising sort order has benefits for transaction
|
||||
// processing. It guarantees that transactions creating Tickets are
|
||||
// sorted in from of transactions that consume Tickets.
|
||||
friend constexpr bool
|
||||
operator==(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
if (lhs.type_ != rhs.type_)
|
||||
return false;
|
||||
return (lhs.value() == rhs.value());
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator!=(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator<(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
if (lhs.type_ != rhs.type_)
|
||||
return lhs.type_ < rhs.type_;
|
||||
return lhs.value() < rhs.value();
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator>(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator>=(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator<=(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, SeqProxy seqProx)
|
||||
{
|
||||
os << (seqProx.isSeq() ? "sequence " : "ticket ");
|
||||
os << seqProx.value();
|
||||
return os;
|
||||
}
|
||||
};
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
433
include/xrpl/protocol/Serializer.h
Normal file
433
include/xrpl/protocol/Serializer.h
Normal file
@@ -0,0 +1,433 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SERIALIZER_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SERIALIZER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/Slice.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/safe_cast.h>
|
||||
#include <ripple/basics/strHex.h>
|
||||
#include <ripple/protocol/HashPrefix.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Serializer
|
||||
{
|
||||
private:
|
||||
// DEPRECATED
|
||||
Blob mData;
|
||||
|
||||
public:
|
||||
explicit Serializer(int n = 256)
|
||||
{
|
||||
mData.reserve(n);
|
||||
}
|
||||
|
||||
Serializer(void const* data, std::size_t size)
|
||||
{
|
||||
mData.resize(size);
|
||||
|
||||
if (size)
|
||||
{
|
||||
assert(data != nullptr);
|
||||
std::memcpy(mData.data(), data, size);
|
||||
}
|
||||
}
|
||||
|
||||
Slice
|
||||
slice() const noexcept
|
||||
{
|
||||
return Slice(mData.data(), mData.size());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return mData.size();
|
||||
}
|
||||
|
||||
void const*
|
||||
data() const noexcept
|
||||
{
|
||||
return mData.data();
|
||||
}
|
||||
|
||||
// assemble functions
|
||||
int
|
||||
add8(unsigned char i);
|
||||
int
|
||||
add16(std::uint16_t i);
|
||||
int
|
||||
add32(std::uint32_t i); // ledger indexes, account sequence, timestamps
|
||||
int
|
||||
add32(HashPrefix p);
|
||||
int
|
||||
add64(std::uint64_t i); // native currency amounts
|
||||
|
||||
template <typename Integer>
|
||||
int addInteger(Integer);
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
int
|
||||
addBitString(base_uint<Bits, Tag> const& v)
|
||||
{
|
||||
return addRaw(v.data(), v.size());
|
||||
}
|
||||
|
||||
int
|
||||
addRaw(Blob const& vector);
|
||||
int
|
||||
addRaw(Slice slice);
|
||||
int
|
||||
addRaw(const void* ptr, int len);
|
||||
int
|
||||
addRaw(const Serializer& s);
|
||||
|
||||
int
|
||||
addVL(Blob const& vector);
|
||||
int
|
||||
addVL(Slice const& slice);
|
||||
template <class Iter>
|
||||
int
|
||||
addVL(Iter begin, Iter end, int len);
|
||||
int
|
||||
addVL(const void* ptr, int len);
|
||||
|
||||
// disassemble functions
|
||||
bool
|
||||
get8(int&, int offset) const;
|
||||
|
||||
template <typename Integer>
|
||||
bool
|
||||
getInteger(Integer& number, int offset)
|
||||
{
|
||||
static const auto bytes = sizeof(Integer);
|
||||
if ((offset + bytes) > mData.size())
|
||||
return false;
|
||||
number = 0;
|
||||
|
||||
auto ptr = &mData[offset];
|
||||
for (auto i = 0; i < bytes; ++i)
|
||||
{
|
||||
if (i)
|
||||
number <<= 8;
|
||||
number |= *ptr++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, typename Tag = void>
|
||||
bool
|
||||
getBitString(base_uint<Bits, Tag>& data, int offset) const
|
||||
{
|
||||
auto success = (offset + (Bits / 8)) <= mData.size();
|
||||
if (success)
|
||||
memcpy(data.begin(), &(mData.front()) + offset, (Bits / 8));
|
||||
return success;
|
||||
}
|
||||
|
||||
int
|
||||
addFieldID(int type, int name);
|
||||
int
|
||||
addFieldID(SerializedTypeID type, int name)
|
||||
{
|
||||
return addFieldID(safe_cast<int>(type), name);
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
uint256
|
||||
getSHA512Half() const;
|
||||
|
||||
// totality functions
|
||||
Blob const&
|
||||
peekData() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
Blob
|
||||
getData() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
Blob&
|
||||
modData()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
int
|
||||
getDataLength() const
|
||||
{
|
||||
return mData.size();
|
||||
}
|
||||
const void*
|
||||
getDataPtr() const
|
||||
{
|
||||
return mData.data();
|
||||
}
|
||||
void*
|
||||
getDataPtr()
|
||||
{
|
||||
return mData.data();
|
||||
}
|
||||
int
|
||||
getLength() const
|
||||
{
|
||||
return mData.size();
|
||||
}
|
||||
std::string
|
||||
getString() const
|
||||
{
|
||||
return std::string(static_cast<const char*>(getDataPtr()), size());
|
||||
}
|
||||
void
|
||||
erase()
|
||||
{
|
||||
mData.clear();
|
||||
}
|
||||
bool
|
||||
chop(int num);
|
||||
|
||||
// vector-like functions
|
||||
Blob ::iterator
|
||||
begin()
|
||||
{
|
||||
return mData.begin();
|
||||
}
|
||||
Blob ::iterator
|
||||
end()
|
||||
{
|
||||
return mData.end();
|
||||
}
|
||||
Blob ::const_iterator
|
||||
begin() const
|
||||
{
|
||||
return mData.begin();
|
||||
}
|
||||
Blob ::const_iterator
|
||||
end() const
|
||||
{
|
||||
return mData.end();
|
||||
}
|
||||
void
|
||||
reserve(size_t n)
|
||||
{
|
||||
mData.reserve(n);
|
||||
}
|
||||
void
|
||||
resize(size_t n)
|
||||
{
|
||||
mData.resize(n);
|
||||
}
|
||||
size_t
|
||||
capacity() const
|
||||
{
|
||||
return mData.capacity();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(Blob const& v) const
|
||||
{
|
||||
return v == mData;
|
||||
}
|
||||
bool
|
||||
operator!=(Blob const& v) const
|
||||
{
|
||||
return v != mData;
|
||||
}
|
||||
bool
|
||||
operator==(const Serializer& v) const
|
||||
{
|
||||
return v.mData == mData;
|
||||
}
|
||||
bool
|
||||
operator!=(const Serializer& v) const
|
||||
{
|
||||
return v.mData != mData;
|
||||
}
|
||||
|
||||
static int
|
||||
decodeLengthLength(int b1);
|
||||
static int
|
||||
decodeVLLength(int b1);
|
||||
static int
|
||||
decodeVLLength(int b1, int b2);
|
||||
static int
|
||||
decodeVLLength(int b1, int b2, int b3);
|
||||
|
||||
private:
|
||||
static int
|
||||
encodeLengthLength(int length); // length to encode length
|
||||
int
|
||||
addEncoded(int length);
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
int
|
||||
Serializer::addVL(Iter begin, Iter end, int len)
|
||||
{
|
||||
int ret = addEncoded(len);
|
||||
for (; begin != end; ++begin)
|
||||
{
|
||||
addRaw(begin->data(), begin->size());
|
||||
#ifndef NDEBUG
|
||||
len -= begin->size();
|
||||
#endif
|
||||
}
|
||||
assert(len == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// DEPRECATED
|
||||
// Transitional adapter to new serialization interfaces
|
||||
class SerialIter
|
||||
{
|
||||
private:
|
||||
std::uint8_t const* p_;
|
||||
std::size_t remain_;
|
||||
std::size_t used_ = 0;
|
||||
|
||||
public:
|
||||
SerialIter(void const* data, std::size_t size) noexcept;
|
||||
|
||||
SerialIter(Slice const& slice) : SerialIter(slice.data(), slice.size())
|
||||
{
|
||||
}
|
||||
|
||||
// Infer the size of the data based on the size of the passed array.
|
||||
template <int N>
|
||||
explicit SerialIter(std::uint8_t const (&data)[N]) : SerialIter(&data[0], N)
|
||||
{
|
||||
static_assert(N > 0, "");
|
||||
}
|
||||
|
||||
std::size_t
|
||||
empty() const noexcept
|
||||
{
|
||||
return remain_ == 0;
|
||||
}
|
||||
|
||||
void
|
||||
reset() noexcept;
|
||||
|
||||
int
|
||||
getBytesLeft() const noexcept
|
||||
{
|
||||
return static_cast<int>(remain_);
|
||||
}
|
||||
|
||||
// get functions throw on error
|
||||
unsigned char
|
||||
get8();
|
||||
|
||||
std::uint16_t
|
||||
get16();
|
||||
|
||||
std::uint32_t
|
||||
get32();
|
||||
|
||||
std::uint64_t
|
||||
get64();
|
||||
|
||||
template <std::size_t Bits, class Tag = void>
|
||||
base_uint<Bits, Tag>
|
||||
getBitString();
|
||||
|
||||
uint128
|
||||
get128()
|
||||
{
|
||||
return getBitString<128>();
|
||||
}
|
||||
|
||||
uint160
|
||||
get160()
|
||||
{
|
||||
return getBitString<160>();
|
||||
}
|
||||
|
||||
uint256
|
||||
get256()
|
||||
{
|
||||
return getBitString<256>();
|
||||
}
|
||||
|
||||
void
|
||||
getFieldID(int& type, int& name);
|
||||
|
||||
// Returns the size of the VL if the
|
||||
// next object is a VL. Advances the iterator
|
||||
// to the beginning of the VL.
|
||||
int
|
||||
getVLDataLength();
|
||||
|
||||
Slice
|
||||
getSlice(std::size_t bytes);
|
||||
|
||||
// VFALCO DEPRECATED Returns a copy
|
||||
Blob
|
||||
getRaw(int size);
|
||||
|
||||
// VFALCO DEPRECATED Returns a copy
|
||||
Blob
|
||||
getVL();
|
||||
|
||||
void
|
||||
skip(int num);
|
||||
|
||||
Buffer
|
||||
getVLBuffer();
|
||||
|
||||
template <class T>
|
||||
T
|
||||
getRawHelper(int size);
|
||||
};
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
base_uint<Bits, Tag>
|
||||
SerialIter::getBitString()
|
||||
{
|
||||
auto const n = Bits / 8;
|
||||
|
||||
if (remain_ < n)
|
||||
Throw<std::runtime_error>("invalid SerialIter getBitString");
|
||||
|
||||
auto const x = p_;
|
||||
|
||||
p_ += n;
|
||||
used_ += n;
|
||||
remain_ -= n;
|
||||
|
||||
return base_uint<Bits, Tag>::fromVoid(x);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
92
include/xrpl/protocol/Sign.h
Normal file
92
include/xrpl/protocol/Sign.h
Normal file
@@ -0,0 +1,92 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SIGN_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SIGN_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/HashPrefix.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Sign an STObject
|
||||
|
||||
@param st Object to sign
|
||||
@param prefix Prefix to insert before serialized object when hashing
|
||||
@param type Signing key type used to derive public key
|
||||
@param sk Signing secret key
|
||||
@param sigField Field in which to store the signature on the object.
|
||||
If not specified the value defaults to `sfSignature`.
|
||||
|
||||
@note If a signature already exists, it is overwritten.
|
||||
*/
|
||||
void
|
||||
sign(
|
||||
STObject& st,
|
||||
HashPrefix const& prefix,
|
||||
KeyType type,
|
||||
SecretKey const& sk,
|
||||
SF_VL const& sigField = sfSignature);
|
||||
|
||||
/** Returns `true` if STObject contains valid signature
|
||||
|
||||
@param st Signed object
|
||||
@param prefix Prefix inserted before serialized object when hashing
|
||||
@param pk Public key for verifying signature
|
||||
@param sigField Object's field containing the signature.
|
||||
If not specified the value defaults to `sfSignature`.
|
||||
*/
|
||||
bool
|
||||
verify(
|
||||
STObject const& st,
|
||||
HashPrefix const& prefix,
|
||||
PublicKey const& pk,
|
||||
SF_VL const& sigField = sfSignature);
|
||||
|
||||
/** Return a Serializer suitable for computing a multisigning TxnSignature. */
|
||||
Serializer
|
||||
buildMultiSigningData(STObject const& obj, AccountID const& signingID);
|
||||
|
||||
/** Break the multi-signing hash computation into 2 parts for optimization.
|
||||
|
||||
We can optimize verifying multiple multisignatures by splitting the
|
||||
data building into two parts;
|
||||
o A large part that is shared by all of the computations.
|
||||
o A small part that is unique to each signer in the multisignature.
|
||||
|
||||
The following methods support that optimization:
|
||||
1. startMultiSigningData provides the large part which can be shared.
|
||||
2. finishMuiltiSigningData caps the passed in serializer with each
|
||||
signer's unique data.
|
||||
*/
|
||||
Serializer
|
||||
startMultiSigningData(STObject const& obj);
|
||||
|
||||
inline void
|
||||
finishMultiSigningData(AccountID const& signingID, Serializer& s)
|
||||
{
|
||||
s.addBitString(signingID);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
92
include/xrpl/protocol/SystemParameters.h
Normal file
92
include/xrpl/protocol/SystemParameters.h
Normal file
@@ -0,0 +1,92 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SYSTEMPARAMETERS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SYSTEMPARAMETERS_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/XRPAmount.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// Various protocol and system specific constant globals.
|
||||
|
||||
/* The name of the system. */
|
||||
static inline std::string const&
|
||||
systemName()
|
||||
{
|
||||
static std::string const name = "xahau";
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Configure the native currency. */
|
||||
|
||||
/** Number of drops in the genesis account. */
|
||||
constexpr XRPAmount INITIAL_XRP{100'000'000'000 * DROPS_PER_XRP};
|
||||
|
||||
/** Returns true if the amount does not exceed the initial XRP in existence. */
|
||||
inline bool
|
||||
isLegalAmount(XRPAmount const& amount)
|
||||
{
|
||||
return amount <= INITIAL_XRP;
|
||||
}
|
||||
|
||||
/** Returns true if the absolute value of the amount does not exceed the initial
|
||||
* XRP in existence. */
|
||||
inline bool
|
||||
isLegalAmountSigned(XRPAmount const& amount)
|
||||
{
|
||||
return amount >= -INITIAL_XRP && amount <= INITIAL_XRP;
|
||||
}
|
||||
|
||||
/* The currency code for the native currency. */
|
||||
static inline std::string const&
|
||||
systemCurrencyCode()
|
||||
{
|
||||
static std::string const code = "XAH";
|
||||
return code;
|
||||
}
|
||||
|
||||
/** The XRP ledger network's earliest allowed sequence */
|
||||
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_SEQ{1U};
|
||||
|
||||
/** The number of ledgers in a shard */
|
||||
static constexpr std::uint32_t DEFAULT_LEDGERS_PER_SHARD{16384u};
|
||||
|
||||
/** The minimum amount of support an amendment should have.
|
||||
|
||||
@note This value is used by legacy code and will become obsolete
|
||||
once the fixAmendmentMajorityCalc amendment activates.
|
||||
*/
|
||||
constexpr std::ratio<204, 256> preFixAmendmentMajorityCalcThreshold;
|
||||
|
||||
constexpr std::ratio<80, 100> postFixAmendmentMajorityCalcThreshold;
|
||||
|
||||
/** The minimum amount of time an amendment must hold a majority */
|
||||
constexpr std::chrono::seconds const defaultAmendmentMajorityTime =
|
||||
std::chrono::days{5};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
/** Default peer port (IANA registered) */
|
||||
inline std::uint16_t constexpr DEFAULT_PEER_PORT{21337};
|
||||
|
||||
#endif
|
||||
699
include/xrpl/protocol/TER.h
Normal file
699
include/xrpl/protocol/TER.h
Normal file
@@ -0,0 +1,699 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012 - 2019 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_TER_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_TER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/safe_cast.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// See https://xrpl.org/transaction-results.html
|
||||
//
|
||||
// "Transaction Engine Result"
|
||||
// or Transaction ERror.
|
||||
//
|
||||
using TERUnderlyingType = int;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum TELcodes : TERUnderlyingType {
|
||||
// Note: Range is stable.
|
||||
// Exact numbers are used in ripple-binary-codec:
|
||||
// https://github.com/ripple/ripple-binary-codec/blob/master/src/enums/definitions.json
|
||||
// Use tokens.
|
||||
|
||||
// -399 .. -300: L Local error (transaction fee inadequate, exceeds local
|
||||
// limit) Only valid during non-consensus processing. Implications:
|
||||
// - Not forwarded
|
||||
// - No fee check
|
||||
telLOCAL_ERROR = -399,
|
||||
telBAD_DOMAIN,
|
||||
telBAD_PATH_COUNT,
|
||||
telBAD_PUBLIC_KEY,
|
||||
telFAILED_PROCESSING,
|
||||
telINSUF_FEE_P,
|
||||
telNO_DST_PARTIAL,
|
||||
telCAN_NOT_QUEUE,
|
||||
telCAN_NOT_QUEUE_BALANCE,
|
||||
telCAN_NOT_QUEUE_BLOCKS,
|
||||
telCAN_NOT_QUEUE_BLOCKED,
|
||||
telCAN_NOT_QUEUE_FEE,
|
||||
telCAN_NOT_QUEUE_FULL,
|
||||
telWRONG_NETWORK,
|
||||
telREQUIRES_NETWORK_ID,
|
||||
telNETWORK_ID_MAKES_TX_NON_CANONICAL,
|
||||
telNON_LOCAL_EMITTED_TXN,
|
||||
telIMPORT_VL_KEY_NOT_RECOGNISED,
|
||||
telCAN_NOT_QUEUE_IMPORT,
|
||||
telENV_RPC_FAILED,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum TEMcodes : TERUnderlyingType {
|
||||
// Note: Range is stable.
|
||||
// Exact numbers are used in ripple-binary-codec:
|
||||
// https://github.com/ripple/ripple-binary-codec/blob/master/src/enums/definitions.json
|
||||
// Use tokens.
|
||||
|
||||
// -299 .. -200: M Malformed (bad signature)
|
||||
// Causes:
|
||||
// - Transaction corrupt.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Reject
|
||||
// - Cannot succeed in any imagined ledger.
|
||||
temMALFORMED = -299,
|
||||
|
||||
temBAD_AMOUNT,
|
||||
temBAD_CURRENCY,
|
||||
temBAD_EXPIRATION,
|
||||
temBAD_FEE,
|
||||
temBAD_ISSUER,
|
||||
temBAD_LIMIT,
|
||||
temBAD_OFFER,
|
||||
temBAD_PATH,
|
||||
temBAD_PATH_LOOP,
|
||||
temBAD_REGKEY,
|
||||
temBAD_SEND_NATIVE_LIMIT,
|
||||
temBAD_SEND_NATIVE_MAX,
|
||||
temBAD_SEND_NATIVE_NO_DIRECT,
|
||||
temBAD_SEND_NATIVE_PARTIAL,
|
||||
temBAD_SEND_NATIVE_PATHS,
|
||||
temBAD_SEQUENCE,
|
||||
temBAD_SIGNATURE,
|
||||
temBAD_SRC_ACCOUNT,
|
||||
temBAD_TRANSFER_RATE,
|
||||
temDST_IS_SRC,
|
||||
temDST_NEEDED,
|
||||
temINVALID,
|
||||
temINVALID_FLAG,
|
||||
temREDUNDANT,
|
||||
temRIPPLE_EMPTY,
|
||||
temDISABLED,
|
||||
temBAD_SIGNER,
|
||||
temBAD_QUORUM,
|
||||
temBAD_WEIGHT,
|
||||
temBAD_TICK_SIZE,
|
||||
temINVALID_ACCOUNT_ID,
|
||||
temCANNOT_PREAUTH_SELF,
|
||||
temINVALID_COUNT,
|
||||
|
||||
temUNCERTAIN, // An internal intermediate result; should never be returned.
|
||||
temUNKNOWN, // An internal intermediate result; should never be returned.
|
||||
|
||||
temSEQ_AND_TICKET,
|
||||
temBAD_NFTOKEN_TRANSFER_FEE,
|
||||
|
||||
temBAD_AMM_TOKENS,
|
||||
|
||||
temXCHAIN_EQUAL_DOOR_ACCOUNTS,
|
||||
temXCHAIN_BAD_PROOF,
|
||||
temXCHAIN_BRIDGE_BAD_ISSUES,
|
||||
temXCHAIN_BRIDGE_NONDOOR_OWNER,
|
||||
temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT,
|
||||
temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT,
|
||||
|
||||
temHOOK_DATA_TOO_LARGE,
|
||||
temEMPTY_DID,
|
||||
|
||||
temARRAY_EMPTY,
|
||||
temARRAY_TOO_LARGE,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum TEFcodes : TERUnderlyingType {
|
||||
// Note: Range is stable.
|
||||
// Exact numbers are used in ripple-binary-codec:
|
||||
// https://github.com/ripple/ripple-binary-codec/blob/master/src/enums/definitions.json
|
||||
// Use tokens.
|
||||
|
||||
// -199 .. -100: F
|
||||
// Failure (sequence number previously used)
|
||||
//
|
||||
// Causes:
|
||||
// - Transaction cannot succeed because of ledger state.
|
||||
// - Unexpected ledger state.
|
||||
// - C++ exception.
|
||||
//
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Could succeed in an imagined ledger.
|
||||
tefFAILURE = -199,
|
||||
tefALREADY,
|
||||
tefBAD_ADD_AUTH,
|
||||
tefBAD_AUTH,
|
||||
tefBAD_LEDGER,
|
||||
tefCREATED,
|
||||
tefEXCEPTION,
|
||||
tefINTERNAL,
|
||||
tefNO_AUTH_REQUIRED, // Can't set auth if auth is not required.
|
||||
tefPAST_SEQ,
|
||||
tefWRONG_PRIOR,
|
||||
tefMASTER_DISABLED,
|
||||
tefMAX_LEDGER,
|
||||
tefBAD_SIGNATURE,
|
||||
tefBAD_QUORUM,
|
||||
tefNOT_MULTI_SIGNING,
|
||||
tefBAD_AUTH_MASTER,
|
||||
tefINVARIANT_FAILED,
|
||||
tefTOO_BIG,
|
||||
tefNO_TICKET,
|
||||
tefNFTOKEN_IS_NOT_TRANSFERABLE,
|
||||
tefPAST_IMPORT_SEQ,
|
||||
tefPAST_IMPORT_VL_SEQ,
|
||||
tefNONDIR_EMIT,
|
||||
tefIMPORT_BLACKHOLED,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum TERcodes : TERUnderlyingType {
|
||||
// Note: Range is stable.
|
||||
// Exact numbers are used in ripple-binary-codec:
|
||||
// https://github.com/ripple/ripple-binary-codec/blob/master/src/enums/definitions.json
|
||||
// Use tokens.
|
||||
|
||||
// -99 .. -1: R Retry
|
||||
// sequence too high, no funds for txn fee, originating -account
|
||||
// non-existent
|
||||
//
|
||||
// Cause:
|
||||
// Prior application of another, possibly non-existent, transaction could
|
||||
// allow this transaction to succeed.
|
||||
//
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - May be forwarded
|
||||
// - Results indicating the txn was forwarded: terQUEUED
|
||||
// - All others are not forwarded.
|
||||
// - Might succeed later
|
||||
// - Hold
|
||||
// - Makes hole in sequence which jams transactions.
|
||||
terRETRY = -99,
|
||||
terFUNDS_SPENT, // DEPRECATED.
|
||||
terINSUF_FEE_B, // Can't pay fee, therefore don't burden network.
|
||||
terNO_ACCOUNT, // Can't pay fee, therefore don't burden network.
|
||||
terNO_AUTH, // Not authorized to hold IOUs.
|
||||
terNO_LINE, // Internal flag.
|
||||
terOWNERS, // Can't succeed with non-zero owner count.
|
||||
terPRE_SEQ, // Can't pay fee, no point in forwarding, so don't
|
||||
// burden network.
|
||||
terLAST, // DEPRECATED.
|
||||
terNO_RIPPLE, // Rippling not allowed
|
||||
terQUEUED, // Transaction is being held in TxQ until fee drops
|
||||
terPRE_TICKET, // Ticket is not yet in ledger but might be on its way
|
||||
terNO_AMM, // AMM doesn't exist for the asset pair
|
||||
terNO_HOOK // Transaction requires a non-existent hook definition
|
||||
// (referenced by sfHookHash)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum TEScodes : TERUnderlyingType {
|
||||
// Note: Exact number must stay stable. This code is stored by value
|
||||
// in metadata for historic transactions.
|
||||
|
||||
// 0: S Success (success)
|
||||
// Causes:
|
||||
// - Success.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
tesSUCCESS = 0,
|
||||
tesPARTIAL = 1,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum TECcodes : TERUnderlyingType {
|
||||
// Note: Exact numbers must stay stable. These codes are stored by
|
||||
// value in metadata for historic transactions.
|
||||
|
||||
// 100 .. 255 C
|
||||
// Claim fee only (ripple transaction with no good paths, pay to
|
||||
// non-existent account, no path)
|
||||
//
|
||||
// Causes:
|
||||
// - Success, but does not achieve optimal result.
|
||||
// - Invalid transaction or no effect, but claim fee to use the sequence
|
||||
// number.
|
||||
//
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
//
|
||||
// Only allowed as a return code of appliedTransaction when !tapRETRY.
|
||||
// Otherwise, treated as terRETRY.
|
||||
//
|
||||
// DO NOT CHANGE THESE NUMBERS: They appear in ledger meta data.
|
||||
tecCLAIM = 100,
|
||||
tecPATH_PARTIAL = 101,
|
||||
tecUNFUNDED_ADD = 102, // Unused legacy code
|
||||
tecUNFUNDED_OFFER = 103,
|
||||
tecUNFUNDED_PAYMENT = 104,
|
||||
tecFAILED_PROCESSING = 105,
|
||||
tecDIR_FULL = 121,
|
||||
tecINSUF_RESERVE_LINE = 122,
|
||||
tecINSUF_RESERVE_OFFER = 123,
|
||||
tecNO_DST = 124,
|
||||
tecNO_DST_INSUF_NATIVE = 125,
|
||||
tecNO_LINE_INSUF_RESERVE = 126,
|
||||
tecNO_LINE_REDUNDANT = 127,
|
||||
tecPATH_DRY = 128,
|
||||
tecUNFUNDED = 129,
|
||||
tecNO_ALTERNATIVE_KEY = 130,
|
||||
tecNO_REGULAR_KEY = 131,
|
||||
tecOWNERS = 132,
|
||||
tecNO_ISSUER = 133,
|
||||
tecNO_AUTH = 134,
|
||||
tecNO_LINE = 135,
|
||||
tecINSUFF_FEE = 136,
|
||||
tecFROZEN = 137,
|
||||
tecNO_TARGET = 138,
|
||||
tecNO_PERMISSION = 139,
|
||||
tecNO_ENTRY = 140,
|
||||
tecINSUFFICIENT_RESERVE = 141,
|
||||
tecNEED_MASTER_KEY = 142,
|
||||
tecDST_TAG_NEEDED = 143,
|
||||
tecINTERNAL = 144,
|
||||
tecOVERSIZE = 145,
|
||||
tecCRYPTOCONDITION_ERROR = 146,
|
||||
tecINVARIANT_FAILED = 147,
|
||||
tecEXPIRED = 148,
|
||||
tecDUPLICATE = 149,
|
||||
tecKILLED = 150,
|
||||
tecHAS_OBLIGATIONS = 151,
|
||||
tecTOO_SOON = 152,
|
||||
tecHOOK_REJECTED = 153,
|
||||
tecMAX_SEQUENCE_REACHED = 154,
|
||||
tecNO_SUITABLE_NFTOKEN_PAGE = 155,
|
||||
tecNFTOKEN_BUY_SELL_MISMATCH = 156,
|
||||
tecNFTOKEN_OFFER_TYPE_MISMATCH = 157,
|
||||
tecCANT_ACCEPT_OWN_NFTOKEN_OFFER = 158,
|
||||
tecINSUFFICIENT_FUNDS = 159,
|
||||
tecOBJECT_NOT_FOUND = 160,
|
||||
tecINSUFFICIENT_PAYMENT = 161,
|
||||
tecUNFUNDED_AMM = 162,
|
||||
tecAMM_BALANCE = 163,
|
||||
tecAMM_FAILED = 164,
|
||||
tecAMM_INVALID_TOKENS = 165,
|
||||
tecAMM_EMPTY = 166,
|
||||
tecAMM_NOT_EMPTY = 167,
|
||||
tecAMM_ACCOUNT = 168,
|
||||
tecREQUIRES_FLAG = 169,
|
||||
tecPRECISION_LOSS = 170,
|
||||
tecXCHAIN_BAD_TRANSFER_ISSUE = 171,
|
||||
tecXCHAIN_NO_CLAIM_ID = 172,
|
||||
tecXCHAIN_BAD_CLAIM_ID = 173,
|
||||
tecXCHAIN_CLAIM_NO_QUORUM = 174,
|
||||
tecXCHAIN_PROOF_UNKNOWN_KEY = 175,
|
||||
tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE = 176,
|
||||
tecXCHAIN_WRONG_CHAIN = 177,
|
||||
tecXCHAIN_REWARD_MISMATCH = 178,
|
||||
tecXCHAIN_NO_SIGNERS_LIST = 179,
|
||||
tecXCHAIN_SENDING_ACCOUNT_MISMATCH = 180,
|
||||
tecXCHAIN_INSUFF_CREATE_AMOUNT = 181,
|
||||
tecXCHAIN_ACCOUNT_CREATE_PAST = 182,
|
||||
tecXCHAIN_ACCOUNT_CREATE_TOO_MANY = 183,
|
||||
tecXCHAIN_PAYMENT_FAILED = 184,
|
||||
tecXCHAIN_SELF_COMMIT = 185,
|
||||
tecXCHAIN_CREATE_ACCOUNT_DISABLED = 186,
|
||||
tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR = 191,
|
||||
tecINSUF_RESERVE_SELLER = 187,
|
||||
tecIMMUTABLE = 188,
|
||||
tecTOO_MANY_REMARKS = 189,
|
||||
tecINCOMPLETE = 190,
|
||||
// 191: tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR
|
||||
tecEMPTY_DID = 192,
|
||||
tecINVALID_UPDATE_TIME = 193,
|
||||
tecTOKEN_PAIR_NOT_FOUND = 194,
|
||||
tecARRAY_EMPTY = 195,
|
||||
tecARRAY_TOO_LARGE = 196,
|
||||
tecLAST_POSSIBLE_ENTRY = 255,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// For generic purposes, a free function that returns the value of a TE*codes.
|
||||
constexpr TERUnderlyingType
|
||||
TERtoInt(TELcodes v)
|
||||
{
|
||||
return safe_cast<TERUnderlyingType>(v);
|
||||
}
|
||||
|
||||
constexpr TERUnderlyingType
|
||||
TERtoInt(TEMcodes v)
|
||||
{
|
||||
return safe_cast<TERUnderlyingType>(v);
|
||||
}
|
||||
|
||||
constexpr TERUnderlyingType
|
||||
TERtoInt(TEFcodes v)
|
||||
{
|
||||
return safe_cast<TERUnderlyingType>(v);
|
||||
}
|
||||
|
||||
constexpr TERUnderlyingType
|
||||
TERtoInt(TERcodes v)
|
||||
{
|
||||
return safe_cast<TERUnderlyingType>(v);
|
||||
}
|
||||
|
||||
constexpr TERUnderlyingType
|
||||
TERtoInt(TEScodes v)
|
||||
{
|
||||
return safe_cast<TERUnderlyingType>(v);
|
||||
}
|
||||
|
||||
constexpr TERUnderlyingType
|
||||
TERtoInt(TECcodes v)
|
||||
{
|
||||
return safe_cast<TERUnderlyingType>(v);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Template class that is specific to selected ranges of error codes. The
|
||||
// Trait tells std::enable_if which ranges are allowed.
|
||||
template <template <typename> class Trait>
|
||||
class TERSubset
|
||||
{
|
||||
public:
|
||||
TERUnderlyingType code_;
|
||||
|
||||
// Constructors
|
||||
constexpr TERSubset() : code_(tesSUCCESS)
|
||||
{
|
||||
}
|
||||
constexpr TERSubset(TERSubset const& rhs) = default;
|
||||
constexpr TERSubset(TERSubset&& rhs) = default;
|
||||
|
||||
private:
|
||||
constexpr explicit TERSubset(int rhs) : code_(rhs)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr TERSubset
|
||||
fromInt(int from)
|
||||
{
|
||||
return TERSubset(from);
|
||||
}
|
||||
|
||||
// Trait tells enable_if which types are allowed for construction.
|
||||
template <
|
||||
typename T,
|
||||
typename = std::enable_if_t<
|
||||
Trait<std::remove_cv_t<std::remove_reference_t<T>>>::value>>
|
||||
constexpr TERSubset(T rhs) : code_(TERtoInt(rhs))
|
||||
{
|
||||
}
|
||||
|
||||
// Assignment
|
||||
constexpr TERSubset&
|
||||
operator=(TERSubset const& rhs) = default;
|
||||
constexpr TERSubset&
|
||||
operator=(TERSubset&& rhs) = default;
|
||||
|
||||
// Trait tells enable_if which types are allowed for assignment.
|
||||
template <typename T>
|
||||
constexpr auto
|
||||
operator=(T rhs) -> std::enable_if_t<Trait<T>::value, TERSubset&>
|
||||
{
|
||||
code_ = TERtoInt(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Conversion to bool.
|
||||
explicit operator bool() const
|
||||
{
|
||||
return code_ < tesSUCCESS || code_ >= tecCLAIM;
|
||||
}
|
||||
|
||||
// Conversion to Json::Value allows assignment to Json::Objects
|
||||
// without casting.
|
||||
operator Json::Value() const
|
||||
{
|
||||
return Json::Value{code_};
|
||||
}
|
||||
|
||||
// Streaming operator.
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, TERSubset const& rhs)
|
||||
{
|
||||
return os << rhs.code_;
|
||||
}
|
||||
|
||||
// Return the underlying value. Not a member so similarly named free
|
||||
// functions can do the same work for the enums.
|
||||
//
|
||||
// It's worth noting that an explicit conversion operator was considered
|
||||
// and rejected. Consider this case, taken from Status.h
|
||||
//
|
||||
// class Status {
|
||||
// int code_;
|
||||
// public:
|
||||
// Status (TER ter)
|
||||
// : code_ (ter) {}
|
||||
// }
|
||||
//
|
||||
// This code compiles with no errors or warnings if TER has an explicit
|
||||
// (unnamed) conversion to int. To avoid silent conversions like these
|
||||
// we provide (only) a named conversion.
|
||||
friend constexpr TERUnderlyingType
|
||||
TERtoInt(TERSubset v)
|
||||
{
|
||||
return v.code_;
|
||||
}
|
||||
};
|
||||
|
||||
// Comparison operators.
|
||||
// Only enabled if both arguments return int if TERtiInt is called with them.
|
||||
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,
|
||||
bool>
|
||||
{
|
||||
return TERtoInt(lhs) == TERtoInt(rhs);
|
||||
}
|
||||
|
||||
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,
|
||||
bool>
|
||||
{
|
||||
return TERtoInt(lhs) != TERtoInt(rhs);
|
||||
}
|
||||
|
||||
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,
|
||||
bool>
|
||||
{
|
||||
return TERtoInt(lhs) < TERtoInt(rhs);
|
||||
}
|
||||
|
||||
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,
|
||||
bool>
|
||||
{
|
||||
return TERtoInt(lhs) <= TERtoInt(rhs);
|
||||
}
|
||||
|
||||
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,
|
||||
bool>
|
||||
{
|
||||
return TERtoInt(lhs) > TERtoInt(rhs);
|
||||
}
|
||||
|
||||
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,
|
||||
bool>
|
||||
{
|
||||
return TERtoInt(lhs) >= TERtoInt(rhs);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Use traits to build a TERSubset that can convert from any of the TE*codes
|
||||
// enums *except* TECcodes: NotTEC
|
||||
|
||||
// NOTE: NotTEC is useful for codes returned by preflight in transactors.
|
||||
// Preflight checks occur prior to signature checking. If preflight returned
|
||||
// a tec code, then a malicious user could submit a transaction with a very
|
||||
// large fee and have that fee charged against an account without using that
|
||||
// account's valid signature.
|
||||
template <typename FROM>
|
||||
class CanCvtToNotTEC : public std::false_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToNotTEC<TELcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToNotTEC<TEMcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToNotTEC<TEFcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToNotTEC<TERcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToNotTEC<TEScodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
using NotTEC = TERSubset<CanCvtToNotTEC>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Use traits to build a TERSubset that can convert from any of the TE*codes
|
||||
// enums as well as from NotTEC.
|
||||
template <typename FROM>
|
||||
class CanCvtToTER : public std::false_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<TELcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<TEMcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<TEFcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<TERcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<TEScodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<TECcodes> : public std::true_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class CanCvtToTER<NotTEC> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// TER allows all of the subsets.
|
||||
using TER = TERSubset<CanCvtToTER>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline bool
|
||||
isTelLocal(TER x)
|
||||
{
|
||||
return ((x) >= telLOCAL_ERROR && (x) < temMALFORMED);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTemMalformed(TER x)
|
||||
{
|
||||
return ((x) >= temMALFORMED && (x) < tefFAILURE);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTefFailure(TER x)
|
||||
{
|
||||
return ((x) >= tefFAILURE && (x) < terRETRY);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTerRetry(TER x)
|
||||
{
|
||||
return ((x) >= terRETRY && (x) < tesSUCCESS);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
isTesSuccess(T x)
|
||||
{
|
||||
return ((x) >= tesSUCCESS) && (x) < tecCLAIM;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTesSuccess(TER x)
|
||||
{
|
||||
return ((x) >= tesSUCCESS) && (x) < tecCLAIM;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTecClaim(TER x)
|
||||
{
|
||||
return ((x) >= tecCLAIM);
|
||||
}
|
||||
|
||||
std::unordered_map<
|
||||
TERUnderlyingType,
|
||||
std::pair<char const* const, char const* const>> const&
|
||||
transResults();
|
||||
|
||||
bool
|
||||
transResultInfo(TER code, std::string& token, std::string& text);
|
||||
|
||||
std::string
|
||||
transToken(TER code);
|
||||
|
||||
std::string
|
||||
transHuman(TER code);
|
||||
|
||||
std::optional<TER>
|
||||
transCode(std::string const& token);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
227
include/xrpl/protocol/TxFlags.h
Normal file
227
include/xrpl/protocol/TxFlags.h
Normal file
@@ -0,0 +1,227 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_TXFLAGS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_TXFLAGS_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Transaction flags.
|
||||
|
||||
These flags are specified in a transaction's 'Flags' field and modify the
|
||||
behavior of that transaction.
|
||||
|
||||
There are two types of flags:
|
||||
|
||||
(1) Universal flags: these are flags which apply to, and are interpreted
|
||||
the same way by, all transactions, except, perhaps,
|
||||
to special pseudo-transactions.
|
||||
|
||||
(2) Tx-Specific flags: these are flags which are interpreted according
|
||||
to the type of the transaction being executed.
|
||||
That is, the same numerical flag value may have
|
||||
different effects, depending on the transaction
|
||||
being executed.
|
||||
|
||||
@note The universal transaction flags occupy the high-order 8 bits. The
|
||||
tx-specific flags occupy the remaining 24 bits.
|
||||
|
||||
@warning Transaction flags form part of the protocol. **Changing them
|
||||
should be avoided because without special handling, this will
|
||||
result in a hard fork.**
|
||||
|
||||
@ingroup protocol
|
||||
*/
|
||||
|
||||
// Formatting equals sign aligned 4 spaces after longest prefix, except for
|
||||
// wrapped lines
|
||||
// clang-format off
|
||||
// Universal Transaction flags:
|
||||
enum UniversalFlags : uint32_t {
|
||||
tfFullyCanonicalSig = 0x80000000,
|
||||
};
|
||||
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig;
|
||||
constexpr std::uint32_t tfUniversalMask = ~tfUniversal;
|
||||
|
||||
// AccountSet flags:
|
||||
enum AccountSetFlags : uint32_t {
|
||||
tfRequireDestTag = 0x00010000,
|
||||
tfOptionalDestTag = 0x00020000,
|
||||
tfRequireAuth = 0x00040000,
|
||||
tfOptionalAuth = 0x00080000,
|
||||
tfDisallowXRP = 0x00100000,
|
||||
tfAllowXRP = 0x00200000,
|
||||
};
|
||||
constexpr std::uint32_t tfAccountSetMask =
|
||||
~(tfUniversal | tfRequireDestTag | tfOptionalDestTag | tfRequireAuth |
|
||||
tfOptionalAuth | tfDisallowXRP | tfAllowXRP);
|
||||
|
||||
// AccountSet SetFlag/ClearFlag values
|
||||
enum AccountFlags : uint32_t {
|
||||
asfRequireDest = 1,
|
||||
asfRequireAuth = 2,
|
||||
asfDisallowXRP = 3,
|
||||
asfDisableMaster = 4,
|
||||
asfAccountTxnID = 5,
|
||||
asfNoFreeze = 6,
|
||||
asfGlobalFreeze = 7,
|
||||
asfDefaultRipple = 8,
|
||||
asfDepositAuth = 9,
|
||||
asfAuthorizedNFTokenMinter = 10,
|
||||
asfTshCollect = 11,
|
||||
asfDisallowIncomingNFTokenOffer = 12,
|
||||
asfDisallowIncomingCheck = 13,
|
||||
asfDisallowIncomingPayChan = 14,
|
||||
asfDisallowIncomingTrustline = 15,
|
||||
asfDisallowIncomingRemit = 16,
|
||||
asfAllowTrustLineClawback = 17,
|
||||
};
|
||||
|
||||
// OfferCreate flags:
|
||||
enum OfferCreateFlags : uint32_t {
|
||||
tfPassive = 0x00010000,
|
||||
tfImmediateOrCancel = 0x00020000,
|
||||
tfFillOrKill = 0x00040000,
|
||||
tfSell = 0x00080000,
|
||||
};
|
||||
constexpr std::uint32_t tfOfferCreateMask =
|
||||
~(tfUniversal | tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell);
|
||||
|
||||
// Payment flags:
|
||||
enum PaymentFlags : uint32_t {
|
||||
tfNoRippleDirect = 0x00010000,
|
||||
tfPartialPayment = 0x00020000,
|
||||
tfLimitQuality = 0x00040000,
|
||||
};
|
||||
constexpr std::uint32_t tfPaymentMask =
|
||||
~(tfUniversal | tfPartialPayment | tfLimitQuality | tfNoRippleDirect);
|
||||
|
||||
// TrustSet flags:
|
||||
enum TrustSetFlags : uint32_t {
|
||||
tfSetfAuth = 0x00010000,
|
||||
tfSetNoRipple = 0x00020000,
|
||||
tfClearNoRipple = 0x00040000,
|
||||
tfSetFreeze = 0x00100000,
|
||||
tfClearFreeze = 0x00200000,
|
||||
};
|
||||
constexpr std::uint32_t tfTrustSetMask =
|
||||
~(tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple | tfSetFreeze |
|
||||
tfClearFreeze);
|
||||
|
||||
// EnableAmendment flags:
|
||||
enum EnableAmendmentFlags : std::uint32_t {
|
||||
tfGotMajority = 0x00010000,
|
||||
tfLostMajority = 0x00020000,
|
||||
tfTestSuite = 0x80000000,
|
||||
};
|
||||
|
||||
// PaymentChannelClaim flags:
|
||||
enum PaymentChannelClaimFlags : uint32_t {
|
||||
tfRenew = 0x00010000,
|
||||
tfClose = 0x00020000,
|
||||
};
|
||||
constexpr std::uint32_t tfPayChanClaimMask = ~(tfUniversal | tfRenew | tfClose);
|
||||
|
||||
// NFTokenMint flags:
|
||||
enum NFTokenMintFlags : uint32_t {
|
||||
tfBurnable = 0x00000001,
|
||||
tfOnlyXRP = 0x00000002,
|
||||
tfTrustLine = 0x00000004,
|
||||
tfTransferable = 0x00000008,
|
||||
tfStrongTSH = 0x00008000,
|
||||
};
|
||||
|
||||
constexpr std::uint32_t const tfNFTokenMintOldMask =
|
||||
~(tfUniversal | tfBurnable | tfOnlyXRP | tfTrustLine | tfTransferable | tfStrongTSH);
|
||||
|
||||
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between
|
||||
// accounts allowed a TrustLine to be added to the issuer of that token
|
||||
// without explicit permission from that issuer. This was enabled by
|
||||
// minting the NFToken with the tfTrustLine flag set.
|
||||
//
|
||||
// That capability could be used to attack the NFToken issuer. It
|
||||
// would be possible for two accounts to trade the NFToken back and forth
|
||||
// building up any number of TrustLines on the issuer, increasing the
|
||||
// issuer's reserve without bound.
|
||||
//
|
||||
// The fixRemoveNFTokenAutoTrustLine amendment disables minting with the
|
||||
// tfTrustLine flag as a way to prevent the attack. But until the
|
||||
// amendment passes we still need to keep the old behavior available.
|
||||
|
||||
constexpr std::uint32_t const tfNFTokenMintMask =
|
||||
~(tfUniversal | tfBurnable | tfOnlyXRP | tfTransferable | tfStrongTSH);
|
||||
|
||||
// NFTokenCreateOffer flags:
|
||||
enum NFTokenCreateOfferFlags : uint32_t {
|
||||
tfSellNFToken = 0x00000001,
|
||||
};
|
||||
constexpr std::uint32_t const tfNFTokenCreateOfferMask =
|
||||
~(tfUniversal | tfSellNFToken);
|
||||
|
||||
// NFTokenCancelOffer flags:
|
||||
constexpr std::uint32_t const tfNFTokenCancelOfferMask = ~(tfUniversal);
|
||||
|
||||
// NFTokenAcceptOffer flags:
|
||||
constexpr std::uint32_t const tfNFTokenAcceptOfferMask = ~tfUniversal;
|
||||
|
||||
// URIToken mask
|
||||
constexpr std::uint32_t const tfURITokenMintMask = ~(tfUniversal | tfBurnable);
|
||||
constexpr std::uint32_t const tfURITokenNonMintMask = ~tfUniversal;
|
||||
|
||||
// ClaimReward flags:
|
||||
enum ClaimRewardFlags : uint32_t {
|
||||
tfOptOut = 0x00000001,
|
||||
};
|
||||
constexpr std::uint32_t const tfClaimRewardMask = ~(tfUniversal | tfOptOut);
|
||||
|
||||
// Remarks flags:
|
||||
constexpr std::uint32_t const tfImmutable = 1;
|
||||
|
||||
// Clawback flags:
|
||||
constexpr std::uint32_t const tfClawbackMask = ~tfUniversal;
|
||||
|
||||
// AMM Flags:
|
||||
constexpr std::uint32_t tfLPToken = 0x00010000;
|
||||
constexpr std::uint32_t tfWithdrawAll = 0x00020000;
|
||||
constexpr std::uint32_t tfOneAssetWithdrawAll = 0x00040000;
|
||||
constexpr std::uint32_t tfSingleAsset = 0x00080000;
|
||||
constexpr std::uint32_t tfTwoAsset = 0x00100000;
|
||||
constexpr std::uint32_t tfOneAssetLPToken = 0x00200000;
|
||||
constexpr std::uint32_t tfLimitLPToken = 0x00400000;
|
||||
constexpr std::uint32_t tfTwoAssetIfEmpty = 0x00800000;
|
||||
constexpr std::uint32_t tfWithdrawSubTx =
|
||||
tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken |
|
||||
tfLimitLPToken | tfWithdrawAll | tfOneAssetWithdrawAll;
|
||||
constexpr std::uint32_t tfDepositSubTx =
|
||||
tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken |
|
||||
tfLimitLPToken | tfTwoAssetIfEmpty;
|
||||
constexpr std::uint32_t tfWithdrawMask = ~(tfUniversal | tfWithdrawSubTx);
|
||||
constexpr std::uint32_t tfDepositMask = ~(tfUniversal | tfDepositSubTx);
|
||||
|
||||
// BridgeModify flags:
|
||||
constexpr std::uint32_t tfClearAccountCreateAmount = 0x00010000;
|
||||
constexpr std::uint32_t tfBridgeModifyMask = ~(tfUniversal | tfClearAccountCreateAmount);
|
||||
|
||||
// clang-format on
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
268
include/xrpl/protocol/TxFormats.h
Normal file
268
include/xrpl/protocol/TxFormats.h
Normal file
@@ -0,0 +1,268 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_TXFORMATS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_TXFORMATS_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/KnownFormats.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Transaction type identifiers.
|
||||
|
||||
These are part of the binary message format.
|
||||
|
||||
@ingroup protocol
|
||||
*/
|
||||
/** Transaction type identifieers
|
||||
|
||||
Each ledger object requires a unique type identifier, which is stored
|
||||
within the object itself; this makes it possible to iterate the entire
|
||||
ledger and determine each object's type and verify that the object you
|
||||
retrieved from a given hash matches the expected type.
|
||||
|
||||
@warning Since these values are included in transactions, which are signed
|
||||
objects, and used by the code to determine the type of transaction
|
||||
being invoked, they are part of the protocol. **Changing them
|
||||
should be avoided because without special handling, this will
|
||||
result in a hard fork.**
|
||||
|
||||
@note When retiring types, the specific values should not be removed but
|
||||
should be marked as [[deprecated]]. This is to avoid accidental
|
||||
reuse of identifiers.
|
||||
|
||||
@todo The C++ language does not enable checking for duplicate values
|
||||
here. If it becomes possible then we should do this.
|
||||
|
||||
@ingroup protocol
|
||||
*/
|
||||
// clang-format off
|
||||
enum TxType : std::uint16_t
|
||||
{
|
||||
/** This transaction type executes a payment. */
|
||||
ttPAYMENT = 0,
|
||||
|
||||
/** This transaction type creates an escrow object. */
|
||||
ttESCROW_CREATE = 1,
|
||||
|
||||
/** This transaction type completes an existing escrow. */
|
||||
ttESCROW_FINISH = 2,
|
||||
|
||||
/** This transaction type adjusts various account settings. */
|
||||
ttACCOUNT_SET = 3,
|
||||
|
||||
/** This transaction type cancels an existing escrow. */
|
||||
ttESCROW_CANCEL = 4,
|
||||
|
||||
/** This transaction type sets or clears an account's "regular key". */
|
||||
ttREGULAR_KEY_SET = 5,
|
||||
|
||||
/** 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,
|
||||
|
||||
/** This transaction type creates an offer to trade one asset for another. */
|
||||
ttOFFER_CREATE = 7,
|
||||
|
||||
/** This transaction type cancels existing offers to trade one asset for another. */
|
||||
ttOFFER_CANCEL = 8,
|
||||
|
||||
/** 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,
|
||||
|
||||
/** This transaction type creates a new set of tickets. */
|
||||
ttTICKET_CREATE = 10,
|
||||
|
||||
/** 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,
|
||||
|
||||
/** This transaction type modifies the signer list associated with an account. */
|
||||
ttSIGNER_LIST_SET = 12,
|
||||
|
||||
/** This transaction type creates a new unidirectional XRP payment channel. */
|
||||
ttPAYCHAN_CREATE = 13,
|
||||
|
||||
/** This transaction type funds an existing unidirectional XRP payment channel. */
|
||||
ttPAYCHAN_FUND = 14,
|
||||
|
||||
/** This transaction type submits a claim against an existing unidirectional payment channel. */
|
||||
ttPAYCHAN_CLAIM = 15,
|
||||
|
||||
/** This transaction type creates a new check. */
|
||||
ttCHECK_CREATE = 16,
|
||||
|
||||
/** This transaction type cashes an existing check. */
|
||||
ttCHECK_CASH = 17,
|
||||
|
||||
/** This transaction type cancels an existing check. */
|
||||
ttCHECK_CANCEL = 18,
|
||||
|
||||
/** This transaction type grants or revokes authorization to transfer funds. */
|
||||
ttDEPOSIT_PREAUTH = 19,
|
||||
|
||||
/** This transaction type modifies a trustline between two accounts. */
|
||||
ttTRUST_SET = 20,
|
||||
|
||||
/** This transaction type deletes an existing account. */
|
||||
ttACCOUNT_DELETE = 21,
|
||||
|
||||
/** This transaction type installs a hook. */
|
||||
ttHOOK_SET = 22,
|
||||
|
||||
/** This transaction mints a new NFT. */
|
||||
ttNFTOKEN_MINT = 25,
|
||||
|
||||
/** This transaction burns (i.e. destroys) an existing NFT. */
|
||||
ttNFTOKEN_BURN = 26,
|
||||
|
||||
/** This transaction creates a new offer to buy or sell an NFT. */
|
||||
ttNFTOKEN_CREATE_OFFER = 27,
|
||||
|
||||
/** This transaction cancels an existing offer to buy or sell an existing NFT. */
|
||||
ttNFTOKEN_CANCEL_OFFER = 28,
|
||||
|
||||
/** This transaction accepts an existing offer to buy or sell an existing NFT. */
|
||||
ttNFTOKEN_ACCEPT_OFFER = 29,
|
||||
|
||||
/** This transaction claws back issued tokens. */
|
||||
ttCLAWBACK = 30,
|
||||
|
||||
/** This transaction type creates an AMM instance */
|
||||
ttAMM_CREATE = 35,
|
||||
|
||||
/** This transaction type deposits into an AMM instance */
|
||||
ttAMM_DEPOSIT = 36,
|
||||
|
||||
/** This transaction type withdraws from an AMM instance */
|
||||
ttAMM_WITHDRAW = 37,
|
||||
|
||||
/** This transaction type votes for the trading fee */
|
||||
ttAMM_VOTE = 38,
|
||||
|
||||
/** This transaction type bids for the auction slot */
|
||||
ttAMM_BID = 39,
|
||||
|
||||
/** This transaction type deletes AMM in the empty state */
|
||||
ttAMM_DELETE = 40,
|
||||
|
||||
/** This transaction mints/burns/buys/sells a URI TOKEN */
|
||||
ttURITOKEN_MINT = 45,
|
||||
ttURITOKEN_BURN = 46,
|
||||
ttURITOKEN_BUY = 47,
|
||||
ttURITOKEN_CREATE_SELL_OFFER = 48,
|
||||
ttURITOKEN_CANCEL_SELL_OFFER = 49,
|
||||
|
||||
/** This transactions creates a crosschain sequence number */
|
||||
ttXCHAIN_CREATE_CLAIM_ID = 50,
|
||||
|
||||
/** This transactions initiates a crosschain transaction */
|
||||
ttXCHAIN_COMMIT = 51,
|
||||
|
||||
/** This transaction completes a crosschain transaction */
|
||||
ttXCHAIN_CLAIM = 52,
|
||||
|
||||
/** This transaction initiates a crosschain account create transaction */
|
||||
ttXCHAIN_ACCOUNT_CREATE_COMMIT = 53,
|
||||
|
||||
/** This transaction adds an attestation to a claimid*/
|
||||
ttXCHAIN_ADD_CLAIM_ATTESTATION = 54,
|
||||
|
||||
/** This transaction adds an attestation to a claimid*/
|
||||
ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION = 55,
|
||||
|
||||
/** This transaction modifies a sidechain */
|
||||
ttXCHAIN_MODIFY_BRIDGE = 56,
|
||||
|
||||
/** This transactions creates a sidechain */
|
||||
ttXCHAIN_CREATE_BRIDGE = 57,
|
||||
|
||||
/** This transaction type creates or updates a DID */
|
||||
ttDID_SET = 58,
|
||||
|
||||
/** This transaction type deletes a DID */
|
||||
ttDID_DELETE = 59,
|
||||
|
||||
/** This transaction type creates an Oracle instance */
|
||||
ttORACLE_SET = 60,
|
||||
|
||||
/** This transaction type deletes an Oracle instance */
|
||||
ttORACLE_DELETE = 61,
|
||||
|
||||
/* A note attaching transactor that allows the owner or issuer (on a object by object basis) to attach remarks */
|
||||
ttREMARKS_SET = 94,
|
||||
|
||||
/* A payment transactor that delivers only the exact amounts specified, creating accounts and TLs as needed
|
||||
* that the sender pays for. */
|
||||
ttREMIT = 95,
|
||||
|
||||
/** This transaction can only be used by the genesis account, which is controlled exclusively by
|
||||
* rewards/governance hooks, to print new XRP to be delivered directly to an array of destinations,
|
||||
* according to reward schedule */
|
||||
ttGENESIS_MINT = 96,
|
||||
|
||||
/** This transaction accepts a proof of burn from an external network as a basis
|
||||
* for minting according to featureImport */
|
||||
ttIMPORT = 97,
|
||||
|
||||
/** This transaction resets accumulator/counters and claims a reward for holding an average balance
|
||||
* from a specified hook */
|
||||
ttCLAIM_REWARD = 98,
|
||||
|
||||
/** This transaction invokes a hook, providing arbitrary data. Essentially as a 0 drop payment. **/
|
||||
ttINVOKE = 99,
|
||||
|
||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||
|
||||
For details, see: https://xrpl.org/amendments.html
|
||||
*/
|
||||
ttAMENDMENT = 100,
|
||||
|
||||
/** This system-generated transaction type is used to update the network's fee settings.
|
||||
|
||||
For details, see: https://xrpl.org/fee-voting.html
|
||||
*/
|
||||
ttFEE = 101,
|
||||
|
||||
/** This system-generated transaction type is used to update the network's negative UNL
|
||||
|
||||
For details, see: https://xrpl.org/negative-unl.html
|
||||
*/
|
||||
ttUNL_MODIFY = 102,
|
||||
ttEMIT_FAILURE = 103,
|
||||
ttUNL_REPORT = 104,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/** Manages the list of known transaction formats.
|
||||
*/
|
||||
class TxFormats : public KnownFormats<TxType, TxFormats>
|
||||
{
|
||||
private:
|
||||
/** Create the object.
|
||||
This will load the object with all the known transaction formats.
|
||||
*/
|
||||
TxFormats();
|
||||
|
||||
public:
|
||||
static TxFormats const&
|
||||
getInstance();
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
183
include/xrpl/protocol/TxMeta.h
Normal file
183
include/xrpl/protocol/TxMeta.h
Normal file
@@ -0,0 +1,183 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_TX_TRANSACTIONMETA_H_INCLUDED
|
||||
#define RIPPLE_APP_TX_TRANSACTIONMETA_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/utility/Journal.h>
|
||||
#include <ripple/protocol/STArray.h>
|
||||
#include <ripple/protocol/STLedgerEntry.h>
|
||||
#include <ripple/protocol/TER.h>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class TxMeta
|
||||
{
|
||||
private:
|
||||
struct CtorHelper
|
||||
{
|
||||
explicit CtorHelper() = default;
|
||||
};
|
||||
template <class T>
|
||||
TxMeta(
|
||||
uint256 const& txID,
|
||||
std::uint32_t ledger,
|
||||
T const& data,
|
||||
CtorHelper);
|
||||
|
||||
public:
|
||||
TxMeta(uint256 const& transactionID, std::uint32_t ledger);
|
||||
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
|
||||
TxMeta(uint256 const& txID, std::uint32_t ledger, std::string const&);
|
||||
TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
|
||||
|
||||
uint256 const&
|
||||
getTxID() const
|
||||
{
|
||||
return mTransactionID;
|
||||
}
|
||||
std::uint32_t
|
||||
getLgrSeq() const
|
||||
{
|
||||
return mLedger;
|
||||
}
|
||||
int
|
||||
getResult() const
|
||||
{
|
||||
return mResult;
|
||||
}
|
||||
TER
|
||||
getResultTER() const
|
||||
{
|
||||
return TER::fromInt(mResult);
|
||||
}
|
||||
std::uint32_t
|
||||
getIndex() const
|
||||
{
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
void
|
||||
setResult(TER res, int index);
|
||||
|
||||
void
|
||||
setAffectedNode(uint256 const&, SField const& type, std::uint16_t nodeType);
|
||||
STObject&
|
||||
getAffectedNode(SLE::ref node, SField const& type); // create if needed
|
||||
STObject&
|
||||
getAffectedNode(uint256 const&);
|
||||
|
||||
/** Return a list of accounts affected by this transaction */
|
||||
boost::container::flat_set<AccountID>
|
||||
getAffectedAccounts() const;
|
||||
|
||||
Json::Value
|
||||
getJson(JsonOptions p) const
|
||||
{
|
||||
return getAsObject().getJson(p);
|
||||
}
|
||||
void
|
||||
addRaw(Serializer&, TER, std::uint32_t index);
|
||||
|
||||
STObject
|
||||
getAsObject() const;
|
||||
STArray&
|
||||
getNodes()
|
||||
{
|
||||
return (mNodes);
|
||||
}
|
||||
STArray const&
|
||||
getNodes() const
|
||||
{
|
||||
return (mNodes);
|
||||
}
|
||||
|
||||
void
|
||||
setDeliveredAmount(STAmount const& delivered)
|
||||
{
|
||||
mDelivered = delivered;
|
||||
}
|
||||
|
||||
STArray const&
|
||||
getHookExecutions() const
|
||||
{
|
||||
return *mHookExecutions;
|
||||
}
|
||||
|
||||
STArray const&
|
||||
getHookEmissions() const
|
||||
{
|
||||
return *mHookEmissions;
|
||||
}
|
||||
|
||||
void
|
||||
setHookExecutions(STArray const& hookExecutions)
|
||||
{
|
||||
mHookExecutions = hookExecutions;
|
||||
}
|
||||
|
||||
void
|
||||
setHookEmissions(STArray const& hookEmissions)
|
||||
{
|
||||
mHookEmissions = hookEmissions;
|
||||
}
|
||||
|
||||
bool
|
||||
hasHookExecutions() const
|
||||
{
|
||||
return static_cast<bool>(mHookExecutions);
|
||||
}
|
||||
|
||||
bool
|
||||
hasHookEmissions() const
|
||||
{
|
||||
return static_cast<bool>(mHookEmissions);
|
||||
}
|
||||
|
||||
STAmount
|
||||
getDeliveredAmount() const
|
||||
{
|
||||
assert(hasDeliveredAmount());
|
||||
return *mDelivered;
|
||||
}
|
||||
|
||||
bool
|
||||
hasDeliveredAmount() const
|
||||
{
|
||||
return static_cast<bool>(mDelivered);
|
||||
}
|
||||
|
||||
private:
|
||||
uint256 mTransactionID;
|
||||
std::uint32_t mLedger;
|
||||
std::uint32_t mIndex;
|
||||
int mResult;
|
||||
|
||||
std::optional<STAmount> mDelivered;
|
||||
std::optional<STArray> mHookExecutions;
|
||||
std::optional<STArray> mHookEmissions;
|
||||
|
||||
STArray mNodes;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
151
include/xrpl/protocol/UintTypes.h
Normal file
151
include/xrpl/protocol/UintTypes.h
Normal file
@@ -0,0 +1,151 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2014 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_UINTTYPES_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_UINTTYPES_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/UnorderedContainers.h>
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/beast/utility/Zero.h>
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace detail {
|
||||
|
||||
class CurrencyTag
|
||||
{
|
||||
public:
|
||||
explicit CurrencyTag() = default;
|
||||
};
|
||||
|
||||
class DirectoryTag
|
||||
{
|
||||
public:
|
||||
explicit DirectoryTag() = default;
|
||||
};
|
||||
|
||||
class NodeIDTag
|
||||
{
|
||||
public:
|
||||
explicit NodeIDTag() = default;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** 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>;
|
||||
|
||||
/** Currency is a hash representing a specific currency. */
|
||||
using Currency = base_uint<160, detail::CurrencyTag>;
|
||||
|
||||
/** NodeID is a 160-bit hash representing one node. */
|
||||
using NodeID = base_uint<160, detail::NodeIDTag>;
|
||||
|
||||
/** XRP currency. */
|
||||
Currency const&
|
||||
xrpCurrency();
|
||||
|
||||
/** A placeholder for empty currencies. */
|
||||
Currency const&
|
||||
noCurrency();
|
||||
|
||||
/** We deliberately disallow the currency that looks like "XAH" because too
|
||||
many people were using it instead of the correct XAH currency. */
|
||||
Currency const&
|
||||
badCurrency();
|
||||
|
||||
inline bool
|
||||
isXRP(Currency const& c)
|
||||
{
|
||||
return c == beast::zero;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isBadCurrency(Currency const& c)
|
||||
{
|
||||
static const std::set<Currency> badCurrencies{
|
||||
Currency(0x7861680000000000), // xah
|
||||
Currency(0x7861480000000000), // xaH
|
||||
Currency(0x7841680000000000), // xAh
|
||||
Currency(0x7841480000000000), // xAH
|
||||
Currency(0x5861680000000000), // Xah
|
||||
Currency(0x5861480000000000), // XaH
|
||||
Currency(0x5841680000000000), // XAh
|
||||
Currency(0x5841480000000000) // XAH
|
||||
};
|
||||
|
||||
return badCurrencies.find(c) != badCurrencies.end();
|
||||
}
|
||||
|
||||
/** Returns "", "XAH", or three letter ISO code. */
|
||||
std::string
|
||||
to_string(Currency const& c);
|
||||
|
||||
/** Tries to convert a string to a Currency, returns true on success.
|
||||
|
||||
@note This function will return success if the resulting currency is
|
||||
badCurrency(). This legacy behavior is unfortunate; changing this
|
||||
will require very careful checking everywhere and may mean having
|
||||
to rewrite some unit test code.
|
||||
*/
|
||||
bool
|
||||
to_currency(Currency&, std::string const&);
|
||||
|
||||
/** Tries to convert a string to a Currency, returns noCurrency() on failure.
|
||||
|
||||
@note This function can return badCurrency(). This legacy behavior is
|
||||
unfortunate; changing this will require very careful checking
|
||||
everywhere and may mean having to rewrite some unit test code.
|
||||
*/
|
||||
Currency
|
||||
to_currency(std::string const&);
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, Currency const& x)
|
||||
{
|
||||
os << to_string(x);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<ripple::Currency> : ripple::Currency::hasher
|
||||
{
|
||||
explicit hash() = default;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<ripple::NodeID> : ripple::NodeID::hasher
|
||||
{
|
||||
explicit hash() = default;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<ripple::Directory> : ripple::Directory::hasher
|
||||
{
|
||||
explicit hash() = default;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
504
include/xrpl/protocol/XChainAttestations.h
Normal file
504
include/xrpl/protocol/XChainAttestations.h
Normal file
@@ -0,0 +1,504 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2022 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STXATTESTATIONS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STXATTESTATIONS_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/Expected.h>
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
#include <ripple/protocol/Issue.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/STXChainBridge.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <ripple/protocol/TER.h>
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace Attestations {
|
||||
|
||||
struct AttestationBase
|
||||
{
|
||||
// Account associated with the public key
|
||||
AccountID attestationSignerAccount;
|
||||
// Public key from the witness server attesting to the event
|
||||
PublicKey publicKey;
|
||||
// Signature from the witness server attesting to the event
|
||||
Buffer signature;
|
||||
// Account on the sending chain that triggered the event (sent the
|
||||
// transaction)
|
||||
AccountID sendingAccount;
|
||||
// Amount transfered on the sending chain
|
||||
STAmount sendingAmount;
|
||||
// Account on the destination chain that collects a share of the attestation
|
||||
// reward
|
||||
AccountID rewardAccount;
|
||||
// Amount was transfered on the locking chain
|
||||
bool wasLockingChainSend;
|
||||
|
||||
explicit AttestationBase(
|
||||
AccountID attestationSignerAccount_,
|
||||
PublicKey const& publicKey_,
|
||||
Buffer signature_,
|
||||
AccountID const& sendingAccount_,
|
||||
STAmount const& sendingAmount_,
|
||||
AccountID const& rewardAccount_,
|
||||
bool wasLockingChainSend_);
|
||||
|
||||
AttestationBase(AttestationBase const&) = default;
|
||||
|
||||
virtual ~AttestationBase() = default;
|
||||
|
||||
AttestationBase&
|
||||
operator=(AttestationBase const&) = default;
|
||||
|
||||
// verify that the signature attests to the data.
|
||||
bool
|
||||
verify(STXChainBridge const& bridge) const;
|
||||
|
||||
protected:
|
||||
explicit AttestationBase(STObject const& o);
|
||||
explicit AttestationBase(Json::Value const& v);
|
||||
|
||||
[[nodiscard]] static bool
|
||||
equalHelper(AttestationBase const& lhs, AttestationBase const& rhs);
|
||||
|
||||
[[nodiscard]] static bool
|
||||
sameEventHelper(AttestationBase const& lhs, AttestationBase const& rhs);
|
||||
|
||||
void
|
||||
addHelper(STObject& o) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] virtual std::vector<std::uint8_t>
|
||||
message(STXChainBridge const& bridge) const = 0;
|
||||
};
|
||||
|
||||
// Attest to a regular cross-chain transfer
|
||||
struct AttestationClaim : AttestationBase
|
||||
{
|
||||
std::uint64_t claimID;
|
||||
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_);
|
||||
|
||||
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_);
|
||||
|
||||
explicit AttestationClaim(STObject const& o);
|
||||
explicit AttestationClaim(Json::Value const& v);
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
// return true if the two attestations attest to the same thing
|
||||
[[nodiscard]] bool
|
||||
sameEvent(AttestationClaim const& rhs) const;
|
||||
|
||||
[[nodiscard]] static std::vector<std::uint8_t>
|
||||
message(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t claimID,
|
||||
std::optional<AccountID> const& dst);
|
||||
|
||||
[[nodiscard]] bool
|
||||
validAmounts() const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::vector<std::uint8_t>
|
||||
message(STXChainBridge const& bridge) const override;
|
||||
|
||||
friend bool
|
||||
operator==(AttestationClaim const& lhs, AttestationClaim const& rhs);
|
||||
};
|
||||
|
||||
struct CmpByClaimID
|
||||
{
|
||||
bool
|
||||
operator()(AttestationClaim const& lhs, AttestationClaim const& rhs) const
|
||||
{
|
||||
return lhs.claimID < rhs.claimID;
|
||||
}
|
||||
};
|
||||
|
||||
// Attest to a cross-chain transfer that creates an account
|
||||
struct AttestationCreateAccount : AttestationBase
|
||||
{
|
||||
// createCount on the sending chain. This is the value of the `CreateCount`
|
||||
// field of the bridge on the sending chain when the transaction was
|
||||
// executed.
|
||||
std::uint64_t createCount;
|
||||
// Account to create on the destination chain
|
||||
AccountID toCreate;
|
||||
// Total amount of the reward pool
|
||||
STAmount rewardAmount;
|
||||
|
||||
explicit AttestationCreateAccount(STObject const& o);
|
||||
|
||||
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_);
|
||||
|
||||
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_);
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
// return true if the two attestations attest to the same thing
|
||||
[[nodiscard]] bool
|
||||
sameEvent(AttestationCreateAccount const& rhs) const;
|
||||
|
||||
friend bool
|
||||
operator==(
|
||||
AttestationCreateAccount const& lhs,
|
||||
AttestationCreateAccount const& rhs);
|
||||
|
||||
[[nodiscard]] static std::vector<std::uint8_t>
|
||||
message(
|
||||
STXChainBridge const& bridge,
|
||||
AccountID const& sendingAccount,
|
||||
STAmount const& sendingAmount,
|
||||
STAmount const& rewardAmount,
|
||||
AccountID const& rewardAccount,
|
||||
bool wasLockingChainSend,
|
||||
std::uint64_t createCount,
|
||||
AccountID const& dst);
|
||||
|
||||
[[nodiscard]] bool
|
||||
validAmounts() const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::vector<std::uint8_t>
|
||||
message(STXChainBridge const& bridge) const override;
|
||||
};
|
||||
|
||||
struct CmpByCreateCount
|
||||
{
|
||||
bool
|
||||
operator()(
|
||||
AttestationCreateAccount const& lhs,
|
||||
AttestationCreateAccount const& rhs) const
|
||||
{
|
||||
return lhs.createCount < rhs.createCount;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace Attestations
|
||||
|
||||
// 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,
|
||||
// all of the fields match, except the dst field
|
||||
matchExceptDst,
|
||||
// all of the fields match
|
||||
match
|
||||
};
|
||||
|
||||
struct XChainClaimAttestation
|
||||
{
|
||||
using TSignedAttestation = Attestations::AttestationClaim;
|
||||
static SField const& ArrayFieldName;
|
||||
|
||||
AccountID keyAccount;
|
||||
PublicKey publicKey;
|
||||
STAmount amount;
|
||||
AccountID rewardAccount;
|
||||
bool wasLockingChainSend;
|
||||
std::optional<AccountID> dst;
|
||||
|
||||
struct MatchFields
|
||||
{
|
||||
STAmount amount;
|
||||
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}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
explicit XChainClaimAttestation(
|
||||
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_,
|
||||
std::optional<STAccount> const& dst);
|
||||
|
||||
explicit XChainClaimAttestation(TSignedAttestation const& claimAtt);
|
||||
|
||||
explicit XChainClaimAttestation(STObject const& o);
|
||||
|
||||
explicit XChainClaimAttestation(Json::Value const& v);
|
||||
|
||||
AttestationMatch
|
||||
match(MatchFields const& rhs) const;
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
friend bool
|
||||
operator==(
|
||||
XChainClaimAttestation const& lhs,
|
||||
XChainClaimAttestation const& rhs);
|
||||
};
|
||||
|
||||
struct XChainCreateAccountAttestation
|
||||
{
|
||||
using TSignedAttestation = Attestations::AttestationCreateAccount;
|
||||
static SField const& ArrayFieldName;
|
||||
|
||||
AccountID keyAccount;
|
||||
PublicKey publicKey;
|
||||
STAmount amount;
|
||||
STAmount rewardAmount;
|
||||
AccountID rewardAccount;
|
||||
bool wasLockingChainSend;
|
||||
AccountID dst;
|
||||
|
||||
struct MatchFields
|
||||
{
|
||||
STAmount amount;
|
||||
STAmount rewardAmount;
|
||||
bool wasLockingChainSend;
|
||||
AccountID dst;
|
||||
|
||||
MatchFields(TSignedAttestation const& att);
|
||||
};
|
||||
|
||||
explicit XChainCreateAccountAttestation(
|
||||
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);
|
||||
|
||||
[[nodiscard]] STObject
|
||||
toSTObject() const;
|
||||
|
||||
AttestationMatch
|
||||
match(MatchFields const& rhs) const;
|
||||
|
||||
friend bool
|
||||
operator==(
|
||||
XChainCreateAccountAttestation const& lhs,
|
||||
XChainCreateAccountAttestation const& rhs);
|
||||
};
|
||||
|
||||
// Attestations from witness servers for a particular claimid and bridge.
|
||||
// Only one attestation per signature is allowed.
|
||||
template <class TAttestation>
|
||||
class XChainAttestationsBase
|
||||
{
|
||||
public:
|
||||
using AttCollection = std::vector<TAttestation>;
|
||||
|
||||
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;
|
||||
AttCollection attestations_;
|
||||
|
||||
protected:
|
||||
// Prevent slicing to the base class
|
||||
~XChainAttestationsBase() = default;
|
||||
|
||||
public:
|
||||
XChainAttestationsBase() = default;
|
||||
XChainAttestationsBase(XChainAttestationsBase const& rhs) = default;
|
||||
XChainAttestationsBase&
|
||||
operator=(XChainAttestationsBase const& rhs) = default;
|
||||
|
||||
explicit XChainAttestationsBase(AttCollection&& sigs);
|
||||
|
||||
explicit XChainAttestationsBase(Json::Value const& v);
|
||||
|
||||
explicit XChainAttestationsBase(STArray const& arr);
|
||||
|
||||
[[nodiscard]] STArray
|
||||
toSTArray() const;
|
||||
|
||||
typename AttCollection::const_iterator
|
||||
begin() const;
|
||||
|
||||
typename AttCollection::const_iterator
|
||||
end() const;
|
||||
|
||||
typename AttCollection::iterator
|
||||
begin();
|
||||
|
||||
typename AttCollection::iterator
|
||||
end();
|
||||
|
||||
template <class F>
|
||||
std::size_t
|
||||
erase_if(F&& f);
|
||||
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
bool
|
||||
empty() const;
|
||||
|
||||
AttCollection const&
|
||||
attestations() const;
|
||||
|
||||
template <class T>
|
||||
void
|
||||
emplace_back(T&& att);
|
||||
};
|
||||
|
||||
template <class TAttestation>
|
||||
[[nodiscard]] inline bool
|
||||
operator==(
|
||||
XChainAttestationsBase<TAttestation> const& lhs,
|
||||
XChainAttestationsBase<TAttestation> const& rhs)
|
||||
{
|
||||
return lhs.attestations() == rhs.attestations();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline typename XChainAttestationsBase<TAttestation>::AttCollection const&
|
||||
XChainAttestationsBase<TAttestation>::attestations() const
|
||||
{
|
||||
return attestations_;
|
||||
};
|
||||
|
||||
template <class TAttestation>
|
||||
template <class T>
|
||||
inline void
|
||||
XChainAttestationsBase<TAttestation>::emplace_back(T&& att)
|
||||
{
|
||||
attestations_.emplace_back(std::forward<T>(att));
|
||||
};
|
||||
|
||||
template <class TAttestation>
|
||||
template <class F>
|
||||
inline std::size_t
|
||||
XChainAttestationsBase<TAttestation>::erase_if(F&& f)
|
||||
{
|
||||
return std::erase_if(attestations_, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline std::size_t
|
||||
XChainAttestationsBase<TAttestation>::size() const
|
||||
{
|
||||
return attestations_.size();
|
||||
}
|
||||
|
||||
template <class TAttestation>
|
||||
inline bool
|
||||
XChainAttestationsBase<TAttestation>::empty() const
|
||||
{
|
||||
return attestations_.empty();
|
||||
}
|
||||
|
||||
class XChainClaimAttestations final
|
||||
: public XChainAttestationsBase<XChainClaimAttestation>
|
||||
{
|
||||
using TBase = XChainAttestationsBase<XChainClaimAttestation>;
|
||||
using TBase::TBase;
|
||||
};
|
||||
|
||||
class XChainCreateAccountAttestations final
|
||||
: public XChainAttestationsBase<XChainCreateAccountAttestation>
|
||||
{
|
||||
using TBase = XChainAttestationsBase<XChainCreateAccountAttestation>;
|
||||
using TBase::TBase;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif // STXCHAINATTESTATIONS_H_
|
||||
165
include/xrpl/protocol/detail/STVar.h
Normal file
165
include/xrpl/protocol/detail/STVar.h
Normal file
@@ -0,0 +1,165 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_STVAR_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STVAR_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
namespace detail {
|
||||
|
||||
struct defaultObject_t
|
||||
{
|
||||
explicit defaultObject_t() = default;
|
||||
};
|
||||
|
||||
struct nonPresentObject_t
|
||||
{
|
||||
explicit nonPresentObject_t() = default;
|
||||
};
|
||||
|
||||
extern defaultObject_t defaultObject;
|
||||
extern nonPresentObject_t nonPresentObject;
|
||||
|
||||
// "variant" that can hold any type of serialized object
|
||||
// and includes a small-object allocation optimization.
|
||||
class STVar
|
||||
{
|
||||
private:
|
||||
// The largest "small object" we can accomodate
|
||||
static std::size_t constexpr max_size = 72;
|
||||
|
||||
std::aligned_storage<max_size>::type d_;
|
||||
STBase* p_ = nullptr;
|
||||
|
||||
public:
|
||||
~STVar();
|
||||
STVar(STVar const& other);
|
||||
STVar(STVar&& other);
|
||||
STVar&
|
||||
operator=(STVar const& rhs);
|
||||
STVar&
|
||||
operator=(STVar&& rhs);
|
||||
|
||||
STVar(STBase&& t)
|
||||
{
|
||||
p_ = t.move(max_size, &d_);
|
||||
}
|
||||
|
||||
STVar(STBase const& t)
|
||||
{
|
||||
p_ = t.copy(max_size, &d_);
|
||||
}
|
||||
|
||||
STVar(defaultObject_t, SField const& name);
|
||||
STVar(nonPresentObject_t, SField const& name);
|
||||
STVar(SerialIter& sit, SField const& name, int depth = 0);
|
||||
|
||||
STBase&
|
||||
get()
|
||||
{
|
||||
return *p_;
|
||||
}
|
||||
STBase&
|
||||
operator*()
|
||||
{
|
||||
return get();
|
||||
}
|
||||
STBase*
|
||||
operator->()
|
||||
{
|
||||
return &get();
|
||||
}
|
||||
STBase const&
|
||||
get() const
|
||||
{
|
||||
return *p_;
|
||||
}
|
||||
STBase const&
|
||||
operator*() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
STBase const*
|
||||
operator->() const
|
||||
{
|
||||
return &get();
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
friend STVar
|
||||
make_stvar(Args&&... args);
|
||||
|
||||
private:
|
||||
STVar() = default;
|
||||
|
||||
STVar(SerializedTypeID id, SField const& name);
|
||||
|
||||
void
|
||||
destroy();
|
||||
|
||||
template <class T, class... Args>
|
||||
void
|
||||
construct(Args&&... args)
|
||||
{
|
||||
if constexpr (sizeof(T) > max_size)
|
||||
p_ = new T(std::forward<Args>(args)...);
|
||||
else
|
||||
p_ = new (&d_) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
bool
|
||||
on_heap() const
|
||||
{
|
||||
return static_cast<void const*>(p_) != static_cast<void const*>(&d_);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class... Args>
|
||||
inline STVar
|
||||
make_stvar(Args&&... args)
|
||||
{
|
||||
STVar st;
|
||||
st.construct<T>(std::forward<Args>(args)...);
|
||||
return st;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STVar const& lhs, STVar const& rhs)
|
||||
{
|
||||
return lhs.get().isEquivalent(rhs.get());
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(STVar const& lhs, STVar const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
192
include/xrpl/protocol/detail/b58_utils.h
Normal file
192
include/xrpl/protocol/detail/b58_utils.h
Normal file
@@ -0,0 +1,192 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2022 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/protocol/impl/token_errors.h>
|
||||
|
||||
#include <boost/outcome.hpp>
|
||||
#include <boost/outcome/result.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <span>
|
||||
#include <system_error>
|
||||
#include <tuple>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <class T>
|
||||
using Result = boost::outcome_v2::result<T, std::error_code>;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
namespace b58_fast {
|
||||
namespace 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
unsigned __int128 const x = a;
|
||||
unsigned __int128 const y = b;
|
||||
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)
|
||||
{
|
||||
unsigned __int128 const x = a;
|
||||
unsigned __int128 const y = b;
|
||||
unsigned __int128 const c = x + y;
|
||||
return {c & 0xffff'ffff'ffff'ffff, c >> 64};
|
||||
}
|
||||
|
||||
// Add a u64 to a "big uint" value inplace.
|
||||
// The bigint value is stored with the smallest coefficients first
|
||||
// (i.e a[0] is the 2^0 coefficient, a[n] is the 2^(64*n) coefficient)
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
std::uint64_t carry = 0;
|
||||
for (auto& coeff : a.subspan(0, last_index))
|
||||
{
|
||||
std::tie(coeff, carry) = carrying_mul(coeff, b, carry);
|
||||
}
|
||||
a[last_index] = 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)
|
||||
{
|
||||
if (numerator.size() == 0)
|
||||
{
|
||||
// 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.
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto to_u128 = [](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> {
|
||||
unsigned __int128 const denom128 = denom;
|
||||
unsigned __int128 const d = num / denom128;
|
||||
unsigned __int128 const r = num - (denom128 * d);
|
||||
assert(d >> 64 == 0);
|
||||
assert(r >> 64 == 0);
|
||||
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)
|
||||
{
|
||||
unsigned __int128 const cur_num = to_u128(prev_rem, numerator[i]);
|
||||
std::tie(numerator[i], prev_rem) = div_rem_64(cur_num, divisor);
|
||||
}
|
||||
return prev_rem;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
|
||||
assert(input < B_58_10);
|
||||
constexpr std::size_t resultSize = 10;
|
||||
std::array<std::uint8_t, resultSize> result{};
|
||||
int i = 0;
|
||||
while (input > 0)
|
||||
{
|
||||
std::uint64_t rem;
|
||||
std::tie(input, rem) = div_rem(input, 58);
|
||||
result[resultSize - 1 - i] = rem;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace b58_fast
|
||||
#endif
|
||||
|
||||
} // namespace ripple
|
||||
#endif // RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
|
||||
51
include/xrpl/protocol/detail/secp256k1.h
Normal file
51
include/xrpl/protocol/detail/secp256k1.h
Normal file
@@ -0,0 +1,51 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SECP256K1_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SECP256K1_H_INCLUDED
|
||||
|
||||
#include <secp256k1.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <class = void>
|
||||
secp256k1_context const*
|
||||
secp256k1Context()
|
||||
{
|
||||
struct holder
|
||||
{
|
||||
secp256k1_context* impl;
|
||||
holder()
|
||||
: impl(secp256k1_context_create(
|
||||
SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN))
|
||||
{
|
||||
}
|
||||
|
||||
~holder()
|
||||
{
|
||||
secp256k1_context_destroy(impl);
|
||||
}
|
||||
};
|
||||
static holder const h;
|
||||
return h.impl;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
102
include/xrpl/protocol/detail/token_errors.h
Normal file
102
include/xrpl/protocol/detail/token_errors.h
Normal file
@@ -0,0 +1,102 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2022 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_TOKEN_ERRORS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_TOKEN_ERRORS_H_INCLUDED
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace ripple {
|
||||
enum class TokenCodecErrc {
|
||||
success = 0,
|
||||
inputTooLarge,
|
||||
inputTooSmall,
|
||||
badB58Character,
|
||||
outputTooSmall,
|
||||
mismatchedTokenType,
|
||||
mismatchedChecksum,
|
||||
invalidEncodingChar,
|
||||
overflowAdd,
|
||||
unknown,
|
||||
};
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct is_error_code_enum<ripple::TokenCodecErrc> : true_type
|
||||
{
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace ripple {
|
||||
namespace detail {
|
||||
class TokenCodecErrcCategory : public std::error_category
|
||||
{
|
||||
public:
|
||||
// Return a short descriptive name for the category
|
||||
virtual const char*
|
||||
name() const noexcept override final
|
||||
{
|
||||
return "TokenCodecError";
|
||||
}
|
||||
// Return what each enum means in text
|
||||
virtual std::string
|
||||
message(int c) const override final
|
||||
{
|
||||
switch (static_cast<TokenCodecErrc>(c))
|
||||
{
|
||||
case TokenCodecErrc::success:
|
||||
return "conversion successful";
|
||||
case TokenCodecErrc::inputTooLarge:
|
||||
return "input too large";
|
||||
case TokenCodecErrc::inputTooSmall:
|
||||
return "input too small";
|
||||
case TokenCodecErrc::badB58Character:
|
||||
return "bad base 58 character";
|
||||
case TokenCodecErrc::outputTooSmall:
|
||||
return "output too small";
|
||||
case TokenCodecErrc::mismatchedTokenType:
|
||||
return "mismatched token type";
|
||||
case TokenCodecErrc::mismatchedChecksum:
|
||||
return "mismatched checksum";
|
||||
case TokenCodecErrc::invalidEncodingChar:
|
||||
return "invalid encoding char";
|
||||
case TokenCodecErrc::unknown:
|
||||
return "unknown";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
inline const ripple::detail::TokenCodecErrcCategory&
|
||||
TokenCodecErrcCategory()
|
||||
{
|
||||
static ripple::detail::TokenCodecErrcCategory c;
|
||||
return c;
|
||||
}
|
||||
|
||||
inline std::error_code
|
||||
make_error_code(ripple::TokenCodecErrc e)
|
||||
{
|
||||
return {static_cast<int>(e), TokenCodecErrcCategory()};
|
||||
}
|
||||
} // namespace ripple
|
||||
#endif // TOKEN_ERRORS_H_
|
||||
242
include/xrpl/protocol/digest.h
Normal file
242
include/xrpl/protocol/digest.h
Normal file
@@ -0,0 +1,242 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_DIGEST_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_DIGEST_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/crypto/secure_erase.h>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Message digest functions used in the codebase
|
||||
|
||||
@note These are modeled to meet the requirements of `Hasher` in the
|
||||
`hash_append` interface, discussed in proposal:
|
||||
|
||||
N3980 "Types Don't Know #"
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** RIPEMD-160 digest
|
||||
|
||||
@note This uses the OpenSSL implementation
|
||||
*/
|
||||
struct openssl_ripemd160_hasher
|
||||
{
|
||||
public:
|
||||
static constexpr auto const endian = boost::endian::order::native;
|
||||
|
||||
using result_type = std::array<std::uint8_t, 20>;
|
||||
|
||||
openssl_ripemd160_hasher();
|
||||
|
||||
void
|
||||
operator()(void const* data, std::size_t size) noexcept;
|
||||
|
||||
explicit operator result_type() noexcept;
|
||||
|
||||
private:
|
||||
char ctx_[96];
|
||||
};
|
||||
|
||||
/** SHA-512 digest
|
||||
|
||||
@note This uses the OpenSSL implementation
|
||||
*/
|
||||
struct openssl_sha512_hasher
|
||||
{
|
||||
public:
|
||||
static constexpr auto const endian = boost::endian::order::native;
|
||||
|
||||
using result_type = std::array<std::uint8_t, 64>;
|
||||
|
||||
openssl_sha512_hasher();
|
||||
|
||||
void
|
||||
operator()(void const* data, std::size_t size) noexcept;
|
||||
|
||||
explicit operator result_type() noexcept;
|
||||
|
||||
private:
|
||||
char ctx_[216];
|
||||
};
|
||||
|
||||
/** SHA-256 digest
|
||||
|
||||
@note This uses the OpenSSL implementation
|
||||
*/
|
||||
struct openssl_sha256_hasher
|
||||
{
|
||||
public:
|
||||
static constexpr auto const endian = boost::endian::order::native;
|
||||
|
||||
using result_type = std::array<std::uint8_t, 32>;
|
||||
|
||||
openssl_sha256_hasher();
|
||||
|
||||
void
|
||||
operator()(void const* data, std::size_t size) noexcept;
|
||||
|
||||
explicit operator result_type() noexcept;
|
||||
|
||||
private:
|
||||
char ctx_[112];
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ripemd160_hasher = openssl_ripemd160_hasher;
|
||||
using sha256_hasher = openssl_sha256_hasher;
|
||||
using sha512_hasher = openssl_sha512_hasher;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** 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
|
||||
message is the public key of the account - which is not
|
||||
stored in the account root.
|
||||
|
||||
The same computation is used regardless of the cryptographic
|
||||
scheme implied by the public key. For example, the public key
|
||||
may be an ed25519 public key or a secp256k1 public key. Support
|
||||
for new cryptographic systems may be added, using the same
|
||||
formula for calculating the account identifier.
|
||||
|
||||
Meets the requirements of Hasher (in hash_append)
|
||||
*/
|
||||
struct ripesha_hasher
|
||||
{
|
||||
private:
|
||||
sha256_hasher h_;
|
||||
|
||||
public:
|
||||
static constexpr auto const endian = boost::endian::order::native;
|
||||
|
||||
using result_type = std::array<std::uint8_t, 20>;
|
||||
|
||||
void
|
||||
operator()(void const* data, std::size_t size) noexcept
|
||||
{
|
||||
h_(data, size);
|
||||
}
|
||||
|
||||
explicit operator result_type() noexcept
|
||||
{
|
||||
auto const d0 = sha256_hasher::result_type(h_);
|
||||
ripemd160_hasher rh;
|
||||
rh(d0.data(), d0.size());
|
||||
return ripemd160_hasher::result_type(rh);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** Returns the SHA512-Half digest of a message.
|
||||
|
||||
The SHA512-Half is the first 256 bits of the
|
||||
SHA-512 digest of the message.
|
||||
*/
|
||||
template <bool Secure>
|
||||
struct basic_sha512_half_hasher
|
||||
{
|
||||
private:
|
||||
sha512_hasher h_;
|
||||
|
||||
public:
|
||||
static constexpr auto const endian = boost::endian::order::big;
|
||||
|
||||
using result_type = uint256;
|
||||
|
||||
~basic_sha512_half_hasher()
|
||||
{
|
||||
erase(std::integral_constant<bool, Secure>{});
|
||||
}
|
||||
|
||||
void
|
||||
operator()(void const* data, std::size_t size) noexcept
|
||||
{
|
||||
h_(data, size);
|
||||
}
|
||||
|
||||
explicit operator result_type() noexcept
|
||||
{
|
||||
auto const digest = sha512_hasher::result_type(h_);
|
||||
return result_type::fromVoid(digest.data());
|
||||
}
|
||||
|
||||
private:
|
||||
inline void erase(std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
inline void erase(std::true_type)
|
||||
{
|
||||
secure_erase(&h_, sizeof(h_));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using sha512_half_hasher = detail::basic_sha512_half_hasher<false>;
|
||||
|
||||
// secure version
|
||||
using sha512_half_hasher_s = detail::basic_sha512_half_hasher<true>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Returns the SHA512-Half of a series of objects. */
|
||||
template <class... Args>
|
||||
sha512_half_hasher::result_type
|
||||
sha512Half(Args const&... args)
|
||||
{
|
||||
sha512_half_hasher h;
|
||||
using beast::hash_append;
|
||||
hash_append(h, args...);
|
||||
return static_cast<typename sha512_half_hasher::result_type>(h);
|
||||
}
|
||||
|
||||
/** Returns the SHA512-Half of a series of objects.
|
||||
|
||||
Postconditions:
|
||||
Temporary memory storing copies of
|
||||
input messages will be cleared.
|
||||
*/
|
||||
template <class... Args>
|
||||
sha512_half_hasher_s::result_type
|
||||
sha512Half_s(Args const&... args)
|
||||
{
|
||||
sha512_half_hasher_s h;
|
||||
using beast::hash_append;
|
||||
hash_append(h, args...);
|
||||
return static_cast<typename sha512_half_hasher_s::result_type>(h);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
159
include/xrpl/protocol/json_get_or_throw.h
Normal file
159
include/xrpl/protocol/json_get_or_throw.h
Normal file
@@ -0,0 +1,159 @@
|
||||
#ifndef PROTOCOL_GET_OR_THROW_H_
|
||||
#define PROTOCOL_GET_OR_THROW_H_
|
||||
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
|
||||
#include <charconv>
|
||||
#include <exception>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace Json {
|
||||
struct JsonMissingKeyError : std::exception
|
||||
{
|
||||
char const* const key;
|
||||
mutable std::string msg;
|
||||
JsonMissingKeyError(Json::StaticString const& k) : key{k.c_str()}
|
||||
{
|
||||
}
|
||||
const char*
|
||||
what() const noexcept override
|
||||
{
|
||||
if (msg.empty())
|
||||
{
|
||||
msg = std::string("Missing json key: ") + key;
|
||||
}
|
||||
return msg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
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)}
|
||||
{
|
||||
}
|
||||
const char*
|
||||
what() const noexcept override
|
||||
{
|
||||
if (msg.empty())
|
||||
{
|
||||
msg = std::string("Type mismatch on json key: ") + key +
|
||||
"; expected type: " + expectedType;
|
||||
}
|
||||
return msg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
static_assert(sizeof(T) == -1, "This function must be specialized");
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
Json::StaticString const& key = field.getJsonName();
|
||||
if (!v.isMember(key))
|
||||
Throw<JsonMissingKeyError>(key);
|
||||
|
||||
Json::Value const& inner = v[key];
|
||||
if (!inner.isString())
|
||||
Throw<JsonTypeMismatchError>(key, "string");
|
||||
return inner.asString();
|
||||
}
|
||||
|
||||
// Note, this allows integer numeric fields to act as bools
|
||||
template <>
|
||||
inline bool
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
Json::StaticString const& key = field.getJsonName();
|
||||
if (!v.isMember(key))
|
||||
Throw<JsonMissingKeyError>(key);
|
||||
Json::Value const& inner = v[key];
|
||||
if (inner.isBool())
|
||||
return inner.asBool();
|
||||
if (!inner.isIntegral())
|
||||
Throw<JsonTypeMismatchError>(key, "bool");
|
||||
|
||||
return inner.asInt() != 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::uint64_t
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
Json::StaticString const& key = field.getJsonName();
|
||||
if (!v.isMember(key))
|
||||
Throw<JsonMissingKeyError>(key);
|
||||
Json::Value const& inner = v[key];
|
||||
if (inner.isUInt())
|
||||
return inner.asUInt();
|
||||
if (inner.isInt())
|
||||
{
|
||||
auto const r = inner.asInt();
|
||||
if (r < 0)
|
||||
Throw<JsonTypeMismatchError>(key, "uint64");
|
||||
return r;
|
||||
}
|
||||
if (inner.isString())
|
||||
{
|
||||
auto const s = inner.asString();
|
||||
// parse as hex
|
||||
std::uint64_t val;
|
||||
|
||||
auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val, 16);
|
||||
|
||||
if (ec != std::errc() || (p != s.data() + s.size()))
|
||||
Throw<JsonTypeMismatchError>(key, "uint64");
|
||||
return val;
|
||||
}
|
||||
Throw<JsonTypeMismatchError>(key, "uint64");
|
||||
}
|
||||
|
||||
template <>
|
||||
inline ripple::Buffer
|
||||
getOrThrow(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
using namespace ripple;
|
||||
std::string const hex = getOrThrow<std::string>(v, field);
|
||||
if (auto const r = strUnHex(hex))
|
||||
{
|
||||
// TODO: mismatch between a buffer and a blob
|
||||
return Buffer{r->data(), r->size()};
|
||||
}
|
||||
Throw<JsonTypeMismatchError>(field.getJsonName(), "Buffer");
|
||||
}
|
||||
|
||||
// This function may be used by external projects (like the witness server).
|
||||
template <class T>
|
||||
std::optional<T>
|
||||
getOptional(Json::Value const& v, ripple::SField const& field)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getOrThrow<T>(v, field);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Json
|
||||
|
||||
#endif // PROTOCOL_GET_OR_THROW_H_
|
||||
879
include/xrpl/protocol/jss.h
Normal file
879
include/xrpl/protocol/jss.h
Normal file
@@ -0,0 +1,879 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_JSONFIELDS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_JSONFIELDS_H_INCLUDED
|
||||
|
||||
#include <ripple/json/json_value.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace jss {
|
||||
|
||||
// JSON static strings
|
||||
|
||||
#define JSS(x) constexpr ::Json::StaticString x(#x)
|
||||
|
||||
/* These "StaticString" field names are used instead of string literals to
|
||||
optimize the performance of accessing properties of Json::Value objects.
|
||||
|
||||
Most strings have a trailing comment. Here is the legend:
|
||||
|
||||
in: Read by the given RPC handler from its `Json::Value` parameter.
|
||||
out: Assigned by the given RPC handler in the `Json::Value` it returns.
|
||||
field: A field of at least one type of transaction.
|
||||
RPC: Common properties of RPC requests and responses.
|
||||
error: Common properties of RPC error responses.
|
||||
*/
|
||||
|
||||
JSS(AL_size); // out: GetCounts
|
||||
JSS(AL_hit_rate); // out: GetCounts
|
||||
JSS(Account); // in: TransactionSign; field.
|
||||
JSS(AccountDelete); // transaction type.
|
||||
JSS(AccountRoot); // ledger type.
|
||||
JSS(AccountSet); // transaction type.
|
||||
JSS(AMM); // ledger type
|
||||
JSS(AMMBid); // transaction type
|
||||
JSS(AMMID); // field
|
||||
JSS(AMMCreate); // transaction type
|
||||
JSS(AMMDeposit); // transaction type
|
||||
JSS(AMMDelete); // transaction type
|
||||
JSS(AMMVote); // transaction type
|
||||
JSS(AMMWithdraw); // transaction type
|
||||
JSS(Amendments); // ledger type.
|
||||
JSS(Amount); // in: TransactionSign; field.
|
||||
JSS(Authorize); // field
|
||||
JSS(Amount2); // in/out: AMM IOU/XRP pool, deposit, withdraw amount
|
||||
JSS(Asset); // in: AMM Asset1
|
||||
JSS(Asset2); // in: AMM
|
||||
JSS(AssetClass); // in: Oracle
|
||||
JSS(AssetPrice); // in: Oracle
|
||||
JSS(AuthAccount); // in: AMM Auction Slot
|
||||
JSS(AuthAccounts); // in: AMM Auction Slot
|
||||
JSS(BaseAsset); // in: Oracle
|
||||
JSS(Blob);
|
||||
JSS(Bridge); // ledger type.
|
||||
JSS(Check); // ledger type.
|
||||
JSS(CheckCancel); // transaction type.
|
||||
JSS(CheckCash); // transaction type.
|
||||
JSS(CheckCreate); // transaction type.
|
||||
JSS(Clawback); // transaction type.
|
||||
JSS(ClaimReward); // transaction type.
|
||||
JSS(ClearFlag); // field.
|
||||
JSS(CreateCode); // field.
|
||||
JSS(DID); // ledger type.
|
||||
JSS(DIDDelete); // transaction type.
|
||||
JSS(DIDSet); // transaction type.
|
||||
JSS(DeliverMax); // out: alias to Amount
|
||||
JSS(DeliverMin); // in: TransactionSign
|
||||
JSS(DepositPreauth); // transaction and ledger type.
|
||||
JSS(Destination); // in: TransactionSign; field.
|
||||
JSS(DirectoryNode); // ledger type.
|
||||
JSS(EnableAmendment); // transaction type.
|
||||
JSS(EPrice); // in: AMM Deposit option
|
||||
JSS(EmitFailure); // transaction type. (cleanup emit)
|
||||
JSS(Escrow); // ledger type.
|
||||
JSS(EscrowCancel); // transaction type.
|
||||
JSS(EscrowCreate); // transaction type.
|
||||
JSS(EscrowFinish); // transaction type.
|
||||
JSS(Fee); // in/out: TransactionSign; field.
|
||||
JSS(FeeSettings); // ledger type.
|
||||
JSS(FIELDS); // out: RPC server_definitions
|
||||
JSS(Flags); // in/out: TransactionSign; field.
|
||||
JSS(incomplete_shards); // out: OverlayImpl, PeerImp
|
||||
JSS(GenesisMint); // tt
|
||||
JSS(GenesisMints);
|
||||
JSS(GovernanceMarks);
|
||||
JSS(GovernanceFlags);
|
||||
JSS(HookApiVersion); // field
|
||||
JSS(HookCanEmit); // field
|
||||
JSS(HookHash); // field
|
||||
JSS(HookNamespace); // field
|
||||
JSS(HookOn); // field
|
||||
JSS(Hooks); // field
|
||||
JSS(HookGrants); // field
|
||||
JSS(HookParameters); // field
|
||||
JSS(HookParameterName); // field
|
||||
JSS(HookParameterValue); // field
|
||||
JSS(HookParameter); // field
|
||||
JSS(HookGrant); // field
|
||||
JSS(isSerialized); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
JSS(isSigningField); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
JSS(isVLEncoded); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
JSS(Import);
|
||||
JSS(ImportVLSequence);
|
||||
JSS(Invalid); //
|
||||
JSS(Invoke); // transaction type
|
||||
JSS(InvoiceID); // field
|
||||
JSS(LastLedgerSequence); // in: TransactionSign; field
|
||||
JSS(LastUpdateTime); // field.
|
||||
JSS(LedgerHashes); // ledger type.
|
||||
JSS(LimitAmount); // field.
|
||||
JSS(BidMax); // in: AMM Bid
|
||||
JSS(BidMin); // in: AMM Bid
|
||||
JSS(NetworkID); // field.
|
||||
JSS(NFTokenBurn); // transaction type.
|
||||
JSS(NFTokenMint); // transaction type.
|
||||
JSS(NFTokenOffer); // ledger type.
|
||||
JSS(NFTokenAcceptOffer); // transaction type.
|
||||
JSS(NFTokenCancelOffer); // transaction type.
|
||||
JSS(NFTokenCreateOffer); // transaction type.
|
||||
JSS(NFTokenPage); // ledger type.
|
||||
JSS(LPTokenOut); // in: AMM Liquidity Provider deposit tokens
|
||||
JSS(LPTokenIn); // in: AMM Liquidity Provider withdraw tokens
|
||||
JSS(LPToken); // out: AMM Liquidity Provider tokens info
|
||||
JSS(Offer); // ledger type.
|
||||
JSS(OfferCancel); // transaction type.
|
||||
JSS(OfferCreate); // transaction type.
|
||||
JSS(OfferSequence); // field.
|
||||
JSS(Oracle); // ledger type.
|
||||
JSS(OracleDelete); // transaction type.
|
||||
JSS(OracleDocumentID); // field
|
||||
JSS(OracleSet); // transaction type.
|
||||
JSS(Owner); // field
|
||||
JSS(Paths); // in/out: TransactionSign
|
||||
JSS(PayChannel); // ledger type.
|
||||
JSS(Payment); // transaction type.
|
||||
JSS(PaymentChannelClaim); // transaction type.
|
||||
JSS(PaymentChannelCreate); // transaction type.
|
||||
JSS(PaymentChannelFund); // transaction type.
|
||||
JSS(PriceDataSeries); // field.
|
||||
JSS(PriceData); // field.
|
||||
JSS(Provider); // field.
|
||||
JSS(QuoteAsset); // in: Oracle.
|
||||
JSS(Remit); // transaction type.
|
||||
JSS(RippleState); // ledger type.
|
||||
JSS(SLE_hit_rate); // out: GetCounts.
|
||||
JSS(SetFee); // transaction type.
|
||||
JSS(SetRemarks); // transaction type
|
||||
JSS(UNLModify); // transaction type.
|
||||
JSS(Scale); // field.
|
||||
JSS(UNLReport); // transaction type.
|
||||
JSS(SettleDelay); // in: TransactionSign
|
||||
JSS(SendMax); // in: TransactionSign
|
||||
JSS(Sequence); // in/out: TransactionSign; field.
|
||||
JSS(SetFlag); // field.
|
||||
JSS(SetRegularKey); // transaction type.
|
||||
JSS(SetHook); // transaction type.
|
||||
JSS(Hook); // ledger type.
|
||||
JSS(HookDefinition); // ledger type.
|
||||
JSS(HookState); // ledger type.
|
||||
JSS(HookStateData); // field.
|
||||
JSS(HookStateKey); // field.
|
||||
JSS(EmittedTxn); // ledger type.
|
||||
JSS(SignerList); // ledger type.
|
||||
JSS(SignerListSet); // transaction type.
|
||||
JSS(SigningPubKey); // field.
|
||||
JSS(TakerGets); // field.
|
||||
JSS(TakerPays); // field.
|
||||
JSS(Ticket); // ledger type.
|
||||
JSS(TicketCreate); // transaction type.
|
||||
JSS(TxnSignature); // field.
|
||||
JSS(TradingFee); // in/out: AMM trading fee
|
||||
JSS(TransactionType); // in: TransactionSign.
|
||||
JSS(TransferRate); // in: TransferRate.
|
||||
JSS(TrustSet); // transaction type.
|
||||
JSS(URI); // field.
|
||||
JSS(URIToken); // out: LedgerEntry
|
||||
JSS(URITokenMint); // tx type
|
||||
JSS(URITokenBurn); // tx type
|
||||
JSS(URITokenBuy); // tx type
|
||||
JSS(URITokenCreateSellOffer); // tx type
|
||||
JSS(URITokenCancelSellOffer); // tx type
|
||||
JSS(VoteSlots); // out: AMM Vote
|
||||
JSS(XChainAddAccountCreateAttestation); // transaction type.
|
||||
JSS(XChainAddClaimAttestation); // transaction type.
|
||||
JSS(XChainAccountCreateCommit); // transaction type.
|
||||
JSS(XChainClaim); // transaction type.
|
||||
JSS(XChainCommit); // transaction type.
|
||||
JSS(XChainCreateBridge); // transaction type.
|
||||
JSS(XChainCreateClaimID); // transaction type.
|
||||
JSS(XChainModifyBridge); // transaction type.
|
||||
JSS(XChainOwnedClaimID); // ledger type.
|
||||
JSS(XChainOwnedCreateAccountClaimID); // ledger type.
|
||||
JSS(aborted); // out: InboundLedger
|
||||
JSS(accepted); // out: LedgerToJson, OwnerInfo, SubmitTransaction
|
||||
JSS(account); // in/out: many
|
||||
JSS(accountState); // out: LedgerToJson
|
||||
JSS(accountTreeHash); // out: ledger/Ledger.cpp
|
||||
JSS(account_data); // out: AccountInfo
|
||||
JSS(account_flags); // out: AccountInfo
|
||||
JSS(account_hash); // out: LedgerToJson
|
||||
JSS(account_id); // out: WalletPropose
|
||||
JSS(account_namespace); // out: AccountNamespace
|
||||
JSS(account_nfts); // out: AccountNFTs
|
||||
JSS(account_objects); // out: AccountObjects
|
||||
JSS(account_root); // in: LedgerEntry
|
||||
JSS(account_sequence_next); // out: SubmitTransaction
|
||||
JSS(account_sequence_available); // out: SubmitTransaction
|
||||
JSS(account_history_tx_stream); // in: Subscribe, Unsubscribe
|
||||
JSS(account_history_tx_index); // out: Account txn history subscribe
|
||||
|
||||
JSS(account_history_tx_first); // out: Account txn history subscribe
|
||||
JSS(account_history_boundary); // out: Account txn history subscribe
|
||||
JSS(accounts); // in: LedgerEntry, Subscribe,
|
||||
// handlers/Ledger, Unsubscribe
|
||||
JSS(accounts_proposed); // in: Subscribe, Unsubscribe
|
||||
JSS(acroot);
|
||||
JSS(action);
|
||||
JSS(acquiring); // out: LedgerRequest
|
||||
JSS(address); // out: PeerImp
|
||||
JSS(affected); // out: AcceptedLedgerTx
|
||||
JSS(age); // out: NetworkOPs, Peers
|
||||
JSS(alternatives); // out: PathRequest, RipplePathFind
|
||||
JSS(amendment_blocked); // out: NetworkOPs
|
||||
JSS(amendments); // in: AccountObjects, out: NetworkOPs
|
||||
JSS(amm); // out: amm_info
|
||||
JSS(amm_account); // in: amm_info
|
||||
JSS(amount); // out: AccountChannels, amm_info
|
||||
JSS(amount2); // out: amm_info
|
||||
JSS(api_version); // in: many, out: Version
|
||||
JSS(api_version_low); // out: Version
|
||||
JSS(applied); // out: SubmitTransaction
|
||||
JSS(asks); // out: Subscribe
|
||||
JSS(asset); // in: amm_info
|
||||
JSS(asset2); // in: amm_info
|
||||
JSS(assets); // out: GatewayBalances
|
||||
JSS(asset_frozen); // out: amm_info
|
||||
JSS(asset2_frozen); // out: amm_info
|
||||
JSS(attestations); //
|
||||
JSS(attestation_reward_account); //
|
||||
JSS(auction_slot); // out: amm_info
|
||||
JSS(authorized); // out: AccountLines
|
||||
JSS(auth_accounts); // out: amm_info
|
||||
JSS(auth_change); // out: AccountInfo
|
||||
JSS(auth_change_queued); // out: AccountInfo
|
||||
JSS(available); // out: ValidatorList
|
||||
JSS(avg_bps_recv); // out: Peers
|
||||
JSS(avg_bps_sent); // out: Peers
|
||||
JSS(balance); // out: AccountLines
|
||||
JSS(balances); // out: GatewayBalances
|
||||
JSS(base); // out: LogLevel
|
||||
JSS(base_asset); // in: get_aggregate_price
|
||||
JSS(base_fee); // out: NetworkOPs
|
||||
JSS(base_fee_no_hooks);
|
||||
JSS(base_fee_xrp); // out: NetworkOPs
|
||||
JSS(base_fee_native); // out: NetworkOPs
|
||||
JSS(bids); // out: Subscribe
|
||||
JSS(binary); // in: AccountTX, LedgerEntry,
|
||||
// AccountTxOld, Tx LedgerData
|
||||
JSS(blob); // out: ValidatorList
|
||||
JSS(blobs_v2); // out: ValidatorList
|
||||
// in: UNL
|
||||
JSS(books); // in: Subscribe, Unsubscribe
|
||||
JSS(both); // in: Subscribe, Unsubscribe
|
||||
JSS(both_sides); // in: Subscribe, Unsubscribe
|
||||
JSS(broadcast); // out: SubmitTransaction
|
||||
JSS(bridge); // in: LedgerEntry
|
||||
JSS(bridge_account); // in: LedgerEntry
|
||||
JSS(build_path); // in: TransactionSign
|
||||
JSS(build_version); // out: NetworkOPs
|
||||
JSS(bytes_written);
|
||||
JSS(cancel_after); // out: AccountChannels
|
||||
JSS(can_delete); // out: CanDelete
|
||||
JSS(changes); // out: BookChanges
|
||||
JSS(channel_id); // out: AccountChannels
|
||||
JSS(channels); // out: AccountChannels
|
||||
JSS(check); // in: AccountObjects
|
||||
JSS(check_nodes); // in: LedgerCleaner
|
||||
JSS(clear); // in/out: FetchInfo
|
||||
JSS(close); // out: BookChanges
|
||||
JSS(close_flags); // out: LedgerToJson
|
||||
JSS(close_time); // in: Application, out: NetworkOPs,
|
||||
// RCLCxPeerPos, LedgerToJson
|
||||
JSS(close_time_iso); // out: Tx, NetworkOPs, TransactionEntry
|
||||
// AccountTx, LedgerToJson
|
||||
JSS(close_time_estimated); // in: Application, out: LedgerToJson
|
||||
JSS(close_time_human); // out: LedgerToJson
|
||||
JSS(close_time_offset); // out: NetworkOPs
|
||||
JSS(close_time_resolution); // in: Application; out: LedgerToJson
|
||||
JSS(closed); // out: NetworkOPs, LedgerToJson,
|
||||
// handlers/Ledger
|
||||
JSS(closed_ledger); // out: NetworkOPs
|
||||
JSS(cluster); // out: PeerImp
|
||||
JSS(code); // out: errors
|
||||
JSS(command); // in: RPCHandler
|
||||
JSS(complete); // out: NetworkOPs, InboundLedger
|
||||
JSS(complete_ledgers); // out: NetworkOPs, PeerImp
|
||||
JSS(complete_ledgers_pinned);
|
||||
JSS(complete_shards); // out: OverlayImpl, PeerImp
|
||||
JSS(compression_level);
|
||||
JSS(consensus); // out: NetworkOPs, LedgerConsensus
|
||||
JSS(converge_time); // out: NetworkOPs
|
||||
JSS(converge_time_s); // out: NetworkOPs
|
||||
JSS(cookie); // out: NetworkOPs
|
||||
JSS(count); // in: AccountTx*, ValidatorList
|
||||
JSS(counters); // in/out: retrieve counters
|
||||
JSS(coins);
|
||||
JSS(children);
|
||||
JSS(ctid); // in/out: Tx RPC
|
||||
JSS(cres);
|
||||
JSS(currency_a); // out: BookChanges
|
||||
JSS(currency_b); // out: BookChanges
|
||||
JSS(currentShard); // out: NodeToShardStatus
|
||||
JSS(currentShardIndex); // out: NodeToShardStatus
|
||||
JSS(currency); // in: paths/PathRequest, STAmount
|
||||
// out: STPathSet, STAmount,
|
||||
// AccountLines
|
||||
JSS(current); // out: OwnerInfo
|
||||
JSS(current_activities);
|
||||
JSS(current_ledger_size); // out: TxQ
|
||||
JSS(current_ledger);
|
||||
JSS(current_queue_size); // out: TxQ
|
||||
JSS(data); // out: LedgerData
|
||||
JSS(date); // out: tx/Transaction, NetworkOPs
|
||||
JSS(dbKBLedger); // out: getCounts
|
||||
JSS(dbKBTotal); // out: getCounts
|
||||
JSS(dbKBTransaction); // out: getCounts
|
||||
JSS(debug_signing); // in: TransactionSign
|
||||
JSS(deletion_blockers_only); // in: AccountObjects
|
||||
JSS(delivered_amount); // out: insertDeliveredAmount
|
||||
JSS(deposit_authorized); // out: deposit_authorized
|
||||
JSS(deposit_preauth); // in: AccountObjects, LedgerData
|
||||
JSS(deprecated); // out
|
||||
JSS(descending); // in: AccountTx*
|
||||
JSS(description); // in/out: Reservations
|
||||
JSS(destination); // in: nft_buy_offers, nft_sell_offers
|
||||
JSS(destination_account); // in: PathRequest, RipplePathFind, account_lines
|
||||
// out: AccountChannels
|
||||
JSS(destination_amount); // in: PathRequest, RipplePathFind
|
||||
JSS(destination_currencies); // in: PathRequest, RipplePathFind
|
||||
JSS(destination_tag); // in: PathRequest
|
||||
// out: AccountChannels
|
||||
JSS(details); // out: Manifest, server_info
|
||||
JSS(did); // in: LedgerEntry
|
||||
JSS(dir_entry); // out: DirectoryEntryIterator
|
||||
JSS(dir_index); // out: DirectoryEntryIterator
|
||||
JSS(dir_root); // out: DirectoryEntryIterator
|
||||
JSS(directory); // in: LedgerEntry
|
||||
JSS(discounted_fee); // out: amm_info
|
||||
JSS(domain); // out: ValidatorInfo, Manifest
|
||||
JSS(drops); // out: TxQ
|
||||
JSS(duration_us); // out: NetworkOPs
|
||||
JSS(effective); // out: ValidatorList
|
||||
// in: UNL
|
||||
JSS(elapsed_seconds);
|
||||
JSS(enabled); // out: AmendmentTable
|
||||
JSS(engine_result); // out: NetworkOPs, TransactionSign, Submit
|
||||
JSS(engine_result_code); // out: NetworkOPs, TransactionSign, Submit
|
||||
JSS(engine_result_message); // out: NetworkOPs, TransactionSign, Submit
|
||||
JSS(entire_set); // out: get_aggregate_price
|
||||
JSS(ephemeral_key); // out: ValidatorInfo
|
||||
// in/out: Manifest
|
||||
JSS(error); // out: error
|
||||
JSS(errored);
|
||||
JSS(error_code); // out: error
|
||||
JSS(error_exception); // out: Submit
|
||||
JSS(error_message); // out: error
|
||||
JSS(escrow); // in: LedgerEntry
|
||||
JSS(estimated_time_remaining);
|
||||
JSS(emitted_txn); // in: LedgerEntry
|
||||
JSS(expand); // in: handler/Ledger
|
||||
JSS(expected_date); // out: any (warnings)
|
||||
JSS(expected_date_UTC); // out: any (warnings)
|
||||
JSS(expected_ledger_size); // out: TxQ
|
||||
JSS(expiration); // out: AccountOffers, AccountChannels,
|
||||
// ValidatorList, amm_info
|
||||
JSS(fail_hard); // in: Sign, Submit
|
||||
JSS(failed); // out: InboundLedger
|
||||
JSS(failed_ledgers); // out: catalogue
|
||||
JSS(feature); // in: Feature
|
||||
JSS(features); // out: Feature
|
||||
JSS(fee); // out: NetworkOPs, Peers
|
||||
JSS(fee_base); // out: NetworkOPs
|
||||
JSS(fee_div_max); // in: TransactionSign
|
||||
JSS(fee_hooks_feeunits); // out: Fee rpc call
|
||||
JSS(fee_level); // out: AccountInfo
|
||||
JSS(fee_mult_max); // in: TransactionSign
|
||||
JSS(fee_ref); // out: NetworkOPs, DEPRECATED
|
||||
JSS(fetch_pack); // out: NetworkOPs
|
||||
JSS(first); // out: rpc/Version
|
||||
JSS(firstSequence); // out: NodeToShardStatus
|
||||
JSS(firstShardIndex); // out: NodeToShardStatus
|
||||
JSS(finished);
|
||||
JSS(fix_txns); // in: LedgerCleaner
|
||||
JSS(file);
|
||||
JSS(file_size);
|
||||
JSS(file_size_estimated_human);
|
||||
JSS(file_size_human);
|
||||
JSS(flags); // out: AccountOffers,
|
||||
// NetworkOPs
|
||||
JSS(force); // in: catalogue
|
||||
JSS(forward); // in: AccountTx
|
||||
JSS(freeze); // out: AccountLines
|
||||
JSS(freeze_peer); // out: AccountLines
|
||||
JSS(frozen_balances); // out: GatewayBalances
|
||||
JSS(full); // in: LedgerClearer, handlers/Ledger
|
||||
JSS(full_reply); // out: PathFind
|
||||
JSS(fullbelow_size); // out: GetCounts
|
||||
JSS(good); // out: RPCVersion
|
||||
JSS(hash); // out: NetworkOPs, InboundLedger,
|
||||
JSS(hash_mismatches); // out: catalogue
|
||||
// LedgerToJson, STTx; field
|
||||
JSS(hashes); // in: AccountObjects
|
||||
JSS(have_header); // out: InboundLedger
|
||||
JSS(have_state); // out: InboundLedger
|
||||
JSS(have_transactions); // out: InboundLedger
|
||||
JSS(high); // out: BookChanges
|
||||
JSS(highest_sequence); // out: AccountInfo
|
||||
JSS(highest_ticket); // out: AccountInfo
|
||||
JSS(historical_perminute); // historical_perminute.
|
||||
JSS(hook); // in: LedgerEntry
|
||||
JSS(hook_definition); // in: LedgerEntry
|
||||
JSS(hook_state); // in: LedgerEntry
|
||||
JSS(hostid); // out: NetworkOPs
|
||||
JSS(hotwallet); // in: GatewayBalances
|
||||
JSS(id); // websocket.
|
||||
JSS(ident); // in: AccountCurrencies, AccountInfo,
|
||||
// OwnerInfo
|
||||
JSS(ignore_default); // in: AccountLines
|
||||
JSS(ignore_hash);
|
||||
JSS(import_vlseq); // in: LedgerEntry
|
||||
JSS(imported); // out: catalogue
|
||||
JSS(inLedger); // out: tx/Transaction
|
||||
JSS(in_queue);
|
||||
JSS(inbound); // out: PeerImp
|
||||
JSS(index); // in: LedgerEntry, DownloadShard
|
||||
// out: STLedgerEntry,
|
||||
// LedgerEntry, TxHistory, LedgerData
|
||||
JSS(info); // out: ServerInfo, ConsensusInfo, FetchInfo
|
||||
JSS(initial_sync_duration_us);
|
||||
JSS(internal_command); // in: Internal
|
||||
JSS(invalid_API_version); // out: Many, when a request has an invalid
|
||||
// version
|
||||
JSS(io_latency_ms); // out: NetworkOPs
|
||||
JSS(ip); // in: Connect, out: OverlayImpl
|
||||
JSS(is_burned); // out: nft_info (clio)
|
||||
JSS(issuer); // in: RipplePathFind, Subscribe,
|
||||
// Unsubscribe, BookOffers
|
||||
// out: STPathSet, STAmount
|
||||
JSS(job);
|
||||
JSS(job_queue);
|
||||
JSS(job_type);
|
||||
JSS(job_status);
|
||||
JSS(jobs);
|
||||
JSS(jsonrpc); // json version
|
||||
JSS(jq_trans_overflow); // JobQueue transaction limit overflow.
|
||||
JSS(kept); // out: SubmitTransaction
|
||||
JSS(key); // out
|
||||
JSS(key_type); // in/out: WalletPropose, TransactionSign
|
||||
JSS(latency); // out: PeerImp
|
||||
JSS(last); // out: RPCVersion
|
||||
JSS(lastSequence); // out: NodeToShardStatus
|
||||
JSS(lastShardIndex); // out: NodeToShardStatus
|
||||
JSS(last_close); // out: NetworkOPs
|
||||
JSS(last_refresh_time); // out: ValidatorSite
|
||||
JSS(last_refresh_status); // out: ValidatorSite
|
||||
JSS(last_refresh_message); // out: ValidatorSite
|
||||
JSS(ledger); // in: NetworkOPs, LedgerCleaner,
|
||||
// RPCHelpers
|
||||
// out: NetworkOPs, PeerImp
|
||||
JSS(ledger_count);
|
||||
JSS(ledgers_loaded);
|
||||
JSS(ledgers_written);
|
||||
JSS(ledger_current_index); // out: NetworkOPs, RPCHelpers,
|
||||
// LedgerCurrent, LedgerAccept,
|
||||
// AccountLines
|
||||
JSS(ledger_data); // out: LedgerHeader
|
||||
JSS(ledger_hash); // in: RPCHelpers, LedgerRequest,
|
||||
// RipplePathFind, TransactionEntry,
|
||||
// handlers/Ledger
|
||||
// out: NetworkOPs, RPCHelpers,
|
||||
// LedgerClosed, LedgerData,
|
||||
// AccountLines
|
||||
JSS(ledger_hit_rate); // out: GetCounts
|
||||
JSS(ledger_index); // in/out: many
|
||||
JSS(ledger_index_max); // in, out: AccountTx*
|
||||
JSS(ledger_index_min); // in, out: AccountTx*
|
||||
JSS(ledger_max); // in, out: AccountTx*
|
||||
JSS(ledger_min); // in, out: AccountTx*
|
||||
JSS(ledger_time); // out: NetworkOPs
|
||||
JSS(LEDGER_ENTRY_TYPES); // out: RPC server_definitions
|
||||
JSS(levels); // LogLevels
|
||||
JSS(level);
|
||||
JSS(limit); // in/out: AccountTx*, AccountOffers,
|
||||
// AccountLines, AccountObjects
|
||||
// in: LedgerData, BookOffers
|
||||
JSS(limit_peer); // out: AccountLines
|
||||
JSS(lines); // out: AccountLines
|
||||
JSS(list); // out: ValidatorList
|
||||
JSS(load); // out: NetworkOPs, PeerImp
|
||||
JSS(load_base); // out: NetworkOPs
|
||||
JSS(load_factor); // out: NetworkOPs
|
||||
JSS(load_factor_cluster); // out: NetworkOPs
|
||||
JSS(load_factor_fee_escalation); // out: NetworkOPs
|
||||
JSS(load_factor_fee_queue); // out: NetworkOPs
|
||||
JSS(load_factor_fee_reference); // out: NetworkOPs
|
||||
JSS(load_factor_local); // out: NetworkOPs
|
||||
JSS(load_factor_net); // out: NetworkOPs
|
||||
JSS(load_factor_server); // out: NetworkOPs
|
||||
JSS(load_fee); // out: LoadFeeTrackImp, NetworkOPs
|
||||
JSS(local); // out: resource/Logic.h
|
||||
JSS(local_txs); // out: GetCounts
|
||||
JSS(local_static_keys); // out: ValidatorList
|
||||
JSS(locked_balance); // out: AccountLines
|
||||
JSS(low); // out: BookChanges
|
||||
JSS(lock_count); // out: AccountLines
|
||||
JSS(lowest_sequence); // out: AccountInfo
|
||||
JSS(lowest_ticket); // out: AccountInfo
|
||||
JSS(lp_token); // out: amm_info
|
||||
JSS(majority); // out: RPC feature
|
||||
JSS(manifest); // out: ValidatorInfo, Manifest
|
||||
JSS(marker); // in/out: AccountTx, AccountOffers,
|
||||
// AccountLines, AccountObjects,
|
||||
// LedgerData
|
||||
// in: BookOffers
|
||||
JSS(master_key); // out: WalletPropose, NetworkOPs,
|
||||
// ValidatorInfo
|
||||
// in/out: Manifest
|
||||
JSS(master_seed); // out: WalletPropose
|
||||
JSS(master_seed_hex); // out: WalletPropose
|
||||
JSS(master_signature); // out: pubManifest
|
||||
JSS(max_ledger); // in/out: LedgerCleaner
|
||||
JSS(max_queue_size); // out: TxQ
|
||||
JSS(max_spend_drops); // out: AccountInfo
|
||||
JSS(max_spend_drops_total); // out: AccountInfo
|
||||
JSS(mean); // out: get_aggregate_price
|
||||
JSS(median); // out: get_aggregate_price
|
||||
JSS(median_fee); // out: TxQ
|
||||
JSS(median_level); // out: TxQ
|
||||
JSS(message); // error.
|
||||
JSS(meta); // out: NetworkOPs, AccountTx*, Tx
|
||||
JSS(meta_blob); // out: NetworkOPs, AccountTx*, Tx
|
||||
JSS(metaData);
|
||||
JSS(metadata); // out: TransactionEntry
|
||||
JSS(method); // RPC
|
||||
JSS(methods);
|
||||
JSS(metrics); // out: Peers
|
||||
JSS(Memo); // Field
|
||||
JSS(Memos); // Field
|
||||
JSS(MemoFormat); // Field
|
||||
JSS(MemoData); // Field
|
||||
JSS(MemoType); // Field
|
||||
JSS(min_count); // in: GetCounts
|
||||
JSS(min_ledger); // in: LedgerCleaner
|
||||
JSS(minimum_fee); // out: TxQ
|
||||
JSS(minimum_level); // out: TxQ
|
||||
JSS(missingCommand); // error
|
||||
JSS(name); // out: AmendmentTableImpl, PeerImp
|
||||
JSS(namespace_entries); // out: AccountNamespace
|
||||
JSS(namespace_id); // in/out: AccountNamespace
|
||||
JSS(native_currency_code); // out: RPC
|
||||
JSS(needed_state_hashes); // out: InboundLedger
|
||||
JSS(needed_transaction_hashes); // out: InboundLedger
|
||||
JSS(network_id); // out: NetworkOPs
|
||||
JSS(network_ledger); // out: NetworkOPs
|
||||
JSS(next_refresh_time); // out: ValidatorSite
|
||||
JSS(nft_id); // in: nft_sell_offers, nft_buy_offers
|
||||
JSS(nft_offer); // in: LedgerEntry
|
||||
JSS(nft_offer_index); // out nft_buy_offers, nft_sell_offers
|
||||
JSS(nft_page); // in: LedgerEntry
|
||||
JSS(nft_serial); // out: account_nfts
|
||||
JSS(nft_taxon); // out: nft_info (clio)
|
||||
JSS(nftoken_id); // out: insertNFTokenID
|
||||
JSS(nftoken_ids); // out: insertNFTokenID
|
||||
JSS(no_ripple); // out: AccountLines
|
||||
JSS(no_ripple_peer); // out: AccountLines
|
||||
JSS(node); // out: LedgerEntry
|
||||
JSS(node_binary); // out: LedgerEntry
|
||||
JSS(node_read_bytes); // out: GetCounts
|
||||
JSS(node_read_errors); // out: GetCounts
|
||||
JSS(node_read_retries); // out: GetCounts
|
||||
JSS(node_reads_hit); // out: GetCounts
|
||||
JSS(node_reads_total); // out: GetCounts
|
||||
JSS(node_reads_duration_us); // out: GetCounts
|
||||
JSS(node_size); // out: server_info
|
||||
JSS(nodestore); // out: GetCounts
|
||||
JSS(node_writes); // out: GetCounts
|
||||
JSS(node_written_bytes); // out: GetCounts
|
||||
JSS(node_writes_duration_us); // out: GetCounts
|
||||
JSS(node_write_retries); // out: GetCounts
|
||||
JSS(node_writes_delayed); // out::GetCounts
|
||||
JSS(nth); // out: RPC server_definitions
|
||||
JSS(nunl); // in: AccountObjects
|
||||
JSS(obligations); // out: GatewayBalances
|
||||
JSS(offer); // in: LedgerEntry
|
||||
JSS(offers); // out: NetworkOPs, AccountOffers, Subscribe
|
||||
JSS(offer_id); // out: insertNFTokenOfferID
|
||||
JSS(offline); // in: TransactionSign
|
||||
JSS(offset); // in/out: AccountTxOld
|
||||
JSS(open); // out: handlers/Ledger
|
||||
JSS(open_ledger_cost); // out: SubmitTransaction
|
||||
JSS(open_ledger_fee); // out: TxQ
|
||||
JSS(open_ledger_level); // out: TxQ
|
||||
JSS(oracle); // in: LedgerEntry
|
||||
JSS(oracles); // in: get_aggregate_price
|
||||
JSS(oracle_document_id); // in: get_aggregate_price
|
||||
JSS(owner); // in: LedgerEntry, out: NetworkOPs
|
||||
JSS(owner_funds); // in/out: Ledger, NetworkOPs, AcceptedLedgerTx
|
||||
JSS(page_index);
|
||||
JSS(params); // RPC
|
||||
JSS(parent_close_time); // out: LedgerToJson
|
||||
JSS(parent_hash); // out: LedgerToJson
|
||||
JSS(partition); // in: LogLevel
|
||||
JSS(passphrase); // in: WalletPropose
|
||||
JSS(password); // in: Subscribe
|
||||
JSS(paths); // in: RipplePathFind
|
||||
JSS(paths_canonical); // out: RipplePathFind
|
||||
JSS(paths_computed); // out: PathRequest, RipplePathFind
|
||||
JSS(output_file); // in: CatalogueCreate
|
||||
JSS(input_file); // in: CatalogueLoad
|
||||
JSS(payment_channel); // in: LedgerEntry
|
||||
JSS(pclose);
|
||||
JSS(peer); // in: AccountLines
|
||||
JSS(peer_authorized); // out: AccountLines
|
||||
JSS(peer_id); // out: RCLCxPeerPos
|
||||
JSS(peers); // out: InboundLedger, handlers/Peers, Overlay
|
||||
JSS(peer_disconnects); // Severed peer connection counter.
|
||||
JSS(peer_disconnects_resources); // Severed peer connections because of
|
||||
// excess resource consumption.
|
||||
JSS(percent_complete);
|
||||
JSS(phash);
|
||||
JSS(port); // in: Connect, out: NetworkOPs
|
||||
JSS(ports); // out: NetworkOPs
|
||||
JSS(previous); // out: Reservations
|
||||
JSS(previous_ledger); // out: LedgerPropose
|
||||
JSS(price); // out: amm_info, AuctionSlot
|
||||
JSS(proof); // in: BookOffers
|
||||
JSS(propose_seq); // out: LedgerPropose
|
||||
JSS(proposers); // out: NetworkOPs, LedgerConsensus
|
||||
JSS(protocol); // out: NetworkOPs, PeerImp
|
||||
JSS(proxied); // out: RPC ping
|
||||
JSS(pubkey_node); // out: NetworkOPs
|
||||
JSS(pubkey_publisher); // out: ValidatorList
|
||||
JSS(pubkey_validator); // out: NetworkOPs, ValidatorList
|
||||
JSS(public_key); // out: OverlayImpl, PeerImp, WalletPropose,
|
||||
// ValidatorInfo
|
||||
// in/out: Manifest
|
||||
JSS(public_key_hex); // out: WalletPropose
|
||||
JSS(published_ledger); // out: NetworkOPs
|
||||
JSS(publisher_lists); // out: ValidatorList
|
||||
JSS(quality); // out: NetworkOPs
|
||||
JSS(quality_in); // out: AccountLines
|
||||
JSS(quality_out); // out: AccountLines
|
||||
JSS(queue); // in: AccountInfo
|
||||
JSS(queue_data); // out: AccountInfo
|
||||
JSS(queued); // out: SubmitTransaction
|
||||
JSS(queued_duration_us);
|
||||
JSS(quote_asset); // in: get_aggregate_price
|
||||
JSS(random); // out: Random
|
||||
JSS(raw_meta); // out: AcceptedLedgerTx
|
||||
JSS(receive_currencies); // out: AccountCurrencies
|
||||
JSS(reference_level); // out: TxQ
|
||||
JSS(refresh_interval); // in: UNL
|
||||
JSS(refresh_interval_min); // out: ValidatorSites
|
||||
JSS(regular_seed); // in/out: LedgerEntry
|
||||
JSS(remaining); // out: ValidatorList
|
||||
JSS(remote); // out: Logic.h
|
||||
JSS(request); // RPC
|
||||
JSS(requested); // out: Manifest
|
||||
JSS(reservations); // out: Reservations
|
||||
JSS(reserve_base); // out: NetworkOPs
|
||||
JSS(reserve_base_xrp); // out: NetworkOPs
|
||||
JSS(reserve_base_native); // out: NetworkOPs
|
||||
JSS(reserve_inc); // out: NetworkOPs
|
||||
JSS(reserve_inc_xrp); // out: NetworkOPs
|
||||
JSS(reserve_inc_native); // out: NetworkOPs
|
||||
JSS(response); // websocket
|
||||
JSS(result); // RPC
|
||||
JSS(ripple_lines); // out: NetworkOPs
|
||||
JSS(ripple_state); // in: LedgerEntr
|
||||
JSS(ripplerpc); // ripple RPC version
|
||||
JSS(role); // out: Ping.cpp
|
||||
JSS(rpc);
|
||||
JSS(rt_accounts); // in: Subscribe, Unsubscribe
|
||||
JSS(running_duration_us);
|
||||
JSS(search_depth); // in: RipplePathFind
|
||||
JSS(searched_all); // out: Tx
|
||||
JSS(secret); // in: TransactionSign,
|
||||
// ValidationCreate, ValidationSeed,
|
||||
// channel_authorize
|
||||
JSS(seed); //
|
||||
JSS(seed_hex); // in: WalletPropose, TransactionSign
|
||||
JSS(send_currencies); // out: AccountCurrencies
|
||||
JSS(send_max); // in: PathRequest, RipplePathFind
|
||||
JSS(seq); // in: LedgerEntry;
|
||||
// out: NetworkOPs, RPCSub, AccountOffers,
|
||||
// ValidatorList, ValidatorInfo, Manifest
|
||||
JSS(sequence); // in: UNL
|
||||
JSS(sequence_count); // out: AccountInfo
|
||||
JSS(server_domain); // out: NetworkOPs
|
||||
JSS(server_state); // out: NetworkOPs
|
||||
JSS(server_state_duration_us); // out: NetworkOPs
|
||||
JSS(server_status); // out: NetworkOPs
|
||||
JSS(server_version); // out: NetworkOPs
|
||||
JSS(settle_delay); // out: AccountChannels
|
||||
JSS(severity); // in: LogLevel
|
||||
JSS(shards); // in/out: GetCounts, DownloadShard
|
||||
JSS(signature); // out: NetworkOPs, ChannelAuthorize
|
||||
JSS(signature_verified); // out: ChannelVerify
|
||||
JSS(signing_key); // out: NetworkOPs
|
||||
JSS(signing_keys); // out: ValidatorList
|
||||
JSS(signing_time); // out: NetworkOPs
|
||||
JSS(signer_list); // in: AccountObjects
|
||||
JSS(signer_lists); // in/out: AccountInfo
|
||||
JSS(size); // out: get_aggregate_price
|
||||
JSS(snapshot); // in: Subscribe
|
||||
JSS(source_account); // in: PathRequest, RipplePathFind
|
||||
JSS(source_amount); // in: PathRequest, RipplePathFind
|
||||
JSS(source_currencies); // in: PathRequest, RipplePathFind
|
||||
JSS(source_tag); // out: AccountChannels
|
||||
JSS(stand_alone); // out: NetworkOPs
|
||||
JSS(standard_deviation); // out: get_aggregate_price
|
||||
JSS(start); // in: TxHistory
|
||||
JSS(start_time);
|
||||
JSS(started);
|
||||
JSS(state); // out: Logic.h, ServerState, LedgerData
|
||||
JSS(state_accounting); // out: NetworkOPs
|
||||
JSS(state_now); // in: Subscribe
|
||||
JSS(status); // error
|
||||
JSS(stop); // in: LedgerCleaner
|
||||
JSS(stop_history_tx_only); // in: Unsubscribe, stop history tx stream
|
||||
JSS(storedSeqs); // out: NodeToShardStatus
|
||||
JSS(streams); // in: Subscribe, Unsubscribe
|
||||
JSS(strict); // in: AccountCurrencies, AccountInfo
|
||||
JSS(sub_index); // in: LedgerEntry
|
||||
JSS(subcommand); // in: PathFind
|
||||
JSS(success); // rpc
|
||||
JSS(supported); // out: AmendmentTableImpl
|
||||
JSS(sync_mode); // in: Submit
|
||||
JSS(system_time_offset); // out: NetworkOPs
|
||||
JSS(tag); // out: Peers
|
||||
JSS(taker); // in: Subscribe, BookOffers
|
||||
JSS(taker_gets); // in: Subscribe, Unsubscribe, BookOffers
|
||||
JSS(taker_gets_funded); // out: NetworkOPs
|
||||
JSS(taker_pays); // in: Subscribe, Unsubscribe, BookOffers
|
||||
JSS(taker_pays_funded); // out: NetworkOPs
|
||||
JSS(threshold); // in: Blacklist
|
||||
JSS(ticket); // in: AccountObjects
|
||||
JSS(ticket_count); // out: AccountInfo
|
||||
JSS(ticket_seq); // in: LedgerEntry
|
||||
JSS(time);
|
||||
JSS(timeouts); // out: InboundLedger
|
||||
JSS(time_threshold); // in/out: Oracle aggregate
|
||||
JSS(time_interval); // out: AMM Auction Slot
|
||||
JSS(track); // out: PeerImp
|
||||
JSS(traffic); // out: Overlay
|
||||
JSS(trim); // in: get_aggregate_price
|
||||
JSS(trimmed_set); // out: get_aggregate_price
|
||||
JSS(total); // out: counters
|
||||
JSS(total_bytes_recv); // out: Peers
|
||||
JSS(total_bytes_sent); // out: Peers
|
||||
JSS(total_coins); // out: LedgerToJson
|
||||
JSS(trading_fee); // out: amm_info
|
||||
JSS(transTreeHash); // out: ledger/Ledger.cpp
|
||||
JSS(transaction); // in: Tx
|
||||
// out: NetworkOPs, AcceptedLedgerTx,
|
||||
JSS(transaction_hash); // out: RCLCxPeerPos, LedgerToJson
|
||||
JSS(transactions); // out: LedgerToJson,
|
||||
// in: AccountTx*, Unsubscribe
|
||||
JSS(transfer_rate); // out: nft_info (clio)
|
||||
JSS(transitions); // out: NetworkOPs
|
||||
JSS(treenode_cache_size); // out: GetCounts
|
||||
JSS(treenode_track_size); // out: GetCounts
|
||||
JSS(trusted); // out: UnlList
|
||||
JSS(trusted_validator_keys); // out: ValidatorList
|
||||
JSS(tx); // out: STTx, AccountTx*
|
||||
JSS(txroot);
|
||||
JSS(tx_blob); // in/out: Submit,
|
||||
// in: TransactionSign, AccountTx*
|
||||
JSS(tx_hash); // in: TransactionEntry
|
||||
JSS(tx_json); // in/out: TransactionSign
|
||||
// out: TransactionEntry
|
||||
JSS(tx_signing_hash); // out: TransactionSign
|
||||
JSS(tx_unsigned); // out: TransactionSign
|
||||
JSS(txn_count); // out: NetworkOPs
|
||||
JSS(txr_tx_cnt); // out: protocol message tx's count
|
||||
JSS(txr_tx_sz); // out: protocol message tx's size
|
||||
JSS(txr_have_txs_cnt); // out: protocol message have tx count
|
||||
JSS(txr_have_txs_sz); // out: protocol message have tx size
|
||||
JSS(txr_get_ledger_cnt); // out: protocol message get ledger count
|
||||
JSS(txr_get_ledger_sz); // out: protocol message get ledger size
|
||||
JSS(txr_ledger_data_cnt); // out: protocol message ledger data count
|
||||
JSS(txr_ledger_data_sz); // out: protocol message ledger data size
|
||||
JSS(txr_transactions_cnt); // out: protocol message get object count
|
||||
JSS(txr_transactions_sz); // out: protocol message get object size
|
||||
JSS(txr_selected_cnt); // out: selected peers count
|
||||
JSS(txr_suppressed_cnt); // out: suppressed peers count
|
||||
JSS(txr_not_enabled_cnt); // out: peers with tx reduce-relay disabled count
|
||||
JSS(txr_missing_tx_freq); // out: missing tx frequency average
|
||||
JSS(txs); // out: TxHistory
|
||||
JSS(type); // in: AccountObjects
|
||||
// out: NetworkOPs RPC server_definitions
|
||||
// OverlayImpl, Logic
|
||||
JSS(TRANSACTION_RESULTS); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
JSS(TRANSACTION_TYPES); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
JSS(TYPES); // out: RPC server_definitions
|
||||
// matches definitions.json format
|
||||
JSS(TRANSACTION_FLAGS); // out: RPC server_definitions
|
||||
JSS(TRANSACTION_FLAGS_INDICES); // out: RPC server_definitions
|
||||
JSS(type_hex); // out: STPathSet
|
||||
JSS(unl); // out: UnlList
|
||||
JSS(unlimited); // out: Connection.h
|
||||
JSS(unl_report); // in: LedgerEntry
|
||||
JSS(uptime); // out: GetCounts
|
||||
JSS(uri); // out: ValidatorSites
|
||||
JSS(uri_token); // in: LedgerEntry
|
||||
JSS(url); // in/out: Subscribe, Unsubscribe
|
||||
JSS(url_password); // in: Subscribe
|
||||
JSS(url_username); // in: Subscribe
|
||||
JSS(urlgravatar); //
|
||||
JSS(username); // in: Subscribe
|
||||
JSS(validated); // out: NetworkOPs, RPCHelpers, AccountTx*
|
||||
// Tx
|
||||
JSS(validator_list_expires); // out: NetworkOps, ValidatorList
|
||||
JSS(validator_list); // out: NetworkOps, ValidatorList
|
||||
JSS(validators);
|
||||
JSS(validated_hash); // out: NetworkOPs
|
||||
JSS(validated_ledger); // out: NetworkOPs
|
||||
JSS(validated_ledger_index); // out: SubmitTransaction
|
||||
JSS(validated_ledgers); // out: NetworkOPs
|
||||
JSS(validation_key); // out: ValidationCreate, ValidationSeed
|
||||
JSS(validation_private_key); // out: ValidationCreate
|
||||
JSS(validation_public_key); // out: ValidationCreate, ValidationSeed
|
||||
JSS(validation_quorum); // out: NetworkOPs
|
||||
JSS(validation_seed); // out: ValidationCreate, ValidationSeed
|
||||
JSS(validation);
|
||||
JSS(validations); // out: AmendmentTableImpl
|
||||
JSS(validator_sites); // out: ValidatorSites
|
||||
JSS(value); // out: STAmount
|
||||
JSS(version); // out: RPCVersion
|
||||
JSS(vetoed); // out: AmendmentTableImpl
|
||||
JSS(volume_a); // out: BookChanges
|
||||
JSS(volume_b); // out: BookChanges
|
||||
JSS(vote); // in: Feature
|
||||
JSS(vote_slots); // out: amm_info
|
||||
JSS(vote_weight); // out: amm_info
|
||||
JSS(warning); // rpc:
|
||||
JSS(warnings); // out: server_info, server_state
|
||||
JSS(workers);
|
||||
JSS(write_load); // out: GetCounts
|
||||
JSS(xchain_owned_claim_id); // in: LedgerEntry, AccountObjects
|
||||
JSS(xchain_owned_create_account_claim_id); // in: LedgerEntry
|
||||
JSS(NegativeUNL); // out: ValidatorList; ledger type
|
||||
#undef JSS
|
||||
|
||||
} // namespace jss
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
36
include/xrpl/protocol/messages.h
Normal file
36
include/xrpl/protocol/messages.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_MESSAGES_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_MESSAGES_H_INCLUDED
|
||||
|
||||
// Some versions of protobuf generate code that will produce errors during
|
||||
// compilation. See https://github.com/google/protobuf/issues/549 for more
|
||||
// details. We work around this by undefining this macro.
|
||||
//
|
||||
// TODO: Remove this after the protoc we use is upgraded to not generate
|
||||
// code that conflicts with the TYPE_BOOL macro.
|
||||
|
||||
#ifdef TYPE_BOOL
|
||||
#undef TYPE_BOOL
|
||||
#endif
|
||||
|
||||
#include <ripple/proto/ripple.pb.h>
|
||||
|
||||
#endif
|
||||
127
include/xrpl/protocol/nft.h
Normal file
127
include/xrpl/protocol/nft.h
Normal file
@@ -0,0 +1,127 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_NFT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_NFT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/tagged_integer.h>
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace ripple {
|
||||
namespace nft {
|
||||
|
||||
// Separate taxons from regular integers.
|
||||
struct TaxonTag
|
||||
{
|
||||
};
|
||||
using Taxon = tagged_integer<std::uint32_t, TaxonTag>;
|
||||
|
||||
inline Taxon
|
||||
toTaxon(std::uint32_t i)
|
||||
{
|
||||
return static_cast<Taxon>(i);
|
||||
}
|
||||
|
||||
inline std::uint32_t
|
||||
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;
|
||||
|
||||
inline std::uint16_t
|
||||
getFlags(uint256 const& id)
|
||||
{
|
||||
std::uint16_t flags;
|
||||
memcpy(&flags, id.begin(), 2);
|
||||
return boost::endian::big_to_native(flags);
|
||||
}
|
||||
|
||||
inline std::uint16_t
|
||||
getTransferFee(uint256 const& id)
|
||||
{
|
||||
std::uint16_t fee;
|
||||
memcpy(&fee, id.begin() + 2, 2);
|
||||
return boost::endian::big_to_native(fee);
|
||||
}
|
||||
|
||||
inline std::uint32_t
|
||||
getSerial(uint256 const& id)
|
||||
{
|
||||
std::uint32_t seq;
|
||||
memcpy(&seq, id.begin() + 28, 4);
|
||||
return boost::endian::big_to_native(seq);
|
||||
}
|
||||
|
||||
inline Taxon
|
||||
cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
|
||||
{
|
||||
// An issuer may issue several NFTs with the same taxon; to ensure that NFTs
|
||||
// are spread across multiple pages we lightly mix the taxon up by using the
|
||||
// sequence (which is not under the issuer's direct control) as the seed for
|
||||
// a simple linear congruential generator.
|
||||
//
|
||||
// From the Hull-Dobell theorem we know that f(x)=(m*x+c) mod n will yield a
|
||||
// permutation of [0, n) when n is a power of 2 if m is congruent to 1 mod 4
|
||||
// and c is odd.
|
||||
//
|
||||
// Here we use m = 384160001 and c = 2459. The modulo is implicit because we
|
||||
// use 2^32 for n and the arithmetic gives it to us for "free".
|
||||
//
|
||||
// Note that the scramble value we calculate is not cryptographically secure
|
||||
// but that's fine since all we're looking for is some dispersion.
|
||||
//
|
||||
// **IMPORTANT** Changing these numbers would be a breaking change requiring
|
||||
// an amendment along with a way to distinguish token IDs that
|
||||
// were generated with the old code.
|
||||
return taxon ^ toTaxon(((384160001 * tokenSeq) + 2459));
|
||||
}
|
||||
|
||||
inline Taxon
|
||||
getTaxon(uint256 const& id)
|
||||
{
|
||||
std::uint32_t taxon;
|
||||
memcpy(&taxon, id.begin() + 24, 4);
|
||||
taxon = boost::endian::big_to_native(taxon);
|
||||
|
||||
// The taxon cipher is just an XOR, so it is reversible by applying the
|
||||
// XOR a second time.
|
||||
return cipheredTaxon(getSerial(id), toTaxon(taxon));
|
||||
}
|
||||
|
||||
inline AccountID
|
||||
getIssuer(uint256 const& id)
|
||||
{
|
||||
return AccountID::fromVoid(id.data() + 4);
|
||||
}
|
||||
|
||||
} // namespace nft
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
37
include/xrpl/protocol/nftPageMask.h
Normal file
37
include/xrpl/protocol/nftPageMask.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2022 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_NFT_PAGE_MASK_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_NFT_PAGE_MASK_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <string_view>
|
||||
|
||||
namespace ripple {
|
||||
namespace 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(std::string_view(
|
||||
"0000000000000000000000000000000000000000ffffffffffffffffffffffff"));
|
||||
|
||||
} // namespace nft
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
48
include/xrpl/protocol/serialize.h
Normal file
48
include/xrpl/protocol/serialize.h
Normal file
@@ -0,0 +1,48 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2023 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_SERIALIZE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SERIALIZE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/strHex.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Serialize an object to a blob. */
|
||||
template <class Object>
|
||||
Blob
|
||||
serializeBlob(Object const& o)
|
||||
{
|
||||
Serializer s;
|
||||
o.add(s);
|
||||
return s.peekData();
|
||||
}
|
||||
|
||||
/** Serialize an object to a hex string. */
|
||||
inline std::string
|
||||
serializeHex(STObject const& o)
|
||||
{
|
||||
return strHex(serializeBlob(o));
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
39
include/xrpl/protocol/st.h
Normal file
39
include/xrpl/protocol/st.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_ST_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_ST_H_INCLUDED
|
||||
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/STAccount.h>
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
#include <ripple/protocol/STArray.h>
|
||||
#include <ripple/protocol/STBase.h>
|
||||
#include <ripple/protocol/STBitString.h>
|
||||
#include <ripple/protocol/STBlob.h>
|
||||
#include <ripple/protocol/STInteger.h>
|
||||
#include <ripple/protocol/STLedgerEntry.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/STParsedJSON.h>
|
||||
#include <ripple/protocol/STPathSet.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/STValidation.h>
|
||||
#include <ripple/protocol/STVector256.h>
|
||||
|
||||
#endif
|
||||
135
include/xrpl/protocol/tokens.h
Normal file
135
include/xrpl/protocol/tokens.h
Normal file
@@ -0,0 +1,135 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_PROTOCOL_TOKENS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_TOKENS_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Expected.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/protocol/impl/token_errors.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <class T>
|
||||
using B58Result = Expected<T, std::error_code>;
|
||||
|
||||
enum class TokenType : std::uint8_t {
|
||||
None = 1, // unused
|
||||
NodePublic = 28,
|
||||
NodePrivate = 32,
|
||||
AccountID = 0,
|
||||
AccountPublic = 35,
|
||||
AccountSecret = 34,
|
||||
FamilyGenerator = 41, // unused
|
||||
FamilySeed = 33
|
||||
};
|
||||
|
||||
template <class T>
|
||||
[[nodiscard]] std::optional<T>
|
||||
parseBase58(std::string const& s);
|
||||
|
||||
template <class T>
|
||||
[[nodiscard]] std::optional<T>
|
||||
parseBase58(TokenType type, std::string const& s);
|
||||
|
||||
/** Encode data in Base58Check format using XRPL alphabet
|
||||
|
||||
For details on the format see
|
||||
https://xrpl.org/base58-encodings.html#base58-encodings
|
||||
|
||||
@param type The type of token to encode.
|
||||
@param token Pointer to the data to encode.
|
||||
@param size The size of the data to encode.
|
||||
|
||||
@return the encoded token.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
encodeBase58Token(TokenType type, void const* token, std::size_t size);
|
||||
|
||||
[[nodiscard]] std::string
|
||||
decodeBase58Token(std::string const& s, TokenType type);
|
||||
|
||||
namespace b58_ref {
|
||||
// The reference version does not use gcc extensions (int128 in particular)
|
||||
[[nodiscard]] std::string
|
||||
encodeBase58Token(TokenType type, void const* token, std::size_t size);
|
||||
|
||||
[[nodiscard]] std::string
|
||||
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);
|
||||
|
||||
std::string
|
||||
decodeBase58(std::string const& s);
|
||||
} // namespace detail
|
||||
} // namespace b58_ref
|
||||
|
||||
#ifndef _MSC_VER
|
||||
namespace b58_fast {
|
||||
// Use the fast version (10-15x faster) is using gcc extensions (int128 in
|
||||
// particular)
|
||||
[[nodiscard]] B58Result<std::span<std::uint8_t>>
|
||||
encodeBase58Token(
|
||||
TokenType token_type,
|
||||
std::span<std::uint8_t const> input,
|
||||
std::span<std::uint8_t> out);
|
||||
|
||||
[[nodiscard]] B58Result<std::span<std::uint8_t>>
|
||||
decodeBase58Token(
|
||||
TokenType type,
|
||||
std::string_view s,
|
||||
std::span<std::uint8_t> outBuf);
|
||||
|
||||
// This interface matches the old interface, but requires additional allocation
|
||||
[[nodiscard]] std::string
|
||||
encodeBase58Token(TokenType type, void const* token, std::size_t size);
|
||||
|
||||
// This interface matches the old interface, but requires additional allocation
|
||||
[[nodiscard]] std::string
|
||||
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);
|
||||
|
||||
B58Result<std::span<std::uint8_t>>
|
||||
b58_to_b256_be(std::string_view input, std::span<std::uint8_t> out);
|
||||
} // namespace detail
|
||||
|
||||
} // namespace b58_fast
|
||||
#endif // _MSC_VER
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user