Compare commits

..
Author SHA1 Message Date
Nik Bougalis c5aa162322 Make ApplyFlags a scoped enumeration
Convert ApplyFlags to a scoped enum, drop the now-redundant `Tap`
prefix from its enumerators and replace the hand-written bitwise
operators by opting in to enum_bitops.

No functional change.
2026-10-20 14:05:13 -07:00
Nik Bougalis 82421bc2a1 Make the path element type a scoped enumeration
STPathElement stored its type as an unsigned int, returned it as a
std::uint32_t, and defined the flags as an unscoped enum. The type
has always been serialized as a single byte.

Introduce STPathElementType, a scoped enum with std::uint8_t as its
fixed underlying type, opted into the bitwise operators from
enum_bitops.h:

- Store the type as STPathElementType, and use it for the
  constructor parameter and the return type of getNodeType().
- Rename call sites from STPathElement::TypeAccount and friends to
  STPathElementType::Account and friends.
- Replace raw mask tests in the serializer, JSON output, strand
  construction and pathfinder with the existing predicates.
- Validate the type byte once when deserializing, before any field
  is read, and restructure the loop around that.
- Remove the cached hashValue_ and getHash(). Their only consumer
  was a fast-reject prefilter in operator==, whose operands are
  equal in practice (hash-set lookups after a hash match, serdes
  self-checks), so the hash was computed on every construction and
  never rejected anything. operator== keeps the same semantics
  (TypeAccount bit plus the three fields) as a hidden friend.
- Give type_ and isOffer_ default member initializers, default the
  default constructor, and move isOffer_ next to type_ so the two
  one-byte members share a word.
- Mark the trivial accessors noexcept.

sizeof(STPathElement) drops from 88 to 72 bytes and its alignment
from 8 to 4. Every parsed path and every pathfinder candidate is a
vector of these.

No functional changes are intended. Observable differences are
confined to malformed input:

- The deserializer no longer logs rejected elements at error level
  through debugLog() before throwing. The exception carries the
  reason, and logging peer-supplied garbage at error level was a
  log-spam vector.
- The exception text changed: "empty path" is now "bad path element:
  empty path", and an element with undefined type bits reports the
  byte in hex.
- If the currency and MPT bits are both set and the input is
  truncated within the account field, the invalid bit combination
  is now detected before the short read; previously the short read
  was detected first. Such elements are rejected either way.
2026-10-20 14:05:08 -07:00
Nik Bougalis 969d9035aa Introduce opt-in bitwise operators for scoped enumerations
Scoped enumerations do not support bitwise operators, so using an
`enum class` as a set of flags requires extensive casting at call
sites or a hand-written set of operators for each type.

Add `enum_bitops.h`, which provides `&`, `|`, `^`, `~` along with
the compound assignment forms for any scoped enumeration that has
an unsigned underlying type and is opted in:

    enum class Flags : std::uint8_t { a = 1, b = 2 };

    // Opt into bitwise operations
    template <>
    struct enum_bitops::OptIn<Flags> : std::true_type {};

All synthesized operators are constexpr and noexcept, and preserve
the enumeration type.
2026-10-20 14:05:05 -07:00
139 changed files with 1645 additions and 2895 deletions

No files matched your search

@@ -31,12 +31,6 @@ on:
type: string
default: ""
unittest_args:
description: "Additional arguments to pass to rippled when running tests"
required: false
type: string
default: ""
cmake_target:
description: "The CMake target to build."
required: true
@@ -364,7 +358,6 @@ jobs:
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', env.BUILD_DIR, inputs.build_type) || env.BUILD_DIR }}
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
UNITTEST_ARGS: ${{ inputs.unittest_args }}
run: |
set -o pipefail
# Coverage builds are slower due to instrumentation; use fewer parallel jobs to avoid flakiness
@@ -45,7 +45,6 @@ jobs:
build_type: ${{ matrix.build_type }}
ccache_enabled: ${{ inputs.ccache_enabled }}
cmake_args: ${{ matrix.cmake_args }}
unittest_args: ${{ matrix.unittest_args }}
cmake_target: ${{ matrix.cmake_target }}
runs_on: ${{ toJSON(matrix.architecture.runner) }}
image: ${{ matrix.image || '' }}
+4
View File
@@ -275,6 +275,10 @@ if(xrpld)
patch_nix_binary(xrpld)
if(tests)
target_compile_definitions(xrpld PUBLIC ENABLE_TESTS)
target_compile_definitions(
xrpld
PRIVATE UNIT_TEST_REFERENCE_FEE=${UNIT_TEST_REFERENCE_FEE}
)
endif()
target_include_directories(
xrpld
+6
View File
@@ -23,6 +23,12 @@ option(assert "Enables asserts, even in release builds" OFF)
option(xrpld "Build xrpld" ON)
option(tests "Build tests" ON)
if(tests)
# This setting allows making a separate workflow to test fees other than default 10
if(NOT UNIT_TEST_REFERENCE_FEE)
set(UNIT_TEST_REFERENCE_FEE "10" CACHE STRING "")
endif()
endif()
option(benchmark "Build benchmarks" ON)
+200
View File
@@ -0,0 +1,200 @@
#pragma once
#include <concepts>
#include <type_traits>
#include <utility>
namespace xrpl {
/**
* Opt-in bitwise operators for scoped enumerations.
*
* Provides `&`, `|`, `^`, `~` and the corresponding compound assignment forms
* for any scoped enumeration with an unsigned underlying type that opts in by
* specializing @ref OptIn:
*
* @code
* namespace xrpl {
*
* enum class MyFlags : std::uint32_t { a = 1, b = 2, c = 4 };
*
* template <>
* struct enum_bitops::OptIn<MyFlags> : std::true_type {};
*
* } // namespace xrpl
* @endcode
*
* The operators are constexpr and noexcept, and return the enumeration type.
*
* @par Where the specialization may be declared
* In namespace xrpl, or at global scope with full qualification, and after
* the enumeration is defined but before the operators are first used. This
* cannot be done in a nested namespace or at class scope; for enumerations
* nested in a class this means after the class definition.
*
* @par Where the operators are found
* The operators are declared in namespace xrpl, so argument-dependent lookup
* will find them only for enumerations declared in xrpl or nested in a class
* declared directly in xrpl. Enumerations in a nested namespace will only be
* found from code inside xrpl, and only if no enclosing scope declares an
* operator of the same name; elsewhere they require using-declarations.
*/
namespace enum_bitops {
/**
* Types that may be opted in to the bitwise operators.
*
* Satisfied by a scoped enumeration whose underlying type is an unsigned
* integer type.
*
* @tparam T The type to test.
*/
template <typename T>
concept Eligible = std::is_scoped_enum_v<T> && std::unsigned_integral<std::underlying_type_t<T>>;
/**
* Opt-in switch for the bitwise operators.
*
* The primary template derives from std::false_type. Specialize it to derive
* from std::true_type to enable the operators for an @ref Eligible enumeration.
*
* @tparam T The scoped enumeration to opt in.
*/
template <Eligible T>
struct OptIn : std::false_type
{
};
/**
* Enumerations for which the bitwise operators are enabled.
*
* Satisfied when @p T satisfies @ref Eligible and @ref OptIn has been
* specialized for it to derive from std::true_type.
*
* @tparam T The type to test.
*/
template <typename T>
concept Candidate = Eligible<T> && OptIn<T>::value;
} // namespace enum_bitops
// These are declared in xrpl, not in enum_bitops, so that argument-dependent
// lookup finds them for enumerations whose associated namespace is xrpl.
/**
* @name Bitwise operators for opted-in scoped enumerations
*
* Each operator applies the corresponding built-in operator to the
* underlying values and converts the result back to the enumeration type.
* Both operands must have the same enumeration type; there is no implicit
* conversion to or from the underlying type.
*/
/** @{ */
/**
* Bitwise AND.
*
* @param lhs The left operand.
* @param rhs The right operand.
* @return The bits set in both @p lhs and @p rhs.
*/
template <enum_bitops::Candidate T>
constexpr T
operator&(T lhs, T rhs) noexcept
{
return static_cast<T>(std::to_underlying(lhs) & std::to_underlying(rhs));
}
/**
* Bitwise OR.
*
* @param lhs The left operand.
* @param rhs The right operand.
* @return The bits set in @p lhs, in @p rhs, or in both.
*/
template <enum_bitops::Candidate T>
constexpr T
operator|(T lhs, T rhs) noexcept
{
return static_cast<T>(std::to_underlying(lhs) | std::to_underlying(rhs));
}
/**
* Bitwise exclusive OR.
*
* @param lhs The left operand.
* @param rhs The right operand.
* @return The bits set in exactly one of @p lhs and @p rhs.
*/
template <enum_bitops::Candidate T>
constexpr T
operator^(T lhs, T rhs) noexcept
{
return static_cast<T>(std::to_underlying(lhs) ^ std::to_underlying(rhs));
}
/**
* Bitwise complement.
*
* The result has every bit of the underlying type that is clear in
* @p val, including bits that no enumerator names. It is intended for
* clearing flags, as in `flags & ~flag`.
*
* @param val The operand.
* @return The complement of @p val.
*/
template <enum_bitops::Candidate T>
constexpr T
operator~(T val) noexcept
{
return static_cast<T>(~std::to_underlying(val));
}
/**
* Bitwise AND assignment.
*
* @param lhs The value to modify.
* @param rhs The right operand.
* @return A reference to @p lhs.
*/
template <enum_bitops::Candidate T>
constexpr T&
operator&=(T& lhs, T rhs) noexcept
{
lhs = lhs & rhs;
return lhs;
}
/**
* Bitwise OR assignment.
*
* @param lhs The value to modify.
* @param rhs The right operand.
* @return A reference to @p lhs.
*/
template <enum_bitops::Candidate T>
constexpr T&
operator|=(T& lhs, T rhs) noexcept
{
lhs = lhs | rhs;
return lhs;
}
/**
* Bitwise exclusive OR assignment.
*
* @param lhs The value to modify.
* @param rhs The right operand.
* @return A reference to @p lhs.
*/
template <enum_bitops::Candidate T>
constexpr T&
operator^=(T& lhs, T rhs) noexcept
{
lhs = lhs ^ rhs;
return lhs;
}
/** @} */
} // namespace xrpl
-22
View File
@@ -9,7 +9,6 @@
#include <boost/assert.hpp>
#include <mutex>
#include <optional>
#include <string>
namespace beast::unit_test {
@@ -23,7 +22,6 @@ namespace beast::unit_test {
class Runner
{
std::string arg_;
std::optional<std::int64_t> referenceFee_;
bool default_ = false;
bool failed_ = false;
bool cond_ = false;
@@ -59,26 +57,6 @@ public:
return arg_;
}
/**
* Set the reference fee (in drops) for tests.
*
* If provided, this value is used in every suite that does not override it.
*/
void
referenceFee(std::int64_t fee)
{
referenceFee_ = fee;
}
/**
* Returns the reference fee, if any.
*/
[[nodiscard]] std::optional<std::int64_t> const&
referenceFee() const
{
return referenceFee_;
}
/**
* Run the specified suite.
* @return `true` if any conditions failed.
-12
View File
@@ -308,18 +308,6 @@ protected:
}
public:
/**
* Return the reference fee associated with the runner.
*/
std::optional<std::int64_t>
referenceFee() const
{
assert(runner_);
if (runner_ == nullptr)
return {};
return runner_->referenceFee();
}
/**
* DEPRECATED
* @return `true` if the test condition indicates success(a false value)
+12 -53
View File
@@ -1,7 +1,7 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/basics/enum_bitops.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/OwnerCounts.h>
#include <xrpl/ledger/ReadView.h>
@@ -22,80 +22,39 @@
namespace xrpl {
// Bitwise flag enum with existing operator overloads
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum ApplyFlags : std::uint32_t {
TapNone = 0x00,
enum class ApplyFlags : std::uint32_t {
None = 0x00,
// This is a local transaction with the
// fail_hard flag set.
TapFailHard = 0x10,
FailHard = 0x10,
// This is not the transaction's last pass
// Transaction can be retried, soft failures allowed
TapRetry = 0x20,
Retry = 0x20,
// Transaction came from a privileged source
TapUnlimited = 0x400,
Unlimited = 0x400,
// Transaction is executing as part of a batch
TapBatch = 0x800,
Batch = 0x800,
// Transaction shouldn't be applied
// Signatures shouldn't be checked
TapDryRun = 0x1000,
DryRun = 0x1000,
// Transaction is being preflighted as the payload of a
// TransactionProposalCreate. Its signatures are collected on-ledger
// afterward, so signature-presence checks (e.g. Batch signer matching)
// are skipped at proposal-creation time (On-Chain Cosigner spec
// §5.3.1.2).
TapProposal = 0x2000,
Proposal = 0x2000,
};
constexpr ApplyFlags
operator|(ApplyFlags const& lhs, ApplyFlags const& rhs)
template <>
struct enum_bitops::OptIn<ApplyFlags> : std::true_type
{
return safeCast<ApplyFlags>(
safeCast<std::underlying_type_t<ApplyFlags>>(lhs) |
safeCast<std::underlying_type_t<ApplyFlags>>(rhs));
}
static_assert((TapFailHard | TapRetry) == safeCast<ApplyFlags>(0x30u), "ApplyFlags operator |");
static_assert((TapRetry | TapFailHard) == safeCast<ApplyFlags>(0x30u), "ApplyFlags operator |");
constexpr ApplyFlags
operator&(ApplyFlags const& lhs, ApplyFlags const& rhs)
{
return safeCast<ApplyFlags>(
safeCast<std::underlying_type_t<ApplyFlags>>(lhs) &
safeCast<std::underlying_type_t<ApplyFlags>>(rhs));
}
static_assert((TapFailHard & TapRetry) == TapNone, "ApplyFlags operator &");
static_assert((TapRetry & TapFailHard) == TapNone, "ApplyFlags operator &");
constexpr ApplyFlags
operator~(ApplyFlags const& flags)
{
return safeCast<ApplyFlags>(~safeCast<std::underlying_type_t<ApplyFlags>>(flags));
}
static_assert(~TapRetry == safeCast<ApplyFlags>(0xFFFFFFDFu), "ApplyFlags operator ~");
inline ApplyFlags
operator|=(ApplyFlags& lhs, ApplyFlags const& rhs)
{
lhs = lhs | rhs;
return lhs;
}
inline ApplyFlags
operator&=(ApplyFlags& lhs, ApplyFlags const& rhs)
{
lhs = lhs & rhs;
return lhs;
}
};
//------------------------------------------------------------------------------
+80 -107
View File
@@ -2,6 +2,8 @@
#include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/basics/enum_bitops.h>
#include <xrpl/beast/hash/hash_append.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
@@ -15,37 +17,43 @@
#include <cstdint>
#include <memory>
#include <optional>
#include <type_traits>
#include <utility>
#include <vector>
namespace xrpl {
enum class STPathElementType : std::uint8_t {
// clang-format off
None = 0x00, ///< No element; also terminates the serialized path set.
Account = 0x01, ///< Rippling through an account (vs taking an offer).
Currency = 0x10, ///< Currency follows.
Issuer = 0x20, ///< Issuer follows.
Mpt = 0x40, ///< MPT follows.
Boundary = 0xFF, ///< Boundary between alternate paths.
Asset = Currency | Mpt, ///< Either asset kind.
All = Account | Currency | Issuer | Mpt, ///< Every value-carrying bit.
// clang-format on
};
template <>
struct enum_bitops::OptIn<STPathElementType> : std::true_type
{
};
class STPathElement final : public CountedObject<STPathElement>
{
unsigned int type_;
STPathElementType type_ = STPathElementType::None;
bool isOffer_ = true;
AccountID accountID_;
PathAsset assetID_;
AccountID issuerID_;
bool isOffer_;
std::size_t hashValue_;
public:
// Bitwise values (typeCurrency | typeMPT)
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum Type {
TypeNone = 0x00,
TypeAccount = 0x01, // Rippling through an account (vs taking an offer).
TypeCurrency = 0x10, // Currency follows.
TypeIssuer = 0x20, // Issuer follows.
TypeMpt = 0x40, // MPT follows.
TypeBoundary = 0xFF, // Boundary between alternate paths.
TypeAsset = TypeCurrency | TypeMpt,
TypeAll = TypeAccount | TypeCurrency | TypeIssuer | TypeMpt,
// Combination of all types.
};
STPathElement();
STPathElement() = default;
STPathElement(STPathElement const&) = default;
STPathElement&
operator=(STPathElement const&) = default;
@@ -62,42 +70,42 @@ public:
bool forceAsset = false);
STPathElement(
unsigned int uType,
STPathElementType type,
AccountID const& account,
PathAsset const& asset,
AccountID const& issuer);
[[nodiscard]] std::uint32_t
getNodeType() const;
[[nodiscard]] STPathElementType
getNodeType() const noexcept;
[[nodiscard]] bool
isOffer() const;
isOffer() const noexcept;
[[nodiscard]] bool
isAccount() const;
isAccount() const noexcept;
[[nodiscard]] bool
hasIssuer() const;
hasIssuer() const noexcept;
[[nodiscard]] bool
hasCurrency() const;
hasCurrency() const noexcept;
[[nodiscard]] bool
hasMPT() const;
hasMPT() const noexcept;
[[nodiscard]] bool
hasAsset() const;
hasAsset() const noexcept;
[[nodiscard]] bool
isNone() const;
isNone() const noexcept;
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
// class of offers.
[[nodiscard]] AccountID const&
getAccountID() const;
getAccountID() const noexcept;
[[nodiscard]] PathAsset const&
getPathAsset() const;
getPathAsset() const noexcept;
[[nodiscard]] Currency const&
getCurrency() const;
@@ -106,17 +114,18 @@ public:
getMPTID() const;
[[nodiscard]] AccountID const&
getIssuerID() const;
getIssuerID() const noexcept;
[[nodiscard]] bool
isType(Type const& pe) const;
isType(STPathElementType pe) const noexcept;
bool
operator==(STPathElement const& t) const;
private:
static std::size_t
getHash(STPathElement const& element);
friend bool
operator==(STPathElement const& lhs, STPathElement const& rhs) noexcept
{
return lhs.isType(STPathElementType::Account) == rhs.isType(STPathElementType::Account) &&
lhs.accountID_ == rhs.accountID_ && lhs.assetID_ == rhs.assetID_ &&
lhs.issuerID_ == rhs.issuerID_;
}
};
template <class Hasher>
@@ -124,7 +133,7 @@ void
hash_append(Hasher& h, STPathElement const& e) noexcept
{
using beast::hash_append;
hash_append(h, (e.getNodeType() & STPathElement::TypeAccount) != 0u);
hash_append(h, e.isType(STPathElementType::Account));
hash_append(h, e.getAccountID());
hash_append(h, e.getPathAsset());
hash_append(h, e.getIssuerID());
@@ -337,29 +346,16 @@ private:
// ------------ STPathElement ------------
inline STPathElement::STPathElement() : type_(TypeNone), isOffer_(true)
{
// hashValue_ is derived from the whole object, so it is computed in the body
// once every other member is initialized (as in the other constructors).
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
hashValue_ = getHash(*this);
}
inline STPathElement::STPathElement(
std::optional<AccountID> const& account,
std::optional<PathAsset> const& asset,
std::optional<AccountID> const& issuer)
: type_(TypeNone)
{
if (!account)
{
isOffer_ = true;
}
else
if (account)
{
isOffer_ = false;
accountID_ = *account;
type_ |= TypeAccount;
type_ |= STPathElementType::Account;
XRPL_ASSERT(
accountID_ != noAccount(), "xrpl::STPathElement::STPathElement : account is set");
}
@@ -367,17 +363,15 @@ inline STPathElement::STPathElement(
if (asset)
{
assetID_ = *asset;
type_ |= assetID_.holds<Currency>() ? TypeCurrency : TypeMpt;
type_ |= assetID_.holds<Currency>() ? STPathElementType::Currency : STPathElementType::Mpt;
}
if (issuer)
{
issuerID_ = *issuer;
type_ |= TypeIssuer;
type_ |= STPathElementType::Issuer;
XRPL_ASSERT(issuerID_ != noAccount(), "xrpl::STPathElement::STPathElement : issuer is set");
}
hashValue_ = getHash(*this);
}
inline STPathElement::STPathElement(
@@ -385,108 +379,94 @@ inline STPathElement::STPathElement(
PathAsset const& asset,
AccountID const& issuer,
bool forceAsset)
: type_(TypeNone)
, accountID_(account)
, assetID_(asset)
, issuerID_(issuer)
, isOffer_(isXRP(accountID_))
: isOffer_(isXRP(account)), accountID_(account), assetID_(asset), issuerID_(issuer)
{
if (!isOffer_)
type_ |= TypeAccount;
type_ |= STPathElementType::Account;
if (forceAsset || !isXRP(assetID_))
type_ |= asset.holds<Currency>() ? TypeCurrency : TypeMpt;
type_ |= asset.holds<Currency>() ? STPathElementType::Currency : STPathElementType::Mpt;
if (!isXRP(issuer))
type_ |= TypeIssuer;
hashValue_ = getHash(*this);
type_ |= STPathElementType::Issuer;
}
inline STPathElement::STPathElement(
unsigned int uType,
STPathElementType type,
AccountID const& account,
PathAsset const& asset,
AccountID const& issuer)
: type_(uType)
, accountID_(account)
, assetID_(asset)
, issuerID_(issuer)
, isOffer_(isXRP(accountID_))
: type_(type), isOffer_(isXRP(account)), accountID_(account), assetID_(asset), issuerID_(issuer)
{
assetID_.visit(
[&](Currency const&) { type_ = type_ & (~Type::TypeMpt); },
[&](MPTID const&) { type_ = type_ & (~Type::TypeCurrency); });
// hashValue_ must be computed after type_ is adjusted above, so this cannot
// be a member initializer.
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
hashValue_ = getHash(*this);
[&](Currency const&) { type_ &= ~STPathElementType::Mpt; },
[&](MPTID const&) { type_ &= ~STPathElementType::Currency; });
}
inline std::uint32_t
STPathElement::getNodeType() const
inline STPathElementType
STPathElement::getNodeType() const noexcept
{
return type_;
}
inline bool
STPathElement::isOffer() const
STPathElement::isOffer() const noexcept
{
return isOffer_;
}
inline bool
STPathElement::isAccount() const
STPathElement::isAccount() const noexcept
{
return !isOffer();
}
inline bool
STPathElement::isType(Type const& pe) const
STPathElement::isType(STPathElementType pe) const noexcept
{
return (type_ & pe) != 0u;
return (type_ & pe) != STPathElementType::None;
}
inline bool
STPathElement::hasIssuer() const
STPathElement::hasIssuer() const noexcept
{
return isType(STPathElement::TypeIssuer);
return isType(STPathElementType::Issuer);
}
inline bool
STPathElement::hasCurrency() const
STPathElement::hasCurrency() const noexcept
{
return isType(STPathElement::TypeCurrency);
return isType(STPathElementType::Currency);
}
inline bool
STPathElement::hasMPT() const
STPathElement::hasMPT() const noexcept
{
return isType(STPathElement::TypeMpt);
return isType(STPathElementType::Mpt);
}
inline bool
STPathElement::hasAsset() const
STPathElement::hasAsset() const noexcept
{
return isType(STPathElement::TypeAsset);
return isType(STPathElementType::Asset);
}
inline bool
STPathElement::isNone() const
STPathElement::isNone() const noexcept
{
return getNodeType() == STPathElement::TypeNone;
return getNodeType() == STPathElementType::None;
}
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
// class of offers.
inline AccountID const&
STPathElement::getAccountID() const
STPathElement::getAccountID() const noexcept
{
return accountID_;
}
inline PathAsset const&
STPathElement::getPathAsset() const
STPathElement::getPathAsset() const noexcept
{
return assetID_;
}
@@ -504,18 +484,11 @@ STPathElement::getMPTID() const
}
inline AccountID const&
STPathElement::getIssuerID() const
STPathElement::getIssuerID() const noexcept
{
return issuerID_;
}
inline bool
STPathElement::operator==(STPathElement const& t) const
{
return (type_ & TypeAccount) == (t.type_ & TypeAccount) && hashValue_ == t.hashValue_ &&
accountID_ == t.accountID_ && assetID_ == t.assetID_ && issuerID_ == t.issuerID_;
}
// ------------ STPath ------------
inline STPath::STPath(std::vector<STPathElement> p) : path_(std::move(p))
+2 -1
View File
@@ -51,7 +51,8 @@ public:
beast::Journal journal = beast::Journal{beast::Journal::getNullSink()})
: ApplyContext(registry, base, std::nullopt, tx, preclaimResult, baseFee, flags, journal)
{
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
XRPL_ASSERT(
(flags & ApplyFlags::Batch) == ApplyFlags::None, "Batch apply flag should not be set");
}
std::reference_wrapper<ServiceRegistry> registry;
+11 -8
View File
@@ -59,10 +59,11 @@ public:
, parentBatchId(parentBatchId)
, j(j)
{
XRPL_ASSERT((flags & TapBatch) == TapBatch, "Batch apply flag should be set");
XRPL_ASSERT(
(flags & ApplyFlags::Batch) == ApplyFlags::Batch, "Batch apply flag should be set");
XRPL_ASSERT_IF(
(flags & TapProposal) != TapNone,
(flags & TapDryRun) != TapNone,
(flags & ApplyFlags::Proposal) != ApplyFlags::None,
(flags & ApplyFlags::DryRun) != ApplyFlags::None,
"xrpl::PreflightContext : proposal preflight implies dry run");
}
@@ -74,10 +75,11 @@ public:
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
: registry(registry), tx(tx), rules(std::move(rules)), flags(flags), j(j)
{
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
XRPL_ASSERT(
(flags & ApplyFlags::Batch) == ApplyFlags::None, "Batch apply flag should not be set");
XRPL_ASSERT_IF(
(flags & TapProposal) != TapNone,
(flags & TapDryRun) != TapNone,
(flags & ApplyFlags::Proposal) != ApplyFlags::None,
(flags & ApplyFlags::DryRun) != ApplyFlags::None,
"xrpl::PreflightContext : proposal preflight implies dry run");
}
@@ -116,7 +118,7 @@ public:
, j(j)
{
XRPL_ASSERT(
parentBatchId.has_value() == ((flags & TapBatch) == TapBatch),
parentBatchId.has_value() == ((flags & ApplyFlags::Batch) == ApplyFlags::Batch),
"Parent Batch ID should be set if batch apply flag is set");
}
@@ -129,7 +131,8 @@ public:
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
: PreclaimContext(registry, view, preflightResult, tx, flags, std::nullopt, j)
{
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
XRPL_ASSERT(
(flags & ApplyFlags::Batch) == ApplyFlags::None, "Batch apply flag should not be set");
}
PreclaimContext&
+1 -1
View File
@@ -41,7 +41,7 @@ struct ApplyResult
inline bool
isTecClaimHardFail(TER ter, ApplyFlags flags)
{
return isTecClaim(ter) && ((flags & TapRetry) == 0u);
return isTecClaim(ter) && ((flags & ApplyFlags::Retry) == ApplyFlags::None);
}
/**
+62 -95
View File
@@ -1,11 +1,10 @@
#include <xrpl/protocol/STPathSet.h>
#include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/hash/uhash.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
@@ -17,7 +16,9 @@
#include <xrpl/protocol/jss.h>
#include <algorithm>
#include <cstddef>
#include <concepts>
#include <cstdint>
#include <format>
#include <memory>
#include <stdexcept>
#include <utility>
@@ -25,41 +26,6 @@
namespace xrpl {
std::size_t
STPathElement::getHash(STPathElement const& element)
{
std::size_t hashAccount = 2654435761;
std::size_t hashCurrency = 2654435761;
std::size_t hashIssuer = 2654435761;
// NIKB NOTE: This doesn't have to be a secure hash as speed is more
// important. We don't even really need to fully hash the whole
// base_uint here, as a few bytes would do for our use.
//
// The note above is only true because the result of this function reaches
// nothing but STPathElement::operator==, where it is a fast-reject
// prefilter ahead of the field comparisons that decide the answer. Do not
// use it to key a container.
for (auto const x : element.getAccountID())
hashAccount += (hashAccount * 257) ^ x;
// Check pathAsset type instead of element's type_
// In some cases type_ might be account but the asset
// is still set to either MPT or currency (see Pathfinder::addLink())
element.getPathAsset().visit(
[&](MPTID const& mpt) { hashCurrency += beast::Uhash<>{}(mpt); },
[&](Currency const& currency) {
for (auto const x : currency)
hashCurrency += (hashCurrency * 509) ^ x;
});
for (auto const x : element.getIssuerID())
hashIssuer += (hashIssuer * 911) ^ x;
return (hashAccount ^ hashCurrency ^ hashIssuer);
}
// For guidance on deciding which option to pursue:
// 1. Try to decrease the size of the STPathSet first. For instance, if a std::optional was
// injected into the type, could you get the same functionality using a std::unique_ptr instead?
@@ -108,62 +74,57 @@ STPathSet::operator=(STPathSet const& other)
STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name)
{
std::vector<STPathElement> path;
for (;;)
{
int const iType = sit.get8();
if (iType == STPathElement::TypeNone || iType == STPathElement::TypeBoundary)
STPathElementType type = STPathElementType::None;
do
{
type = safeCast<STPathElementType>(sit.get8());
if (type == STPathElementType::None || type == STPathElementType::Boundary)
{
if (path.empty())
{
JLOG(debugLog().error()) << "Empty path in pathset";
Throw<std::runtime_error>("empty path");
}
Throw<std::runtime_error>("bad path element: empty path");
// Move rather than converting the vector to an STPath by copy.
value_.emplace_back(std::move(path));
path.clear();
if (iType == STPathElement::TypeNone)
return;
continue;
}
else if ((iType & ~STPathElement::TypeAll) != 0)
{
JLOG(debugLog().error()) << "Bad path element " << iType << " in pathset";
Throw<std::runtime_error>("bad path element");
}
else
{
auto const hasAccount = (iType & STPathElement::TypeAccount) != 0u;
auto const hasCurrency = (iType & STPathElement::TypeCurrency) != 0u;
auto const hasIssuer = (iType & STPathElement::TypeIssuer) != 0u;
auto const hasMPT = (iType & STPathElement::TypeMpt) != 0u;
AccountID account;
PathAsset asset;
AccountID issuer;
if ((type & ~STPathElementType::All) != STPathElementType::None)
Throw<std::runtime_error>(
std::format("bad path element: <{:#04x}>", std::to_underlying(type)));
if (hasAccount)
account = sit.get160();
bool const hasAccount = (type & STPathElementType::Account) == STPathElementType::Account;
bool const hasCurrency =
(type & STPathElementType::Currency) == STPathElementType::Currency;
bool const hasMPT = (type & STPathElementType::Mpt) == STPathElementType::Mpt;
bool const hasIssuer = (type & STPathElementType::Issuer) == STPathElementType::Issuer;
if (hasCurrency && hasMPT)
{
JLOG(debugLog().error()) << "Bad path element MPT and Currency in pathset";
Throw<std::runtime_error>("bad path element: MPT and Currency");
}
if (hasCurrency && hasMPT)
Throw<std::runtime_error>("bad path element: MPT and Currency");
if (hasCurrency)
asset = Currency::fromRaw(sit.get160());
AccountID account;
PathAsset asset;
AccountID issuer;
if (hasMPT)
asset = sit.get192();
if (hasAccount)
account = sit.get160();
if (hasIssuer)
issuer = sit.get160();
if (hasCurrency)
asset = Currency::fromRaw(sit.get160());
path.emplace_back(account, asset, issuer, hasCurrency || hasMPT);
}
}
if (hasMPT)
asset = sit.get192();
if (hasIssuer)
issuer = sit.get160();
path.emplace_back(account, asset, issuer, hasCurrency || hasMPT);
} while (type != STPathElementType::None);
}
STBase*
@@ -217,24 +178,22 @@ STPath::getJson(JsonOptions) const
for (auto const& it : path_)
{
json::Value elem(json::ValueType::Object);
auto const iType = it.getNodeType();
elem[jss::type] = iType;
elem[jss::type] = safeCast<std::uint32_t>(it.getNodeType());
if ((iType & STPathElement::TypeAccount) != 0u)
if (it.isType(STPathElementType::Account))
elem[jss::account] = to_string(it.getAccountID());
XRPL_ASSERT(
((iType & STPathElement::TypeCurrency) == 0u) ||
((iType & STPathElement::TypeMpt) == 0u),
!(it.hasCurrency() && it.hasMPT()),
"xrpl::STPath::getJson : not type Currency and MPT");
if ((iType & STPathElement::TypeCurrency) != 0u)
if (it.hasCurrency())
elem[jss::currency] = to_string(it.getCurrency());
if ((iType & STPathElement::TypeMpt) != 0u)
if (it.hasMPT())
elem[jss::mpt_issuance_id] = to_string(it.getMPTID());
if ((iType & STPathElement::TypeIssuer) != 0u)
if (it.hasIssuer())
elem[jss::issuer] = to_string(it.getIssuerID());
ret.append(elem);
@@ -266,34 +225,42 @@ STPathSet::add(Serializer& s) const
XRPL_ASSERT(getFName().fieldType == STI_PATHSET, "xrpl::STPathSet::add : valid field type");
bool first = true;
// Workaround, since `Serializer` does not accept strongly-typed enums
// yet. When support is added, the static_assert will trigger, and the
// lambda can be removed entirely.
auto const toByte = [](std::same_as<STPathElementType> auto t) noexcept {
static_assert(
!requires(Serializer& ser) { ser.add8(t); },
"Serializer::add8 now accepts STPathElementType directly; remove toByte.");
return std::to_underlying(t);
};
for (auto const& spPath : value_)
{
if (!first)
s.add8(STPathElement::TypeBoundary);
s.add8(toByte(STPathElementType::Boundary));
for (auto const& speElement : spPath)
{
int const iType = speElement.getNodeType();
s.add8(toByte(speElement.getNodeType()));
s.add8(iType);
if ((iType & STPathElement::TypeAccount) != 0u)
if (speElement.isType(STPathElementType::Account))
s.addBitString(speElement.getAccountID());
if ((iType & STPathElement::TypeMpt) != 0u)
if (speElement.hasMPT())
s.addBitString(speElement.getMPTID());
if ((iType & STPathElement::TypeCurrency) != 0u)
if (speElement.hasCurrency())
s.addBitString(speElement.getCurrency());
if ((iType & STPathElement::TypeIssuer) != 0u)
if (speElement.hasIssuer())
s.addBitString(speElement.getIssuerID());
}
first = false;
}
s.add8(STPathElement::TypeNone);
s.add8(toByte(STPathElementType::None));
}
} // namespace xrpl
+4 -3
View File
@@ -38,7 +38,7 @@ ApplyContext::ApplyContext(
, parentBatchId_(parentBatchId)
{
XRPL_ASSERT(
parentBatchId.has_value() == ((flags_ & TapBatch) == TapBatch),
parentBatchId.has_value() == ((flags_ & ApplyFlags::Batch) == ApplyFlags::Batch),
"Parent Batch ID should be set if batch apply flag is set");
view_.emplace(&base_, flags_);
}
@@ -53,13 +53,14 @@ std::optional<TxMeta>
ApplyContext::apply(TER ter)
{
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) view_ emplaced in constructor
return view_->apply(base_, tx, ter, parentBatchId_, (flags_ & TapDryRun) != 0u, journal);
return view_->apply(
base_, tx, ter, parentBatchId_, (flags_ & ApplyFlags::DryRun) != ApplyFlags::None, journal);
}
void
ApplyContext::addOrderBook(Book const& book)
{
if ((flags_ & TapDryRun) == TapNone)
if ((flags_ & ApplyFlags::DryRun) == ApplyFlags::None)
registry.get().getOrderBookDB().addOrderBook(book);
}
+9 -7
View File
@@ -135,7 +135,7 @@ preflightCheckSigningKey(STObject const& sigObject, beast::Journal j)
std::optional<NotTEC>
preflightCheckSimulateKeys(ApplyFlags flags, STObject const& sigObject, beast::Journal j)
{
if ((flags & TapDryRun) != 0u) // simulation
if ((flags & ApplyFlags::DryRun) != ApplyFlags::None) // simulation
{
std::optional<Slice> const signature = sigObject[~sfTxnSignature];
if (signature && !signature->empty())
@@ -510,7 +510,8 @@ Transactor::minimumFee(
Fees const& fees,
ApplyFlags flags)
{
return scaleFeeLoad(baseFee, registry.getFeeTrack(), fees, (flags & TapUnlimited) != 0u);
return scaleFeeLoad(
baseFee, registry.getFeeTrack(), fees, (flags & ApplyFlags::Unlimited) != ApplyFlags::None);
}
TER
@@ -521,7 +522,7 @@ Transactor::checkFee(PreclaimContext const& ctx, XRPAmount baseFee)
auto const feePaid = ctx.tx[sfFee].xrp();
if ((ctx.flags & TapBatch) != 0u)
if ((ctx.flags & ApplyFlags::Batch) != ApplyFlags::None)
{
if (feePaid == beast::kZero)
return tesSUCCESS;
@@ -984,7 +985,8 @@ Transactor::checkSign(
return tesSUCCESS;
}
if (((flags & TapDryRun) != 0u) && pkSigner.empty() && !sigObject.isFieldPresent(sfSigners))
if (((flags & ApplyFlags::DryRun) != ApplyFlags::None) && pkSigner.empty() &&
!sigObject.isFieldPresent(sfSigners))
{
// simulate: skip signature validation when neither SigningPubKey nor
// Signers are provided
@@ -1155,7 +1157,7 @@ Transactor::checkMultiSign(
}
XRPL_ASSERT(
(flags & TapDryRun) || !spk.empty(),
(flags & ApplyFlags::DryRun) != ApplyFlags::None || !spk.empty(),
"xrpl::Transactor::checkMultiSign : non-empty signer or "
"simulation");
AccountID const signingAcctIDFromPubKey =
@@ -1643,7 +1645,7 @@ Transactor::operator()()
if (ctx_.size() > kOversizeMetaDataCap)
result = tecOVERSIZE;
if (isTecClaim(result) && ((view().flags() & TapFailHard) != 0u))
if (isTecClaim(result) && ((view().flags() & ApplyFlags::FailHard) != ApplyFlags::None))
{
// If the TapFailHard flag is set, a tec result
// must not do anything
@@ -1723,7 +1725,7 @@ Transactor::operator()()
// Once we call apply, we will no longer be able to look at view()
metadata = ctx_.apply(result);
if ((ctx_.flags() & TapDryRun) != 0u)
if ((ctx_.flags() & ApplyFlags::DryRun) != ApplyFlags::None)
return logger(result, false, std::move(metadata));
return logger(result, canApply, std::move(metadata));
+2 -2
View File
@@ -215,7 +215,7 @@ applyBatchTransactions(
auto const applyOneTransaction = [&registry, &j, &parentBatchId, &batchView](STTx const& tx) {
OpenView perTxBatchView(kBatchView, batchView);
auto const ret = apply(registry, perTxBatchView, parentBatchId, tx, TapBatch, j);
auto const ret = apply(registry, perTxBatchView, parentBatchId, tx, ApplyFlags::Batch, j);
XRPL_ASSERT(
ret.applied == (isTesSuccess(ret.ter) || isTecClaim(ret.ter)),
"Inner transaction should not be applied");
@@ -274,7 +274,7 @@ applyTransaction(
{
// Returns false if the transaction has need not be retried.
if (retryAssured)
flags = flags | TapRetry;
flags = flags | ApplyFlags::Retry;
JLOG(j.debug()) << "TXN " << txn.getTransactionID() << (retryAssured ? "/retry" : "/final");
+4 -2
View File
@@ -348,7 +348,8 @@ preflight(
// builds; re-check the same invariant here so a release build can't
// silently skip a proposed transaction's signature-presence checks
// outside of a dry run.
if ((flags & TapProposal) != TapNone && (flags & TapDryRun) == TapNone)
if ((flags & ApplyFlags::Proposal) != ApplyFlags::None &&
(flags & ApplyFlags::DryRun) == ApplyFlags::None)
{
// LCOV_EXCL_START
JLOG(j.fatal()) << "apply (preflight): TapProposal set without TapDryRun.";
@@ -379,7 +380,8 @@ preflight(
PreflightContext const pfCtx(registry, tx, parentBatchId, rules, flags, j);
// See the comment in the other preflight() overload above.
if ((flags & TapProposal) != TapNone && (flags & TapDryRun) == TapNone)
if ((flags & ApplyFlags::Proposal) != ApplyFlags::None &&
(flags & ApplyFlags::DryRun) == ApplyFlags::None)
{
// LCOV_EXCL_START
JLOG(j.fatal()) << "apply (preflight): TapProposal set without TapDryRun.";
+1 -1
View File
@@ -1101,7 +1101,7 @@ std::optional<std::variant<Quality, AMMOffer<TIn, TOut>>>
BookStep<TIn, TOut, TDerived>::tip(ReadView const& view) const
{
// This can be simplified (and sped up) if directories are never empty.
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
BookTip bt(sb, book_);
auto const lobQuality = bt.step(j_) ? std::optional<Quality>(bt.quality()) : std::nullopt;
// Multi-path offer generates an offer with the quality
+18 -32
View File
@@ -57,10 +57,8 @@ checkNear(IOUAmount const& expected, IOUAmount const& actual)
static bool
isXRPAccount(STPathElement const& pe)
{
if (pe.getNodeType() != STPathElement::TypeAccount)
return false;
return isXRP(pe.getAccountID());
};
return pe.getNodeType() == STPathElementType::Account && isXRP(pe.getAccountID());
}
static std::pair<TER, std::unique_ptr<Step>>
toStep(
@@ -71,11 +69,8 @@ toStep(
{
auto& j = ctx.j;
if (ctx.isFirst && e1->isAccount() &&
((e1->getNodeType() & STPathElement::TypeCurrency) != 0u) && e1->getPathAsset().isXRP())
{
if (ctx.isFirst && e1->isAccount() && e1->hasCurrency() && e1->getPathAsset().isXRP())
return makeXrpEndpointStep(ctx, e1->getAccountID());
}
if (ctx.isLast && isXRPAccount(*e1) && e2->isAccount())
return makeXrpEndpointStep(ctx, e2->getAccountID());
@@ -117,15 +112,9 @@ toStep(
// LCOV_EXCL_STOP
}
XRPL_ASSERT(
(e2->getNodeType() & STPathElement::TypeAsset) ||
(e2->getNodeType() & STPathElement::TypeIssuer),
"xrpl::toStep : currency or issuer");
PathAsset const outAsset =
((e2->getNodeType() & STPathElement::TypeAsset) != 0u) ? e2->getPathAsset() : curAsset;
auto const outIssuer = ((e2->getNodeType() & STPathElement::TypeIssuer) != 0u)
? e2->getIssuerID()
: curAsset.getIssuer();
XRPL_ASSERT(e2->hasAsset() || e2->hasIssuer(), "xrpl::toStep : currency or issuer");
PathAsset const outAsset = e2->hasAsset() ? e2->getPathAsset() : curAsset;
auto const outIssuer = e2->hasIssuer() ? e2->getIssuerID() : curAsset.getIssuer();
if (isXRP(curAsset) && outAsset.isXRP())
{
@@ -197,16 +186,15 @@ toStrand(
for (std::size_t i = 0; i < path.size(); ++i)
{
auto const& pe = path[i];
auto const t = pe.getNodeType();
if (((t & ~STPathElement::TypeAll) != 0u) || (t == 0u))
if ((pe.getNodeType() & ~STPathElementType::All) != STPathElementType::None || pe.isNone())
return {temBAD_PATH, Strand{}};
bool const hasAccount = (t & STPathElement::TypeAccount) != 0u;
bool const hasIssuer = (t & STPathElement::TypeIssuer) != 0u;
bool const hasCurrency = (t & STPathElement::TypeCurrency) != 0u;
bool const hasMPT = (t & STPathElement::TypeMpt) != 0u;
bool const hasAsset = (t & STPathElement::TypeAsset) != 0u;
bool const hasAccount = pe.isType(STPathElementType::Account);
bool const hasIssuer = pe.hasIssuer();
bool const hasCurrency = pe.hasCurrency();
bool const hasMPT = pe.hasMPT();
bool const hasAsset = pe.hasAsset();
if (hasAccount && (hasIssuer || hasCurrency))
return {temBAD_PATH, Strand{}};
@@ -250,9 +238,7 @@ toStrand(
}();
// Currency or MPT
auto const hasAsset = [](STPathElement const pe) {
return pe.getNodeType() & STPathElement::TypeAsset;
};
auto const hasAsset = [](STPathElement const& pe) { return pe.hasAsset(); };
std::vector<STPathElement> normPath;
// reserve enough for the path, the implied source, destination,
@@ -263,10 +249,10 @@ toStrand(
// transaction, as defined by the transaction's Account field. The Asset
// is either SendMax or Deliver.
auto const t = [&] {
auto const t = STPathElement::TypeAccount | STPathElement::TypeIssuer;
auto const t = STPathElementType::Account | STPathElementType::Issuer;
return curAsset.visit(
[&](MPTIssue const&) { return t | STPathElement::TypeMpt; },
[&](Issue const&) { return t | STPathElement::TypeCurrency; });
[&](MPTIssue const&) { return t | STPathElementType::Mpt; },
[&](Issue const&) { return t | STPathElementType::Currency; });
}();
// If MPT then the issuer is the actual issuer, it is never the source
// account.
@@ -435,7 +421,7 @@ toStrand(
return {msr.first, Strand{}};
result.push_back(std::move(msr.second));
impliedPE.emplace(
STPathElement::TypeAccount, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
STPathElementType::Account, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
cur = &*impliedPE;
}
}
@@ -450,7 +436,7 @@ toStrand(
return {msr.first, Strand{}};
result.push_back(std::move(msr.second));
impliedPE.emplace(
STPathElement::TypeAccount, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
STPathElementType::Account, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
cur = &*impliedPE;
}
}
@@ -187,7 +187,8 @@ AccountSet::preclaim(PreclaimContext const& ctx)
if (!dirIsEmpty(ctx.view, keylet::ownerDir(id)))
{
JLOG(ctx.j.trace()) << "Retry: Owner directory not empty.";
return ((ctx.flags & TapRetry) != 0u) ? TER{terOWNERS} : TER{tecOWNERS};
return ((ctx.flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terOWNERS}
: TER{tecOWNERS};
}
}
@@ -297,7 +297,8 @@ OfferCreate::checkAcceptAsset(
JLOG(j.debug()) << "delay: can't receive IOUs from non-existent issuer: "
<< to_string(asset.getIssuer());
return ((flags & TapRetry) != 0u) ? TER{terNO_ACCOUNT} : TER{tecNO_ISSUER};
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_ACCOUNT}
: TER{tecNO_ISSUER};
}
// An account cannot create a trustline to itself, so no line can exist
@@ -320,7 +321,8 @@ OfferCreate::checkAcceptAsset(
{
JLOG(j.debug()) << "delay: can't receive IOUs from issuer with "
"DisallowIncomingTrustline set";
return ((flags & TapRetry) != 0u) ? TER{terNO_LINE} : TER{tecNO_LINE};
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_LINE}
: TER{tecNO_LINE};
}
}
@@ -328,7 +330,8 @@ OfferCreate::checkAcceptAsset(
{
if (!trustLine)
{
return ((flags & TapRetry) != 0u) ? TER{terNO_LINE} : TER{tecNO_LINE};
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_LINE}
: TER{tecNO_LINE};
}
// Entries have a canonical representation, determined by a
@@ -344,7 +347,8 @@ OfferCreate::checkAcceptAsset(
JLOG(j.debug()) << "delay: can't receive IOUs from "
"issuer without auth.";
return ((flags & TapRetry) != 0u) ? TER{terNO_AUTH} : TER{tecNO_AUTH};
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_AUTH}
: TER{tecNO_AUTH};
}
}
@@ -93,7 +93,8 @@ LoanSet::preflight(PreflightContext const& ctx)
// A proposed LoanSet is stored unsigned; its CounterpartySignature is
// collected on-ledger afterward, so its absence here is expected, not an
// error (On-Chain Cosigner spec §5.3.1.2).
if (!tx.isFlag(tfInnerBatchTxn) && !counterPartySig && (ctx.flags & TapProposal) == 0)
if (!tx.isFlag(tfInnerBatchTxn) && !counterPartySig &&
(ctx.flags & ApplyFlags::Proposal) == ApplyFlags::None)
{
JLOG(ctx.j.warn()) << "LoanSet transaction must have a CounterpartySignature.";
return temBAD_SIGNER;
@@ -54,8 +54,8 @@ TransactionProposalCreate::preflight(PreflightContext const& ctx)
try
{
STTx const stx{STObject{proposedTx}};
auto const inner =
xrpl::preflight(ctx.registry, ctx.rules, stx, TapDryRun | TapProposal, ctx.j);
auto const inner = xrpl::preflight(
ctx.registry, ctx.rules, stx, ApplyFlags::DryRun | ApplyFlags::Proposal, ctx.j);
if (!isTesSuccess(inner.ter))
{
JLOG(ctx.j.debug()) << "TransactionProposalCreate: proposed txn "
@@ -205,7 +205,7 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
// is collected on-ledger afterward, so its absence here is expected, not
// an error (On-Chain Cosigner spec §5.3.1.2).
if (isAccountReserveSponsorship && !ctx.tx.isFieldPresent(sfSponsorSignature) &&
(ctx.flags & TapProposal) == 0)
(ctx.flags & ApplyFlags::Proposal) == ApplyFlags::None)
{
JLOG(ctx.j.debug()) << "preflight: account sponsorship requires sfSponsorSignature";
return temMALFORMED;
+3 -2
View File
@@ -371,7 +371,8 @@ Batch::preflight(PreflightContext const& ctx)
// TapBatch — PreflightContext with a parentBatchId requires it.
// LoanSet already short-circuits on tfInnerBatchTxn; it is also in
// kDisabledTxTypes, so it never reaches this call.
ApplyFlags const innerFlags = TapBatch | (ctx.flags & (TapProposal | TapDryRun));
ApplyFlags const innerFlags =
ApplyFlags::Batch | (ctx.flags & (ApplyFlags::Proposal | ApplyFlags::DryRun));
if (auto const preflightResult =
xrpl::preflight(ctx.registry, ctx.rules, parentBatchId, stx, innerFlags, ctx.j);
!isTesSuccess(preflightResult.ter))
@@ -443,7 +444,7 @@ Batch::preflightSigValidated(PreflightContext const& ctx)
// A proposed Batch is stored unsigned; its BatchSigners are collected
// on-ledger afterward, so the signer-presence match belongs to submission
// time, not proposal creation (On-Chain Cosigner spec §5.3.1.2).
if ((ctx.flags & TapProposal) != 0)
if ((ctx.flags & ApplyFlags::Proposal) != ApplyFlags::None)
return tesSUCCESS;
auto const parentBatchId = ctx.tx.getTransactionID();
+3 -3
View File
@@ -1941,11 +1941,11 @@ private:
auto const flowResult = [&] {
STAmount const deliver(eth(51'000'000));
STAmount smax(btc(61'000'000));
PaymentSandbox sb(env.current().get(), TapNone);
PaymentSandbox sb(env.current().get(), ApplyFlags::None);
STPathSet paths;
auto const ipe = [](MPTTester const& iss) {
return STPathElement(
STPathElement::TypeMpt | STPathElement::TypeIssuer,
STPathElementType::Mpt | STPathElementType::Issuer,
xrpAccount(),
PathAsset{iss.issuanceID()},
iss.issuer());
@@ -1979,7 +1979,7 @@ private:
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
if (flowResult.removableOffers.empty())
return false;
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
for (auto const& o : flowResult.removableOffers)
{
if (auto const ok = sb.peek(keylet::offer(o)))
+3 -3
View File
@@ -2015,11 +2015,11 @@ private:
auto const flowResult = [&] {
STAmount const deliver(USD(51));
STAmount smax(BTC(61));
PaymentSandbox sb(env.current().get(), TapNone);
PaymentSandbox sb(env.current().get(), ApplyFlags::None);
STPathSet paths;
auto const ipe = [](Issue const& iss) {
return STPathElement(
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
STPathElementType::Currency | STPathElementType::Issuer,
xrpAccount(),
iss.currency,
iss.account);
@@ -2053,7 +2053,7 @@ private:
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
if (flowResult.removableOffers.empty())
return false;
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
for (auto const& o : flowResult.removableOffers)
{
if (auto const ok = sb.peek(keylet::offer(o)))
+2 -2
View File
@@ -4207,7 +4207,7 @@ private:
auto const jtx = env.jt(tx, Seq(1), Fee(10));
env.app().config().features.erase(featureMPTokensV2);
PreflightContext const ctx(
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
env.app(), *jtx.stx, env.current()->rules(), ApplyFlags::None, env.journal);
auto const pf = AMMBid::checkExtraFeatures(ctx);
BEAST_EXPECT(pf == false);
env.app().config().features.insert(featureMPTokensV2);
@@ -4219,7 +4219,7 @@ private:
jtx.jv["Asset2"].removeMember("mpt_issuance_id");
jtx.stx = env.ust(jtx);
PreflightContext const ctx(
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
env.app(), *jtx.stx, env.current()->rules(), ApplyFlags::None, env.journal);
auto const pf = AMMBid::preflight(ctx);
BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
}
+17 -5
View File
@@ -3194,7 +3194,7 @@ private:
auto const jtx = env.jt(tx, Seq(1), Fee(baseFee));
env.app().config().features.erase(featureAMM);
PreflightContext const pfCtx(
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
env.app(), *jtx.stx, env.current()->rules(), ApplyFlags::None, env.journal);
auto const pf = Transactor::invokePreflight<AMMBid>(pfCtx);
BEAST_EXPECT(pf == temDISABLED);
env.app().config().features.insert(featureAMM);
@@ -3205,7 +3205,7 @@ private:
jtx.jv["TxnSignature"] = "deadbeef";
jtx.stx = env.ust(jtx);
PreflightContext const pfCtx(
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
env.app(), *jtx.stx, env.current()->rules(), ApplyFlags::None, env.journal);
auto const pf = Transactor::invokePreflight<AMMBid>(pfCtx);
BEAST_EXPECT(!isTesSuccess(pf));
}
@@ -3216,7 +3216,7 @@ private:
jtx.jv["Asset2"].removeMember("issuer");
jtx.stx = env.ust(jtx);
PreflightContext const pfCtx(
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
env.app(), *jtx.stx, env.current()->rules(), ApplyFlags::None, env.journal);
auto const pf = Transactor::invokePreflight<AMMBid>(pfCtx);
BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
}
@@ -4835,7 +4835,13 @@ private:
FeatureBitset const all{testableAmendments()};
{
Env env(*this, all, XRPAmount(1));
Env env(
*this,
envconfig([](std::unique_ptr<Config> cfg) {
cfg->fees.referenceFee = XRPAmount(1);
return cfg;
}),
all);
fund(env, gw_, {alice_}, XRP(20'000), {USD(10'000)});
AMM amm(env, gw_, XRP(10'000), USD(10'000));
for (auto i = 0; i < kMaxDeletableAmmTrustLines + 10; ++i)
@@ -4887,7 +4893,13 @@ private:
}
{
Env env(*this, all, XRPAmount(1));
Env env(
*this,
envconfig([](std::unique_ptr<Config> cfg) {
cfg->fees.referenceFee = XRPAmount(1);
return cfg;
}),
all);
fund(env, gw_, {alice_}, XRP(20'000), {USD(10'000)});
AMM amm(env, gw_, XRP(10'000), USD(10'000));
for (auto i = 0; i < (kMaxDeletableAmmTrustLines * 2) + 10; ++i)
+12 -19
View File
@@ -32,7 +32,6 @@
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -895,9 +894,8 @@ public:
auto const jNoCred = credentials::ledgerEntry(env, becky, carol, credType);
BEAST_EXPECT(
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
jNoCred[jss::result][jss::error] == "entryNotFound" &&
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jNoCred[jss::result][jss::error_message] == "Entry not found.");
jNoCred[jss::result].isMember(jss::error) &&
jNoCred[jss::result][jss::error] == "entryNotFound");
}
testcase("Credentials that aren't required");
@@ -920,9 +918,8 @@ public:
BEAST_EXPECT(
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
jNoCred[jss::result][jss::error] == "entryNotFound" &&
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jNoCred[jss::result][jss::error_message] == "Entry not found.");
jNoCred[jss::result].isMember(jss::error) &&
jNoCred[jss::result][jss::error] == "entryNotFound");
}
{
@@ -960,9 +957,8 @@ public:
BEAST_EXPECT(
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
jNoCred[jss::result][jss::error] == "entryNotFound" &&
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jNoCred[jss::result][jss::error_message] == "Entry not found.");
jNoCred[jss::result].isMember(jss::error) &&
jNoCred[jss::result][jss::error] == "entryNotFound");
}
testcase("Expired credentials");
@@ -998,9 +994,8 @@ public:
auto jv = credentials::ledgerEntry(env, john, carol, credType);
BEAST_EXPECT(
jv.isObject() && jv.isMember(jss::result) &&
jv[jss::result][jss::error] == "entryNotFound" &&
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
jv[jss::result][jss::error_message] == "Entry not found.");
jv[jss::result].isMember(jss::error) &&
jv[jss::result][jss::error] == "entryNotFound");
}
}
}
@@ -1084,9 +1079,8 @@ public:
auto const jv = credentials::ledgerEntry(env, becky, carol, credType);
BEAST_EXPECT(
jv.isObject() && jv.isMember(jss::result) &&
jv[jss::result][jss::error] == "entryNotFound" &&
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
jv[jss::result][jss::error_message] == "Entry not found.");
jv[jss::result].isMember(jss::error) &&
jv[jss::result][jss::error] == "entryNotFound");
}
}
@@ -1127,9 +1121,8 @@ public:
auto const jv = credentials::ledgerEntry(env, becky, carol, credType);
BEAST_EXPECT(
jv.isObject() && jv.isMember(jss::result) &&
jv[jss::result][jss::error] == "entryNotFound" &&
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
jv[jss::result][jss::error_message] == "Entry not found.");
jv[jss::result].isMember(jss::error) &&
jv[jss::result][jss::error] == "entryNotFound");
}
}
}
+1 -1
View File
@@ -597,7 +597,7 @@ public:
stx->at(sfSigningPubKey) = makeSlice(std::string("badkey"));
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, *stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, *stx, ApplyFlags::None, j);
BEAST_EXPECT(result.ter == temBAD_SIGNATURE);
BEAST_EXPECT(!result.applied);
return result.applied;
+13 -16
View File
@@ -43,7 +43,6 @@
#include <xrpl/ledger/OpenView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Batch.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -433,7 +432,7 @@ class Batch_test : public beast::unit_test::Suite
{
auto const jtx = env.jt(pay(alice, bob, XRP(1)), Txflags(tfInnerBatchTxn));
PreflightContext const pfCtx(
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
env.app(), *jtx.stx, env.current()->rules(), ApplyFlags::None, env.journal);
auto const pf = Transactor::invokePreflight<Payment>(pfCtx);
BEAST_EXPECT(pf == temINVALID_INNER_BATCH);
}
@@ -448,7 +447,7 @@ class Batch_test : public beast::unit_test::Suite
disabledEnv.app(),
*jtx.stx,
disabledEnv.current()->rules(),
TapNone,
ApplyFlags::None,
disabledEnv.journal);
auto const pf = Transactor::invokePreflight<Payment>(pfCtx);
BEAST_EXPECT(pf == temINVALID_FLAG);
@@ -459,7 +458,12 @@ class Batch_test : public beast::unit_test::Suite
{
auto const jtx = env.jt(pay(alice, bob, XRP(1)));
PreflightContext const pfCtx(
env.app(), *jtx.stx, UInt256{1}, env.current()->rules(), TapBatch, env.journal);
env.app(),
*jtx.stx,
UInt256{1},
env.current()->rules(),
ApplyFlags::Batch,
env.journal);
auto const pf = Transactor::invokePreflight<Payment>(pfCtx);
BEAST_EXPECT(pf == temINVALID_INNER_BATCH);
}
@@ -1597,7 +1601,7 @@ class Batch_test : public beast::unit_test::Suite
batch::Sig(std::vector<Reg>(kMaxBatchSigners + 1, bob)));
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, *jt.stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, *jt.stx, ApplyFlags::None, j);
BEAST_EXPECT(!result.applied && result.ter == temARRAY_TOO_LARGE);
return result.applied;
});
@@ -2801,7 +2805,6 @@ class Batch_test : public beast::unit_test::Suite
auto const jrr = env.rpc("submit", strHex(slice))[jss::result];
expect(
jrr[jss::status] == "error" && jrr[jss::error] == "invalidTransaction" &&
!jrr.isMember(jss::error_code) && jrr[jss::error_message].isNull() &&
jrr[jss::error_exception] ==
"fails local checks: Batch inner transactions are never "
"considered validly signed.",
@@ -4718,7 +4721,7 @@ class Batch_test : public beast::unit_test::Suite
BEAST_EXPECT(!passesLocalChecks(stx, reason));
BEAST_EXPECT(reason == "Cannot submit pseudo transactions.");
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, stx, ApplyFlags::None, j);
BEAST_EXPECT(!result.applied && result.ter == temINVALID_FLAG);
return result.applied;
});
@@ -5409,10 +5412,7 @@ class Batch_test : public beast::unit_test::Suite
// The delegated payment never applied.
BEAST_EXPECT(env.balance(mallory) == preMallory);
auto const txResult = env.rpc("tx", txIDs[1])[jss::result];
BEAST_EXPECT(txResult[jss::error] == "txnNotFound");
BEAST_EXPECT(txResult[jss::error_code] == RpcTxnNotFound);
BEAST_EXPECT(txResult[jss::error_message] == "Transaction not found.");
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
}
}
@@ -5823,10 +5823,7 @@ class Batch_test : public beast::unit_test::Suite
validateClosedLedger(env, testCases);
// verify jv2 is not present in the closed ledger.
auto const txResult = env.rpc("tx", txIDs[1])[jss::result];
BEAST_EXPECT(txResult[jss::error] == "txnNotFound");
BEAST_EXPECT(txResult[jss::error_code] == RpcTxnNotFound);
BEAST_EXPECT(txResult[jss::error_message] == "Transaction not found.");
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
}
}
@@ -6024,7 +6021,7 @@ class Batch_test : public beast::unit_test::Suite
obj.setFieldU32(sfFlags, tfInnerBatchTxn);
});
auto const result = xrpl::apply(env.app(), view, stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, stx, ApplyFlags::None, j);
// Must NOT be applied — signature was never checked
BEAST_EXPECT(!result.applied);
return false;
@@ -20,7 +20,6 @@
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/ConfidentialTransfer.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
@@ -260,9 +259,8 @@ class ConfidentialTransferExtended_test : public ConfidentialTransferTestBase
auto const credentialDeleted = [&](Env& env, Account const& subject) -> bool {
auto const credentials = credentials::ledgerEntry(env, subject, dpIssuer, credType);
return credentials[jss::result][jss::error] == "entryNotFound" &&
credentials[jss::result][jss::error_code] == RpcEntryNotFound &&
credentials[jss::result][jss::error_message] == "Entry not found.";
return credentials[jss::result].isMember(jss::error) &&
credentials[jss::result][jss::error] == "entryNotFound";
};
// TEST 4: Expired credential with matching depositPreauth entry.
+2 -11
View File
@@ -1748,7 +1748,8 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
(*sle)[sfConfidentialBalanceVersion] = wrappedFrom;
view.rawReplace(sle);
auto const result = xrpl::apply(env.app(), view, *jt.stx, TapNone, env.journal);
auto const result =
xrpl::apply(env.app(), view, *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(result.ter == tesSUCCESS);
return result.applied;
}));
@@ -7944,8 +7945,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
// Signature verification fails — rejected before ZKP check
auto const jr = env.rpc("submit", strHex(tampered.slice()));
BEAST_EXPECT(jr[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!jr[jss::result].isMember(jss::error_code));
BEAST_EXPECT(jr[jss::result][jss::error_message].isNull());
}
// Variant B: Re-signed with inflated ciphertext.
@@ -8053,8 +8052,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
auto const jr = env.rpc("submit", strHex(tampered.slice()));
BEAST_EXPECT(jr[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!jr[jss::result].isMember(jss::error_code));
BEAST_EXPECT(jr[jss::result][jss::error_message].isNull());
}
// Variant B: Re-signed with all negated ciphertexts.
@@ -8158,8 +8155,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
auto const jr = env.rpc("submit", strHex(tampered.slice()));
BEAST_EXPECT(jr[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!jr[jss::result].isMember(jss::error_code));
BEAST_EXPECT(jr[jss::result][jss::error_message].isNull());
}
// Variant B: Re-signed with combined ciphertext.
@@ -8284,8 +8279,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
// Signature verification fails
auto const jr = env.rpc("submit", strHex(tampered.slice()));
BEAST_EXPECT(jr[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!jr[jss::result].isMember(jss::error_code));
BEAST_EXPECT(jr[jss::result][jss::error_message].isNull());
}
// Variant B: Re-signed C1 substitution.
@@ -8376,8 +8369,6 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
// signed — transaction rejected before ZKP verification.
auto const jr = env.rpc("submit", strHex(tampered.slice()));
BEAST_EXPECT(jr[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!jr[jss::result].isMember(jss::error_code));
BEAST_EXPECT(jr[jss::result][jss::error_message].isNull());
}
// -----------------------------------------------------------------
+24 -36
View File
@@ -23,7 +23,6 @@
#include <xrpl/ledger/ApplyViewImpl.h>
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -125,9 +124,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
}
@@ -175,9 +173,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, issuer, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
}
}
@@ -225,9 +222,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
// resurrection
@@ -263,9 +259,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
// resurrection
@@ -299,9 +294,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
// resurrection
@@ -337,9 +331,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
// resurrection
@@ -375,9 +368,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
}
@@ -398,9 +390,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
}
@@ -419,9 +410,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jle = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jle.isObject() && jle.isMember(jss::result) &&
jle[jss::result][jss::error] == "entryNotFound" &&
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
jle[jss::result][jss::error_message] == "Entry not found.");
jle[jss::result].isMember(jss::error) &&
jle[jss::result][jss::error] == "entryNotFound");
}
}
}
@@ -754,9 +744,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jDelCred = credentials::ledgerEntry(env, subject, issuer, credType2);
BEAST_EXPECT(
jDelCred.isObject() && jDelCred.isMember(jss::result) &&
jDelCred[jss::result][jss::error] == "entryNotFound" &&
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jDelCred[jss::result][jss::error_message] == "Entry not found.");
jDelCred[jss::result].isMember(jss::error) &&
jDelCred[jss::result][jss::error] == "entryNotFound");
BEAST_EXPECT(ownerCount(env, issuer) == 0);
BEAST_EXPECT(ownerCount(env, subject) == 1);
@@ -792,9 +781,8 @@ struct Credentials_test : public beast::unit_test::Suite
auto const jDelCred = credentials::ledgerEntry(env, subject, issuer, credType);
BEAST_EXPECT(
jDelCred.isObject() && jDelCred.isMember(jss::result) &&
jDelCred[jss::result][jss::error] == "entryNotFound" &&
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jDelCred[jss::result][jss::error_message] == "Entry not found.");
jDelCred[jss::result].isMember(jss::error) &&
jDelCred[jss::result][jss::error] == "entryNotFound");
}
}
}
@@ -921,7 +909,7 @@ struct Credentials_test : public beast::unit_test::Suite
{
testcase("deleteSLE fail, bad SLE.");
auto const view =
std::make_shared<ApplyViewImpl>(env.current().get(), ApplyFlags::TapNone);
std::make_shared<ApplyViewImpl>(env.current().get(), ApplyFlags::None);
auto const ter = xrpl::credentials::deleteSLE(*view, {}, env.journal);
BEAST_EXPECT(ter == tecNO_ENTRY);
}
@@ -1144,7 +1132,7 @@ struct Credentials_test : public beast::unit_test::Suite
// Create an ApplyViewImpl on top of the current closed ledger
// and corrupt it by erasing the issuer's account SLE
auto const open = env.current();
ApplyViewImpl av(&*open, TapNone);
ApplyViewImpl av(&*open, ApplyFlags::None);
// Erase the issuer's account to simulate ledger corruption
auto const sleIssuer = av.peek(keylet::account(issuer.id()));
+2 -9
View File
@@ -38,7 +38,6 @@
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/Dir.h>
#include <xrpl/ledger/helpers/DelegateHelpers.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -160,8 +159,6 @@ class Delegate_test : public beast::unit_test::Suite
env.close();
auto const jle = delegate::entry(env, gw, alice);
BEAST_EXPECT(jle[jss::result][jss::error] == "entryNotFound");
BEAST_EXPECT(jle[jss::result][jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jle[jss::result][jss::error_message] == "Entry not found.");
// alice can delegate permissions to gw as well
env(delegate::set(alice, gw, permissions));
@@ -170,8 +167,6 @@ class Delegate_test : public beast::unit_test::Suite
auto const response = delegate::entry(env, gw, alice);
// alice has not been granted any permissions by gw
BEAST_EXPECT(response[jss::result][jss::error] == "entryNotFound");
BEAST_EXPECT(response[jss::result][jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(response[jss::result][jss::error_message] == "Entry not found.");
}
void
@@ -2785,11 +2780,9 @@ class Delegate_test : public beast::unit_test::Suite
jv[jss::secret] = bob.name();
auto jrr = env.rpc("json", "sign_for", to_string(jv))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] ==
"A Signer may not be the transaction's Account (" + bob.human() + ").");
jrr[jss::error_message].asString().contains(
"A Signer may not be the transaction's Account"));
}
}
+8 -13
View File
@@ -28,7 +28,6 @@
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/LedgerFormats.h>
@@ -1144,9 +1143,8 @@ struct DepositPreauth_test : public beast::unit_test::Suite
ledgerEntryDepositPreauth(env, bob, {{.issuer = issuer, .credType = credType}});
BEAST_EXPECT(
jDP.isObject() && jDP.isMember(jss::result) &&
jDP[jss::result][jss::error] == "entryNotFound" &&
jDP[jss::result][jss::error_code] == RpcEntryNotFound &&
jDP[jss::result][jss::error_message] == "Entry not found.");
jDP[jss::result].isMember(jss::error) &&
jDP[jss::result][jss::error] == "entryNotFound");
}
}
}
@@ -1234,9 +1232,8 @@ struct DepositPreauth_test : public beast::unit_test::Suite
auto const jDelCred = credentials::ledgerEntry(env, alice, issuer, credType);
BEAST_EXPECT(
jDelCred.isObject() && jDelCred.isMember(jss::result) &&
jDelCred[jss::result][jss::error] == "entryNotFound" &&
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jDelCred[jss::result][jss::error_message] == "Entry not found.");
jDelCred[jss::result].isMember(jss::error) &&
jDelCred[jss::result][jss::error] == "entryNotFound");
}
{
@@ -1286,9 +1283,8 @@ struct DepositPreauth_test : public beast::unit_test::Suite
auto const jDelCred = credentials::ledgerEntry(env, gw, issuer, credType);
BEAST_EXPECT(
jDelCred.isObject() && jDelCred.isMember(jss::result) &&
jDelCred[jss::result][jss::error] == "entryNotFound" &&
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jDelCred[jss::result][jss::error_message] == "Entry not found.");
jDelCred[jss::result].isMember(jss::error) &&
jDelCred[jss::result][jss::error] == "entryNotFound");
BEAST_EXPECT(ownerCount(env, issuer) == 0);
BEAST_EXPECT(ownerCount(env, gw) == 0);
@@ -1362,9 +1358,8 @@ struct DepositPreauth_test : public beast::unit_test::Suite
auto const jDelCred = credentials::ledgerEntry(env, zelda, issuer, credType);
BEAST_EXPECT(
jDelCred.isObject() && jDelCred.isMember(jss::result) &&
jDelCred[jss::result][jss::error] == "entryNotFound" &&
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
jDelCred[jss::result][jss::error_message] == "Entry not found.");
jDelCred[jss::result].isMember(jss::error) &&
jDelCred[jss::result][jss::error] == "entryNotFound");
}
}
+2 -2
View File
@@ -2773,7 +2773,7 @@ struct EscrowToken_test : public beast::unit_test::Suite
auto const seq1 = env.seq(alice);
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
auto const sleNew =
std::make_shared<SLE>(keylet::escrow(alice, SeqProxy::rawSequence(seq1)));
MPTIssue const mpt{MPTIssue{makeMptID(1, AccountID(0x4985601))}};
@@ -3003,7 +3003,7 @@ struct EscrowToken_test : public beast::unit_test::Suite
auto const seq1 = env.seq(alice);
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
auto const sleNew =
std::make_shared<SLE>(keylet::escrow(alice, SeqProxy::rawSequence(seq1)));
MPTIssue const mpt{MPTIssue{makeMptID(1, AccountID(0x4985601))}};
+8 -8
View File
@@ -1126,8 +1126,8 @@ struct Escrow_test : public beast::unit_test::Suite
env(jt, Ter(fixEnabled ? TER{temMALFORMED} : TER{tecCRYPTOCONDITION_ERROR}));
// Run preflight on the same transaction again, now with the
// HashRouter flag cached. The result must not change.
auto const pf =
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(pf.ter == (fixEnabled ? TER{temMALFORMED} : TER{tesSUCCESS}));
env.close();
@@ -1344,8 +1344,8 @@ struct Escrow_test : public beast::unit_test::Suite
escrow::kFinishTime(env.now() + 1s),
Seq(1),
Fee(baseFee));
auto const pf =
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jtx.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
@@ -1354,8 +1354,8 @@ struct Escrow_test : public beast::unit_test::Suite
{
auto const jtx = env.jt(escrow::cancel("bob", "alice", 3), Seq(1), Fee(baseFee));
auto const pf =
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jtx.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
@@ -1364,8 +1364,8 @@ struct Escrow_test : public beast::unit_test::Suite
{
auto const jtx = env.jt(escrow::finish("bob", "alice", 3), Seq(1), Fee(baseFee));
auto const pf =
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jtx.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
+3 -4
View File
@@ -160,7 +160,7 @@ createInvalidFeeTx(
TER
applyFeeAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx)
{
auto const res = apply(env.app(), view, tx, ApplyFlags::TapNone, env.journal);
auto const res = apply(env.app(), view, tx, ApplyFlags::None, env.journal);
return res.ter;
}
@@ -984,7 +984,7 @@ class FeeVote_test : public beast::unit_test::Suite
Env env(*this, testableAmendments() - featureSmartEscrow);
// establish what the current fees are
BEAST_EXPECT(env.current()->fees().base == env.app().config().fees.referenceFee);
BEAST_EXPECT(env.current()->fees().base == XRPAmount{UNIT_TEST_REFERENCE_FEE});
BEAST_EXPECT(env.current()->fees().reserve == XRPAmount{200'000'000});
BEAST_EXPECT(env.current()->fees().increment == XRPAmount{50'000'000});
@@ -1473,8 +1473,7 @@ class FeeVote_test : public beast::unit_test::Suite
OpenView accum(ledger.get());
BEAST_EXPECT(!accum.open());
auto const result =
apply(env.app(), accum, amendTx, ApplyFlags::TapNone, env.journal);
auto const result = apply(env.app(), accum, amendTx, ApplyFlags::None, env.journal);
BEAST_EXPECTS(result.applied && isTesSuccess(result.ter), transToken(result.ter));
accum.apply(*ledger);
}
+3 -3
View File
@@ -338,11 +338,11 @@ struct FlowMPT_test : public beast::unit_test::Suite
auto const flowResult = [&] {
STAmount const deliver(usd(5'100));
STAmount smax(btc(61));
PaymentSandbox sb(env.current().get(), TapNone);
PaymentSandbox sb(env.current().get(), ApplyFlags::None);
STPathSet paths;
auto const ipe = [](Asset const& asset) {
return STPathElement(
STPathElement::TypeAsset | STPathElement::TypeIssuer,
STPathElementType::Asset | STPathElementType::Issuer,
xrpAccount(),
asset,
asset.getIssuer());
@@ -376,7 +376,7 @@ struct FlowMPT_test : public beast::unit_test::Suite
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
if (flowResult.removableOffers.empty())
return false;
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
for (auto const& o : flowResult.removableOffers)
{
if (auto const ok = sb.peek(keylet::offer(o)))
+3 -3
View File
@@ -476,11 +476,11 @@ struct Flow_test : public beast::unit_test::Suite
auto const flowResult = [&] {
STAmount const deliver(usd(51));
STAmount smax(btc(61));
PaymentSandbox sb(env.current().get(), TapNone);
PaymentSandbox sb(env.current().get(), ApplyFlags::None);
STPathSet paths;
auto const ipe = [](Issue const& iss) {
return STPathElement(
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
STPathElementType::Currency | STPathElementType::Issuer,
xrpAccount(),
iss.currency,
iss.account);
@@ -514,7 +514,7 @@ struct Flow_test : public beast::unit_test::Suite
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
if (flowResult.removableOffers.empty())
return false;
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
for (auto const& o : flowResult.removableOffers)
{
if (auto const ok = sb.peek(keylet::offer(o)))
+1 -1
View File
@@ -63,7 +63,7 @@ public:
if (stx)
{
OpenView accum(&*res);
applyTransaction(env.app(), accum, *stx, false, TapNone, env.journal);
applyTransaction(env.app(), accum, *stx, false, ApplyFlags::None, env.journal);
accum.apply(*res);
}
res->updateSkipList();
+3 -3
View File
@@ -17,7 +17,6 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/XRPAmount.h>
#include <chrono>
#include <cstdint>
@@ -37,6 +36,8 @@ class LedgerMaster_test : public beast::unit_test::Suite
using namespace jtx;
return envconfig([&](std::unique_ptr<Config> cfg) {
cfg->networkId = networkID;
// This test relies on ledger hash so must lock it to fee 10.
cfg->fees.referenceFee = 10;
return cfg;
});
}
@@ -49,8 +50,7 @@ class LedgerMaster_test : public beast::unit_test::Suite
using namespace test::jtx;
using namespace std::literals;
// This test relies on ledger hash so must lock it to fee 10.
test::jtx::Env env{*this, makeNetworkConfig(11111), XRPAmount(10)};
test::jtx::Env env{*this, makeNetworkConfig(11111)};
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
+2 -2
View File
@@ -90,7 +90,7 @@ struct LedgerReplay_test : public beast::unit_test::Suite
auto const lastClosedParent = ledgerMaster.getLedgerByHash(lastClosed->header().parentHash);
auto const replayed = buildLedger(
LedgerReplay(lastClosedParent, lastClosed), TapNone, env.app(), env.journal);
LedgerReplay(lastClosedParent, lastClosed), ApplyFlags::None, env.app(), env.journal);
BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
}
@@ -122,7 +122,7 @@ struct LedgerReplay_test : public beast::unit_test::Suite
auto const lastClosedParent = ledgerMaster.getLedgerByHash(lastClosed->header().parentHash);
auto const replayed = buildLedger(
LedgerReplay(lastClosedParent, lastClosed), TapNone, env.app(), env.journal);
LedgerReplay(lastClosedParent, lastClosed), ApplyFlags::None, env.app(), env.journal);
BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
}
+4 -15
View File
@@ -39,7 +39,6 @@
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
#include <xrpl/ledger/helpers/TokenHelpers.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/protocol/Indexes.h>
@@ -1021,7 +1020,6 @@ class MPToken_test : public beast::unit_test::Suite
payment[jss::build_path] = true;
auto jrr = env.rpc("json", "submit", to_string(payment));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::result][jss::error_message] ==
"Field 'build_path' not allowed in this context.");
@@ -1583,8 +1581,6 @@ class MPToken_test : public beast::unit_test::Suite
jv[jss::tx_json][jss::Amount][jss::value] = std::to_string(kMaxMpTokenAmount + 1);
auto const jrr = env.rpc("json", "submit", to_string(jv));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::result][jss::error_message] == "Invalid field 'tx_json.Amount'.");
}
// Pay maximum amount with the transfer fee, SendMax, and
@@ -1949,8 +1945,6 @@ class MPToken_test : public beast::unit_test::Suite
jtx.stx->add(s);
auto jrr = env.rpc("submit", strHex(s.slice()));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!jrr[jss::result].isMember(jss::error_code));
BEAST_EXPECT(jrr[jss::result][jss::error_message].isNull());
// tx is unsigned
json::Value jv1;
@@ -1958,13 +1952,9 @@ class MPToken_test : public beast::unit_test::Suite
jv1[jss::tx_json] = jv;
jrr = env.rpc("json", "submit", to_string(jv1));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::result][jss::error_message] == "Amount can not be MPT.");
jrr = env.rpc("json", "sign", to_string(jv1));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::result][jss::error_message] == "Amount can not be MPT.");
};
auto setMPTFields = [&](SField const& field, json::Value& jv, bool withAmount = true) {
jv[jss::Asset] = toJson(xrpIssue());
@@ -3042,7 +3032,9 @@ class MPToken_test : public beast::unit_test::Suite
Account const alice{"alice"};
Env env{*this, features, XRPAmount(10)};
auto cfg = envconfig();
cfg->fees.referenceFee = 10;
Env env{*this, std::move(cfg), features};
MPTTester mptAlice(env, alice);
mptAlice.create();
@@ -3206,9 +3198,6 @@ class MPToken_test : public beast::unit_test::Suite
jv1[jss::tx_json] = jv;
auto const jrr = env.rpc("json", "submit", to_string(jv1));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::result][jss::error_message] == "Field 'tx_json.Amount' has invalid data.");
}
}
@@ -4129,7 +4118,7 @@ class MPToken_test : public beast::unit_test::Suite
TER expectedTer,
std::optional<std::uint64_t> expectedOutstanding,
std::string const& label) {
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
auto const ter =
accountSendMulti(av, issuer.id(), asset, receivers, env.app().getJournal("View"));
BEAST_EXPECTS(ter == expectedTer, label);
-44
View File
@@ -31,7 +31,6 @@
#include <xrpl/config/Constants.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/KeyType.h>
@@ -587,7 +586,6 @@ public:
auto jrr = env.rpc("json", "sign_for", to_string(jvOne))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] ==
"When multi-signing 'tx_json.SigningPubKey' must be empty.");
@@ -615,7 +613,6 @@ public:
jrr = env.rpc("json", "submit_multisigned", to_string(jvSubmit))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid Fee field. Fees must be greater than zero.");
}
@@ -642,7 +639,6 @@ public:
jrr = env.rpc("json", "submit_multisigned", to_string(jvSubmit))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "internal");
BEAST_EXPECT(jrr[jss::error_code] == RpcInternal);
BEAST_EXPECT(jrr[jss::error_message] == "Internal error.");
}
@@ -655,8 +651,6 @@ public:
auto jrr = env.rpc("json", "sign_for", to_string(jv))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "masterDisabled");
BEAST_EXPECT(jrr[jss::error_code] == RpcMasterDisabled);
BEAST_EXPECT(jrr[jss::error_message] == "Master key is disabled.");
env.close();
BEAST_EXPECT(env.seq(alice) == aliceSeq);
}
@@ -696,16 +690,12 @@ public:
auto jrr = env.rpc("json", "sign_for", to_string(jv))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "srcActMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcActMalformed);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'tx_json.Account'.");
Account const jimmy{"jimmy"};
jv[jss::tx_json][jss::Account] = jimmy.human();
jrr = env.rpc("json", "sign_for", to_string(jv))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "srcActNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcActNotFound);
BEAST_EXPECT(jrr[jss::error_message] == "Source account not found.");
}
{
@@ -716,7 +706,6 @@ public:
auto jrr = env.rpc("json", "submit_multisigned", to_string(jv))[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "tx_json.Signers array may not be empty.");
env.close();
BEAST_EXPECT(env.seq(alice) == aliceSeq);
@@ -1079,9 +1068,6 @@ public:
STTx local = *tx.stx;
local.setFieldVL(sfSigningPubKey, Blob()); // Empty SigningPubKey
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Empty SigningPubKey.");
@@ -1096,9 +1082,6 @@ public:
local.setFieldVL(sfTxnSignature, badSig);
// Signature should fail.
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Invalid signature.");
@@ -1112,9 +1095,6 @@ public:
local.setFieldU32(sfSequence, seq + 1);
// Signature should fail.
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Invalid signature.");
@@ -1125,9 +1105,6 @@ public:
STTx local = *tx.stx;
local[sfSigningPubKey] = alice.pk(); // Insert sfSigningPubKey
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Cannot both single- and multi-sign.");
@@ -1139,9 +1116,6 @@ public:
local.sign(alice.pk(), alice.sk());
local.setFieldVL(sfSigningPubKey, Blob()); // Empty SigningPubKey
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Cannot both single- and multi-sign.");
@@ -1157,9 +1131,6 @@ public:
signer.setFieldVL(sfTxnSignature, badSig);
// Signature should fail.
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception].asString().contains(
"Invalid signature on account r"));
@@ -1170,9 +1141,6 @@ public:
STTx local = *tx.stx;
local.peekFieldArray(sfSigners).clear(); // Empty Signers array.
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Invalid Signers array size.");
@@ -1218,9 +1186,6 @@ public:
bogie_));
STTx const local = *tx.stx;
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Invalid Signers array size.");
@@ -1230,9 +1195,6 @@ public:
JTx const tx = env.jt(noop(alice), Fee(2 * baseFee), Msig(alice));
STTx const local = *tx.stx;
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Invalid multisigner.");
@@ -1242,9 +1204,6 @@ public:
JTx const tx = env.jt(noop(alice), Fee(2 * baseFee), Msig(bogie_, bogie_));
STTx const local = *tx.stx;
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Duplicate Signers not allowed.");
@@ -1258,9 +1217,6 @@ public:
std::ranges::reverse(signers);
// Signature should fail.
auto const info = submitSTTx(local);
BEAST_EXPECT(info[jss::result][jss::error] == "invalidTransaction");
BEAST_EXPECT(!info[jss::result].isMember(jss::error_code));
BEAST_EXPECT(info[jss::result][jss::error_message].isNull());
BEAST_EXPECT(
info[jss::result][jss::error_exception] ==
"fails local checks: Unsorted Signers array.");
+14 -2
View File
@@ -777,7 +777,13 @@ class NFTokenBurn_test : public beast::unit_test::Suite
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
// Verify that the last page is present and contains one NFT.
auto const lastNFTokenPage = ac.view().peek(keylet::nftokenPageMax(alice));
@@ -809,7 +815,13 @@ class NFTokenBurn_test : public beast::unit_test::Suite
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
// Verify that the middle page is present.
auto const lastNFTokenPage = ac.view().peek(keylet::nftokenPageMax(alice));
+12 -21
View File
@@ -30,7 +30,6 @@
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/protocol/ApiVersion.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
@@ -4654,22 +4653,18 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite
if (expect(
nftOffers.isMember(jss::result), "expected \"result\"", __FILE__, line))
{
json::Value const& result = nftOffers[jss::result];
expect(
result[jss::error].asString() == "objectNotFound",
"expected \"objectNotFound\"",
__FILE__,
line);
expect(
result[jss::error_code] == RpcObjectNotFound,
"expected RpcObjectNotFound",
__FILE__,
line);
expect(
result[jss::error_message] == "The requested object was not found.",
"expected \"The requested object was not found.\"",
__FILE__,
line);
if (expect(
nftOffers[jss::result].isMember(jss::error),
"expected \"error\"",
__FILE__,
line))
{
expect(
nftOffers[jss::result][jss::error].asString() == "objectNotFound",
"expected \"objectNotFound\"",
__FILE__,
line);
}
}
break;
}
@@ -4865,15 +4860,11 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite
// Sell-side marker passed to nft_buy_offers.
json::Value const result = queryWithMarker("nft_buy_offers", sellOfferIndex);
BEAST_EXPECT(result[jss::error].asString() == "invalidParams");
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(result[jss::error_message] == "Invalid parameters.");
}
{
// Buy-side marker passed to nft_sell_offers.
json::Value const result = queryWithMarker("nft_sell_offers", buyOfferIndex);
BEAST_EXPECT(result[jss::error].asString() == "invalidParams");
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(result[jss::error_message] == "Invalid parameters.");
}
// A same-side marker is still accepted. With a single offer on each
-7
View File
@@ -34,7 +34,6 @@
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -2756,8 +2755,6 @@ public:
jro = ledgerEntryOffer(env, bob, bobOfferSeq);
BEAST_EXPECT(jro[jss::error] == "entryNotFound");
BEAST_EXPECT(jro[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jro[jss::error_message] == "Entry not found.");
env.require(Owners(alice, 1), Owners(bob, 1));
}
@@ -2791,8 +2788,6 @@ public:
auto jro = ledgerEntryOffer(env, bob, bobOfferSeq);
BEAST_EXPECT(jro[jss::error] == "entryNotFound");
BEAST_EXPECT(jro[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jro[jss::error_message] == "Entry not found.");
};
testHelper3TokensMix(test);
}
@@ -2852,8 +2847,6 @@ public:
// Verify the offer was consumed
jro = ledgerEntryOffer(env, bob, bobOfferSeq);
BEAST_EXPECT(jro[jss::error] == "entryNotFound");
BEAST_EXPECT(jro[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jro[jss::error_message] == "Entry not found.");
// verify balances look right after the partial payment
// only 300 XRP should have been payed since that's all
-7
View File
@@ -30,7 +30,6 @@
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -1708,8 +1707,6 @@ public:
jro = ledgerEntryOffer(env, bob, bobOfferSeq);
BEAST_EXPECT(jro[jss::error] == "entryNotFound");
BEAST_EXPECT(jro[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jro[jss::error_message] == "Entry not found.");
env.require(Owners(alice, 1), Owners(bob, 1));
}
@@ -1741,8 +1738,6 @@ public:
auto jro = ledgerEntryOffer(env, bob, bobOfferSeq);
BEAST_EXPECT(jro[jss::error] == "entryNotFound");
BEAST_EXPECT(jro[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jro[jss::error_message] == "Entry not found.");
}
void
@@ -1803,8 +1798,6 @@ public:
// Verify the offer was consumed
jro = ledgerEntryOffer(env, bob, bobOfferSeq);
BEAST_EXPECT(jro[jss::error] == "entryNotFound");
BEAST_EXPECT(jro[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jro[jss::error_message] == "Entry not found.");
// verify balances look right after the partial payment
// only 300 XRP should be have been payed since that's all
+2 -7
View File
@@ -26,7 +26,6 @@
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ApiVersion.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/PathAsset.h>
#include <xrpl/protocol/SField.h>
@@ -163,9 +162,7 @@ public:
g.signal();
});
BEAST_EXPECT(g.waitFor(5s));
BEAST_EXPECT(result[jss::error] == "srcCurMalformed");
BEAST_EXPECT(result[jss::error_code] == RpcSrcCurMalformed);
BEAST_EXPECT(result[jss::error_message] == "Source currency is malformed.");
BEAST_EXPECT(result.isMember(jss::error));
// Test rpc::tuning::max_auto_src_cur source currencies.
numSrc.clear();
@@ -192,9 +189,7 @@ public:
g.signal();
});
BEAST_EXPECT(g.waitFor(5s));
BEAST_EXPECT(result[jss::error] == "internal");
BEAST_EXPECT(result[jss::error_code] == RpcInternal);
BEAST_EXPECT(result[jss::error_message] == "Internal error.");
BEAST_EXPECT(result.isMember(jss::error));
}
void
+6 -11
View File
@@ -33,7 +33,6 @@
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ApiVersion.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/SField.h>
@@ -319,9 +318,7 @@ public:
g.signal();
});
BEAST_EXPECT(g.waitFor(5s));
BEAST_EXPECT(result[jss::error] == "srcCurMalformed");
BEAST_EXPECT(result[jss::error_code] == RpcSrcCurMalformed);
BEAST_EXPECT(result[jss::error_message] == "Source currency is malformed.");
BEAST_EXPECT(result.isMember(jss::error));
// Test rpc::tuning::max_auto_src_cur source currencies.
for (auto i = 0; i < (rpc::tuning::kMaxAutoSrcCur - 1); ++i)
@@ -344,9 +341,7 @@ public:
g.signal();
});
BEAST_EXPECT(g.waitFor(5s));
BEAST_EXPECT(result[jss::error] == "internal");
BEAST_EXPECT(result[jss::error_code] == RpcInternal);
BEAST_EXPECT(result[jss::error_message] == "Internal error.");
BEAST_EXPECT(result.isMember(jss::error));
}
void
@@ -1969,9 +1964,9 @@ public:
auto const createPathElements = [](auto const& account1, auto const& account2) {
auto base = STPath{};
base.pushBack(
STPathElement{STPathElement::TypeAccount, account1, xrpCurrency(), account1});
STPathElement{STPathElementType::Account, account1, xrpCurrency(), account1});
auto const tail =
STPathElement{STPathElement::TypeAccount, account2, xrpCurrency(), account2};
STPathElement{STPathElementType::Account, account2, xrpCurrency(), account2};
return std::make_pair(base, tail);
};
@@ -2055,7 +2050,7 @@ public:
auto const makePath = [](AccountID const& account) {
auto p = STPath{};
p.pushBack(STPathElement{STPathElement::TypeAccount, account, xrpCurrency(), account});
p.pushBack(STPathElement{STPathElementType::Account, account, xrpCurrency(), account});
return p;
};
@@ -2179,7 +2174,7 @@ public:
},
// An explicit type mask vs. one derived from the populated fields.
{
STPathElement{STPathElement::TypeAccount, kAccount, xrpCurrency(), kIssuer},
STPathElement{STPathElementType::Account, kAccount, xrpCurrency(), kIssuer},
STPathElement{kAccount, PathAsset{xrpCurrency()}, kIssuer, false},
},
};
+1 -70
View File
@@ -1058,7 +1058,6 @@ struct PayChan_test : public beast::unit_test::Suite
auto const jrr = env.rpc("json", "account_channels", to_string(params))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "actMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jrr[jss::error_message] == "Account malformed.");
BEAST_EXPECT(!jrr.isMember(jss::ledger_index));
BEAST_EXPECT(!jrr.isMember(jss::ledger_current_index));
}
@@ -1233,9 +1232,7 @@ struct PayChan_test : public beast::unit_test::Suite
{
// degenerate case
auto const r = testLimit(env, alice, 0);
BEAST_EXPECT(r[jss::error] == "invalidParams");
BEAST_EXPECT(r[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(r[jss::error_message] == "Invalid field 'limit'.");
BEAST_EXPECT(r.isMember(jss::error_message));
}
{
@@ -1329,12 +1326,7 @@ struct PayChan_test : public beast::unit_test::Suite
auto const rs =
env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
auto const error = apiVersion < 2u ? "invalidParams" : "badKeyType";
auto const errorCode = apiVersion < 2u ? RpcInvalidParams : RpcBadKeyType;
auto const errorMessage =
apiVersion < 2u ? "Invalid field 'key_type'." : "Bad key type.";
BEAST_EXPECT(rs[jss::error] == error);
BEAST_EXPECT(rs[jss::error_code] == errorCode);
BEAST_EXPECT(rs[jss::error_message] == errorMessage);
});
}
@@ -1423,40 +1415,22 @@ struct PayChan_test : public beast::unit_test::Suite
auto const pkAsHex = sliceToHex(pk.slice());
auto rv = env.rpc("channel_verify", pkAsHex, chan1Str, "1000x", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, "1000 ", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, "x1000", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, "x", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, " ", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, "1000 1000", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, "1,000", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, " 1000", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
rv = env.rpc("channel_verify", pkAsHex, chan1Str, "", sig);
BEAST_EXPECT(rv[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel amount is malformed.");
}
{
// malformed channel
@@ -1465,34 +1439,22 @@ struct PayChan_test : public beast::unit_test::Suite
chan1StrBad.pop_back();
auto rv = env.rpc("channel_verify", pkAsHex, chan1StrBad, "1000", sig);
BEAST_EXPECT(rv[jss::error] == "channelMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel is malformed.");
rv = env.rpc("channel_authorize", "alice", chan1StrBad, "1000");
BEAST_EXPECT(rv[jss::error] == "channelMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel is malformed.");
chan1StrBad = chan1Str;
chan1StrBad.push_back('0');
rv = env.rpc("channel_verify", pkAsHex, chan1StrBad, "1000", sig);
BEAST_EXPECT(rv[jss::error] == "channelMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel is malformed.");
rv = env.rpc("channel_authorize", "alice", chan1StrBad, "1000");
BEAST_EXPECT(rv[jss::error] == "channelMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel is malformed.");
chan1StrBad = chan1Str;
chan1StrBad.back() = 'x';
rv = env.rpc("channel_verify", pkAsHex, chan1StrBad, "1000", sig);
BEAST_EXPECT(rv[jss::error] == "channelMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel is malformed.");
rv = env.rpc("channel_authorize", "alice", chan1StrBad, "1000");
BEAST_EXPECT(rv[jss::error] == "channelMalformed");
BEAST_EXPECT(rv[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rv[jss::error_message] == "Payment channel is malformed.");
}
{
// channel_id is not a string.
@@ -1505,8 +1467,6 @@ struct PayChan_test : public beast::unit_test::Suite
auto const ra =
env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(ra[jss::error] == "invalidParams");
BEAST_EXPECT(ra[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(ra[jss::error_message] == "Invalid parameters.");
}
{
// channel_id is not a string.
@@ -1519,8 +1479,6 @@ struct PayChan_test : public beast::unit_test::Suite
auto const rv =
env.rpc("json", "channel_verify", args.toStyledString())[jss::result];
BEAST_EXPECT(rv[jss::error] == "invalidParams");
BEAST_EXPECT(rv[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(rv[jss::error_message] == "Invalid parameters.");
}
{
// give an ill formed base 58 public key
@@ -1579,8 +1537,6 @@ struct PayChan_test : public beast::unit_test::Suite
// Try to authorize using an unknown key type, except an error:
auto const rs1 = env.rpc("channel_authorize", "charlie", "nyx", chan, "1000");
BEAST_EXPECT(rs1[jss::error] == "badKeyType");
BEAST_EXPECT(rs1[jss::error_code] == RpcBadKeyType);
BEAST_EXPECT(rs1[jss::error_message] == "Bad key type.");
// Try to authorize using secp256k1; the authorization _should_
// succeed but the verification should fail:
@@ -1606,16 +1562,10 @@ struct PayChan_test : public beast::unit_test::Suite
// send malformed amounts rpc requests
auto rs = env.rpc("channel_authorize", "alice", chan1Str, "1000x");
BEAST_EXPECT(rs[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rs[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rs[jss::error_message] == "Payment channel amount is malformed.");
rs = env.rpc("channel_authorize", "alice", chan1Str, "x1000");
BEAST_EXPECT(rs[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rs[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rs[jss::error_message] == "Payment channel amount is malformed.");
rs = env.rpc("channel_authorize", "alice", chan1Str, "x");
BEAST_EXPECT(rs[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rs[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rs[jss::error_message] == "Payment channel amount is malformed.");
{
// Missing channel_id
json::Value args{json::ValueType::Object};
@@ -1624,8 +1574,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::passphrase] = "passphrase_can_be_anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "invalidParams");
BEAST_EXPECT(rs[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(rs[jss::error_message] == "Missing field 'channel_id'.");
}
{
// Missing amount
@@ -1635,8 +1583,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::passphrase] = "passphrase_can_be_anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "invalidParams");
BEAST_EXPECT(rs[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(rs[jss::error_message] == "Missing field 'amount'.");
}
{
// Missing key_type and no secret.
@@ -1646,8 +1592,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::passphrase] = "passphrase_can_be_anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "invalidParams");
BEAST_EXPECT(rs[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(rs[jss::error_message] == "Missing field 'secret'.");
}
{
// Both passphrase and seed specified.
@@ -1659,11 +1603,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::seed] = "seed can be anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "invalidParams");
BEAST_EXPECT(rs[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
rs[jss::error_message] ==
"Exactly one of the following must be specified: passphrase, secret, seed or "
"seed_hex");
}
{
// channel_id is not exact hex.
@@ -1674,8 +1613,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::passphrase] = "passphrase_can_be_anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "channelMalformed");
BEAST_EXPECT(rs[jss::error_code] == RpcChannelMalformed);
BEAST_EXPECT(rs[jss::error_message] == "Payment channel is malformed.");
}
{
// amount is not a string
@@ -1686,8 +1623,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::passphrase] = "passphrase_can_be_anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rs[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rs[jss::error_message] == "Payment channel amount is malformed.");
}
{
// Amount is not a decimal string.
@@ -1698,8 +1633,6 @@ struct PayChan_test : public beast::unit_test::Suite
args[jss::passphrase] = "passphrase_can_be_anything";
rs = env.rpc("json", "channel_authorize", args.toStyledString())[jss::result];
BEAST_EXPECT(rs[jss::error] == "channelAmtMalformed");
BEAST_EXPECT(rs[jss::error_code] == RpcChannelAmtMalformed);
BEAST_EXPECT(rs[jss::error_message] == "Payment channel amount is malformed.");
}
}
}
@@ -1950,8 +1883,6 @@ struct PayChan_test : public beast::unit_test::Suite
)*";
auto const r = env.rpc("json", "channel_verify", txn);
BEAST_EXPECT(r["result"]["error"] == "publicMalformed");
BEAST_EXPECT(r["result"]["error_code"] == RpcPublicMalformed);
BEAST_EXPECT(r["result"]["error_message"] == "Public key is malformed.");
}
}
+2 -2
View File
@@ -256,7 +256,7 @@ struct PayStrandMPT_test : public beast::unit_test::Suite
usd,
STPath({
STPathElement{
STPathElement::TypeCurrency, xrpAccount(), xrpCurrency(), xrpAccount()},
STPathElementType::Currency, xrpAccount(), xrpCurrency(), xrpAccount()},
}),
tesSUCCESS,
makeEndpointStep(alice, gw, usd),
@@ -583,7 +583,7 @@ struct PayStrandMPT_test : public beast::unit_test::Suite
inputs.defaultPathsAllowed = true;
try
{
PaymentSandbox sb{env.current().get(), TapNone};
PaymentSandbox sb{env.current().get(), ApplyFlags::None};
{
auto const r = ::xrpl::path::RippleCalc::rippleCalculate(
sb,
+5 -4
View File
@@ -225,7 +225,7 @@ public:
else
{
col.emplace_back(
STPathElement::Type::TypeBoundary,
STPathElementType::Boundary,
acc.value_or(AccountID{}),
cur.value_or(Currency{}),
iss.value_or(AccountID{}));
@@ -684,7 +684,7 @@ struct PayStrand_test : public beast::unit_test::Suite
usd,
STPath({
STPathElement{
STPathElement::TypeCurrency, xrpAccount(), xrpCurrency(), xrpAccount()},
STPathElementType::Currency, xrpAccount(), xrpCurrency(), xrpAccount()},
}),
tesSUCCESS,
D{.src = alice, .dst = gw, .currency = usdC},
@@ -770,7 +770,8 @@ struct PayStrand_test : public beast::unit_test::Suite
env,
usd,
std::nullopt,
STPath({STPathElement(0, xrpAccount(), xrpCurrency(), xrpAccount())}),
STPath({STPathElement(
STPathElementType::None, xrpAccount(), xrpCurrency(), xrpAccount())}),
temBAD_PATH);
// The same account can't appear more than once on a path
@@ -1078,7 +1079,7 @@ struct PayStrand_test : public beast::unit_test::Suite
inputs.defaultPathsAllowed = true;
try
{
PaymentSandbox sb{env.current().get(), TapNone};
PaymentSandbox sb{env.current().get(), ApplyFlags::None};
{
auto const r = ::xrpl::path::RippleCalc::rippleCalculate(
sb,
+1 -1
View File
@@ -88,7 +88,7 @@ struct PseudoTx_test : public beast::unit_test::Suite
BEAST_EXPECT(!passesLocalChecks(stx, reason));
BEAST_EXPECT(reason == "Cannot submit pseudo transactions.");
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, stx, ApplyFlags::None, j);
BEAST_EXPECT(!result.applied && result.ter == temINVALID);
return result.applied;
});
+2 -4
View File
@@ -13,7 +13,6 @@
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Quality.h>
#include <xrpl/protocol/SField.h>
@@ -43,9 +42,8 @@ class ReducedOffer_test : public beast::unit_test::Suite
{
json::Value ledgerOffer = ledgerEntryOffer(env, acct, offerSeq);
return !(
ledgerOffer[jss::error].asString() == "entryNotFound" &&
ledgerOffer[jss::error_code] == RpcEntryNotFound &&
ledgerOffer[jss::error_message] == "Entry not found.");
ledgerOffer.isMember(jss::error) &&
ledgerOffer[jss::error].asString() == "entryNotFound");
}
// Common code to clean up unneeded offers.
+9 -10
View File
@@ -103,7 +103,8 @@ struct Regression_test : public beast::unit_test::Suite
auto const jt = env.jt(pay(env.master, "alice", aliceAmount));
OpenView accum(&*next);
auto const result = xrpl::apply(env.app(), accum, *jt.stx, TapNone, env.journal);
auto const result =
xrpl::apply(env.app(), accum, *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(result.ter));
BEAST_EXPECT(result.applied);
@@ -126,7 +127,8 @@ struct Regression_test : public beast::unit_test::Suite
OpenView accum(&*next);
auto const result = xrpl::apply(env.app(), accum, *jt.stx, TapNone, env.journal);
auto const result =
xrpl::apply(env.app(), accum, *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(result.ter == tecINSUFF_FEE);
BEAST_EXPECT(result.applied);
@@ -193,14 +195,11 @@ struct Regression_test : public beast::unit_test::Suite
{
testcase("Autofilled fee should use the escalated fee");
using namespace jtx;
Env env(
*this,
envconfig([](std::unique_ptr<Config> cfg) {
cfg->section(Sections::kTransactionQueue)
.set(Keys::kMinimumTxnInLedgerStandalone, "3");
return cfg;
}),
XRPAmount(10));
Env env(*this, envconfig([](std::unique_ptr<Config> cfg) {
cfg->section(Sections::kTransactionQueue).set(Keys::kMinimumTxnInLedgerStandalone, "3");
cfg->fees.referenceFee = 10;
return cfg;
}));
EnvSs envs(env);
auto const alice = Account("alice");
+7 -11
View File
@@ -302,14 +302,10 @@ class SHAMapStore_test : public beast::unit_test::Suite
}
static bool
bad(json::Value const& json,
std::string const& token,
ErrorCodeI error,
std::string const& message)
bad(json::Value const& json, ErrorCodeI error = RpcLgrNotFound)
{
return json.isMember(jss::result) && json[jss::result][jss::error] == token &&
json[jss::result][jss::error_code] == error &&
json[jss::result][jss::error_message] == message;
return json.isMember(jss::result) && rpc::containsError(json[jss::result]) &&
json[jss::result][jss::error_code] == error;
}
std::string
@@ -887,7 +883,7 @@ public:
std::map<std::uint32_t, json::Value const> ledgers;
auto ledgerTmp = env.rpc("ledger", "0");
BEAST_EXPECT(bad(ledgerTmp, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound"));
BEAST_EXPECT(bad(ledgerTmp));
ledgers.emplace(1, env.rpc("ledger", "1"));
BEAST_EXPECT(goodLedger(env, ledgers[1], "1"));
@@ -899,10 +895,10 @@ public:
BEAST_EXPECT(goodLedger(env, ledgerTmp, "3"));
ledgerTmp = env.rpc("ledger", "4");
BEAST_EXPECT(bad(ledgerTmp, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound"));
BEAST_EXPECT(bad(ledgerTmp));
ledgerTmp = env.rpc("ledger", "100");
BEAST_EXPECT(bad(ledgerTmp, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound"));
BEAST_EXPECT(bad(ledgerTmp));
auto const firstSeq = waitForReady(env);
auto lastRotated = firstSeq - 1;
@@ -991,7 +987,7 @@ public:
// Because advisory_delete is unset,
// "can_delete" is disabled.
auto const canDelete = env.rpc("can_delete");
BEAST_EXPECT(bad(canDelete, "notEnabled", RpcNotEnabled, "Not enabled in configuration."));
BEAST_EXPECT(bad(canDelete, RpcNotEnabled));
// Close ledgers without triggering a rotate
for (; ledgerSeq < lastRotated + kDeleteInterval; ++ledgerSeq)
+10 -8
View File
@@ -990,8 +990,8 @@ public:
sponsor::SponseeAcc(alice),
Seq(1),
Fee(baseFee));
auto const pf =
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
@@ -1006,8 +1006,8 @@ public:
sponsor::SponseeAcc(alice),
Seq(1),
Fee(baseFee));
auto const pf =
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
@@ -1021,8 +1021,8 @@ public:
sponsor::SponseeAcc(alice),
Seq(1),
Fee(baseFee));
auto const pf =
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
@@ -2318,7 +2318,8 @@ public:
Seq(env.seq(alice)),
sponsor::As(carol, spfSponsorFee));
auto const result = xrpl::apply(env.app(), overlay, *jt.stx, TapNone, env.journal);
auto const result =
xrpl::apply(env.app(), overlay, *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(result.ter == tecINSUFF_FEE);
BEAST_EXPECT(result.applied);
@@ -2371,7 +2372,8 @@ public:
Fee(fixFee),
sponsor::As(sponsor, spfSponsorFee));
auto const pf = preflight(env.app(), overlay.rules(), *jt.stx, TapNone, env.journal);
auto const pf =
preflight(env.app(), overlay.rules(), *jt.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
auto const pc = preclaim(pf, env.app(), overlay);
BEAST_EXPECT(isTesSuccess(pc.ter));
+1 -1
View File
@@ -252,7 +252,7 @@ class TheoreticalQuality_test : public beast::unit_test::Suite
std::shared_ptr<ReadView const> closed,
std::optional<Quality> const& expectedQ = {})
{
PaymentSandbox const sb(closed.get(), TapNone);
PaymentSandbox const sb(closed.get(), ApplyFlags::None);
AMMContext ammContext(rcp.srcAccount, false);
auto const sendMaxIssue = [&rcp] -> std::optional<Asset> {
@@ -20,7 +20,6 @@
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
@@ -1033,25 +1032,15 @@ struct TransactionProposalCancel_test : public beast::unit_test::Suite
{
json::Value noTicket;
noTicket[jss::account] = target.human();
auto const noTicketResult = ledgerEntry(noTicket);
BEAST_EXPECT(noTicketResult[jss::error] == "malformedRequest");
BEAST_EXPECT(noTicketResult[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(noTicketResult[jss::error_message] == "Missing field 'ticket_seq'.");
BEAST_EXPECT(ledgerEntry(noTicket)[jss::error] == "malformedRequest");
json::Value noAccount;
noAccount[jss::ticket_seq] = ticketSeq;
auto const noAccountResult = ledgerEntry(noAccount);
BEAST_EXPECT(noAccountResult[jss::error] == "malformedRequest");
BEAST_EXPECT(noAccountResult[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(noAccountResult[jss::error_message] == "Missing field 'account'.");
BEAST_EXPECT(ledgerEntry(noAccount)[jss::error] == "malformedRequest");
json::Value badAccount = byPair;
badAccount[jss::account] = "not an account";
auto const badAccountResult = ledgerEntry(badAccount);
BEAST_EXPECT(badAccountResult[jss::error] == "malformedAddress");
BEAST_EXPECT(badAccountResult[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
badAccountResult[jss::error_message] == "Invalid field 'account', not AccountID.");
BEAST_EXPECT(ledgerEntry(badAccount)[jss::error] == "malformedAddress");
}
// Listed for the proposer, who owns it, and not for the target.
@@ -1068,8 +1057,6 @@ struct TransactionProposalCancel_test : public beast::unit_test::Suite
{
auto const jrr = ledgerEntry(byPair);
BEAST_EXPECT(jrr[jss::error] == "entryNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jrr[jss::error_message] == "Entry not found.");
BEAST_EXPECT(!jrr.isMember(jss::node));
BEAST_EXPECT(jrr[jss::index] == to_string(proposalID));
}
@@ -1603,7 +1603,7 @@ struct TransactionProposalReservedTicket_test : public beast::unit_test::Suite
auto const stx = rebuilt(mutated);
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, *stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, *stx, ApplyFlags::None, j);
BEAST_EXPECT(result.ter == temBAD_SIGNATURE);
BEAST_EXPECT(!result.applied);
return result.applied;
@@ -1639,7 +1639,7 @@ struct TransactionProposalReservedTicket_test : public beast::unit_test::Suite
auto const stx = rebuilt(mutated);
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, *stx, TapNone, j);
auto const result = xrpl::apply(env.app(), view, *stx, ApplyFlags::None, j);
BEAST_EXPECT(result.ter == temINVALID);
BEAST_EXPECT(!result.applied);
return result.applied;
-5
View File
@@ -14,7 +14,6 @@
#include <xrpl/basics/strHex.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/TER.h>
@@ -67,8 +66,6 @@ class TrustAndBalance_test : public beast::unit_test::Suite
// reflects this
auto jrr = ledgerEntryState(env, gw, alice, "USD");
BEAST_EXPECT(jrr[jss::error] == "entryNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jrr[jss::error_message] == "Entry not found.");
// now create a credit limit
env(trust(alice, gw["USD"](800)));
@@ -103,8 +100,6 @@ class TrustAndBalance_test : public beast::unit_test::Suite
// ensure line is deleted
jrr = ledgerEntryState(env, gw, alice, "USD");
BEAST_EXPECT(jrr[jss::error] == "entryNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcEntryNotFound);
BEAST_EXPECT(jrr[jss::error_message] == "Entry not found.");
// TODO Check in both owner books.
+20 -18
View File
@@ -989,7 +989,8 @@ public:
Env::ParsedResult parsed;
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const result = xrpl::apply(env.app(), view, *jt.stx, TapNone, env.journal);
auto const result =
xrpl::apply(env.app(), view, *jt.stx, ApplyFlags::None, env.journal);
parsed.ter = result.ter;
return result.applied;
});
@@ -1262,7 +1263,8 @@ public:
testcase("tie breaking");
auto cfg = makeConfig({{Keys::kMinimumTxnInLedgerStandalone, "4"}});
Env env(*this, std::move(cfg), XRPAmount(10));
cfg->fees.referenceFee = 10;
Env env(*this, std::move(cfg));
auto const alice = Account("alice");
auto const bob = Account("bob");
@@ -2427,8 +2429,8 @@ public:
env.memoize("carol");
{
auto const jtx = env.jt(offerCancel(alice, 3), Seq(5), Fee(10));
auto const pf =
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jtx.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(10));
@@ -2439,8 +2441,8 @@ public:
auto const usd = alice["USD"];
auto const jtx = env.jt(trust("carol", usd(50000000)), Seq(1), Fee(10));
auto const pf =
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jtx.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(10));
@@ -2449,8 +2451,8 @@ public:
{
auto const jtx = env.jt(ticket::create(alice, 1), Seq(1), Fee(10));
auto const pf =
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
auto const pf = preflight(
env.app(), env.current()->rules(), *jtx.stx, ApplyFlags::None, env.journal);
BEAST_EXPECT(isTesSuccess(pf.ter));
BEAST_EXPECT(!pf.consequences.isBlocker());
BEAST_EXPECT(pf.consequences.fee() == drops(10));
@@ -2729,11 +2731,13 @@ public:
using namespace jtx;
testcase("full queue gap handling");
auto cfg = makeConfig(
{{Keys::kMinimumTxnInLedgerStandalone, "1"},
{Keys::kLedgersInQueue, "10"},
{Keys::kMaximumTxnPerAccount, "11"}});
Env env(*this, std::move(cfg), XRPAmount(10));
auto cfg = makeConfig({
{Keys::kMinimumTxnInLedgerStandalone, "1"},
{Keys::kLedgersInQueue, "10"},
{Keys::kMaximumTxnPerAccount, "11"},
});
cfg->fees.referenceFee = 10;
Env env(*this, std::move(cfg));
auto const baseFee = env.current()->fees().base.drops();
@@ -3228,9 +3232,7 @@ public:
{
auto const info = env.rpc("json", "account_info", to_string(prevLedgerWithQueue));
BEAST_EXPECT(info[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(info[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(info[jss::result][jss::error_message] == "Invalid parameters.");
BEAST_EXPECT(info.isMember(jss::result) && rpc::containsError(info[jss::result]));
}
env.close();
@@ -4009,7 +4011,7 @@ public:
// be callable via RPC.)
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const tx = env.jt(noop(alice), Seq(aliceSeq), Fee(openLedgerCost(env)));
auto const result = xrpl::apply(env.app(), view, *tx.stx, TapUnlimited, j);
auto const result = xrpl::apply(env.app(), view, *tx.stx, ApplyFlags::Unlimited, j);
BEAST_EXPECT(isTesSuccess(result.ter) && result.applied);
return result.applied;
});
@@ -4077,7 +4079,7 @@ public:
// be callable via RPC.)
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
auto const tx = env.jt(noop(alice), ticket::Use(tktSeq0 + 1), Fee(openLedgerCost(env)));
auto const result = xrpl::apply(env.app(), view, *tx.stx, TapUnlimited, j);
auto const result = xrpl::apply(env.app(), view, *tx.stx, ApplyFlags::Unlimited, j);
BEAST_EXPECT(isTesSuccess(result.ter) && result.applied);
return result.applied;
});
+2 -1
View File
@@ -122,7 +122,8 @@ InvariantsBase::doInvariantCheck(
OpenView ov{*env.current()};
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
// Invariants normally run in the Transaction's "apply" (operator()) context, and can always
// access global Rules.
@@ -845,7 +845,13 @@ class InvariantsMisc_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -900,7 +906,13 @@ class InvariantsMisc_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -1023,7 +1035,13 @@ class InvariantsMisc_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -1507,7 +1525,7 @@ class InvariantsMisc_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sle = ac.view().peek(vaultKeylet);
@@ -1574,7 +1592,7 @@ class InvariantsMisc_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
// visitEntry only runs for entries the transaction touched, so
@@ -1631,7 +1649,8 @@ class InvariantsMisc_test : public InvariantsBase
STTx const tx{ttACCOUNT_SET, [](STObject&) {}};
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
FailingTxInvariantCheck failing;
@@ -681,7 +681,7 @@ class InvariantsPseudoAccount_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleBroker = ac.view().peek(brokerKeylet);
@@ -733,7 +733,7 @@ class InvariantsPseudoAccount_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleBroker = ac.view().peek(brokerKeylet);
@@ -781,7 +781,7 @@ class InvariantsPseudoAccount_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleBroker = ac.view().peek(brokerKeylet);
@@ -1131,7 +1131,13 @@ class InvariantsVault_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -1183,7 +1189,7 @@ class InvariantsVault_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -1360,7 +1366,13 @@ class InvariantsVault_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -1415,7 +1427,13 @@ class InvariantsVault_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(),
ov,
tx,
tesSUCCESS,
env.current()->fees().base,
ApplyFlags::None,
jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
auto const sleLoan = ac.view().peek(loanKeylet);
@@ -1519,7 +1537,7 @@ class InvariantsVault_test : public InvariantsBase
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
{
+3 -4
View File
@@ -1154,8 +1154,6 @@ class LoanBroker_test : public beast::unit_test::Suite
auto const jrr = env.rpc("submit", strHex(s.slice()))[jss::result];
// fails in doSubmit() on STTx construction
BEAST_EXPECT(jrr[jss::error] == "invalidTransaction");
BEAST_EXPECT(!jrr.isMember(jss::error_code));
BEAST_EXPECT(jrr[jss::error_message].isNull());
BEAST_EXPECT(jrr[jss::error_exception] == "invalid native account");
}
@@ -1273,7 +1271,8 @@ class LoanBroker_test : public beast::unit_test::Suite
OpenView ov{*env.current()};
test::StreamSink sink{beast::Severity::Warning};
beast::Journal const jlog{sink};
ApplyContext ac{env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
ApplyContext ac{
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, ApplyFlags::None, jlog};
if (auto const sleBroker = ac.view().peek(keylet::loanBroker(brokerKeylet.key)))
{
@@ -1286,7 +1285,7 @@ class LoanBroker_test : public beast::unit_test::Suite
// Invoke preclaim against the mutated (ApplyView) view; triggers
// nullptr deref
PreclaimContext const pctx{env.app(), ac.view(), tesSUCCESS, tx, TapNone, jlog};
PreclaimContext const pctx{env.app(), ac.view(), tesSUCCESS, tx, ApplyFlags::None, jlog};
(void)LoanBrokerCoverDeposit::preclaim(pctx);
}
@@ -190,8 +190,6 @@ private:
BEAST_EXPECT(jr.isMember(jss::result));
auto const jResult = jr[jss::result];
BEAST_EXPECT(jResult[jss::error] == "invalidTransaction");
BEAST_EXPECT(!jResult.isMember(jss::error_code));
BEAST_EXPECT(jResult[jss::error_message].isNull());
BEAST_EXPECT(
jResult[jss::error_exception] ==
"fails local checks: Transaction has bad signature.");
+6 -4
View File
@@ -18,7 +18,6 @@
#include <xrpl/beast/xor_shift_engine.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/KeyType.h>
@@ -127,9 +126,12 @@ private:
return params;
}();
auto const jSignBorrower = env.rpc("json", "sign", to_string(borrowerSignParams));
BEAST_EXPECT(jSignBorrower[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(jSignBorrower[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jSignBorrower[jss::result][jss::error_message] == target);
BEAST_EXPECT(
jSignBorrower.isMember(jss::result) &&
jSignBorrower[jss::result].isMember(jss::error) &&
jSignBorrower[jss::result][jss::error] == "invalidParams" &&
jSignBorrower[jss::result].isMember(jss::error_message) &&
jSignBorrower[jss::result][jss::error_message] == target);
}
}
{
+1 -2
View File
@@ -196,8 +196,7 @@ private:
jvResult[jss::tx_blob] = strHex(local.getSerializer().slice());
auto res = env.rpc("json", "submit", to_string(jvResult))["result"];
BEAST_EXPECT(
res[jss::error] == "invalidTransaction" && !res.isMember(jss::error_code) &&
res[jss::error_message].isNull() &&
res[jss::error] == "invalidTransaction" &&
res[jss::error_exception] ==
"fails local checks: Counterparty: Invalid signature.");
});
+11 -35
View File
@@ -172,7 +172,7 @@ private:
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::vault] = to_string(UInt256(42));
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(jvVault[jss::result], "entryNotFound", RpcEntryNotFound, "Entry not found.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "entryNotFound");
}
{
@@ -182,7 +182,7 @@ private:
jvParams[jss::vault][jss::owner] = issuer.human();
jvParams[jss::vault][jss::seq] = 1'000'000;
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(jvVault[jss::result], "entryNotFound", RpcEntryNotFound, "Entry not found.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "entryNotFound");
}
{
@@ -191,11 +191,7 @@ private:
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::vault] = 42;
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(
jvVault[jss::result],
"malformedRequest",
RpcInvalidParams,
"Invalid field 'vault', not hex string or object.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
}
{
@@ -205,11 +201,7 @@ private:
jvParams[jss::vault][jss::owner] = 42;
jvParams[jss::vault][jss::seq] = sequence;
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(
jvVault[jss::result],
"malformedOwner",
RpcInvalidParams,
"Invalid field 'owner', not AccountID.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedOwner");
}
{
@@ -219,11 +211,7 @@ private:
jvParams[jss::vault][jss::owner] = issuer.human();
jvParams[jss::vault][jss::seq] = "foo";
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(
jvVault[jss::result],
"malformedRequest",
RpcInvalidParams,
"Invalid field 'seq', not number.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
}
{
@@ -233,11 +221,7 @@ private:
jvParams[jss::vault][jss::owner] = issuer.human();
jvParams[jss::vault][jss::seq] = -1;
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(
jvVault[jss::result],
"malformedRequest",
RpcInvalidParams,
"Invalid field 'seq', not number.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
}
{
@@ -247,11 +231,7 @@ private:
jvParams[jss::vault][jss::owner] = issuer.human();
jvParams[jss::vault][jss::seq] = 1e20;
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(
jvVault[jss::result],
"malformedRequest",
RpcInvalidParams,
"Invalid field 'seq', not number.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
}
{
@@ -261,11 +241,7 @@ private:
jvParams[jss::vault][jss::owner] = issuer.human();
jvParams[jss::vault][jss::seq] = true;
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
checkError(
jvVault[jss::result],
"malformedRequest",
RpcInvalidParams,
"Invalid field 'seq', not number.");
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
}
{
@@ -524,8 +500,8 @@ private:
{
testcase("RPC vault_info command line invalid index");
json::Value const jv = env.rpc("vault_info", "foobar", "validated");
checkError(jv, "invalidParams", RpcInvalidParams, "Invalid parameters.");
json::Value jv = env.rpc("vault_info", "foobar", "validated");
BEAST_EXPECT(jv[jss::error].asString() == "invalidParams");
}
{
@@ -543,7 +519,7 @@ private:
{
testcase("RPC vault_info command line invalid ledger");
json::Value jv = env.rpc("vault_info", strHex(keylet.key), "0");
checkError(jv[jss::result], "lgrNotFound", RpcLgrNotFound, "ledgerNotFound");
BEAST_EXPECT(jv[jss::result][jss::error].asString() == "lgrNotFound");
}
}
+1 -1
View File
@@ -114,7 +114,7 @@ private:
auto const peek = [keylet, &env, this](std::function<bool(SLE&, SLE&)> fn) -> bool {
return env.app().getOpenLedger().modify(
[&](OpenView& view, beast::Journal j) -> bool {
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
auto const vault = sb.peek(keylet::vault(keylet.key));
if (!BEAST_EXPECT(vault))
return false;
+1 -1
View File
@@ -304,7 +304,7 @@ private:
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
for (auto const field : encryptedBalanceFields)
{
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
auto const token = sb.peek(tokenKeylet);
if (!BEAST_EXPECT(token))
return false;
+11 -15
View File
@@ -23,7 +23,6 @@
#include <iterator>
#include <limits>
#include <memory>
#include <optional>
#include <ostream>
#include <random>
#include <ranges>
@@ -62,8 +61,8 @@ class PerfLog_test : public beast::unit_test::Suite
// We're only using Env for its Journal. That Journal gives better
// coverage in unit tests.
std::optional<test::jtx::Env> env_;
std::optional<beast::Journal> j_;
test::jtx::Env env_{*this, test::jtx::envconfig(), nullptr, beast::Severity::Disabled};
beast::Journal j_{env_.app().getJournal("PerfLog_test")};
struct Fixture
{
@@ -222,7 +221,7 @@ public:
{
// Verify a PerfLog creates its file when constructed.
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
BEAST_EXPECT(!exists(fixture.logFile()));
auto const perfLog{fixture.perfLog(WithFile::Yes)};
@@ -234,7 +233,7 @@ public:
// Create a file where PerfLog wants to put its directory.
// Make sure that PerfLog tries to shutdown the server since it
// can't open its file.
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
if (!BEAST_EXPECT(!exists(fixture.logDir())))
return;
@@ -269,7 +268,7 @@ public:
// since it can't open its file.
using std::filesystem::perms;
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
if (!BEAST_EXPECT(!exists(fixture.logDir())))
return;
@@ -326,7 +325,7 @@ public:
{
// Exercise the rpc interfaces of PerfLog.
// Start up the PerfLog that we'll use for testing.
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
auto perfLog{fixture.perfLog(withFile)};
perfLog->start();
@@ -524,7 +523,7 @@ public:
// Exercise the jobs interfaces of PerfLog.
// Start up the PerfLog that we'll use for testing.
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
auto perfLog{fixture.perfLog(withFile)};
perfLog->start();
@@ -847,7 +846,7 @@ public:
// the PerLog behaves as well as possible if an invalid ID is passed.
// Start up the PerfLog that we'll use for testing.
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
auto perfLog{fixture.perfLog(withFile)};
perfLog->start();
@@ -986,7 +985,7 @@ public:
// the interface and see that it doesn't crash.
using namespace std::filesystem;
Fixture fixture{env_->app(), *j_};
Fixture fixture{env_.app(), j_};
BEAST_EXPECT(!exists(fixture.logDir()));
auto perfLog{fixture.perfLog(withFile)};
@@ -1044,13 +1043,13 @@ public:
{
testcase("Caller's range need not outlive the PerfLog");
Fixture const fixture{env_->app(), *j_};
Fixture const fixture{env_.app(), j_};
std::unique_ptr<perf::PerfLog> perfLog;
{
std::vector<NullTerminatedView> const names{kMethodNames.begin(), kMethodNames.end()};
perf::PerfLog::Setup const setup{.perfLog = "", .logInterval = fixture.logInterval()};
perfLog = perf::makePerfLog(setup, env_->app(), names, *j_, [] {});
perfLog = perf::makePerfLog(setup, env_.app(), names, j_, [] {});
}
perfLog->start();
@@ -1066,9 +1065,6 @@ public:
void
run() override
{
env_.emplace(*this, test::jtx::envconfig(), nullptr, beast::Severity::Disabled);
j_.emplace(env_->app().getJournal("PerfLog_test"));
testFileCreation();
testRPC(WithFile::No);
testRPC(WithFile::Yes);
+1 -1
View File
@@ -1939,7 +1939,7 @@ negUnlSizeTest(
bool
applyAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx, bool pass)
{
auto const res = apply(env.app(), view, tx, ApplyFlags::TapNone, env.journal);
auto const res = apply(env.app(), view, tx, ApplyFlags::None, env.journal);
if (pass)
{
return isTesSuccess(res.ter);
+4 -8
View File
@@ -7,7 +7,6 @@
#include <atomic>
#include <optional>
#include <string>
#include <thread>
#include <utility>
@@ -19,8 +18,8 @@ class ClosureCounter_test : public beast::unit_test::Suite
{
// We're only using Env for its Journal. That Journal gives better
// coverage in unit tests.
std::optional<test::jtx::Env> env_;
std::optional<beast::Journal> j_;
test::jtx::Env env_{*this, jtx::envconfig(), nullptr, beast::Severity::Disabled};
beast::Journal j_{env_.app().getJournal("ClosureCounter_test")};
void
testConstruction()
@@ -260,7 +259,7 @@ class ClosureCounter_test : public beast::unit_test::Suite
// Join with 0 count should not stall.
using namespace std::chrono_literals;
voidCounter.join("testWrap", 1ms, *j_);
voidCounter.join("testWrap", 1ms, j_);
// Wrapping a closure after join() should return std::nullopt.
BEAST_EXPECT(voidCounter.wrap([]() {}) == std::nullopt);
@@ -281,7 +280,7 @@ class ClosureCounter_test : public beast::unit_test::Suite
std::thread localThread([&voidCounter, &threadExited, this] {
// Should stall after calling join.
using namespace std::chrono_literals;
voidCounter.join("testWaitOnJoin", 1ms, *j_);
voidCounter.join("testWaitOnJoin", 1ms, j_);
threadExited.store(true);
});
@@ -311,9 +310,6 @@ public:
void
run() override
{
env_.emplace(*this, jtx::envconfig(), nullptr, beast::Severity::Disabled);
j_.emplace(env_->app().getJournal("ClosureCounter_test"));
testConstruction();
testArgs();
testWrap();
+16 -83
View File
@@ -194,8 +194,7 @@ private:
beast::unit_test::Suite& suite,
std::unique_ptr<Config> config,
std::unique_ptr<Logs> logs,
beast::Severity thresh,
std::optional<XRPAmount> referenceFee);
beast::Severity thresh);
~AppBundle();
};
@@ -216,7 +215,7 @@ public:
* and takes ownership the passed Config pointer. Features will be enabled
* according to rules described below (see next constructor).
*
* @param suite the current unit_test::Suite
* @param suite the current unit_test::suite
* @param config The desired Config - ownership will be taken by moving
* the pointer. See envconfig and related functions for common config
* tweaks.
@@ -228,15 +227,9 @@ public:
std::unique_ptr<Config> config,
FeatureBitset features,
std::unique_ptr<Logs> logs = nullptr,
std::optional<beast::Severity> thresh = std::nullopt,
std::optional<XRPAmount> referenceFee = std::nullopt)
beast::Severity thresh = beast::Severity::Error)
: test(suite)
, bundle_(
suite,
std::move(config),
std::move(logs),
thresh.value_or(beast::Severity::Error),
referenceFee)
, bundle_(suite, std::move(config), std::move(logs), thresh)
, journal{bundle_.app->getJournal("Env")}
{
memoize(Account::kMaster);
@@ -247,45 +240,22 @@ public:
}
/**
* @brief Create Env with default config, specified
* features, log handler, and reference fee.
* @brief Create Env with default config and specified
* features.
*
* This constructor will create an Env with the standard Env configuration
* (from envconfig()) and features explicitly specified. Use
* with_only_features(...) or supported_features_except(...) to create a
* collection of features appropriate for passing here.
*
* @param suite the current unit_test::Suite
* @param features collection of features
* @param logs log handler
* @param referenceFee non-default reference fee
* @param suite the current unit_test::suite
* @param args collection of features
*
*/
Env(beast::unit_test::Suite& suite,
FeatureBitset features,
std::unique_ptr<Logs> logs,
std::optional<XRPAmount> referenceFee = std::nullopt)
: Env(suite, envconfig(), features, std::move(logs), std::nullopt, referenceFee)
{
}
/**
* @brief Create Env with default config, specified
* features, and reference fee.
*
* This constructor will create an Env with the standard Env configuration
* (from envconfig()) and features explicitly specified. Use
* with_only_features(...) or supported_features_except(...) to create a
* collection of features appropriate for passing here.
*
* @param suite the current unit_test::Suite
* @param features collection of features
* @param referenceFee non-default reference fee
*
*/
Env(beast::unit_test::Suite& suite,
FeatureBitset features,
std::optional<XRPAmount> referenceFee = std::nullopt)
: Env(suite, envconfig(), features, nullptr, std::nullopt, referenceFee)
std::unique_ptr<Logs> logs = nullptr)
: Env(suite, envconfig(), features, std::move(logs))
{
}
@@ -296,7 +266,7 @@ public:
* and takes ownership the passed Config pointer. All supported amendments
* are enabled by this version of the constructor.
*
* @param suite the current unit_test::Suite
* @param suite the current unit_test::suite
* @param config The desired Config - ownership will be taken by moving
* the pointer. See envconfig and related functions for common config
* tweaks.
@@ -304,43 +274,8 @@ public:
Env(beast::unit_test::Suite& suite,
std::unique_ptr<Config> config,
std::unique_ptr<Logs> logs = nullptr,
std::optional<beast::Severity> thresh = std::nullopt,
std::optional<XRPAmount> referenceFee = std::nullopt)
: Env(suite, std::move(config), testableAmendments(), std::move(logs), thresh, referenceFee)
{
}
/**
* @brief Create Env using suite, Config pointer, and reference fee.
*
* This constructor will create an Env with the specified configuration
* and takes ownership the passed Config pointer. All supported amendments
* are enabled by this version of the constructor.
*
* @param suite the current unit_test::Suite
* @param config The desired Config - ownership will be taken by moving
* the pointer. See envconfig and related functions for common config
* tweaks.
* @param referenceFee Optional reference fee to use in fee settings.
*/
Env(beast::unit_test::Suite& suite,
std::unique_ptr<Config> config,
std::optional<XRPAmount> referenceFee)
: Env(suite, std::move(config), testableAmendments(), nullptr, std::nullopt, referenceFee)
{
}
/**
* @brief Create Env with the current test suite and a referenceFee
*
* This constructor will create an Env with the standard
* test Env configuration (from envconfig()) and all supported
* amendments enabled.
*
* @param suite the current unit_test::Suite
*/
Env(beast::unit_test::Suite& suite, std::optional<XRPAmount> referenceFee)
: Env(suite, envconfig(), referenceFee)
beast::Severity thresh = beast::Severity::Error)
: Env(suite, std::move(config), testableAmendments(), std::move(logs), thresh)
{
}
@@ -351,12 +286,10 @@ public:
* test Env configuration (from envconfig()) and all supported
* amendments enabled.
*
* @param suite the current unit_test::Suite
* @param suite the current unit_test::suite
*/
Env(beast::unit_test::Suite& suite,
beast::Severity thresh = beast::Severity::Error,
std::optional<XRPAmount> referenceFee = std::nullopt)
: Env(suite, envconfig(), nullptr, thresh, referenceFee)
Env(beast::unit_test::Suite& suite, beast::Severity thresh = beast::Severity::Error)
: Env(suite, envconfig(), nullptr, thresh)
{
}
+2 -2
View File
@@ -125,7 +125,7 @@ inline TestPath&
TestPath::pushBack(Issue const& iss)
{
path.emplaceBack(
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
STPathElementType::Currency | STPathElementType::Issuer,
beast::kZero,
iss.currency,
iss.account);
@@ -136,7 +136,7 @@ inline TestPath&
TestPath::pushBack(MPTIssue const& iss)
{
path.emplaceBack(
STPathElement::TypeMpt | STPathElement::TypeIssuer,
STPathElementType::Mpt | STPathElementType::Issuer,
beast::kZero,
iss.getMptID(),
iss.getIssuer());
+1 -11
View File
@@ -47,7 +47,6 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/server/NetworkOPs.h>
@@ -74,8 +73,7 @@ Env::AppBundle::AppBundle(
beast::unit_test::Suite& suite,
std::unique_ptr<Config> config,
std::unique_ptr<Logs> logs,
beast::Severity thresh,
std::optional<XRPAmount> referenceFee)
beast::Severity thresh)
: AppBundle()
{
using beast::Severity;
@@ -91,14 +89,6 @@ Env::AppBundle::AppBundle(
}
auto tk = std::make_unique<ManualTimeKeeper>();
timeKeeper = tk.get();
if (referenceFee)
{
config->fees.referenceFee = *referenceFee;
}
else if (auto const fee = suite.referenceFee())
{
config->fees.referenceFee = *fee;
}
// Hack so we don't have to call Config::setup
HTTPClient::initializeSSLContext(
config->sslVerifyDir, config->sslVerifyFile, config->sslVerify, debugLog());
+6 -6
View File
@@ -570,10 +570,10 @@ cpe(PathAsset const& pa)
{
return pa.visit(
[](Currency const& currency) {
return STPathElement(STPathElement::TypeCurrency, xrpAccount(), currency, xrpAccount());
return STPathElement(STPathElementType::Currency, xrpAccount(), currency, xrpAccount());
},
[](MPTID const& mpt) {
return STPathElement(STPathElement::TypeMpt, xrpAccount(), mpt, xrpAccount());
return STPathElement(STPathElementType::Mpt, xrpAccount(), mpt, xrpAccount());
});
};
@@ -590,14 +590,14 @@ ipe(Asset const& asset)
return asset.visit(
[](Issue const& issue) {
return STPathElement(
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
STPathElementType::Currency | STPathElementType::Issuer,
xrpAccount(),
issue.currency,
issue.account);
},
[](MPTIssue const& issue) {
return STPathElement(
STPathElement::TypeMpt | STPathElement::TypeIssuer,
STPathElementType::Mpt | STPathElementType::Issuer,
xrpAccount(),
issue.getMptID(),
issue.getIssuer());
@@ -608,14 +608,14 @@ ipe(Asset const& asset)
STPathElement
iape(AccountID const& account)
{
return STPathElement(STPathElement::TypeIssuer, xrpAccount(), xrpCurrency(), account);
return STPathElement(STPathElementType::Issuer, xrpAccount(), xrpCurrency(), account);
};
// Account path element
STPathElement
ape(AccountID const& a)
{
return STPathElement(STPathElement::TypeAccount, a, xrpCurrency(), xrpAccount());
return STPathElement(STPathElementType::Account, a, xrpCurrency(), xrpAccount());
};
bool
+1 -1
View File
@@ -32,7 +32,7 @@ bumpLastPage(
{
std::expected<void, Error> res{};
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) -> bool {
Sandbox sb(&view, TapNone);
Sandbox sb(&view, ApplyFlags::None);
// Find the root page
auto const sleRoot = sb.peek(directory);
+1 -1
View File
@@ -24,7 +24,7 @@ setupConfigForUnitTests(Config& cfg)
// Reserves held at pre-2021 mainnet values; many tests carry balance
// expectations built on them. Extension limits are deliberately unset --
// tests inherit the FeeSetup defaults, or set [voting].
cfg.fees.referenceFee = XRPAmount(10);
cfg.fees.referenceFee = UNIT_TEST_REFERENCE_FEE;
cfg.fees.accountReserve = XRP(200).value().xrp().drops();
cfg.fees.ownerReserve = XRP(50).value().xrp().drops();
+3 -3
View File
@@ -313,7 +313,7 @@ struct Directory_test : public beast::unit_test::Suite
// All the offers have been cancelled, so the book
// should have no entries and be empty:
{
Sandbox const sb(env.closed().get(), TapNone);
Sandbox const sb(env.closed().get(), ApplyFlags::None);
UInt256 const bookBase = getBookBase({xrpIssue(), usd, std::nullopt});
BEAST_EXPECT(dirIsEmpty(sb, keylet::page(bookBase)));
@@ -352,7 +352,7 @@ struct Directory_test : public beast::unit_test::Suite
{
// Create a chain of three pages:
Sandbox sb(env.closed().get(), TapNone);
Sandbox sb(env.closed().get(), ApplyFlags::None);
makePages(sb, kBase, 3);
// Insert an item in the middle page:
@@ -376,7 +376,7 @@ struct Directory_test : public beast::unit_test::Suite
{
// Create a chain of four pages:
Sandbox sb(env.closed().get(), TapNone);
Sandbox sb(env.closed().get(), ApplyFlags::None);
makePages(sb, kBase, 4);
// Now add items on pages 1 and 2:
+11 -11
View File
@@ -131,7 +131,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
STAmount const toDebit(usdGw1(20));
{
// accountSend, no deferredCredits
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
auto const iss = usdGw1;
auto const startingAmount =
@@ -156,7 +156,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
{
// directSendNoFee, no deferredCredits
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
auto const iss = usdGw1;
auto const startingAmount =
@@ -177,7 +177,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
{
// accountSend, w/ deferredCredits
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox pv(&av);
auto const iss = usdGw1;
@@ -205,7 +205,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
{
// directSendNoFee, w/ deferredCredits
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox pv(&av);
auto const iss = usdGw1;
@@ -221,7 +221,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
{
// redeemIOU, w/ deferredCredits
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox pv(&av);
auto const iss = usdGw1;
@@ -237,7 +237,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
{
// issueIOU, w/ deferredCredits
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox pv(&av);
auto const iss = usdGw1;
@@ -253,7 +253,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
{
// accountSend, w/ deferredCredits and stacked views
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox pv(&av);
auto const iss = usdGw1;
@@ -319,7 +319,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
STAmount const hugeAmt(
issue, STAmount::kMaxValue, STAmount::kMaxOffset - 1, false, STAmount::Unchecked{});
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox pv(&av);
pv.creditHookIOU(gw, alice, hugeAmt, -tinyAmt);
BEAST_EXPECT(pv.balanceHookIOU(alice, gw, hugeAmt) == tinyAmt);
@@ -347,7 +347,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
env.fund(reserve(env, 1), alice);
env.close();
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox sb(&av);
{
// Send alice an amount and spend it. The deferredCredits will cause
@@ -380,7 +380,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
auto const usd = gw["USD"];
Account const alice("alice");
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox sb(&av);
// The currency we pass for the last argument mimics the currency that
@@ -412,7 +412,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
env.fund(XRP(10000), alice, sponsor);
env.close();
ApplyViewImpl av(&*env.current(), TapNone);
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
PaymentSandbox sb(&av);
// Test basic owner count hook without sponsor
+9 -9
View File
@@ -189,7 +189,7 @@ class View_test : public beast::unit_test::Suite
Env env(*this);
wipe(env.app().getOpenLedger());
auto const open = env.current();
ApplyViewImpl v(&*open, TapNone);
ApplyViewImpl v(&*open, ApplyFlags::None);
succ(v, 0, std::nullopt);
v.insert(sle(1));
BEAST_EXPECT(v.exists(k(1)));
@@ -222,7 +222,7 @@ class View_test : public beast::unit_test::Suite
Env env(*this);
wipe(env.app().getOpenLedger());
auto const open = env.current();
ApplyViewImpl v0(&*open, TapNone);
ApplyViewImpl v0(&*open, ApplyFlags::None);
v0.insert(sle(1));
v0.insert(sle(2));
v0.insert(sle(4));
@@ -288,7 +288,7 @@ class View_test : public beast::unit_test::Suite
Env env(*this);
wipe(env.app().getOpenLedger());
auto const open = env.current();
ApplyViewImpl v0(&*open, TapNone);
ApplyViewImpl v0(&*open, ApplyFlags::None);
v0.rawInsert(sle(1, 1));
v0.rawInsert(sle(2, 2));
v0.rawInsert(sle(4, 4));
@@ -368,22 +368,22 @@ class View_test : public beast::unit_test::Suite
BEAST_EXPECT(v1.seq() == v0.seq());
BEAST_EXPECT(v1.parentCloseTime() == v1.parentCloseTime());
ApplyViewImpl v2(&v1, TapRetry);
ApplyViewImpl v2(&v1, ApplyFlags::Retry);
BEAST_EXPECT(v2.parentCloseTime() == v1.parentCloseTime());
BEAST_EXPECT(v2.seq() == v1.seq());
BEAST_EXPECT(v2.flags() == TapRetry);
BEAST_EXPECT(v2.flags() == ApplyFlags::Retry);
Sandbox const v3(&v2);
BEAST_EXPECT(v3.seq() == v2.seq());
BEAST_EXPECT(v3.parentCloseTime() == v2.parentCloseTime());
BEAST_EXPECT(v3.flags() == TapRetry);
BEAST_EXPECT(v3.flags() == ApplyFlags::Retry);
}
{
ApplyViewImpl v1(&v0, TapRetry);
ApplyViewImpl v1(&v0, ApplyFlags::Retry);
PaymentSandbox v2(&v1);
BEAST_EXPECT(v2.seq() == v0.seq());
BEAST_EXPECT(v2.parentCloseTime() == v0.parentCloseTime());
BEAST_EXPECT(v2.flags() == TapRetry);
BEAST_EXPECT(v2.flags() == ApplyFlags::Retry);
PaymentSandbox const v3(&v2);
BEAST_EXPECT(v3.seq() == v2.seq());
BEAST_EXPECT(v3.parentCloseTime() == v2.parentCloseTime());
@@ -1030,7 +1030,7 @@ class View_test : public beast::unit_test::Suite
wipe(*ledger);
ledger->rawInsert(sle(1));
ReadView const& v0 = *ledger;
ApplyViewImpl v1(&v0, TapNone);
ApplyViewImpl v1(&v0, ApplyFlags::None);
{
Sandbox v2(&v1);
v2.erase(v2.peek(k(1)));
+70 -67
View File
@@ -780,9 +780,9 @@ protected:
void
printPeers(std::string const& msg, std::uint16_t validator = 0)
{
auto peers = network_->overlay().getPeers(network_->validator(validator));
std::cout << msg << " " << "num peers " << (int)network_->overlay().getNumPeers()
<< std::endl;
auto peers = network_.overlay().getPeers(network_.validator(validator));
std::cout << msg << " "
<< "num peers " << (int)network_.overlay().getNumPeers() << std::endl;
for (auto& [k, v] : peers)
std::cout << k << ":" << (int)std::get<reduce_relay::PeerState>(v) << " ";
std::cout << std::endl;
@@ -841,8 +841,8 @@ protected:
};
time_point<ManualClock> lastCheck = ManualClock::now();
network_->reset();
network_->propagate([&](Link& link, MessageSPtr m) {
network_.reset();
network_.propagate([&](Link& link, MessageSPtr m) {
auto& validator = link.validator();
auto now = ManualClock::now();
@@ -859,7 +859,7 @@ protected:
if (squelched)
{
auto const selected = network_->overlay().getSelected(validator);
auto const selected = network_.overlay().getSelected(validator);
str << " selected: ";
for (auto const s : selected)
str << s << " ";
@@ -869,10 +869,10 @@ protected:
<< " random, squelched, validator: " << validator.id()
<< " peers: " << str.str() << std::endl;
}
auto const countingState = network_->overlay().isCountingState(validator);
auto const countingState = network_.overlay().isCountingState(validator);
BEAST_EXPECT(
countingState == false &&
selected.size() == env_->app().config().vpReduceRelaySquelchMaxSelectedPeers);
selected.size() == env_.app().config().vpReduceRelaySquelchMaxSelectedPeers);
}
// Trigger Link Down or Peer Disconnect event
@@ -888,13 +888,13 @@ protected:
events[event].time = now;
if (event == EventType::LinkDown)
{
network_->enableLink(validator.id(), link.peerId(), false);
network_.enableLink(validator.id(), link.peerId(), false);
events[event].isSelected =
network_->overlay().isSelected(validator, link.peerId());
network_.overlay().isSelected(validator, link.peerId());
}
else
{
events[event].isSelected = network_->isSelected(link.peerId());
events[event].isSelected = network_.isSelected(link.peerId());
}
};
auto const r = randInt(0, 1000);
@@ -907,8 +907,8 @@ protected:
if (events[EventType::PeerDisconnected].state == State::On)
{
auto& event = events[EventType::PeerDisconnected];
bool const allCounting = network_->allCounting(event.peer);
network_->overlay().deletePeer(
bool const allCounting = network_.allCounting(event.peer);
network_.overlay().deletePeer(
event.peer, [&](PublicKey const& v, PeerWPtr const& peerPtr) {
if (event.isSelected)
sendSquelch(v, peerPtr, {});
@@ -926,7 +926,7 @@ protected:
event.isSelected = false;
event.handledCnt += handled;
event.handled = false;
network_->onDisconnectPeer(event.peer);
network_.onDisconnectPeer(event.peer);
}
auto& event = events[EventType::LinkDown];
@@ -944,17 +944,17 @@ protected:
bool mustHandle = false;
if (event.state == State::On && BEAST_EXPECT(event.key))
{
event.isSelected = network_->overlay().isSelected(*event.key, event.peer);
auto peers = network_->overlay().getPeers(*event.key);
event.isSelected = network_.overlay().isSelected(*event.key, event.peer);
auto peers = network_.overlay().getPeers(*event.key);
auto const d = reduce_relay::epoch<milliseconds>(now).count() -
std::get<3>(peers[event.peer]);
mustHandle = event.isSelected &&
d > milliseconds(reduce_relay::kIdled).count() &&
network_->overlay().inState(
*event.key, reduce_relay::PeerState::Squelched) > 0 &&
network_.overlay().inState(*event.key, reduce_relay::PeerState::Squelched) >
0 &&
peers.contains(event.peer);
}
network_->overlay().deleteIdlePeers([&](PublicKey const& v, PeerWPtr const& ptr) {
network_.overlay().deleteIdlePeers([&](PublicKey const& v, PeerWPtr const& ptr) {
event.handled = true;
if (mustHandle && v == event.key)
{
@@ -976,7 +976,7 @@ protected:
event.isSelected = false;
event.handledCnt += handled;
event.handled = false;
network_->enableLink(event.validator, event.peer, true);
network_.enableLink(event.validator, event.peer, true);
}
});
@@ -997,7 +997,7 @@ protected:
bool
checkCounting(PublicKey const& validator, bool isCountingState)
{
auto const countingState = network_->overlay().isCountingState(validator);
auto const countingState = network_.overlay().isCountingState(validator);
BEAST_EXPECT(countingState == isCountingState);
return countingState == isCountingState;
}
@@ -1053,7 +1053,7 @@ protected:
propagateAndSquelch(bool log, bool purge = true, bool resetClock = true)
{
int n = 0;
network_->propagate(
network_.propagate(
[&](Link& link, MessageSPtr message) {
std::uint16_t squelched = 0;
link.send(
@@ -1066,7 +1066,7 @@ protected:
{
BEAST_EXPECT(
squelched ==
kMaxPeers - env_->app().config().vpReduceRelaySquelchMaxSelectedPeers);
kMaxPeers - env_.app().config().vpReduceRelaySquelchMaxSelectedPeers);
n++;
}
},
@@ -1074,10 +1074,10 @@ protected:
reduce_relay::kMaxMessageThreshold + 2,
purge,
resetClock);
auto const selected = network_->overlay().getSelected(network_->validator(0));
BEAST_EXPECT(selected.size() == env_->app().config().vpReduceRelaySquelchMaxSelectedPeers);
auto const selected = network_.overlay().getSelected(network_.validator(0));
BEAST_EXPECT(selected.size() == env_.app().config().vpReduceRelaySquelchMaxSelectedPeers);
BEAST_EXPECT(n == 1); // only one selection round
auto const res = checkCounting(network_->validator(0), false);
auto const res = checkCounting(network_.validator(0), false);
BEAST_EXPECT(res);
return n == 1 && res;
}
@@ -1094,7 +1094,7 @@ protected:
bool resetClock = true)
{
bool squelched = false;
network_->propagate(
network_.propagate(
[&](Link& link, MessageSPtr message) {
link.send(
message,
@@ -1107,7 +1107,7 @@ protected:
nMessages,
purge,
resetClock);
auto const res = checkCounting(network_->validator(0), countingState);
auto const res = checkCounting(network_.validator(0), countingState);
return !squelched && res;
}
@@ -1120,7 +1120,7 @@ protected:
{
doTest("New Peer", log, [this](bool log) {
BEAST_EXPECT(propagateAndSquelch(log, true, false));
network_->addPeer();
network_.addPeer();
BEAST_EXPECT(propagateNoSquelch(log, 1, true, false, false));
});
}
@@ -1135,14 +1135,14 @@ protected:
doTest("Selected Peer Disconnects", log, [this](bool log) {
ManualClock::advance(seconds(601));
BEAST_EXPECT(propagateAndSquelch(log, true, false));
auto const id = network_->overlay().getSelectedPeer(network_->validator(0));
auto const id = network_.overlay().getSelectedPeer(network_.validator(0));
std::uint16_t unsquelched = 0;
network_->overlay().deletePeer(
network_.overlay().deletePeer(
id, [&](PublicKey const& key, PeerWPtr const& peer) { unsquelched++; });
BEAST_EXPECT(
unsquelched ==
kMaxPeers - env_->app().config().vpReduceRelaySquelchMaxSelectedPeers);
BEAST_EXPECT(checkCounting(network_->validator(0), true));
kMaxPeers - env_.app().config().vpReduceRelaySquelchMaxSelectedPeers);
BEAST_EXPECT(checkCounting(network_.validator(0), true));
});
}
@@ -1158,13 +1158,13 @@ protected:
BEAST_EXPECT(propagateAndSquelch(log, true, false));
ManualClock::advance(reduce_relay::kIdled + seconds(1));
std::uint16_t unsquelched = 0;
network_->overlay().deleteIdlePeers(
network_.overlay().deleteIdlePeers(
[&](PublicKey const& key, PeerWPtr const& peer) { unsquelched++; });
auto const peers = network_->overlay().getPeers(network_->validator(0));
auto const peers = network_.overlay().getPeers(network_.validator(0));
BEAST_EXPECT(
unsquelched ==
kMaxPeers - env_->app().config().vpReduceRelaySquelchMaxSelectedPeers);
BEAST_EXPECT(checkCounting(network_->validator(0), true));
kMaxPeers - env_.app().config().vpReduceRelaySquelchMaxSelectedPeers);
BEAST_EXPECT(checkCounting(network_.validator(0), true));
});
}
@@ -1177,17 +1177,17 @@ protected:
doTest("Squelched Peer Disconnects", log, [this](bool log) {
ManualClock::advance(seconds(601));
BEAST_EXPECT(propagateAndSquelch(log, true, false));
auto const peers = network_->overlay().getPeers(network_->validator(0));
auto peers = network_.overlay().getPeers(network_.validator(0));
auto const it = std::ranges::find_if(peers, [&](auto it) {
return std::get<reduce_relay::PeerState>(it.second) ==
reduce_relay::PeerState::Squelched;
});
assert(it != peers.end());
std::uint16_t unsquelched = 0;
network_->overlay().deletePeer(
network_.overlay().deletePeer(
it->first, [&](PublicKey const& key, PeerWPtr const& peer) { unsquelched++; });
BEAST_EXPECT(unsquelched == 0);
BEAST_EXPECT(checkCounting(network_->validator(0), false));
BEAST_EXPECT(checkCounting(network_.validator(0), false));
});
}
@@ -1332,9 +1332,9 @@ vp_base_squelch_max_selected_peers=2
ManualClock::reset();
auto const createSlots =
[&](bool baseSquelchEnabled) -> reduce_relay::Slots<ManualClock> {
env_->app().config().vpReduceRelayBaseSquelchEnable = baseSquelchEnabled;
env_.app().config().vpReduceRelayBaseSquelchEnable = baseSquelchEnabled;
return reduce_relay::Slots<ManualClock>(
env_->app(), network_->overlay(), env_->app().config());
env_.app(), network_.overlay(), env_.app().config());
};
// base squelching must not be ready if squelching is disabled
BEAST_EXPECT(!createSlots(false).baseSquelchReady());
@@ -1358,32 +1358,32 @@ vp_base_squelch_max_selected_peers=2
testInternalHashRouter(bool log)
{
doTest("Duplicate Message", log, [&](bool log) {
network_->reset();
network_.reset();
// update message count for the same peer/validator
std::int16_t const nMessages = 5;
for (int i = 0; i < nMessages; i++)
{
UInt256 const key(i);
network_->overlay().updateSlotAndSquelch(
key, network_->validator(0), 0, [&](PublicKey const&, PeerWPtr, std::uint32_t) {
network_.overlay().updateSlotAndSquelch(
key, network_.validator(0), 0, [&](PublicKey const&, PeerWPtr, std::uint32_t) {
});
}
auto peers = network_->overlay().getPeers(network_->validator(0));
auto peers = network_.overlay().getPeers(network_.validator(0));
// first message changes Slot state to Counting and is not counted,
// hence '-1'.
BEAST_EXPECT(std::get<1>(peers[0]) == (nMessages - 1));
// add duplicate
UInt256 const key(nMessages - 1);
network_->overlay().updateSlotAndSquelch(
key, network_->validator(0), 0, [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
network_.overlay().updateSlotAndSquelch(
key, network_.validator(0), 0, [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
// confirm the same number of messages
peers = network_->overlay().getPeers(network_->validator(0));
peers = network_.overlay().getPeers(network_.validator(0));
BEAST_EXPECT(std::get<1>(peers[0]) == (nMessages - 1));
// advance the clock
ManualClock::advance(reduce_relay::kIdled + seconds(1));
network_->overlay().updateSlotAndSquelch(
key, network_->validator(0), 0, [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
peers = network_->overlay().getPeers(network_->validator(0));
network_.overlay().updateSlotAndSquelch(
key, network_.validator(0), 0, [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
peers = network_.overlay().getPeers(network_.validator(0));
// confirm message number increased
BEAST_EXPECT(std::get<1>(peers[0]) == nMessages);
});
@@ -1413,7 +1413,7 @@ vp_base_squelch_max_selected_peers=2
auto const run = [&](int npeers) {
handler.maxDuration = 0;
reduce_relay::Slots<ManualClock> slots(env_->app(), handler, env_->app().config());
reduce_relay::Slots<ManualClock> slots(env_.app(), handler, env_.app().config());
// 1st message from a new peer switches the slot
// to counting state and resets the counts of all peers +
// MAX_MESSAGE_THRESHOLD + 1 messages to reach the threshold
@@ -1488,10 +1488,10 @@ vp_base_squelch_max_selected_peers=2
<< "[compression]\n"
<< "1\n";
c.loadFromString(str.str());
env_->app().config().vpReduceRelayBaseSquelchEnable =
env_.app().config().vpReduceRelayBaseSquelchEnable =
c.vpReduceRelayBaseSquelchEnable;
env_->app().config().compression = c.compression;
env_.app().config().compression = c.compression;
};
auto const handshake = [&](int outboundEnable, int inboundEnable) {
beast::ip::Address const addr = boost::asio::ip::make_address("172.1.1.100");
@@ -1499,10 +1499,10 @@ vp_base_squelch_max_selected_peers=2
setEnv(outboundEnable);
auto request = xrpl::makeRequest(
true,
env_->app().config().compression,
env_.app().config().compression,
false,
env_->app().config().txReduceRelayEnable,
env_->app().config().vpReduceRelayBaseSquelchEnable);
env_.app().config().txReduceRelayEnable,
env_.app().config().vpReduceRelayBaseSquelchEnable);
HttpRequestType httpRequest;
httpRequest.version(request.version());
httpRequest.base() = request.base();
@@ -1517,7 +1517,7 @@ vp_base_squelch_max_selected_peers=2
setEnv(inboundEnable);
auto const httpResp = xrpl::makeResponse(
true, httpRequest, addr, addr, UInt256{1}, 1, {1, 0}, env_->app());
true, httpRequest, addr, addr, UInt256{1}, 1, {1, 0}, env_.app());
// outbound is enabled if the response's header has the feature
// enabled and the peer's configuration is enabled
auto const outboundEnabled =
@@ -1531,20 +1531,23 @@ vp_base_squelch_max_selected_peers=2
});
}
std::optional<jtx::Env> env_;
std::optional<Network> network_;
jtx::Env env_;
Network network_;
public:
void
run() override
{
env_.emplace(*this, jtx::envconfig([](std::unique_ptr<Config> cfg) {
reduce_relay_test()
: env_(*this, jtx::envconfig([](std::unique_ptr<Config> cfg) {
cfg->vpReduceRelayBaseSquelchEnable = true;
cfg->vpReduceRelaySquelchMaxSelectedPeers = 6;
return cfg;
}));
network_.emplace(env_->app());
}))
, network_(env_.app())
{
}
void
run() override
{
bool const log = false;
testConfig(log);
testInitialRound(log);
-3
View File
@@ -12,7 +12,6 @@
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/MPTIssue.h>
@@ -181,7 +180,6 @@ public:
auto const result = env.rpc("json", "sign", to_string(req))[jss::result];
BEAST_EXPECT(result[jss::error] == "invalidParams");
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(result[jss::error_message] == "Field 'tx_json.Asset' has invalid data.");
}
@@ -255,7 +253,6 @@ public:
auto const result = env.rpc("json", "sign", to_string(req))[jss::result];
BEAST_EXPECT(result[jss::error] == "invalidParams");
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(result[jss::error_message] == "Field 'tx_json.Asset' has invalid data.");
}
+1 -29
View File
@@ -8,7 +8,6 @@
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/TxFlags.h>
@@ -57,16 +56,12 @@ public:
Account const gw("gw");
auto const usd = gw["USD"];
auto const jv = ammAlice.ammRpcInfo({}, {}, usd, usd);
BEAST_EXPECT(jv[jss::error] == "actNotFound");
BEAST_EXPECT(jv[jss::error_code] == RpcActNotFound);
BEAST_EXPECT(jv[jss::error_message] == "Account not found.");
});
// Invalid LP account id
testAMM([&](AMM& ammAlice, Env&) {
auto const jv = ammAlice.ammRpcInfo(bogie.id());
BEAST_EXPECT(jv[jss::error] == "actMalformed");
BEAST_EXPECT(jv[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
});
@@ -74,8 +69,6 @@ public:
testAMM([&](AMM& ammAlice, Env&) {
auto const jv =
ammAlice.ammRpcInfo(json::Value{42}, std::nullopt, XRP, USD, std::nullopt, true, 3);
BEAST_EXPECT(jv[jss::error] == "actMalformed");
BEAST_EXPECT(jv[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
});
@@ -89,8 +82,6 @@ public:
json::Value{42},
false,
3);
BEAST_EXPECT(jv[jss::error] == "actMalformed");
BEAST_EXPECT(jv[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
});
@@ -115,8 +106,6 @@ public:
iss2,
accountId(ammAlice, acct),
ignoreParams);
BEAST_EXPECT(jv[jss::error] == "invalidParams");
BEAST_EXPECT(jv[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jv[jss::error_message] == "Invalid parameters.");
}
});
@@ -132,8 +121,6 @@ public:
iss2,
accountId(ammAlice, acct),
ignoreParams);
BEAST_EXPECT(jv[jss::error] == "invalidParams");
BEAST_EXPECT(jv[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jv[jss::error_message] == "Invalid parameters.");
}
});
@@ -150,8 +137,6 @@ public:
accountId(ammAlice, acct),
ignoreParams,
3);
BEAST_EXPECT(jv[jss::error] == "actMalformed");
BEAST_EXPECT(jv[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
}
});
@@ -160,8 +145,6 @@ public:
testAMM([&](AMM& ammAlice, Env&) {
auto const jv = ammAlice.ammRpcInfo(
std::nullopt, std::nullopt, std::nullopt, std::nullopt, bogie.id());
BEAST_EXPECT(jv[jss::error] == "actMalformed");
BEAST_EXPECT(jv[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jv[jss::error_message] == "Account malformed.");
});
@@ -186,8 +169,6 @@ public:
iss2,
accountId(ammAlice, acct),
ignoreParams);
BEAST_EXPECT(jv[jss::error] == "invalidParams");
BEAST_EXPECT(jv[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jv[jss::error_message] == "Invalid parameters.");
}
});
@@ -204,13 +185,6 @@ public:
accountId(ammAlice, acct),
ignoreParams,
3);
BEAST_EXPECT(
jv[jss::error] ==
(acct == TestAccount::Bogie ? std::string("actMalformed")
: std::string("invalidParams")));
BEAST_EXPECT(
jv[jss::error_code] ==
(acct == TestAccount::Bogie ? RpcActMalformed : RpcInvalidParams));
BEAST_EXPECT(
jv[jss::error_message] ==
(acct == TestAccount::Bogie ? std::string("Account malformed.")
@@ -409,9 +383,7 @@ public:
testAMM([&](AMM& amm, Env&) {
auto const resp = amm.ammRpcInfo(
std::nullopt, jss::validated.cStr(), std::nullopt, std::nullopt, gw_);
BEAST_EXPECT(resp[jss::error] == "actNotFound");
BEAST_EXPECT(resp[jss::error_code] == RpcActNotFound);
BEAST_EXPECT(resp[jss::error_message] == "Account not found.");
BEAST_EXPECT(resp.isMember("error") && resp["error"] == "actNotFound");
});
}
-5
View File
@@ -35,7 +35,6 @@ public:
{
// account_info with no account.
auto const info = env.rpc("json", "account_info", "{ }");
BEAST_EXPECT(info[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(info[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(info[jss::result][jss::error_message] == "Missing field 'account'.");
}
@@ -46,7 +45,6 @@ public:
"account_info",
"{\"account\": "
"\"n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV\"}");
BEAST_EXPECT(info[jss::result][jss::error] == "actMalformed");
BEAST_EXPECT(info[jss::result][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(info[jss::result][jss::error_message] == "Account malformed.");
BEAST_EXPECT(info[jss::result].isMember(jss::ledger_current_index));
@@ -58,7 +56,6 @@ public:
json::Value params;
params[jss::account] = bogie.human();
auto const info = env.rpc("json", "account_info", to_string(params));
BEAST_EXPECT(info[jss::result][jss::error] == "actNotFound");
BEAST_EXPECT(info[jss::result][jss::error_code] == RpcActNotFound);
BEAST_EXPECT(info[jss::result][jss::error_message] == "Account not found.");
BEAST_EXPECT(info[jss::result][jss::account] == bogie.human());
@@ -68,7 +65,6 @@ public:
{
// Cannot use a seed as account
auto const info = env.rpc("json", "account_info", R"JSON({"account": "foo"})JSON");
BEAST_EXPECT(info[jss::result][jss::error] == "actMalformed");
BEAST_EXPECT(info[jss::result][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(info[jss::result][jss::error_message] == "Account malformed.");
}
@@ -338,7 +334,6 @@ public:
BEAST_EXPECT(info[jss::status] == "error");
BEAST_EXPECT(info[jss::error] == "invalidParams");
BEAST_EXPECT(info[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(info[jss::error_message] == "Invalid parameters.");
BEAST_EXPECT(info.isMember(jss::account_data));
BEAST_EXPECT(info[jss::account_data][sfAccount.jsonName] == alice.human());
BEAST_EXPECT(info.isMember(jss::ledger_current_index));
+1 -26
View File
@@ -55,7 +55,6 @@ public:
{
// account_lines with no account.
auto const lines = env.rpc("json", "account_lines", "{ }");
BEAST_EXPECT(lines[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -66,7 +65,6 @@ public:
json::Value params;
params[jss::account] = "n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj";
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "actMalformed");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -120,7 +118,6 @@ public:
json::Value params;
params[jss::account] = alice.human();
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "actNotFound");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcActNotFound);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -164,7 +161,6 @@ public:
params[jss::account] = alice.human();
params[jss::ledger_index] = "nonsense";
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -176,7 +172,6 @@ public:
params[jss::account] = alice.human();
params[jss::ledger_index] = 50000;
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "lgrNotFound");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcLgrNotFound);
BEAST_EXPECT(lines[jss::result][jss::error_message] == "ledgerNotFound");
}
@@ -310,7 +305,6 @@ public:
params[jss::account] = alice.human();
params[jss::peer] = "n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj";
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "actMalformed");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -350,7 +344,6 @@ public:
params[jss::account] = alice.human();
params[jss::limit] = -1;
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -389,7 +382,6 @@ public:
paramsD[jss::account] = alice.human();
paramsD[jss::marker] = marker;
auto const linesD = env.rpc("json", "account_lines", to_string(paramsD));
BEAST_EXPECT(linesD[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(linesD[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
linesD[jss::result][jss::error_message] ==
@@ -401,7 +393,6 @@ public:
params[jss::account] = alice.human();
params[jss::marker] = true;
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -413,7 +404,6 @@ public:
params[jss::account] = alice.human();
params[jss::marker] = "NOT_A_MARKER";
auto const lines = env.rpc("json", "account_lines", to_string(params));
BEAST_EXPECT(lines[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::result][jss::error_message] ==
@@ -558,11 +548,7 @@ public:
beckyLinesParams[jss::account] = becky.human();
beckyLinesParams[jss::marker] = aliceMarker;
auto const beckyLines = env.rpc("json", "account_lines", to_string(beckyLinesParams));
BEAST_EXPECT(beckyLines[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(beckyLines[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
beckyLines[jss::result][jss::error_message] ==
rpc::makeError(RpcInvalidParams)[jss::error_message]);
BEAST_EXPECT(beckyLines[jss::result].isMember(jss::error_message));
}
void
@@ -630,7 +616,6 @@ public:
linesEndParams[jss::account] = alice.human();
linesEndParams[jss::marker] = linesBeg[jss::result][jss::marker];
auto const linesEnd = env.rpc("json", "account_lines", to_string(linesEndParams));
BEAST_EXPECT(linesEnd[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(linesEnd[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
linesEnd[jss::result][jss::error_message] ==
@@ -929,7 +914,6 @@ public:
request[jss::ripplerpc] = "2.0";
request[jss::id] = 5;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -949,7 +933,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "actMalformed");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -970,7 +953,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "actNotFound");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcActNotFound);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -1043,7 +1025,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -1064,7 +1045,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "lgrNotFound");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcLgrNotFound);
BEAST_EXPECT(lines[jss::error][jss::message] == "ledgerNotFound");
BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
@@ -1240,7 +1220,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "actMalformed");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -1261,7 +1240,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -1336,7 +1314,6 @@ public:
requestD[jss::id] = 5;
requestD[jss::params] = paramsD;
auto const linesD = env.rpc("json2", to_string(requestD));
BEAST_EXPECT(linesD[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(linesD[jss::error][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
linesD[jss::error][jss::message] ==
@@ -1357,7 +1334,6 @@ public:
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::error][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
lines[jss::error][jss::message] ==
@@ -1516,7 +1492,6 @@ public:
linesEndRequest[jss::id] = 5;
linesEndRequest[jss::params] = linesEndParams;
auto const linesEnd = env.rpc("json2", to_string(linesEndRequest));
BEAST_EXPECT(linesEnd[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(linesEnd[jss::error][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
linesEnd[jss::error][jss::message] ==
+3 -37
View File
@@ -140,8 +140,6 @@ public:
{
json::Value const params;
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Missing field 'account'.");
}
// test account non-string
@@ -151,7 +149,6 @@ public:
params[jss::account] = param;
auto jrr = env.rpc("json", "account_objects", to_string(params))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'account'.");
};
@@ -167,8 +164,6 @@ public:
json::Value params;
params[jss::account] = "n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV";
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "actMalformed");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcActMalformed);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Account malformed.");
}
// test error on account that's not in the ledger.
@@ -176,8 +171,6 @@ public:
json::Value params;
params[jss::account] = Account{"bogie"}.human();
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "actNotFound");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcActNotFound);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Account not found.");
}
Account const bob{"bob"};
@@ -187,8 +180,6 @@ public:
params[jss::account] = bob.human();
params[jss::ledger_index] = 10;
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "lgrNotFound");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcLgrNotFound);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "ledgerNotFound");
}
@@ -199,8 +190,6 @@ public:
params[jss::account] = bob.human();
params[jss::type] = 10;
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
resp[jss::result][jss::error_message] == "Invalid field 'type', not string.");
}
@@ -210,8 +199,6 @@ public:
params[jss::account] = bob.human();
params[jss::type] = "expedited";
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Invalid field 'type'.");
}
// test error on limit -ve
@@ -220,8 +207,6 @@ public:
params[jss::account] = bob.human();
params[jss::limit] = -1;
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
resp[jss::result][jss::error_message] ==
"Invalid field 'limit', not unsigned integer.");
@@ -232,8 +217,6 @@ public:
params[jss::account] = bob.human();
params[jss::sponsored] = "true";
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
resp[jss::result][jss::error_message] == "Invalid field 'sponsored', not boolean.");
}
@@ -255,39 +238,27 @@ public:
std::string mark = to_string(resumeMarker);
params[jss::marker] = 10;
resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
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_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
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_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Invalid field 'marker'.");
params[jss::marker] = std::string(&mark[1U], 64);
resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Invalid field 'marker'.");
params[jss::marker] = std::string(&mark[1U], 65);
resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
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_objects", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(resp[jss::result][jss::error_message] == "Invalid field 'marker'.");
// Should this be an error?
@@ -632,8 +603,7 @@ public:
// Make a lambda that checks if the response has error for invalid type
auto const acctObjsTypeIsInvalid = [](json::Value const& resp) {
return resp[jss::result][jss::error] == "invalidParams" &&
resp[jss::result][jss::error_code] == RpcInvalidParams &&
return resp[jss::result].isMember(jss::error) &&
resp[jss::result][jss::error_message] == "Invalid field \'type\'.";
};
@@ -1204,9 +1174,7 @@ public:
params[jss::ledger_index] = jss::validated;
params[jss::marker] = marker;
json::Value const resp = env.rpc("json", "account_nfts", to_string(params));
return resp[jss::result][jss::error] == "invalidParams" &&
resp[jss::result][jss::error_code] == RpcInvalidParams &&
resp[jss::result][jss::error_message] == errorMessage;
return resp[jss::result][jss::error_message] == errorMessage;
};
// test an invalid marker that is not a string
@@ -1459,9 +1427,7 @@ public:
params[jss::ledger_index] = jss::validated;
params[jss::marker] = marker;
json::Value const resp = env.rpc("json", "account_objects", to_string(params));
return resp[jss::result][jss::error] == "invalidParams" &&
resp[jss::result][jss::error_code] == RpcInvalidParams &&
resp[jss::result][jss::error_message] == "Invalid field \'marker\'.";
return resp[jss::result][jss::error_message] == "Invalid field \'marker\'.";
};
auto const markerStr = marker.asString();
+8 -10
View File
@@ -173,9 +173,7 @@ public:
jvParams[jss::limit] = 0u;
auto const jrr =
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'limit'.");
BEAST_EXPECT(jrr.isMember(jss::error_message));
}
}
@@ -197,9 +195,9 @@ public:
{
// no account field
auto const jrr = env.rpc("account_offers");
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "badSyntax");
BEAST_EXPECT(jrr[jss::error_code] == RpcBadSyntax);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error_message] == "Syntax error.");
}
@@ -228,9 +226,9 @@ public:
jvParams[jss::account] = "";
auto const jrr =
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "actMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcActMalformed);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error_message] == "Account malformed.");
BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
BEAST_EXPECT(jrr[jss::validated] == false);
@@ -239,9 +237,9 @@ public:
{
// bogus account value
auto const jrr = env.rpc("account_offers", Account("bogus").human())[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "actNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcActNotFound);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error_message] == "Account not found.");
}
@@ -252,9 +250,9 @@ public:
jvParams[jss::limit] = "0"; // NOT an integer
auto const jrr =
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'limit', not unsigned integer.");
}
@@ -265,9 +263,9 @@ public:
jvParams[jss::marker] = "NOT_A_MARKER";
auto const jrr =
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECTS(
jrr[jss::error_message] == "Invalid field 'marker'.", jrr.toStyledString());
}
@@ -279,9 +277,9 @@ public:
jvParams[jss::marker] = 1;
auto const jrr =
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'marker', not string.");
}
@@ -292,9 +290,9 @@ public:
jvParams[jss::ledger_index] = 10u;
auto const jrr =
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcLgrNotFound);
BEAST_EXPECT(jrr[jss::status] == "error");
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
}
+66 -131
View File
@@ -38,7 +38,6 @@
#include <xrpl/protocol/SeqProxy.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/jss.h>
#include <boost/container/flat_set.hpp>
@@ -135,7 +134,10 @@ class AccountTx_test : public beast::unit_test::Suite
testcase("Parameters APIv" + std::to_string(apiVersion));
using namespace test::jtx;
Env env(*this, XRPAmount(10));
Env env(*this, envconfig([](std::unique_ptr<Config> cfg) {
cfg->fees.referenceFee = 10;
return cfg;
}));
Account const a1{"A1"};
env.fund(XRP(10000), a1);
env.close();
@@ -193,27 +195,19 @@ class AccountTx_test : public beast::unit_test::Suite
(j[jss::result][jss::transactions].size() == 0);
};
auto const isErr = [](json::Value const& j, ErrorCodeI code, std::string const& message) {
return j.isMember(jss::result) &&
j[jss::result][jss::error] == rpc::getErrorInfo(code).token &&
j[jss::result][jss::error_code] == code &&
j[jss::result][jss::error_message] == message;
auto const isErr = [](json::Value const& j, ErrorCodeI code) {
return j.isMember(jss::result) && j[jss::result].isMember(jss::error) &&
j[jss::result][jss::error] == rpc::getErrorInfo(code).token;
};
json::Value jParams;
jParams[jss::api_version] = apiVersion;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(jParams)),
RpcInvalidParams,
"Missing field 'account'."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(jParams)), RpcInvalidParams));
jParams[jss::account] = "0xDEADBEEF";
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(jParams)),
RpcActMalformed,
"Account malformed."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(jParams)), RpcActMalformed));
jParams[jss::account] = a1.human();
BEAST_EXPECT(hasTxs(env.rpc(apiVersion, "json", "account_tx", to_string(jParams))));
@@ -233,10 +227,8 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrIdxMalformed,
"Ledger index malformed."));
BEAST_EXPECT(
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
}
p[jss::ledger_index_min] = 1;
@@ -247,18 +239,15 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrIdxMalformed,
"Ledger index malformed."));
BEAST_EXPECT(
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
}
p[jss::ledger_index_min] = 2;
p[jss::ledger_index_max] = 1;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
(apiVersion == 1 ? RpcLgrIdxsInvalid : RpcInvalidLgrRange),
(apiVersion == 1 ? "Ledger indexes invalid." : "Ledger range is invalid.")));
(apiVersion == 1 ? RpcLgrIdxsInvalid : RpcInvalidLgrRange)));
}
// Ledger index min only
{
@@ -273,17 +262,14 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrIdxMalformed,
"Ledger index malformed."));
BEAST_EXPECT(
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
}
p[jss::ledger_index_min] = env.current()->header().seq;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
(apiVersion == 1 ? RpcLgrIdxsInvalid : RpcInvalidLgrRange),
(apiVersion == 1 ? "Ledger indexes invalid." : "Ledger range is invalid.")));
(apiVersion == 1 ? RpcLgrIdxsInvalid : RpcInvalidLgrRange)));
}
// Ledger index max only
@@ -299,10 +285,8 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrIdxMalformed,
"Ledger index malformed."));
BEAST_EXPECT(
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
}
p[jss::ledger_index_max] = 3;
@@ -326,14 +310,10 @@ class AccountTx_test : public beast::unit_test::Suite
BEAST_EXPECT(noTxs(env.rpc("json", "account_tx", to_string(p))));
p[jss::ledger_index] = env.current()->header().seq;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrNotValidated,
"Ledger not validated."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrNotValidated));
p[jss::ledger_index] = env.current()->header().seq + 1;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)), RpcLgrNotFound, "ledgerNotFound"));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrNotFound));
}
{
@@ -346,16 +326,10 @@ class AccountTx_test : public beast::unit_test::Suite
BEAST_EXPECT(hasTxs(env.rpc(apiVersion, "json", "account_tx", to_string(p))));
p[jss::ledger_index] = "current";
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrNotValidated,
"Ledger not validated."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrNotValidated));
p[jss::ledger_index] = "";
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrNotValidated,
"Ledger not validated."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrNotValidated));
}
// Ledger Hash
@@ -386,10 +360,7 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
"invalidParams"));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
}
}
@@ -403,10 +374,8 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcLgrIdxMalformed,
"Ledger index malformed."));
BEAST_EXPECT(
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
}
}
// test account non-string
@@ -416,7 +385,6 @@ class AccountTx_test : public beast::unit_test::Suite
params[jss::account] = param;
auto jrr = env.rpc("json", "account_tx", to_string(params))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'account'.");
};
@@ -438,10 +406,7 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
"Invalid field 'binary'."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
}
p[jss::binary] = true;
@@ -455,10 +420,7 @@ class AccountTx_test : public beast::unit_test::Suite
}
else
{
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
"Invalid field 'forward'."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
}
p[jss::forward] = false;
@@ -471,83 +433,70 @@ class AccountTx_test : public beast::unit_test::Suite
// Test case: limit = 0 should fail (below minimum)
p[jss::limit] = 0;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
"Invalid field 'limit'."));
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
// Test case: limit = 1.2 should fail (not an integer)
p[jss::limit] = 1.2;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = "10" should fail (string instead of integer)
p[jss::limit] = "10";
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = true should fail (boolean instead of integer)
p[jss::limit] = true;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = false should fail (boolean instead of integer)
p[jss::limit] = false;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = -1 should fail (negative number)
p[jss::limit] = -1;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = [] should fail (array instead of integer)
p[jss::limit] = json::Value(json::ValueType::Array);
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = {} should fail (object instead of integer)
p[jss::limit] = json::Value(json::ValueType::Object);
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = "malformed" should fail (malformed string)
p[jss::limit] = "malformed";
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = ["limit"] should fail (array with string)
p[jss::limit] = json::Value(json::ValueType::Array);
p[jss::limit].append("limit");
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = {"limit": 10} should fail (object with
// property)
p[jss::limit] = json::Value(json::ValueType::Object);
p[jss::limit][jss::limit] = 10;
BEAST_EXPECT(isErr(
env.rpc("json", "account_tx", to_string(p)),
RpcInvalidParams,
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
BEAST_EXPECT(
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
// Test case: limit = 10 should succeed (valid integer)
p[jss::limit] = 10;
@@ -1036,16 +985,12 @@ class AccountTx_test : public beast::unit_test::Suite
};
auto const checkError = [&](json::Value const& delegateParams,
std::string const& errToken,
ErrorCodeI code,
std::string const& errMessage) {
std::string const& errToken) {
json::Value params;
params[jss::account] = alice.human();
params[jss::delegate] = delegateParams;
auto res = env.rpc("json", "account_tx", to_string(params));
BEAST_EXPECT(res[jss::result][jss::error] == errToken);
BEAST_EXPECT(res[jss::result][jss::error_code] == code);
BEAST_EXPECT(res[jss::result][jss::error_message] == errMessage);
};
// Filter: Delegatee. Expects TX #2 (Signed by Bob)
@@ -1116,27 +1061,27 @@ class AccountTx_test : public beast::unit_test::Suite
// "delegate" is not an object (e.g., string)
{
json::Value const p = "not_an_object";
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate'.");
checkError(p, "invalidParams");
}
// Missing "delegate_filter" inside object
{
json::Value const p(json::ValueType::Object);
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate_filter'.");
checkError(p, "invalidParams");
}
// "delegate_filter" is not a string (e.g., int)
{
json::Value p;
p[jss::delegate_filter] = 123;
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate_filter'.");
checkError(p, "invalidParams");
}
// "delegate_filter" has invalid value
{
json::Value p;
p[jss::delegate_filter] = "random_string";
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate_filter'.");
checkError(p, "invalidParams");
}
// "counterparty" is not a string
@@ -1144,7 +1089,7 @@ class AccountTx_test : public beast::unit_test::Suite
json::Value p;
p[jss::delegate_filter] = "actor";
p[jss::counter_party] = 123;
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'counter_party'.");
checkError(p, "invalidParams");
}
// "counterparty" is malformed base58
@@ -1152,7 +1097,7 @@ class AccountTx_test : public beast::unit_test::Suite
json::Value p;
p[jss::delegate_filter] = "actor";
p[jss::counter_party] = "not_an_account";
checkError(p, "actMalformed", RpcActMalformed, "Account malformed.");
checkError(p, "actMalformed");
}
// Multi-signed non-delegated TX: Alice pays Carol via multi-sig.
@@ -1236,11 +1181,6 @@ class AccountTx_test : public beast::unit_test::Suite
p[jss::marker] = delegateMarker;
auto const r = env.rpc("json", "account_tx", to_string(p));
BEAST_EXPECT(r[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(r[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
r[jss::result][jss::error_message] ==
"Do not mix delegate and non-delegate pagination markers in account_tx; "
"repeat the same `delegate` object when using a delegate marker.");
}
// Obtain a non-delegate marker; it must not carry the flag.
@@ -1265,11 +1205,6 @@ class AccountTx_test : public beast::unit_test::Suite
p[jss::marker] = normalMarker;
auto const r = env.rpc("json", "account_tx", to_string(p));
BEAST_EXPECT(r[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(r[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
r[jss::result][jss::error_message] ==
"Do not mix delegate and non-delegate pagination markers in account_tx; "
"repeat the same `delegate` object when using a delegate marker.");
}
}
}
+6 -19
View File
@@ -14,7 +14,6 @@
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/config/Constants.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/jss.h>
@@ -187,42 +186,32 @@ class AmendmentBlocked_test : public beast::unit_test::Suite
// ledger_accept
jr = env.rpc("ledger_accept")[jss::result];
BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::status] == "error");
BEAST_EXPECT(jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::error_code] == RpcAmendmentBlocked);
BEAST_EXPECT(jr[jss::error_message] == "Amendment blocked, need upgrade.");
BEAST_EXPECT(!jr.isMember(jss::warnings));
// ledger_current
jr = env.rpc("ledger_current")[jss::result];
BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::status] == "error");
BEAST_EXPECT(jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::error_code] == RpcAmendmentBlocked);
BEAST_EXPECT(jr[jss::error_message] == "Amendment blocked, need upgrade.");
BEAST_EXPECT(!jr.isMember(jss::warnings));
// owner_info
jr = env.rpc("owner_info", alice.human())[jss::result];
BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::status] == "error");
BEAST_EXPECT(jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::error_code] == RpcAmendmentBlocked);
BEAST_EXPECT(jr[jss::error_message] == "Amendment blocked, need upgrade.");
BEAST_EXPECT(!jr.isMember(jss::warnings));
// path_find
jr = wsc->invoke("path_find", pfReq)[jss::result];
BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::status] == "error");
BEAST_EXPECT(jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::error_code] == RpcAmendmentBlocked);
BEAST_EXPECT(jr[jss::error_message] == "Amendment blocked, need upgrade.");
BEAST_EXPECT(!jr.isMember(jss::warnings));
// submit
jr = env.rpc("submit", strHex(s.slice()))[jss::result];
BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::status] == "error");
BEAST_EXPECT(jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::error_code] == RpcAmendmentBlocked);
BEAST_EXPECT(jr[jss::error_message] == "Amendment blocked, need upgrade.");
BEAST_EXPECT(!jr.isMember(jss::warnings));
// submit_multisigned
@@ -232,9 +221,7 @@ class AmendmentBlocked_test : public beast::unit_test::Suite
BEAST_EXPECT(jr[jss::status] == "success");
msReq[jss::tx_json] = jr[jss::tx_json];
jr = env.rpc("json", "submit_multisigned", to_string(msReq))[jss::result];
BEAST_EXPECT(jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(jr[jss::error_code] == RpcAmendmentBlocked);
BEAST_EXPECT(jr[jss::error_message] == "Amendment blocked, need upgrade.");
BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
BEAST_EXPECT(!jr.isMember(jss::warnings));
}
+2 -7
View File
@@ -19,7 +19,6 @@
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/Ledger.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
@@ -78,12 +77,8 @@ public:
// non-conventional ledger input should throw an error
params["ledger"] = "non_conventional_ledger_input";
resp = env.rpc("json", "book_changes", to_string(params));
BEAST_EXPECT(resp[jss::result][jss::status] == "error");
BEAST_EXPECT(resp[jss::result][jss::error] == "invalidParams");
BEAST_EXPECT(resp[jss::result][jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
resp[jss::result][jss::error_message] ==
"Invalid field 'ledger', not string or number.");
BEAST_EXPECT(resp[jss::result].isMember(jss::error));
BEAST_EXPECT(resp[jss::result][jss::status] != "success");
}
void
-28
View File
@@ -20,7 +20,6 @@
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Issue.h>
@@ -1226,7 +1225,6 @@ public:
jvParams[jss::ledger_index] = 10u;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
BEAST_EXPECT(jrr[jss::error_code] == RpcLgrNotFound);
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
}
@@ -1235,7 +1233,6 @@ public:
jvParams[jss::ledger_index] = "validated";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Missing field 'taker_pays'.");
}
@@ -1245,7 +1242,6 @@ public:
jvParams[jss::taker_pays] = json::ValueType::Object;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Missing field 'taker_gets'.");
}
@@ -1256,7 +1252,6 @@ public:
jvParams[jss::taker_gets] = json::ValueType::Object;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'taker_pays', not object.");
}
@@ -1267,7 +1262,6 @@ public:
jvParams[jss::taker_gets] = "not an object";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'taker_gets', not object.");
}
@@ -1278,7 +1272,6 @@ public:
jvParams[jss::taker_gets] = json::ValueType::Object;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Missing field 'taker_pays.currency'.");
}
@@ -1289,7 +1282,6 @@ public:
jvParams[jss::taker_gets] = json::ValueType::Object;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_pays.currency', not string.");
}
@@ -1301,7 +1293,6 @@ public:
jvParams[jss::taker_gets] = json::ValueType::Object;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Missing field 'taker_gets.currency'.");
}
@@ -1312,7 +1303,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = 1;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_gets.currency', not string.");
}
@@ -1324,7 +1314,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = "XRP";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "srcCurMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcCurMalformed);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_pays.currency', bad currency.");
}
@@ -1336,7 +1325,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = "NOT_VALID";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "dstAmtMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcDstAmtMalformed);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_gets.currency', bad currency.");
}
@@ -1349,7 +1337,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = 1;
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_gets.issuer', not string.");
}
@@ -1362,7 +1349,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = "USD";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_pays.issuer', not string.");
}
@@ -1375,7 +1361,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = "USD";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "srcIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_pays.issuer', bad issuer.");
}
@@ -1388,7 +1373,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = "USD";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "srcIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] ==
"Invalid field 'taker_pays.issuer', bad issuer account one.");
@@ -1402,7 +1386,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human() + "DEAD";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "dstIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcDstIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'taker_gets.issuer', bad issuer.");
}
@@ -1415,7 +1398,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = toBase58(noAccount());
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "dstIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcDstIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] ==
"Invalid field 'taker_gets.issuer', bad issuer account one.");
@@ -1430,7 +1412,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "srcIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] ==
"Unneeded field 'taker_pays.issuer' "
@@ -1446,7 +1427,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "srcIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcSrcIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] ==
"Invalid field 'taker_pays.issuer', expected non-XRP issuer.");
@@ -1461,7 +1441,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'taker', not string.");
}
@@ -1474,7 +1453,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'taker'.");
}
@@ -1488,7 +1466,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "badMarket");
BEAST_EXPECT(jrr[jss::error_code] == RpcBadMarket);
BEAST_EXPECT(jrr[jss::error_message] == "No such market.");
}
@@ -1502,7 +1479,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'limit', not unsigned integer.");
}
@@ -1516,7 +1492,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'limit'.");
}
@@ -1528,7 +1503,6 @@ public:
jvParams[jss::taker_gets][jss::currency] = "USD";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "dstIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcDstIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] ==
"Invalid field 'taker_gets.issuer', "
@@ -1544,7 +1518,6 @@ public:
jvParams[jss::taker_gets][jss::issuer] = gw.human();
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "dstIsrMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcDstIsrMalformed);
BEAST_EXPECT(
jrr[jss::error_message] ==
"Unneeded field 'taker_gets.issuer' "
@@ -1560,7 +1533,6 @@ public:
jvParams[jss::domain] = "badString";
auto const jrr = env.rpc("json", "book_offers", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "domainMalformed");
BEAST_EXPECT(jrr[jss::error_code] == RpcDomainMalformed);
BEAST_EXPECT(jrr[jss::error_message] == "Unable to parse domain.");
}
}
Loaded 100 of 139 files, more files were not shown because too many files have changed in this diff. Show more