mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-19 01:55:48 +00:00
Merge branch 'dev' into remarks
This commit is contained in:
@@ -986,6 +986,7 @@ if (tests)
|
||||
src/test/rpc/AccountLinesRPC_test.cpp
|
||||
src/test/rpc/AccountObjects_test.cpp
|
||||
src/test/rpc/AccountOffers_test.cpp
|
||||
src/test/rpc/AccountNamespace_test.cpp
|
||||
src/test/rpc/AccountSet_test.cpp
|
||||
src/test/rpc/AccountTx_test.cpp
|
||||
src/test/rpc/AmendmentBlocked_test.cpp
|
||||
|
||||
@@ -52,6 +52,9 @@ Loop: ripple.overlay ripple.rpc
|
||||
Loop: test.app test.jtx
|
||||
test.app > test.jtx
|
||||
|
||||
Loop: test.app test.rpc
|
||||
test.rpc == test.app
|
||||
|
||||
Loop: test.jtx test.toplevel
|
||||
test.toplevel > test.jtx
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@ test.app > ripple.overlay
|
||||
test.app > ripple.protocol
|
||||
test.app > ripple.resource
|
||||
test.app > ripple.rpc
|
||||
test.app > test.rpc
|
||||
test.app > test.toplevel
|
||||
test.app > test.unit_test
|
||||
test.basics > ripple.basics
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_|
|
||||
// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____|
|
||||
// __/ | https://github.com/Neargye/magic_enum
|
||||
// |___/ version 0.9.3
|
||||
// |___/ version 0.9.5
|
||||
//
|
||||
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2019 - 2023 Daniil Goncharov <neargye@gmail.com>.
|
||||
// Copyright (c) 2019 - 2024 Daniil Goncharov <neargye@gmail.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#define MAGIC_ENUM_VERSION_MAJOR 0
|
||||
#define MAGIC_ENUM_VERSION_MINOR 9
|
||||
#define MAGIC_ENUM_VERSION_PATCH 3
|
||||
#define MAGIC_ENUM_VERSION_PATCH 5
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
#if defined(MAGIC_ENUM_NO_ASSERT)
|
||||
# define MAGIC_ENUM_ASSERT(...) static_cast<void>(0)
|
||||
#else
|
||||
#elif !defined(MAGIC_ENUM_ASSERT)
|
||||
# include <cassert>
|
||||
# define MAGIC_ENUM_ASSERT(...) assert((__VA_ARGS__))
|
||||
#endif
|
||||
@@ -69,9 +69,11 @@
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||
# pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
|
||||
# pragma clang diagnostic ignored "-Wuseless-cast" // suppresses 'static_cast<char_type>('\0')' for char_type = char (common on Linux).
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'.
|
||||
# pragma GCC diagnostic ignored "-Wuseless-cast" // suppresses 'static_cast<char_type>('\0')' for char_type = char (common on Linux).
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 26495) // Variable 'static_str<N>::chars_' is uninitialized.
|
||||
@@ -164,14 +166,11 @@ namespace customize {
|
||||
// If need another range for specific enum type, add specialization enum_range for necessary enum type.
|
||||
template <typename E>
|
||||
struct enum_range {
|
||||
static_assert(std::is_enum_v<E>, "magic_enum::customize::enum_range requires enum type.");
|
||||
static constexpr int min = MAGIC_ENUM_RANGE_MIN;
|
||||
static constexpr int max = MAGIC_ENUM_RANGE_MAX;
|
||||
static_assert(max > min, "magic_enum::customize::enum_range requires max > min.");
|
||||
};
|
||||
|
||||
static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN.");
|
||||
static_assert((MAGIC_ENUM_RANGE_MAX - MAGIC_ENUM_RANGE_MIN) < (std::numeric_limits<std::uint16_t>::max)(), "MAGIC_ENUM_RANGE must be less than UINT16_MAX.");
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -216,9 +215,9 @@ namespace detail {
|
||||
template <typename T>
|
||||
struct supported
|
||||
#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || defined(MAGIC_ENUM_NO_CHECK_SUPPORT)
|
||||
: std::true_type {};
|
||||
: std::true_type {};
|
||||
#else
|
||||
: std::false_type {};
|
||||
: std::false_type {};
|
||||
#endif
|
||||
|
||||
template <auto V, typename E = std::decay_t<decltype(V)>, std::enable_if_t<std::is_enum_v<E>, int> = 0>
|
||||
@@ -423,10 +422,20 @@ constexpr auto n() noexcept {
|
||||
constexpr auto name_ptr = MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(E);
|
||||
constexpr auto name = name_ptr ? str_view{name_ptr, std::char_traits<char>::length(name_ptr)} : str_view{};
|
||||
#elif defined(__clang__)
|
||||
auto name = str_view{__PRETTY_FUNCTION__ + 34, sizeof(__PRETTY_FUNCTION__) - 36};
|
||||
str_view name;
|
||||
if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) {
|
||||
static_assert(always_false_v<E>, "magic_enum::detail::n requires __PRETTY_FUNCTION__.");
|
||||
return str_view{};
|
||||
} else {
|
||||
name.size_ = sizeof(__PRETTY_FUNCTION__) - 36;
|
||||
name.str_ = __PRETTY_FUNCTION__ + 34;
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
auto name = str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1};
|
||||
if (name.str_[name.size_ - 1] == ']') {
|
||||
if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) {
|
||||
static_assert(always_false_v<E>, "magic_enum::detail::n requires __PRETTY_FUNCTION__.");
|
||||
return str_view{};
|
||||
} else if (name.str_[name.size_ - 1] == ']') {
|
||||
name.size_ -= 50;
|
||||
name.str_ += 49;
|
||||
} else {
|
||||
@@ -489,7 +498,14 @@ constexpr auto n() noexcept {
|
||||
constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V);
|
||||
auto name = name_ptr ? str_view{name_ptr, std::char_traits<char>::length(name_ptr)} : str_view{};
|
||||
#elif defined(__clang__)
|
||||
auto name = str_view{__PRETTY_FUNCTION__ + 34, sizeof(__PRETTY_FUNCTION__) - 36};
|
||||
str_view name;
|
||||
if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) {
|
||||
static_assert(always_false_v<decltype(V)>, "magic_enum::detail::n requires __PRETTY_FUNCTION__.");
|
||||
return str_view{};
|
||||
} else {
|
||||
name.size_ = sizeof(__PRETTY_FUNCTION__) - 36;
|
||||
name.str_ = __PRETTY_FUNCTION__ + 34;
|
||||
}
|
||||
if (name.size_ > 22 && name.str_[0] == '(' && name.str_[1] == 'a' && name.str_[10] == ' ' && name.str_[22] == ':') {
|
||||
name.size_ -= 23;
|
||||
name.str_ += 23;
|
||||
@@ -499,7 +515,10 @@ constexpr auto n() noexcept {
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
auto name = str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1};
|
||||
if (name.str_[name.size_ - 1] == ']') {
|
||||
if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) {
|
||||
static_assert(always_false_v<decltype(V)>, "magic_enum::detail::n requires __PRETTY_FUNCTION__.");
|
||||
return str_view{};
|
||||
} else if (name.str_[name.size_ - 1] == ']') {
|
||||
name.size_ -= 55;
|
||||
name.str_ += 54;
|
||||
} else {
|
||||
@@ -698,7 +717,7 @@ constexpr void valid_count(bool* valid, std::size_t& count) noexcept {
|
||||
} \
|
||||
}
|
||||
|
||||
MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_V);
|
||||
MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_V)
|
||||
|
||||
if constexpr ((I + 256) < Size) {
|
||||
valid_count<E, S, Size, Min, I + 256>(valid, count);
|
||||
@@ -750,7 +769,6 @@ constexpr auto values() noexcept {
|
||||
constexpr auto max = reflected_max<E, S>();
|
||||
constexpr auto range_size = max - min + 1;
|
||||
static_assert(range_size > 0, "magic_enum::enum_range requires valid size.");
|
||||
static_assert(range_size < (std::numeric_limits<std::uint16_t>::max)(), "magic_enum::enum_range requires valid size.");
|
||||
|
||||
return values<E, S, range_size, min>();
|
||||
}
|
||||
@@ -807,7 +825,8 @@ inline constexpr auto max_v = (count_v<E, S> > 0) ? static_cast<U>(values_v<E, S
|
||||
|
||||
template <typename E, enum_subtype S, std::size_t... I>
|
||||
constexpr auto names(std::index_sequence<I...>) noexcept {
|
||||
return std::array<string_view, sizeof...(I)>{{enum_name_v<E, values_v<E, S>[I]>...}};
|
||||
constexpr auto names = std::array<string_view, sizeof...(I)>{{enum_name_v<E, values_v<E, S>[I]>...}};
|
||||
return names;
|
||||
}
|
||||
|
||||
template <typename E, enum_subtype S>
|
||||
@@ -818,7 +837,8 @@ using names_t = decltype((names_v<D, S>));
|
||||
|
||||
template <typename E, enum_subtype S, std::size_t... I>
|
||||
constexpr auto entries(std::index_sequence<I...>) noexcept {
|
||||
return std::array<std::pair<E, string_view>, sizeof...(I)>{{{values_v<E, S>[I], enum_name_v<E, values_v<E, S>[I]>}...}};
|
||||
constexpr auto entries = std::array<std::pair<E, string_view>, sizeof...(I)>{{{values_v<E, S>[I], enum_name_v<E, values_v<E, S>[I]>}...}};
|
||||
return entries;
|
||||
}
|
||||
|
||||
template <typename E, enum_subtype S>
|
||||
@@ -845,17 +865,16 @@ constexpr bool is_sparse() noexcept {
|
||||
template <typename E, enum_subtype S = subtype_v<E>>
|
||||
inline constexpr bool is_sparse_v = is_sparse<E, S>();
|
||||
|
||||
template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>>
|
||||
constexpr U values_ors() noexcept {
|
||||
static_assert(S == enum_subtype::flags, "magic_enum::detail::values_ors requires valid subtype.");
|
||||
template <typename E, enum_subtype S>
|
||||
struct is_reflected
|
||||
#if defined(MAGIC_ENUM_NO_CHECK_REFLECTED_ENUM)
|
||||
: std::true_type {};
|
||||
#else
|
||||
: std::bool_constant<std::is_enum_v<E> && (count_v<E, S> != 0)> {};
|
||||
#endif
|
||||
|
||||
auto ors = U{0};
|
||||
for (std::size_t i = 0; i < count_v<E, S>; ++i) {
|
||||
ors |= static_cast<U>(values_v<E, S>[i]);
|
||||
}
|
||||
|
||||
return ors;
|
||||
}
|
||||
template <typename E, enum_subtype S>
|
||||
inline constexpr bool is_reflected_v = is_reflected<std::decay_t<E>, S>{};
|
||||
|
||||
template <bool, typename R>
|
||||
struct enable_if_enum {};
|
||||
@@ -1156,6 +1175,7 @@ template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_t<E, std::decay_t<E>> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
if constexpr (detail::is_sparse_v<D, S>) {
|
||||
return MAGIC_ENUM_ASSERT(index < detail::count_v<D, S>), detail::values_v<D, S>[index];
|
||||
@@ -1170,6 +1190,7 @@ template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
template <typename E, std::size_t I, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_t<E, std::decay_t<E>> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
static_assert(I < detail::count_v<D, S>, "magic_enum::enum_value out of range.");
|
||||
|
||||
return enum_value<D, S>(I);
|
||||
@@ -1178,7 +1199,10 @@ template <typename E, std::size_t I, detail::enum_subtype S = detail::subtype_v<
|
||||
// Returns std::array with enum values, sorted by enum value.
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_t<E, detail::values_t<E, S>> {
|
||||
return detail::values_v<std::decay_t<E>, S>;
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
return detail::values_v<D, S>;
|
||||
}
|
||||
|
||||
// Returns integer value from enum value.
|
||||
@@ -1199,11 +1223,9 @@ template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> {
|
||||
using D = std::decay_t<E>;
|
||||
using U = underlying_type_t<D>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
if constexpr (detail::count_v<D, S> == 0) {
|
||||
static_cast<void>(value);
|
||||
return {}; // Empty enum.
|
||||
} else if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) {
|
||||
if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) {
|
||||
#if defined(MAGIC_ENUM_ENABLE_HASH)
|
||||
return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::index>(
|
||||
[](std::size_t i) { return optional<std::size_t>{i}; },
|
||||
@@ -1231,14 +1253,17 @@ template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
template <detail::enum_subtype S, typename E>
|
||||
[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
return enum_index<D, S>(value);
|
||||
}
|
||||
|
||||
// Obtains index in enum values from static storage enum variable.
|
||||
template <auto V, detail::enum_subtype S = detail::subtype_v<std::decay_t<decltype(V)>>>
|
||||
[[nodiscard]] constexpr auto enum_index() noexcept -> detail::enable_if_t<decltype(V), std::size_t> {
|
||||
constexpr auto index = enum_index<std::decay_t<decltype(V)>, S>(V);
|
||||
[[nodiscard]] constexpr auto enum_index() noexcept -> detail::enable_if_t<decltype(V), std::size_t> {\
|
||||
using D = std::decay_t<decltype(V)>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
constexpr auto index = enum_index<D, S>(V);
|
||||
static_assert(index, "magic_enum::enum_index enum value does not have a index.");
|
||||
|
||||
return *index;
|
||||
@@ -1259,6 +1284,7 @@ template <auto V>
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_t<E, string_view> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
if (const auto i = enum_index<D, S>(value)) {
|
||||
return detail::names_v<D, S>[*i];
|
||||
@@ -1271,6 +1297,7 @@ template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
template <detail::enum_subtype S, typename E>
|
||||
[[nodiscard]] constexpr auto enum_name(E value) -> detail::enable_if_t<E, string_view> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
return enum_name<D, S>(value);
|
||||
}
|
||||
@@ -1278,13 +1305,19 @@ template <detail::enum_subtype S, typename E>
|
||||
// Returns std::array with names, sorted by enum value.
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_t<E, detail::names_t<E, S>> {
|
||||
return detail::names_v<std::decay_t<E>, S>;
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
return detail::names_v<D, S>;
|
||||
}
|
||||
|
||||
// Returns std::array with pairs (value, name), sorted by enum value.
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_t<E, detail::entries_t<E, S>> {
|
||||
return detail::entries_v<std::decay_t<E>, S>;
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
return detail::entries_v<D, S>;
|
||||
}
|
||||
|
||||
// Allows you to write magic_enum::enum_cast<foo>("bar", magic_enum::case_insensitive);
|
||||
@@ -1295,31 +1328,27 @@ inline constexpr auto case_insensitive = detail::case_insensitive<>{};
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
[[nodiscard]] constexpr auto enum_cast(underlying_type_t<E> value) noexcept -> detail::enable_if_t<E, optional<std::decay_t<E>>> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
if constexpr (detail::count_v<D, S> == 0) {
|
||||
static_cast<void>(value);
|
||||
return {}; // Empty enum.
|
||||
} else {
|
||||
if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) {
|
||||
if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) {
|
||||
#if defined(MAGIC_ENUM_ENABLE_HASH)
|
||||
return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::value>(
|
||||
[](D v) { return optional<D>{v}; },
|
||||
static_cast<D>(value),
|
||||
detail::default_result_type_lambda<optional<D>>);
|
||||
return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::value>(
|
||||
[](D v) { return optional<D>{v}; },
|
||||
static_cast<D>(value),
|
||||
detail::default_result_type_lambda<optional<D>>);
|
||||
#else
|
||||
for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
|
||||
if (value == static_cast<underlying_type_t<D>>(enum_value<D, S>(i))) {
|
||||
return static_cast<D>(value);
|
||||
}
|
||||
}
|
||||
return {}; // Invalid value or out of range.
|
||||
#endif
|
||||
} else {
|
||||
if (value >= detail::min_v<D, S> && value <= detail::max_v<D, S>) {
|
||||
for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
|
||||
if (value == static_cast<underlying_type_t<D>>(enum_value<D, S>(i))) {
|
||||
return static_cast<D>(value);
|
||||
}
|
||||
return {}; // Invalid value or out of range.
|
||||
}
|
||||
return {}; // Invalid value or out of range.
|
||||
#endif
|
||||
} else {
|
||||
if (value >= detail::min_v<D, S> && value <= detail::max_v<D, S>) {
|
||||
return static_cast<D>(value);
|
||||
}
|
||||
return {}; // Invalid value or out of range.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1328,26 +1357,23 @@ template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
|
||||
template <typename E, detail::enum_subtype S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
|
||||
[[nodiscard]] constexpr auto enum_cast(string_view value, [[maybe_unused]] BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable<BinaryPredicate>()) -> detail::enable_if_t<E, optional<std::decay_t<E>>, BinaryPredicate> {
|
||||
using D = std::decay_t<E>;
|
||||
static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min.");
|
||||
|
||||
if constexpr (detail::count_v<D, S> == 0) {
|
||||
static_cast<void>(value);
|
||||
return {}; // Empty enum.
|
||||
#if defined(MAGIC_ENUM_ENABLE_HASH)
|
||||
} else if constexpr (detail::is_default_predicate<BinaryPredicate>()) {
|
||||
return detail::constexpr_switch<&detail::names_v<D, S>, detail::case_call_t::index>(
|
||||
[](std::size_t i) { return optional<D>{detail::values_v<D, S>[i]}; },
|
||||
value,
|
||||
detail::default_result_type_lambda<optional<D>>,
|
||||
[&p](string_view lhs, string_view rhs) { return detail::cmp_equal(lhs, rhs, p); });
|
||||
#endif
|
||||
} else {
|
||||
for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
|
||||
if (detail::cmp_equal(value, detail::names_v<D, S>[i], p)) {
|
||||
return enum_value<D, S>(i);
|
||||
}
|
||||
}
|
||||
return {}; // Invalid value or out of range.
|
||||
if constexpr (detail::is_default_predicate<BinaryPredicate>()) {
|
||||
return detail::constexpr_switch<&detail::names_v<D, S>, detail::case_call_t::index>(
|
||||
[](std::size_t i) { return optional<D>{detail::values_v<D, S>[i]}; },
|
||||
value,
|
||||
detail::default_result_type_lambda<optional<D>>,
|
||||
[&p](string_view lhs, string_view rhs) { return detail::cmp_equal(lhs, rhs, p); });
|
||||
}
|
||||
#endif
|
||||
for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) {
|
||||
if (detail::cmp_equal(value, detail::names_v<D, S>[i], p)) {
|
||||
return enum_value<D, S>(i);
|
||||
}
|
||||
}
|
||||
return {}; // Invalid value or out of range.
|
||||
}
|
||||
|
||||
// Checks whether enum contains value with such value.
|
||||
|
||||
@@ -55,80 +55,98 @@ namespace ripple {
|
||||
// wrapped lines
|
||||
// clang-format off
|
||||
// Universal Transaction flags:
|
||||
constexpr std::uint32_t tfFullyCanonicalSig = 0x80000000;
|
||||
enum UniversalFlags : uint32_t {
|
||||
tfFullyCanonicalSig = 0x80000000,
|
||||
};
|
||||
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig;
|
||||
constexpr std::uint32_t tfUniversalMask = ~tfUniversal;
|
||||
|
||||
// AccountSet flags:
|
||||
constexpr std::uint32_t tfRequireDestTag = 0x00010000;
|
||||
constexpr std::uint32_t tfOptionalDestTag = 0x00020000;
|
||||
constexpr std::uint32_t tfRequireAuth = 0x00040000;
|
||||
constexpr std::uint32_t tfOptionalAuth = 0x00080000;
|
||||
constexpr std::uint32_t tfDisallowXRP = 0x00100000;
|
||||
constexpr std::uint32_t tfAllowXRP = 0x00200000;
|
||||
enum AccountSetFlags : uint32_t {
|
||||
tfRequireDestTag = 0x00010000,
|
||||
tfOptionalDestTag = 0x00020000,
|
||||
tfRequireAuth = 0x00040000,
|
||||
tfOptionalAuth = 0x00080000,
|
||||
tfDisallowXRP = 0x00100000,
|
||||
tfAllowXRP = 0x00200000,
|
||||
};
|
||||
constexpr std::uint32_t tfAccountSetMask =
|
||||
~(tfUniversal | tfRequireDestTag | tfOptionalDestTag | tfRequireAuth |
|
||||
tfOptionalAuth | tfDisallowXRP | tfAllowXRP);
|
||||
|
||||
// AccountSet SetFlag/ClearFlag values
|
||||
constexpr std::uint32_t asfRequireDest = 1;
|
||||
constexpr std::uint32_t asfRequireAuth = 2;
|
||||
constexpr std::uint32_t asfDisallowXRP = 3;
|
||||
constexpr std::uint32_t asfDisableMaster = 4;
|
||||
constexpr std::uint32_t asfAccountTxnID = 5;
|
||||
constexpr std::uint32_t asfNoFreeze = 6;
|
||||
constexpr std::uint32_t asfGlobalFreeze = 7;
|
||||
constexpr std::uint32_t asfDefaultRipple = 8;
|
||||
constexpr std::uint32_t asfDepositAuth = 9;
|
||||
constexpr std::uint32_t asfAuthorizedNFTokenMinter = 10;
|
||||
constexpr std::uint32_t asfTshCollect = 11;
|
||||
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer = 12;
|
||||
constexpr std::uint32_t asfDisallowIncomingCheck = 13;
|
||||
constexpr std::uint32_t asfDisallowIncomingPayChan = 14;
|
||||
constexpr std::uint32_t asfDisallowIncomingTrustline = 15;
|
||||
constexpr std::uint32_t asfDisallowIncomingRemit = 16;
|
||||
enum AccountFlags : uint32_t {
|
||||
asfRequireDest = 1,
|
||||
asfRequireAuth = 2,
|
||||
asfDisallowXRP = 3,
|
||||
asfDisableMaster = 4,
|
||||
asfAccountTxnID = 5,
|
||||
asfNoFreeze = 6,
|
||||
asfGlobalFreeze = 7,
|
||||
asfDefaultRipple = 8,
|
||||
asfDepositAuth = 9,
|
||||
asfAuthorizedNFTokenMinter = 10,
|
||||
asfTshCollect = 11,
|
||||
asfDisallowIncomingNFTokenOffer = 12,
|
||||
asfDisallowIncomingCheck = 13,
|
||||
asfDisallowIncomingPayChan = 14,
|
||||
asfDisallowIncomingTrustline = 15,
|
||||
asfDisallowIncomingRemit = 16,
|
||||
};
|
||||
|
||||
// OfferCreate flags:
|
||||
constexpr std::uint32_t tfPassive = 0x00010000;
|
||||
constexpr std::uint32_t tfImmediateOrCancel = 0x00020000;
|
||||
constexpr std::uint32_t tfFillOrKill = 0x00040000;
|
||||
constexpr std::uint32_t tfSell = 0x00080000;
|
||||
enum OfferCreateFlags : uint32_t {
|
||||
tfPassive = 0x00010000,
|
||||
tfImmediateOrCancel = 0x00020000,
|
||||
tfFillOrKill = 0x00040000,
|
||||
tfSell = 0x00080000,
|
||||
};
|
||||
constexpr std::uint32_t tfOfferCreateMask =
|
||||
~(tfUniversal | tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell);
|
||||
|
||||
// Payment flags:
|
||||
constexpr std::uint32_t tfNoRippleDirect = 0x00010000;
|
||||
constexpr std::uint32_t tfPartialPayment = 0x00020000;
|
||||
constexpr std::uint32_t tfLimitQuality = 0x00040000;
|
||||
enum PaymentFlags : uint32_t {
|
||||
tfNoRippleDirect = 0x00010000,
|
||||
tfPartialPayment = 0x00020000,
|
||||
tfLimitQuality = 0x00040000,
|
||||
};
|
||||
constexpr std::uint32_t tfPaymentMask =
|
||||
~(tfUniversal | tfPartialPayment | tfLimitQuality | tfNoRippleDirect);
|
||||
|
||||
// TrustSet flags:
|
||||
constexpr std::uint32_t tfSetfAuth = 0x00010000;
|
||||
constexpr std::uint32_t tfSetNoRipple = 0x00020000;
|
||||
constexpr std::uint32_t tfClearNoRipple = 0x00040000;
|
||||
constexpr std::uint32_t tfSetFreeze = 0x00100000;
|
||||
constexpr std::uint32_t tfClearFreeze = 0x00200000;
|
||||
enum TrustSetFlags : uint32_t {
|
||||
tfSetfAuth = 0x00010000,
|
||||
tfSetNoRipple = 0x00020000,
|
||||
tfClearNoRipple = 0x00040000,
|
||||
tfSetFreeze = 0x00100000,
|
||||
tfClearFreeze = 0x00200000,
|
||||
};
|
||||
constexpr std::uint32_t tfTrustSetMask =
|
||||
~(tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple | tfSetFreeze |
|
||||
tfClearFreeze);
|
||||
|
||||
// EnableAmendment flags:
|
||||
constexpr std::uint32_t tfGotMajority = 0x00010000;
|
||||
constexpr std::uint32_t tfLostMajority = 0x00020000;
|
||||
constexpr std::uint32_t tfTestSuite = 0x80000000;
|
||||
enum EnableAmendmentFlags : std::uint32_t {
|
||||
tfGotMajority = 0x00010000,
|
||||
tfLostMajority = 0x00020000,
|
||||
tfTestSuite = 0x80000000,
|
||||
};
|
||||
|
||||
// PaymentChannelClaim flags:
|
||||
constexpr std::uint32_t tfRenew = 0x00010000;
|
||||
constexpr std::uint32_t tfClose = 0x00020000;
|
||||
enum PaymentChannelClaimFlags : uint32_t {
|
||||
tfRenew = 0x00010000,
|
||||
tfClose = 0x00020000,
|
||||
};
|
||||
constexpr std::uint32_t tfPayChanClaimMask = ~(tfUniversal | tfRenew | tfClose);
|
||||
|
||||
// NFTokenMint flags:
|
||||
constexpr std::uint32_t const tfBurnable = 0x00000001;
|
||||
constexpr std::uint32_t const tfOnlyXRP = 0x00000002;
|
||||
constexpr std::uint32_t const tfTrustLine = 0x00000004;
|
||||
constexpr std::uint32_t const tfTransferable = 0x00000008;
|
||||
constexpr std::uint32_t const tfStrongTSH = 0x00008000;
|
||||
enum NFTokenMintFlags : uint32_t {
|
||||
tfBurnable = 0x00000001,
|
||||
tfOnlyXRP = 0x00000002,
|
||||
tfTrustLine = 0x00000004,
|
||||
tfTransferable = 0x00000008,
|
||||
tfStrongTSH = 0x00008000,
|
||||
};
|
||||
|
||||
constexpr std::uint32_t const tfNFTokenMintOldMask =
|
||||
~(tfUniversal | tfBurnable | tfOnlyXRP | tfTrustLine | tfTransferable | tfStrongTSH);
|
||||
@@ -151,7 +169,9 @@ constexpr std::uint32_t const tfNFTokenMintMask =
|
||||
~(tfUniversal | tfBurnable | tfOnlyXRP | tfTransferable | tfStrongTSH);
|
||||
|
||||
// NFTokenCreateOffer flags:
|
||||
constexpr std::uint32_t const tfSellNFToken = 0x00000001;
|
||||
enum NFTokenCreateOfferFlags : uint32_t {
|
||||
tfSellNFToken = 0x00000001,
|
||||
};
|
||||
constexpr std::uint32_t const tfNFTokenCreateOfferMask =
|
||||
~(tfUniversal | tfSellNFToken);
|
||||
|
||||
@@ -166,7 +186,9 @@ constexpr std::uint32_t const tfURITokenMintMask = ~(tfUniversal | tfBurnable);
|
||||
constexpr std::uint32_t const tfURITokenNonMintMask = ~tfUniversal;
|
||||
|
||||
// ClaimReward flags:
|
||||
constexpr std::uint32_t const tfOptOut = 0x00000001;
|
||||
enum ClaimRewardFlags : uint32_t {
|
||||
tfOptOut = 0x00000001,
|
||||
};
|
||||
|
||||
// Remarks flags:
|
||||
constexpr std::uint32_t const tfImmutable = 1;
|
||||
|
||||
@@ -108,6 +108,7 @@ constexpr static ErrorInfo unorderedErrorInfos[]{
|
||||
{rpcSTREAM_MALFORMED, "malformedStream", "Stream malformed.", 400},
|
||||
{rpcTOO_BUSY, "tooBusy", "The server is too busy to help you now.", 503},
|
||||
{rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found.", 404},
|
||||
{rpcNAMESPACE_NOT_FOUND, "namespaceNotFound", "Namespace not found.", 404},
|
||||
{rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method.", 405}};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ JSS(account_data); // out: AccountInfo
|
||||
JSS(account_flags); // out: AccountInfo
|
||||
JSS(account_hash); // out: LedgerToJson
|
||||
JSS(account_id); // out: WalletPropose
|
||||
JSS(account_namespace); // out: AccountNamespace
|
||||
JSS(account_nfts); // out: AccountNFTs
|
||||
JSS(account_objects); // out: AccountObjects
|
||||
JSS(account_root); // in: LedgerEntry
|
||||
@@ -354,6 +355,7 @@ JSS(id); // websocket.
|
||||
JSS(ident); // in: AccountCurrencies, AccountInfo,
|
||||
// OwnerInfo
|
||||
JSS(ignore_default); // in: AccountLines
|
||||
JSS(import_vlseq); // in: LedgerEntry
|
||||
JSS(inLedger); // out: tx/Transaction
|
||||
JSS(in_queue);
|
||||
JSS(inbound); // out: PeerImp
|
||||
@@ -666,50 +668,53 @@ JSS(trusted); // out: UnlList
|
||||
JSS(trusted_validator_keys); // out: ValidatorList
|
||||
JSS(tx); // out: STTx, AccountTx*
|
||||
JSS(txroot);
|
||||
JSS(tx_blob); // in/out: Submit,
|
||||
// in: TransactionSign, AccountTx*
|
||||
JSS(tx_hash); // in: TransactionEntry
|
||||
JSS(tx_json); // in/out: TransactionSign
|
||||
// out: TransactionEntry
|
||||
JSS(tx_signing_hash); // out: TransactionSign
|
||||
JSS(tx_unsigned); // out: TransactionSign
|
||||
JSS(txn_count); // out: NetworkOPs
|
||||
JSS(txr_tx_cnt); // out: protocol message tx's count
|
||||
JSS(txr_tx_sz); // out: protocol message tx's size
|
||||
JSS(txr_have_txs_cnt); // out: protocol message have tx count
|
||||
JSS(txr_have_txs_sz); // out: protocol message have tx size
|
||||
JSS(txr_get_ledger_cnt); // out: protocol message get ledger count
|
||||
JSS(txr_get_ledger_sz); // out: protocol message get ledger size
|
||||
JSS(txr_ledger_data_cnt); // out: protocol message ledger data count
|
||||
JSS(txr_ledger_data_sz); // out: protocol message ledger data size
|
||||
JSS(txr_transactions_cnt); // out: protocol message get object count
|
||||
JSS(txr_transactions_sz); // out: protocol message get object size
|
||||
JSS(txr_selected_cnt); // out: selected peers count
|
||||
JSS(txr_suppressed_cnt); // out: suppressed peers count
|
||||
JSS(txr_not_enabled_cnt); // out: peers with tx reduce-relay disabled count
|
||||
JSS(txr_missing_tx_freq); // out: missing tx frequency average
|
||||
JSS(txs); // out: TxHistory
|
||||
JSS(type); // in: AccountObjects
|
||||
// out: NetworkOPs RPC server_definitions
|
||||
// OverlayImpl, Logic
|
||||
JSS(TRANSACTION_RESULTS); // out: RPC server_definitions
|
||||
JSS(TRANSACTION_TYPES); // out: RPC server_definitions
|
||||
JSS(TYPES); // out: RPC server_definitions
|
||||
JSS(type_hex); // out: STPathSet
|
||||
JSS(unl); // out: UnlList
|
||||
JSS(unlimited); // out: Connection.h
|
||||
JSS(uptime); // out: GetCounts
|
||||
JSS(uri); // out: ValidatorSites
|
||||
JSS(uri_token); // in: LedgerEntry
|
||||
JSS(url); // in/out: Subscribe, Unsubscribe
|
||||
JSS(url_password); // in: Subscribe
|
||||
JSS(url_username); // in: Subscribe
|
||||
JSS(urlgravatar); //
|
||||
JSS(username); // in: Subscribe
|
||||
JSS(validated); // out: NetworkOPs, RPCHelpers, AccountTx*
|
||||
// Tx
|
||||
JSS(validator_list_expires); // out: NetworkOps, ValidatorList
|
||||
JSS(validator_list); // out: NetworkOps, ValidatorList
|
||||
JSS(tx_blob); // in/out: Submit,
|
||||
// in: TransactionSign, AccountTx*
|
||||
JSS(tx_hash); // in: TransactionEntry
|
||||
JSS(tx_json); // in/out: TransactionSign
|
||||
// out: TransactionEntry
|
||||
JSS(tx_signing_hash); // out: TransactionSign
|
||||
JSS(tx_unsigned); // out: TransactionSign
|
||||
JSS(txn_count); // out: NetworkOPs
|
||||
JSS(txr_tx_cnt); // out: protocol message tx's count
|
||||
JSS(txr_tx_sz); // out: protocol message tx's size
|
||||
JSS(txr_have_txs_cnt); // out: protocol message have tx count
|
||||
JSS(txr_have_txs_sz); // out: protocol message have tx size
|
||||
JSS(txr_get_ledger_cnt); // out: protocol message get ledger count
|
||||
JSS(txr_get_ledger_sz); // out: protocol message get ledger size
|
||||
JSS(txr_ledger_data_cnt); // out: protocol message ledger data count
|
||||
JSS(txr_ledger_data_sz); // out: protocol message ledger data size
|
||||
JSS(txr_transactions_cnt); // out: protocol message get object count
|
||||
JSS(txr_transactions_sz); // out: protocol message get object size
|
||||
JSS(txr_selected_cnt); // out: selected peers count
|
||||
JSS(txr_suppressed_cnt); // out: suppressed peers count
|
||||
JSS(txr_not_enabled_cnt); // out: peers with tx reduce-relay disabled count
|
||||
JSS(txr_missing_tx_freq); // out: missing tx frequency average
|
||||
JSS(txs); // out: TxHistory
|
||||
JSS(type); // in: AccountObjects
|
||||
// out: NetworkOPs RPC server_definitions
|
||||
// OverlayImpl, Logic
|
||||
JSS(TRANSACTION_RESULTS); // out: RPC server_definitions
|
||||
JSS(TRANSACTION_TYPES); // out: RPC server_definitions
|
||||
JSS(TYPES); // out: RPC server_definitions
|
||||
JSS(TRANSACTION_FLAGS); // out: RPC server_definitions
|
||||
JSS(TRANSACTION_FLAGS_INDICES); // out: RPC server_definitions
|
||||
JSS(type_hex); // out: STPathSet
|
||||
JSS(unl); // out: UnlList
|
||||
JSS(unlimited); // out: Connection.h
|
||||
JSS(unl_report); // in: LedgerEntry
|
||||
JSS(uptime); // out: GetCounts
|
||||
JSS(uri); // out: ValidatorSites
|
||||
JSS(uri_token); // in: LedgerEntry
|
||||
JSS(url); // in/out: Subscribe, Unsubscribe
|
||||
JSS(url_password); // in: Subscribe
|
||||
JSS(url_username); // in: Subscribe
|
||||
JSS(urlgravatar); //
|
||||
JSS(username); // in: Subscribe
|
||||
JSS(validated); // out: NetworkOPs, RPCHelpers, AccountTx*
|
||||
// Tx
|
||||
JSS(validator_list_expires); // out: NetworkOps, ValidatorList
|
||||
JSS(validator_list); // out: NetworkOps, ValidatorList
|
||||
JSS(validators);
|
||||
JSS(validated_hash); // out: NetworkOPs
|
||||
JSS(validated_ledger); // out: NetworkOPs
|
||||
|
||||
@@ -78,7 +78,7 @@ doAccountInfo(RPC::JsonContext& context)
|
||||
return jvAccepted;
|
||||
|
||||
static constexpr std::
|
||||
array<std::pair<std::string_view, LedgerSpecificFlags>, 9>
|
||||
array<std::pair<std::string_view, LedgerSpecificFlags>, 10>
|
||||
lsFlags{
|
||||
{{"defaultRipple", lsfDefaultRipple},
|
||||
{"depositAuth", lsfDepositAuth},
|
||||
@@ -88,6 +88,7 @@ doAccountInfo(RPC::JsonContext& context)
|
||||
{"noFreeze", lsfNoFreeze},
|
||||
{"passwordSpent", lsfPasswordSpent},
|
||||
{"requireAuthorization", lsfRequireAuth},
|
||||
{"tshCollect", lsfTshCollect},
|
||||
{"requireDestinationTag", lsfRequireDestTag}}};
|
||||
|
||||
static constexpr std::
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace ripple {
|
||||
namespace_id: <namespace hex>
|
||||
ledger_hash: <string> // optional
|
||||
ledger_index: <string | unsigned integer> // optional
|
||||
type: <string> // optional, defaults to all account objects types
|
||||
limit: <integer> // optional
|
||||
marker: <opaque> // optional, resume previous query
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <ripple/net/RPCErr.h>
|
||||
#include <ripple/protocol/ErrorCodes.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <ripple/rpc/Context.h>
|
||||
#include <ripple/rpc/GRPCHandlers.h>
|
||||
@@ -231,6 +232,41 @@ doLedgerEntry(RPC::JsonContext& context)
|
||||
uNodeIndex = keylet::emittedTxn(uNodeIndex).key;
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::import_vlseq))
|
||||
{
|
||||
expectedType = ltIMPORT_VLSEQ;
|
||||
if (!context.params[jss::import_vlseq].isObject())
|
||||
{
|
||||
if (!uNodeIndex.parseHex(
|
||||
context.params[jss::import_vlseq].asString()))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
}
|
||||
else if (
|
||||
!context.params[jss::import_vlseq].isMember(jss::public_key) ||
|
||||
!context.params[jss::import_vlseq][jss::public_key].isString())
|
||||
{
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const pkHex = strUnHex(
|
||||
context.params[jss::import_vlseq][jss::public_key].asString());
|
||||
auto const pkSlice = makeSlice(*pkHex);
|
||||
if (!publicKeyType(pkSlice))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const pk = PublicKey(pkSlice);
|
||||
uNodeIndex = keylet::import_vlseq(pk).key;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::offer))
|
||||
{
|
||||
expectedType = ltOFFER;
|
||||
@@ -277,11 +313,32 @@ doLedgerEntry(RPC::JsonContext& context)
|
||||
{
|
||||
expectedType = ltURI_TOKEN;
|
||||
|
||||
if (!uNodeIndex.parseHex(context.params[jss::uri_token].asString()))
|
||||
if (!context.params[jss::uri_token].isObject())
|
||||
{
|
||||
if (!uNodeIndex.parseHex(context.params[jss::uri_token].asString()))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
}
|
||||
else if (
|
||||
!context.params[jss::uri_token].isMember(jss::account) ||
|
||||
!context.params[jss::uri_token].isMember(jss::uri))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const id = parseBase58<AccountID>(
|
||||
context.params[jss::uri_token][jss::account].asString());
|
||||
auto const strUri =
|
||||
context.params[jss::uri_token][jss::uri].asString();
|
||||
Blob raw = Blob(strUri.begin(), strUri.end());
|
||||
if (!id)
|
||||
jvResult[jss::error] = "malformedAddress";
|
||||
else
|
||||
uNodeIndex = keylet::uritoken(*id, raw).key;
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::ripple_state))
|
||||
{
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#define MAGIC_ENUM_NO_CHECK_REFLECTED_ENUM
|
||||
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/AmendmentTable.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
@@ -26,6 +28,7 @@
|
||||
#include <ripple/net/RPCErr.h>
|
||||
#include <ripple/protocol/LedgerFormats.h>
|
||||
#include <ripple/protocol/SField.h>
|
||||
#include <ripple/protocol/TxFlags.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <ripple/rpc/impl/TransactionSign.h>
|
||||
@@ -41,6 +44,21 @@
|
||||
static constexpr int max = 20000; \
|
||||
};
|
||||
|
||||
#define MAGIC_ENUM_16(x) \
|
||||
template <> \
|
||||
struct magic_enum::customize::enum_range<x> \
|
||||
{ \
|
||||
static constexpr int min = -128; \
|
||||
static constexpr int max = 127; \
|
||||
};
|
||||
|
||||
#define MAGIC_ENUM_FLAG(x) \
|
||||
template <> \
|
||||
struct magic_enum::customize::enum_range<x> \
|
||||
{ \
|
||||
static constexpr bool is_flags = true; \
|
||||
};
|
||||
|
||||
MAGIC_ENUM(ripple::SerializedTypeID);
|
||||
MAGIC_ENUM(ripple::LedgerEntryType);
|
||||
MAGIC_ENUM(ripple::TELcodes);
|
||||
@@ -49,22 +67,45 @@ MAGIC_ENUM(ripple::TEFcodes);
|
||||
MAGIC_ENUM(ripple::TERcodes);
|
||||
MAGIC_ENUM(ripple::TEScodes);
|
||||
MAGIC_ENUM(ripple::TECcodes);
|
||||
MAGIC_ENUM_16(ripple::TxType);
|
||||
MAGIC_ENUM_FLAG(ripple::UniversalFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::AccountSetFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::OfferCreateFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::PaymentFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::TrustSetFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::EnableAmendmentFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::PaymentChannelClaimFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::NFTokenMintFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::NFTokenCreateOfferFlags);
|
||||
MAGIC_ENUM_FLAG(ripple::ClaimRewardFlags);
|
||||
MAGIC_ENUM_16(ripple::AccountFlags);
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Definitions
|
||||
{
|
||||
private:
|
||||
Json::Value
|
||||
generate()
|
||||
{
|
||||
// RH TODO: probably a better way to do this?
|
||||
#define STR(x) \
|
||||
([&] { \
|
||||
std::ostringstream ss; \
|
||||
return ss << (x), ss.str(); \
|
||||
}())
|
||||
|
||||
template <typename EnumType>
|
||||
void
|
||||
addFlagsToJson(Json::Value& json, std::string const& key)
|
||||
{
|
||||
for (auto const& entry : magic_enum::enum_entries<EnumType>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
json[jss::TRANSACTION_FLAGS][key][STR(name)] =
|
||||
static_cast<uint32_t>(entry.first);
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value
|
||||
generate()
|
||||
{
|
||||
Json::Value ret{Json::objectValue};
|
||||
ret[jss::TYPES] = Json::objectValue;
|
||||
|
||||
@@ -368,6 +409,39 @@ private:
|
||||
ret[jss::TRANSACTION_TYPES][type_name] = type_value;
|
||||
}
|
||||
|
||||
// Transaction Flags:
|
||||
ret[jss::TRANSACTION_FLAGS] = Json::objectValue;
|
||||
addFlagsToJson<UniversalFlags>(ret, "Universal");
|
||||
addFlagsToJson<AccountSetFlags>(ret, "AccountSet");
|
||||
addFlagsToJson<OfferCreateFlags>(ret, "OfferCreate");
|
||||
addFlagsToJson<PaymentFlags>(ret, "Payment");
|
||||
addFlagsToJson<TrustSetFlags>(ret, "TrustSet");
|
||||
addFlagsToJson<EnableAmendmentFlags>(ret, "EnableAmendment");
|
||||
addFlagsToJson<PaymentChannelClaimFlags>(ret, "PaymentChannelClaim");
|
||||
addFlagsToJson<NFTokenMintFlags>(ret, "NFTokenMint");
|
||||
addFlagsToJson<NFTokenCreateOfferFlags>(ret, "NFTokenCreateOffer");
|
||||
addFlagsToJson<ClaimRewardFlags>(ret, "ClaimReward");
|
||||
struct FlagData
|
||||
{
|
||||
std::string name;
|
||||
std::uint32_t value;
|
||||
};
|
||||
std::array<FlagData, 1> uriTokenMintFlags{{{"tfBurnable", tfBurnable}}};
|
||||
for (auto const& entry : uriTokenMintFlags)
|
||||
{
|
||||
ret[jss::TRANSACTION_FLAGS]["URITokenMint"][entry.name] =
|
||||
static_cast<uint32_t>(entry.value);
|
||||
}
|
||||
|
||||
// Transaction Indicies Flags:
|
||||
ret[jss::TRANSACTION_FLAGS_INDICES] = Json::objectValue;
|
||||
for (auto const& entry : magic_enum::enum_entries<AccountFlags>())
|
||||
{
|
||||
const auto name = entry.second;
|
||||
ret[jss::TRANSACTION_FLAGS_INDICES]["AccountSet"][STR(name)] =
|
||||
static_cast<uint32_t>(entry.first);
|
||||
}
|
||||
|
||||
ret[jss::native_currency_code] = systemCurrencyCode();
|
||||
|
||||
// generate hash
|
||||
|
||||
@@ -1067,7 +1067,7 @@ chooseLedgerEntryType(Json::Value const& params)
|
||||
std::pair<RPC::Status, LedgerEntryType> result{RPC::Status::OK, ltANY};
|
||||
if (params.isMember(jss::type))
|
||||
{
|
||||
static constexpr std::array<std::pair<char const*, LedgerEntryType>, 19>
|
||||
static constexpr std::array<std::pair<char const*, LedgerEntryType>, 22>
|
||||
types{
|
||||
{{jss::account, ltACCOUNT_ROOT},
|
||||
{jss::amendments, ltAMENDMENTS},
|
||||
@@ -1075,11 +1075,13 @@ chooseLedgerEntryType(Json::Value const& params)
|
||||
{jss::deposit_preauth, ltDEPOSIT_PREAUTH},
|
||||
{jss::directory, ltDIR_NODE},
|
||||
{jss::escrow, ltESCROW},
|
||||
{jss::emitted_txn, ltEMITTED_TXN},
|
||||
{jss::hook, ltHOOK},
|
||||
{jss::hook_definition, ltHOOK_DEFINITION},
|
||||
{jss::hook_state, ltHOOK_STATE},
|
||||
{jss::fee, ltFEE_SETTINGS},
|
||||
{jss::hashes, ltLEDGER_HASHES},
|
||||
{jss::import_vlseq, ltIMPORT_VLSEQ},
|
||||
{jss::offer, ltOFFER},
|
||||
{jss::payment_channel, ltPAYCHAN},
|
||||
{jss::uri_token, ltURI_TOKEN},
|
||||
@@ -1087,7 +1089,8 @@ chooseLedgerEntryType(Json::Value const& params)
|
||||
{jss::state, ltRIPPLE_STATE},
|
||||
{jss::ticket, ltTICKET},
|
||||
{jss::nft_offer, ltNFTOKEN_OFFER},
|
||||
{jss::nft_page, ltNFTOKEN_PAGE}}};
|
||||
{jss::nft_page, ltNFTOKEN_PAGE},
|
||||
{jss::unl_report, ltUNL_REPORT}}};
|
||||
|
||||
auto const& p = params[jss::type];
|
||||
if (!p.isString())
|
||||
|
||||
@@ -84,28 +84,6 @@ class Import_test : public beast::unit_test::suite
|
||||
return 0;
|
||||
}
|
||||
|
||||
STTx
|
||||
createUNLReportTx(
|
||||
LedgerIndex seq,
|
||||
PublicKey const& importKey,
|
||||
PublicKey const& valKey)
|
||||
{
|
||||
auto fill = [&](auto& obj) {
|
||||
obj.setFieldU32(sfLedgerSequence, seq);
|
||||
obj.set(([&]() {
|
||||
auto inner = std::make_unique<STObject>(sfActiveValidator);
|
||||
inner->setFieldVL(sfPublicKey, valKey);
|
||||
return inner;
|
||||
})());
|
||||
obj.set(([&]() {
|
||||
auto inner = std::make_unique<STObject>(sfImportVLKey);
|
||||
inner->setFieldVL(sfPublicKey, importKey);
|
||||
return inner;
|
||||
})());
|
||||
};
|
||||
return STTx(ttUNL_REPORT, fill);
|
||||
}
|
||||
|
||||
bool
|
||||
hasUNLReport(jtx::Env const& env)
|
||||
{
|
||||
@@ -5320,7 +5298,7 @@ class Import_test : public beast::unit_test::suite
|
||||
// insert a ttUNL_REPORT pseudo into the open ledger
|
||||
env.app().openLedger().modify(
|
||||
[&](OpenView& view, beast::Journal j) -> bool {
|
||||
STTx tx = createUNLReportTx(
|
||||
STTx tx = unl::createUNLReportTx(
|
||||
env.current()->seq() + 1, ivlKeys[0], vlKeys[0]);
|
||||
uint256 txID = tx.getTransactionID();
|
||||
auto s = std::make_shared<ripple::Serializer>();
|
||||
|
||||
@@ -3598,28 +3598,6 @@ struct XahauGenesis_test : public beast::unit_test::suite
|
||||
return slep != nullptr;
|
||||
}
|
||||
|
||||
STTx
|
||||
createUNLReportTx(
|
||||
LedgerIndex seq,
|
||||
PublicKey const& importKey,
|
||||
PublicKey const& valKey)
|
||||
{
|
||||
auto fill = [&](auto& obj) {
|
||||
obj.setFieldU32(sfLedgerSequence, seq);
|
||||
obj.set(([&]() {
|
||||
auto inner = std::make_unique<STObject>(sfActiveValidator);
|
||||
inner->setFieldVL(sfPublicKey, valKey);
|
||||
return inner;
|
||||
})());
|
||||
obj.set(([&]() {
|
||||
auto inner = std::make_unique<STObject>(sfImportVLKey);
|
||||
inner->setFieldVL(sfPublicKey, importKey);
|
||||
return inner;
|
||||
})());
|
||||
};
|
||||
return STTx(ttUNL_REPORT, fill);
|
||||
}
|
||||
|
||||
void
|
||||
activateUNLReport(
|
||||
jtx::Env& env,
|
||||
@@ -3631,7 +3609,7 @@ struct XahauGenesis_test : public beast::unit_test::suite
|
||||
{
|
||||
env.app().openLedger().modify(
|
||||
[&](OpenView& view, beast::Journal j) -> bool {
|
||||
STTx tx = createUNLReportTx(
|
||||
STTx tx = unl::createUNLReportTx(
|
||||
env.current()->seq() + 1, ivlKeys[0], vlKey);
|
||||
uint256 txID = tx.getTransactionID();
|
||||
auto s = std::make_shared<ripple::Serializer>();
|
||||
|
||||
@@ -90,6 +90,28 @@ createTx(bool disabling, LedgerIndex seq, PublicKey const& txKey)
|
||||
return STTx(ttUNL_MODIFY, fill);
|
||||
}
|
||||
|
||||
STTx
|
||||
createUNLReportTx(
|
||||
LedgerIndex seq,
|
||||
PublicKey const& importKey,
|
||||
PublicKey const& valKey)
|
||||
{
|
||||
auto fill = [&](auto& obj) {
|
||||
obj.setFieldU32(sfLedgerSequence, seq);
|
||||
obj.set(([&]() {
|
||||
auto inner = std::make_unique<STObject>(sfActiveValidator);
|
||||
inner->setFieldVL(sfPublicKey, valKey);
|
||||
return inner;
|
||||
})());
|
||||
obj.set(([&]() {
|
||||
auto inner = std::make_unique<STObject>(sfImportVLKey);
|
||||
inner->setFieldVL(sfPublicKey, importKey);
|
||||
return inner;
|
||||
})());
|
||||
};
|
||||
return STTx(ttUNL_REPORT, fill);
|
||||
}
|
||||
|
||||
} // namespace unl
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
|
||||
@@ -78,6 +78,20 @@ countTx(std::shared_ptr<SHAMap> const& txSet);
|
||||
STTx
|
||||
createTx(bool disabling, LedgerIndex seq, PublicKey const& txKey);
|
||||
|
||||
/**
|
||||
* Create ttUNL_REPORT Tx
|
||||
*
|
||||
* @param seq current ledger seq
|
||||
* @param importKey the public key of the import network
|
||||
* @param txKey the public key of the validator
|
||||
* @return the ttUNL_REPORT Tx
|
||||
*/
|
||||
STTx
|
||||
createUNLReportTx(
|
||||
LedgerIndex seq,
|
||||
PublicKey const& importKey,
|
||||
PublicKey const& valKey);
|
||||
|
||||
} // namespace unl
|
||||
|
||||
} // namespace test
|
||||
|
||||
@@ -516,7 +516,7 @@ public:
|
||||
};
|
||||
|
||||
static constexpr std::
|
||||
array<std::pair<std::string_view, std::uint32_t>, 7>
|
||||
array<std::pair<std::string_view, std::uint32_t>, 8>
|
||||
asFlags{
|
||||
{{"defaultRipple", asfDefaultRipple},
|
||||
{"depositAuth", asfDepositAuth},
|
||||
@@ -524,6 +524,7 @@ public:
|
||||
{"globalFreeze", asfGlobalFreeze},
|
||||
{"noFreeze", asfNoFreeze},
|
||||
{"requireAuthorization", asfRequireAuth},
|
||||
{"tshCollect", asfTshCollect},
|
||||
{"requireDestinationTag", asfRequireDest}}};
|
||||
|
||||
for (auto& asf : asFlags)
|
||||
|
||||
250
src/test/rpc/AccountNamespace_test.cpp
Normal file
250
src/test/rpc/AccountNamespace_test.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2024 XRPL-Labs
|
||||
|
||||
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 <ripple/protocol/Feature.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <test/jtx.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
class AccountNamespace_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
testErrors(FeatureBitset features)
|
||||
{
|
||||
testcase("error cases");
|
||||
|
||||
using namespace jtx;
|
||||
Env env(*this);
|
||||
|
||||
Account const alice{"alice"};
|
||||
Account const bob{"bob"};
|
||||
Account const carol{"carol"};
|
||||
env.fund(XRP(1000), alice, bob);
|
||||
env.close();
|
||||
|
||||
auto const ns = uint256::fromVoid(
|
||||
(std::array<uint8_t, 32>{
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU})
|
||||
.data());
|
||||
|
||||
{
|
||||
// account_namespace with no account.
|
||||
auto const info = env.rpc("json", "account_namespace", "{ }");
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_message] ==
|
||||
"Missing field 'account'.");
|
||||
}
|
||||
{
|
||||
// account_namespace missing filed namespace_id.
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
auto const info =
|
||||
env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_message] ==
|
||||
"Missing field 'namespace_id'.");
|
||||
}
|
||||
{
|
||||
// account_namespace with a malformed account string.
|
||||
Json::Value params;
|
||||
params[jss::account] =
|
||||
"n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV";
|
||||
params[jss::namespace_id] = "";
|
||||
auto const info =
|
||||
env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
{
|
||||
// account_namespace with an invalid namespace_id.
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::namespace_id] = "DEADBEEF";
|
||||
auto const info =
|
||||
env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
{
|
||||
// account_namespace with an account that's not in the ledger.
|
||||
Json::Value params;
|
||||
params[jss::account] = carol.human();
|
||||
params[jss::namespace_id] = to_string(ns);
|
||||
auto const info =
|
||||
env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_message] == "Account not found.");
|
||||
}
|
||||
{
|
||||
// account_namespace with a namespace that doesnt exist.
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::namespace_id] = to_string(ns);
|
||||
auto const info =
|
||||
env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_message] ==
|
||||
"Namespace not found.");
|
||||
}
|
||||
// test errors on marker
|
||||
{
|
||||
auto const key = uint256::fromVoid(
|
||||
(std::array<uint8_t, 32>{
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 'k', 'e', 'y', 0x00U})
|
||||
.data());
|
||||
|
||||
auto const ns = uint256::fromVoid(
|
||||
(std::array<uint8_t, 32>{
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU})
|
||||
.data());
|
||||
|
||||
auto const nons = uint256::fromVoid(
|
||||
(std::array<uint8_t, 32>{
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU,
|
||||
0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFEU, 0xCAU, 0xFFU})
|
||||
.data());
|
||||
|
||||
// Lambda to create a hook.
|
||||
auto setHook = [](test::jtx::Account const& account) {
|
||||
std::string const createCodeHex =
|
||||
"0061736D01000000011B0460027F7F017F60047F7F7F7F017E60037F7F"
|
||||
"7E01"
|
||||
"7E60017F017E02270303656E76025F67000003656E760973746174655F"
|
||||
"7365"
|
||||
"74000103656E76066163636570740002030201030503010002062B077F"
|
||||
"0141"
|
||||
"9088040B7F004180080B7F00418A080B7F004180080B7F00419088040B"
|
||||
"7F00"
|
||||
"41000B7F0041010B07080104686F6F6B00030AE7800001E3800002017F"
|
||||
"017E"
|
||||
"230041106B220124002001200036020C41012200200010001A20014180"
|
||||
"0828"
|
||||
"0000360208200141046A410022002F0088083B01002001200028008408"
|
||||
"3602"
|
||||
"004100200020014106200141086A4104100110022102200141106A2400"
|
||||
"2002"
|
||||
"0B0B1001004180080B096B65790076616C7565";
|
||||
std::string ns_str =
|
||||
"CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECA"
|
||||
"FECA"
|
||||
"FE";
|
||||
Json::Value jv =
|
||||
ripple::test::jtx::hook(account, {{hso(createCodeHex)}}, 0);
|
||||
jv[jss::Hooks][0U][jss::Hook][jss::HookNamespace] = ns_str;
|
||||
return jv;
|
||||
};
|
||||
|
||||
env(setHook(bob), fee(XRP(1)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
env(pay(alice, bob, XRP(1)), fee(XRP(1)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
Json::Value params;
|
||||
params[jss::account] = bob.human();
|
||||
params[jss::namespace_id] = to_string(ns);
|
||||
params[jss::limit] = 1;
|
||||
auto resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
|
||||
auto resume_marker = resp[jss::result][jss::marker];
|
||||
std::string mark = to_string(resume_marker);
|
||||
params[jss::marker] = 10;
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker', not string.");
|
||||
|
||||
params[jss::marker] = "This is a string with no comma";
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker'.");
|
||||
|
||||
params[jss::marker] = "This string has a comma, but is not hex";
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker'.");
|
||||
|
||||
params[jss::marker] = std::string(&mark[1U], 64);
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker'.");
|
||||
|
||||
params[jss::marker] = std::string(&mark[1U], 65);
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker'.");
|
||||
|
||||
params[jss::marker] = std::string(&mark[1U], 65) + "not hex";
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker'.");
|
||||
|
||||
params[jss::marker] = std::string(&mark[1U], 128);
|
||||
resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'marker'.");
|
||||
}
|
||||
|
||||
// test error on limit -ve
|
||||
{
|
||||
Account const bob{"bob"};
|
||||
Json::Value params;
|
||||
params[jss::account] = bob.human();
|
||||
params[jss::namespace_id] = to_string(ns);
|
||||
params[jss::limit] = -1;
|
||||
auto resp = env.rpc("json", "account_namespace", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
resp[jss::result][jss::error_message] ==
|
||||
"Invalid field 'limit', not unsigned integer.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
using namespace test::jtx;
|
||||
FeatureBitset const all{supported_amendments()};
|
||||
testErrors(all);
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(AccountNamespace, rpc, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -34,19 +34,19 @@ namespace test {
|
||||
static char const* bobs_account_objects[] = {
|
||||
R"json({
|
||||
"Account" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
|
||||
"BookDirectory" : "50AD0A9E54D2B381288D535EB724E4275FFBF41580D28A925D038D7EA4C68000",
|
||||
"BookDirectory" : "B025997A323F5C3E03DDF1334471F5984ABDE31C59D463525D038D7EA4C68000",
|
||||
"BookNode" : "0",
|
||||
"Flags" : 65536,
|
||||
"LedgerEntryType" : "Offer",
|
||||
"OwnerNode" : "0",
|
||||
"Sequence" : 6,
|
||||
"Sequence" : 4,
|
||||
"TakerGets" : {
|
||||
"currency" : "USD",
|
||||
"issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
|
||||
"issuer" : "r32rQHyesiTtdWFU7UJVtff4nCR5SHCbJW",
|
||||
"value" : "1"
|
||||
},
|
||||
"TakerPays" : "100000000",
|
||||
"index" : "29665262716C19830E26AEEC0916E476FC7D8EF195FF3B4F06829E64F82A3B3E"
|
||||
"index" : "A984D036A0E562433A8377CA57D1A1E056E58C0D04818F8DFD3A1AA3F217DD82"
|
||||
})json",
|
||||
R"json({
|
||||
"Balance" : {
|
||||
@@ -94,19 +94,19 @@ static char const* bobs_account_objects[] = {
|
||||
})json",
|
||||
R"json({
|
||||
"Account" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
|
||||
"BookDirectory" : "B025997A323F5C3E03DDF1334471F5984ABDE31C59D463525D038D7EA4C68000",
|
||||
"BookDirectory" : "50AD0A9E54D2B381288D535EB724E4275FFBF41580D28A925D038D7EA4C68000",
|
||||
"BookNode" : "0",
|
||||
"Flags" : 65536,
|
||||
"LedgerEntryType" : "Offer",
|
||||
"OwnerNode" : "0",
|
||||
"Sequence" : 7,
|
||||
"Sequence" : 3,
|
||||
"TakerGets" : {
|
||||
"currency" : "USD",
|
||||
"issuer" : "r32rQHyesiTtdWFU7UJVtff4nCR5SHCbJW",
|
||||
"issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
|
||||
"value" : "1"
|
||||
},
|
||||
"TakerPays" : "100000000",
|
||||
"index" : "F03ABE26CB8C5F4AFB31A86590BD25C64C5756FCE5CE9704C27AFE291A4A29A1"
|
||||
"index" : "E11029302EE744401427793A4F37BCB18F698D55C96851BEC5ABBD6242CF03D7"
|
||||
})json"};
|
||||
|
||||
class AccountObjects_test : public beast::unit_test::suite
|
||||
@@ -328,9 +328,7 @@ public:
|
||||
|
||||
aobj.removeMember("PreviousTxnID");
|
||||
aobj.removeMember("PreviousTxnLgrSeq");
|
||||
|
||||
BEAST_EXPECT(aobj == bobj[i]);
|
||||
|
||||
params[jss::marker] = resp[jss::result][jss::marker];
|
||||
}
|
||||
}
|
||||
@@ -734,7 +732,7 @@ public:
|
||||
auto const& ticket = resp[jss::result][jss::account_objects][0u];
|
||||
BEAST_EXPECT(ticket[sfAccount.jsonName] == gw.human());
|
||||
BEAST_EXPECT(ticket[sfLedgerEntryType.jsonName] == jss::Ticket);
|
||||
BEAST_EXPECT(ticket[sfTicketSequence.jsonName].asUInt() == 13);
|
||||
BEAST_EXPECT(ticket[sfTicketSequence.jsonName].asUInt() == 10);
|
||||
}
|
||||
{
|
||||
// Create a uri token.
|
||||
@@ -856,7 +854,7 @@ public:
|
||||
run() override
|
||||
{
|
||||
using namespace jtx;
|
||||
FeatureBitset const all{supported_amendments() - featureXahauGenesis};
|
||||
FeatureBitset const all{supported_amendments()};
|
||||
testErrors(all);
|
||||
testUnsteppedThenStepped(all);
|
||||
testUnsteppedThenSteppedWithNFTs(all);
|
||||
|
||||
@@ -119,23 +119,23 @@ public:
|
||||
BEAST_EXPECT(jroOuter[0u][jss::quality] == "100000000");
|
||||
BEAST_EXPECT(jroOuter[0u][jss::taker_gets][jss::currency] == "USD");
|
||||
BEAST_EXPECT(
|
||||
jroOuter[0u][jss::taker_gets][jss::issuer] == gw.human());
|
||||
BEAST_EXPECT(jroOuter[0u][jss::taker_gets][jss::value] == "2");
|
||||
BEAST_EXPECT(jroOuter[0u][jss::taker_pays] == "200000000");
|
||||
jroOuter[0u][jss::taker_gets][jss::issuer] == bob.human());
|
||||
BEAST_EXPECT(jroOuter[0u][jss::taker_gets][jss::value] == "1");
|
||||
BEAST_EXPECT(jroOuter[0u][jss::taker_pays] == "100000000");
|
||||
|
||||
BEAST_EXPECT(jroOuter[1u][jss::quality] == "100000000");
|
||||
BEAST_EXPECT(jroOuter[1u][jss::quality] == "5000000");
|
||||
BEAST_EXPECT(jroOuter[1u][jss::taker_gets][jss::currency] == "USD");
|
||||
BEAST_EXPECT(
|
||||
jroOuter[1u][jss::taker_gets][jss::issuer] == bob.human());
|
||||
BEAST_EXPECT(jroOuter[1u][jss::taker_gets][jss::value] == "1");
|
||||
BEAST_EXPECT(jroOuter[1u][jss::taker_pays] == "100000000");
|
||||
jroOuter[1u][jss::taker_gets][jss::issuer] == gw.human());
|
||||
BEAST_EXPECT(jroOuter[1u][jss::taker_gets][jss::value] == "6");
|
||||
BEAST_EXPECT(jroOuter[1u][jss::taker_pays] == "30000000");
|
||||
|
||||
BEAST_EXPECT(jroOuter[2u][jss::quality] == "5000000");
|
||||
BEAST_EXPECT(jroOuter[2u][jss::quality] == "100000000");
|
||||
BEAST_EXPECT(jroOuter[2u][jss::taker_gets][jss::currency] == "USD");
|
||||
BEAST_EXPECT(
|
||||
jroOuter[2u][jss::taker_gets][jss::issuer] == gw.human());
|
||||
BEAST_EXPECT(jroOuter[2u][jss::taker_gets][jss::value] == "6");
|
||||
BEAST_EXPECT(jroOuter[2u][jss::taker_pays] == "30000000");
|
||||
BEAST_EXPECT(jroOuter[2u][jss::taker_gets][jss::value] == "2");
|
||||
BEAST_EXPECT(jroOuter[2u][jss::taker_pays] == "200000000");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -327,7 +327,7 @@ public:
|
||||
run() override
|
||||
{
|
||||
using namespace jtx;
|
||||
FeatureBitset const all{supported_amendments() - featureXahauGenesis};
|
||||
FeatureBitset const all{supported_amendments()};
|
||||
testSequential(all, true);
|
||||
testSequential(all, false);
|
||||
testBadInput(all);
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/misc/HashRouter.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <test/app/Import_json.h>
|
||||
#include <test/jtx.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -308,11 +311,16 @@ public:
|
||||
// Put a bunch of different LedgerEntryTypes into a ledger
|
||||
using namespace test::jtx;
|
||||
using namespace std::chrono;
|
||||
Env env{*this, envconfig(validator, "")};
|
||||
|
||||
std::vector<std::string> const keys = {
|
||||
"ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC"
|
||||
"1"};
|
||||
Env env{*this, network::makeNetworkVLConfig(21337, keys)};
|
||||
|
||||
Account const alice{"alice"};
|
||||
Account const gw{"gateway"};
|
||||
auto const USD = gw["USD"];
|
||||
env.fund(XRP(100000), gw);
|
||||
env.fund(XRP(100000), gw, alice);
|
||||
|
||||
auto makeRequest = [&env](Json::StaticString const& type) {
|
||||
Json::Value jvParams;
|
||||
@@ -335,6 +343,10 @@ public:
|
||||
jss::ticket,
|
||||
jss::escrow,
|
||||
jss::payment_channel,
|
||||
jss::hook,
|
||||
jss::hook_definition,
|
||||
jss::hook_state,
|
||||
jss::uri_token,
|
||||
jss::deposit_preauth})
|
||||
{
|
||||
auto const jrr = makeRequest(type);
|
||||
@@ -399,6 +411,12 @@ public:
|
||||
env.close();
|
||||
}
|
||||
|
||||
{
|
||||
std::string const uri(maxTokenURILength, '?');
|
||||
env(uritoken::mint(Account{"bob2"}, uri));
|
||||
env.close();
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::PaymentChannelCreate;
|
||||
@@ -414,6 +432,63 @@ public:
|
||||
env(jv);
|
||||
}
|
||||
|
||||
{
|
||||
auto const master = Account("masterpassphrase");
|
||||
env(noop(master), fee(10'000'000'000), ter(tesSUCCESS));
|
||||
env.close();
|
||||
env(import::import(
|
||||
alice, import::loadXpop(test::ImportTCAccountSet::w_seed)),
|
||||
fee(10 * 10),
|
||||
ter(tesSUCCESS));
|
||||
env.close();
|
||||
}
|
||||
|
||||
{
|
||||
// ADD UNL REPORT
|
||||
std::vector<std::string> const _ivlKeys = {
|
||||
"ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1"
|
||||
"CDC1",
|
||||
"ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1"
|
||||
"CDC2",
|
||||
};
|
||||
|
||||
std::vector<PublicKey> ivlKeys;
|
||||
for (auto const& strPk : _ivlKeys)
|
||||
{
|
||||
auto pkHex = strUnHex(strPk);
|
||||
ivlKeys.emplace_back(makeSlice(*pkHex));
|
||||
}
|
||||
|
||||
std::vector<std::string> const _vlKeys = {
|
||||
"ED8E43A943A174190BA2FAE91F44AC6E2D1D8202EFDCC2EA3DBB39814576D6"
|
||||
"90F7",
|
||||
"ED45D1840EE724BE327ABE9146503D5848EFD5F38B6D5FEDE71E80ACCE5E6E"
|
||||
"738B"};
|
||||
|
||||
std::vector<PublicKey> vlKeys;
|
||||
for (auto const& strPk : _vlKeys)
|
||||
{
|
||||
auto pkHex = strUnHex(strPk);
|
||||
vlKeys.emplace_back(makeSlice(*pkHex));
|
||||
}
|
||||
|
||||
// insert a ttUNL_REPORT pseudo into the open ledger
|
||||
env.app().openLedger().modify(
|
||||
[&](OpenView& view, beast::Journal j) -> bool {
|
||||
STTx tx = test::unl::createUNLReportTx(
|
||||
env.current()->seq() + 1, ivlKeys[0], vlKeys[0]);
|
||||
uint256 txID = tx.getTransactionID();
|
||||
auto s = std::make_shared<ripple::Serializer>();
|
||||
tx.add(*s);
|
||||
env.app().getHashRouter().setFlags(txID, SF_PRIVATE2);
|
||||
view.rawTxInsert(txID, std::move(s), nullptr);
|
||||
return true;
|
||||
});
|
||||
|
||||
// close the ledger
|
||||
env.close();
|
||||
}
|
||||
|
||||
env(check::create("bob6", "bob7", XRP(100)));
|
||||
|
||||
// bob9 DepositPreauths bob4 and bob8.
|
||||
@@ -425,18 +500,26 @@ public:
|
||||
|
||||
{ // jvParams[jss::type] = "account";
|
||||
auto const jrr = makeRequest(jss::account);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 12));
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 13));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::AccountRoot);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "amendments";
|
||||
auto const jrr = makeRequest(jss::amendments);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 0));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::Amendments);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "unl_report";
|
||||
auto const jrr = makeRequest(jss::unl_report);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::UNLReport);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "check";
|
||||
auto const jrr = makeRequest(jss::check);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
@@ -465,6 +548,13 @@ public:
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::LedgerHashes);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "import_vlseq";
|
||||
auto const jrr = makeRequest(jss::import_vlseq);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::ImportVLSequence);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "offer";
|
||||
auto const jrr = makeRequest(jss::offer);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
@@ -521,6 +611,13 @@ public:
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::HookState);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "uri_token";
|
||||
auto const jrr = makeRequest(jss::uri_token);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
for (auto const& j : jrr[jss::state])
|
||||
BEAST_EXPECT(j["LedgerEntryType"] == jss::URIToken);
|
||||
}
|
||||
|
||||
{ // jvParams[jss::type] = "payment_channel";
|
||||
auto const jrr = makeRequest(jss::payment_channel);
|
||||
BEAST_EXPECT(checkArraySize(jrr[jss::state], 1));
|
||||
|
||||
@@ -1707,6 +1707,39 @@ public:
|
||||
BEAST_EXPECT(jrr[jss::node][sfURI.jsonName] == strHex(uri));
|
||||
BEAST_EXPECT(jrr[jss::node][sfFlags.jsonName] == lsfBurnable);
|
||||
}
|
||||
{
|
||||
// Request the uritoken using its account and uri.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::uri_token] = Json::objectValue;
|
||||
jvParams[jss::uri_token][jss::account] = alice.human();
|
||||
jvParams[jss::uri_token][jss::uri] = uri;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.human());
|
||||
BEAST_EXPECT(jrr[jss::node][sfURI.jsonName] == strHex(uri));
|
||||
BEAST_EXPECT(jrr[jss::node][sfFlags.jsonName] == lsfBurnable);
|
||||
}
|
||||
{
|
||||
// Malformed uritoken object. Missing account member.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::uri_token] = Json::objectValue;
|
||||
jvParams[jss::uri_token][jss::uri] = uri;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
{
|
||||
// Malformed uritoken object. Missing seq member.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::uri_token] = Json::objectValue;
|
||||
jvParams[jss::uri_token][jss::account] = env.master.human();
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
{
|
||||
// Request an index that is not a uritoken.
|
||||
Json::Value jvParams;
|
||||
@@ -1718,6 +1751,93 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testLedgerEntryImportVLSeq()
|
||||
{
|
||||
testcase("ledger_entry Request ImportVLSeq");
|
||||
using namespace test::jtx;
|
||||
|
||||
std::vector<std::string> const keys = {
|
||||
"ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC"
|
||||
"1"};
|
||||
Env env{*this, network::makeNetworkVLConfig(21337, keys)};
|
||||
|
||||
Account const alice{"alice"};
|
||||
env.fund(XRP(10000), alice);
|
||||
env.close();
|
||||
|
||||
auto const master = Account("masterpassphrase");
|
||||
env(noop(master), fee(10'000'000'000), ter(tesSUCCESS));
|
||||
env.close();
|
||||
env(import::import(
|
||||
alice, import::loadXpop(test::ImportTCAccountSet::w_seed)),
|
||||
fee(10 * 10),
|
||||
ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
std::string const ledgerHash{to_string(env.closed()->info().hash)};
|
||||
|
||||
auto const pk = PublicKey(makeSlice(*strUnHex(keys[0u])));
|
||||
uint256 const importvlIndex{keylet::import_vlseq(pk).key};
|
||||
{
|
||||
// Request the import vl using its index.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::import_vlseq] = to_string(importvlIndex);
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::node][sfPublicKey.jsonName] == keys[0u]);
|
||||
}
|
||||
{
|
||||
// Request the import vl using its public key.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::import_vlseq] = Json::objectValue;
|
||||
jvParams[jss::import_vlseq][jss::public_key] = keys[0u];
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::node][sfPublicKey.jsonName] == keys[0u]);
|
||||
}
|
||||
{
|
||||
// Malformed import vl object. Missing public key.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::import_vlseq] = Json::objectValue;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
{
|
||||
// Malformed import vl object. Bad public key.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::import_vlseq] = Json::objectValue;
|
||||
jvParams[jss::import_vlseq][jss::public_key] = 1;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
{
|
||||
// Malformed import vl object. Bad public key.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::import_vlseq] = Json::objectValue;
|
||||
jvParams[jss::import_vlseq][jss::public_key] = "DEADBEEF";
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
{
|
||||
// Request an index that is not a uritoken.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::import_vlseq] = ledgerHash;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testLedgerEntryUnknownOption()
|
||||
{
|
||||
@@ -2242,6 +2362,7 @@ public:
|
||||
testLedgerEntryRippleState();
|
||||
testLedgerEntryTicket();
|
||||
testLedgerEntryURIToken();
|
||||
testLedgerEntryImportVLSeq();
|
||||
testLedgerEntryUnknownOption();
|
||||
testLookupLedger();
|
||||
testNoQueue();
|
||||
|
||||
@@ -57,12 +57,16 @@ public:
|
||||
{
|
||||
Env env(*this);
|
||||
auto const result = env.rpc("server_definitions");
|
||||
std::cout << "RESULT: " << result << "\n";
|
||||
BEAST_EXPECT(!result[jss::result].isMember(jss::error));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
|
||||
BEAST_EXPECT(
|
||||
result[jss::result].isMember(jss::TRANSACTION_RESULTS));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_FLAGS));
|
||||
BEAST_EXPECT(
|
||||
result[jss::result].isMember(jss::TRANSACTION_FLAGS_INDICES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::hash));
|
||||
BEAST_EXPECT(result[jss::result][jss::status] == "success");
|
||||
@@ -70,7 +74,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
testDefitionsHash(FeatureBitset features)
|
||||
testDefinitionsHash(FeatureBitset features)
|
||||
{
|
||||
testcase("Definitions Hash");
|
||||
|
||||
@@ -92,6 +96,9 @@ public:
|
||||
BEAST_EXPECT(
|
||||
!result[jss::result].isMember(jss::TRANSACTION_RESULTS));
|
||||
BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_TYPES));
|
||||
BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_FLAGS));
|
||||
BEAST_EXPECT(
|
||||
!result[jss::result].isMember(jss::TRANSACTION_FLAGS_INDICES));
|
||||
BEAST_EXPECT(!result[jss::result].isMember(jss::TYPES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::hash));
|
||||
}
|
||||
@@ -113,6 +120,9 @@ public:
|
||||
BEAST_EXPECT(
|
||||
result[jss::result].isMember(jss::TRANSACTION_RESULTS));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_FLAGS));
|
||||
BEAST_EXPECT(
|
||||
result[jss::result].isMember(jss::TRANSACTION_FLAGS_INDICES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::hash));
|
||||
}
|
||||
@@ -330,7 +340,7 @@ public:
|
||||
testServerDefinitions(FeatureBitset features)
|
||||
{
|
||||
testDefinitions(features);
|
||||
testDefitionsHash(features);
|
||||
testDefinitionsHash(features);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user