mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 15:28:03 +00:00
Merge upstream/ripple/smart-escrow into xrplf/smart-contracts
Upstream rewrote the wasm VM and host-function system (Rust `crates/` bridged via cxx), collapsed `transactions.macro` onto `TxSettings`, and moved invariant running from `ApplyContext` to `Transactor`. This merge resolves those conflicts and the breaks that carried no conflict marker. Conflict resolutions of note: - transactions.macro: took upstream's 5-argument `TxSettings` form and re-expressed our `emitable` column as `TxSettings::emittance`, a new scoped `Emittance` enum in TxSettings.h. `Emitable.cpp` and the transaction code generator read the new member. - sfields.macro: upstream claimed UINT32 75-80, so `sfParameterFlag` moves from 80 to 86. The amendment is not live, so no wire break. - HostFunc.h: took upstream's version, which drops `floatRoot`, and re-added the 15 contract virtuals. `setDataNestedObjectField`'s parameters are renamed to `(account, key, nestedKey, value)` to match the implementation; the wire order is unchanged. - WasmCommon.h: `SubmitTxnFailure` (-21) and `InvalidState` (-22) join upstream's enum and the Rust `host_errors!` table. `Success` is gone; the helpers that compared against it now return `expected<void, ...>`. - Transactor.cpp: kept the emitted-transaction pass, now using `checkInvariants(result, fee, InvariantScope::ProtocolOnly)`. Breaks with no conflict marker: - `Emitable.cpp` used the 8-argument TRANSACTION macro. - `STTx::getSeqValue` is gone; use `getSeqProxy().value()`. - `NetworkOPsImp::subLock_` is now `streamLock_`, held with `scoped_lock`. - The `LedgerEntryHelpers` namespace is now `ledger_entry_helpers`. - `keylet::vault` takes a `SeqProxy`. The three contract `ledger_entry` parsers were copy-pasted from the vault one and returned vault keylets; they now build contract, contract source and contract data keylets from their own fields. `contract_hash` is added to jss. The 15 contract host functions still register through the deleted C++ wrapper layer, so contract bytecode does not run yet. Porting them to the Rust-declared ABI is the next commit.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -13,6 +13,6 @@ namespace xrpl {
|
||||
* @throws runtime_error
|
||||
*/
|
||||
void
|
||||
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst);
|
||||
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
@@ -156,6 +157,19 @@ public:
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Set every byte in the buffer to the given value.
|
||||
*
|
||||
* The size is unchanged, and this is a no-op on an empty buffer.
|
||||
*
|
||||
* @param value the byte to write to every position.
|
||||
*/
|
||||
void
|
||||
fill(std::uint8_t value) noexcept
|
||||
{
|
||||
std::fill_n(p_.get(), size_, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the buffer.
|
||||
* All memory is deallocated. The resulting size is 0.
|
||||
@@ -226,10 +240,4 @@ operator==(Buffer const& lhs, Buffer const& rhs) noexcept
|
||||
return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Buffer const& lhs, Buffer const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,24 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
std::string
|
||||
getFileContents(
|
||||
boost::system::error_code& ec,
|
||||
boost::filesystem::path const& sourcePath,
|
||||
std::error_code& ec,
|
||||
std::filesystem::path const& sourcePath,
|
||||
std::optional<std::size_t> maxSize = std::nullopt);
|
||||
|
||||
void
|
||||
writeFileContents(
|
||||
boost::system::error_code& ec,
|
||||
boost::filesystem::path const& destPath,
|
||||
std::error_code& ec,
|
||||
std::filesystem::path const& destPath,
|
||||
std::string const& contents);
|
||||
|
||||
/**
|
||||
* Generate a unique, non-existing path under @p base whose filename starts with
|
||||
* @p prefix and ends with a random hex suffix.
|
||||
*
|
||||
* Attempts up to @p maxAttempts paths. Throws `std::runtime_error` if a unique
|
||||
* path cannot be found or if the filesystem returns an error while checking for
|
||||
* existence.
|
||||
*/
|
||||
std::filesystem::path
|
||||
uniqueRandomPath(
|
||||
std::filesystem::path const& base,
|
||||
std::string const& prefix = "",
|
||||
std::size_t maxAttempts = 100);
|
||||
|
||||
/**
|
||||
* RAII temporary directory.
|
||||
*
|
||||
* The directory and all its contents are deleted when
|
||||
* the instance of `TempDir` is destroyed.
|
||||
*/
|
||||
class TempDir
|
||||
{
|
||||
std::filesystem::path path_;
|
||||
|
||||
public:
|
||||
#if !GENERATING_DOCS
|
||||
TempDir(TempDir const&) = delete;
|
||||
TempDir&
|
||||
operator=(TempDir const&) = delete;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Construct a temporary directory.
|
||||
*/
|
||||
TempDir();
|
||||
|
||||
/**
|
||||
* Destroy a temporary directory.
|
||||
*/
|
||||
~TempDir();
|
||||
|
||||
/**
|
||||
* Get the native path for the temporary directory.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
path() const;
|
||||
|
||||
/**
|
||||
* Get the native path for a file.
|
||||
*
|
||||
* The file does not need to exist.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
file(std::string const& name) const;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -96,9 +96,6 @@ public:
|
||||
SharedIntrusive&
|
||||
operator=(SharedIntrusive const& rhs);
|
||||
|
||||
bool
|
||||
operator!=(std::nullptr_t) const;
|
||||
|
||||
bool
|
||||
operator==(std::nullptr_t) const;
|
||||
|
||||
|
||||
@@ -111,13 +111,6 @@ SharedIntrusive<T>::operator=(SharedIntrusive<TT>&& rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool
|
||||
SharedIntrusive<T>::operator!=(std::nullptr_t) const
|
||||
{
|
||||
return this->get() != nullptr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool
|
||||
SharedIntrusive<T>::operator==(std::nullptr_t) const
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -84,7 +84,7 @@ private:
|
||||
* @return `true` if the file was opened.
|
||||
*/
|
||||
bool
|
||||
open(boost::filesystem::path const& path);
|
||||
open(std::filesystem::path const& path);
|
||||
|
||||
/**
|
||||
* Close and re-open the system file associated with the log
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::ofstream> stream_;
|
||||
boost::filesystem::path path_;
|
||||
std::filesystem::path path_;
|
||||
};
|
||||
|
||||
std::mutex mutable mutex_;
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
virtual ~Logs() = default;
|
||||
|
||||
bool
|
||||
open(boost::filesystem::path const& pathToLogFile);
|
||||
open(std::filesystem::path const& pathToLogFile);
|
||||
|
||||
beast::Journal::Sink&
|
||||
get(std::string const& name);
|
||||
|
||||
@@ -85,12 +85,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator!=(SHAMapHash const& x, SHAMapHash const& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::size_t
|
||||
extract(SHAMapHash const& key)
|
||||
|
||||
@@ -208,12 +208,6 @@ operator==(Slice const& lhs, Slice const& rhs) noexcept
|
||||
return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Slice const& lhs, Slice const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(Slice const& lhs, Slice const& rhs) noexcept
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Blob.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
|
||||
#include <array>
|
||||
@@ -125,9 +124,31 @@ struct ParsedUrl
|
||||
bool
|
||||
parseUrl(ParsedUrl& pUrl, std::string const& strUrl);
|
||||
|
||||
/**
|
||||
* Remove leading and trailing ASCII whitespace.
|
||||
*
|
||||
* Whitespace is the fixed set " \t\n\v\f\r"; the current locale is not
|
||||
* consulted, so the result depends only on the input.
|
||||
*
|
||||
* @param str The string to trim.
|
||||
* @return @p str without leading or trailing whitespace.
|
||||
*/
|
||||
std::string
|
||||
trimWhitespace(std::string str);
|
||||
|
||||
/**
|
||||
* Fold ASCII upper case letters to lower case.
|
||||
*
|
||||
* Only 'A' through 'Z' are remapped; every other byte is left alone and the
|
||||
* current locale is not consulted, so the result depends only on the input.
|
||||
*
|
||||
* @param str The string to fold.
|
||||
* @return @p str with each ASCII upper case letter replaced by its lower case
|
||||
* equivalent.
|
||||
*/
|
||||
std::string
|
||||
toLower(std::string str);
|
||||
|
||||
std::optional<std::uint64_t>
|
||||
toUInt64(std::string const& s);
|
||||
|
||||
|
||||
@@ -116,12 +116,6 @@ public:
|
||||
{
|
||||
return lhs.map == rhs.map && lhs.ait == rhs.ait && lhs.mit == rhs.mit;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(Iterator const& lhs, Iterator const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
struct ConstIterator
|
||||
@@ -189,12 +183,6 @@ public:
|
||||
{
|
||||
return lhs.map == rhs.map && lhs.ait == rhs.ait && lhs.mit == rhs.mit;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(ConstIterator const& lhs, ConstIterator const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -1038,25 +1038,6 @@ public:
|
||||
Compare,
|
||||
OtherAllocator> const& other) const;
|
||||
|
||||
template <
|
||||
bool OtherIsMulti,
|
||||
bool OtherIsMap,
|
||||
class OtherT,
|
||||
class OtherDuration,
|
||||
class OtherAllocator>
|
||||
bool
|
||||
operator!=(AgedOrderedContainer<
|
||||
OtherIsMulti,
|
||||
OtherIsMap,
|
||||
Key,
|
||||
OtherT,
|
||||
OtherDuration,
|
||||
Compare,
|
||||
OtherAllocator> const& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
template <
|
||||
bool OtherIsMulti,
|
||||
bool OtherIsMap,
|
||||
|
||||
@@ -1340,28 +1340,6 @@ public:
|
||||
OtherAllocator> const& other) const
|
||||
requires MaybeMulti;
|
||||
|
||||
template <
|
||||
bool OtherIsMulti,
|
||||
bool OtherIsMap,
|
||||
class OtherKey,
|
||||
class OtherT,
|
||||
class OtherDuration,
|
||||
class OtherHash,
|
||||
class OtherAllocator>
|
||||
bool
|
||||
operator!=(AgedUnorderedContainer<
|
||||
OtherIsMulti,
|
||||
OtherIsMap,
|
||||
OtherKey,
|
||||
OtherT,
|
||||
OtherDuration,
|
||||
OtherHash,
|
||||
KeyEqual,
|
||||
OtherAllocator> const& other) const
|
||||
{
|
||||
return !(this->operator==(other));
|
||||
}
|
||||
|
||||
private:
|
||||
bool
|
||||
wouldExceed(size_type additional) const
|
||||
|
||||
@@ -82,13 +82,6 @@ public:
|
||||
return node_ == other.node_;
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
bool
|
||||
operator!=(ListIterator<M> const& other) const noexcept
|
||||
{
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const noexcept
|
||||
{
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace boost {
|
||||
template <>
|
||||
struct hash<::beast::ip::Address>
|
||||
{
|
||||
explicit hash() = default;
|
||||
hash() = default;
|
||||
|
||||
std::size_t
|
||||
operator()(::beast::ip::Address const& addr) const
|
||||
|
||||
@@ -110,12 +110,6 @@ public:
|
||||
operator==(Endpoint const& lhs, Endpoint const& rhs);
|
||||
friend bool
|
||||
operator<(Endpoint const& lhs, Endpoint const& rhs);
|
||||
|
||||
friend bool
|
||||
operator!=(Endpoint const& lhs, Endpoint const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
friend bool
|
||||
operator>(Endpoint const& lhs, Endpoint const& rhs)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace beast::rfc2616 {
|
||||
@@ -186,7 +187,7 @@ splitCommas(FwdIt first, FwdIt last)
|
||||
|
||||
template <class Result = std::vector<std::string>>
|
||||
Result
|
||||
splitCommas(boost::beast::string_view const& s)
|
||||
splitCommas(std::string_view s)
|
||||
{
|
||||
return splitCommas(s.begin(), s.end());
|
||||
}
|
||||
@@ -229,12 +230,6 @@ public:
|
||||
return other.it_ == it_ && other.end_ == end_ && other.value_.size() == value_.size();
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(ListIterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <xrpl/beast/unit_test/runner.h>
|
||||
#include <xrpl/beast/unit_test/suite_info.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -188,7 +187,7 @@ Reporter<Unused>::fmtdur(clock_type::duration const& d)
|
||||
using namespace std::chrono;
|
||||
auto const ms = duration_cast<milliseconds>(d);
|
||||
if (ms < seconds{1})
|
||||
return boost::lexical_cast<std::string>(ms.count()) + "ms";
|
||||
return std::to_string(ms.count()) + "ms";
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(1) << (ms.count() / 1000.) << "s";
|
||||
return ss.str();
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
|
||||
#include <xrpl/beast/unit_test/runner.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
@@ -27,10 +26,10 @@ makeReason(String const& reason, char const* file, int line)
|
||||
std::string s(reason);
|
||||
if (!s.empty())
|
||||
s.append(": ");
|
||||
namespace fs = boost::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
s.append(fs::path{file}.filename().string());
|
||||
s.append("(");
|
||||
s.append(boost::lexical_cast<std::string>(line));
|
||||
s.append(std::to_string(line));
|
||||
s.append(")");
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/**
|
||||
* RAII temporary directory.
|
||||
*
|
||||
* The directory and all its contents are deleted when
|
||||
* the instance of `temp_dir` is destroyed.
|
||||
*/
|
||||
class TempDir
|
||||
{
|
||||
boost::filesystem::path path_;
|
||||
|
||||
public:
|
||||
#if !GENERATING_DOCS
|
||||
TempDir(TempDir const&) = delete;
|
||||
TempDir&
|
||||
operator=(TempDir const&) = delete;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Construct a temporary directory.
|
||||
*/
|
||||
TempDir()
|
||||
{
|
||||
auto const dir = boost::filesystem::temp_directory_path();
|
||||
do
|
||||
{
|
||||
path_ = dir / boost::filesystem::unique_path();
|
||||
} while (boost::filesystem::exists(path_));
|
||||
boost::filesystem::create_directory(path_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a temporary directory.
|
||||
*/
|
||||
~TempDir()
|
||||
{
|
||||
// use non-throwing calls in the destructor
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::remove_all(path_, ec);
|
||||
// TODO: warn/notify if ec set ?
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native path for the temporary directory
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
path() const
|
||||
{
|
||||
return path_.string();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native path for the a file.
|
||||
*
|
||||
* The file does not need to exist.
|
||||
*/
|
||||
[[nodiscard]] std::string
|
||||
file(std::string const& name) const
|
||||
{
|
||||
return (path_ / name).string();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
@@ -92,10 +92,4 @@ operator==(Condition const& lhs, Condition const& rhs)
|
||||
lhs.fingerprint == rhs.fingerprint;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Condition const& lhs, Condition const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace xrpl::cryptoconditions
|
||||
|
||||
@@ -93,12 +93,6 @@ operator==(Fulfillment const& lhs, Fulfillment const& rhs)
|
||||
lhs.fingerprint() == rhs.fingerprint();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(Fulfillment const& lhs, Fulfillment const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given fulfillment and condition match
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -128,6 +128,7 @@ struct Keys
|
||||
static constexpr auto kMaximumTxnInLedger = "maximum_txn_in_ledger";
|
||||
static constexpr auto kMaximumTxnPerAccount = "maximum_txn_per_account";
|
||||
static constexpr auto kMemoryLevel = "memory_level";
|
||||
static constexpr auto kMaxWaitingLedgers = "max_waiting_ledgers";
|
||||
static constexpr auto kMinLedgersToComputeSizeLimit = "min_ledgers_to_compute_size_limit";
|
||||
static constexpr auto kMinimumEscalationMultiplier = "minimum_escalation_multiplier";
|
||||
static constexpr auto kMinimumLastLedgerBuffer = "minimum_last_ledger_buffer";
|
||||
|
||||
@@ -34,7 +34,10 @@ enum class HashRouterFlags : std::uint16_t {
|
||||
PRIVATE4 = 0x0800,
|
||||
// Used in EscrowFinish.cpp
|
||||
PRIVATE5 = 0x1000,
|
||||
PRIVATE6 = 0x2000
|
||||
PRIVATE6 = 0x2000,
|
||||
// Used in apply.cpp
|
||||
PRIVATE7 = 0x4000,
|
||||
PRIVATE8 = 0x8000
|
||||
};
|
||||
|
||||
constexpr HashRouterFlags
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
#include <xrpl/core/Job.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -44,7 +43,7 @@ public:
|
||||
*/
|
||||
struct Setup
|
||||
{
|
||||
boost::filesystem::path perfLog;
|
||||
std::filesystem::path perfLog;
|
||||
// log_interval is in milliseconds to support faster testing.
|
||||
milliseconds logInterval{seconds(1)};
|
||||
};
|
||||
@@ -149,7 +148,7 @@ public:
|
||||
};
|
||||
|
||||
PerfLog::Setup
|
||||
setupPerfLog(Section const& section, boost::filesystem::path const& configDir);
|
||||
setupPerfLog(Section const& section, std::filesystem::path const& configDir);
|
||||
|
||||
std::unique_ptr<PerfLog>
|
||||
makePerfLog(
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace json {
|
||||
|
||||
class Value;
|
||||
|
||||
using Output = std::function<void(boost::beast::string_view const&)>;
|
||||
using Output = std::function<void(std::string_view)>;
|
||||
|
||||
inline Output
|
||||
stringOutput(std::string& s)
|
||||
{
|
||||
return [&](boost::beast::string_view const& b) { s.append(b.data(), b.size()); };
|
||||
return [&](std::string_view b) { s.append(b.data(), b.size()); };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/json/json_forwards.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -72,36 +73,18 @@ operator==(StaticString x, StaticString y)
|
||||
return strcmp(x.cStr(), y.cStr()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(StaticString x, StaticString y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(std::string const& x, StaticString y)
|
||||
{
|
||||
return strcmp(x.c_str(), y.cStr()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(std::string const& x, StaticString y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(StaticString x, std::string const& y)
|
||||
{
|
||||
return y == x;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(StaticString x, std::string const& y)
|
||||
{
|
||||
return !(y == x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Represents a <a HREF="http://www.json.org">JSON</a> value.
|
||||
*
|
||||
@@ -489,12 +472,6 @@ toJson(xrpl::Number const& number)
|
||||
bool
|
||||
operator==(Value const&, Value const&);
|
||||
|
||||
inline bool
|
||||
operator!=(Value const& x, Value const& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(Value const&, Value const&);
|
||||
|
||||
@@ -548,6 +525,7 @@ public:
|
||||
class ValueIteratorBase
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using size_t = unsigned int;
|
||||
using difference_type = int;
|
||||
using SelfType = ValueIteratorBase;
|
||||
@@ -562,12 +540,6 @@ public:
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(SelfType const& other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return either the index or the member name of the referenced value as a
|
||||
* Value.
|
||||
|
||||
@@ -49,12 +49,6 @@ public:
|
||||
bool
|
||||
operator==(const_iterator const& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const_iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const;
|
||||
|
||||
|
||||
@@ -59,12 +59,6 @@ private:
|
||||
return lhs.txId_ == rhs.txId_;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(Key const& lhs, Key const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] uint256 const&
|
||||
getAccount() const
|
||||
{
|
||||
|
||||
@@ -59,12 +59,6 @@ public:
|
||||
bool
|
||||
operator==(ConstIterator const& other) const;
|
||||
|
||||
bool
|
||||
operator!=(ConstIterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -39,6 +40,11 @@ enum class SkipEntry : bool { No = false, Yes };
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Whether an expiration check should be inclusive or exclusive.
|
||||
*/
|
||||
enum class ExpiryComparison { Inclusive, Exclusive };
|
||||
|
||||
/**
|
||||
* Determines whether the given expiration time has passed.
|
||||
*
|
||||
@@ -58,11 +64,16 @@ enum class SkipEntry : bool { No = false, Yes };
|
||||
*
|
||||
* @param view The ledger whose parent time is used as the clock.
|
||||
* @param exp The optional expiration time we want to check.
|
||||
* @param comparison Whether the boundary is inclusive (`now >= exp`, the
|
||||
* default) or exclusive (`now > exp`).
|
||||
*
|
||||
* @return `true` if `exp` is in the past; `false` otherwise.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
hasExpired(ReadView const& view, std::optional<std::uint32_t> const& exp);
|
||||
hasExpired(
|
||||
ReadView const& view,
|
||||
std::optional<std::uint32_t> const& exp,
|
||||
ExpiryComparison comparison = ExpiryComparison::Inclusive);
|
||||
|
||||
// Note, depth parameter is used to limit the recursion depth
|
||||
[[nodiscard]] bool
|
||||
@@ -72,6 +83,13 @@ isVaultPseudoAccountFrozen(
|
||||
MPTIssue const& mptShare,
|
||||
std::uint8_t depth);
|
||||
|
||||
[[nodiscard]] bool
|
||||
isVaultPseudoAccountFrozen(
|
||||
ReadView const& view,
|
||||
AccountID const& account,
|
||||
SLE const& issuanceSle,
|
||||
std::uint8_t depth);
|
||||
|
||||
[[nodiscard]] bool
|
||||
isLPTokenFrozen(
|
||||
ReadView const& view,
|
||||
@@ -79,6 +97,26 @@ isLPTokenFrozen(
|
||||
Asset const& asset,
|
||||
Asset const& asset2);
|
||||
|
||||
/**
|
||||
* Check whether an AMM LPToken may be transferred between @p from and @p to.
|
||||
*
|
||||
* @p lpTokenIssuer is the issuer of the LPToken being moved. If it is not an
|
||||
* AMM account the token is not an LPToken and the transfer is unconditionally
|
||||
* permitted. Otherwise, for each MPT pool asset of that AMM, canTransfer() must
|
||||
* permit the transfer (which exempts the MPT issuer). Non-MPT pool assets are
|
||||
* always transferable by this check, so it is implicitly gated by
|
||||
* featureMPTokensV2 (MPTs can only be AMM pool assets once V2 is enabled).
|
||||
*
|
||||
* @return tesSUCCESS if permitted, otherwise the canTransfer() failure code
|
||||
* (e.g. tecNO_AUTH) of the first MPT pool asset that disallows it.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
canTransferLPToken(
|
||||
ReadView const& view,
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
AccountID const& lpTokenIssuer);
|
||||
|
||||
// Return the list of enabled amendments
|
||||
[[nodiscard]] std::set<uint256>
|
||||
getEnabledAmendments(ReadView const& view);
|
||||
@@ -165,7 +203,10 @@ dirLink(
|
||||
* if withdrawing to self.
|
||||
* - If withdrawing to self, succeed.
|
||||
* - If not, checks if the receiver requires deposit authorization, and if
|
||||
* the sender has it.
|
||||
* the sender has it (account-based or credential-based).
|
||||
* - Expects any credentials passed in to already exist in the ledger, and
|
||||
* returns an internal error otherwise. Validate them beforehand with
|
||||
* credentials::valid().
|
||||
* - Checks that the receiver will not exceed the limit (IOU trustline limit
|
||||
* or MPT MaximumAmount).
|
||||
*/
|
||||
@@ -176,7 +217,8 @@ canWithdraw(
|
||||
AccountID const& to,
|
||||
SLE::const_ref toSle,
|
||||
STAmount const& amount,
|
||||
bool hasDestinationTag);
|
||||
bool hasDestinationTag,
|
||||
std::optional<std::vector<uint256>> const& credentialIDs = std::nullopt);
|
||||
|
||||
/**
|
||||
* Checks that can withdraw funds from an object to itself or a destination.
|
||||
@@ -189,7 +231,10 @@ canWithdraw(
|
||||
* if withdrawing to self.
|
||||
* - If withdrawing to self, succeed.
|
||||
* - If not, checks if the receiver requires deposit authorization, and if
|
||||
* the sender has it.
|
||||
* the sender has it (account-based or credential-based).
|
||||
* - Expects any credentials passed in to already exist in the ledger, and
|
||||
* returns an internal error otherwise. Validate them beforehand with
|
||||
* credentials::valid().
|
||||
* - Checks that the receiver will not exceed the limit (IOU trustline limit
|
||||
* or MPT MaximumAmount).
|
||||
*/
|
||||
@@ -199,20 +244,25 @@ canWithdraw(
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
STAmount const& amount,
|
||||
bool hasDestinationTag);
|
||||
bool hasDestinationTag,
|
||||
std::optional<std::vector<uint256>> const& credentialIDs = std::nullopt);
|
||||
|
||||
/**
|
||||
* Checks that can withdraw funds from an object to itself or a destination.
|
||||
*
|
||||
* The receiver may be either the submitting account (sfAccount) or a different
|
||||
* destination account (sfDestination).
|
||||
* destination account (sfDestination). Credentials, if any, are taken from the
|
||||
* transaction's sfCredentialIDs field.
|
||||
*
|
||||
* - Checks that the receiver account exists.
|
||||
* - If the receiver requires a destination tag, check that one exists, even
|
||||
* if withdrawing to self.
|
||||
* - If withdrawing to self, succeed.
|
||||
* - If not, checks if the receiver requires deposit authorization, and if
|
||||
* the sender has it.
|
||||
* the sender has it (account-based or credential-based).
|
||||
* - Expects any credentials in sfCredentialIDs to already exist in the
|
||||
* ledger, and returns an internal error otherwise. Validate them
|
||||
* beforehand with credentials::valid().
|
||||
* - Checks that the receiver will not exceed the limit (IOU trustline limit
|
||||
* or MPT MaximumAmount).
|
||||
*/
|
||||
|
||||
@@ -85,9 +85,6 @@ public:
|
||||
bool
|
||||
operator==(Iterator const& other) const;
|
||||
|
||||
bool
|
||||
operator!=(Iterator const& other) const;
|
||||
|
||||
// Can throw
|
||||
reference
|
||||
operator*() const;
|
||||
|
||||
@@ -64,13 +64,6 @@ ReadViewFwdRange<ValueType>::Iterator::operator==(Iterator const& other) const
|
||||
return impl_ == other.impl_;
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
bool
|
||||
ReadViewFwdRange<ValueType>::Iterator::operator!=(Iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
auto
|
||||
ReadViewFwdRange<ValueType>::Iterator::operator*() const -> reference
|
||||
|
||||
@@ -226,7 +226,7 @@ getAMMOfferStartWithTakerGets(
|
||||
|
||||
auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerGets is XRP.
|
||||
// This has the most impact when takerGets is integral.
|
||||
auto const takerGets =
|
||||
toAmount<TOut>(getAsset(pool.out), nTakerGetsProposed, Number::RoundingMode::Downward);
|
||||
return TAmounts<TIn, TOut>{swapAssetOut(pool, takerGets, tfee), takerGets};
|
||||
@@ -294,7 +294,7 @@ getAMMOfferStartWithTakerPays(
|
||||
|
||||
auto getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
|
||||
// Round downward to minimize the offer and to maximize the quality.
|
||||
// This has the most impact when takerPays is XRP.
|
||||
// This has the most impact when takerPays is integral.
|
||||
auto const takerPays =
|
||||
toAmount<TIn>(getAsset(pool.in), nTakerPaysProposed, Number::RoundingMode::Downward);
|
||||
return TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
|
||||
@@ -313,11 +313,11 @@ getAMMOfferStartWithTakerPays(
|
||||
* is equal to LOB quality (in this case AMM offer quality is
|
||||
* better than LOB quality) or AMM offer is equal to LOB quality
|
||||
* (in this case SPQ is better than LOB quality).
|
||||
* Pre-amendment code calculates takerPays first. If takerGets is XRP,
|
||||
* it is rounded down, which results in worse offer quality than
|
||||
* LOB quality, and the offer might fail to generate.
|
||||
* Post-amendment code calculates the XRP offer side first. The result
|
||||
* is rounded down, which makes the offer quality better.
|
||||
* Pre-amendment code calculates takerPays first. If takerGets is the
|
||||
* economically coarser integral side, it is rounded down, which results in
|
||||
* worse offer quality than LOB quality, and the offer might fail to generate.
|
||||
* Post-amendment code calculates the economically coarser integral offer side
|
||||
* first. The result is rounded down, which makes the offer quality better.
|
||||
* It might not be possible to match either SPQ or AMM offer to LOB
|
||||
* quality. This generally happens at higher fees.
|
||||
* @param pool AMM pool balances
|
||||
@@ -396,10 +396,18 @@ changeSpotPriceQuality(
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Generate the offer starting with XRP side. Return seated offer amounts
|
||||
// if the offer can be generated, otherwise nullopt.
|
||||
auto amounts = [&]() {
|
||||
if (isXRP(getAsset(pool.out)))
|
||||
bool const inIntegral = getAsset(pool.in).integral();
|
||||
bool const outIntegral = getAsset(pool.out).integral();
|
||||
|
||||
// Preserve historical behavior for fractional pairs and XRP/IOU-style
|
||||
// one-integral-side pairs. For two integral assets, pick the side whose
|
||||
// minimum unit is economically coarser at this quality.
|
||||
//
|
||||
// Quality::rate() is input units per output unit, so one output unit is
|
||||
// coarser when it costs at least one input unit. Ties use takerGets,
|
||||
// matching the historical XRP-output behavior.
|
||||
if (outIntegral && (!inIntegral || Number(quality.rate()) >= 1))
|
||||
return getAMMOfferStartWithTakerGets(pool, quality, tfee);
|
||||
return getAMMOfferStartWithTakerPays(pool, quality, tfee);
|
||||
}();
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -353,14 +352,14 @@ pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey);
|
||||
*
|
||||
* The list is constructed during initialization and is const after that.
|
||||
* Pseudo-account designator fields MUST be maintained by including the
|
||||
* SField::sMD_PseudoAccount flag in the SField definition.
|
||||
* SField::kSmdPseudoAccount flag in the SField definition.
|
||||
*/
|
||||
[[nodiscard]] std::vector<SField const*> const&
|
||||
getPseudoAccountFields();
|
||||
|
||||
/**
|
||||
* Returns true if and only if sleAcct is a pseudo-account or specific
|
||||
* pseudo-accounts in pseudoFieldFilter.
|
||||
* Returns true if and only if sleAcct is a pseudo-account of any kind
|
||||
* (i.e. carries at least one field flagged with SField::kSmdPseudoAccount).
|
||||
*
|
||||
* Returns false if sleAcct is:
|
||||
* - NOT a pseudo-account OR
|
||||
@@ -368,18 +367,15 @@ getPseudoAccountFields();
|
||||
* - null pointer
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});
|
||||
isPseudoAccount(SLE::const_pointer sleAcct);
|
||||
|
||||
/**
|
||||
* Convenience overload that reads the account from the view.
|
||||
*/
|
||||
[[nodiscard]] inline bool
|
||||
isPseudoAccount(
|
||||
ReadView const& view,
|
||||
AccountID const& accountId,
|
||||
std::set<SField const*> const& pseudoFieldFilter = {})
|
||||
isPseudoAccount(ReadView const& view, AccountID const& accountId)
|
||||
{
|
||||
return isPseudoAccount(view.read(keylet::account(accountId)), pseudoFieldFilter);
|
||||
return isPseudoAccount(view.read(keylet::account(accountId)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,25 +29,39 @@ class ContractEventMap : public std::map<std::string, STJson>
|
||||
|
||||
namespace contract {
|
||||
|
||||
/** The maximum number of data modifications in a single function. */
|
||||
/**
|
||||
* The maximum number of data modifications in a single function.
|
||||
*/
|
||||
int64_t constexpr maxDataModifications = 1000;
|
||||
|
||||
/** The maximum number of bytes the data can occupy. */
|
||||
/**
|
||||
* The maximum number of bytes the data can occupy.
|
||||
*/
|
||||
int64_t constexpr maxContractDataSize = 1024;
|
||||
|
||||
/** The multiplier for contract data size calculations. */
|
||||
/**
|
||||
* The multiplier for contract data size calculations.
|
||||
*/
|
||||
int64_t constexpr dataByteMultiplier = 512;
|
||||
|
||||
/** The cost multiplier of creating a contract in bytes. */
|
||||
/**
|
||||
* The cost multiplier of creating a contract in bytes.
|
||||
*/
|
||||
int64_t constexpr createByteMultiplier = 500ULL;
|
||||
|
||||
/** The value to return when the fee calculation failed. */
|
||||
/**
|
||||
* The value to return when the fee calculation failed.
|
||||
*/
|
||||
int64_t constexpr feeCalculationFailed = 0x7FFFFFFFFFFFFFFFLL;
|
||||
|
||||
/** The maximum number of contract parameters that can be in a transaction. */
|
||||
/**
|
||||
* The maximum number of contract parameters that can be in a transaction.
|
||||
*/
|
||||
std::size_t constexpr maxContractParams = 8;
|
||||
|
||||
/** The maximum number of contract functions that can be in a transaction. */
|
||||
/**
|
||||
* The maximum number of contract functions that can be in a transaction.
|
||||
*/
|
||||
std::size_t constexpr maxContractFunctions = 32;
|
||||
|
||||
int64_t
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
@@ -34,7 +35,7 @@ deleteSLE(ApplyView& view, SLE::ref sleCredential, beast::Journal j);
|
||||
|
||||
// Amendment and parameters checks for sfCredentialIDs field
|
||||
NotTEC
|
||||
checkFields(STTx const& tx, beast::Journal j);
|
||||
checkFields(STTx const& tx, Rules const& rules, beast::Journal j);
|
||||
|
||||
// Accessing the ledger to check if provided credentials are valid. Do not use
|
||||
// in doApply (only in preclaim) since it does not remove expired credentials.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
@@ -21,6 +22,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
@@ -58,6 +60,42 @@ canApplyToBrokerCover(
|
||||
bool
|
||||
checkLendingProtocolDependencies(Rules const& rules, STTx const& tx);
|
||||
|
||||
/**
|
||||
* The accounts and asset that LoanManage::defaultLoan's fixCleanup3_4_0
|
||||
* freeze/lock exemption applies to.
|
||||
*
|
||||
* `defaultLoan` moves funds from the LoanBroker pseudo-account to the Vault
|
||||
* pseudo-account via `accountSend`. Since neither is the vault asset's
|
||||
* issuer, this is a third-party transfer that transits through the issuer in
|
||||
* two hops (broker -> issuer, issuer -> vault; see
|
||||
* `directSendNoLimitIOU`/`directSendNoLimitMPT`), so the exemption must cover
|
||||
* both the issuer/broker and issuer/vault pairs, not a direct broker/vault
|
||||
* pair. `asset` scopes it further to the vault's own currency/MPT issuance,
|
||||
* so an unrelated one the same accounts happen to hold is still protected.
|
||||
*/
|
||||
struct LoanDefaultFreezeExemptAccounts
|
||||
{
|
||||
AccountID issuer;
|
||||
AccountID broker;
|
||||
AccountID vault;
|
||||
Asset asset;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves the accounts and asset a LoanManage default transaction is
|
||||
* exempt from freeze/lock for.
|
||||
*
|
||||
* @param view Ledger view used to resolve the Loan -> LoanBroker -> Vault
|
||||
* chain.
|
||||
* @param tx The transaction under invariant review.
|
||||
* @return The exempt accounts and asset if `tx` is a `ttLOAN_MANAGE`
|
||||
* transaction with the `tfLoanDefault` flag set, `fixCleanup3_4_0` is
|
||||
* enabled, and the loan/broker/vault objects it references can all be
|
||||
* resolved; `std::nullopt` otherwise.
|
||||
*/
|
||||
[[nodiscard]] std::optional<LoanDefaultFreezeExemptAccounts>
|
||||
getLoanDefaultFreezeExemptAccounts(ReadView const& view, STTx const& tx);
|
||||
|
||||
static constexpr std::uint32_t kSecondsInYear = 365 * 24 * 60 * 60;
|
||||
|
||||
Number
|
||||
@@ -286,6 +324,12 @@ computeFullPaymentInterest(
|
||||
std::uint32_t startDate,
|
||||
TenthBips32 closeInterestRate);
|
||||
|
||||
// Returns true if the loan's next payment is late per protocol rules. The
|
||||
// boundary is amendment-gated: with fixCleanup3_4_0 the due date must be
|
||||
// strictly in the past, otherwise the exact due-date instant counts as late.
|
||||
[[nodiscard]] bool
|
||||
isPaymentLate(ReadView const& view, SLE::const_ref loanSle);
|
||||
|
||||
// Deltas applied to Vault.AssetsTotal and LoanBroker.DebtTotal at a single
|
||||
// accounting touch point (origination, payment, impair/unimpair/default).
|
||||
struct AccountingDeltas
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace xrpl {
|
||||
[[nodiscard]] bool
|
||||
isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue);
|
||||
|
||||
[[nodiscard]] bool
|
||||
isGlobalFrozen(SLE const& issuanceSle);
|
||||
|
||||
/**
|
||||
* Returns true if @p account's MPToken for @p mptIssue carries the
|
||||
* individual-lock flag (lsfMPTLocked).
|
||||
@@ -40,9 +43,29 @@ isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue);
|
||||
* receive tokens — it combines isIndividualFrozen, isGlobalFrozen, and
|
||||
* isVaultPseudoAccountFrozen into a single complete check.
|
||||
*/
|
||||
|
||||
[[nodiscard]] bool
|
||||
isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue);
|
||||
|
||||
[[nodiscard]] bool
|
||||
isIndividualFrozen(SLE const& mptSle);
|
||||
|
||||
/**
|
||||
* Returns true if @p account cannot send or receive tokens of @p mptIssue
|
||||
* because a freeze applies. This is the complete check callers should use
|
||||
* before moving MPT value: it combines @ref isGlobalFrozen (issuance-level
|
||||
* lock), @ref isIndividualFrozen (per-holder lock bit), and the transitive
|
||||
* vault pseudo-account check (if @p mptIssue is a vault share, the underlying
|
||||
* asset is checked, and so on recursively up to @c maxAssetCheckDepth).
|
||||
*
|
||||
* The @c SLE overload takes an already-loaded ltMPTOKEN or ltMPTOKEN_ISSUANCE
|
||||
* ledger entry; for ltMPTOKEN it can skip the per-holder individual-lock lookup.
|
||||
* @ref isAnyFrozen answers the same question for a set of accounts and returns true
|
||||
* if the freeze applies to any of them.
|
||||
*
|
||||
* @param depth Current recursion depth for the vault-share walk. Callers
|
||||
* outside this module should leave it at the default.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isFrozen(
|
||||
ReadView const& view,
|
||||
@@ -50,6 +73,18 @@ isFrozen(
|
||||
MPTIssue const& mptIssue,
|
||||
std::uint8_t depth = 0);
|
||||
|
||||
/**
|
||||
* SLE overload: pass an already-loaded ltMPTOKEN (holder row) or
|
||||
* ltMPTOKEN_ISSUANCE to reuse it for the freeze checks and avoid re-reading
|
||||
* the same object. For an ltMPTOKEN, @p sle is used directly for the
|
||||
* individual-lock check and the issuance is read once for global-freeze and
|
||||
* vault-pseudo-account. For an ltMPTOKEN_ISSUANCE, @p sle is used directly
|
||||
* for global-freeze and vault-pseudo-account, and the caller's holder row is
|
||||
* read for the individual-lock check.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isFrozen(ReadView const& view, AccountID const& account, SLE const& sle, std::uint8_t depth = 0);
|
||||
|
||||
[[nodiscard]] bool
|
||||
isAnyFrozen(
|
||||
ReadView const& view,
|
||||
@@ -261,6 +296,14 @@ checkCreateMPT(
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
SLE::ref sponsorSle,
|
||||
std::uint32_t flags,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
checkCreateMPT(
|
||||
xrpl::ApplyView& view,
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
beast::Journal j);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -239,8 +239,13 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Any transactors that call addEmptyHolding() in doApply must call
|
||||
* canAddHolding() in preflight with the same View and Asset
|
||||
* XRP and the issuer itself are always tesSUCCESS. Otherwise, after
|
||||
* fixCleanup3_4_0, an existing trust line returns tecDUPLICATE without
|
||||
* consulting issuer freeze or DefaultRipple; both still apply on the create
|
||||
* path (DefaultRipple off is terNO_RIPPLE). canAddHolding() ignores existing
|
||||
* holdings, so transactors that may create a holding in doApply should gate
|
||||
* their preclaim call on it: after the amendment only when no holding
|
||||
* exists, before it always.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
|
||||
@@ -38,6 +38,12 @@ enum class FreezeHandling { IgnoreFreeze, ZeroIfFrozen };
|
||||
*/
|
||||
enum class AuthHandling { IgnoreAuth, ZeroIfUnauthorized };
|
||||
|
||||
/**
|
||||
* Controls whether the recipient owner-reserve check is enforced when
|
||||
* auto-creating a trustline or MPToken during AMMWithdraw or AMMClawback.
|
||||
*/
|
||||
enum class ReserveHandling : bool { EnforceReserve, IgnoreReserve };
|
||||
|
||||
/**
|
||||
* Controls whether to include the account's full spendable balance
|
||||
*/
|
||||
@@ -294,6 +300,14 @@ accountFunds(
|
||||
AuthHandling authHandling,
|
||||
beast::Journal j);
|
||||
|
||||
/**
|
||||
* Returns the transfer fee as Rate based on the type of token
|
||||
* @param view The ledger view
|
||||
* @param asset The asset being transferred
|
||||
*/
|
||||
[[nodiscard]] Rate
|
||||
transferRate(ReadView const& view, Asset const& asset);
|
||||
|
||||
/**
|
||||
* Returns the transfer fee as Rate based on the type of token
|
||||
* @param view The ledger view
|
||||
@@ -311,6 +325,12 @@ transferRate(ReadView const& view, STAmount const& amount);
|
||||
[[nodiscard]] TER
|
||||
canAddHolding(ReadView const& view, Asset const& asset);
|
||||
|
||||
/**
|
||||
* True if the account already holds this asset (or is the issuer / XRP).
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
holdingExists(ReadView const& view, AccountID const& account, Asset const& asset);
|
||||
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyViewContext ctx,
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STTx;
|
||||
|
||||
/**
|
||||
* From the perspective of a vault, return the number of shares to give
|
||||
* depositor when they offer a fixed amount of assets. Note, since shares are
|
||||
@@ -38,6 +45,32 @@ assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co
|
||||
[[nodiscard]] std::optional<STAmount>
|
||||
sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& shares);
|
||||
|
||||
/**
|
||||
* Adjusts a requested asset change (`delta`) to match the decimal scale of the
|
||||
* updated total vault assets. This ensures `sfAssetsTotal`, `sfAssetsAvailable`,
|
||||
* and the actual asset transfer change by the exact same representable amount.
|
||||
*
|
||||
* Rounding strategy:
|
||||
* - Debits (withdrawals): Rounds down `|delta|` on the new scale to prevent
|
||||
* paying out more than requested.
|
||||
* - Credits (deposits): Floors the resulting total asset balance and returns the
|
||||
* difference from the current total. This prevents crediting the vault with
|
||||
* more assets than the user deposited.
|
||||
*
|
||||
* Key rules:
|
||||
* - The returned magnitude never exceeds `|delta|`.
|
||||
* - Returns `tecPRECISION_LOSS` if the change is smaller than 1 ULP of the target scale
|
||||
* (prevents share operations when totals cannot change).
|
||||
* - For integer assets (XRP, MPT), rounding is a no-op.
|
||||
*
|
||||
* @param vault The vault ledger entry.
|
||||
* @param delta The requested signed change to sfAssetsTotal.
|
||||
* @return The rounded, positive magnitude, or `tecPRECISION_LOSS` if the
|
||||
* change is below representable precision.
|
||||
*/
|
||||
[[nodiscard]] std::expected<STAmount, TER>
|
||||
clampToAssetsTotalScale(SLE::const_ref vault, STAmount const& delta);
|
||||
|
||||
/**
|
||||
* Controls whether to truncate shares instead of rounding.
|
||||
*/
|
||||
@@ -52,6 +85,35 @@ enum class TruncateShares : bool { No = false, Yes = true };
|
||||
*/
|
||||
enum class WaiveUnrealizedLoss : bool { No = false, Yes = true };
|
||||
|
||||
/**
|
||||
* Returns the assets backing outstanding shares for a withdrawal:
|
||||
* sfAssetsTotal minus sfLossUnrealized, or sfAssetsTotal alone when the
|
||||
* unrealized loss is waived. Used by assetsToSharesWithdraw and
|
||||
* sharesToAssetsWithdraw as the numerator of the share/asset exchange rate.
|
||||
*
|
||||
* @param vault The vault SLE.
|
||||
* @param waive Whether to skip subtracting the unrealized loss.
|
||||
*/
|
||||
[[nodiscard]] Number
|
||||
assetsTotalForWithdrawal(SLE::const_ref vault, WaiveUnrealizedLoss waive);
|
||||
|
||||
/**
|
||||
* Returns true if debiting `amount` from `total` (the current value of a
|
||||
* vault's sfAssetsTotal or sfAssetsAvailable) would canonicalize to the
|
||||
* same STAmount value. This happens when `amount` is non-zero but too small
|
||||
* to change the stored total at STAmount's precision. Shares would still
|
||||
* move, so the ValidVault invariant would fail after apply; callers use
|
||||
* this to reject the transaction upfront instead.
|
||||
*
|
||||
* @param asset The vault's underlying asset, used to canonicalize both
|
||||
* sides the same way the ledger will when the field is stored.
|
||||
* @param total The field's current value.
|
||||
* @param amount The amount to debit. Zero always returns false; that case
|
||||
* is rejected separately.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
debitIsNonZeroDust(Asset const& asset, Number const& total, Number const& amount);
|
||||
|
||||
/**
|
||||
* From the perspective of a vault, return the number of shares to demand from
|
||||
* the depositor when they ask to withdraw a fixed amount of assets. Since
|
||||
@@ -123,4 +185,118 @@ isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref
|
||||
[[nodiscard]] VaultVersion
|
||||
getVaultVersion(SLE::const_ref vault);
|
||||
|
||||
/**
|
||||
* Resolves the VaultKind of a vault SLE. Returns VaultKind::ClosedEnded when
|
||||
* sfVaultKind is present and equal to that value; anything else (including an
|
||||
* absent field or an unrecognised value) is treated as VaultKind::OpenEnded.
|
||||
*
|
||||
* @param vault The vault SLE.
|
||||
*/
|
||||
[[nodiscard]] VaultKind
|
||||
getVaultKind(SLE::const_ref vault);
|
||||
|
||||
/**
|
||||
* Reads sfVaultKind from a transaction. An absent field resolves to
|
||||
* VaultKind::OpenEnded (matching the on-ledger default); any unrecognised
|
||||
* value is also treated as VaultKind::OpenEnded, mirroring the SLE overload.
|
||||
* Callers that need to reject out-of-range values (e.g. preflight) should
|
||||
* gate on isValidVaultKind() first.
|
||||
*
|
||||
* @param tx The transaction.
|
||||
*/
|
||||
[[nodiscard]] VaultKind
|
||||
getVaultKind(STTx const& tx);
|
||||
|
||||
/**
|
||||
* Returns true iff sfVaultKind is either absent from @p tx or is present and
|
||||
* equal to a recognised VaultKind enumerator. Intended for use in preflight
|
||||
* to reject malformed transactions before decoding with getVaultKind().
|
||||
*
|
||||
* @param tx The transaction.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isValidVaultKind(STTx const& tx);
|
||||
|
||||
/**
|
||||
* Returns true iff the (SubscriptionDate, RedemptionDate) gap of a
|
||||
* closed-ended vault satisfies
|
||||
* kMinInvestmentPeriod <= (red - sub) < kMaxInvestmentPeriod. The arithmetic
|
||||
* is performed in std::int64_t so that @p sub near UINT32_MAX does not
|
||||
* overflow. Shared by VaultCreate::preflight and the ValidVault invariant.
|
||||
*
|
||||
* @param sub The value of sfSubscriptionDate.
|
||||
* @param red The value of sfRedemptionDate.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isValidClosedEndedGap(std::uint32_t sub, std::uint32_t red);
|
||||
|
||||
/**
|
||||
* Returns the current lifecycle phase of a vault. Open-ended
|
||||
* vaults are always NoPhase. For closed-ended vaults the phase is derived
|
||||
* from the parent ledger close time and the vault's immutable
|
||||
* SubscriptionDate and RedemptionDate.
|
||||
*
|
||||
* @param view The ledger view whose parent close time is used as the clock.
|
||||
* @param vault The vault SLE.
|
||||
*/
|
||||
[[nodiscard]] VaultPhase
|
||||
getVaultPhase(ReadView const& view, SLE::const_ref vault);
|
||||
|
||||
/**
|
||||
* Raw-fields overload of getVaultPhase. Derives the phase from an already
|
||||
* decomposed vault snapshot: an absent or non-ClosedEnded @p vaultKind
|
||||
* resolves to VaultPhase::NoPhase; otherwise the phase is computed from
|
||||
* @p subscriptionDate and @p redemptionDate against the view's parent
|
||||
* close time using the same boundary semantics as the SLE overload
|
||||
* (Subscription is inclusive of now == SubscriptionDate; Investment starts
|
||||
* strictly after).
|
||||
*
|
||||
* @param view The ledger view whose parent close time is used as the clock.
|
||||
* @param vaultKind The value of sfVaultKind, or nullopt if absent.
|
||||
* @param subscriptionDate The value of sfSubscriptionDate, or nullopt if absent.
|
||||
* @param redemptionDate The value of sfRedemptionDate, or nullopt if absent.
|
||||
*/
|
||||
[[nodiscard]] VaultPhase
|
||||
getVaultPhase(
|
||||
ReadView const& view,
|
||||
std::optional<std::uint8_t> vaultKind,
|
||||
std::optional<std::uint32_t> subscriptionDate,
|
||||
std::optional<std::uint32_t> redemptionDate);
|
||||
|
||||
/**
|
||||
* Controls whether checkVaultDomain reports an expired credential as an
|
||||
* error. A caller that deletes expired credentials later, in doApply, passes
|
||||
* Yes and treats the subject as authorized; a caller with no such cleanup
|
||||
* step must keep the error.
|
||||
*/
|
||||
enum class SuppressExpired : bool { No = false, Yes = true };
|
||||
|
||||
/**
|
||||
* Checks that subject belongs to the permissioned domain governing a vault's
|
||||
* shares.
|
||||
*
|
||||
* The domain is read from the share issuance rather than from the vault. Vault
|
||||
* shares are issued by the vault's pseudo-account, which cannot grant an
|
||||
* authorization explicitly, so domain membership is the only route to being
|
||||
* authorized: a vault with no domain set has no authorized participants at
|
||||
* all, and every subject fails with tecNO_AUTH.
|
||||
*
|
||||
* Which accounts to check, and whether to check at all, is left to the caller.
|
||||
* This says nothing about vault privacy or about the roles of the accounts.
|
||||
*
|
||||
* @param view The ledger view.
|
||||
* @param issuance The MPTokenIssuance SLE for the vault's shares.
|
||||
* @param subject The account whose domain membership is checked.
|
||||
* @param suppressExpired Whether an expired credential counts as authorized.
|
||||
*
|
||||
* @return tesSUCCESS if the subject is a domain member, otherwise the reason
|
||||
* it is not.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkVaultDomain(
|
||||
ReadView const& view,
|
||||
SLE::const_ref issuance,
|
||||
AccountID const& subject,
|
||||
SuppressExpired suppressExpired);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/tls1.h>
|
||||
|
||||
#include <format>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@@ -38,8 +38,8 @@ public:
|
||||
|
||||
if (ec && sslVerifyDir.empty())
|
||||
{
|
||||
Throw<std::runtime_error>(boost::str(
|
||||
boost::format("Failed to set_default_verify_paths: %s") % ec.message()));
|
||||
Throw<std::runtime_error>(
|
||||
std::format("Failed to set_default_verify_paths: {}", ec.message()));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
if (ec)
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
boost::str(boost::format("Failed to add verify path: %s") % ec.message()));
|
||||
std::format("Failed to add verify path: {}", ec.message()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
syntax = "proto2";
|
||||
package protocol;
|
||||
|
||||
// Unused numbers in the list below may have been used previously. Please don't
|
||||
// reassign them for reuse unless you are 100% certain that there won't be a
|
||||
// conflict. Even if you're sure, it's probably best to assign a new type.
|
||||
enum MessageType {
|
||||
// Previously used - don't reuse.
|
||||
reserved 0 to 1, 4, 6 to 14, 16 to 29, 36 to 40, 43 to 54, 61 to 62;
|
||||
|
||||
mtMANIFESTS = 2;
|
||||
mtPING = 3;
|
||||
mtCLUSTER = 5;
|
||||
@@ -17,7 +17,6 @@ enum MessageType {
|
||||
mtHAVE_SET = 35;
|
||||
mtVALIDATION = 41;
|
||||
mtGET_OBJECTS = 42;
|
||||
mtVALIDATOR_LIST = 54;
|
||||
mtSQUELCH = 55;
|
||||
mtVALIDATOR_LIST_COLLECTION = 56;
|
||||
mtPROOF_PATH_REQ = 57;
|
||||
@@ -162,14 +161,6 @@ message TMHaveTransactionSet {
|
||||
required bytes hash = 2;
|
||||
}
|
||||
|
||||
// Validator list (UNL)
|
||||
message TMValidatorList {
|
||||
required bytes manifest = 1;
|
||||
required bytes blob = 2;
|
||||
required bytes signature = 3;
|
||||
required uint32 version = 4;
|
||||
}
|
||||
|
||||
// Validator List v2
|
||||
message ValidatorBlobInfo {
|
||||
optional bytes manifest = 1;
|
||||
|
||||
@@ -91,6 +91,17 @@ getFee(std::uint16_t tfee)
|
||||
return Number{tfee} / kAuctionSlotFeeScaleFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum auction slot price: LPTokens * TradingFee / kAuctionSlotMinFeeFraction
|
||||
* @param lptAMMBalance AMM LP token balance
|
||||
* @param tradingFee trading fee in {0, 1000}
|
||||
*/
|
||||
inline Number
|
||||
ammAuctionMinSlotPrice(Number const& lptAMMBalance, std::uint16_t tradingFee)
|
||||
{
|
||||
return lptAMMBalance * getFee(tradingFee) / kAuctionSlotMinFeeFraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fee multiplier (1 - tfee)
|
||||
* @tfee trading fee in basis points
|
||||
|
||||
@@ -154,7 +154,7 @@ T
|
||||
toAmount(Asset const& asset, Number const& n, Number::RoundingMode mode = Number::getround())
|
||||
{
|
||||
SaveNumberRoundMode const rm(Number::getround());
|
||||
if (isXRP(asset))
|
||||
if (asset.integral())
|
||||
Number::setround(mode);
|
||||
|
||||
if constexpr (std::is_same_v<IOUAmount, T>)
|
||||
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
using id_hash_type = boost::base_from_member<std::hash<xrpl::MPTID>, 0>;
|
||||
|
||||
public:
|
||||
explicit hash() = default;
|
||||
hash() = default;
|
||||
|
||||
using value_type = std::size_t;
|
||||
using argument_type = xrpl::MPTIssue;
|
||||
@@ -160,7 +160,7 @@ private:
|
||||
mptissue_hasher mMptissueHasher_;
|
||||
|
||||
public:
|
||||
explicit hash() = default;
|
||||
hash() = default;
|
||||
|
||||
value_type
|
||||
operator()(argument_type const& asset) const
|
||||
@@ -227,7 +227,7 @@ struct hash<xrpl::Issue> : std::hash<xrpl::Issue>
|
||||
template <>
|
||||
struct hash<xrpl::MPTIssue> : std::hash<xrpl::MPTIssue>
|
||||
{
|
||||
explicit hash() = default;
|
||||
hash() = default;
|
||||
|
||||
using Base = std::hash<xrpl::MPTIssue>;
|
||||
};
|
||||
@@ -235,7 +235,7 @@ struct hash<xrpl::MPTIssue> : std::hash<xrpl::MPTIssue>
|
||||
template <>
|
||||
struct hash<xrpl::Asset> : std::hash<xrpl::Asset>
|
||||
{
|
||||
explicit hash() = default;
|
||||
hash() = default;
|
||||
|
||||
using Base = std::hash<xrpl::Asset>;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/TxSettings.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -28,8 +29,6 @@ enum GranularEmitableType : std::uint32_t {
|
||||
#pragma pop_macro("EMITABLE")
|
||||
};
|
||||
|
||||
enum Emittance { emitable, notEmitable };
|
||||
|
||||
class Emitable
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -92,6 +92,26 @@ enum class HashPrefix : std::uint32_t {
|
||||
* Batch
|
||||
*/
|
||||
Batch = detail::makeHashPrefix('B', 'C', 'H'),
|
||||
|
||||
/**
|
||||
* inner transaction to sign as the counterparty
|
||||
*/
|
||||
CounterpartyTxSign = detail::makeHashPrefix('C', 'P', 'T'),
|
||||
|
||||
/**
|
||||
* inner transaction to multi-sign as the counterparty
|
||||
*/
|
||||
CounterpartyTxMultiSign = detail::makeHashPrefix('C', 'P', 'M'),
|
||||
|
||||
/**
|
||||
* inner transaction to sign as the sponsor
|
||||
*/
|
||||
SponsorTxSign = detail::makeHashPrefix('S', 'P', 'N'),
|
||||
|
||||
/**
|
||||
* inner transaction to multi-sign as the sponsor
|
||||
*/
|
||||
SponsorTxMultiSign = detail::makeHashPrefix('S', 'P', 'M'),
|
||||
};
|
||||
|
||||
template <class Hasher>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@@ -174,4 +175,17 @@ mulRatio(MPTAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
|
||||
return MPTAmount(r.convert_to<MPTAmount::value_type>());
|
||||
}
|
||||
|
||||
inline std::optional<MPTAmount>
|
||||
tryMulRatio(MPTAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundUp)
|
||||
{
|
||||
try
|
||||
{
|
||||
return mulRatio(amt, num, den, roundUp);
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace std {
|
||||
template <>
|
||||
struct hash<xrpl::MPTID> : xrpl::MPTID::hasher
|
||||
{
|
||||
explicit hash() = default;
|
||||
hash() = default;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/json/json_forwards.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TxMeta.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl::rpc {
|
||||
|
||||
/**
|
||||
* Adds common synthetic fields to transaction-related JSON responses
|
||||
*/
|
||||
/** @{ */
|
||||
void
|
||||
insertNFTSyntheticInJson(json::Value&, std::shared_ptr<STTx const> const&, TxMeta const&);
|
||||
/** @} */
|
||||
|
||||
} // namespace xrpl::rpc
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/SOTemplate.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/TxSettings.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@@ -38,11 +39,6 @@ enum GranularPermissionType : std::uint32_t {
|
||||
#pragma pop_macro("GRANULAR_PERMISSION")
|
||||
};
|
||||
|
||||
// Injected bare enumerators (xrpl::delegable / xrpl::notDelegable) are required by preprocessor
|
||||
// tricks in tests and macro-generated code; enum class would break that.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum Delegation { Delegable, NotDelegable };
|
||||
|
||||
class Permission
|
||||
{
|
||||
private:
|
||||
@@ -65,7 +61,7 @@ private:
|
||||
struct TxDelegationEntry
|
||||
{
|
||||
uint256 amendment;
|
||||
Delegation delegable{NotDelegable};
|
||||
Delegation delegable{Delegation::NotDelegable};
|
||||
};
|
||||
|
||||
std::unordered_set<TxType> granularTxTypes_;
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
#include <mpt_protocol.h>
|
||||
#include <secp256k1_mpt.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -327,6 +329,47 @@ enum class VaultVersion : uint8_t {
|
||||
CashBasis,
|
||||
};
|
||||
|
||||
/**
|
||||
* Vault kind. Distinguishes closed-ended vaults from the default open-ended
|
||||
* kind. Persisted as sfVaultKind (UINT8); absent means OpenEnded.
|
||||
*/
|
||||
enum class VaultKind : std::uint8_t {
|
||||
OpenEnded = 0,
|
||||
ClosedEnded = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Lifecycle phase of a vault. Open-ended vaults are always NoPhase; the other
|
||||
* three values are the phases of a closed-ended vault.
|
||||
*/
|
||||
enum class VaultPhase : std::uint8_t {
|
||||
NoPhase = 0,
|
||||
Subscription,
|
||||
Investment,
|
||||
Redemption,
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimum gap between a closed-ended loan's final scheduled payment and the
|
||||
* vault's RedemptionDate. LoanSet rejects a schedule whose final payment is
|
||||
* fewer than this many seconds before RedemptionDate.
|
||||
*/
|
||||
constexpr std::uint32_t kLoanRedemptionBuffer = std::chrono::seconds{60}.count();
|
||||
|
||||
/**
|
||||
* Bounds on the length of a closed-ended vault's Investment phase
|
||||
* (RedemptionDate - SubscriptionDate). At vault creation the gap must satisfy
|
||||
* kMinInvestmentPeriod <= gap < kMaxInvestmentPeriod.
|
||||
*
|
||||
* 180s is enough to originate a loan that uses the minimum payment interval
|
||||
* and kLoanRedemptionBuffer after StartDate, which is strictly after
|
||||
* SubscriptionDate. The interval and buffer need not be equal; only their
|
||||
* sum plus one second must fit in this floor.
|
||||
*/
|
||||
constexpr std::uint32_t kMinInvestmentPeriod = std::chrono::seconds{180}.count();
|
||||
// This is 946708560 seconds which 30 x 365.2425 days (the average length of a Gregorian year).
|
||||
constexpr std::uint32_t kMaxInvestmentPeriod = std::chrono::seconds{std::chrono::years{30}}.count();
|
||||
|
||||
/**
|
||||
* Maximum recursion depth for vault shares being put as an asset inside
|
||||
* another vault; counted from 0
|
||||
@@ -512,6 +555,11 @@ constexpr std::size_t kEcClawbackProofLength = SECP256K1_COMPACT_CLAWBACK_PROOF_
|
||||
*/
|
||||
constexpr std::uint32_t kConfidentialFeeMultiplier = 9;
|
||||
|
||||
/**
|
||||
* Maximum value a confidential MPT key epoch may reach.
|
||||
*/
|
||||
constexpr std::uint32_t kMaxKeyEpoch = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
/**
|
||||
* Compressed EC point prefix for even y-coordinate
|
||||
*/
|
||||
|
||||
@@ -75,13 +75,6 @@ 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);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// XRPL specific constant used for parsing qualities and other things
|
||||
@@ -271,12 +264,6 @@ public:
|
||||
return lhs.value_ == rhs.value_;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(Quality const& lhs, Quality const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, Quality const& quality)
|
||||
{
|
||||
|
||||
@@ -60,6 +60,15 @@ public:
|
||||
std::optional<Number>
|
||||
outFromAvgQ(Quality const& quality);
|
||||
|
||||
/**
|
||||
* Return whether `out` produces at least the requested
|
||||
* average quality.
|
||||
* @param quality requested average quality (quality limit)
|
||||
* @param out output amount to test
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
satisfiesAvgQ(Quality const& quality, Number const& out) const;
|
||||
|
||||
/**
|
||||
* Return true if the quality function is constant
|
||||
*/
|
||||
|
||||
@@ -98,9 +98,6 @@ public:
|
||||
*/
|
||||
bool
|
||||
operator==(Rules const&) const;
|
||||
|
||||
bool
|
||||
operator!=(Rules const& other) const;
|
||||
};
|
||||
|
||||
std::optional<Rules> const&
|
||||
|
||||
@@ -642,12 +642,6 @@ 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)
|
||||
{
|
||||
|
||||
@@ -133,9 +133,6 @@ public:
|
||||
bool
|
||||
operator==(STArray const& s) const;
|
||||
|
||||
bool
|
||||
operator!=(STArray const& s) const;
|
||||
|
||||
iterator
|
||||
erase(iterator pos);
|
||||
|
||||
@@ -283,12 +280,6 @@ STArray::operator==(STArray const& s) const
|
||||
return v_ == s.v_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STArray::operator!=(STArray const& s) const
|
||||
{
|
||||
return v_ != s.v_;
|
||||
}
|
||||
|
||||
inline STArray::iterator
|
||||
STArray::erase(iterator pos)
|
||||
{
|
||||
|
||||
@@ -140,8 +140,6 @@ public:
|
||||
|
||||
bool
|
||||
operator==(STBase const& t) const;
|
||||
bool
|
||||
operator!=(STBase const& t) const;
|
||||
|
||||
template <class D>
|
||||
D&
|
||||
|
||||
@@ -93,12 +93,6 @@ 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)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace xrpl {
|
||||
|
||||
class Rules;
|
||||
namespace test {
|
||||
class Invariants_test;
|
||||
class InvariantsMisc_test;
|
||||
} // namespace test
|
||||
|
||||
class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
|
||||
@@ -83,8 +83,8 @@ private:
|
||||
void
|
||||
setSLEType();
|
||||
|
||||
friend test::Invariants_test; // this test wants access to the private
|
||||
// type_
|
||||
friend test::InvariantsMisc_test; // this test wants access to the
|
||||
// private type_
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
|
||||
@@ -444,8 +444,6 @@ public:
|
||||
|
||||
bool
|
||||
operator==(STObject const& o) const;
|
||||
bool
|
||||
operator!=(STObject const& o) const;
|
||||
|
||||
class FieldErr;
|
||||
|
||||
@@ -679,36 +677,6 @@ public:
|
||||
return !lhs.engaged() || *lhs == *rhs;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(OptionalProxy const& lhs, std::nullopt_t) noexcept
|
||||
{
|
||||
return !(lhs == std::nullopt);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(std::nullopt_t, OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return !(rhs == std::nullopt);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
// Emulate std::optional::value_or
|
||||
[[nodiscard]] value_type
|
||||
valueOr(value_type val) const;
|
||||
@@ -1214,12 +1182,6 @@ STObject::setFieldH160(SField const& field, BaseUInt<160, Tag> const& v)
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
STObject::operator!=(STObject const& o) const
|
||||
{
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
template <typename T, typename V>
|
||||
V
|
||||
STObject::getFieldByValue(SField const& field) const
|
||||
|
||||
@@ -115,9 +115,6 @@ public:
|
||||
bool
|
||||
operator==(STPathElement const& t) const;
|
||||
|
||||
bool
|
||||
operator!=(STPathElement const& t) const;
|
||||
|
||||
private:
|
||||
static std::size_t
|
||||
getHash(STPathElement const& element);
|
||||
@@ -432,12 +429,6 @@ STPathElement::operator==(STPathElement const& t) const
|
||||
accountID_ == t.accountID_ && assetID_ == t.assetID_ && issuerID_ == t.issuerID_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::operator!=(STPathElement const& t) const
|
||||
{
|
||||
return !operator==(t);
|
||||
}
|
||||
|
||||
// ------------ STPath ------------
|
||||
|
||||
inline STPath::STPath(std::vector<STPathElement> p) : path_(std::move(p))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/SeqProxy.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/Sign.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
@@ -105,14 +107,36 @@ public:
|
||||
[[nodiscard]] json::Value
|
||||
getJson(JsonOptions options, bool binary) const;
|
||||
|
||||
/**
|
||||
* Sign the transaction as its account.
|
||||
*
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
*/
|
||||
void
|
||||
sign(PublicKey const& publicKey, SecretKey const& secretKey);
|
||||
|
||||
/**
|
||||
* Sign the transaction in one of its signature fields.
|
||||
*
|
||||
* The signature is bound to the role that made it, so it cannot be moved
|
||||
* into another role.
|
||||
*
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @param role The role signing the transaction.
|
||||
* @param rules The current ledger rules.
|
||||
*/
|
||||
void
|
||||
sign(
|
||||
PublicKey const& publicKey,
|
||||
SecretKey const& secretKey,
|
||||
std::optional<std::reference_wrapper<SField const>> signatureTarget = {});
|
||||
SignatureRole role,
|
||||
Rules const& rules);
|
||||
|
||||
/**
|
||||
* Check the signature.
|
||||
*
|
||||
* @param rules The current ledger rules.
|
||||
* @return `true` if valid signature. If invalid, the error message string.
|
||||
*/
|
||||
@@ -120,7 +144,7 @@ public:
|
||||
checkSign(Rules const& rules) const;
|
||||
|
||||
[[nodiscard]] std::expected<void, std::string>
|
||||
checkBatchSign(Rules const& rules) const;
|
||||
checkBatchSign() const;
|
||||
|
||||
// SQL Functions with metadata.
|
||||
static std::string const&
|
||||
@@ -162,28 +186,28 @@ public:
|
||||
private:
|
||||
/**
|
||||
* Check the signature.
|
||||
*
|
||||
* @param rules The current ledger rules.
|
||||
* @param sigObject Reference to object that contains the signature fields.
|
||||
* Will be *this more often than not.
|
||||
* @param role The role that made the signature in sigObject. Determines
|
||||
* the signing prefix, which binds the signature to that role.
|
||||
* @return `true` if valid signature. If invalid, the error message string.
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, std::string>
|
||||
checkSign(Rules const& rules, STObject const& sigObject) const;
|
||||
checkSign(Rules const& rules, STObject const& sigObject, SignatureRole role) const;
|
||||
|
||||
[[nodiscard]] std::expected<void, std::string>
|
||||
checkSingleSign(STObject const& sigObject) const;
|
||||
checkSingleSign(STObject const& sigObject, HashPrefix prefix) const;
|
||||
|
||||
[[nodiscard]] std::expected<void, std::string>
|
||||
checkMultiSign(Rules const& rules, STObject const& sigObject) const;
|
||||
checkMultiSign(STObject const& sigObject, HashPrefix prefix) const;
|
||||
|
||||
[[nodiscard]] std::expected<void, std::string>
|
||||
checkBatchSingleSign(STObject const& batchSigner, std::vector<uint256> const& txIds) const;
|
||||
|
||||
[[nodiscard]] std::expected<void, std::string>
|
||||
checkBatchMultiSign(
|
||||
STObject const& batchSigner,
|
||||
Rules const& rules,
|
||||
std::vector<uint256> const& txIds) const;
|
||||
checkBatchMultiSign(STObject const& batchSigner, std::vector<uint256> const& txIds) const;
|
||||
|
||||
void
|
||||
buildBatchTxns();
|
||||
|
||||
@@ -123,12 +123,6 @@ public:
|
||||
return (lhs.value() == rhs.value());
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator!=(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend constexpr bool
|
||||
operator<(SeqProxy lhs, SeqProxy rhs)
|
||||
{
|
||||
|
||||
@@ -265,20 +265,10 @@ public:
|
||||
return v == data_;
|
||||
}
|
||||
bool
|
||||
operator!=(Blob const& v) const
|
||||
{
|
||||
return v != data_;
|
||||
}
|
||||
bool
|
||||
operator==(Serializer const& v) const
|
||||
{
|
||||
return v.data_ == data_;
|
||||
}
|
||||
bool
|
||||
operator!=(Serializer const& v) const
|
||||
{
|
||||
return v.data_ != data_;
|
||||
}
|
||||
|
||||
static int
|
||||
decodeLengthLength(int b1);
|
||||
|
||||
@@ -4,13 +4,65 @@
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/KeyType.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* The signature slots on a transaction.
|
||||
*
|
||||
* Each role signs different bytes, so a signature cannot be moved from the
|
||||
* role that made it into another role. See signingPrefix.
|
||||
*/
|
||||
enum class SignatureRole {
|
||||
/**
|
||||
* The transaction's own signature, in sfTxnSignature or sfSigners.
|
||||
*/
|
||||
Transaction,
|
||||
/**
|
||||
* The counterparty's signature, in sfCounterpartySignature.
|
||||
*/
|
||||
Counterparty,
|
||||
/**
|
||||
* The sponsor's signature, in sfSponsorSignature.
|
||||
*/
|
||||
Sponsor
|
||||
};
|
||||
|
||||
/**
|
||||
* The field that holds this role's signature.
|
||||
*
|
||||
* @return The signature field, or nullptr for SignatureRole::Transaction,
|
||||
* whose signature lives at the top level of the transaction.
|
||||
*/
|
||||
[[nodiscard]] SField const*
|
||||
signatureField(SignatureRole role);
|
||||
|
||||
/**
|
||||
* The role that signs into the given field.
|
||||
*
|
||||
* @return The role, or an unseated optional if the field does not hold a
|
||||
* transaction signature.
|
||||
*/
|
||||
[[nodiscard]] std::optional<SignatureRole>
|
||||
signatureRole(SField const& sigField);
|
||||
|
||||
/**
|
||||
* The hash prefix that binds a transaction signature to the role that made it.
|
||||
*
|
||||
* @param role The role making the signature.
|
||||
* @param multiSigning Whether the signature is a multi-signature.
|
||||
* @param rules The current ledger rules.
|
||||
*/
|
||||
[[nodiscard]] HashPrefix
|
||||
signingPrefix(SignatureRole role, bool multiSigning, Rules const& rules);
|
||||
|
||||
/**
|
||||
* Sign an STObject
|
||||
*
|
||||
@@ -49,9 +101,12 @@ verify(
|
||||
|
||||
/**
|
||||
* Return a Serializer suitable for computing a multisigning TxnSignature.
|
||||
*
|
||||
* @param prefix Prefix to insert before the serialized object. Get it from
|
||||
* signingPrefix, so that the signature is bound to the role making it.
|
||||
*/
|
||||
Serializer
|
||||
buildMultiSigningData(STObject const& obj, AccountID const& signingID);
|
||||
buildMultiSigningData(STObject const& obj, AccountID const& signingID, HashPrefix prefix);
|
||||
|
||||
/**
|
||||
* Break the multi-signing hash computation into 2 parts for optimization.
|
||||
@@ -67,7 +122,7 @@ buildMultiSigningData(STObject const& obj, AccountID const& signingID);
|
||||
* signer's unique data.
|
||||
*/
|
||||
Serializer
|
||||
startMultiSigningData(STObject const& obj);
|
||||
startMultiSigningData(STObject const& obj, HashPrefix prefix);
|
||||
|
||||
inline void
|
||||
finishMultiSigningData(AccountID const& signingID, Serializer& s)
|
||||
|
||||
@@ -132,7 +132,6 @@ enum TEMcodes : TERUnderlyingType {
|
||||
|
||||
temBAD_MPT,
|
||||
temBAD_CIPHERTEXT,
|
||||
temBAD_WASM,
|
||||
temINVALID_BYTECODE,
|
||||
temTEMP_DISABLED,
|
||||
};
|
||||
|
||||
@@ -438,8 +438,7 @@ inline constexpr FlagValue tfDepositSubTx =
|
||||
ASF_FLAG(asfDefaultRipple, 8) \
|
||||
ASF_FLAG(asfDepositAuth, 9) \
|
||||
ASF_FLAG(asfAuthorizedNFTokenMinter, 10) \
|
||||
/* 11 is reserved for Hooks amendment */ \
|
||||
/* ASF_FLAG(asfTshCollect, 11) */ \
|
||||
/* 11 is unused */ \
|
||||
ASF_FLAG(asfDisallowIncomingNFTokenOffer, 12) \
|
||||
ASF_FLAG(asfDisallowIncomingCheck, 13) \
|
||||
ASF_FLAG(asfDisallowIncomingPayChan, 14) \
|
||||
|
||||
106
include/xrpl/protocol/TxSettings.h
Normal file
106
include/xrpl/protocol/TxSettings.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class Delegation { Delegable, NotDelegable };
|
||||
|
||||
/**
|
||||
* Whether a smart contract may emit this transaction type.
|
||||
*/
|
||||
enum class Emittance { Emitable, NotEmitable };
|
||||
|
||||
/**
|
||||
* Operations a transaction is permitted to perform, as a bitfield.
|
||||
*
|
||||
* These are declared per-transaction in transactions.macro (via
|
||||
* TxSettings::privileges) and enforced in InvariantCheck.cpp.
|
||||
*/
|
||||
enum class Privilege : std::uint16_t {
|
||||
NoPriv = 0x0000, // The transaction can not do any of the enumerated operations
|
||||
CreateAcct = 0x0001, // The transaction can create a new ACCOUNT_ROOT object.
|
||||
CreatePseudoAcct = 0x0002, // The transaction can create a pseudo account,
|
||||
// which implies createAcct
|
||||
MustDeleteAcct = 0x0004, // The transaction must delete an ACCOUNT_ROOT object
|
||||
MayDeleteAcct = 0x0008, // The transaction may delete an ACCOUNT_ROOT
|
||||
// object, but does not have to
|
||||
OverrideFreeze = 0x0010, // The transaction can override some freeze rules
|
||||
ChangeNftCounts = 0x0020, // The transaction can mint or burn an NFT
|
||||
CreateMptIssuance = 0x0040, // The transaction can create a new MPT issuance
|
||||
DestroyMptIssuance = 0x0080, // The transaction can destroy an MPT issuance
|
||||
MustAuthorizeMpt = 0x0100, // The transaction MUST create or delete an MPT
|
||||
// object (except by issuer)
|
||||
MayAuthorizeMpt = 0x0200, // The transaction MAY create or delete an MPT
|
||||
// object (except by issuer)
|
||||
MayDeleteMpt = 0x0400, // The transaction MAY delete an MPT object. May not create.
|
||||
MustModifyVault = 0x0800, // The transaction must modify, delete or create, a vault
|
||||
MayModifyVault = 0x1000, // The transaction MAY modify, delete or create, a vault
|
||||
MayCreateMpt = 0x2000, // The transaction MAY create an MPT object, except for issuer.
|
||||
};
|
||||
|
||||
// The inner static_cast is not redundant: the underlying type is narrower than
|
||||
// `int`, so the operands integer-promote and the result has to be narrowed back.
|
||||
// safeCast rejects that narrowing, but every input bit is a Privilege bit by
|
||||
// construction, so the result is always representable.
|
||||
constexpr Privilege
|
||||
operator|(Privilege lhs, Privilege rhs)
|
||||
{
|
||||
using Underlying = std::underlying_type_t<Privilege>;
|
||||
return static_cast<Privilege>(
|
||||
static_cast<Underlying>(safeCast<Underlying>(lhs) | safeCast<Underlying>(rhs)));
|
||||
}
|
||||
|
||||
constexpr Privilege
|
||||
operator&(Privilege lhs, Privilege rhs)
|
||||
{
|
||||
using Underlying = std::underlying_type_t<Privilege>;
|
||||
return static_cast<Privilege>(
|
||||
static_cast<Underlying>(safeCast<Underlying>(lhs) & safeCast<Underlying>(rhs)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-transaction metadata declared in transactions.macro.
|
||||
*
|
||||
* Every member has a default, so a transaction only needs to name the settings
|
||||
* that differ from the common case. See the documentation at the top of
|
||||
* transactions.macro for the authoring syntax.
|
||||
*
|
||||
* This is deliberately not a constexpr-friendly type: amendment identifiers are
|
||||
* runtime-initialized `extern uint256 const` globals (see Feature.h), so a
|
||||
* TxSettings can only be built at runtime.
|
||||
*/
|
||||
struct TxSettings
|
||||
{
|
||||
/**
|
||||
* Whether an account may delegate this transaction to another account.
|
||||
*/
|
||||
Delegation delegable{Delegation::NotDelegable};
|
||||
|
||||
/**
|
||||
* The amendment gating this transaction, or uint256{} if always available.
|
||||
*/
|
||||
// The `{}` looks redundant, because BaseUInt's default constructor already
|
||||
// zeroes the value. It is not: without a default member initializer here,
|
||||
// every partial designated initializer in transactions.macro trips the
|
||||
// missing-designated-field-initializers warning, which the build treats as
|
||||
// an error.
|
||||
// NOLINTNEXTLINE(readability-redundant-member-init)
|
||||
uint256 amendment{};
|
||||
|
||||
/**
|
||||
* Operations this transaction is permitted to perform.
|
||||
*/
|
||||
Privilege privileges{Privilege::NoPriv};
|
||||
|
||||
/**
|
||||
* Whether a smart contract may emit this transaction type.
|
||||
*/
|
||||
Emittance emittance{Emittance::Emitable};
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -258,13 +258,6 @@ public:
|
||||
return value_ == other;
|
||||
}
|
||||
|
||||
template <Compatible<ValueUnit> Other>
|
||||
constexpr bool
|
||||
operator!=(ValueUnit<unit_type, Other> const& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator<(ValueUnit const& other) const
|
||||
{
|
||||
|
||||
@@ -152,10 +152,4 @@ 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 xrpl::detail
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(SmartContract, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_4_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(SmartEscrow, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocolV1_2, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_5_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ConfidentialMPTKeyRotation, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_4_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Sponsor, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(BatchV1_1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocolV1_1, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocolV1_1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ConfidentialTransfer, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_3_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Cleanup3_2_0, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -416,6 +416,8 @@ LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
|
||||
{sfReferenceHolding, SoeOptional},
|
||||
{sfIssuerEncryptionKey, SoeOptional},
|
||||
{sfAuditorEncryptionKey, SoeOptional},
|
||||
{sfIssuerKeyEpoch, SoeOptional},
|
||||
{sfAuditorKeyEpoch, SoeOptional},
|
||||
{sfConfidentialOutstandingAmount, SoeDefault},
|
||||
}))
|
||||
|
||||
@@ -514,6 +516,9 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
|
||||
{sfWithdrawalPolicy, SoeRequired},
|
||||
{sfScale, SoeDefault},
|
||||
{sfLEVersion, SoeDefault},
|
||||
{sfVaultKind, SoeDefault},
|
||||
{sfSubscriptionDate, SoeOptional},
|
||||
{sfRedemptionDate, SoeOptional},
|
||||
// no SharesTotal ever (use MPTIssuance.sfOutstandingAmount)
|
||||
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
|
||||
}))
|
||||
|
||||
@@ -27,6 +27,7 @@ TYPED_SFIELD(sfUNLModifyDisabling, UINT8, 17)
|
||||
TYPED_SFIELD(sfWasLockingChainSend, UINT8, 19)
|
||||
TYPED_SFIELD(sfWithdrawalPolicy, UINT8, 20)
|
||||
TYPED_SFIELD(sfContractResult, UINT8, 21)
|
||||
TYPED_SFIELD(sfVaultKind, UINT8, 22)
|
||||
|
||||
// 16-bit integers (common)
|
||||
TYPED_SFIELD(sfLedgerEntryType, UINT16, 1, SField::kSmdNever)
|
||||
@@ -116,12 +117,18 @@ TYPED_SFIELD(sfSponsoringOwnerCount, UINT32, 71)
|
||||
TYPED_SFIELD(sfSponsoringAccountCount, UINT32, 72)
|
||||
TYPED_SFIELD(sfRemainingOwnerCount, UINT32, 73)
|
||||
TYPED_SFIELD(sfSponsorFlags, UINT32, 74)
|
||||
TYPED_SFIELD(sfGasLimit, UINT32, 75)
|
||||
TYPED_SFIELD(sfBytecodeSizeLimit, UINT32, 76)
|
||||
TYPED_SFIELD(sfGasPrice, UINT32, 77)
|
||||
TYPED_SFIELD(sfGas, UINT32, 78)
|
||||
TYPED_SFIELD(sfGasUsed, UINT32, 79)
|
||||
TYPED_SFIELD(sfParameterFlag, UINT32, 80)
|
||||
TYPED_SFIELD(sfSubscriptionDate, UINT32, 75)
|
||||
TYPED_SFIELD(sfRedemptionDate, UINT32, 76)
|
||||
TYPED_SFIELD(sfIssuerKeyEpoch, UINT32, 77)
|
||||
TYPED_SFIELD(sfAuditorKeyEpoch, UINT32, 78)
|
||||
TYPED_SFIELD(sfIssuerKeyMirrorEpoch, UINT32, 79)
|
||||
TYPED_SFIELD(sfAuditorKeyMirrorEpoch, UINT32, 80)
|
||||
TYPED_SFIELD(sfGasLimit, UINT32, 81)
|
||||
TYPED_SFIELD(sfBytecodeSizeLimit, UINT32, 82)
|
||||
TYPED_SFIELD(sfGasPrice, UINT32, 83)
|
||||
TYPED_SFIELD(sfGas, UINT32, 84)
|
||||
TYPED_SFIELD(sfGasUsed, UINT32, 85)
|
||||
TYPED_SFIELD(sfParameterFlag, UINT32, 86)
|
||||
|
||||
// 64-bit integers (common)
|
||||
TYPED_SFIELD(sfIndexNext, UINT64, 1)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -189,7 +189,8 @@ JSS(confidential_balance_inbox); // out: mpt_holders (confidential MPT)
|
||||
JSS(confidential_balance_spending); // out: mpt_holders (confidential MPT)
|
||||
JSS(confidential_balance_version); // out: mpt_holders (confidential MPT)
|
||||
JSS(consensus); // out: NetworkOPs, LedgerConsensus
|
||||
JSS(contract_account); // out: ContractInfo
|
||||
JSS(contract_account); // in: LedgerEntry, out: ContractInfo
|
||||
JSS(contract_hash); // in: LedgerEntry
|
||||
JSS(converge_time); // out: NetworkOPs
|
||||
JSS(converge_time_s); // out: NetworkOPs
|
||||
JSS(cookie); // out: NetworkOPs
|
||||
|
||||
@@ -351,6 +351,54 @@ public:
|
||||
return this->sle_->isFieldPresent(sfAuditorEncryptionKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfIssuerKeyEpoch (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getIssuerKeyEpoch() const
|
||||
{
|
||||
if (hasIssuerKeyEpoch())
|
||||
return this->sle_->at(sfIssuerKeyEpoch);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfIssuerKeyEpoch is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasIssuerKeyEpoch() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfIssuerKeyEpoch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAuditorKeyEpoch (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getAuditorKeyEpoch() const
|
||||
{
|
||||
if (hasAuditorKeyEpoch())
|
||||
return this->sle_->at(sfAuditorKeyEpoch);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfAuditorKeyEpoch is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasAuditorKeyEpoch() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfAuditorKeyEpoch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfConfidentialOutstandingAmount (SoeDefault)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
@@ -600,6 +648,28 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfIssuerKeyEpoch (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
MPTokenIssuanceBuilder&
|
||||
setIssuerKeyEpoch(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfIssuerKeyEpoch] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAuditorKeyEpoch (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
MPTokenIssuanceBuilder&
|
||||
setAuditorKeyEpoch(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAuditorKeyEpoch] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfConfidentialOutstandingAmount (SoeDefault)
|
||||
* @return Reference to this builder for method chaining.
|
||||
|
||||
@@ -311,6 +311,78 @@ public:
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfLEVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfVaultKind (SoeDefault)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT8::type::value_type>
|
||||
getVaultKind() const
|
||||
{
|
||||
if (hasVaultKind())
|
||||
return this->sle_->at(sfVaultKind);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfVaultKind is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasVaultKind() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfVaultKind);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSubscriptionDate (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSubscriptionDate() const
|
||||
{
|
||||
if (hasSubscriptionDate())
|
||||
return this->sle_->at(sfSubscriptionDate);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSubscriptionDate is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSubscriptionDate() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSubscriptionDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfRedemptionDate (SoeOptional)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getRedemptionDate() const
|
||||
{
|
||||
if (hasRedemptionDate())
|
||||
return this->sle_->at(sfRedemptionDate);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfRedemptionDate is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasRedemptionDate() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfRedemptionDate);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -543,6 +615,39 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfVaultKind (SoeDefault)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
VaultBuilder&
|
||||
setVaultKind(std::decay_t<typename SF_UINT8::type::value_type> const& value)
|
||||
{
|
||||
object_[sfVaultKind] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSubscriptionDate (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
VaultBuilder&
|
||||
setSubscriptionDate(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSubscriptionDate] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfRedemptionDate (SoeOptional)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
VaultBuilder&
|
||||
setRedemptionDate(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfRedemptionDate] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed Vault wrapper.
|
||||
* @param index The ledger entry index.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMBidBuilder;
|
||||
* Type: ttAMM_BID (39)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMBidBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMClawbackBuilder;
|
||||
* Type: ttAMM_CLAWBACK (31)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMMClawback
|
||||
* Privileges: MayDeleteAcct | OverrideFreeze | MayAuthorizeMpt
|
||||
* Privileges: Privilege::MayDeleteAcct | Privilege::OverrideFreeze | Privilege::MayAuthorizeMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMClawbackBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMCreateBuilder;
|
||||
* Type: ttAMM_CREATE (35)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Privileges: CreatePseudoAcct | MayCreateMpt
|
||||
* Privileges: Privilege::CreatePseudoAcct | Privilege::MayCreateMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMCreateBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMDeleteBuilder;
|
||||
* Type: ttAMM_DELETE (40)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Privileges: MustDeleteAcct | MayDeleteMpt
|
||||
* Privileges: Privilege::MustDeleteAcct | Privilege::MayDeleteMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMDeleteBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMDepositBuilder;
|
||||
* Type: ttAMM_DEPOSIT (36)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMDepositBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMVoteBuilder;
|
||||
* Type: ttAMM_VOTE (38)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMVoteBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AMMWithdrawBuilder;
|
||||
* Type: ttAMM_WITHDRAW (37)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureAMM
|
||||
* Privileges: MayDeleteAcct | MayAuthorizeMpt
|
||||
* Privileges: Privilege::MayDeleteAcct | Privilege::MayAuthorizeMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AMMWithdrawBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AccountDeleteBuilder;
|
||||
* Type: ttACCOUNT_DELETE (21)
|
||||
* Delegable: Delegation::NotDelegable
|
||||
* Amendment: uint256{}
|
||||
* Privileges: MustDeleteAcct
|
||||
* Privileges: Privilege::MustDeleteAcct
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AccountDeleteBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class AccountSetBuilder;
|
||||
* Type: ttACCOUNT_SET (3)
|
||||
* Delegable: Delegation::NotDelegable
|
||||
* Amendment: uint256{}
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use AccountSetBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class BatchBuilder;
|
||||
* Type: ttBATCH (71)
|
||||
* Delegable: Delegation::NotDelegable
|
||||
* Amendment: featureBatchV1_1
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use BatchBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class CheckCancelBuilder;
|
||||
* Type: ttCHECK_CANCEL (18)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: uint256{}
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use CheckCancelBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class CheckCashBuilder;
|
||||
* Type: ttCHECK_CASH (17)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: uint256{}
|
||||
* Privileges: MayCreateMpt
|
||||
* Privileges: Privilege::MayCreateMpt
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use CheckCashBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class CheckCreateBuilder;
|
||||
* Type: ttCHECK_CREATE (16)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: uint256{}
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use CheckCreateBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ClawbackBuilder;
|
||||
* Type: ttCLAWBACK (30)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: uint256{}
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ClawbackBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ConfidentialMPTClawbackBuilder;
|
||||
* Type: ttCONFIDENTIAL_MPT_CLAWBACK (89)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureConfidentialTransfer
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ConfidentialMPTClawbackBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ConfidentialMPTConvertBuilder;
|
||||
* Type: ttCONFIDENTIAL_MPT_CONVERT (85)
|
||||
* Delegable: Delegation::NotDelegable
|
||||
* Amendment: featureConfidentialTransfer
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ConfidentialMPTConvertBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ConfidentialMPTConvertBackBuilder;
|
||||
* Type: ttCONFIDENTIAL_MPT_CONVERT_BACK (87)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureConfidentialTransfer
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ConfidentialMPTConvertBackBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ConfidentialMPTMergeInboxBuilder;
|
||||
* Type: ttCONFIDENTIAL_MPT_MERGE_INBOX (86)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureConfidentialTransfer
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ConfidentialMPTMergeInboxBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ConfidentialMPTSendBuilder;
|
||||
* Type: ttCONFIDENTIAL_MPT_SEND (88)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureConfidentialTransfer
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ConfidentialMPTSendBuilder to construct new transactions.
|
||||
|
||||
@@ -21,7 +21,7 @@ class ContractCallBuilder;
|
||||
* Type: ttCONTRACT_CALL (97)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: NoPriv
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractCallBuilder to construct new transactions.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user