Compare commits

..

8 Commits

Author SHA1 Message Date
Michael Legleux
09690f1b38 Set version to 2.5.0-b1 2025-05-18 20:39:18 +01:00
Valentin Balaschenko
380ba9f1c1 Fix: Resolve slow test on macOS pipeline (#5392)
Using std::barrier performs extremely poorly (~1 hour vs ~1 minute to run the test suite) in certain macOS environments.
To unblock our macOS CI pipeline, std::barrier has been replaced with a custom mutex-based barrier (Barrier) that significantly improves performance without compromising correctness.
2025-05-16 10:31:51 +00:00
brettmollin
c3e9380fb4 fix: Update validators-example.txt fix xrplf example URL (#5384) 2025-05-16 09:49:14 +00:00
Jingchen
e3ebc253fa fix: Ensure that coverage file generation is atomic. (#5426)
Running unit tests in parallel and multiple threads can write into one file can corrupt output files, and then gcovr won't be able to parse the corrupted file. This change adds -fprofile-update=atomic as instructed by https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68080.
2025-05-12 14:54:01 +00:00
Bart
c6c7c84355 Configure CODEOWNERS for changes to RPC code (#5266)
To ensure changes to any RPC-related code are compatible with other services, such as Clio, the RPC team will be required to review them.
2025-05-12 12:42:03 +00:00
yinyiqian1
28f50cb7cf fix: enable LedgerStateFix for delegation (#5427) 2025-05-10 10:36:11 -04:00
Vito Tumas
3e152fec74 refactor: use east const convention (#5409)
This change refactors the codebase to use the "east const convention", and adds a clang-format rule to follow this convention.
2025-05-08 11:00:42 +00:00
yinyiqian1
2db2791805 Add PermissionDelegation feature (#5354)
This change implements the account permission delegation described in XLS-75d, see https://github.com/XRPLF/XRPL-Standards/pull/257.

* Introduces transaction-level and granular permissions that can be delegated to other accounts.
* Adds `DelegateSet` transaction to grant specified permissions to another account.
* Adds `ltDelegate` ledger object to maintain the permission list for delegating/delegated account pair.
* Adds an optional `Delegate` field in common fields, allowing a delegated account to send transactions on behalf of the delegating account within the granted permission scope. The `Account` field remains the delegating account; the `Delegate` field specifies the delegated account. The transaction is signed by the delegated account.
2025-05-08 06:14:02 -04:00
428 changed files with 5591 additions and 17509 deletions

View File

@@ -94,3 +94,4 @@ SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
QualifierAlignment: Right

8
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,8 @@
# Allow anyone to review any change by default.
*
# Require the rpc-reviewers team to review changes to the rpc code.
include/libxrpl/protocol/ @xrplf/rpc-reviewers
src/libxrpl/protocol/ @xrplf/rpc-reviewers
src/xrpld/rpc/ @xrplf/rpc-reviewers
src/xrpld/app/misc/ @xrplf/rpc-reviewers

View File

@@ -71,6 +71,9 @@ jobs:
nproc --version
echo -n "nproc returns: "
nproc
system_profiler SPHardwareDataType
sysctl -n hw.logicalcpu
clang --version
- name: configure Conan
run : |
conan profile new default --detect || true
@@ -89,9 +92,8 @@ jobs:
generator: ${{ matrix.generator }}
configuration: ${{ matrix.configuration }}
cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}"
# TODO: Temporary disabled tests
# - name: test
# run: |
# n=$(nproc)
# echo "Using $n test jobs"
# ${build_dir}/rippled --unittest --unittest-jobs $n
- name: test
run: |
n=$(nproc)
echo "Using $n test jobs"
${build_dir}/rippled --unittest --unittest-jobs $n

View File

@@ -247,7 +247,7 @@ jobs:
mkdir -p ~/.conan
tar -xzf conan.tar -C ~/.conan
- name: install gcovr
run: pip install "gcovr>=7,<8"
run: pip install "gcovr>=7,<9"
- name: check environment
run: |
echo ${PATH} | tr ':' '\n'

View File

@@ -26,7 +26,7 @@
#
# Examples:
# https://vl.ripple.com
# https://vl.xrplf.org
# https://unl.xrplf.org
# http://127.0.0.1:8000
# file:///etc/opt/ripple/vl.txt
#

View File

@@ -98,6 +98,9 @@
# 2024-04-03, Bronek Kozicki
# - add support for output formats: jacoco, clover, lcov
#
# 2025-05-12, Jingchen Wu
# - add -fprofile-update=atomic to ensure atomic profile generation
#
# USAGE:
#
# 1. Copy this file into your cmake modules path.
@@ -200,15 +203,27 @@ set(COVERAGE_COMPILER_FLAGS "-g --coverage"
CACHE INTERNAL "")
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
if(HAVE_cxx_fprofile_abs_path)
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
include(CheckCCompilerFlag)
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
if(HAVE_c_fprofile_abs_path)
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
check_cxx_compiler_flag(-fprofile-update HAVE_cxx_fprofile_update)
if(HAVE_cxx_fprofile_update)
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-update=atomic")
endif()
check_c_compiler_flag(-fprofile-update HAVE_c_fprofile_update)
if(HAVE_c_fprofile_update)
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-update=atomic")
endif()
endif()
set(CMAKE_Fortran_FLAGS_COVERAGE

View File

@@ -367,7 +367,7 @@ get(Section const& section,
}
inline std::string
get(Section const& section, std::string const& name, const char* defaultValue)
get(Section const& section, std::string const& name, char const* defaultValue)
{
try
{

View File

@@ -55,7 +55,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
auto compressed = bf(outCapacity);
auto compressedSize = LZ4_compress_default(
reinterpret_cast<const char*>(in),
reinterpret_cast<char const*>(in),
reinterpret_cast<char*>(compressed),
inSize,
outCapacity);
@@ -89,7 +89,7 @@ lz4Decompress(
Throw<std::runtime_error>("lz4Decompress: integer overflow (output)");
if (LZ4_decompress_safe(
reinterpret_cast<const char*>(in),
reinterpret_cast<char const*>(in),
reinterpret_cast<char*>(decompressed),
inSize,
decompressedSize) != decompressedSize)

View File

@@ -93,7 +93,7 @@ public:
{
}
constexpr const E&
constexpr E const&
value() const&
{
return val_;
@@ -111,7 +111,7 @@ public:
return std::move(val_);
}
constexpr const E&&
constexpr E const&&
value() const&&
{
return std::move(val_);

View File

@@ -115,7 +115,7 @@ public:
sweep();
bool
del(const key_type& key, bool valid);
del(key_type const& key, bool valid);
public:
/** Replace aliased objects with originals.
@@ -134,20 +134,20 @@ public:
template <class R>
bool
canonicalize(
const key_type& key,
key_type const& key,
SharedPointerType& data,
R&& replaceCallback);
bool
canonicalize_replace_cache(
const key_type& key,
key_type const& key,
SharedPointerType const& data);
bool
canonicalize_replace_client(const key_type& key, SharedPointerType& data);
canonicalize_replace_client(key_type const& key, SharedPointerType& data);
SharedPointerType
fetch(const key_type& key);
fetch(key_type const& key);
/** Insert the element into the container.
If the key already exists, nothing happens.
@@ -168,7 +168,7 @@ public:
// simply return an iterator.
//
bool
retrieve(const key_type& key, T& data);
retrieve(key_type const& key, T& data);
mutex_type&
peekMutex();
@@ -322,10 +322,10 @@ private:
std::string m_name;
// Desired number of cache entries (0 = ignore)
const int m_target_size;
int const m_target_size;
// Desired maximum cache age
const clock_type::duration m_target_age;
clock_type::duration const m_target_age;
// Number of items cached
int m_cache_count;

View File

@@ -365,7 +365,7 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::del(const key_type& key, bool valid)
Mutex>::del(key_type const& key, bool valid)
{
// Remove from cache, if !valid, remove from map too. Returns true if
// removed from cache
@@ -414,7 +414,7 @@ TaggedCache<
KeyEqual,
Mutex>::
canonicalize(
const key_type& key,
key_type const& key,
SharedPointerType& data,
R&& replaceCallback)
{
@@ -509,7 +509,7 @@ TaggedCache<
KeyEqual,
Mutex>::
canonicalize_replace_cache(
const key_type& key,
key_type const& key,
SharedPointerType const& data)
{
return canonicalize(
@@ -535,7 +535,7 @@ TaggedCache<
Hash,
KeyEqual,
Mutex>::
canonicalize_replace_client(const key_type& key, SharedPointerType& data)
canonicalize_replace_client(key_type const& key, SharedPointerType& data)
{
return canonicalize(key, data, []() { return false; });
}
@@ -558,7 +558,7 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::fetch(const key_type& key)
Mutex>::fetch(key_type const& key)
{
std::lock_guard<mutex_type> l(m_mutex);
auto ret = initialFetch(key, l);
@@ -656,7 +656,7 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::retrieve(const key_type& key, T& data)
Mutex>::retrieve(key_type const& key, T& data)
{
// retrieve the value of the stored data
auto entry = fetch(key);

View File

@@ -374,7 +374,7 @@ public:
}
base_uint&
operator^=(const base_uint& b)
operator^=(base_uint const& b)
{
for (int i = 0; i < WIDTH; i++)
data_[i] ^= b.data_[i];
@@ -383,7 +383,7 @@ public:
}
base_uint&
operator&=(const base_uint& b)
operator&=(base_uint const& b)
{
for (int i = 0; i < WIDTH; i++)
data_[i] &= b.data_[i];
@@ -392,7 +392,7 @@ public:
}
base_uint&
operator|=(const base_uint& b)
operator|=(base_uint const& b)
{
for (int i = 0; i < WIDTH; i++)
data_[i] |= b.data_[i];
@@ -415,11 +415,11 @@ public:
return *this;
}
const base_uint
base_uint const
operator++(int)
{
// postfix operator
const base_uint ret = *this;
base_uint const ret = *this;
++(*this);
return ret;
@@ -441,11 +441,11 @@ public:
return *this;
}
const base_uint
base_uint const
operator--(int)
{
// postfix operator
const base_uint ret = *this;
base_uint const ret = *this;
--(*this);
return ret;
@@ -466,7 +466,7 @@ public:
}
base_uint&
operator+=(const base_uint& b)
operator+=(base_uint const& b)
{
std::uint64_t carry = 0;
@@ -511,7 +511,7 @@ public:
}
[[nodiscard]] constexpr bool
parseHex(const char* str)
parseHex(char const* str)
{
return parseHex(std::string_view{str});
}
@@ -632,13 +632,6 @@ to_string(base_uint<Bits, Tag> const& a)
return strHex(a.cbegin(), a.cend());
}
template <std::size_t Bits, class Tag>
inline std::string
to_short_string(base_uint<Bits, Tag> const& a)
{
return to_string(a).substr(0, 8) + "...";
}
template <std::size_t Bits, class Tag>
inline std::ostream&
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)

View File

@@ -43,7 +43,7 @@ struct less
using result_type = bool;
constexpr bool
operator()(const T& left, const T& right) const
operator()(T const& left, T const& right) const
{
return std::less<T>()(left, right);
}
@@ -55,7 +55,7 @@ struct equal_to
using result_type = bool;
constexpr bool
operator()(const T& left, const T& right) const
operator()(T const& left, T const& right) const
{
return std::equal_to<T>()(left, right);
}

View File

@@ -52,7 +52,7 @@ template <
typename Value,
typename Hash,
typename Pred = std::equal_to<Key>,
typename Alloc = std::allocator<std::pair<const Key, Value>>>
typename Alloc = std::allocator<std::pair<Key const, Value>>>
class partitioned_unordered_map
{
std::size_t partitions_;

View File

@@ -76,13 +76,13 @@ public:
}
bool
operator<(const tagged_integer& rhs) const noexcept
operator<(tagged_integer const& rhs) const noexcept
{
return m_value < rhs.m_value;
}
bool
operator==(const tagged_integer& rhs) const noexcept
operator==(tagged_integer const& rhs) const noexcept
{
return m_value == rhs.m_value;
}
@@ -144,14 +144,14 @@ public:
}
tagged_integer&
operator<<=(const tagged_integer& rhs) noexcept
operator<<=(tagged_integer const& rhs) noexcept
{
m_value <<= rhs.m_value;
return *this;
}
tagged_integer&
operator>>=(const tagged_integer& rhs) noexcept
operator>>=(tagged_integer const& rhs) noexcept
{
m_value >>= rhs.m_value;
return *this;

View File

@@ -39,8 +39,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE
#define XRPL_ASSERT2(cond, location, message, ...) \
XRPL_ASSERT(cond, std::string(location) + " : " + message)
// How to use the instrumentation macros:
//

View File

@@ -37,9 +37,9 @@ class temp_dir
public:
#if !GENERATING_DOCS
temp_dir(const temp_dir&) = delete;
temp_dir(temp_dir const&) = delete;
temp_dir&
operator=(const temp_dir&) = delete;
operator=(temp_dir const&) = delete;
#endif
/// Construct a temporary directory.

View File

@@ -39,7 +39,7 @@ class Reader
{
public:
using Char = char;
using Location = const Char*;
using Location = Char const*;
/** \brief Constructs a Reader allowing all features
* for parsing.
@@ -64,7 +64,7 @@ public:
* error occurred.
*/
bool
parse(const char* beginDoc, const char* endDoc, Value& root);
parse(char const* beginDoc, char const* endDoc, Value& root);
/// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&).
@@ -133,7 +133,7 @@ private:
using Errors = std::deque<ErrorInfo>;
bool
expectToken(TokenType type, Token& token, const char* message);
expectToken(TokenType type, Token& token, char const* message);
bool
readToken(Token& token);
void

View File

@@ -20,13 +20,11 @@
#ifndef RIPPLE_JSON_JSON_VALUE_H_INCLUDED
#define RIPPLE_JSON_JSON_VALUE_H_INCLUDED
#include <xrpl/basics/Number.h>
#include <xrpl/json/json_forwards.h>
#include <cstring>
#include <map>
#include <string>
#include <utility>
#include <vector>
/** \brief JSON (JavaScript Object Notation).
@@ -63,24 +61,24 @@ enum ValueType {
class StaticString
{
public:
constexpr explicit StaticString(const char* czstring) : str_(czstring)
constexpr explicit StaticString(char const* czstring) : str_(czstring)
{
}
constexpr
operator const char*() const
operator char const*() const
{
return str_;
}
constexpr const char*
constexpr char const*
c_str() const
{
return str_;
}
private:
const char* str_;
char const* str_;
};
inline bool
@@ -158,10 +156,10 @@ public:
using Int = Json::Int;
using ArrayIndex = UInt;
static const Value null;
static const Int minInt;
static const Int maxInt;
static const UInt maxUInt;
static Value const null;
static Int const minInt;
static Int const maxInt;
static UInt const maxUInt;
private:
class CZString
@@ -173,24 +171,24 @@ private:
duplicateOnCopy
};
CZString(int index);
CZString(const char* cstr, DuplicationPolicy allocate);
CZString(const CZString& other);
CZString(char const* cstr, DuplicationPolicy allocate);
CZString(CZString const& other);
~CZString();
CZString&
operator=(const CZString& other) = delete;
operator=(CZString const& other) = delete;
bool
operator<(const CZString& other) const;
operator<(CZString const& other) const;
bool
operator==(const CZString& other) const;
operator==(CZString const& other) const;
int
index() const;
const char*
char const*
c_str() const;
bool
isStaticString() const;
private:
const char* cstr_;
char const* cstr_;
int index_;
};
@@ -217,8 +215,7 @@ public:
Value(Int value);
Value(UInt value);
Value(double value);
Value(const char* value);
Value(ripple::Number const& value);
Value(char const* value);
/** \brief Constructs a value from a static string.
* Like other value string constructor but do not duplicate the string for
@@ -230,10 +227,10 @@ public:
* Json::Value aValue( StaticString("some text") );
* \endcode
*/
Value(const StaticString& value);
Value(StaticString const& value);
Value(std::string const& value);
Value(bool value);
Value(const Value& other);
Value(Value const& other);
~Value();
Value&
@@ -250,7 +247,7 @@ public:
ValueType
type() const;
const char*
char const*
asCString() const;
/** Returns the unquoted string value. */
std::string
@@ -320,12 +317,12 @@ public:
/// Access an array element (zero based index )
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
const Value&
Value const&
operator[](UInt index) const;
/// If the array contains at least index+1 elements, returns the element
/// value, otherwise returns defaultValue.
Value
get(UInt index, const Value& defaultValue) const;
get(UInt index, Value const& defaultValue) const;
/// Return true if index < size().
bool
isValidIndex(UInt index) const;
@@ -333,25 +330,25 @@ public:
///
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value&
append(const Value& value);
append(Value const& value);
Value&
append(Value&& value);
/// Access an object value by name, create a null member if it does not
/// exist.
Value&
operator[](const char* key);
operator[](char const* key);
/// Access an object value by name, returns null if there is no member with
/// that name.
const Value&
operator[](const char* key) const;
Value const&
operator[](char const* key) const;
/// Access an object value by name, create a null member if it does not
/// exist.
Value&
operator[](std::string const& key);
/// Access an object value by name, returns null if there is no member with
/// that name.
const Value&
Value const&
operator[](std::string const& key) const;
/** \brief Access an object value by name, create a null member if it does
not exist.
@@ -367,16 +364,14 @@ public:
* \endcode
*/
Value&
operator[](const StaticString& key);
Value const&
operator[](const StaticString& key) const;
operator[](StaticString const& key);
/// Return the member named key if it exist, defaultValue otherwise.
Value
get(const char* key, const Value& defaultValue) const;
get(char const* key, Value const& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
Value
get(std::string const& key, const Value& defaultValue) const;
get(std::string const& key, Value const& defaultValue) const;
/// \brief Remove and return the named member.
///
@@ -385,14 +380,14 @@ public:
/// \pre type() is objectValue or nullValue
/// \post type() is unchanged
Value
removeMember(const char* key);
removeMember(char const* key);
/// Same as removeMember(const char*)
Value
removeMember(std::string const& key);
/// Return true if the object has a member named key.
bool
isMember(const char* key) const;
isMember(char const* key) const;
/// Return true if the object has a member named key.
bool
isMember(std::string const& key) const;
@@ -419,13 +414,13 @@ public:
end();
friend bool
operator==(const Value&, const Value&);
operator==(Value const&, Value const&);
friend bool
operator<(const Value&, const Value&);
operator<(Value const&, Value const&);
private:
Value&
resolveReference(const char* key, bool isStatic);
resolveReference(char const* key, bool isStatic);
private:
union ValueHolder
@@ -441,38 +436,32 @@ private:
int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
};
inline Value
to_json(ripple::Number const& number)
{
return to_string(number);
}
bool
operator==(const Value&, const Value&);
operator==(Value const&, Value const&);
inline bool
operator!=(const Value& x, const Value& y)
operator!=(Value const& x, Value const& y)
{
return !(x == y);
}
bool
operator<(const Value&, const Value&);
operator<(Value const&, Value const&);
inline bool
operator<=(const Value& x, const Value& y)
operator<=(Value const& x, Value const& y)
{
return !(y < x);
}
inline bool
operator>(const Value& x, const Value& y)
operator>(Value const& x, Value const& y)
{
return y < x;
}
inline bool
operator>=(const Value& x, const Value& y)
operator>=(Value const& x, Value const& y)
{
return !(x < y);
}
@@ -493,11 +482,11 @@ public:
virtual ~ValueAllocator() = default;
virtual char*
makeMemberName(const char* memberName) = 0;
makeMemberName(char const* memberName) = 0;
virtual void
releaseMemberName(char* memberName) = 0;
virtual char*
duplicateStringValue(const char* value, unsigned int length = unknown) = 0;
duplicateStringValue(char const* value, unsigned int length = unknown) = 0;
virtual void
releaseStringValue(char* value) = 0;
};
@@ -514,16 +503,16 @@ public:
ValueIteratorBase();
explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
explicit ValueIteratorBase(Value::ObjectValues::iterator const& current);
bool
operator==(const SelfType& other) const
operator==(SelfType const& other) const
{
return isEqual(other);
}
bool
operator!=(const SelfType& other) const
operator!=(SelfType const& other) const
{
return !isEqual(other);
}
@@ -539,7 +528,7 @@ public:
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
const char*
char const*
memberName() const;
protected:
@@ -553,13 +542,13 @@ protected:
decrement();
difference_type
computeDistance(const SelfType& other) const;
computeDistance(SelfType const& other) const;
bool
isEqual(const SelfType& other) const;
isEqual(SelfType const& other) const;
void
copy(const SelfType& other);
copy(SelfType const& other);
private:
Value::ObjectValues::iterator current_;
@@ -577,8 +566,8 @@ class ValueConstIterator : public ValueIteratorBase
public:
using size_t = unsigned int;
using difference_type = int;
using reference = const Value&;
using pointer = const Value*;
using reference = Value const&;
using pointer = Value const*;
using SelfType = ValueConstIterator;
ValueConstIterator() = default;
@@ -586,11 +575,11 @@ public:
private:
/*! \internal Use by Value to create an iterator.
*/
explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
explicit ValueConstIterator(Value::ObjectValues::iterator const& current);
public:
SelfType&
operator=(const ValueIteratorBase& other);
operator=(ValueIteratorBase const& other);
SelfType
operator++(int)
@@ -643,17 +632,17 @@ public:
using SelfType = ValueIterator;
ValueIterator() = default;
ValueIterator(const ValueConstIterator& other);
ValueIterator(const ValueIterator& other);
ValueIterator(ValueConstIterator const& other);
ValueIterator(ValueIterator const& other);
private:
/*! \internal Use by Value to create an iterator.
*/
explicit ValueIterator(const Value::ObjectValues::iterator& current);
explicit ValueIterator(Value::ObjectValues::iterator const& current);
public:
SelfType&
operator=(const SelfType& other);
operator=(SelfType const& other);
SelfType
operator++(int)

View File

@@ -39,7 +39,7 @@ public:
{
}
virtual std::string
write(const Value& root) = 0;
write(Value const& root) = 0;
};
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
@@ -60,11 +60,11 @@ public:
public: // overridden from Writer
std::string
write(const Value& root) override;
write(Value const& root) override;
private:
void
writeValue(const Value& value);
writeValue(Value const& value);
std::string document_;
};
@@ -101,15 +101,15 @@ public: // overridden from Writer
* JSON document that represents the root value.
*/
std::string
write(const Value& root) override;
write(Value const& root) override;
private:
void
writeValue(const Value& value);
writeValue(Value const& value);
void
writeArrayValue(const Value& value);
writeArrayValue(Value const& value);
bool
isMultineArray(const Value& value);
isMultineArray(Value const& value);
void
pushValue(std::string const& value);
void
@@ -168,15 +168,15 @@ public:
* return a value.
*/
void
write(std::ostream& out, const Value& root);
write(std::ostream& out, Value const& root);
private:
void
writeValue(const Value& value);
writeValue(Value const& value);
void
writeArrayValue(const Value& value);
writeArrayValue(Value const& value);
bool
isMultineArray(const Value& value);
isMultineArray(Value const& value);
void
pushValue(std::string const& value);
void
@@ -207,12 +207,12 @@ valueToString(double value);
std::string
valueToString(bool value);
std::string
valueToQuotedString(const char* value);
valueToQuotedString(char const* value);
/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
std::ostream&
operator<<(std::ostream&, const Value& root);
operator<<(std::ostream&, Value const& root);
//------------------------------------------------------------------------------

View File

@@ -37,7 +37,7 @@ pretty(Value const&);
/** Output using the StyledStreamWriter. @see Json::operator>>(). */
std::ostream&
operator<<(std::ostream&, const Value& root);
operator<<(std::ostream&, Value const& root);
} // namespace Json

View File

@@ -48,6 +48,14 @@ class STObject;
class STAmount;
class Rules;
/** Calculate AMM account ID.
*/
AccountID
ammAccountID(
std::uint16_t prefix,
uint256 const& parentHash,
uint256 const& ammID);
/** Calculate Liquidity Provider Token (LPT) Currency.
*/
Currency

View File

@@ -20,7 +20,6 @@
#ifndef RIPPLE_PROTOCOL_ASSET_H_INCLUDED
#define RIPPLE_PROTOCOL_ASSET_H_INCLUDED
#include <xrpl/basics/Number.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>
@@ -28,7 +27,6 @@
namespace ripple {
class Asset;
class STAmount;
template <typename TIss>
concept ValidIssueType =
@@ -94,9 +92,6 @@ public:
void
setJson(Json::Value& jv) const;
STAmount
operator()(Number const&) const;
bool
native() const
{
@@ -119,14 +114,6 @@ public:
equalTokens(Asset const& lhs, Asset const& rhs);
};
inline Json::Value
to_json(Asset const& asset)
{
Json::Value jv;
asset.setJson(jv);
return jv;
}
template <ValidIssueType TIss>
constexpr bool
Asset::holds() const
@@ -232,6 +219,9 @@ validJSONAsset(Json::Value const& jv);
Asset
assetFromJson(Json::Value const& jv);
Json::Value
to_json(Asset const& asset);
} // namespace ripple
#endif // RIPPLE_PROTOCOL_ASSET_H_INCLUDED

View File

@@ -120,7 +120,7 @@ enum error_code_i {
rpcSRC_ACT_MALFORMED = 65,
rpcSRC_ACT_MISSING = 66,
rpcSRC_ACT_NOT_FOUND = 67,
// unused 68,
rpcDELEGATE_ACT_NOT_FOUND = 68,
rpcSRC_CUR_MALFORMED = 69,
rpcSRC_ISR_MALFORMED = 70,
rpcSTREAM_MALFORMED = 71,

View File

@@ -16,8 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef PROTOCOL_UNITS_H_INCLUDED
#define PROTOCOL_UNITS_H_INCLUDED
#ifndef BASICS_FEES_H_INCLUDED
#define BASICS_FEES_H_INCLUDED
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/Zero.h>
@@ -38,23 +38,23 @@
namespace ripple {
namespace unit {
namespace feeunit {
/** "drops" are the smallest divisible amount of XRP. This is what most
of the code uses. */
struct dropTag;
/** "fee units" calculations are a not-really-unitless value that is used
to express the cost of a given transaction vs. a reference transaction.
They are primarily used by the Transactor classes. */
struct feeunitTag;
/** "fee levels" are used by the transaction queue to compare the relative
cost of transactions that require different levels of effort to process.
See also: src/ripple/app/misc/FeeEscalation.md#fee-level */
struct feelevelTag;
/** unitless values are plain scalars wrapped in a ValueUnit. They are
/** unitless values are plain scalars wrapped in a TaggedFee. They are
used for calculations in this header. */
struct unitlessTag;
/** Units to represent basis points (bips) and 1/10 basis points */
class BipsTag;
class TenthBipsTag;
template <class T>
using enable_if_unit_t = typename std::enable_if_t<
std::is_class_v<T> && std::is_object_v<typename T::unit_type> &&
@@ -62,33 +62,32 @@ using enable_if_unit_t = typename std::enable_if_t<
/** `is_usable_unit_v` is checked to ensure that only values with
known valid type tags can be used (sometimes transparently) in
non-unit contexts. At the time of implementation, this includes
non-fee contexts. At the time of implementation, this includes
all known tags, but more may be added in the future, and they
should not be added automatically unless determined to be
appropriate.
*/
template <class T, class = enable_if_unit_t<T>>
constexpr bool is_usable_unit_v =
std::is_same_v<typename T::unit_type, feeunitTag> ||
std::is_same_v<typename T::unit_type, feelevelTag> ||
std::is_same_v<typename T::unit_type, unitlessTag> ||
std::is_same_v<typename T::unit_type, dropTag> ||
std::is_same_v<typename T::unit_type, BipsTag> ||
std::is_same_v<typename T::unit_type, TenthBipsTag>;
std::is_same_v<typename T::unit_type, dropTag>;
template <class UnitTag, class T>
class ValueUnit : private boost::totally_ordered<ValueUnit<UnitTag, T>>,
private boost::additive<ValueUnit<UnitTag, T>>,
private boost::equality_comparable<ValueUnit<UnitTag, T>, T>,
private boost::dividable<ValueUnit<UnitTag, T>, T>,
private boost::modable<ValueUnit<UnitTag, T>, T>,
private boost::unit_steppable<ValueUnit<UnitTag, T>>
class TaggedFee : private boost::totally_ordered<TaggedFee<UnitTag, T>>,
private boost::additive<TaggedFee<UnitTag, T>>,
private boost::equality_comparable<TaggedFee<UnitTag, T>, T>,
private boost::dividable<TaggedFee<UnitTag, T>, T>,
private boost::modable<TaggedFee<UnitTag, T>, T>,
private boost::unit_steppable<TaggedFee<UnitTag, T>>
{
public:
using unit_type = UnitTag;
using value_type = T;
private:
value_type value_;
value_type fee_;
protected:
template <class Other>
@@ -96,44 +95,44 @@ protected:
std::is_arithmetic_v<Other> && std::is_arithmetic_v<value_type> &&
std::is_convertible_v<Other, value_type>;
template <class OtherValue, class = enable_if_unit_t<OtherValue>>
static constexpr bool is_compatiblevalue_v =
is_compatible_v<typename OtherValue::value_type> &&
std::is_same_v<UnitTag, typename OtherValue::unit_type>;
template <class OtherFee, class = enable_if_unit_t<OtherFee>>
static constexpr bool is_compatiblefee_v =
is_compatible_v<typename OtherFee::value_type> &&
std::is_same_v<UnitTag, typename OtherFee::unit_type>;
template <class Other>
using enable_if_compatible_t =
typename std::enable_if_t<is_compatible_v<Other>>;
template <class OtherValue>
using enable_if_compatiblevalue_t =
typename std::enable_if_t<is_compatiblevalue_v<OtherValue>>;
template <class OtherFee>
using enable_if_compatiblefee_t =
typename std::enable_if_t<is_compatiblefee_v<OtherFee>>;
public:
ValueUnit() = default;
constexpr ValueUnit(ValueUnit const& other) = default;
constexpr ValueUnit&
operator=(ValueUnit const& other) = default;
TaggedFee() = default;
constexpr TaggedFee(TaggedFee const& other) = default;
constexpr TaggedFee&
operator=(TaggedFee const& other) = default;
constexpr explicit ValueUnit(beast::Zero) : value_(0)
constexpr explicit TaggedFee(beast::Zero) : fee_(0)
{
}
constexpr ValueUnit&
constexpr TaggedFee&
operator=(beast::Zero)
{
value_ = 0;
fee_ = 0;
return *this;
}
constexpr explicit ValueUnit(value_type value) : value_(value)
constexpr explicit TaggedFee(value_type fee) : fee_(fee)
{
}
constexpr ValueUnit&
operator=(value_type value)
TaggedFee&
operator=(value_type fee)
{
value_ = value;
fee_ = fee;
return *this;
}
@@ -145,181 +144,153 @@ public:
class = std::enable_if_t<
is_compatible_v<Other> &&
is_safetocasttovalue_v<value_type, Other>>>
constexpr ValueUnit(ValueUnit<unit_type, Other> const& value)
: ValueUnit(safe_cast<value_type>(value.value()))
constexpr TaggedFee(TaggedFee<unit_type, Other> const& fee)
: TaggedFee(safe_cast<value_type>(fee.fee()))
{
}
constexpr ValueUnit
operator+(value_type const& rhs) const
{
return ValueUnit{value_ + rhs};
}
friend constexpr ValueUnit
operator+(value_type lhs, ValueUnit const& rhs)
{
// addition is commutative
return rhs + lhs;
}
constexpr ValueUnit
operator-(value_type const& rhs) const
{
return ValueUnit{value_ - rhs};
}
friend constexpr ValueUnit
operator-(value_type lhs, ValueUnit const& rhs)
{
// subtraction is NOT commutative, but (lhs + (-rhs)) is addition, which
// is
return -rhs + lhs;
}
constexpr ValueUnit
constexpr TaggedFee
operator*(value_type const& rhs) const
{
return ValueUnit{value_ * rhs};
return TaggedFee{fee_ * rhs};
}
friend constexpr ValueUnit
operator*(value_type lhs, ValueUnit const& rhs)
friend constexpr TaggedFee
operator*(value_type lhs, TaggedFee const& rhs)
{
// multiplication is commutative
return rhs * lhs;
}
constexpr value_type
operator/(ValueUnit const& rhs) const
operator/(TaggedFee const& rhs) const
{
return value_ / rhs.value_;
return fee_ / rhs.fee_;
}
ValueUnit&
operator+=(ValueUnit const& other)
TaggedFee&
operator+=(TaggedFee const& other)
{
value_ += other.value();
fee_ += other.fee();
return *this;
}
ValueUnit&
operator-=(ValueUnit const& other)
TaggedFee&
operator-=(TaggedFee const& other)
{
value_ -= other.value();
fee_ -= other.fee();
return *this;
}
ValueUnit&
TaggedFee&
operator++()
{
++value_;
++fee_;
return *this;
}
ValueUnit&
TaggedFee&
operator--()
{
--value_;
--fee_;
return *this;
}
ValueUnit&
TaggedFee&
operator*=(value_type const& rhs)
{
value_ *= rhs;
fee_ *= rhs;
return *this;
}
ValueUnit&
TaggedFee&
operator/=(value_type const& rhs)
{
value_ /= rhs;
fee_ /= rhs;
return *this;
}
template <class transparent = value_type>
std::enable_if_t<std::is_integral_v<transparent>, ValueUnit&>
std::enable_if_t<std::is_integral_v<transparent>, TaggedFee&>
operator%=(value_type const& rhs)
{
value_ %= rhs;
fee_ %= rhs;
return *this;
}
ValueUnit
TaggedFee
operator-() const
{
static_assert(
std::is_signed_v<T>, "- operator illegal on unsigned value types");
return ValueUnit{-value_};
std::is_signed_v<T>, "- operator illegal on unsigned fee types");
return TaggedFee{-fee_};
}
constexpr bool
operator==(ValueUnit const& other) const
bool
operator==(TaggedFee const& other) const
{
return value_ == other.value_;
return fee_ == other.fee_;
}
template <class Other, class = enable_if_compatible_t<Other>>
constexpr bool
operator==(ValueUnit<unit_type, Other> const& other) const
bool
operator==(TaggedFee<unit_type, Other> const& other) const
{
return value_ == other.value();
return fee_ == other.fee();
}
constexpr bool
bool
operator==(value_type other) const
{
return value_ == other;
return fee_ == other;
}
template <class Other, class = enable_if_compatible_t<Other>>
constexpr bool
operator!=(ValueUnit<unit_type, Other> const& other) const
bool
operator!=(TaggedFee<unit_type, Other> const& other) const
{
return !operator==(other);
}
constexpr bool
operator<(ValueUnit const& other) const
bool
operator<(TaggedFee const& other) const
{
return value_ < other.value_;
return fee_ < other.fee_;
}
/** Returns true if the amount is not zero */
explicit constexpr
operator bool() const noexcept
{
return value_ != 0;
return fee_ != 0;
}
/** Return the sign of the amount */
constexpr int
signum() const noexcept
{
return (value_ < 0) ? -1 : (value_ ? 1 : 0);
return (fee_ < 0) ? -1 : (fee_ ? 1 : 0);
}
/** Returns the number of drops */
// TODO: Move this to a new class, maybe with the old "TaggedFee" name
constexpr value_type
fee() const
{
return value_;
return fee_;
}
template <class Other>
constexpr double
decimalFromReference(ValueUnit<unit_type, Other> reference) const
decimalFromReference(TaggedFee<unit_type, Other> reference) const
{
return static_cast<double>(value_) / reference.value();
return static_cast<double>(fee_) / reference.fee();
}
// `is_usable_unit_v` is checked to ensure that only values with
// known valid type tags can be converted to JSON. At the time
// of implementation, that includes all known tags, but more may
// be added in the future.
std::enable_if_t<is_usable_unit_v<ValueUnit>, Json::Value>
std::enable_if_t<is_usable_unit_v<TaggedFee>, Json::Value>
jsonClipped() const
{
if constexpr (std::is_integral_v<value_type>)
@@ -332,15 +303,15 @@ public:
constexpr auto min = std::numeric_limits<jsontype>::min();
constexpr auto max = std::numeric_limits<jsontype>::max();
if (value_ < min)
if (fee_ < min)
return min;
if (value_ > max)
if (fee_ > max)
return max;
return static_cast<jsontype>(value_);
return static_cast<jsontype>(fee_);
}
else
{
return value_;
return fee_;
}
}
@@ -351,30 +322,30 @@ public:
constexpr value_type
value() const
{
return value_;
return fee_;
}
friend std::istream&
operator>>(std::istream& s, ValueUnit& val)
operator>>(std::istream& s, TaggedFee& val)
{
s >> val.value_;
s >> val.fee_;
return s;
}
};
// Output Values as just their numeric value.
// Output Fees as just their numeric value.
template <class Char, class Traits, class UnitTag, class T>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os, const ValueUnit<UnitTag, T>& q)
operator<<(std::basic_ostream<Char, Traits>& os, TaggedFee<UnitTag, T> const& q)
{
return os << q.value();
}
template <class UnitTag, class T>
std::string
to_string(ValueUnit<UnitTag, T> const& amount)
to_string(TaggedFee<UnitTag, T> const& amount)
{
return std::to_string(amount.value());
return std::to_string(amount.fee());
}
template <class Source, class = enable_if_unit_t<Source>>
@@ -437,10 +408,10 @@ using enable_muldiv_commute_t =
typename std::enable_if_t<can_muldiv_commute_v<Source1, Source2, Dest>>;
template <class T>
ValueUnit<unitlessTag, T>
TaggedFee<unitlessTag, T>
scalar(T value)
{
return ValueUnit<unitlessTag, T>{value};
return TaggedFee<unitlessTag, T>{value};
}
template <
@@ -451,17 +422,18 @@ template <
std::optional<Dest>
mulDivU(Source1 value, Dest mul, Source2 div)
{
// values can never be negative in any context.
// Fees can never be negative in any context.
if (value.value() < 0 || mul.value() < 0 || div.value() < 0)
{
// split the asserts so if one hits, the user can tell which
// without a debugger.
XRPL_ASSERT(
value.value() >= 0, "ripple::unit::mulDivU : minimum value input");
value.value() >= 0,
"ripple::feeunit::mulDivU : minimum value input");
XRPL_ASSERT(
mul.value() >= 0, "ripple::unit::mulDivU : minimum mul input");
mul.value() >= 0, "ripple::feeunit::mulDivU : minimum mul input");
XRPL_ASSERT(
div.value() >= 0, "ripple::unit::mulDivU : minimum div input");
div.value() >= 0, "ripple::feeunit::mulDivU : minimum div input");
return std::nullopt;
}
@@ -494,57 +466,46 @@ mulDivU(Source1 value, Dest mul, Source2 div)
return Dest{static_cast<desttype>(quotient)};
}
} // namespace unit
} // namespace feeunit
// Fee Levels
template <class T>
using FeeLevel = unit::ValueUnit<unit::feelevelTag, T>;
using FeeLevel = feeunit::TaggedFee<feeunit::feelevelTag, T>;
using FeeLevel64 = FeeLevel<std::uint64_t>;
using FeeLevelDouble = FeeLevel<double>;
// Basis points (Bips)
template <class T>
using Bips = unit::ValueUnit<unit::BipsTag, T>;
using Bips16 = Bips<std::uint16_t>;
using Bips32 = Bips<std::uint32_t>;
template <class T>
using TenthBips = unit::ValueUnit<unit::TenthBipsTag, T>;
using TenthBips16 = TenthBips<std::uint16_t>;
using TenthBips32 = TenthBips<std::uint32_t>;
template <
class Source1,
class Source2,
class Dest,
class = unit::enable_muldiv_t<Source1, Source2, Dest>>
class = feeunit::enable_muldiv_t<Source1, Source2, Dest>>
std::optional<Dest>
mulDiv(Source1 value, Dest mul, Source2 div)
{
return unit::mulDivU(value, mul, div);
return feeunit::mulDivU(value, mul, div);
}
template <
class Source1,
class Source2,
class Dest,
class = unit::enable_muldiv_commute_t<Source1, Source2, Dest>>
class = feeunit::enable_muldiv_commute_t<Source1, Source2, Dest>>
std::optional<Dest>
mulDiv(Dest value, Source1 mul, Source2 div)
{
// Multiplication is commutative
return unit::mulDivU(mul, value, div);
return feeunit::mulDivU(mul, value, div);
}
template <class Dest, class = unit::enable_muldiv_dest_t<Dest>>
template <class Dest, class = feeunit::enable_muldiv_dest_t<Dest>>
std::optional<Dest>
mulDiv(std::uint64_t value, Dest mul, std::uint64_t div)
{
// Give the scalars a non-tag so the
// unit-handling version gets called.
return unit::mulDivU(unit::scalar(value), mul, unit::scalar(div));
return feeunit::mulDivU(feeunit::scalar(value), mul, feeunit::scalar(div));
}
template <class Dest, class = unit::enable_muldiv_dest_t<Dest>>
template <class Dest, class = feeunit::enable_muldiv_dest_t<Dest>>
std::optional<Dest>
mulDiv(Dest value, std::uint64_t mul, std::uint64_t div)
{
@@ -555,13 +516,13 @@ mulDiv(Dest value, std::uint64_t mul, std::uint64_t div)
template <
class Source1,
class Source2,
class = unit::enable_muldiv_sources_t<Source1, Source2>>
class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
std::optional<std::uint64_t>
mulDiv(Source1 value, std::uint64_t mul, Source2 div)
{
// Give the scalars a dimensionless unit so the
// unit-handling version gets called.
auto unitresult = unit::mulDivU(value, unit::scalar(mul), div);
auto unitresult = feeunit::mulDivU(value, feeunit::scalar(mul), div);
if (!unitresult)
return std::nullopt;
@@ -572,7 +533,7 @@ mulDiv(Source1 value, std::uint64_t mul, Source2 div)
template <
class Source1,
class Source2,
class = unit::enable_muldiv_sources_t<Source1, Source2>>
class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
std::optional<std::uint64_t>
mulDiv(std::uint64_t value, Source1 mul, Source2 div)
{
@@ -592,16 +553,6 @@ safe_cast(Src s) noexcept
return Dest{safe_cast<typename Dest::value_type>(s.value())};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_integral_v<typename Dest::value_type> && std::is_integral_v<Src>,
Dest>
safe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s)};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_same_v<typename Dest::unit_type, typename Src::unit_type> &&
@@ -614,16 +565,6 @@ unsafe_cast(Src s) noexcept
return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_integral_v<typename Dest::value_type> && std::is_integral_v<Src>,
Dest>
unsafe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{unsafe_cast<typename Dest::value_type>(s)};
}
} // namespace ripple
#endif // PROTOCOL_UNITS_H_INCLUDED
#endif // BASICS_FEES_H_INCLUDED

View File

@@ -28,6 +28,7 @@
#include <cstdint>
#include <string>
#include <utility>
namespace ripple {

View File

@@ -279,6 +279,10 @@ amm(Asset const& issue1, Asset const& issue2) noexcept;
Keylet
amm(uint256 const& amm) noexcept;
/** A keylet for Delegate object */
Keylet
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept;
Keylet
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
@@ -330,33 +334,6 @@ mptoken(uint256 const& mptokenKey)
Keylet
mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept;
Keylet
vault(AccountID const& owner, std::uint32_t seq) noexcept;
inline Keylet
vault(uint256 const& vaultKey)
{
return {ltVAULT, vaultKey};
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept;
inline Keylet
loanbroker(uint256 const& vaultKey)
{
return {ltLOAN_BROKER, vaultKey};
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept;
inline Keylet
loan(uint256 const& vaultKey)
{
return {ltLOAN, vaultKey};
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept;

View File

@@ -191,14 +191,6 @@ enum LedgerSpecificFlags {
// ltCREDENTIAL
lsfAccepted = 0x00010000,
// ltVAULT
lsfVaultPrivate = 0x00010000,
// ltLOAN
lsfLoanDefault = 0x00010000,
lsfLoanImpaired = 0x00020000,
lsfLoanOverpayment = 0x00040000, // True, loan allows overpayments
};
//------------------------------------------------------------------------------

View File

@@ -24,12 +24,15 @@
#include <xrpl/basics/contract.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/json/json_value.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/operators.hpp>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
namespace ripple {

View File

@@ -42,11 +42,8 @@ public:
AccountID const&
getIssuer() const;
constexpr MPTID const&
getMptID() const
{
return mptID_;
}
MPTID const&
getMptID() const;
std::string
getText() const;

View File

@@ -80,7 +80,7 @@ struct MultiApiJson
}
void
set(const char* key, auto const& v)
set(char const* key, auto const& v)
requires std::constructible_from<Json::Value, decltype(v)>
{
for (auto& a : this->val)
@@ -91,7 +91,7 @@ struct MultiApiJson
enum IsMemberResult : int { none = 0, some, all };
[[nodiscard]] IsMemberResult
isMember(const char* key) const
isMember(char const* key) const
{
int count = 0;
for (auto& a : this->val)

View File

@@ -0,0 +1,97 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_PERMISSION_H_INCLUDED
#define RIPPLE_PROTOCOL_PERMISSION_H_INCLUDED
#include <xrpl/protocol/TxFormats.h>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
namespace ripple {
/**
* We have both transaction type permissions and granular type permissions.
* Since we will reuse the TransactionFormats to parse the Transaction
* Permissions, only the GranularPermissionType is defined here. To prevent
* conflicts with TxType, the GranularPermissionType is always set to a value
* greater than the maximum value of uint16.
*/
enum GranularPermissionType : std::uint32_t {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) type = value,
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
enum Delegation { delegatable, notDelegatable };
class Permission
{
private:
Permission();
std::unordered_map<std::uint16_t, Delegation> delegatableTx_;
std::unordered_map<std::string, GranularPermissionType>
granularPermissionMap_;
std::unordered_map<GranularPermissionType, std::string> granularNameMap_;
std::unordered_map<GranularPermissionType, TxType> granularTxTypeMap_;
public:
static Permission const&
getInstance();
Permission(Permission const&) = delete;
Permission&
operator=(Permission const&) = delete;
std::optional<std::uint32_t>
getGranularValue(std::string const& name) const;
std::optional<std::string>
getGranularName(GranularPermissionType const& value) const;
std::optional<TxType>
getGranularTxType(GranularPermissionType const& gpType) const;
bool
isDelegatable(std::uint32_t const& permissionValue) const;
// for tx level permission, permission value is equal to tx type plus one
uint32_t
txToPermissionType(TxType const& type) const;
// tx type value is permission value minus one
TxType
permissionToTxType(uint32_t const& value) const;
};
} // namespace ripple
#endif

View File

@@ -23,8 +23,6 @@
#include <xrpl/basics/ByteUtilities.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/partitioned_unordered_map.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
@@ -84,90 +82,6 @@ std::size_t constexpr maxDeletableTokenOfferEntries = 500;
*/
std::uint16_t constexpr maxTransferFee = 50000;
/** There are 10,000 basis points (bips) in 100%.
*
* Basis points represent 0.01%.
*
* Given a value X, to find the amount for B bps,
* use X * B / bipsPerUnity
*
* Example: If a loan broker has 999 XRP of debt, and must maintain 1,000 bps of
* that debt as cover (10%), then the minimum cover amount is 999,000,000 drops
* * 1000 / bipsPerUnity = 99,900,00 drops or 99.9 XRP.
*
* Given a percentage P, to find the number of bps that percentage represents,
* use P * bipsPerUnity.
*
* Example: 50% is 0.50 * bipsPerUnity = 5,000 bps.
*/
Bips32 constexpr bipsPerUnity(100 * 100);
TenthBips32 constexpr tenthBipsPerUnity(bipsPerUnity.value() * 10);
constexpr Bips32
percentageToBips(std::uint32_t percentage)
{
return Bips32(percentage * bipsPerUnity.value() / 100);
}
constexpr TenthBips32
percentageToTenthBips(std::uint32_t percentage)
{
return TenthBips32(percentage * tenthBipsPerUnity.value() / 100);
}
template <typename T, class TBips>
constexpr T
bipsOfValue(T value, Bips<TBips> bips)
{
return value * bips.value() / bipsPerUnity.value();
}
template <typename T, class TBips>
constexpr T
tenthBipsOfValue(T value, TenthBips<TBips> bips)
{
return value * bips.value() / tenthBipsPerUnity.value();
}
/** The maximum management fee rate allowed by a loan broker in 1/10 bips.
Valid values are between 0 and 10% inclusive.
*/
TenthBips16 constexpr maxManagementFeeRate(
unsafe_cast<std::uint16_t>(percentageToTenthBips(10).value()));
static_assert(maxManagementFeeRate == TenthBips16(std::uint16_t(10'000u)));
/** The maximum coverage rate required of a loan broker in 1/10 bips.
Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxCoverRate = percentageToTenthBips(100);
static_assert(maxCoverRate == TenthBips32(100'000u));
/** The maximum overpayment fee on a loan in 1/10 bips.
*
Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxOverpaymentFee = percentageToTenthBips(100);
/** The maximum premium added to the interest rate for late payments on a loan
* in 1/10 bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxLateInterestRate = percentageToTenthBips(100);
/** The maximum close interest rate charged for repaying a loan early in 1/10
* bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxCloseInterestRate = percentageToTenthBips(100);
/** The maximum overpayment interest rate charged on loan overpayments in 1/10
* bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxOverpaymentInterestRate = percentageToTenthBips(100);
/** The maximum length of a URI inside an NFT */
std::size_t constexpr maxTokenURILength = 256;
@@ -202,16 +116,6 @@ std::size_t constexpr maxMPTokenMetadataLength = 1024;
/** The maximum amount of MPTokenIssuance */
std::uint64_t constexpr maxMPTokenAmount = 0x7FFF'FFFF'FFFF'FFFFull;
/** The maximum length of Data payload */
std::size_t constexpr maxDataPayloadLength = 256;
/** Vault withdrawal policies */
std::uint8_t constexpr vaultStrategyFirstComeFirstServe = 1;
/** Maximum recursion depth for vault shares being put as an asset inside
* another vault; counted from 0 */
std::uint8_t constexpr maxAssetCheckDepth = 5;
/** A ledger index. */
using LedgerIndex = std::uint32_t;
@@ -251,6 +155,10 @@ std::size_t constexpr maxPriceScale = 20;
*/
std::size_t constexpr maxTrim = 25;
/** The maximum number of delegate permissions an account can grant
*/
std::size_t constexpr permissionMaxSize = 10;
} // namespace ripple
#endif

View File

@@ -113,8 +113,8 @@ public:
// have lower unsigned integer representations.
using value_type = std::uint64_t;
static const int minTickSize = 3;
static const int maxTickSize = 16;
static int const minTickSize = 3;
static int const maxTickSize = 16;
private:
// This has the same representation as STAmount, see the comment on the

View File

@@ -22,10 +22,10 @@
#include <xrpl/basics/safe_cast.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
#include <map>
#include <utility>
namespace ripple {
@@ -54,9 +54,6 @@ class STXChainBridge;
class STVector256;
class STCurrency;
template <class Integer>
concept HasValue = requires(Integer i) { i.value(); };
#pragma push_macro("XMACRO")
#undef XMACRO
@@ -139,9 +136,9 @@ field_code(int id, int index)
the binary format of the transaction can be canonicalized. All
SFields are created at compile time.
Each SField, once constructed, lives until program termination, and
there is only one instance per fieldType/fieldValue pair which serves the
entire application.
Each SField, once constructed, lives until program termination, and there
is only one instance per fieldType/fieldValue pair which serves the entire
application.
*/
class SField
{
@@ -152,11 +149,8 @@ public:
sMD_ChangeNew = 0x02, // new value when it changes
sMD_DeleteFinal = 0x04, // final value when it is deleted
sMD_Create = 0x08, // value when it's created
sMD_Always = 0x10, // value when node containing it is affected at all
sMD_BaseTen = 0x20, // value is treated as base 10, overriding
// default behavior
sMD_PseudoAccount = 0x40, // if this field is set in an ACCOUNT_ROOT
// _only_, then it is a pseudo-account
sMD_Always = 0x10, // value when node containing it is affected at all
sMD_BaseTen = 0x20,
sMD_Default =
sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create
};
@@ -181,30 +175,29 @@ public:
operator=(SField&&) = delete;
public:
struct private_access_tag_t; // public, but still an implementation
// detail
struct private_access_tag_t; // public, but still an implementation detail
// These constructors can only be called from SField.cpp
SField(
private_access_tag_t,
SerializedTypeID tid,
int fv,
const char* fn,
char const* fn,
int meta = sMD_Default,
IsSigning signing = IsSigning::yes);
explicit SField(private_access_tag_t, int fc);
static const SField&
static SField const&
getField(int fieldCode);
static const SField&
static SField const&
getField(std::string const& fieldName);
static const SField&
static SField const&
getField(int type, int value)
{
return getField(field_code(type, value));
}
static const SField&
static SField const&
getField(SerializedTypeID type, int value)
{
return getField(field_code(type, value));
@@ -291,19 +284,19 @@ public:
}
bool
operator==(const SField& f) const
operator==(SField const& f) const
{
return fieldCode == f.fieldCode;
}
bool
operator!=(const SField& f) const
operator!=(SField const& f) const
{
return fieldCode != f.fieldCode;
}
static int
compare(const SField& f1, const SField& f2);
compare(SField const& f1, SField const& f2);
static std::map<int, SField const*> const&
getKnownCodeToField()
@@ -314,7 +307,6 @@ public:
private:
static int num;
static std::map<int, SField const*> knownCodeToField;
static std::map<std::string, SField const*> knownNameToField;
};
/** A field with a type known at compile time. */

View File

@@ -58,7 +58,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;

View File

@@ -62,20 +62,20 @@ private:
public:
using value_type = STAmount;
static const int cMinOffset = -96;
static const int cMaxOffset = 80;
static int const cMinOffset = -96;
static int const cMaxOffset = 80;
// Maximum native value supported by the code
static const std::uint64_t cMinValue = 1000000000000000ull;
static const std::uint64_t cMaxValue = 9999999999999999ull;
static const std::uint64_t cMaxNative = 9000000000000000000ull;
static std::uint64_t const cMinValue = 1000000000000000ull;
static std::uint64_t const cMaxValue = 9999999999999999ull;
static std::uint64_t const cMaxNative = 9000000000000000000ull;
// Max native value on network.
static const std::uint64_t cMaxNativeN = 100000000000000000ull;
static const std::uint64_t cIssuedCurrency = 0x8000000000000000ull;
static const std::uint64_t cPositive = 0x4000000000000000ull;
static const std::uint64_t cMPToken = 0x2000000000000000ull;
static const std::uint64_t cValueMask = ~(cPositive | cMPToken);
static std::uint64_t const cMaxNativeN = 100000000000000000ull;
static std::uint64_t const cIssuedCurrency = 0x8000000000000000ull;
static std::uint64_t const cPositive = 0x4000000000000000ull;
static std::uint64_t const cMPToken = 0x2000000000000000ull;
static std::uint64_t const cValueMask = ~(cPositive | cMPToken);
static std::uint64_t const uRateOne;
@@ -153,12 +153,6 @@ public:
template <AssetType A>
STAmount(A const& asset, int mantissa, int exponent = 0);
template <AssetType A>
STAmount(A const& asset, Number const& number)
: STAmount(asset, number.mantissa(), number.exponent())
{
}
// Legacy support for new-style amounts
STAmount(IOUAmount const& amount, Issue const& issue);
STAmount(XRPAmount const& amount);
@@ -236,9 +230,6 @@ public:
STAmount&
operator=(XRPAmount const& amount);
STAmount&
operator=(Number const&);
//--------------------------------------------------------------------------
//
// Modification
@@ -277,13 +268,13 @@ public:
std::string
getText() const override;
Json::Value getJson(JsonOptions = JsonOptions::none) const override;
Json::Value getJson(JsonOptions) const override;
void
add(Serializer& s) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
@@ -426,7 +417,7 @@ STAmount
amountFromQuality(std::uint64_t rate);
STAmount
amountFromString(Asset const& asset, std::string const& amount);
amountFromString(Asset const& issue, std::string const& amount);
STAmount
amountFromJson(SField const& name, Json::Value const& v);
@@ -550,16 +541,6 @@ STAmount::operator=(XRPAmount const& amount)
return *this;
}
inline STAmount&
STAmount::operator=(Number const& number)
{
mIsNegative = number.mantissa() < 0;
mValue = mIsNegative ? -number.mantissa() : number.mantissa();
mOffset = number.exponent();
canonicalize();
return *this;
}
inline void
STAmount::negate()
{
@@ -695,16 +676,6 @@ divRoundStrict(
std::uint64_t
getRate(STAmount const& offerOut, STAmount const& offerIn);
template <AssetType A>
Number
roundToAsset(A const& asset, Number const& value)
{
STAmount const amount{asset, value};
if (amount != value)
return amount;
return value;
}
//------------------------------------------------------------------------------
inline bool

View File

@@ -128,13 +128,13 @@ public:
add(Serializer& s) const override;
void
sort(bool (*compare)(const STObject& o1, const STObject& o2));
sort(bool (*compare)(STObject const& o1, STObject const& o2));
bool
operator==(const STArray& s) const;
operator==(STArray const& s) const;
bool
operator!=(const STArray& s) const;
operator!=(STArray const& s) const;
iterator
erase(iterator pos);
@@ -152,7 +152,7 @@ public:
getSType() const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
@@ -275,13 +275,13 @@ STArray::swap(STArray& a) noexcept
}
inline bool
STArray::operator==(const STArray& s) const
STArray::operator==(STArray const& s) const
{
return v_ == s.v_;
}
inline bool
STArray::operator!=(const STArray& s) const
STArray::operator!=(STArray const& s) const
{
return v_ != s.v_;
}

View File

@@ -92,16 +92,6 @@ struct JsonOptions
}
};
template <typename T>
requires requires(T const& t) {
{ t.getJson(JsonOptions::none) } -> std::convertible_to<Json::Value>;
}
Json::Value
to_json(T const& t)
{
return t.getJson(JsonOptions::none);
}
namespace detail {
class STVar;
}
@@ -139,16 +129,16 @@ class STBase
public:
virtual ~STBase() = default;
STBase();
STBase(const STBase&) = default;
STBase(STBase const&) = default;
STBase&
operator=(const STBase& t);
operator=(STBase const& t);
explicit STBase(SField const& n);
bool
operator==(const STBase& t) const;
operator==(STBase const& t) const;
bool
operator!=(const STBase& t) const;
operator!=(STBase const& t) const;
template <class D>
D&
@@ -167,7 +157,7 @@ public:
virtual std::string
getText() const;
virtual Json::Value getJson(JsonOptions = JsonOptions::none) const;
virtual Json::Value getJson(JsonOptions /*options*/) const;
virtual void
add(Serializer& s) const;
@@ -207,7 +197,7 @@ private:
//------------------------------------------------------------------------------
std::ostream&
operator<<(std::ostream& out, const STBase& t);
operator<<(std::ostream& out, STBase const& t);
template <class D>
D&

View File

@@ -45,8 +45,8 @@ public:
STBitString() = default;
STBitString(SField const& n);
STBitString(const value_type& v);
STBitString(SField const& n, const value_type& v);
STBitString(value_type const& v);
STBitString(SField const& n, value_type const& v);
STBitString(SerialIter& sit, SField const& name);
SerializedTypeID
@@ -56,7 +56,7 @@ public:
getText() const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
void
add(Serializer& s) const override;
@@ -93,12 +93,12 @@ inline STBitString<Bits>::STBitString(SField const& n) : STBase(n)
}
template <int Bits>
inline STBitString<Bits>::STBitString(const value_type& v) : value_(v)
inline STBitString<Bits>::STBitString(value_type const& v) : value_(v)
{
}
template <int Bits>
inline STBitString<Bits>::STBitString(SField const& n, const value_type& v)
inline STBitString<Bits>::STBitString(SField const& n, value_type const& v)
: STBase(n), value_(v)
{
}
@@ -160,9 +160,9 @@ STBitString<Bits>::getText() const
template <int Bits>
bool
STBitString<Bits>::isEquivalent(const STBase& t) const
STBitString<Bits>::isEquivalent(STBase const& t) const
{
const STBitString* v = dynamic_cast<const STBitString*>(&t);
STBitString const* v = dynamic_cast<STBitString const*>(&t);
return v && (value_ == v->value_);
}

View File

@@ -63,7 +63,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;

View File

@@ -65,7 +65,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;

View File

@@ -21,7 +21,6 @@
#define RIPPLE_PROTOCOL_STINTEGER_H_INCLUDED
#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/STBase.h>
namespace ripple {
@@ -37,7 +36,7 @@ private:
public:
explicit STInteger(Integer v);
STInteger(SField const& n, Integer v = {});
STInteger(SField const& n, Integer v = 0);
STInteger(SerialIter& sit, SField const& name);
SerializedTypeID
@@ -55,7 +54,7 @@ public:
isDefault() const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
STInteger&
operator=(value_type const& v);
@@ -123,14 +122,14 @@ template <typename Integer>
inline bool
STInteger<Integer>::isDefault() const
{
return value_ == Integer{};
return value_ == 0;
}
template <typename Integer>
inline bool
STInteger<Integer>::isEquivalent(const STBase& t) const
STInteger<Integer>::isEquivalent(STBase const& t) const
{
const STInteger* v = dynamic_cast<const STInteger*>(&t);
STInteger const* v = dynamic_cast<STInteger const*>(&t);
return v && (value_ == v->value_);
}

View File

@@ -37,7 +37,6 @@ public:
using value_type = Asset;
STIssue() = default;
STIssue(STIssue const& rhs) = default;
explicit STIssue(SerialIter& sit, SField const& name);
@@ -46,15 +45,6 @@ public:
explicit STIssue(SField const& name);
STIssue&
operator=(STIssue const& rhs) = default;
STIssue&
operator=(Asset const& rhs)
{
asset_ = rhs;
return *this;
}
template <ValidIssueType TIss>
TIss const&
get() const;
@@ -81,7 +71,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;

View File

@@ -26,9 +26,7 @@
namespace ripple {
class Rules;
namespace test {
class Invariants_test;
}
class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
{
@@ -37,9 +35,7 @@ class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
public:
using pointer = std::shared_ptr<STLedgerEntry>;
using ref = const std::shared_ptr<STLedgerEntry>&;
using const_pointer = std::shared_ptr<STLedgerEntry const>;
using const_ref = const std::shared_ptr<STLedgerEntry const>&;
using ref = std::shared_ptr<STLedgerEntry> const&;
/** Create an empty object with the given key and type. */
explicit STLedgerEntry(Keylet const& k);
@@ -58,7 +54,7 @@ public:
getText() const override;
Json::Value
getJson(JsonOptions options = JsonOptions::none) const override;
getJson(JsonOptions options) const override;
/** Returns the 'key' (or 'index') of this item.
The key identifies this entry's position in
@@ -88,8 +84,7 @@ private:
void
setSLEType();
friend test::Invariants_test; // this test wants access to the private
// type_
friend Invariants_test; // this test wants access to the private type_
STBase*
copy(std::size_t n, void* buf) const override;

View File

@@ -63,13 +63,6 @@ public:
void
setValue(Number const& v);
STNumber&
operator=(Number const& rhs)
{
setValue(rhs);
return *this;
}
bool
isEquivalent(STBase const& t) const override;
bool
@@ -90,19 +83,6 @@ private:
std::ostream&
operator<<(std::ostream& out, STNumber const& rhs);
struct NumberParts
{
std::uint64_t mantissa = 0;
int exponent = 0;
bool negative = false;
};
NumberParts
partsFromString(std::string const& number);
STNumber
numberFromJson(SField const& field, Json::Value const& value);
} // namespace ripple
#endif

View File

@@ -25,6 +25,7 @@
#include <xrpl/basics/chrono.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/FeeUnits.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/SOTemplate.h>
#include <xrpl/protocol/STAmount.h>
@@ -33,7 +34,6 @@
#include <xrpl/protocol/STIssue.h>
#include <xrpl/protocol/STPathSet.h>
#include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/Units.h>
#include <xrpl/protocol/detail/STVar.h>
#include <boost/iterator/transform_iterator.hpp>
@@ -99,8 +99,8 @@ public:
STObject&
operator=(STObject&& other);
STObject(const SOTemplate& type, SField const& name);
STObject(const SOTemplate& type, SerialIter& sit, SField const& name);
STObject(SOTemplate const& type, SField const& name);
STObject(SOTemplate const& type, SerialIter& sit, SField const& name);
STObject(SerialIter& sit, SField const& name, int depth = 0);
STObject(SerialIter&& sit, SField const& name);
explicit STObject(SField const& name);
@@ -121,7 +121,7 @@ public:
reserve(std::size_t n);
void
applyTemplate(const SOTemplate& type);
applyTemplate(SOTemplate const& type);
void
applyTemplateFromSField(SField const&);
@@ -130,7 +130,7 @@ public:
isFree() const;
void
set(const SOTemplate&);
set(SOTemplate const&);
bool
set(SerialIter& u, int depth = 0);
@@ -139,7 +139,7 @@ public:
getSType() const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
@@ -154,7 +154,8 @@ public:
getText() const override;
// TODO(tom): options should be an enum.
Json::Value getJson(JsonOptions = JsonOptions::none) const override;
Json::Value
getJson(JsonOptions options) const override;
void
addWithoutSigningFields(Serializer& s) const;
@@ -182,13 +183,13 @@ public:
uint256
getSigningHash(HashPrefix prefix) const;
const STBase&
STBase const&
peekAtIndex(int offset) const;
STBase&
getIndex(int offset);
const STBase*
STBase const*
peekAtPIndex(int offset) const;
STBase*
@@ -200,13 +201,13 @@ public:
SField const&
getFieldSType(int index) const;
const STBase&
STBase const&
peekAtField(SField const& field) const;
STBase&
getField(SField const& field);
const STBase*
STBase const*
peekAtPField(SField const& field) const;
STBase*
@@ -240,14 +241,11 @@ public:
getFieldAmount(SField const& field) const;
STPathSet const&
getFieldPathSet(SField const& field) const;
const STVector256&
STVector256 const&
getFieldV256(SField const& field) const;
// If not found, returns an object constructed with the given field
STObject
getFieldObject(SField const& field) const;
const STArray&
STArray const&
getFieldArray(SField const& field) const;
const STCurrency&
STCurrency const&
getFieldCurrency(SField const& field) const;
STNumber const&
getFieldNumber(SField const& field) const;
@@ -411,12 +409,12 @@ public:
delField(int index);
bool
hasMatchingEntry(const STBase&);
hasMatchingEntry(STBase const&);
bool
operator==(const STObject& o) const;
operator==(STObject const& o) const;
bool
operator!=(const STObject& o) const;
operator!=(STObject const& o) const;
class FieldErr;
@@ -486,19 +484,9 @@ private:
template <class T>
class STObject::Proxy
{
public:
protected:
using value_type = typename T::value_type;
value_type
value() const;
value_type
operator*() const;
T const*
operator->() const;
protected:
STObject* st_;
SOEStyle style_;
TypedField<T> const* f_;
@@ -507,6 +495,9 @@ protected:
Proxy(STObject* st, TypedField<T> const* f);
value_type
value() const;
T const*
find() const;
@@ -518,29 +509,10 @@ protected:
// Constraint += and -= ValueProxy operators
// to value types that support arithmetic operations
template <typename U>
concept IsArithmeticNumber = std::is_arithmetic_v<U> ||
std::is_same_v<U, Number> || std::is_same_v<U, STAmount>;
template <
typename U,
typename Value = typename U::value_type,
typename Unit = typename U::unit_type>
concept IsArithmeticValueUnit =
std::is_same_v<U, unit::ValueUnit<Unit, Value>> &&
IsArithmeticNumber<Value> && std::is_class_v<Unit>;
template <typename U, typename Value = typename U::value_type>
concept IsArithmeticST = !IsArithmeticValueUnit<U> && IsArithmeticNumber<Value>;
template <typename U>
concept IsArithmetic =
IsArithmeticNumber<U> || IsArithmeticST<U> || IsArithmeticValueUnit<U>;
template <class T, class U>
concept Addable = requires(T t, U u) { t = t + u; };
template <typename T, typename U>
concept IsArithmeticCompatible =
IsArithmetic<typename T::value_type> && Addable<typename T::value_type, U>;
concept IsArithmetic = std::is_arithmetic_v<U> || std::is_same_v<U, STAmount>;
template <class T>
class STObject::ValueProxy : public Proxy<T>
class STObject::ValueProxy : private Proxy<T>
{
private:
using value_type = typename T::value_type;
@@ -557,24 +529,15 @@ public:
// Convenience operators for value types supporting
// arithmetic operations
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
ValueProxy&
operator+=(U const& u);
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
ValueProxy&
operator-=(U const& u);
operator value_type() const;
template <typename U>
friend bool
operator==(U const& lhs, STObject::ValueProxy<T> const& rhs)
{
return rhs.value() == lhs;
}
private:
friend class STObject;
@@ -582,7 +545,7 @@ private:
};
template <class T>
class STObject::OptionalProxy : public Proxy<T>
class STObject::OptionalProxy : private Proxy<T>
{
private:
using value_type = typename T::value_type;
@@ -602,6 +565,15 @@ public:
explicit
operator bool() const noexcept;
/** Return the contained value
Throws:
STObject::FieldErr if !engaged()
*/
value_type
operator*() const;
operator optional_type() const;
/** Explicit conversion to std::optional */
@@ -745,20 +717,6 @@ STObject::Proxy<T>::value() const -> value_type
return value_type{};
}
template <class T>
auto
STObject::Proxy<T>::operator*() const -> value_type
{
return this->value();
}
template <class T>
T const*
STObject::Proxy<T>::operator->() const
{
return this->find();
}
template <class T>
inline T const*
STObject::Proxy<T>::find() const
@@ -798,7 +756,6 @@ STObject::ValueProxy<T>::operator=(U&& u)
template <typename T>
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
STObject::ValueProxy<T>&
STObject::ValueProxy<T>::operator+=(U const& u)
{
@@ -808,7 +765,6 @@ STObject::ValueProxy<T>::operator+=(U const& u)
template <class T>
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
STObject::ValueProxy<T>&
STObject::ValueProxy<T>::operator-=(U const& u)
{
@@ -836,6 +792,13 @@ STObject::OptionalProxy<T>::operator bool() const noexcept
return engaged();
}
template <class T>
auto
STObject::OptionalProxy<T>::operator*() const -> value_type
{
return this->value();
}
template <class T>
STObject::OptionalProxy<T>::operator typename STObject::OptionalProxy<
T>::optional_type() const
@@ -1007,7 +970,7 @@ STObject::getCount() const
return v_.size();
}
inline const STBase&
inline STBase const&
STObject::peekAtIndex(int offset) const
{
return v_[offset].get();
@@ -1019,7 +982,7 @@ STObject::getIndex(int offset)
return v_[offset].get();
}
inline const STBase*
inline STBase const*
STObject::peekAtPIndex(int offset) const
{
return &v_[offset].get();
@@ -1154,7 +1117,7 @@ STObject::setFieldH160(SField const& field, base_uint<160, Tag> const& v)
}
inline bool
STObject::operator!=(const STObject& o) const
STObject::operator!=(STObject const& o) const
{
return !(*this == o);
}
@@ -1163,7 +1126,7 @@ template <typename T, typename V>
V
STObject::getFieldByValue(SField const& field) const
{
const STBase* rf = peekAtPField(field);
STBase const* rf = peekAtPField(field);
if (!rf)
throwFieldNotFound(field);
@@ -1173,7 +1136,7 @@ STObject::getFieldByValue(SField const& field) const
if (id == STI_NOTPRESENT)
return V(); // optional field not present
const T* cf = dynamic_cast<const T*>(rf);
T const* cf = dynamic_cast<T const*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");
@@ -1190,7 +1153,7 @@ template <typename T, typename V>
V const&
STObject::getFieldByConstRef(SField const& field, V const& empty) const
{
const STBase* rf = peekAtPField(field);
STBase const* rf = peekAtPField(field);
if (!rf)
throwFieldNotFound(field);
@@ -1200,7 +1163,7 @@ STObject::getFieldByConstRef(SField const& field, V const& empty) const
if (id == STI_NOTPRESENT)
return empty; // optional field not present
const T* cf = dynamic_cast<const T*>(rf);
T const* cf = dynamic_cast<T const*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");

View File

@@ -106,10 +106,10 @@ public:
getIssuerID() const;
bool
operator==(const STPathElement& t) const;
operator==(STPathElement const& t) const;
bool
operator!=(const STPathElement& t) const;
operator!=(STPathElement const& t) const;
private:
static std::size_t
@@ -164,7 +164,7 @@ public:
STPathElement&
operator[](int i);
const STPathElement&
STPathElement const&
operator[](int i) const;
void
@@ -196,7 +196,7 @@ public:
assembleAdd(STPath const& base, STPathElement const& tail);
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
@@ -375,7 +375,7 @@ STPathElement::getIssuerID() const
}
inline bool
STPathElement::operator==(const STPathElement& t) const
STPathElement::operator==(STPathElement const& t) const
{
return (mType & typeAccount) == (t.mType & typeAccount) &&
hash_value_ == t.hash_value_ && mAccountID == t.mAccountID &&
@@ -383,7 +383,7 @@ STPathElement::operator==(const STPathElement& t) const
}
inline bool
STPathElement::operator!=(const STPathElement& t) const
STPathElement::operator!=(STPathElement const& t) const
{
return !operator==(t);
}
@@ -455,7 +455,7 @@ STPath::operator[](int i)
return mPath[i];
}
inline const STPathElement&
inline STPathElement const&
STPath::operator[](int i) const
{
return mPath[i];

View File

@@ -88,13 +88,7 @@ public:
// Outer transaction functions / signature functions.
Blob
getSignature(STObject const& sigObject) const;
Blob
getSignature() const
{
return getSignature(*this);
}
getSignature() const;
uint256
getSigningHash() const;
@@ -108,10 +102,6 @@ public:
SeqProxy
getSeqProxy() const;
/** Returns the first non-zero value of (Sequence, TicketSequence). */
std::uint32_t
getSeqValue() const;
boost::container::flat_set<AccountID>
getMentionedAccounts() const;
@@ -127,28 +117,10 @@ public:
void
sign(PublicKey const& publicKey, SecretKey const& secretKey);
/** Check the signature.
@return `true` if valid signature. If invalid, the error message string.
*/
enum class RequireFullyCanonicalSig : bool { no, yes };
/** Check the signature.
@param requireCanonicalSig If `true`, check that the signature is fully
canonical. If `false`, only check that the signature is valid.
@param rules The current ledger rules.
@param pSig Pointer to object that contains the signature fields, if not
using "this". Will most often be null
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
checkSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules,
STObject const* pSig) const;
/** Check the signature.
@param requireCanonicalSig If `true`, check that the signature is fully
canonical. If `false`, only check that the signature is valid.
@param rules The current ledger rules.
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
const;
@@ -170,15 +142,12 @@ public:
private:
Expected<void, std::string>
checkSingleSign(
RequireFullyCanonicalSig requireCanonicalSig,
STObject const* pSig) const;
checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
Expected<void, std::string>
checkMultiSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules,
STObject const* pSig) const;
Rules const& rules) const;
STBase*
copy(std::size_t n, void* buf) const override;

View File

@@ -22,10 +22,10 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/FeeUnits.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/SecretKey.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
#include <functional>

View File

@@ -50,7 +50,7 @@ public:
Json::Value getJson(JsonOptions) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;
@@ -62,7 +62,7 @@ public:
operator=(std::vector<uint256>&& v);
void
setValue(const STVector256& v);
setValue(STVector256 const& v);
/** Retrieve a copy of the vector we contain */
explicit
@@ -153,7 +153,7 @@ STVector256::operator=(std::vector<uint256>&& v)
}
inline void
STVector256::setValue(const STVector256& v)
STVector256::setValue(STVector256 const& v)
{
mValue = v.mValue;
}

View File

@@ -107,7 +107,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(const STBase& t) const override;
isEquivalent(STBase const& t) const override;
bool
isDefault() const override;

View File

@@ -125,17 +125,8 @@ public:
}
template <typename Integer>
requires(!HasValue<Integer>)
int addInteger(Integer);
template <typename Integer>
requires HasValue<Integer>
int
addInteger(Integer i)
{
return addInteger(i.value());
}
template <std::size_t Bits, class Tag>
int
addBitString(base_uint<Bits, Tag> const& v)
@@ -148,9 +139,9 @@ public:
int
addRaw(Slice slice);
int
addRaw(const void* ptr, int len);
addRaw(void const* ptr, int len);
int
addRaw(const Serializer& s);
addRaw(Serializer const& s);
int
addVL(Blob const& vector);
@@ -160,7 +151,7 @@ public:
int
addVL(Iter begin, Iter end, int len);
int
addVL(const void* ptr, int len);
addVL(void const* ptr, int len);
// disassemble functions
bool
@@ -170,7 +161,7 @@ public:
bool
getInteger(Integer& number, int offset)
{
static const auto bytes = sizeof(Integer);
static auto const bytes = sizeof(Integer);
if ((offset + bytes) > mData.size())
return false;
number = 0;
@@ -229,7 +220,7 @@ public:
{
return mData.size();
}
const void*
void const*
getDataPtr() const
{
return mData.data();
@@ -247,7 +238,7 @@ public:
std::string
getString() const
{
return std::string(static_cast<const char*>(getDataPtr()), size());
return std::string(static_cast<char const*>(getDataPtr()), size());
}
void
erase()
@@ -305,12 +296,12 @@ public:
return v != mData;
}
bool
operator==(const Serializer& v) const
operator==(Serializer const& v) const
{
return v.mData == mData;
}
bool
operator!=(const Serializer& v) const
operator!=(Serializer const& v) const
{
return v.mData != mData;
}

View File

@@ -225,8 +225,6 @@ enum TERcodes : TERUnderlyingType {
terQUEUED, // Transaction is being held in TxQ until fee drops
terPRE_TICKET, // Ticket is not yet in ledger but might be on its way
terNO_AMM, // AMM doesn't exist for the asset pair
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
// create a pseudo-account
};
//------------------------------------------------------------------------------
@@ -267,17 +265,6 @@ enum TECcodes : TERUnderlyingType {
// Otherwise, treated as terRETRY.
//
// DO NOT CHANGE THESE NUMBERS: They appear in ledger meta data.
//
// Note:
// tecNO_ENTRY is often used interchangeably with tecOBJECT_NOT_FOUND.
// While there does not seem to be a clear rule which to use when, the
// following guidance will help to keep errors consistent with the
// majority of (but not all) transaction types:
// - tecNO_ENTRY : cannot find the primary ledger object on which the
// transaction is being attempted
// - tecOBJECT_NOT_FOUND : cannot find the additional object(s) needed to
// complete the transaction
tecCLAIM = 100,
tecPATH_PARTIAL = 101,
tecUNFUNDED_ADD = 102, // Unused legacy code
@@ -357,9 +344,6 @@ enum TECcodes : TERUnderlyingType {
tecARRAY_TOO_LARGE = 191,
tecLOCKED = 192,
tecBAD_CREDENTIALS = 193,
tecWRONG_ASSET = 194,
tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196,
};
//------------------------------------------------------------------------------

View File

@@ -120,11 +120,16 @@ constexpr std::uint32_t tfTrustSetMask =
~(tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple | tfSetFreeze |
tfClearFreeze | tfSetDeepFreeze | tfClearDeepFreeze);
// valid flags for granular permission
constexpr std::uint32_t tfTrustSetGranularMask = tfSetfAuth | tfSetFreeze | tfClearFreeze;
// bits representing supportedGranularMask are set to 0 and the bits
// representing other flags are set to 1 in tfPermissionMask.
constexpr std::uint32_t tfTrustSetPermissionMask = (~tfTrustSetMask) & (~tfTrustSetGranularMask);
// EnableAmendment flags:
constexpr std::uint32_t tfGotMajority = 0x00010000;
constexpr std::uint32_t tfLostMajority = 0x00020000;
constexpr std::uint32_t tfChangeMask =
~( tfUniversal | tfGotMajority | tfLostMajority);
// PaymentChannelClaim flags:
constexpr std::uint32_t tfRenew = 0x00010000;
@@ -139,7 +144,7 @@ constexpr std::uint32_t const tfTransferable = 0x00000008;
constexpr std::uint32_t const tfMutable = 0x00000010;
// MPTokenIssuanceCreate flags:
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
constexpr std::uint32_t const tfMPTCanLock = lsfMPTCanLock;
constexpr std::uint32_t const tfMPTRequireAuth = lsfMPTRequireAuth;
constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
@@ -157,6 +162,8 @@ constexpr std::uint32_t const tfMPTokenAuthorizeMask = ~(tfUniversal | tfMPTUna
constexpr std::uint32_t const tfMPTLock = 0x00000001;
constexpr std::uint32_t const tfMPTUnlock = 0x00000002;
constexpr std::uint32_t const tfMPTokenIssuanceSetMask = ~(tfUniversal | tfMPTLock | tfMPTUnlock);
constexpr std::uint32_t const tfMPTokenIssuanceSetGranularMask = tfMPTLock | tfMPTUnlock;
constexpr std::uint32_t const tfMPTokenIssuanceSetPermissionMask = (~tfMPTokenIssuanceSetMask) & (~tfMPTokenIssuanceSetGranularMask);
// MPTokenIssuanceDestroy flags:
constexpr std::uint32_t const tfMPTokenIssuanceDestroyMask = ~tfUniversal;
@@ -226,24 +233,6 @@ constexpr std::uint32_t tfAMMClawbackMask = ~(tfUniversal | tfClawTwoAssets);
// BridgeModify flags:
constexpr std::uint32_t tfClearAccountCreateAmount = 0x00010000;
constexpr std::uint32_t tfBridgeModifyMask = ~(tfUniversal | tfClearAccountCreateAmount);
// VaultCreate flags:
constexpr std::uint32_t const tfVaultPrivate = 0x00010000;
static_assert(tfVaultPrivate == lsfVaultPrivate);
constexpr std::uint32_t const tfVaultShareNonTransferable = 0x00020000;
constexpr std::uint32_t const tfVaultCreateMask = ~(tfUniversal | tfVaultPrivate | tfVaultShareNonTransferable);
// LoanSet flags:
// True, indicates the loan supports overpayments
constexpr std::uint32_t const tfLoanOverpayment = 0x00010000;
constexpr std::uint32_t const tfLoanSetMask = ~(tfUniversal | tfLoanOverpayment);
// LoanManage flags:
constexpr std::uint32_t const tfLoanDefault = 0x00010000;
constexpr std::uint32_t const tfLoanImpair = 0x00020000;
constexpr std::uint32_t const tfLoanUnimpair = 0x00040000;
constexpr std::uint32_t const tfLoanManageMask = ~(tfUniversal | tfLoanDefault | tfLoanImpair | tfLoanUnimpair);
// clang-format on
} // namespace ripple

View File

@@ -59,7 +59,7 @@ enum TxType : std::uint16_t
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, name, privileges, fields) tag = value,
#define TRANSACTION(tag, value, name, delegatable, fields) tag = value,
#include <xrpl/protocol/detail/transactions.macro>

View File

@@ -24,7 +24,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/Units.h>
#include <xrpl/protocol/FeeUnits.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/operators.hpp>
@@ -42,7 +42,7 @@ class XRPAmount : private boost::totally_ordered<XRPAmount>,
private boost::additive<XRPAmount, std::int64_t>
{
public:
using unit_type = unit::dropTag;
using unit_type = feeunit::dropTag;
using value_type = std::int64_t;
private:
@@ -267,7 +267,7 @@ XRPAmount::decimalXRP() const
// Output XRPAmount as just the drops value.
template <class Char, class Traits>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os, const XRPAmount& q)
operator<<(std::basic_ostream<Char, Traits>& os, XRPAmount const& q)
{
return os << q.drops();
}

View File

@@ -27,13 +27,12 @@
#error "undefined macro: XRPL_RETIRE"
#endif
// clang-format off
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
// If you add an amendment here, then do not forget to increment `numFeatures`
// in include/xrpl/protocol/Feature.h.
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegation, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
@@ -146,5 +145,3 @@ XRPL_RETIRE(fix1201)
XRPL_RETIRE(fix1512)
XRPL_RETIRE(fix1523)
XRPL_RETIRE(fix1528)
// clang-format on

View File

@@ -165,9 +165,7 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfMintedNFTokens, soeDEFAULT},
{sfBurnedNFTokens, soeDEFAULT},
{sfFirstNFTokenSequence, soeOPTIONAL},
{sfAMMID, soeOPTIONAL}, // pseudo-account designator
{sfVaultID, soeOPTIONAL}, // pseudo-account designator
{sfLoanBrokerID, soeOPTIONAL}, // pseudo-account designator
{sfAMMID, soeOPTIONAL},
}))
/** A ledger object which contains a list of object identifiers.
@@ -392,6 +390,21 @@ LEDGER_ENTRY(ltAMM, 0x0079, AMM, amm, ({
{sfPreviousTxnLgrSeq, soeOPTIONAL},
}))
/** A ledger object which tracks Oracle
\sa keylet::oracle
*/
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
{sfOwner, soeREQUIRED},
{sfProvider, soeREQUIRED},
{sfPriceDataSeries, soeREQUIRED},
{sfAssetClass, soeREQUIRED},
{sfLastUpdateTime, soeREQUIRED},
{sfURI, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
/** A ledger object which tracks MPTokenIssuance
\sa keylet::mptIssuance
*/
@@ -406,7 +419,6 @@ LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
{sfMPTokenMetadata, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDomainID, soeOPTIONAL},
}))
/** A ledger object which tracks MPToken
@@ -421,21 +433,6 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
/** A ledger object which tracks Oracle
\sa keylet::oracle
*/
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
{sfOwner, soeREQUIRED},
{sfProvider, soeREQUIRED},
{sfPriceDataSeries, soeREQUIRED},
{sfAssetClass, soeREQUIRED},
{sfLastUpdateTime, soeREQUIRED},
{sfURI, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
/** A ledger object which tracks Credential
\sa keylet::credential
*/
@@ -463,84 +460,16 @@ LEDGER_ENTRY(ltPERMISSIONED_DOMAIN, 0x0082, PermissionedDomain, permissioned_dom
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
/** A ledger object representing a single asset vault.
\sa keylet::mptoken
/** A ledger object representing permissions an account has delegated to another account.
\sa keylet::delegate
*/
LEDGER_ENTRY(ltVAULT, 0x0083, Vault, vault, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfOwner, soeREQUIRED},
LEDGER_ENTRY(ltDELEGATE, 0x0083, Delegate, delegate, ({
{sfAccount, soeREQUIRED},
{sfData, soeOPTIONAL},
{sfAsset, soeREQUIRED},
{sfAssetsTotal, soeREQUIRED},
{sfAssetsAvailable, soeREQUIRED},
{sfAssetsMaximum, soeDEFAULT},
{sfLossUnrealized, soeREQUIRED},
{sfShareMPTID, soeREQUIRED},
{sfWithdrawalPolicy, soeREQUIRED},
// no SharesTotal ever (use MPTIssuance.sfOutstandingAmount)
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))
/** Reserve 0x0084-0x0087 for future Vault-related objects. */
/** A ledger object representing a loan broker
\sa keylet::loanbroker
*/
LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfVaultNode, soeREQUIRED},
{sfVaultID, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfOwner, soeREQUIRED},
{sfLoanSequence, soeREQUIRED},
{sfData, soeDEFAULT},
{sfManagementFeeRate, soeDEFAULT},
{sfOwnerCount, soeDEFAULT},
{sfDebtTotal, soeDEFAULT},
{sfDebtMaximum, soeDEFAULT},
{sfCoverAvailable, soeDEFAULT},
{sfCoverRateMinimum, soeDEFAULT},
{sfCoverRateLiquidation, soeDEFAULT},
}))
/** A ledger object representing a loan between a Borrower and a Loan Broker
\sa keylet::loan
*/
LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfLoanBrokerNode, soeREQUIRED},
{sfLoanBrokerID, soeREQUIRED},
{sfLoanSequence, soeREQUIRED},
{sfBorrower, soeREQUIRED},
{sfLoanOriginationFee, soeREQUIRED},
{sfLoanServiceFee, soeREQUIRED},
{sfLatePaymentFee, soeREQUIRED},
{sfClosePaymentFee, soeREQUIRED},
{sfOverpaymentFee, soeREQUIRED},
{sfInterestRate, soeREQUIRED},
{sfLateInterestRate, soeREQUIRED},
{sfCloseInterestRate, soeREQUIRED},
{sfOverpaymentInterestRate, soeREQUIRED},
{sfStartDate, soeREQUIRED},
{sfPaymentInterval, soeREQUIRED},
{sfGracePeriod, soeREQUIRED},
{sfPreviousPaymentDate, soeREQUIRED},
{sfNextPaymentDueDate, soeREQUIRED},
{sfPaymentRemaining, soeREQUIRED},
{sfAssetsAvailable, soeREQUIRED},
{sfPrincipalOutstanding, soeREQUIRED},
}))
#undef EXPAND

View File

@@ -0,0 +1,68 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#if !defined(PERMISSION)
#error "undefined macro: PERMISSION"
#endif
/**
* PERMISSION(name, type, txType, value)
*
* This macro defines a permission:
* name: the name of the permission.
* type: the GranularPermissionType enum.
* txType: the corresponding TxType for this permission.
* value: the uint32 numeric value for the enum type.
*/
/** This permission grants the delegated account the ability to authorize a trustline. */
PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537)
/** This permission grants the delegated account the ability to freeze a trustline. */
PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538)
/** This permission grants the delegated account the ability to unfreeze a trustline. */
PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539)
/** This permission grants the delegated account the ability to set Domain. */
PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540)
/** This permission grants the delegated account the ability to set EmailHashSet. */
PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541)
/** This permission grants the delegated account the ability to set MessageKey. */
PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542)
/** This permission grants the delegated account the ability to set TransferRate. */
PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543)
/** This permission grants the delegated account the ability to set TickSize. */
PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544)
/** This permission grants the delegated account the ability to mint payment, which means sending a payment for a currency where the sending account is the issuer. */
PERMISSION(PaymentMint, ttPAYMENT, 65545)
/** This permission grants the delegated account the ability to burn payment, which means sending a payment for a currency where the destination account is the issuer */
PERMISSION(PaymentBurn, ttPAYMENT, 65546)
/** This permission grants the delegated account the ability to lock MPToken. */
PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547)
/** This permission grants the delegated account the ability to unlock MPToken. */
PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548)

View File

@@ -24,8 +24,6 @@
#error "undefined macro: TYPED_SFIELD"
#endif
// clang-format off
// untyped
UNTYPED_SFIELD(sfLedgerEntry, LEDGERENTRY, 257)
UNTYPED_SFIELD(sfTransaction, TRANSACTION, 257)
@@ -44,7 +42,6 @@ TYPED_SFIELD(sfTickSize, UINT8, 16)
TYPED_SFIELD(sfUNLModifyDisabling, UINT8, 17)
TYPED_SFIELD(sfHookResult, UINT8, 18)
TYPED_SFIELD(sfWasLockingChainSend, UINT8, 19)
TYPED_SFIELD(sfWithdrawalPolicy, UINT8, 20)
// 16-bit integers (common)
TYPED_SFIELD(sfLedgerEntryType, UINT16, 1, SField::sMD_Never)
@@ -61,7 +58,6 @@ TYPED_SFIELD(sfHookEmitCount, UINT16, 18)
TYPED_SFIELD(sfHookExecutionIndex, UINT16, 19)
TYPED_SFIELD(sfHookApiVersion, UINT16, 20)
TYPED_SFIELD(sfLedgerFixType, UINT16, 21)
TYPED_SFIELD(sfManagementFeeRate, UINT16, 22) // 1/10 basis points (bips)
// 32-bit integers (common)
TYPED_SFIELD(sfNetworkID, UINT32, 1)
@@ -116,21 +112,7 @@ TYPED_SFIELD(sfEmitGeneration, UINT32, 46)
TYPED_SFIELD(sfVoteWeight, UINT32, 48)
TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
TYPED_SFIELD(sfStartDate, UINT32, 52)
TYPED_SFIELD(sfPaymentInterval, UINT32, 53)
TYPED_SFIELD(sfGracePeriod, UINT32, 54)
TYPED_SFIELD(sfPreviousPaymentDate, UINT32, 55)
TYPED_SFIELD(sfNextPaymentDueDate, UINT32, 56)
TYPED_SFIELD(sfPaymentRemaining, UINT32, 57)
TYPED_SFIELD(sfPaymentTotal, UINT32, 58)
TYPED_SFIELD(sfLoanSequence, UINT32, 59)
TYPED_SFIELD(sfCoverRateMinimum, UINT32, 60) // 1/10 basis points (bips)
TYPED_SFIELD(sfCoverRateLiquidation, UINT32, 61) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentFee, UINT32, 62) // 1/10 basis points (bips)
TYPED_SFIELD(sfInterestRate, UINT32, 63) // 1/10 basis points (bips)
TYPED_SFIELD(sfLateInterestRate, UINT32, 64) // 1/10 basis points (bips)
TYPED_SFIELD(sfCloseInterestRate, UINT32, 65) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 66) // 1/10 basis points (bips)
TYPED_SFIELD(sfPermissionValue, UINT32, 52)
// 64-bit integers (common)
TYPED_SFIELD(sfIndexNext, UINT64, 1)
@@ -161,8 +143,6 @@ TYPED_SFIELD(sfOutstandingAmount, UINT64, 25, SField::sMD_BaseTen|SFie
TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfIssuerNode, UINT64, 27)
TYPED_SFIELD(sfSubjectNode, UINT64, 28)
TYPED_SFIELD(sfVaultNode, UINT64, 29)
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 30)
// 128-bit
TYPED_SFIELD(sfEmailHash, UINT128, 1)
@@ -175,7 +155,6 @@ TYPED_SFIELD(sfTakerGetsIssuer, UINT160, 4)
// 192-bit (common)
TYPED_SFIELD(sfMPTokenIssuanceID, UINT192, 1)
TYPED_SFIELD(sfShareMPTID, UINT192, 2)
// 256-bit (common)
TYPED_SFIELD(sfLedgerHash, UINT256, 1)
@@ -191,8 +170,7 @@ TYPED_SFIELD(sfNFTokenID, UINT256, 10)
TYPED_SFIELD(sfEmitParentTxnID, UINT256, 11)
TYPED_SFIELD(sfEmitNonce, UINT256, 12)
TYPED_SFIELD(sfEmitHookHash, UINT256, 13)
TYPED_SFIELD(sfAMMID, UINT256, 14,
SField::sMD_PseudoAccount |SField::sMD_Default)
TYPED_SFIELD(sfAMMID, UINT256, 14)
// 256-bit (uncommon)
TYPED_SFIELD(sfBookDirectory, UINT256, 16)
@@ -214,27 +192,9 @@ TYPED_SFIELD(sfHookHash, UINT256, 31)
TYPED_SFIELD(sfHookNamespace, UINT256, 32)
TYPED_SFIELD(sfHookSetTxnID, UINT256, 33)
TYPED_SFIELD(sfDomainID, UINT256, 34)
TYPED_SFIELD(sfVaultID, UINT256, 35,
SField::sMD_PseudoAccount | SField::sMD_Default)
TYPED_SFIELD(sfLoanBrokerID, UINT256, 36,
SField::sMD_PseudoAccount | SField::sMD_Default)
TYPED_SFIELD(sfLoanID, UINT256, 37)
// number (common)
TYPED_SFIELD(sfNumber, NUMBER, 1)
TYPED_SFIELD(sfAssetsAvailable, NUMBER, 2)
TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3)
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4)
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5)
TYPED_SFIELD(sfDebtTotal, NUMBER, 6)
TYPED_SFIELD(sfDebtMaximum, NUMBER, 7)
TYPED_SFIELD(sfCoverAvailable, NUMBER, 8)
TYPED_SFIELD(sfLoanOriginationFee, NUMBER, 9)
TYPED_SFIELD(sfLoanServiceFee, NUMBER, 10)
TYPED_SFIELD(sfLatePaymentFee, NUMBER, 11)
TYPED_SFIELD(sfClosePaymentFee, NUMBER, 12)
TYPED_SFIELD(sfPrincipalOutstanding, NUMBER, 13)
TYPED_SFIELD(sfPrincipalRequested, NUMBER, 14)
// currency amount (common)
TYPED_SFIELD(sfAmount, AMOUNT, 1)
@@ -319,6 +279,7 @@ TYPED_SFIELD(sfRegularKey, ACCOUNT, 8)
TYPED_SFIELD(sfNFTokenMinter, ACCOUNT, 9)
TYPED_SFIELD(sfEmitCallback, ACCOUNT, 10)
TYPED_SFIELD(sfHolder, ACCOUNT, 11)
TYPED_SFIELD(sfDelegate, ACCOUNT, 12)
// account (uncommon)
TYPED_SFIELD(sfHookAccount, ACCOUNT, 16)
@@ -329,8 +290,6 @@ TYPED_SFIELD(sfAttestationRewardAccount, ACCOUNT, 21)
TYPED_SFIELD(sfLockingChainDoor, ACCOUNT, 22)
TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
// vector of 256-bit
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
@@ -370,6 +329,7 @@ UNTYPED_SFIELD(sfSignerEntry, OBJECT, 11)
UNTYPED_SFIELD(sfNFToken, OBJECT, 12)
UNTYPED_SFIELD(sfEmitDetails, OBJECT, 13)
UNTYPED_SFIELD(sfHook, OBJECT, 14)
UNTYPED_SFIELD(sfPermission, OBJECT, 15)
// inner object (uncommon)
UNTYPED_SFIELD(sfSigner, OBJECT, 16)
@@ -390,7 +350,6 @@ UNTYPED_SFIELD(sfXChainClaimAttestationCollectionElement, OBJECT, 30)
UNTYPED_SFIELD(sfXChainCreateAccountAttestationCollectionElement, OBJECT, 31)
UNTYPED_SFIELD(sfPriceData, OBJECT, 32)
UNTYPED_SFIELD(sfCredential, OBJECT, 33)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 34, SField::sMD_Default, SField::notSigning)
// array of objects (common)
// ARRAY/1 is reserved for end of array
@@ -421,5 +380,4 @@ UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
UNTYPED_SFIELD(sfAuthorizeCredentials, ARRAY, 26)
UNTYPED_SFIELD(sfUnauthorizeCredentials, ARRAY, 27)
UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
// clang-format on
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)

View File

@@ -50,7 +50,7 @@ class TokenCodecErrcCategory : public std::error_category
{
public:
// Return a short descriptive name for the category
virtual const char*
virtual char const*
name() const noexcept override final
{
return "TokenCodecError";
@@ -86,7 +86,7 @@ public:
};
} // namespace detail
inline const ripple::detail::TokenCodecErrcCategory&
inline ripple::detail::TokenCodecErrcCategory const&
TokenCodecErrcCategory()
{
static ripple::detail::TokenCodecErrcCategory c;

View File

@@ -22,42 +22,14 @@
#endif
/**
* TRANSACTION(tag, value, name, privileges, fields)
* TRANSACTION(tag, value, name, delegatable, fields)
*
* You must define a transactor class in the `ripple` namespace named `name`,
* and include its header alongside the TRANSACTOR definition using this
* format:
* #if TRANSACTION_INCLUDE
* # include <xrpld/app/tx/detail/HEADER.h>
* #endif
*
* The `privileges` parameter of the TRANSACTION macro is a bitfield
* defining which operations the transaction can perform.
*
* The values are only used in InvariantCheck.cpp
* Valid values are
noPriv - The transaction can not do any of the enumerated operations
createAcct - The transaction can create a new ACCOUNT_ROOT object.
createPseudoAcct - The transaction can create a pseudo account,
which implies createAcct
mustDeleteAcct - The transaction must delete an ACCOUNT_ROOT object
mayDeleteAcct - The transaction may delete an ACCOUNT_ROOT object,
but does not have to
overrideFreeze - The transaction can override some freeze rules
changeNFTCounts - The transaction can mint or burn an NFT
createMPTIssuance - The transaction can create a new MPT issuance
destroyMPTIssuance - The transaction can destroy an MPT issuance
mustAuthorizeMPT - The transaction MUST create or delete an MPT
object (except by issuer)
mayAuthorizeMPT - The transaction MAY create or delete an MPT
object (except by issuer)
* and include its header in `src/xrpld/app/tx/detail/applySteps.cpp`.
*/
/** This transaction type executes a payment. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Payment.h>
#endif
TRANSACTION(ttPAYMENT, 0, Payment, createAcct, ({
TRANSACTION(ttPAYMENT, 0, Payment, Delegation::delegatable, ({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfSendMax, soeOPTIONAL, soeMPTSupported},
@@ -69,10 +41,7 @@ TRANSACTION(ttPAYMENT, 0, Payment, createAcct, ({
}))
/** This transaction type creates an escrow object. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Escrow.h>
#endif
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, noPriv, ({
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, Delegation::delegatable, ({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfCondition, soeOPTIONAL},
@@ -82,7 +51,7 @@ TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, noPriv, ({
}))
/** This transaction type completes an existing escrow. */
TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, noPriv, ({
TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, Delegation::delegatable, ({
{sfOwner, soeREQUIRED},
{sfOfferSequence, soeREQUIRED},
{sfFulfillment, soeOPTIONAL},
@@ -92,10 +61,7 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, noPriv, ({
/** This transaction type adjusts various account settings. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetAccount.h>
#endif
TRANSACTION(ttACCOUNT_SET, 3, AccountSet, noPriv, ({
TRANSACTION(ttACCOUNT_SET, 3, AccountSet, Delegation::notDelegatable, ({
{sfEmailHash, soeOPTIONAL},
{sfWalletLocator, soeOPTIONAL},
{sfWalletSize, soeOPTIONAL},
@@ -109,29 +75,20 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet, noPriv, ({
}))
/** This transaction type cancels an existing escrow. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Escrow.h>
#endif
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, noPriv, ({
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, Delegation::delegatable, ({
{sfOwner, soeREQUIRED},
{sfOfferSequence, soeREQUIRED},
}))
/** This transaction type sets or clears an account's "regular key". */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetRegularKey.h>
#endif
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey, noPriv, ({
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey, Delegation::notDelegatable, ({
{sfRegularKey, soeOPTIONAL},
}))
// 6 deprecated
/** This transaction type creates an offer to trade one asset for another. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateOffer.h>
#endif
TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, noPriv, ({
TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, Delegation::delegatable, ({
{sfTakerPays, soeREQUIRED},
{sfTakerGets, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
@@ -139,20 +96,14 @@ TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, noPriv, ({
}))
/** This transaction type cancels existing offers to trade one asset for another. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CancelOffer.h>
#endif
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, noPriv, ({
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, Delegation::delegatable, ({
{sfOfferSequence, soeREQUIRED},
}))
// 9 deprecated
/** This transaction type creates a new set of tickets. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateTicket.h>
#endif
TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, noPriv, ({
TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, Delegation::delegatable, ({
{sfTicketCount, soeREQUIRED},
}))
@@ -161,19 +112,13 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, noPriv, ({
/** This transaction type modifies the signer list associated with an account. */
// The SignerEntries are optional because a SignerList is deleted by
// setting the SignerQuorum to zero and omitting SignerEntries.
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetSignerList.h>
#endif
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, noPriv, ({
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, Delegation::notDelegatable, ({
{sfSignerQuorum, soeREQUIRED},
{sfSignerEntries, soeOPTIONAL},
}))
/** This transaction type creates a new unidirectional XRP payment channel. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PayChan.h>
#endif
TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, noPriv, ({
TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, Delegation::delegatable, ({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfSettleDelay, soeREQUIRED},
@@ -183,14 +128,14 @@ TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, noPriv, ({
}))
/** This transaction type funds an existing unidirectional XRP payment channel. */
TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund, noPriv, ({
TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund, Delegation::delegatable, ({
{sfChannel, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
}))
/** This transaction type submits a claim against an existing unidirectional payment channel. */
TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, noPriv, ({
TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, Delegation::delegatable, ({
{sfChannel, soeREQUIRED},
{sfAmount, soeOPTIONAL},
{sfBalance, soeOPTIONAL},
@@ -200,10 +145,7 @@ TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, noPriv, ({
}))
/** This transaction type creates a new check. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateCheck.h>
#endif
TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, noPriv, ({
TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, Delegation::delegatable, ({
{sfDestination, soeREQUIRED},
{sfSendMax, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
@@ -212,28 +154,19 @@ TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, noPriv, ({
}))
/** This transaction type cashes an existing check. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CashCheck.h>
#endif
TRANSACTION(ttCHECK_CASH, 17, CheckCash, noPriv, ({
TRANSACTION(ttCHECK_CASH, 17, CheckCash, Delegation::delegatable, ({
{sfCheckID, soeREQUIRED},
{sfAmount, soeOPTIONAL},
{sfDeliverMin, soeOPTIONAL},
}))
/** This transaction type cancels an existing check. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CancelCheck.h>
#endif
TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, noPriv, ({
TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, Delegation::delegatable, ({
{sfCheckID, soeREQUIRED},
}))
/** This transaction type grants or revokes authorization to transfer funds. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DepositPreauth.h>
#endif
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, noPriv, ({
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, Delegation::delegatable, ({
{sfAuthorize, soeOPTIONAL},
{sfUnauthorize, soeOPTIONAL},
{sfAuthorizeCredentials, soeOPTIONAL},
@@ -241,20 +174,14 @@ TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, noPriv, ({
}))
/** This transaction type modifies a trustline between two accounts. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetTrust.h>
#endif
TRANSACTION(ttTRUST_SET, 20, TrustSet, noPriv, ({
TRANSACTION(ttTRUST_SET, 20, TrustSet, Delegation::delegatable, ({
{sfLimitAmount, soeOPTIONAL},
{sfQualityIn, soeOPTIONAL},
{sfQualityOut, soeOPTIONAL},
}))
/** This transaction type deletes an existing account. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DeleteAccount.h>
#endif
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, mustDeleteAcct, ({
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, Delegation::notDelegatable, ({
{sfDestination, soeREQUIRED},
{sfDestinationTag, soeOPTIONAL},
{sfCredentialIDs, soeOPTIONAL},
@@ -263,10 +190,7 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, mustDeleteAcct, ({
// 22 reserved
/** This transaction mints a new NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenMint.h>
#endif
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, changeNFTCounts, ({
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, Delegation::delegatable, ({
{sfNFTokenTaxon, soeREQUIRED},
{sfTransferFee, soeOPTIONAL},
{sfIssuer, soeOPTIONAL},
@@ -277,19 +201,13 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, changeNFTCounts, ({
}))
/** This transaction burns (i.e. destroys) an existing NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenBurn.h>
#endif
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn, changeNFTCounts, ({
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn, Delegation::delegatable, ({
{sfNFTokenID, soeREQUIRED},
{sfOwner, soeOPTIONAL},
}))
/** This transaction creates a new offer to buy or sell an NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenCreateOffer.h>
#endif
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, noPriv, ({
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, Delegation::delegatable, ({
{sfNFTokenID, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfDestination, soeOPTIONAL},
@@ -298,38 +216,25 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, noPriv, ({
}))
/** This transaction cancels an existing offer to buy or sell an existing NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenCancelOffer.h>
#endif
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer, noPriv, ({
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer, Delegation::delegatable, ({
{sfNFTokenOffers, soeREQUIRED},
}))
/** This transaction accepts an existing offer to buy or sell an existing NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenAcceptOffer.h>
#endif
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer, noPriv, ({
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer, Delegation::delegatable, ({
{sfNFTokenBuyOffer, soeOPTIONAL},
{sfNFTokenSellOffer, soeOPTIONAL},
{sfNFTokenBrokerFee, soeOPTIONAL},
}))
/** This transaction claws back issued tokens. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Clawback.h>
#endif
TRANSACTION(ttCLAWBACK, 30, Clawback, noPriv, ({
TRANSACTION(ttCLAWBACK, 30, Clawback, Delegation::delegatable, ({
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfHolder, soeOPTIONAL},
}))
/** This transaction claws back tokens from an AMM pool. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMClawback.h>
#endif
TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
mayDeleteAcct | overrideFreeze, ({
TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback, Delegation::delegatable, ({
{sfHolder, soeREQUIRED},
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
@@ -337,20 +242,14 @@ TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
}))
/** This transaction type creates an AMM instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMCreate.h>
#endif
TRANSACTION(ttAMM_CREATE, 35, AMMCreate, createPseudoAcct, ({
TRANSACTION(ttAMM_CREATE, 35, AMMCreate, Delegation::delegatable, ({
{sfAmount, soeREQUIRED},
{sfAmount2, soeREQUIRED},
{sfTradingFee, soeREQUIRED},
}))
/** This transaction type deposits into an AMM instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMDeposit.h>
#endif
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, noPriv, ({
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, Delegation::delegatable, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfAmount, soeOPTIONAL},
@@ -361,10 +260,7 @@ TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, noPriv, ({
}))
/** This transaction type withdraws from an AMM instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMWithdraw.h>
#endif
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, mayDeleteAcct, ({
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, Delegation::delegatable, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfAmount, soeOPTIONAL},
@@ -374,20 +270,14 @@ TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, mayDeleteAcct, ({
}))
/** This transaction type votes for the trading fee */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMVote.h>
#endif
TRANSACTION(ttAMM_VOTE, 38, AMMVote, noPriv, ({
TRANSACTION(ttAMM_VOTE, 38, AMMVote, Delegation::delegatable, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfTradingFee, soeREQUIRED},
}))
/** This transaction type bids for the auction slot */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMBid.h>
#endif
TRANSACTION(ttAMM_BID, 39, AMMBid, noPriv, ({
TRANSACTION(ttAMM_BID, 39, AMMBid, Delegation::delegatable, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfBidMin, soeOPTIONAL},
@@ -396,26 +286,20 @@ TRANSACTION(ttAMM_BID, 39, AMMBid, noPriv, ({
}))
/** This transaction type deletes AMM in the empty state */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMDelete.h>
#endif
TRANSACTION(ttAMM_DELETE, 40, AMMDelete, mustDeleteAcct, ({
TRANSACTION(ttAMM_DELETE, 40, AMMDelete, Delegation::delegatable, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
}))
/** This transactions creates a crosschain sequence number */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/XChainBridge.h>
#endif
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID, noPriv, ({
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfOtherChainSource, soeREQUIRED},
}))
/** This transactions initiates a crosschain transaction */
TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit, noPriv, ({
TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -423,7 +307,7 @@ TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit, noPriv, ({
}))
/** This transaction completes a crosschain transaction */
TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim, noPriv, ({
TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfDestination, soeREQUIRED},
@@ -432,7 +316,7 @@ TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim, noPriv, ({
}))
/** This transaction initiates a crosschain account create transaction */
TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit, noPriv, ({
TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -440,7 +324,7 @@ TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit, noPri
}))
/** This transaction adds an attestation to a claim */
TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation, createAcct, ({
TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfAttestationSignerAccount, soeREQUIRED},
@@ -456,7 +340,7 @@ TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation, creat
}))
/** This transaction adds an attestation to an account */
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateAttestation, createAcct, ({
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateAttestation, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfAttestationSignerAccount, soeREQUIRED},
@@ -473,37 +357,31 @@ TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateA
}))
/** This transaction modifies a sidechain */
TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge, noPriv, ({
TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeOPTIONAL},
{sfMinAccountCreateAmount, soeOPTIONAL},
}))
/** This transactions creates a sidechain */
TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge, noPriv, ({
TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge, Delegation::delegatable, ({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfMinAccountCreateAmount, soeOPTIONAL},
}))
/** This transaction type creates or updates a DID */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DID.h>
#endif
TRANSACTION(ttDID_SET, 49, DIDSet, noPriv, ({
TRANSACTION(ttDID_SET, 49, DIDSet, Delegation::delegatable, ({
{sfDIDDocument, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfData, soeOPTIONAL},
}))
/** This transaction type deletes a DID */
TRANSACTION(ttDID_DELETE, 50, DIDDelete, noPriv, ({}))
TRANSACTION(ttDID_DELETE, 50, DIDDelete, Delegation::delegatable, ({}))
/** This transaction type creates an Oracle instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetOracle.h>
#endif
TRANSACTION(ttORACLE_SET, 51, OracleSet, noPriv, ({
TRANSACTION(ttORACLE_SET, 51, OracleSet, Delegation::delegatable, ({
{sfOracleDocumentID, soeREQUIRED},
{sfProvider, soeOPTIONAL},
{sfURI, soeOPTIONAL},
@@ -513,28 +391,18 @@ TRANSACTION(ttORACLE_SET, 51, OracleSet, noPriv, ({
}))
/** This transaction type deletes an Oracle instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DeleteOracle.h>
#endif
TRANSACTION(ttORACLE_DELETE, 52, OracleDelete, noPriv, ({
TRANSACTION(ttORACLE_DELETE, 52, OracleDelete, Delegation::delegatable, ({
{sfOracleDocumentID, soeREQUIRED},
}))
/** This transaction type fixes a problem in the ledger state */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LedgerStateFix.h>
#endif
TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix, noPriv, ({
TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix, Delegation::delegatable, ({
{sfLedgerFixType, soeREQUIRED},
{sfOwner, soeOPTIONAL},
}))
/** This transaction type creates a MPTokensIssuance instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceCreate.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
createMPTIssuance, ({
TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate, Delegation::delegatable, ({
{sfAssetScale, soeOPTIONAL},
{sfTransferFee, soeOPTIONAL},
{sfMaximumAmount, soeOPTIONAL},
@@ -542,37 +410,24 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
}))
/** This transaction type destroys a MPTokensIssuance instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceDestroy.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy,
destroyMPTIssuance, ({
TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy, Delegation::delegatable, ({
{sfMPTokenIssuanceID, soeREQUIRED},
}))
/** This transaction type sets flags on a MPTokensIssuance or MPToken instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceSet.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet, noPriv, ({
TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet, Delegation::delegatable, ({
{sfMPTokenIssuanceID, soeREQUIRED},
{sfHolder, soeOPTIONAL},
}))
/** This transaction type authorizes a MPToken instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenAuthorize.h>
#endif
TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize, mustAuthorizeMPT, ({
TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize, Delegation::delegatable, ({
{sfMPTokenIssuanceID, soeREQUIRED},
{sfHolder, soeOPTIONAL},
}))
/** This transaction type create an Credential instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Credentials.h>
#endif
TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, noPriv, ({
TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, Delegation::delegatable, ({
{sfSubject, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
@@ -580,219 +435,47 @@ TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, noPriv, ({
}))
/** This transaction type accept an Credential object */
TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept, noPriv, ({
TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept, Delegation::delegatable, ({
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
}))
/** This transaction type delete an Credential object */
TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete, noPriv, ({
TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete, Delegation::delegatable, ({
{sfSubject, soeOPTIONAL},
{sfIssuer, soeOPTIONAL},
{sfCredentialType, soeREQUIRED},
}))
/** This transaction type modify a NFToken */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenModify.h>
#endif
TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify, noPriv, ({
TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify, Delegation::delegatable, ({
{sfNFTokenID, soeREQUIRED},
{sfOwner, soeOPTIONAL},
{sfURI, soeOPTIONAL},
}))
/** This transaction type creates or modifies a Permissioned Domain */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PermissionedDomainSet.h>
#endif
TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet, noPriv, ({
TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet, Delegation::delegatable, ({
{sfDomainID, soeOPTIONAL},
{sfAcceptedCredentials, soeREQUIRED},
}))
/** This transaction type deletes a Permissioned Domain */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PermissionedDomainDelete.h>
#endif
TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete, noPriv, ({
TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete, Delegation::delegatable, ({
{sfDomainID, soeREQUIRED},
}))
/** This transaction creates a single asset vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultCreate.h>
#endif
TRANSACTION(ttVAULT_CREATE, 64, VaultCreate,
createPseudoAcct | createMPTIssuance, ({
{sfAsset, soeREQUIRED, soeMPTSupported},
{sfAssetsMaximum, soeOPTIONAL},
{sfMPTokenMetadata, soeOPTIONAL},
{sfDomainID, soeOPTIONAL}, // PermissionedDomainID
{sfWithdrawalPolicy, soeOPTIONAL},
{sfData, soeOPTIONAL},
}))
/** This transaction updates a single asset vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultSet.h>
#endif
TRANSACTION(ttVAULT_SET, 65, VaultSet, noPriv, ({
{sfVaultID, soeREQUIRED},
{sfAssetsMaximum, soeOPTIONAL},
{sfDomainID, soeOPTIONAL}, // PermissionedDomainID
{sfData, soeOPTIONAL},
}))
/** This transaction deletes a single asset vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultDelete.h>
#endif
TRANSACTION(ttVAULT_DELETE, 66, VaultDelete,
mustDeleteAcct | destroyMPTIssuance, ({
{sfVaultID, soeREQUIRED},
}))
/** This transaction trades assets for shares with a vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultDeposit.h>
#endif
TRANSACTION(ttVAULT_DEPOSIT, 67, VaultDeposit, mayAuthorizeMPT, ({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction trades shares for assets with a vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultWithdraw.h>
#endif
TRANSACTION(ttVAULT_WITHDRAW, 68, VaultWithdraw, noPriv, ({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfDestination, soeOPTIONAL},
}))
/** This transaction claws back tokens from a vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultClawback.h>
#endif
TRANSACTION(ttVAULT_CLAWBACK, 69, VaultClawback, noPriv, ({
{sfVaultID, soeREQUIRED},
{sfHolder, soeREQUIRED},
{sfAmount, soeOPTIONAL, soeMPTSupported},
}))
/** Reserve 70-73 for future Vault-related transactions */
/** This transaction creates and updates a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerSet.h>
#endif
TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
createPseudoAcct | mayAuthorizeMPT, ({
{sfVaultID, soeREQUIRED},
{sfLoanBrokerID, soeOPTIONAL},
{sfData, soeOPTIONAL},
{sfManagementFeeRate, soeOPTIONAL},
{sfDebtMaximum, soeOPTIONAL},
{sfCoverRateMinimum, soeOPTIONAL},
{sfCoverRateLiquidation, soeOPTIONAL},
}))
/** This transaction deletes a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerDelete.h>
#endif
TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
mustDeleteAcct | mayAuthorizeMPT, ({
{sfLoanBrokerID, soeREQUIRED},
}))
/** This transaction deposits First Loss Capital into a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerCoverDeposit.h>
#endif
TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit, noPriv, ({
{sfLoanBrokerID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction withdraws First Loss Capital from a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerCoverWithdraw.h>
#endif
TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw, noPriv, ({
{sfLoanBrokerID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction creates a Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanSet.h>
#endif
TRANSACTION(ttLOAN_SET, 78, LoanSet, noPriv, ({
{sfLoanBrokerID, soeREQUIRED},
{sfData, soeOPTIONAL},
{sfCounterparty, soeOPTIONAL},
{sfCounterpartySignature, soeREQUIRED},
{sfLoanOriginationFee, soeOPTIONAL},
{sfLoanServiceFee, soeOPTIONAL},
{sfLatePaymentFee, soeOPTIONAL},
{sfClosePaymentFee, soeOPTIONAL},
{sfOverpaymentFee, soeOPTIONAL},
{sfInterestRate, soeOPTIONAL},
{sfLateInterestRate, soeOPTIONAL},
{sfCloseInterestRate, soeOPTIONAL},
{sfOverpaymentInterestRate, soeOPTIONAL},
{sfPrincipalRequested, soeREQUIRED},
{sfStartDate, soeREQUIRED},
{sfPaymentTotal, soeOPTIONAL},
{sfPaymentInterval, soeOPTIONAL},
{sfGracePeriod, soeOPTIONAL},
}))
/** This transaction deletes an existing Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanDelete.h>
#endif
TRANSACTION(ttLOAN_DELETE, 79, LoanDelete, noPriv, ({
{sfLoanID, soeREQUIRED},
}))
/** This transaction is used to change the delinquency status of an existing Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanManage.h>
#endif
TRANSACTION(ttLOAN_MANAGE, 80, LoanManage, noPriv, ({
{sfLoanID, soeREQUIRED},
}))
/** The Borrower uses this transaction to draws funds from the Loan. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanDraw.h>
#endif
TRANSACTION(ttLOAN_DRAW, 81, LoanDraw, noPriv, ({
{sfLoanID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** The Borrower uses this transaction to make a Payment on the Loan. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanPay.h>
#endif
TRANSACTION(ttLOAN_PAY, 82, LoanPay, noPriv, ({
{sfLoanID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
/** This transaction type delegates authorized account specified permissions */
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet, Delegation::notDelegatable, ({
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
}))
/** This system-generated transaction type is used to update the status of the various amendments.
For details, see: https://xrpl.org/amendments.html
*/
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Change.h>
#endif
TRANSACTION(ttAMENDMENT, 100, EnableAmendment, noPriv, ({
TRANSACTION(ttAMENDMENT, 100, EnableAmendment, Delegation::notDelegatable, ({
{sfLedgerSequence, soeREQUIRED},
{sfAmendment, soeREQUIRED},
}))
@@ -800,7 +483,7 @@ TRANSACTION(ttAMENDMENT, 100, EnableAmendment, noPriv, ({
/** This system-generated transaction type is used to update the network's fee settings.
For details, see: https://xrpl.org/fee-voting.html
*/
TRANSACTION(ttFEE, 101, SetFee, noPriv, ({
TRANSACTION(ttFEE, 101, SetFee, Delegation::notDelegatable, ({
{sfLedgerSequence, soeOPTIONAL},
// Old version uses raw numbers
{sfBaseFee, soeOPTIONAL},
@@ -817,7 +500,7 @@ TRANSACTION(ttFEE, 101, SetFee, noPriv, ({
For details, see: https://xrpl.org/negative-unl.html
*/
TRANSACTION(ttUNL_MODIFY, 102, UNLModify, noPriv, ({
TRANSACTION(ttUNL_MODIFY, 102, UNLModify, Delegation::notDelegatable, ({
{sfUNLModifyDisabling, soeREQUIRED},
{sfLedgerSequence, soeREQUIRED},
{sfUNLModifyValidator, soeREQUIRED},

View File

@@ -20,7 +20,7 @@ struct JsonMissingKeyError : std::exception
JsonMissingKeyError(Json::StaticString const& k) : key{k.c_str()}
{
}
const char*
char const*
what() const noexcept override
{
if (msg.empty())
@@ -40,7 +40,7 @@ struct JsonTypeMismatchError : std::exception
: key{k.c_str()}, expectedType{std::move(et)}
{
}
const char*
char const*
what() const noexcept override
{
if (msg.empty())

View File

@@ -95,10 +95,10 @@ JSS(SigningPubKey); // field.
JSS(Subject); // in: Credential transactions
JSS(TakerGets); // field.
JSS(TakerPays); // field.
JSS(TxnSignature); // field.
JSS(TradingFee); // in/out: AMM trading fee
JSS(TransactionType); // in: TransactionSign.
JSS(TransferRate); // in: TransferRate.
JSS(TxnSignature); // field.
JSS(URI); // field.
JSS(VoteSlots); // out: AMM Vote
JSS(aborted); // out: InboundLedger
@@ -145,6 +145,7 @@ JSS(attestations);
JSS(attestation_reward_account);
JSS(auction_slot); // out: amm_info
JSS(authorized); // out: AccountLines
JSS(authorize); // out: delegate
JSS(authorized_credentials); // in: ledger_entry DepositPreauth
JSS(auth_accounts); // out: amm_info
JSS(auth_change); // out: AccountInfo
@@ -448,7 +449,6 @@ JSS(node_reads_hit); // out: GetCounts
JSS(node_reads_total); // out: GetCounts
JSS(node_reads_duration_us); // out: GetCounts
JSS(node_size); // out: server_info
JSS(nodes); // out: VaultInfo
JSS(nodestore); // out: GetCounts
JSS(node_writes); // out: GetCounts
JSS(node_written_bytes); // out: GetCounts
@@ -559,7 +559,6 @@ JSS(server_status); // out: NetworkOPs
JSS(server_version); // out: NetworkOPs
JSS(settle_delay); // out: AccountChannels
JSS(severity); // in: LogLevel
JSS(shares); // out: VaultInfo
JSS(signature); // out: NetworkOPs, ChannelAuthorize
JSS(signature_verified); // out: ChannelVerify
JSS(signing_key); // out: NetworkOPs
@@ -685,7 +684,6 @@ JSS(validations); // out: AmendmentTableImpl
JSS(validator_list_threshold); // out: ValidatorList
JSS(validator_sites); // out: ValidatorSites
JSS(value); // out: STAmount
JSS(vault_id); // in: VaultInfo
JSS(version); // out: RPCVersion
JSS(vetoed); // out: AmendmentTableImpl
JSS(volume_a); // out: BookChanges
@@ -702,7 +700,7 @@ JSS(write_load); // out: GetCounts
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, name, privileges, fields) JSS(name);
#define TRANSACTION(tag, value, name, delegatable, fields) JSS(name);
#include <xrpl/protocol/detail/transactions.macro>

View File

@@ -94,7 +94,7 @@ extractTarLz4(
if (archive_entry_size(entry) > 0)
{
const void* buf;
void const* buf;
size_t sz;
la_int64_t offset;
while (true)

View File

@@ -63,7 +63,7 @@ getFileContents(
return {};
}
const std::string result{
std::string const result{
std::istreambuf_iterator<char>{fileStream},
std::istreambuf_iterator<char>{}};

View File

@@ -20,8 +20,6 @@
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/predef.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -471,7 +469,7 @@ Number::operator/=(Number const& y)
}
// Shift by 10^17 gives greatest precision while not overflowing uint128_t
// or the cast back to int64_t
const uint128_t f = 100'000'000'000'000'000;
uint128_t const f = 100'000'000'000'000'000;
mantissa_ = static_cast<std::int64_t>(uint128_t(nm) * f / uint128_t(dm));
exponent_ = ne - de - 17;
mantissa_ *= np * dp;

View File

@@ -89,13 +89,13 @@ parseUrl(parsedURL& pUrl, std::string const& strUrl)
boost::algorithm::to_lower(pUrl.scheme);
pUrl.username = smMatch[2];
pUrl.password = smMatch[3];
const std::string domain = smMatch[4];
std::string const domain = smMatch[4];
// We need to use Endpoint to parse the domain to
// strip surrounding brackets from IPv6 addresses,
// e.g. [::1] => ::1.
const auto result = beast::IP::Endpoint::from_string_checked(domain);
auto const result = beast::IP::Endpoint::from_string_checked(domain);
pUrl.domain = result ? result->address().to_string() : domain;
const std::string port = smMatch[5];
std::string const port = smMatch[5];
if (!port.empty())
{
pUrl.port = beast::lexicalCast<std::uint16_t>(port);

View File

@@ -67,7 +67,7 @@ UptimeClock::time_point
UptimeClock::now()
{
// start the update thread on first use
static const auto init = start_clock();
static auto const init = start_clock();
// Return the number of seconds since rippled start
return time_point{duration{now_}};

View File

@@ -34,7 +34,7 @@ namespace Json {
namespace {
std::map<char, const char*> jsonSpecialCharacterEscape = {
std::map<char, char const*> jsonSpecialCharacterEscape = {
{'"', "\\\""},
{'\\', "\\\\"},
{'/', "\\/"},
@@ -47,13 +47,13 @@ std::map<char, const char*> jsonSpecialCharacterEscape = {
static size_t const jsonEscapeLength = 2;
// All other JSON punctuation.
const char closeBrace = '}';
const char closeBracket = ']';
const char colon = ':';
const char comma = ',';
const char openBrace = '{';
const char openBracket = '[';
const char quote = '"';
char const closeBrace = '}';
char const closeBracket = ']';
char const colon = ':';
char const comma = ',';
char const openBrace = '{';
char const openBracket = '[';
char const quote = '"';
static auto const integralFloatsBecomeInts = false;

View File

@@ -78,8 +78,8 @@ bool
Reader::parse(std::string const& document, Value& root)
{
document_ = document;
const char* begin = document_.c_str();
const char* end = begin + document_.length();
char const* begin = document_.c_str();
char const* end = begin + document_.length();
return parse(begin, end, root);
}
@@ -99,7 +99,7 @@ Reader::parse(std::istream& sin, Value& root)
}
bool
Reader::parse(const char* beginDoc, const char* endDoc, Value& root)
Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
{
begin_ = beginDoc;
end_ = endDoc;
@@ -193,7 +193,7 @@ Reader::skipCommentTokens(Token& token)
}
bool
Reader::expectToken(TokenType type, Token& token, const char* message)
Reader::expectToken(TokenType type, Token& token, char const* message)
{
readToken(token);
@@ -629,7 +629,7 @@ bool
Reader::decodeDouble(Token& token)
{
double value = 0;
const int bufferSize = 32;
int const bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
// Sanity check to avoid buffer overflow exploits.
@@ -939,7 +939,7 @@ Reader::getFormatedErrorMessages() const
itError != errors_.end();
++itError)
{
const ErrorInfo& error = *itError;
ErrorInfo const& error = *itError;
formattedMessage +=
"* " + getLocationLineAndColumn(error.token_.start_) + "\n";
formattedMessage += " " + error.message_ + "\n";

View File

@@ -31,10 +31,10 @@
namespace Json {
const Value Value::null;
const Int Value::minInt = Int(~(UInt(-1) / 2));
const Int Value::maxInt = Int(UInt(-1) / 2);
const UInt Value::maxUInt = UInt(-1);
Value const Value::null;
Int const Value::minInt = Int(~(UInt(-1) / 2));
Int const Value::maxInt = Int(UInt(-1) / 2);
UInt const Value::maxUInt = UInt(-1);
class DefaultValueAllocator : public ValueAllocator
{
@@ -42,7 +42,7 @@ public:
virtual ~DefaultValueAllocator() = default;
char*
makeMemberName(const char* memberName) override
makeMemberName(char const* memberName) override
{
return duplicateStringValue(memberName);
}
@@ -54,7 +54,7 @@ public:
}
char*
duplicateStringValue(const char* value, unsigned int length = unknown)
duplicateStringValue(char const* value, unsigned int length = unknown)
override
{
//@todo investigate this old optimization
@@ -110,14 +110,14 @@ Value::CZString::CZString(int index) : cstr_(0), index_(index)
{
}
Value::CZString::CZString(const char* cstr, DuplicationPolicy allocate)
Value::CZString::CZString(char const* cstr, DuplicationPolicy allocate)
: cstr_(
allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr)
, index_(allocate)
{
}
Value::CZString::CZString(const CZString& other)
Value::CZString::CZString(CZString const& other)
: cstr_(
other.index_ != noDuplication && other.cstr_ != 0
? valueAllocator()->makeMemberName(other.cstr_)
@@ -136,7 +136,7 @@ Value::CZString::~CZString()
}
bool
Value::CZString::operator<(const CZString& other) const
Value::CZString::operator<(CZString const& other) const
{
if (cstr_ && other.cstr_)
return strcmp(cstr_, other.cstr_) < 0;
@@ -145,7 +145,7 @@ Value::CZString::operator<(const CZString& other) const
}
bool
Value::CZString::operator==(const CZString& other) const
Value::CZString::operator==(CZString const& other) const
{
if (cstr_ && other.cstr_)
return strcmp(cstr_, other.cstr_) == 0;
@@ -159,7 +159,7 @@ Value::CZString::index() const
return index_;
}
const char*
char const*
Value::CZString::c_str() const
{
return cstr_;
@@ -232,25 +232,18 @@ Value::Value(double value) : type_(realValue)
value_.real_ = value;
}
Value::Value(const char* value) : type_(stringValue), allocated_(true)
Value::Value(char const* value) : type_(stringValue), allocated_(true)
{
value_.string_ = valueAllocator()->duplicateStringValue(value);
}
Value::Value(ripple::Number const& value) : type_(stringValue), allocated_(true)
{
auto const tmp = to_string(value);
value_.string_ =
valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
}
Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
{
value_.string_ = valueAllocator()->duplicateStringValue(
value.c_str(), (unsigned int)value.length());
}
Value::Value(const StaticString& value) : type_(stringValue), allocated_(false)
Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
{
value_.string_ = const_cast<char*>(value.c_str());
}
@@ -260,7 +253,7 @@ Value::Value(bool value) : type_(booleanValue)
value_.bool_ = value;
}
Value::Value(const Value& other) : type_(other.type_)
Value::Value(Value const& other) : type_(other.type_)
{
switch (type_)
{
@@ -377,7 +370,7 @@ integerCmp(Int i, UInt ui)
}
bool
operator<(const Value& x, const Value& y)
operator<(Value const& x, Value const& y)
{
if (auto signum = x.type_ - y.type_)
{
@@ -426,7 +419,7 @@ operator<(const Value& x, const Value& y)
}
bool
operator==(const Value& x, const Value& y)
operator==(Value const& x, Value const& y)
{
if (x.type_ != y.type_)
{
@@ -471,7 +464,7 @@ operator==(const Value& x, const Value& y)
return 0; // unreachable
}
const char*
char const*
Value::asCString() const
{
XRPL_ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
@@ -802,7 +795,7 @@ Value::operator[](UInt index)
return (*it).second;
}
const Value&
Value const&
Value::operator[](UInt index) const
{
XRPL_ASSERT(
@@ -822,13 +815,13 @@ Value::operator[](UInt index) const
}
Value&
Value::operator[](const char* key)
Value::operator[](char const* key)
{
return resolveReference(key, false);
}
Value&
Value::resolveReference(const char* key, bool isStatic)
Value::resolveReference(char const* key, bool isStatic)
{
XRPL_ASSERT(
type_ == nullValue || type_ == objectValue,
@@ -851,9 +844,9 @@ Value::resolveReference(const char* key, bool isStatic)
}
Value
Value::get(UInt index, const Value& defaultValue) const
Value::get(UInt index, Value const& defaultValue) const
{
const Value* value = &((*this)[index]);
Value const* value = &((*this)[index]);
return value == &null ? defaultValue : *value;
}
@@ -863,8 +856,8 @@ Value::isValidIndex(UInt index) const
return index < size();
}
const Value&
Value::operator[](const char* key) const
Value const&
Value::operator[](char const* key) const
{
XRPL_ASSERT(
type_ == nullValue || type_ == objectValue,
@@ -888,26 +881,20 @@ Value::operator[](std::string const& key)
return (*this)[key.c_str()];
}
const Value&
Value const&
Value::operator[](std::string const& key) const
{
return (*this)[key.c_str()];
}
Value&
Value::operator[](const StaticString& key)
Value::operator[](StaticString const& key)
{
return resolveReference(key, true);
}
Value const&
Value::operator[](const StaticString& key) const
{
return (*this)[key.c_str()];
}
Value&
Value::append(const Value& value)
Value::append(Value const& value)
{
return (*this)[size()] = value;
}
@@ -919,20 +906,20 @@ Value::append(Value&& value)
}
Value
Value::get(const char* key, const Value& defaultValue) const
Value::get(char const* key, Value const& defaultValue) const
{
const Value* value = &((*this)[key]);
Value const* value = &((*this)[key]);
return value == &null ? defaultValue : *value;
}
Value
Value::get(std::string const& key, const Value& defaultValue) const
Value::get(std::string const& key, Value const& defaultValue) const
{
return get(key.c_str(), defaultValue);
}
Value
Value::removeMember(const char* key)
Value::removeMember(char const* key)
{
XRPL_ASSERT(
type_ == nullValue || type_ == objectValue,
@@ -959,12 +946,12 @@ Value::removeMember(std::string const& key)
}
bool
Value::isMember(const char* key) const
Value::isMember(char const* key) const
{
if (type_ != objectValue)
return false;
const Value* value = &((*this)[key]);
Value const* value = &((*this)[key]);
return value != &null;
}

View File

@@ -37,7 +37,7 @@ ValueIteratorBase::ValueIteratorBase() : current_(), isNull_(true)
}
ValueIteratorBase::ValueIteratorBase(
const Value::ObjectValues::iterator& current)
Value::ObjectValues::iterator const& current)
: current_(current), isNull_(false)
{
}
@@ -61,7 +61,7 @@ ValueIteratorBase::decrement()
}
ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance(const SelfType& other) const
ValueIteratorBase::computeDistance(SelfType const& other) const
{
// Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default
@@ -89,7 +89,7 @@ ValueIteratorBase::computeDistance(const SelfType& other) const
}
bool
ValueIteratorBase::isEqual(const SelfType& other) const
ValueIteratorBase::isEqual(SelfType const& other) const
{
if (isNull_)
{
@@ -100,7 +100,7 @@ ValueIteratorBase::isEqual(const SelfType& other) const
}
void
ValueIteratorBase::copy(const SelfType& other)
ValueIteratorBase::copy(SelfType const& other)
{
current_ = other.current_;
}
@@ -108,7 +108,7 @@ ValueIteratorBase::copy(const SelfType& other)
Value
ValueIteratorBase::key() const
{
const Value::CZString czstring = (*current_).first;
Value::CZString const czstring = (*current_).first;
if (czstring.c_str())
{
@@ -124,7 +124,7 @@ ValueIteratorBase::key() const
UInt
ValueIteratorBase::index() const
{
const Value::CZString czstring = (*current_).first;
Value::CZString const czstring = (*current_).first;
if (!czstring.c_str())
return czstring.index();
@@ -132,10 +132,10 @@ ValueIteratorBase::index() const
return Value::UInt(-1);
}
const char*
char const*
ValueIteratorBase::memberName() const
{
const char* name = (*current_).first.c_str();
char const* name = (*current_).first.c_str();
return name ? name : "";
}
@@ -148,13 +148,13 @@ ValueIteratorBase::memberName() const
// //////////////////////////////////////////////////////////////////
ValueConstIterator::ValueConstIterator(
const Value::ObjectValues::iterator& current)
Value::ObjectValues::iterator const& current)
: ValueIteratorBase(current)
{
}
ValueConstIterator&
ValueConstIterator::operator=(const ValueIteratorBase& other)
ValueConstIterator::operator=(ValueIteratorBase const& other)
{
copy(other);
return *this;
@@ -168,23 +168,23 @@ ValueConstIterator::operator=(const ValueIteratorBase& other)
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
ValueIterator::ValueIterator(Value::ObjectValues::iterator const& current)
: ValueIteratorBase(current)
{
}
ValueIterator::ValueIterator(const ValueConstIterator& other)
ValueIterator::ValueIterator(ValueConstIterator const& other)
: ValueIteratorBase(other)
{
}
ValueIterator::ValueIterator(const ValueIterator& other)
ValueIterator::ValueIterator(ValueIterator const& other)
: ValueIteratorBase(other)
{
}
ValueIterator&
ValueIterator::operator=(const SelfType& other)
ValueIterator::operator=(SelfType const& other)
{
copy(other);
return *this;

View File

@@ -40,7 +40,7 @@ isControlCharacter(char ch)
}
static bool
containsControlCharacter(const char* str)
containsControlCharacter(char const* str)
{
while (*str)
{
@@ -117,7 +117,7 @@ valueToString(bool value)
}
std::string
valueToQuotedString(const char* value)
valueToQuotedString(char const* value)
{
// Not sure how to handle unicode...
if (strpbrk(value, "\"\\\b\f\n\r\t") == nullptr &&
@@ -132,7 +132,7 @@ valueToQuotedString(const char* value)
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
for (const char* c = value; *c != 0; ++c)
for (char const* c = value; *c != 0; ++c)
{
switch (*c)
{
@@ -197,7 +197,7 @@ valueToQuotedString(const char* value)
// //////////////////////////////////////////////////////////////////
std::string
FastWriter::write(const Value& root)
FastWriter::write(Value const& root)
{
document_ = "";
writeValue(root);
@@ -205,7 +205,7 @@ FastWriter::write(const Value& root)
}
void
FastWriter::writeValue(const Value& value)
FastWriter::writeValue(Value const& value)
{
switch (value.type())
{
@@ -281,7 +281,7 @@ StyledWriter::StyledWriter() : rightMargin_(74), indentSize_(3)
}
std::string
StyledWriter::write(const Value& root)
StyledWriter::write(Value const& root)
{
document_ = "";
addChildValues_ = false;
@@ -292,7 +292,7 @@ StyledWriter::write(const Value& root)
}
void
StyledWriter::writeValue(const Value& value)
StyledWriter::writeValue(Value const& value)
{
switch (value.type())
{
@@ -338,7 +338,7 @@ StyledWriter::writeValue(const Value& value)
while (true)
{
std::string const& name = *it;
const Value& childValue = value[name];
Value const& childValue = value[name];
writeWithIndent(valueToQuotedString(name.c_str()));
document_ += " : ";
writeValue(childValue);
@@ -358,7 +358,7 @@ StyledWriter::writeValue(const Value& value)
}
void
StyledWriter::writeArrayValue(const Value& value)
StyledWriter::writeArrayValue(Value const& value)
{
unsigned size = value.size();
@@ -377,7 +377,7 @@ StyledWriter::writeArrayValue(const Value& value)
while (true)
{
const Value& childValue = value[index];
Value const& childValue = value[index];
if (hasChildValue)
writeWithIndent(childValues_[index]);
@@ -417,7 +417,7 @@ StyledWriter::writeArrayValue(const Value& value)
}
bool
StyledWriter::isMultineArray(const Value& value)
StyledWriter::isMultineArray(Value const& value)
{
int size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
@@ -425,7 +425,7 @@ StyledWriter::isMultineArray(const Value& value)
for (int index = 0; index < size && !isMultiLine; ++index)
{
const Value& childValue = value[index];
Value const& childValue = value[index];
isMultiLine = isMultiLine ||
((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
@@ -507,7 +507,7 @@ StyledStreamWriter::StyledStreamWriter(std::string indentation)
}
void
StyledStreamWriter::write(std::ostream& out, const Value& root)
StyledStreamWriter::write(std::ostream& out, Value const& root)
{
document_ = &out;
addChildValues_ = false;
@@ -518,7 +518,7 @@ StyledStreamWriter::write(std::ostream& out, const Value& root)
}
void
StyledStreamWriter::writeValue(const Value& value)
StyledStreamWriter::writeValue(Value const& value)
{
switch (value.type())
{
@@ -564,7 +564,7 @@ StyledStreamWriter::writeValue(const Value& value)
while (true)
{
std::string const& name = *it;
const Value& childValue = value[name];
Value const& childValue = value[name];
writeWithIndent(valueToQuotedString(name.c_str()));
*document_ << " : ";
writeValue(childValue);
@@ -584,7 +584,7 @@ StyledStreamWriter::writeValue(const Value& value)
}
void
StyledStreamWriter::writeArrayValue(const Value& value)
StyledStreamWriter::writeArrayValue(Value const& value)
{
unsigned size = value.size();
@@ -603,7 +603,7 @@ StyledStreamWriter::writeArrayValue(const Value& value)
while (true)
{
const Value& childValue = value[index];
Value const& childValue = value[index];
if (hasChildValue)
writeWithIndent(childValues_[index]);
@@ -643,7 +643,7 @@ StyledStreamWriter::writeArrayValue(const Value& value)
}
bool
StyledStreamWriter::isMultineArray(const Value& value)
StyledStreamWriter::isMultineArray(Value const& value)
{
int size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
@@ -651,7 +651,7 @@ StyledStreamWriter::isMultineArray(const Value& value)
for (int index = 0; index < size && !isMultiLine; ++index)
{
const Value& childValue = value[index];
Value const& childValue = value[index];
isMultiLine = isMultiLine ||
((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
@@ -726,7 +726,7 @@ StyledStreamWriter::unindent()
}
std::ostream&
operator<<(std::ostream& sout, const Value& root)
operator<<(std::ostream& sout, Value const& root)
{
Json::StyledStreamWriter writer;
writer.write(sout, root);

View File

@@ -39,6 +39,18 @@
namespace ripple {
AccountID
ammAccountID(
std::uint16_t prefix,
uint256 const& parentHash,
uint256 const& ammID)
{
ripesha_hasher rsh;
auto const hash = sha512Half(prefix, parentHash, ammID);
rsh(hash.data(), hash.size());
return AccountID{static_cast<ripesha_hasher::result_type>(rsh)};
}
Currency
ammLPTCurrency(Currency const& cur1, Currency const& cur2)
{

View File

@@ -23,7 +23,6 @@
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/jss.h>
#include <stdexcept>
@@ -52,12 +51,6 @@ Asset::setJson(Json::Value& jv) const
std::visit([&](auto&& issue) { issue.setJson(jv); }, issue_);
}
STAmount
Asset::operator()(Number const& number) const
{
return STAmount{*this, number};
}
std::string
to_string(Asset const& asset)
{
@@ -85,4 +78,11 @@ assetFromJson(Json::Value const& v)
return mptIssueFromJson(v);
}
Json::Value
to_json(Asset const& asset)
{
return std::visit(
[&](auto const& issue) { return to_json(issue); }, asset.value());
}
} // namespace ripple

View File

@@ -36,7 +36,7 @@ namespace BuildInfo {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "2.4.0"
char const* const versionString = "2.5.0-b1"
// clang-format on
#if defined(DEBUG) || defined(SANITIZER)

View File

@@ -107,6 +107,7 @@ constexpr static ErrorInfo unorderedErrorInfos[]{
{rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed.", 400},
{rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided.", 400},
{rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source account not found.", 404},
{rpcDELEGATE_ACT_NOT_FOUND, "delegateActNotFound", "Delegate account not found.", 404},
{rpcSRC_CUR_MALFORMED, "srcCurMalformed", "Source currency is malformed.", 400},
{rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed.", 400},
{rpcSTREAM_MALFORMED, "malformedStream", "Stream malformed.", 400},

View File

@@ -139,27 +139,27 @@ class FeatureCollections
{
if (i >= features.size())
LogicError("Invalid FeatureBitset index");
const auto& sequence = features.get<Feature::byIndex>();
auto const& sequence = features.get<Feature::byIndex>();
return sequence[i];
}
size_t
getIndex(Feature const& feature) const
{
const auto& sequence = features.get<Feature::byIndex>();
auto const& sequence = features.get<Feature::byIndex>();
auto const it_to = sequence.iterator_to(feature);
return it_to - sequence.begin();
}
Feature const*
getByFeature(uint256 const& feature) const
{
const auto& feature_index = features.get<Feature::byFeature>();
auto const& feature_index = features.get<Feature::byFeature>();
auto const feature_it = feature_index.find(feature);
return feature_it == feature_index.end() ? nullptr : &*feature_it;
}
Feature const*
getByName(std::string const& name) const
{
const auto& name_index = features.get<Feature::byName>();
auto const& name_index = features.get<Feature::byName>();
auto const name_it = name_index.find(name);
return name_it == name_index.end() ? nullptr : &*name_it;
}
@@ -240,7 +240,7 @@ FeatureCollections::getRegisteredFeature(std::string const& name) const
}
void
check(bool condition, const char* logicErrorMessage)
check(bool condition, char const* logicErrorMessage)
{
if (!condition)
LogicError(logicErrorMessage);
@@ -437,9 +437,13 @@ featureToName(uint256 const& f)
uint256 const feature##name = registerFeature(#name, supported, vote);
#define XRPL_FIX(name, supported, vote) \
uint256 const fix##name = registerFeature("fix" #name, supported, vote);
#define XRPL_RETIRE(name) \
[[deprecated("The referenced amendment has been retired"), maybe_unused]] \
// clang-format off
#define XRPL_RETIRE(name) \
[[deprecated("The referenced amendment has been retired")]] \
[[maybe_unused]] \
uint256 const retired##name = retireFeature(#name);
// clang-format on
#include <xrpl/protocol/detail/features.macro>
@@ -455,7 +459,7 @@ featureToName(uint256 const& f)
//
// Use initialization of one final static variable to set
// featureCollections::readOnly.
[[maybe_unused]] static const bool readOnlySet =
[[maybe_unused]] static bool const readOnlySet =
featureCollections.registrationIsDone();
} // namespace ripple

View File

@@ -94,9 +94,7 @@ enum class LedgerNameSpace : std::uint16_t {
MPTOKEN = 't',
CREDENTIAL = 'D',
PERMISSIONED_DOMAIN = 'm',
VAULT = 'V',
LOAN_BROKER = 'l', // lower-case L
LOAN = 'L',
DELEGATE = 'E',
// No longer used or supported. Left here to reserve the space
// to avoid accidental reuse.
@@ -455,6 +453,14 @@ amm(uint256 const& id) noexcept
return {ltAMM, id};
}
Keylet
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
{
return {
ltDELEGATE,
indexHash(LedgerNameSpace::DELEGATE, account, authorizedAccount)};
}
Keylet
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
{
@@ -546,24 +552,6 @@ credential(
indexHash(LedgerNameSpace::CREDENTIAL, subject, issuer, credType)};
}
Keylet
vault(AccountID const& owner, std::uint32_t seq) noexcept
{
return vault(indexHash(LedgerNameSpace::VAULT, owner, seq));
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept
{
return loanbroker(indexHash(LedgerNameSpace::LOAN_BROKER, owner, seq));
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept
{
return loan(indexHash(LedgerNameSpace::LOAN, loanBrokerID, loanSeq));
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept
{

View File

@@ -155,13 +155,9 @@ InnerObjectFormats::InnerObjectFormats()
{sfCredentialType, soeREQUIRED},
});
add(sfCounterpartySignature.jsonName,
sfCounterpartySignature.getCode(),
{
{sfSigningPubKey, soeOPTIONAL},
{sfTxnSignature, soeOPTIONAL},
{sfSigners, soeOPTIONAL},
});
add(sfPermission.jsonName.c_str(),
sfPermission.getCode(),
{{sfPermissionValue, soeREQUIRED}});
}
InnerObjectFormats const&

View File

@@ -37,7 +37,7 @@ Keylet::check(STLedgerEntry const& sle) const
if (type == ltCHILD)
return sle.getType() != ltDIR_NODE;
return sle.getType() == type && sle.key() == key;
return sle.getType() == type;
}
} // namespace ripple

View File

@@ -29,7 +29,7 @@ namespace ripple {
LedgerFormats::LedgerFormats()
{
// Fields shared by all ledger formats:
static const std::initializer_list<SOElement> commonFields{
static std::initializer_list<SOElement> const commonFields{
{sfLedgerIndex, soeOPTIONAL},
{sfLedgerEntryType, soeREQUIRED},
{sfFlags, soeREQUIRED},

View File

@@ -48,6 +48,12 @@ MPTIssue::getIssuer() const
return *account;
}
MPTID const&
MPTIssue::getMptID() const
{
return mptID_;
}
std::string
MPTIssue::getText() const
{

View File

@@ -0,0 +1,148 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Permissions.h>
#include <xrpl/protocol/jss.h>
namespace ripple {
Permission::Permission()
{
delegatableTx_ = {
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, name, delegatable, fields) {value, delegatable},
#include <xrpl/protocol/detail/transactions.macro>
#undef TRANSACTION
#pragma pop_macro("TRANSACTION")
};
granularPermissionMap_ = {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) {#type, type},
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
granularNameMap_ = {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) {type, #type},
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
granularTxTypeMap_ = {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) {type, txType},
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
for ([[maybe_unused]] auto const& permission : granularPermissionMap_)
XRPL_ASSERT(
permission.second > UINT16_MAX,
"ripple::Permission::granularPermissionMap_ : granular permission "
"value must not exceed the maximum uint16_t value.");
}
Permission const&
Permission::getInstance()
{
static Permission const instance;
return instance;
}
std::optional<std::uint32_t>
Permission::getGranularValue(std::string const& name) const
{
auto const it = granularPermissionMap_.find(name);
if (it != granularPermissionMap_.end())
return static_cast<uint32_t>(it->second);
return std::nullopt;
}
std::optional<std::string>
Permission::getGranularName(GranularPermissionType const& value) const
{
auto const it = granularNameMap_.find(value);
if (it != granularNameMap_.end())
return it->second;
return std::nullopt;
}
std::optional<TxType>
Permission::getGranularTxType(GranularPermissionType const& gpType) const
{
auto const it = granularTxTypeMap_.find(gpType);
if (it != granularTxTypeMap_.end())
return it->second;
return std::nullopt;
}
bool
Permission::isDelegatable(std::uint32_t const& permissionValue) const
{
auto const granularPermission =
getGranularName(static_cast<GranularPermissionType>(permissionValue));
if (granularPermission)
// granular permissions are always allowed to be delegated
return true;
auto const it = delegatableTx_.find(permissionValue - 1);
if (it != delegatableTx_.end() && it->second == Delegation::notDelegatable)
return false;
return true;
}
uint32_t
Permission::txToPermissionType(TxType const& type) const
{
return static_cast<uint32_t>(type) + 1;
}
TxType
Permission::permissionToTxType(uint32_t const& value) const
{
return static_cast<TxType>(value - 1);
}
} // namespace ripple

View File

@@ -183,7 +183,7 @@ Quality
Quality::round(int digits) const
{
// Modulus for mantissa
static const std::uint64_t mod[17] = {
static std::uint64_t const mod[17] = {
/* 0 */ 10000000000000000,
/* 1 */ 1000000000000000,
/* 2 */ 100000000000000,

View File

@@ -17,7 +17,6 @@
*/
//==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/SField.h>
#include <map>
@@ -29,7 +28,6 @@ namespace ripple {
SField::IsSigning const SField::notSigning;
int SField::num = 0;
std::map<int, SField const*> SField::knownCodeToField;
std::map<std::string, SField const*> SField::knownNameToField;
// Give only this translation unit permission to construct SFields
struct SField::private_access_tag_t
@@ -47,7 +45,7 @@ TypedField<T>::TypedField(private_access_tag_t pat, Args&&... args)
}
// Construct all compile-time SFields, and register them in the knownCodeToField
// and knownNameToField databases:
// database:
// Use macros for most SField construction to enforce naming conventions.
#pragma push_macro("UNTYPED_SFIELD")
@@ -89,7 +87,7 @@ SField::SField(
private_access_tag_t,
SerializedTypeID tid,
int fv,
const char* fn,
char const* fn,
int meta,
IsSigning signing)
: fieldCode(field_code(tid, fv))
@@ -101,14 +99,7 @@ SField::SField(
, signingField(signing)
, jsonName(fieldName.c_str())
{
XRPL_ASSERT(
!knownCodeToField.contains(fieldCode),
"ripple::SField::SField(tid,fv,fn,meta,signing) : fieldCode is unique");
XRPL_ASSERT(
!knownNameToField.contains(fieldName),
"ripple::SField::SField(tid,fv,fn,meta,signing) : fieldName is unique");
knownCodeToField[fieldCode] = this;
knownNameToField[fieldName] = this;
}
SField::SField(private_access_tag_t, int fc)
@@ -120,9 +111,6 @@ SField::SField(private_access_tag_t, int fc)
, signingField(IsSigning::yes)
, jsonName(fieldName.c_str())
{
XRPL_ASSERT(
!knownCodeToField.contains(fieldCode),
"ripple::SField::SField(fc) : fieldCode is unique");
knownCodeToField[fieldCode] = this;
}
@@ -157,11 +145,11 @@ SField::compare(SField const& f1, SField const& f2)
SField const&
SField::getField(std::string const& fieldName)
{
auto it = knownNameToField.find(fieldName);
if (it != knownNameToField.end())
for (auto const& [_, f] : knownCodeToField)
{
return *(it->second);
(void)_;
if (f->fieldName == fieldName)
return *f;
}
return sfInvalid;
}

View File

@@ -106,7 +106,7 @@ STAccount::add(Serializer& s) const
}
bool
STAccount::isEquivalent(const STBase& t) const
STAccount::isEquivalent(STBase const& t) const
{
auto const* const tPtr = dynamic_cast<STAccount const*>(&t);
return tPtr && (default_ == tPtr->default_) && (value_ == tPtr->value_);

View File

@@ -38,7 +38,6 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/protocol/UintTypes.h>
@@ -91,13 +90,13 @@ setSTAmountCanonicalizeSwitchover(bool v)
*getStaticSTAmountCanonicalizeSwitchover() = v;
}
static const std::uint64_t tenTo14 = 100000000000000ull;
static const std::uint64_t tenTo14m1 = tenTo14 - 1;
static const std::uint64_t tenTo17 = tenTo14 * 1000;
static std::uint64_t const tenTo14 = 100000000000000ull;
static std::uint64_t const tenTo14m1 = tenTo14 - 1;
static std::uint64_t const tenTo17 = tenTo14 * 1000;
//------------------------------------------------------------------------------
static std::int64_t
getInt64Value(STAmount const& amount, bool valid, const char* error)
getInt64Value(STAmount const& amount, bool valid, char const* error)
{
if (!valid)
Throw<std::runtime_error>(error);
@@ -310,7 +309,6 @@ STAmount::xrp() const
"Cannot return non-native STAmount as XRPAmount");
auto drops = static_cast<XRPAmount::value_type>(mValue);
XRPL_ASSERT(mOffset == 0, "ripple::STAmount::xrp : amount is canonical");
if (mIsNegative)
drops = -drops;
@@ -340,7 +338,6 @@ STAmount::mpt() const
Throw<std::logic_error>("Cannot return STAmount as MPTAmount");
auto value = static_cast<MPTAmount::value_type>(mValue);
XRPL_ASSERT(mOffset == 0, "ripple::STAmount::mpt : amount is canonical");
if (mIsNegative)
value = -value;
@@ -683,9 +680,9 @@ STAmount::add(Serializer& s) const
}
bool
STAmount::isEquivalent(const STBase& t) const
STAmount::isEquivalent(STBase const& t) const
{
const STAmount* v = dynamic_cast<const STAmount*>(&t);
STAmount const* v = dynamic_cast<STAmount const*>(&t);
return v && (*v == *this);
}
@@ -868,16 +865,75 @@ amountFromQuality(std::uint64_t rate)
STAmount
amountFromString(Asset const& asset, std::string const& amount)
{
auto const parts = partsFromString(amount);
if ((asset.native() || asset.holds<MPTIssue>()) && parts.exponent < 0)
static boost::regex const reNumber(
"^" // the beginning of the string
"([-+]?)" // (optional) + or - character
"(0|[1-9][0-9]*)" // a number (no leading zeroes, unless 0)
"(\\.([0-9]+))?" // (optional) period followed by any number
"([eE]([+-]?)([0-9]+))?" // (optional) E, optional + or -, any number
"$",
boost::regex_constants::optimize);
boost::smatch match;
if (!boost::regex_match(amount, match, reNumber))
Throw<std::runtime_error>("Number '" + amount + "' is not valid");
// Match fields:
// 0 = whole input
// 1 = sign
// 2 = integer portion
// 3 = whole fraction (with '.')
// 4 = fraction (without '.')
// 5 = whole exponent (with 'e')
// 6 = exponent sign
// 7 = exponent number
// CHECKME: Why 32? Shouldn't this be 16?
if ((match[2].length() + match[4].length()) > 32)
Throw<std::runtime_error>("Number '" + amount + "' is overlong");
bool negative = (match[1].matched && (match[1] == "-"));
// Can't specify XRP or MPT using fractional representation
if ((asset.native() || asset.holds<MPTIssue>()) && match[3].matched)
Throw<std::runtime_error>(
"XRP and MPT must be specified as integral amount.");
return {asset, parts.mantissa, parts.exponent, parts.negative};
std::uint64_t mantissa;
int exponent;
if (!match[4].matched) // integer only
{
mantissa =
beast::lexicalCastThrow<std::uint64_t>(std::string(match[2]));
exponent = 0;
}
else
{
// integer and fraction
mantissa = beast::lexicalCastThrow<std::uint64_t>(match[2] + match[4]);
exponent = -(match[4].length());
}
if (match[5].matched)
{
// we have an exponent
if (match[6].matched && (match[6] == "-"))
exponent -= beast::lexicalCastThrow<int>(std::string(match[7]));
else
exponent += beast::lexicalCastThrow<int>(std::string(match[7]));
}
return {asset, mantissa, exponent, negative};
}
STAmount
amountFromJson(SField const& name, Json::Value const& v)
{
STAmount::mantissa_type mantissa = 0;
STAmount::exponent_type exponent = 0;
bool negative = false;
Asset asset;
Json::Value value;
@@ -969,38 +1025,36 @@ amountFromJson(SField const& name, Json::Value const& v)
}
}
NumberParts parts;
if (value.isInt())
{
if (value.asInt() >= 0)
{
parts.mantissa = value.asInt();
mantissa = value.asInt();
}
else
{
parts.mantissa = -value.asInt();
parts.negative = true;
mantissa = -value.asInt();
negative = true;
}
}
else if (value.isUInt())
{
parts.mantissa = v.asUInt();
mantissa = v.asUInt();
}
else if (value.isString())
{
parts = partsFromString(value.asString());
// Can't specify XRP or MPT using fractional representation
if ((asset.native() || asset.holds<MPTIssue>()) && parts.exponent < 0)
Throw<std::runtime_error>(
"XRP and MPT must be specified as integral amount.");
auto const ret = amountFromString(asset, value.asString());
mantissa = ret.mantissa();
exponent = ret.exponent();
negative = ret.negative();
}
else
{
Throw<std::runtime_error>("invalid amount type");
}
return {name, asset, parts.mantissa, parts.exponent, parts.negative};
return {name, asset, mantissa, exponent, negative};
}
bool
@@ -1011,7 +1065,7 @@ amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource)
result = amountFromJson(sfGeneric, jvSource);
return true;
}
catch (const std::exception& e)
catch (std::exception const& e)
{
JLOG(debugLog().warn())
<< "amountFromJsonNoThrow: caught: " << e.what();

View File

@@ -181,9 +181,9 @@ STArray::getSType() const
}
bool
STArray::isEquivalent(const STBase& t) const
STArray::isEquivalent(STBase const& t) const
{
auto v = dynamic_cast<const STArray*>(&t);
auto v = dynamic_cast<STArray const*>(&t);
return v != nullptr && v_ == v->v_;
}
@@ -194,7 +194,7 @@ STArray::isDefault() const
}
void
STArray::sort(bool (*compare)(const STObject&, const STObject&))
STArray::sort(bool (*compare)(STObject const&, STObject const&))
{
std::sort(v_.begin(), v_.end(), compare);
}

View File

@@ -40,7 +40,7 @@ STBase::STBase(SField const& n) : fName(&n)
}
STBase&
STBase::operator=(const STBase& t)
STBase::operator=(STBase const& t)
{
if (!fName->isUseful())
fName = t.fName;
@@ -48,13 +48,13 @@ STBase::operator=(const STBase& t)
}
bool
STBase::operator==(const STBase& t) const
STBase::operator==(STBase const& t) const
{
return (getSType() == t.getSType()) && isEquivalent(t);
}
bool
STBase::operator!=(const STBase& t) const
STBase::operator!=(STBase const& t) const
{
return (getSType() != t.getSType()) || !isEquivalent(t);
}
@@ -116,7 +116,7 @@ STBase::add(Serializer& s) const
}
bool
STBase::isEquivalent(const STBase& t) const
STBase::isEquivalent(STBase const& t) const
{
XRPL_ASSERT(
getSType() == STI_NOTPRESENT,
@@ -154,7 +154,7 @@ STBase::addFieldID(Serializer& s) const
//------------------------------------------------------------------------------
std::ostream&
operator<<(std::ostream& out, const STBase& t)
operator<<(std::ostream& out, STBase const& t)
{
return out << t.getFullText();
}

View File

@@ -71,9 +71,9 @@ STBlob::add(Serializer& s) const
}
bool
STBlob::isEquivalent(const STBase& t) const
STBlob::isEquivalent(STBase const& t) const
{
const STBlob* v = dynamic_cast<const STBlob*>(&t);
STBlob const* v = dynamic_cast<STBlob const*>(&t);
return v && (value_ == v->value_);
}

View File

@@ -72,9 +72,9 @@ STCurrency::add(Serializer& s) const
}
bool
STCurrency::isEquivalent(const STBase& t) const
STCurrency::isEquivalent(STBase const& t) const
{
const STCurrency* v = dynamic_cast<const STCurrency*>(&t);
STCurrency const* v = dynamic_cast<STCurrency const*>(&t);
return v && (*v == *this);
}

View File

@@ -22,6 +22,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/Permissions.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STInteger.h>
@@ -177,6 +178,27 @@ template <>
Json::Value
STUInt32::getJson(JsonOptions) const
{
if (getFName() == sfPermissionValue)
{
auto const permissionValue =
static_cast<GranularPermissionType>(value_);
auto const granular =
Permission::getInstance().getGranularName(permissionValue);
if (granular)
{
return *granular;
}
else
{
auto const txType =
Permission::getInstance().permissionToTxType(value_);
auto item = TxFormats::getInstance().findByType(txType);
if (item != nullptr)
return item->getName();
}
}
return value_;
}

View File

@@ -128,9 +128,9 @@ STIssue::add(Serializer& s) const
}
bool
STIssue::isEquivalent(const STBase& t) const
STIssue::isEquivalent(STBase const& t) const
{
const STIssue* v = dynamic_cast<const STIssue*>(&t);
STIssue const* v = dynamic_cast<STIssue const*>(&t);
return v && (*v == *this);
}

View File

@@ -18,15 +18,12 @@
//==============================================================================
#include <xrpl/basics/Number.h>
#include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/Serializer.h>
#include <boost/regex.hpp>
#include <cstddef>
#include <ostream>
#include <string>
@@ -118,101 +115,4 @@ operator<<(std::ostream& out, STNumber const& rhs)
return out << rhs.getText();
}
NumberParts
partsFromString(std::string const& number)
{
static boost::regex const reNumber(
"^" // the beginning of the string
"([-+]?)" // (optional) + or - character
"(0|[1-9][0-9]*)" // a number (no leading zeroes, unless 0)
"(\\.([0-9]+))?" // (optional) period followed by any number
"([eE]([+-]?)([0-9]+))?" // (optional) E, optional + or -, any number
"$",
boost::regex_constants::optimize);
boost::smatch match;
if (!boost::regex_match(number, match, reNumber))
Throw<std::runtime_error>("'" + number + "' is not a number");
// Match fields:
// 0 = whole input
// 1 = sign
// 2 = integer portion
// 3 = whole fraction (with '.')
// 4 = fraction (without '.')
// 5 = whole exponent (with 'e')
// 6 = exponent sign
// 7 = exponent number
bool negative = (match[1].matched && (match[1] == "-"));
std::uint64_t mantissa;
int exponent;
if (!match[4].matched) // integer only
{
mantissa =
beast::lexicalCastThrow<std::uint64_t>(std::string(match[2]));
exponent = 0;
}
else
{
// integer and fraction
mantissa = beast::lexicalCastThrow<std::uint64_t>(match[2] + match[4]);
exponent = -(match[4].length());
}
if (match[5].matched)
{
// we have an exponent
if (match[6].matched && (match[6] == "-"))
exponent -= beast::lexicalCastThrow<int>(std::string(match[7]));
else
exponent += beast::lexicalCastThrow<int>(std::string(match[7]));
}
return {mantissa, exponent, negative};
}
STNumber
numberFromJson(SField const& field, Json::Value const& value)
{
NumberParts parts;
if (value.isInt())
{
if (value.asInt() >= 0)
{
parts.mantissa = value.asInt();
}
else
{
parts.mantissa = -value.asInt();
parts.negative = true;
}
}
else if (value.isUInt())
{
parts.mantissa = value.asUInt();
}
else if (value.isString())
{
parts = partsFromString(value.asString());
// Only strings can represent out-of-range values.
if (parts.mantissa > std::numeric_limits<std::int64_t>::max())
Throw<std::range_error>("too high");
}
else
{
Throw<std::runtime_error>("not a number");
}
std::int64_t mantissa = parts.mantissa;
if (parts.negative)
mantissa = -mantissa;
return STNumber{field, Number{mantissa, parts.exponent}};
}
} // namespace ripple

View File

@@ -153,7 +153,7 @@ STObject::operator=(STObject&& other)
}
void
STObject::set(const SOTemplate& type)
STObject::set(SOTemplate const& type)
{
v_.clear();
v_.reserve(type.size());
@@ -169,7 +169,7 @@ STObject::set(const SOTemplate& type)
}
void
STObject::applyTemplate(const SOTemplate& type)
STObject::applyTemplate(SOTemplate const& type)
{
auto throwFieldErr = [](std::string const& field, char const* description) {
std::stringstream ss;
@@ -296,9 +296,9 @@ STObject::set(SerialIter& sit, int depth)
}
bool
STObject::hasMatchingEntry(const STBase& t)
STObject::hasMatchingEntry(STBase const& t)
{
const STBase* o = peekAtPField(t.getFName());
STBase const* o = peekAtPField(t.getFName());
if (!o)
return false;
@@ -357,9 +357,9 @@ STObject::getText() const
}
bool
STObject::isEquivalent(const STBase& t) const
STObject::isEquivalent(STBase const& t) const
{
const STObject* v = dynamic_cast<const STObject*>(&t);
STObject const* v = dynamic_cast<STObject const*>(&t);
if (!v)
return false;
@@ -425,7 +425,7 @@ STObject::getFieldIndex(SField const& field) const
return -1;
}
const STBase&
STBase const&
STObject::peekAtField(SField const& field) const
{
int index = getFieldIndex(field);
@@ -453,7 +453,7 @@ STObject::getFieldSType(int index) const
return v_[index]->getFName();
}
const STBase*
STBase const*
STObject::peekAtPField(SField const& field) const
{
int index = getFieldIndex(field);
@@ -536,7 +536,7 @@ STObject::isFlag(std::uint32_t f) const
std::uint32_t
STObject::getFlags(void) const
{
const STUInt32* t = dynamic_cast<const STUInt32*>(peekAtPField(sfFlags));
STUInt32 const* t = dynamic_cast<STUInt32 const*>(peekAtPField(sfFlags));
if (!t)
return 0;
@@ -574,7 +574,7 @@ STObject::makeFieldAbsent(SField const& field)
if (index == -1)
throwFieldNotFound(field);
const STBase& f = peekAtIndex(index);
STBase const& f = peekAtIndex(index);
if (f.getSType() == STI_NOTPRESENT)
return;
@@ -675,24 +675,14 @@ STObject::getFieldPathSet(SField const& field) const
return getFieldByConstRef<STPathSet>(field, empty);
}
const STVector256&
STVector256 const&
STObject::getFieldV256(SField const& field) const
{
static STVector256 const empty{};
return getFieldByConstRef<STVector256>(field, empty);
}
STObject
STObject::getFieldObject(SField const& field) const
{
STObject const empty{field};
auto ret = getFieldByConstRef<STObject>(field, empty);
if (ret != empty)
ret.applyTemplateFromSField(field);
return ret;
}
const STArray&
STArray const&
STObject::getFieldArray(SField const& field) const
{
static STArray const empty{};
@@ -845,7 +835,7 @@ STObject::getJson(JsonOptions options) const
}
bool
STObject::operator==(const STObject& obj) const
STObject::operator==(STObject const& obj) const
{
// This is not particularly efficient, and only compares data elements
// with binary representations

View File

@@ -27,6 +27,7 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/Permissions.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAccount.h>
#include <xrpl/protocol/STAmount.h>
@@ -36,7 +37,6 @@
#include <xrpl/protocol/STCurrency.h>
#include <xrpl/protocol/STInteger.h>
#include <xrpl/protocol/STIssue.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/STPathSet.h>
#include <xrpl/protocol/STVector256.h>
@@ -82,31 +82,6 @@ constexpr std::
return static_cast<U1>(value);
}
template <typename U, typename S>
requires HasValue<U>
constexpr std::enable_if_t<
std::is_unsigned<typename U::value_type>::value && std::is_signed<S>::value,
U>
to_unsigned(S value)
{
if (value < 0 || std::numeric_limits<typename U::value_type>::max() < value)
Throw<std::runtime_error>("Value out of range");
return safe_cast<U>(static_cast<typename U::value_type>(value));
}
template <typename U1, typename U2>
requires HasValue<U1>
constexpr std::enable_if_t<
std::is_unsigned<typename U1::value_type>::value &&
std::is_unsigned<U2>::value,
U1>
to_unsigned(U2 value)
{
if (std::numeric_limits<typename U1::value_type>::max() < value)
Throw<std::runtime_error>("Value out of range");
return safe_cast<U1>(static_cast<typename U1::value_type>(value));
}
static std::string
make_name(std::string const& object, std::string const& field)
{
@@ -226,119 +201,6 @@ non_object_in_array(std::string const& item, Json::UInt index)
" is not an object. Arrays may only contain objects.");
}
template <class STResult, class Integer>
static std::optional<detail::STVar>
parseUnsigned(
SField const& field,
std::string const& json_name,
std::string const& fieldName,
SField const* name,
Json::Value const& value,
Json::Value& error)
{
std::optional<detail::STVar> ret;
try
{
if (value.isString())
{
ret = detail::make_stvar<STResult>(
field,
safe_cast<typename STResult::value_type>(
beast::lexicalCastThrow<Integer>(value.asString())));
}
else if (value.isInt())
{
ret = detail::make_stvar<STResult>(
field,
to_unsigned<typename STResult::value_type>(value.asInt()));
}
else if (value.isUInt())
{
ret = detail::make_stvar<STResult>(
field,
to_unsigned<typename STResult::value_type>(value.asUInt()));
}
else
{
error = bad_type(json_name, fieldName);
return ret;
}
}
catch (std::exception const&)
{
error = invalid_data(json_name, fieldName);
return ret;
}
return ret;
}
template <class STResult>
static std::optional<detail::STVar>
parseUint16(
SField const& field,
std::string const& json_name,
std::string const& fieldName,
SField const* name,
Json::Value const& value,
Json::Value& error)
{
std::optional<detail::STVar> ret;
try
{
if (value.isString())
{
std::string const strValue = value.asString();
if (!strValue.empty() &&
((strValue[0] < '0') || (strValue[0] > '9')))
{
if (field == sfTransactionType)
{
ret = detail::make_stvar<STResult>(
field,
safe_cast<typename STResult::value_type>(
static_cast<std::uint16_t>(
TxFormats::getInstance().findTypeByName(
strValue))));
if (*name == sfGeneric)
name = &sfTransaction;
}
else if (field == sfLedgerEntryType)
{
ret = detail::make_stvar<STResult>(
field,
safe_cast<typename STResult::value_type>(
static_cast<std::uint16_t>(
LedgerFormats::getInstance().findTypeByName(
strValue))));
if (*name == sfGeneric)
name = &sfLedgerEntry;
}
else
{
error = invalid_data(json_name, fieldName);
return ret;
}
}
}
if (!ret)
return parseUnsigned<STResult, std::uint16_t>(
field, json_name, fieldName, name, value, error);
}
catch (std::exception const&)
{
error = invalid_data(json_name, fieldName);
return ret;
}
return ret;
}
// This function is used by parseObject to parse any JSON type that doesn't
// recurse. Everything represented here is a leaf-type.
static std::optional<detail::STVar>
@@ -439,18 +301,130 @@ parseLeaf(
break;
case STI_UINT16:
ret = parseUint16<STUInt16>(
field, json_name, fieldName, name, value, error);
if (!ret)
try
{
if (value.isString())
{
std::string const strValue = value.asString();
if (!strValue.empty() &&
((strValue[0] < '0') || (strValue[0] > '9')))
{
if (field == sfTransactionType)
{
ret = detail::make_stvar<STUInt16>(
field,
static_cast<std::uint16_t>(
TxFormats::getInstance().findTypeByName(
strValue)));
if (*name == sfGeneric)
name = &sfTransaction;
}
else if (field == sfLedgerEntryType)
{
ret = detail::make_stvar<STUInt16>(
field,
static_cast<std::uint16_t>(
LedgerFormats::getInstance().findTypeByName(
strValue)));
if (*name == sfGeneric)
name = &sfLedgerEntry;
}
else
{
error = invalid_data(json_name, fieldName);
return ret;
}
}
else
{
ret = detail::make_stvar<STUInt16>(
field,
beast::lexicalCastThrow<std::uint16_t>(strValue));
}
}
else if (value.isInt())
{
ret = detail::make_stvar<STUInt16>(
field, to_unsigned<std::uint16_t>(value.asInt()));
}
else if (value.isUInt())
{
ret = detail::make_stvar<STUInt16>(
field, to_unsigned<std::uint16_t>(value.asUInt()));
}
else
{
error = bad_type(json_name, fieldName);
return ret;
}
}
catch (std::exception const&)
{
error = invalid_data(json_name, fieldName);
return ret;
}
break;
case STI_UINT32:
ret = parseUnsigned<STUInt32, std::uint32_t>(
field, json_name, fieldName, name, value, error);
if (!ret)
try
{
if (value.isString())
{
if (field == sfPermissionValue)
{
std::string const strValue = value.asString();
auto const granularPermission =
Permission::getInstance().getGranularValue(
strValue);
if (granularPermission)
{
ret = detail::make_stvar<STUInt32>(
field, *granularPermission);
}
else
{
auto const& txType =
TxFormats::getInstance().findTypeByName(
strValue);
ret = detail::make_stvar<STUInt32>(
field,
Permission::getInstance().txToPermissionType(
txType));
}
}
else
{
ret = detail::make_stvar<STUInt32>(
field,
beast::lexicalCastThrow<std::uint32_t>(
value.asString()));
}
}
else if (value.isInt())
{
ret = detail::make_stvar<STUInt32>(
field, to_unsigned<std::uint32_t>(value.asInt()));
}
else if (value.isUInt())
{
ret = detail::make_stvar<STUInt32>(
field, safe_cast<std::uint32_t>(value.asUInt()));
}
else
{
error = bad_type(json_name, fieldName);
return ret;
}
}
catch (std::exception const&)
{
error = invalid_data(json_name, fieldName);
return ret;
}
break;
@@ -639,20 +613,6 @@ parseLeaf(
break;
case STI_NUMBER:
try
{
ret =
detail::make_stvar<STNumber>(numberFromJson(field, value));
}
catch (std::exception const&)
{
error = invalid_data(json_name, fieldName);
return ret;
}
break;
case STI_VECTOR256:
if (!value.isArrayOrNull())
{
@@ -891,7 +851,7 @@ parseLeaf(
return ret;
}
static const int maxDepth = 64;
static int const maxDepth = 64;
// Forward declaration since parseObject() and parseArray() call each other.
static std::optional<detail::STVar>
@@ -1077,7 +1037,8 @@ parseArray(
Json::Value const objectFields(json[i][objectName]);
std::stringstream ss;
ss << json_name << "." << "[" << i << "]." << objectName;
ss << json_name << "."
<< "[" << i << "]." << objectName;
auto ret = parseObject(
ss.str(), objectFields, nameField, depth + 1, error);

View File

@@ -145,9 +145,9 @@ STPathSet::assembleAdd(STPath const& base, STPathElement const& tail)
}
bool
STPathSet::isEquivalent(const STBase& t) const
STPathSet::isEquivalent(STBase const& t) const
{
const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
STPathSet const* v = dynamic_cast<STPathSet const*>(&t);
return v && (value == v->value);
}

Some files were not shown because too many files have changed in this diff Show More