mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-22 03:27:08 +00:00
Compare commits
392
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9daf4cb52 | ||
|
|
60df4dc75c | ||
|
|
3608433514 | ||
|
|
ad3c2bda5c | ||
|
|
ac49c01dde | ||
|
|
9001749fc7 | ||
|
|
43915164bd | ||
|
|
199c9f6309 | ||
|
|
15ec84140c | ||
|
|
ef6b661d75 | ||
|
|
5a5330b2c8 | ||
|
|
b451cde787 | ||
|
|
beb8f6b3a2 | ||
|
|
80ba0ccd12 | ||
|
|
5eacc2e27e | ||
|
|
ad071f3cd3 | ||
|
|
3e2b40f92d | ||
|
|
e649e91a76 | ||
|
|
fca62622e9 | ||
|
|
7e98cc1777 | ||
|
|
2d8f92aba0 | ||
|
|
5b699f07e3 | ||
|
|
e4719e8230 | ||
|
|
277f486884 | ||
|
|
3c03945ae9 | ||
|
|
456f6a16aa | ||
|
|
a453b17cdc | ||
|
|
d877605e55 | ||
|
|
dfcde92c25 | ||
|
|
41bae9ce51 | ||
|
|
26ab790b71 | ||
|
|
625779954f | ||
|
|
336d5fb970 | ||
|
|
4918df605d | ||
|
|
76fc155243 | ||
|
|
74158c3175 | ||
|
|
d2dd019735 | ||
|
|
e91d5999ec | ||
|
|
814d14ad2b | ||
|
|
e7cfc46275 | ||
|
|
c3c555c260 | ||
|
|
3cc27a4a67 | ||
|
|
17bec9e4d4 | ||
|
|
0e54845db0 | ||
|
|
6f1f53a152 | ||
|
|
080ad9fe34 | ||
|
|
2620ae59ae | ||
|
|
d3d5f39787 | ||
|
|
77793df659 | ||
|
|
6abcc9fe1a | ||
|
|
e67e9f6660 | ||
|
|
6718b3276b | ||
|
|
642dbad885 | ||
|
|
833433b25e | ||
|
|
84e32ed33c | ||
|
|
23369e114a | ||
|
|
d3d0c6366a | ||
|
|
c15c7bfd54 | ||
|
|
af61140cd9 | ||
|
|
4e1de43939 | ||
|
|
dc71651429 | ||
|
|
e372201499 | ||
|
|
8b2a7f6253 | ||
|
|
6211dbd1cc | ||
|
|
d89063acae | ||
|
|
0e328d8277 | ||
|
|
7d55bb7d8e | ||
|
|
14c190fd31 | ||
|
|
efe843d6b2 | ||
|
|
41e422d2c1 | ||
|
|
7f10f3938f | ||
|
|
9c8b45f0ed | ||
|
|
f7e96beba7 | ||
|
|
5a7a715283 | ||
|
|
8f1974d0ec | ||
|
|
f84e07427c | ||
|
|
d375fa356f | ||
|
|
5d5e4d3405 | ||
|
|
1eacb33d72 | ||
|
|
fafc48bda3 | ||
|
|
9a2b6866a7 | ||
|
|
8a49f93b78 | ||
|
|
c5c85eef48 | ||
|
|
5aed870ff0 | ||
|
|
0fe2be63f4 | ||
|
|
4c93c8d5be | ||
|
|
5817d3547e | ||
|
|
7a8d86b0b1 | ||
|
|
1bbe54ad60 | ||
|
|
0bb9716784 | ||
|
|
295c71b007 | ||
|
|
78f3148e4c | ||
|
|
894263bb89 | ||
|
|
9de4e7e58d | ||
|
|
ec844351d9 | ||
|
|
41b4cf36e6 | ||
|
|
6f7ad510e3 | ||
|
|
5db10a4d3b | ||
|
|
919cfd5f49 | ||
|
|
476a64d5ce | ||
|
|
303952aeb4 | ||
|
|
85a6dfee1f | ||
|
|
621f876337 | ||
|
|
da2f36c8a6 | ||
|
|
fab69c28d2 | ||
|
|
afedf445f0 | ||
|
|
fe1b1c8f92 | ||
|
|
e61b134742 | ||
|
|
2ba3edaf14 | ||
|
|
7cf063b1d8 | ||
|
|
5f087f6446 | ||
|
|
a2446e8f99 | ||
|
|
6accc87a10 | ||
|
|
313d0d188b | ||
|
|
53dc3b4051 | ||
|
|
b589985dae | ||
|
|
180c979835 | ||
|
|
88665a6de0 | ||
|
|
66526a8a48 | ||
|
|
18c11097b6 | ||
|
|
bfe54849c9 | ||
|
|
831ac87627 | ||
|
|
1b7af3165d | ||
|
|
48ca6e0025 | ||
|
|
0047ed4db2 | ||
|
|
6dc73cb528 | ||
|
|
7f58c3d7d6 | ||
|
|
86f52c412c | ||
|
|
4dce2f22b6 | ||
|
|
fe8368b970 | ||
|
|
d68273c755 | ||
|
|
df489c7a6e | ||
|
|
b45038f70a | ||
|
|
44cc4e656f | ||
|
|
ac3435bf0a | ||
|
|
bd2f5dbd35 | ||
|
|
4644347d21 | ||
|
|
e34e05ebec | ||
|
|
9b22c6c80b | ||
|
|
d4e166bbdc | ||
|
|
b80776b0fe | ||
|
|
9af4fb521e | ||
|
|
7ee290674c | ||
|
|
68f050b186 | ||
|
|
2be13c18a1 | ||
|
|
df5fa5aade | ||
|
|
51ef3a7343 | ||
|
|
dd4eca22b7 | ||
|
|
1116dbfd0e | ||
|
|
258d5e1f1f | ||
|
|
4270367efc | ||
|
|
fad34e852d | ||
|
|
f5b4ac358f | ||
|
|
875bcc530e | ||
|
|
e75f5b101b | ||
|
|
95f74d61b2 | ||
|
|
4e12b787be | ||
|
|
8b6c80027b | ||
|
|
ace73678cf | ||
|
|
12bbba00b0 | ||
|
|
2affb66f50 | ||
|
|
d09e785c39 | ||
|
|
97fdf310f9 | ||
|
|
d3ce76825c | ||
|
|
1e7e274727 | ||
|
|
b272d71cc7 | ||
|
|
21268d9c36 | ||
|
|
932e22df7d | ||
|
|
652a7cd225 | ||
|
|
4a224dbfa4 | ||
|
|
d2a5981f87 | ||
|
|
a977836630 | ||
|
|
bf075200bb | ||
|
|
ee49e76a16 | ||
|
|
c1318990f3 | ||
|
|
69128294f8 | ||
|
|
149e884ebc | ||
|
|
d27353225c | ||
|
|
13a0f77eb5 | ||
|
|
549c093398 | ||
|
|
fb66ca7a2e | ||
|
|
e2af73b0a0 | ||
|
|
14c3c9a256 | ||
|
|
4b6851a287 | ||
|
|
d182673d24 | ||
|
|
bea609d805 | ||
|
|
56eeb20bc8 | ||
|
|
e293a3d918 | ||
|
|
3dff580d39 | ||
|
|
487f5a0fd3 | ||
|
|
d8134f98e9 | ||
|
|
450a623d4b | ||
|
|
9e517be4ce | ||
|
|
b8370438fb | ||
|
|
ecb5604d3b | ||
|
|
c4527e7b0f | ||
|
|
778e2b3ce8 | ||
|
|
295d03aec8 | ||
|
|
9262c2e624 | ||
|
|
b385a41aa5 | ||
|
|
4eb9726097 | ||
|
|
28a38ef1cc | ||
|
|
39f9380b2b | ||
|
|
239fcaceb4 | ||
|
|
8ab86f009e | ||
|
|
d4b58a74f4 | ||
|
|
ff900591ae | ||
|
|
a5b7471af6 | ||
|
|
e0734986dd | ||
|
|
8440f479e5 | ||
|
|
ac390622e0 | ||
|
|
5d807f0d6d | ||
|
|
b93294f26b | ||
|
|
ef95ace0f9 | ||
|
|
fc58bf6edf | ||
|
|
348555d5ba | ||
|
|
302802e42d | ||
|
|
5d881f87a3 | ||
|
|
a8a8035b32 | ||
|
|
45af14231f | ||
|
|
380bf274d0 | ||
|
|
460ec5eeea | ||
|
|
14be8ca4ea | ||
|
|
948264d44c | ||
|
|
9c816b2043 | ||
|
|
f68402acd1 | ||
|
|
5358e25eaa | ||
|
|
a34d1e5537 | ||
|
|
78a122943d | ||
|
|
06135e7203 | ||
|
|
f20425fa4f | ||
|
|
3e94546acc | ||
|
|
3b088ed0dc | ||
|
|
26182ed52e | ||
|
|
de2a3e10f5 | ||
|
|
e17f8554fc | ||
|
|
386a7192ba | ||
|
|
12cc6e424d | ||
|
|
c9deecf1b7 | ||
|
|
ddd1b49f38 | ||
|
|
c1b2a24005 | ||
|
|
86d88eca31 | ||
|
|
ef09eaea00 | ||
|
|
c504cfb291 | ||
|
|
0c217dfa2b | ||
|
|
b0198d2566 | ||
|
|
7eee8ca802 | ||
|
|
2a079a0154 | ||
|
|
40989c1178 | ||
|
|
addc831eb3 | ||
|
|
b4efc6d116 | ||
|
|
125d075d6e | ||
|
|
370a775479 | ||
|
|
1a2ee706eb | ||
|
|
2a981357ba | ||
|
|
1ae475e724 | ||
|
|
a3e9401fbc | ||
|
|
9091469f9e | ||
|
|
17fa54f1f9 | ||
|
|
8fb5347c2d | ||
|
|
6739bf998f | ||
|
|
6eea38ba67 | ||
|
|
e9cf88b359 | ||
|
|
645b203476 | ||
|
|
be2aff1f4c | ||
|
|
56ed237e82 | ||
|
|
fd7b0fd135 | ||
|
|
e700994891 | ||
|
|
c76f7029ac | ||
|
|
d535c5fb2a | ||
|
|
54f860463e | ||
|
|
950434b8ff | ||
|
|
ee365e876d | ||
|
|
c6c59834b9 | ||
|
|
63b47914b8 | ||
|
|
9e02e5be2e | ||
|
|
093cd70fa1 | ||
|
|
376d65a483 | ||
|
|
a0d9a2458e | ||
|
|
456f639cf7 | ||
|
|
2c559ec2f3 | ||
|
|
619c81f463 | ||
|
|
f1490df960 | ||
|
|
7bdf74de98 | ||
|
|
1743d6fb98 | ||
|
|
ca7a5bb926 | ||
|
|
ce8b1a3f1e | ||
|
|
486fa75a10 | ||
|
|
f8d68cd3d3 | ||
|
|
ef7a3f5606 | ||
|
|
4f84ed7490 | ||
|
|
d534103131 | ||
|
|
82dff3c2ce | ||
|
|
30d73eb5ba | ||
|
|
1b2754bac2 | ||
|
|
cf80cafc75 | ||
|
|
b8897d51de | ||
|
|
3ff25eeb65 | ||
|
|
2bbfc4e786 | ||
|
|
2b1eb052e6 | ||
|
|
360e214e54 | ||
|
|
2618afed94 | ||
|
|
698ba2c788 | ||
|
|
b614e99588 | ||
|
|
fe8e4af2fa | ||
|
|
0a897f1528 | ||
|
|
cf8a3f5779 | ||
|
|
db39a39868 | ||
|
|
37a03d28c2 | ||
|
|
19d275425a | ||
|
|
88e9045602 | ||
|
|
5adbc536b6 | ||
|
|
e27af94ba9 | ||
|
|
43fe1e7e9c | ||
|
|
f456a858c8 | ||
|
|
084c3aa88e | ||
|
|
34f9b63921 | ||
|
|
bd3de79817 | ||
|
|
304eee2259 | ||
|
|
9e729b7f59 | ||
|
|
dd141468c4 | ||
|
|
933147c21f | ||
|
|
9201a4f591 | ||
|
|
5adb1e9b8b | ||
|
|
4df84d7988 | ||
|
|
cd87c0968b | ||
|
|
8a8e7c90bf | ||
|
|
e806069065 | ||
|
|
ce948cbec0 | ||
|
|
6ed34b3294 | ||
|
|
7161a235ca | ||
|
|
71463810de | ||
|
|
e997219a85 | ||
|
|
895cc13fa6 | ||
|
|
8d3c3ca29a | ||
|
|
9829553807 | ||
|
|
e551f9731a | ||
|
|
fd827bf58b | ||
|
|
5a3baba34d | ||
|
|
c78f5b160f | ||
|
|
485f78761a | ||
|
|
23cd2f7b21 | ||
|
|
5753266c43 | ||
|
|
4722d2607d | ||
|
|
85b5b4f855 | ||
|
|
a16f492f0f | ||
|
|
3633dc632c | ||
|
|
b3b30c3a86 | ||
|
|
c78a7684f4 | ||
|
|
cf83d92630 | ||
|
|
a56b1274d8 | ||
|
|
ae4bdd0492 | ||
|
|
e90102dd3b | ||
|
|
71f0e8db3d | ||
|
|
638929373a | ||
|
|
8440654377 | ||
|
|
9fa66c4741 | ||
|
|
38a9235145 | ||
|
|
c7a3cc9108 | ||
|
|
248337908d | ||
|
|
3d003619fd | ||
|
|
f163dca12c | ||
|
|
6e0ce458e5 | ||
|
|
5fae8480f1 | ||
|
|
e6587d374a | ||
|
|
376cc404e0 | ||
|
|
9898ca638f | ||
|
|
34b46d8f7c | ||
|
|
fe7d0798a7 | ||
|
|
0cecc09d71 | ||
|
|
e091d55561 | ||
|
|
69cf18158b | ||
|
|
6513c53817 | ||
|
|
e13baa58a5 | ||
|
|
951056fe9b | ||
|
|
67700ea6bd | ||
|
|
e5442cf3f1 | ||
|
|
da68076f04 | ||
|
|
b24116a118 | ||
|
|
f67398c6bf | ||
|
|
43d3eb1a24 | ||
|
|
0993315ed5 | ||
|
|
0bc383ada9 | ||
|
|
1841ceca43 | ||
|
|
2714cebabd | ||
|
|
e184db4ce2 | ||
|
|
ac6dc6943c | ||
|
|
ddd53806df | ||
|
|
e629a1f70e | ||
|
|
68076d969c | ||
|
|
d3009d3e1c | ||
|
|
54f7f3c894 |
No files matched your search
@@ -1123,7 +1123,8 @@
|
||||
# online deletion gives up on the current ledger and tries
|
||||
# again later. Note this only affects situations that cause
|
||||
# rotation to wait, such as going out of sync, or missing
|
||||
# ledgers. Forward progress is not penalized. Minimum is 64.
|
||||
# ledgers. Forward progress is not penalized. Minimum in
|
||||
# normal operation is 64. Minimum in standalone mode is 2.
|
||||
# Default is the online_delete value.
|
||||
#
|
||||
# Notes:
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
#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
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/enum_bitops.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/OwnerCounts.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -22,39 +22,80 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class ApplyFlags : std::uint32_t {
|
||||
None = 0x00,
|
||||
// Bitwise flag enum with existing operator overloads
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum ApplyFlags : std::uint32_t {
|
||||
TapNone = 0x00,
|
||||
|
||||
// This is a local transaction with the
|
||||
// fail_hard flag set.
|
||||
FailHard = 0x10,
|
||||
TapFailHard = 0x10,
|
||||
|
||||
// This is not the transaction's last pass
|
||||
// Transaction can be retried, soft failures allowed
|
||||
Retry = 0x20,
|
||||
TapRetry = 0x20,
|
||||
|
||||
// Transaction came from a privileged source
|
||||
Unlimited = 0x400,
|
||||
TapUnlimited = 0x400,
|
||||
|
||||
// Transaction is executing as part of a batch
|
||||
Batch = 0x800,
|
||||
TapBatch = 0x800,
|
||||
|
||||
// Transaction shouldn't be applied
|
||||
// Signatures shouldn't be checked
|
||||
DryRun = 0x1000,
|
||||
TapDryRun = 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).
|
||||
Proposal = 0x2000,
|
||||
TapProposal = 0x2000,
|
||||
};
|
||||
|
||||
template <>
|
||||
struct enum_bitops::OptIn<ApplyFlags> : std::true_type
|
||||
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) == 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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/nodestore/Database.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -54,6 +55,12 @@ public:
|
||||
*/
|
||||
virtual void
|
||||
setRotationInFlight(bool inFlight) = 0;
|
||||
virtual bool
|
||||
isRotationInFlight() const = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual std::uint64_t
|
||||
getAndResetDuplicationCount() = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl::node_store
|
||||
@@ -72,19 +72,28 @@ public:
|
||||
|
||||
void
|
||||
setRotationInFlight(bool inFlight) override;
|
||||
bool
|
||||
isRotationInFlight() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
std::uint64_t
|
||||
getAndResetDuplicationCount() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Backend> writableBackend_;
|
||||
std::shared_ptr<Backend> archiveBackend_;
|
||||
mutable std::mutex mutex_;
|
||||
|
||||
// True between SHAMapStore starting the cache-freshen phase and the
|
||||
// completion of rotate(). While true, archive hits on ordinary
|
||||
// (duplicate == false) fetches are copied forward into the writable
|
||||
// backend; copyForwardCount_ tallies them per rotation for the
|
||||
// Set to true during the entire SHAMapStore rotation process.
|
||||
// While true, archive hits on ordinary (duplicate == false)
|
||||
// fetches are copied forward into the writable backend.
|
||||
// copyForwardCount_ tallies them per rotation for the
|
||||
// summary line logged at swap.
|
||||
std::atomic<bool> rotationInFlight_{false};
|
||||
std::atomic<std::uint64_t> copyForwardCount_{0};
|
||||
// Duplication count tracks the number of nodes that are directly duplicated because they're in
|
||||
// the target ledger or rescued from a cache.
|
||||
std::atomic<std::uint64_t> duplicationCount_{0};
|
||||
|
||||
std::shared_ptr<NodeObject>
|
||||
fetchNodeObject(UInt256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#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>
|
||||
@@ -17,43 +15,37 @@
|
||||
#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>
|
||||
{
|
||||
STPathElementType type_ = STPathElementType::None;
|
||||
bool isOffer_ = true;
|
||||
unsigned int type_;
|
||||
AccountID accountID_;
|
||||
PathAsset assetID_;
|
||||
AccountID issuerID_;
|
||||
|
||||
bool isOffer_;
|
||||
std::size_t hashValue_;
|
||||
|
||||
public:
|
||||
STPathElement() = default;
|
||||
// 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(STPathElement const&) = default;
|
||||
STPathElement&
|
||||
operator=(STPathElement const&) = default;
|
||||
@@ -70,42 +62,42 @@ public:
|
||||
bool forceAsset = false);
|
||||
|
||||
STPathElement(
|
||||
STPathElementType type,
|
||||
unsigned int uType,
|
||||
AccountID const& account,
|
||||
PathAsset const& asset,
|
||||
AccountID const& issuer);
|
||||
|
||||
[[nodiscard]] STPathElementType
|
||||
getNodeType() const noexcept;
|
||||
[[nodiscard]] std::uint32_t
|
||||
getNodeType() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isOffer() const noexcept;
|
||||
isOffer() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isAccount() const noexcept;
|
||||
isAccount() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasIssuer() const noexcept;
|
||||
hasIssuer() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasCurrency() const noexcept;
|
||||
hasCurrency() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasMPT() const noexcept;
|
||||
hasMPT() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasAsset() const noexcept;
|
||||
hasAsset() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isNone() const noexcept;
|
||||
isNone() const;
|
||||
|
||||
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
|
||||
// class of offers.
|
||||
[[nodiscard]] AccountID const&
|
||||
getAccountID() const noexcept;
|
||||
getAccountID() const;
|
||||
|
||||
[[nodiscard]] PathAsset const&
|
||||
getPathAsset() const noexcept;
|
||||
getPathAsset() const;
|
||||
|
||||
[[nodiscard]] Currency const&
|
||||
getCurrency() const;
|
||||
@@ -114,18 +106,17 @@ public:
|
||||
getMPTID() const;
|
||||
|
||||
[[nodiscard]] AccountID const&
|
||||
getIssuerID() const noexcept;
|
||||
getIssuerID() const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isType(STPathElementType pe) const noexcept;
|
||||
isType(Type const& pe) const;
|
||||
|
||||
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_;
|
||||
}
|
||||
bool
|
||||
operator==(STPathElement const& t) const;
|
||||
|
||||
private:
|
||||
static std::size_t
|
||||
getHash(STPathElement const& element);
|
||||
};
|
||||
|
||||
template <class Hasher>
|
||||
@@ -133,7 +124,7 @@ void
|
||||
hash_append(Hasher& h, STPathElement const& e) noexcept
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append(h, e.isType(STPathElementType::Account));
|
||||
hash_append(h, (e.getNodeType() & STPathElement::TypeAccount) != 0u);
|
||||
hash_append(h, e.getAccountID());
|
||||
hash_append(h, e.getPathAsset());
|
||||
hash_append(h, e.getIssuerID());
|
||||
@@ -346,16 +337,29 @@ 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)
|
||||
if (!account)
|
||||
{
|
||||
isOffer_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isOffer_ = false;
|
||||
accountID_ = *account;
|
||||
type_ |= STPathElementType::Account;
|
||||
type_ |= TypeAccount;
|
||||
XRPL_ASSERT(
|
||||
accountID_ != noAccount(), "xrpl::STPathElement::STPathElement : account is set");
|
||||
}
|
||||
@@ -363,15 +367,17 @@ inline STPathElement::STPathElement(
|
||||
if (asset)
|
||||
{
|
||||
assetID_ = *asset;
|
||||
type_ |= assetID_.holds<Currency>() ? STPathElementType::Currency : STPathElementType::Mpt;
|
||||
type_ |= assetID_.holds<Currency>() ? TypeCurrency : TypeMpt;
|
||||
}
|
||||
|
||||
if (issuer)
|
||||
{
|
||||
issuerID_ = *issuer;
|
||||
type_ |= STPathElementType::Issuer;
|
||||
type_ |= TypeIssuer;
|
||||
XRPL_ASSERT(issuerID_ != noAccount(), "xrpl::STPathElement::STPathElement : issuer is set");
|
||||
}
|
||||
|
||||
hashValue_ = getHash(*this);
|
||||
}
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
@@ -379,94 +385,108 @@ inline STPathElement::STPathElement(
|
||||
PathAsset const& asset,
|
||||
AccountID const& issuer,
|
||||
bool forceAsset)
|
||||
: isOffer_(isXRP(account)), accountID_(account), assetID_(asset), issuerID_(issuer)
|
||||
: type_(TypeNone)
|
||||
, accountID_(account)
|
||||
, assetID_(asset)
|
||||
, issuerID_(issuer)
|
||||
, isOffer_(isXRP(accountID_))
|
||||
{
|
||||
if (!isOffer_)
|
||||
type_ |= STPathElementType::Account;
|
||||
type_ |= TypeAccount;
|
||||
|
||||
if (forceAsset || !isXRP(assetID_))
|
||||
type_ |= asset.holds<Currency>() ? STPathElementType::Currency : STPathElementType::Mpt;
|
||||
type_ |= asset.holds<Currency>() ? TypeCurrency : TypeMpt;
|
||||
|
||||
if (!isXRP(issuer))
|
||||
type_ |= STPathElementType::Issuer;
|
||||
type_ |= TypeIssuer;
|
||||
|
||||
hashValue_ = getHash(*this);
|
||||
}
|
||||
|
||||
inline STPathElement::STPathElement(
|
||||
STPathElementType type,
|
||||
unsigned int uType,
|
||||
AccountID const& account,
|
||||
PathAsset const& asset,
|
||||
AccountID const& issuer)
|
||||
: type_(type), isOffer_(isXRP(account)), accountID_(account), assetID_(asset), issuerID_(issuer)
|
||||
: type_(uType)
|
||||
, accountID_(account)
|
||||
, assetID_(asset)
|
||||
, issuerID_(issuer)
|
||||
, isOffer_(isXRP(accountID_))
|
||||
{
|
||||
assetID_.visit(
|
||||
[&](Currency const&) { type_ &= ~STPathElementType::Mpt; },
|
||||
[&](MPTID const&) { type_ &= ~STPathElementType::Currency; });
|
||||
[&](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);
|
||||
}
|
||||
|
||||
inline STPathElementType
|
||||
STPathElement::getNodeType() const noexcept
|
||||
inline std::uint32_t
|
||||
STPathElement::getNodeType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isOffer() const noexcept
|
||||
STPathElement::isOffer() const
|
||||
{
|
||||
return isOffer_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isAccount() const noexcept
|
||||
STPathElement::isAccount() const
|
||||
{
|
||||
return !isOffer();
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isType(STPathElementType pe) const noexcept
|
||||
STPathElement::isType(Type const& pe) const
|
||||
{
|
||||
return (type_ & pe) != STPathElementType::None;
|
||||
return (type_ & pe) != 0u;
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasIssuer() const noexcept
|
||||
STPathElement::hasIssuer() const
|
||||
{
|
||||
return isType(STPathElementType::Issuer);
|
||||
return isType(STPathElement::TypeIssuer);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasCurrency() const noexcept
|
||||
STPathElement::hasCurrency() const
|
||||
{
|
||||
return isType(STPathElementType::Currency);
|
||||
return isType(STPathElement::TypeCurrency);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasMPT() const noexcept
|
||||
STPathElement::hasMPT() const
|
||||
{
|
||||
return isType(STPathElementType::Mpt);
|
||||
return isType(STPathElement::TypeMpt);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::hasAsset() const noexcept
|
||||
STPathElement::hasAsset() const
|
||||
{
|
||||
return isType(STPathElementType::Asset);
|
||||
return isType(STPathElement::TypeAsset);
|
||||
}
|
||||
|
||||
inline bool
|
||||
STPathElement::isNone() const noexcept
|
||||
STPathElement::isNone() const
|
||||
{
|
||||
return getNodeType() == STPathElementType::None;
|
||||
return getNodeType() == STPathElement::TypeNone;
|
||||
}
|
||||
|
||||
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
|
||||
// class of offers.
|
||||
inline AccountID const&
|
||||
STPathElement::getAccountID() const noexcept
|
||||
STPathElement::getAccountID() const
|
||||
{
|
||||
return accountID_;
|
||||
}
|
||||
|
||||
inline PathAsset const&
|
||||
STPathElement::getPathAsset() const noexcept
|
||||
STPathElement::getPathAsset() const
|
||||
{
|
||||
return assetID_;
|
||||
}
|
||||
@@ -484,11 +504,18 @@ STPathElement::getMPTID() const
|
||||
}
|
||||
|
||||
inline AccountID const&
|
||||
STPathElement::getIssuerID() const noexcept
|
||||
STPathElement::getIssuerID() const
|
||||
{
|
||||
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))
|
||||
|
||||
@@ -51,8 +51,7 @@ public:
|
||||
beast::Journal journal = beast::Journal{beast::Journal::getNullSink()})
|
||||
: ApplyContext(registry, base, std::nullopt, tx, preclaimResult, baseFee, flags, journal)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(flags & ApplyFlags::Batch) == ApplyFlags::None, "Batch apply flag should not be set");
|
||||
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
|
||||
}
|
||||
|
||||
std::reference_wrapper<ServiceRegistry> registry;
|
||||
|
||||
@@ -59,11 +59,10 @@ public:
|
||||
, parentBatchId(parentBatchId)
|
||||
, j(j)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(flags & ApplyFlags::Batch) == ApplyFlags::Batch, "Batch apply flag should be set");
|
||||
XRPL_ASSERT((flags & TapBatch) == TapBatch, "Batch apply flag should be set");
|
||||
XRPL_ASSERT_IF(
|
||||
(flags & ApplyFlags::Proposal) != ApplyFlags::None,
|
||||
(flags & ApplyFlags::DryRun) != ApplyFlags::None,
|
||||
(flags & TapProposal) != TapNone,
|
||||
(flags & TapDryRun) != TapNone,
|
||||
"xrpl::PreflightContext : proposal preflight implies dry run");
|
||||
}
|
||||
|
||||
@@ -75,11 +74,10 @@ public:
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: registry(registry), tx(tx), rules(std::move(rules)), flags(flags), j(j)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(flags & ApplyFlags::Batch) == ApplyFlags::None, "Batch apply flag should not be set");
|
||||
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
|
||||
XRPL_ASSERT_IF(
|
||||
(flags & ApplyFlags::Proposal) != ApplyFlags::None,
|
||||
(flags & ApplyFlags::DryRun) != ApplyFlags::None,
|
||||
(flags & TapProposal) != TapNone,
|
||||
(flags & TapDryRun) != TapNone,
|
||||
"xrpl::PreflightContext : proposal preflight implies dry run");
|
||||
}
|
||||
|
||||
@@ -118,7 +116,7 @@ public:
|
||||
, j(j)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
parentBatchId.has_value() == ((flags & ApplyFlags::Batch) == ApplyFlags::Batch),
|
||||
parentBatchId.has_value() == ((flags & TapBatch) == TapBatch),
|
||||
"Parent Batch ID should be set if batch apply flag is set");
|
||||
}
|
||||
|
||||
@@ -131,8 +129,7 @@ public:
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: PreclaimContext(registry, view, preflightResult, tx, flags, std::nullopt, j)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(flags & ApplyFlags::Batch) == ApplyFlags::None, "Batch apply flag should not be set");
|
||||
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
|
||||
}
|
||||
|
||||
PreclaimContext&
|
||||
|
||||
@@ -41,7 +41,7 @@ struct ApplyResult
|
||||
inline bool
|
||||
isTecClaimHardFail(TER ter, ApplyFlags flags)
|
||||
{
|
||||
return isTecClaim(ter) && ((flags & ApplyFlags::Retry) == ApplyFlags::None);
|
||||
return isTecClaim(ter) && ((flags & TapRetry) == 0u);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,6 +54,7 @@ DatabaseRotatingImp::rotate(
|
||||
// deleted.
|
||||
std::shared_ptr<node_store::Backend> oldArchiveBackend;
|
||||
std::uint64_t copyForwards = 0;
|
||||
std::uint64_t duplications = 0;
|
||||
{
|
||||
std::scoped_lock const lock(mutex_);
|
||||
|
||||
@@ -66,6 +67,7 @@ DatabaseRotatingImp::rotate(
|
||||
writableBackend_ = std::move(newBackend);
|
||||
|
||||
copyForwards = copyForwardCount_.exchange(0, std::memory_order_relaxed);
|
||||
duplications = duplicationCount_.exchange(0, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
if (copyForwards > 0)
|
||||
@@ -74,6 +76,11 @@ DatabaseRotatingImp::rotate(
|
||||
<< " archive-served reads into the writable backend "
|
||||
"during the rotation window";
|
||||
}
|
||||
if (duplications > 0)
|
||||
{
|
||||
JLOG(j_.warn()) << "Rotating: duplicated " << duplications
|
||||
<< " nodes into the writable backend for the relevant cache.";
|
||||
}
|
||||
|
||||
f(newWritableBackendName, newArchiveBackendName);
|
||||
}
|
||||
@@ -86,6 +93,22 @@ DatabaseRotatingImp::setRotationInFlight(bool inFlight)
|
||||
<< (inFlight ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseRotatingImp::isRotationInFlight() const
|
||||
{
|
||||
return rotationInFlight_.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
std::uint64_t
|
||||
DatabaseRotatingImp::getAndResetDuplicationCount()
|
||||
{
|
||||
std::uint64_t duplications = 0;
|
||||
duplications = duplicationCount_.exchange(0, std::memory_order_relaxed);
|
||||
|
||||
return duplications;
|
||||
}
|
||||
|
||||
std::string
|
||||
DatabaseRotatingImp::getName() const
|
||||
{
|
||||
@@ -186,26 +209,35 @@ DatabaseRotatingImp::fetchNodeObject(
|
||||
nodeObject = fetch(writable);
|
||||
if (!nodeObject)
|
||||
{
|
||||
// While a rotation is in flight, ordinary (duplicate == false)
|
||||
// reads served by the archive are copied forward too: the
|
||||
// archive is about to be deleted, and a body canonicalized
|
||||
// into the cache after the freshen getKeys() snapshot would
|
||||
// otherwise survive only in RAM once the archive is dropped.
|
||||
auto const inFlight = isRotationInFlight();
|
||||
|
||||
// Otherwise try to fetch from the archive backend
|
||||
nodeObject = fetch(archive);
|
||||
if (nodeObject)
|
||||
{
|
||||
{
|
||||
// Refresh the writable backend pointer
|
||||
std::scoped_lock const lock(mutex_);
|
||||
writable = writableBackend_;
|
||||
}
|
||||
|
||||
// Update writable backend with data from the archive backend.
|
||||
// While a rotation is in flight, ordinary (duplicate == false)
|
||||
// reads served by the archive are copied forward too: the
|
||||
// archive is about to be deleted, and a body canonicalized
|
||||
// into the cache after the freshen getKeys() snapshot would
|
||||
// otherwise survive only in RAM once the archive is dropped.
|
||||
if (duplicate || rotationInFlight_.load(std::memory_order_acquire))
|
||||
// Check isRotationInFlight again, because it may have been set since the first check.
|
||||
if (duplicate || inFlight || isRotationInFlight())
|
||||
{
|
||||
if (!duplicate)
|
||||
{
|
||||
// Refresh the writable backend pointer since we need to use it
|
||||
std::scoped_lock const lock(mutex_);
|
||||
writable = writableBackend_;
|
||||
}
|
||||
|
||||
if (duplicate)
|
||||
{
|
||||
duplicationCount_.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
else
|
||||
{
|
||||
copyForwardCount_.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
writable->store(nodeObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#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/basics/safe_cast.h>
|
||||
#include <xrpl/beast/hash/uhash.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -16,9 +17,7 @@
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
@@ -26,6 +25,41 @@
|
||||
|
||||
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?
|
||||
@@ -74,57 +108,62 @@ STPathSet::operator=(STPathSet const& other)
|
||||
STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name)
|
||||
{
|
||||
std::vector<STPathElement> path;
|
||||
|
||||
STPathElementType type = STPathElementType::None;
|
||||
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
type = safeCast<STPathElementType>(sit.get8());
|
||||
int const iType = sit.get8();
|
||||
|
||||
if (type == STPathElementType::None || type == STPathElementType::Boundary)
|
||||
if (iType == STPathElement::TypeNone || iType == STPathElement::TypeBoundary)
|
||||
{
|
||||
if (path.empty())
|
||||
Throw<std::runtime_error>("bad path element: empty path");
|
||||
{
|
||||
JLOG(debugLog().error()) << "Empty path in pathset";
|
||||
Throw<std::runtime_error>("empty path");
|
||||
}
|
||||
|
||||
// Move rather than converting the vector to an STPath by copy.
|
||||
value_.emplace_back(std::move(path));
|
||||
path.clear();
|
||||
|
||||
continue;
|
||||
if (iType == STPathElement::TypeNone)
|
||||
return;
|
||||
}
|
||||
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;
|
||||
|
||||
if ((type & ~STPathElementType::All) != STPathElementType::None)
|
||||
Throw<std::runtime_error>(
|
||||
std::format("bad path element: <{:#04x}>", std::to_underlying(type)));
|
||||
AccountID account;
|
||||
PathAsset asset;
|
||||
AccountID issuer;
|
||||
|
||||
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 (hasAccount)
|
||||
account = sit.get160();
|
||||
|
||||
if (hasCurrency && hasMPT)
|
||||
Throw<std::runtime_error>("bad path element: MPT and Currency");
|
||||
if (hasCurrency && hasMPT)
|
||||
{
|
||||
JLOG(debugLog().error()) << "Bad path element MPT and Currency in pathset";
|
||||
Throw<std::runtime_error>("bad path element: MPT and Currency");
|
||||
}
|
||||
|
||||
AccountID account;
|
||||
PathAsset asset;
|
||||
AccountID issuer;
|
||||
if (hasCurrency)
|
||||
asset = Currency::fromRaw(sit.get160());
|
||||
|
||||
if (hasAccount)
|
||||
account = sit.get160();
|
||||
if (hasMPT)
|
||||
asset = sit.get192();
|
||||
|
||||
if (hasCurrency)
|
||||
asset = Currency::fromRaw(sit.get160());
|
||||
if (hasIssuer)
|
||||
issuer = sit.get160();
|
||||
|
||||
if (hasMPT)
|
||||
asset = sit.get192();
|
||||
|
||||
if (hasIssuer)
|
||||
issuer = sit.get160();
|
||||
|
||||
path.emplace_back(account, asset, issuer, hasCurrency || hasMPT);
|
||||
|
||||
} while (type != STPathElementType::None);
|
||||
path.emplace_back(account, asset, issuer, hasCurrency || hasMPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STBase*
|
||||
@@ -178,22 +217,24 @@ STPath::getJson(JsonOptions) const
|
||||
for (auto const& it : path_)
|
||||
{
|
||||
json::Value elem(json::ValueType::Object);
|
||||
auto const iType = it.getNodeType();
|
||||
|
||||
elem[jss::type] = safeCast<std::uint32_t>(it.getNodeType());
|
||||
elem[jss::type] = iType;
|
||||
|
||||
if (it.isType(STPathElementType::Account))
|
||||
if ((iType & STPathElement::TypeAccount) != 0u)
|
||||
elem[jss::account] = to_string(it.getAccountID());
|
||||
|
||||
XRPL_ASSERT(
|
||||
!(it.hasCurrency() && it.hasMPT()),
|
||||
((iType & STPathElement::TypeCurrency) == 0u) ||
|
||||
((iType & STPathElement::TypeMpt) == 0u),
|
||||
"xrpl::STPath::getJson : not type Currency and MPT");
|
||||
if (it.hasCurrency())
|
||||
if ((iType & STPathElement::TypeCurrency) != 0u)
|
||||
elem[jss::currency] = to_string(it.getCurrency());
|
||||
|
||||
if (it.hasMPT())
|
||||
if ((iType & STPathElement::TypeMpt) != 0u)
|
||||
elem[jss::mpt_issuance_id] = to_string(it.getMPTID());
|
||||
|
||||
if (it.hasIssuer())
|
||||
if ((iType & STPathElement::TypeIssuer) != 0u)
|
||||
elem[jss::issuer] = to_string(it.getIssuerID());
|
||||
|
||||
ret.append(elem);
|
||||
@@ -225,42 +266,34 @@ 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(toByte(STPathElementType::Boundary));
|
||||
s.add8(STPathElement::TypeBoundary);
|
||||
|
||||
for (auto const& speElement : spPath)
|
||||
{
|
||||
s.add8(toByte(speElement.getNodeType()));
|
||||
int const iType = speElement.getNodeType();
|
||||
|
||||
if (speElement.isType(STPathElementType::Account))
|
||||
s.add8(iType);
|
||||
|
||||
if ((iType & STPathElement::TypeAccount) != 0u)
|
||||
s.addBitString(speElement.getAccountID());
|
||||
|
||||
if (speElement.hasMPT())
|
||||
if ((iType & STPathElement::TypeMpt) != 0u)
|
||||
s.addBitString(speElement.getMPTID());
|
||||
|
||||
if (speElement.hasCurrency())
|
||||
if ((iType & STPathElement::TypeCurrency) != 0u)
|
||||
s.addBitString(speElement.getCurrency());
|
||||
|
||||
if (speElement.hasIssuer())
|
||||
if ((iType & STPathElement::TypeIssuer) != 0u)
|
||||
s.addBitString(speElement.getIssuerID());
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
s.add8(toByte(STPathElementType::None));
|
||||
s.add8(STPathElement::TypeNone);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -38,7 +38,7 @@ ApplyContext::ApplyContext(
|
||||
, parentBatchId_(parentBatchId)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
parentBatchId.has_value() == ((flags_ & ApplyFlags::Batch) == ApplyFlags::Batch),
|
||||
parentBatchId.has_value() == ((flags_ & TapBatch) == TapBatch),
|
||||
"Parent Batch ID should be set if batch apply flag is set");
|
||||
view_.emplace(&base_, flags_);
|
||||
}
|
||||
@@ -53,14 +53,13 @@ std::optional<TxMeta>
|
||||
ApplyContext::apply(TER ter)
|
||||
{
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) view_ emplaced in constructor
|
||||
return view_->apply(
|
||||
base_, tx, ter, parentBatchId_, (flags_ & ApplyFlags::DryRun) != ApplyFlags::None, journal);
|
||||
return view_->apply(base_, tx, ter, parentBatchId_, (flags_ & TapDryRun) != 0u, journal);
|
||||
}
|
||||
|
||||
void
|
||||
ApplyContext::addOrderBook(Book const& book)
|
||||
{
|
||||
if ((flags_ & ApplyFlags::DryRun) == ApplyFlags::None)
|
||||
if ((flags_ & TapDryRun) == TapNone)
|
||||
registry.get().getOrderBookDB().addOrderBook(book);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 & ApplyFlags::DryRun) != ApplyFlags::None) // simulation
|
||||
if ((flags & TapDryRun) != 0u) // simulation
|
||||
{
|
||||
std::optional<Slice> const signature = sigObject[~sfTxnSignature];
|
||||
if (signature && !signature->empty())
|
||||
@@ -510,8 +510,7 @@ Transactor::minimumFee(
|
||||
Fees const& fees,
|
||||
ApplyFlags flags)
|
||||
{
|
||||
return scaleFeeLoad(
|
||||
baseFee, registry.getFeeTrack(), fees, (flags & ApplyFlags::Unlimited) != ApplyFlags::None);
|
||||
return scaleFeeLoad(baseFee, registry.getFeeTrack(), fees, (flags & TapUnlimited) != 0u);
|
||||
}
|
||||
|
||||
TER
|
||||
@@ -522,7 +521,7 @@ Transactor::checkFee(PreclaimContext const& ctx, XRPAmount baseFee)
|
||||
|
||||
auto const feePaid = ctx.tx[sfFee].xrp();
|
||||
|
||||
if ((ctx.flags & ApplyFlags::Batch) != ApplyFlags::None)
|
||||
if ((ctx.flags & TapBatch) != 0u)
|
||||
{
|
||||
if (feePaid == beast::kZero)
|
||||
return tesSUCCESS;
|
||||
@@ -985,8 +984,7 @@ Transactor::checkSign(
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
if (((flags & ApplyFlags::DryRun) != ApplyFlags::None) && pkSigner.empty() &&
|
||||
!sigObject.isFieldPresent(sfSigners))
|
||||
if (((flags & TapDryRun) != 0u) && pkSigner.empty() && !sigObject.isFieldPresent(sfSigners))
|
||||
{
|
||||
// simulate: skip signature validation when neither SigningPubKey nor
|
||||
// Signers are provided
|
||||
@@ -1157,7 +1155,7 @@ Transactor::checkMultiSign(
|
||||
}
|
||||
|
||||
XRPL_ASSERT(
|
||||
(flags & ApplyFlags::DryRun) != ApplyFlags::None || !spk.empty(),
|
||||
(flags & TapDryRun) || !spk.empty(),
|
||||
"xrpl::Transactor::checkMultiSign : non-empty signer or "
|
||||
"simulation");
|
||||
AccountID const signingAcctIDFromPubKey =
|
||||
@@ -1645,7 +1643,7 @@ Transactor::operator()()
|
||||
if (ctx_.size() > kOversizeMetaDataCap)
|
||||
result = tecOVERSIZE;
|
||||
|
||||
if (isTecClaim(result) && ((view().flags() & ApplyFlags::FailHard) != ApplyFlags::None))
|
||||
if (isTecClaim(result) && ((view().flags() & TapFailHard) != 0u))
|
||||
{
|
||||
// If the TapFailHard flag is set, a tec result
|
||||
// must not do anything
|
||||
@@ -1725,7 +1723,7 @@ Transactor::operator()()
|
||||
// Once we call apply, we will no longer be able to look at view()
|
||||
metadata = ctx_.apply(result);
|
||||
|
||||
if ((ctx_.flags() & ApplyFlags::DryRun) != ApplyFlags::None)
|
||||
if ((ctx_.flags() & TapDryRun) != 0u)
|
||||
return logger(result, false, std::move(metadata));
|
||||
|
||||
return logger(result, canApply, std::move(metadata));
|
||||
|
||||
@@ -215,7 +215,7 @@ applyBatchTransactions(
|
||||
auto const applyOneTransaction = [®istry, &j, &parentBatchId, &batchView](STTx const& tx) {
|
||||
OpenView perTxBatchView(kBatchView, batchView);
|
||||
|
||||
auto const ret = apply(registry, perTxBatchView, parentBatchId, tx, ApplyFlags::Batch, j);
|
||||
auto const ret = apply(registry, perTxBatchView, parentBatchId, tx, TapBatch, 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 | ApplyFlags::Retry;
|
||||
flags = flags | TapRetry;
|
||||
|
||||
JLOG(j.debug()) << "TXN " << txn.getTransactionID() << (retryAssured ? "/retry" : "/final");
|
||||
|
||||
|
||||
@@ -348,8 +348,7 @@ 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 & ApplyFlags::Proposal) != ApplyFlags::None &&
|
||||
(flags & ApplyFlags::DryRun) == ApplyFlags::None)
|
||||
if ((flags & TapProposal) != TapNone && (flags & TapDryRun) == TapNone)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.fatal()) << "apply (preflight): TapProposal set without TapDryRun.";
|
||||
@@ -380,8 +379,7 @@ preflight(
|
||||
PreflightContext const pfCtx(registry, tx, parentBatchId, rules, flags, j);
|
||||
|
||||
// See the comment in the other preflight() overload above.
|
||||
if ((flags & ApplyFlags::Proposal) != ApplyFlags::None &&
|
||||
(flags & ApplyFlags::DryRun) == ApplyFlags::None)
|
||||
if ((flags & TapProposal) != TapNone && (flags & TapDryRun) == TapNone)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.fatal()) << "apply (preflight): TapProposal set without TapDryRun.";
|
||||
|
||||
@@ -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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
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
|
||||
|
||||
@@ -57,8 +57,10 @@ checkNear(IOUAmount const& expected, IOUAmount const& actual)
|
||||
static bool
|
||||
isXRPAccount(STPathElement const& pe)
|
||||
{
|
||||
return pe.getNodeType() == STPathElementType::Account && isXRP(pe.getAccountID());
|
||||
}
|
||||
if (pe.getNodeType() != STPathElement::TypeAccount)
|
||||
return false;
|
||||
return isXRP(pe.getAccountID());
|
||||
};
|
||||
|
||||
static std::pair<TER, std::unique_ptr<Step>>
|
||||
toStep(
|
||||
@@ -69,8 +71,11 @@ toStep(
|
||||
{
|
||||
auto& j = ctx.j;
|
||||
|
||||
if (ctx.isFirst && e1->isAccount() && e1->hasCurrency() && e1->getPathAsset().isXRP())
|
||||
if (ctx.isFirst && e1->isAccount() &&
|
||||
((e1->getNodeType() & STPathElement::TypeCurrency) != 0u) && e1->getPathAsset().isXRP())
|
||||
{
|
||||
return makeXrpEndpointStep(ctx, e1->getAccountID());
|
||||
}
|
||||
|
||||
if (ctx.isLast && isXRPAccount(*e1) && e2->isAccount())
|
||||
return makeXrpEndpointStep(ctx, e2->getAccountID());
|
||||
@@ -112,9 +117,15 @@ toStep(
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
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();
|
||||
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();
|
||||
|
||||
if (isXRP(curAsset) && outAsset.isXRP())
|
||||
{
|
||||
@@ -186,15 +197,16 @@ toStrand(
|
||||
for (std::size_t i = 0; i < path.size(); ++i)
|
||||
{
|
||||
auto const& pe = path[i];
|
||||
auto const t = pe.getNodeType();
|
||||
|
||||
if ((pe.getNodeType() & ~STPathElementType::All) != STPathElementType::None || pe.isNone())
|
||||
if (((t & ~STPathElement::TypeAll) != 0u) || (t == 0u))
|
||||
return {temBAD_PATH, Strand{}};
|
||||
|
||||
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();
|
||||
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;
|
||||
|
||||
if (hasAccount && (hasIssuer || hasCurrency))
|
||||
return {temBAD_PATH, Strand{}};
|
||||
@@ -238,7 +250,9 @@ toStrand(
|
||||
}();
|
||||
|
||||
// Currency or MPT
|
||||
auto const hasAsset = [](STPathElement const& pe) { return pe.hasAsset(); };
|
||||
auto const hasAsset = [](STPathElement const pe) {
|
||||
return pe.getNodeType() & STPathElement::TypeAsset;
|
||||
};
|
||||
|
||||
std::vector<STPathElement> normPath;
|
||||
// reserve enough for the path, the implied source, destination,
|
||||
@@ -249,10 +263,10 @@ toStrand(
|
||||
// transaction, as defined by the transaction's Account field. The Asset
|
||||
// is either SendMax or Deliver.
|
||||
auto const t = [&] {
|
||||
auto const t = STPathElementType::Account | STPathElementType::Issuer;
|
||||
auto const t = STPathElement::TypeAccount | STPathElement::TypeIssuer;
|
||||
return curAsset.visit(
|
||||
[&](MPTIssue const&) { return t | STPathElementType::Mpt; },
|
||||
[&](Issue const&) { return t | STPathElementType::Currency; });
|
||||
[&](MPTIssue const&) { return t | STPathElement::TypeMpt; },
|
||||
[&](Issue const&) { return t | STPathElement::TypeCurrency; });
|
||||
}();
|
||||
// If MPT then the issuer is the actual issuer, it is never the source
|
||||
// account.
|
||||
@@ -421,7 +435,7 @@ toStrand(
|
||||
return {msr.first, Strand{}};
|
||||
result.push_back(std::move(msr.second));
|
||||
impliedPE.emplace(
|
||||
STPathElementType::Account, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
|
||||
STPathElement::TypeAccount, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
|
||||
cur = &*impliedPE;
|
||||
}
|
||||
}
|
||||
@@ -436,7 +450,7 @@ toStrand(
|
||||
return {msr.first, Strand{}};
|
||||
result.push_back(std::move(msr.second));
|
||||
impliedPE.emplace(
|
||||
STPathElementType::Account, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
|
||||
STPathElement::TypeAccount, curAsset.getIssuer(), xrpCurrency(), xrpAccount());
|
||||
cur = &*impliedPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,8 +187,7 @@ AccountSet::preclaim(PreclaimContext const& ctx)
|
||||
if (!dirIsEmpty(ctx.view, keylet::ownerDir(id)))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Retry: Owner directory not empty.";
|
||||
return ((ctx.flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terOWNERS}
|
||||
: TER{tecOWNERS};
|
||||
return ((ctx.flags & TapRetry) != 0u) ? TER{terOWNERS} : TER{tecOWNERS};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -297,8 +297,7 @@ OfferCreate::checkAcceptAsset(
|
||||
JLOG(j.debug()) << "delay: can't receive IOUs from non-existent issuer: "
|
||||
<< to_string(asset.getIssuer());
|
||||
|
||||
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_ACCOUNT}
|
||||
: TER{tecNO_ISSUER};
|
||||
return ((flags & TapRetry) != 0u) ? TER{terNO_ACCOUNT} : TER{tecNO_ISSUER};
|
||||
}
|
||||
|
||||
// An account cannot create a trustline to itself, so no line can exist
|
||||
@@ -321,8 +320,7 @@ OfferCreate::checkAcceptAsset(
|
||||
{
|
||||
JLOG(j.debug()) << "delay: can't receive IOUs from issuer with "
|
||||
"DisallowIncomingTrustline set";
|
||||
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_LINE}
|
||||
: TER{tecNO_LINE};
|
||||
return ((flags & TapRetry) != 0u) ? TER{terNO_LINE} : TER{tecNO_LINE};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,8 +328,7 @@ OfferCreate::checkAcceptAsset(
|
||||
{
|
||||
if (!trustLine)
|
||||
{
|
||||
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_LINE}
|
||||
: TER{tecNO_LINE};
|
||||
return ((flags & TapRetry) != 0u) ? TER{terNO_LINE} : TER{tecNO_LINE};
|
||||
}
|
||||
|
||||
// Entries have a canonical representation, determined by a
|
||||
@@ -347,8 +344,7 @@ OfferCreate::checkAcceptAsset(
|
||||
JLOG(j.debug()) << "delay: can't receive IOUs from "
|
||||
"issuer without auth.";
|
||||
|
||||
return ((flags & ApplyFlags::Retry) != ApplyFlags::None) ? TER{terNO_AUTH}
|
||||
: TER{tecNO_AUTH};
|
||||
return ((flags & TapRetry) != 0u) ? TER{terNO_AUTH} : TER{tecNO_AUTH};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,8 +93,7 @@ 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 & ApplyFlags::Proposal) == ApplyFlags::None)
|
||||
if (!tx.isFlag(tfInnerBatchTxn) && !counterPartySig && (ctx.flags & TapProposal) == 0)
|
||||
{
|
||||
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, ApplyFlags::DryRun | ApplyFlags::Proposal, ctx.j);
|
||||
auto const inner =
|
||||
xrpl::preflight(ctx.registry, ctx.rules, stx, TapDryRun | TapProposal, 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 & ApplyFlags::Proposal) == ApplyFlags::None)
|
||||
(ctx.flags & TapProposal) == 0)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "preflight: account sponsorship requires sfSponsorSignature";
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -371,8 +371,7 @@ 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 =
|
||||
ApplyFlags::Batch | (ctx.flags & (ApplyFlags::Proposal | ApplyFlags::DryRun));
|
||||
ApplyFlags const innerFlags = TapBatch | (ctx.flags & (TapProposal | TapDryRun));
|
||||
if (auto const preflightResult =
|
||||
xrpl::preflight(ctx.registry, ctx.rules, parentBatchId, stx, innerFlags, ctx.j);
|
||||
!isTesSuccess(preflightResult.ter))
|
||||
@@ -444,7 +443,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 & ApplyFlags::Proposal) != ApplyFlags::None)
|
||||
if ((ctx.flags & TapProposal) != 0)
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const parentBatchId = ctx.tx.getTransactionID();
|
||||
|
||||
@@ -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(), ApplyFlags::None);
|
||||
PaymentSandbox sb(env.current().get(), TapNone);
|
||||
STPathSet paths;
|
||||
auto const ipe = [](MPTTester const& iss) {
|
||||
return STPathElement(
|
||||
STPathElementType::Mpt | STPathElementType::Issuer,
|
||||
STPathElement::TypeMpt | STPathElement::TypeIssuer,
|
||||
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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
for (auto const& o : flowResult.removableOffers)
|
||||
{
|
||||
if (auto const ok = sb.peek(keylet::offer(o)))
|
||||
|
||||
@@ -2015,11 +2015,11 @@ private:
|
||||
auto const flowResult = [&] {
|
||||
STAmount const deliver(USD(51));
|
||||
STAmount smax(BTC(61));
|
||||
PaymentSandbox sb(env.current().get(), ApplyFlags::None);
|
||||
PaymentSandbox sb(env.current().get(), TapNone);
|
||||
STPathSet paths;
|
||||
auto const ipe = [](Issue const& iss) {
|
||||
return STPathElement(
|
||||
STPathElementType::Currency | STPathElementType::Issuer,
|
||||
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
|
||||
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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
for (auto const& o : flowResult.removableOffers)
|
||||
{
|
||||
if (auto const ok = sb.peek(keylet::offer(o)))
|
||||
|
||||
@@ -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(), ApplyFlags::None, env.journal);
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, 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(), ApplyFlags::None, env.journal);
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
|
||||
auto const pf = AMMBid::preflight(ctx);
|
||||
BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
|
||||
}
|
||||
|
||||
@@ -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(), ApplyFlags::None, env.journal);
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, 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(), ApplyFlags::None, env.journal);
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, 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(), ApplyFlags::None, env.journal);
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
|
||||
auto const pf = Transactor::invokePreflight<AMMBid>(pfCtx);
|
||||
BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#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>
|
||||
@@ -894,8 +895,9 @@ public:
|
||||
auto const jNoCred = credentials::ledgerEntry(env, becky, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
|
||||
jNoCred[jss::result].isMember(jss::error) &&
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound");
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jNoCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
testcase("Credentials that aren't required");
|
||||
@@ -918,8 +920,9 @@ public:
|
||||
|
||||
BEAST_EXPECT(
|
||||
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
|
||||
jNoCred[jss::result].isMember(jss::error) &&
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound");
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jNoCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -957,8 +960,9 @@ public:
|
||||
|
||||
BEAST_EXPECT(
|
||||
jNoCred.isObject() && jNoCred.isMember(jss::result) &&
|
||||
jNoCred[jss::result].isMember(jss::error) &&
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound");
|
||||
jNoCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jNoCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jNoCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
testcase("Expired credentials");
|
||||
@@ -994,8 +998,9 @@ public:
|
||||
auto jv = credentials::ledgerEntry(env, john, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
jv[jss::result][jss::error] == "entryNotFound");
|
||||
jv[jss::result][jss::error] == "entryNotFound" &&
|
||||
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jv[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1079,8 +1084,9 @@ public:
|
||||
auto const jv = credentials::ledgerEntry(env, becky, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
jv[jss::result][jss::error] == "entryNotFound");
|
||||
jv[jss::result][jss::error] == "entryNotFound" &&
|
||||
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jv[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1121,8 +1127,9 @@ public:
|
||||
auto const jv = credentials::ledgerEntry(env, becky, carol, credType);
|
||||
BEAST_EXPECT(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
jv[jss::result][jss::error] == "entryNotFound");
|
||||
jv[jss::result][jss::error] == "entryNotFound" &&
|
||||
jv[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jv[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, *stx, TapNone, j);
|
||||
BEAST_EXPECT(result.ter == temBAD_SIGNATURE);
|
||||
BEAST_EXPECT(!result.applied);
|
||||
return result.applied;
|
||||
|
||||
+16
-13
@@ -43,6 +43,7 @@
|
||||
#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>
|
||||
@@ -432,7 +433,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(), ApplyFlags::None, env.journal);
|
||||
env.app(), *jtx.stx, env.current()->rules(), TapNone, env.journal);
|
||||
auto const pf = Transactor::invokePreflight<Payment>(pfCtx);
|
||||
BEAST_EXPECT(pf == temINVALID_INNER_BATCH);
|
||||
}
|
||||
@@ -447,7 +448,7 @@ class Batch_test : public beast::unit_test::Suite
|
||||
disabledEnv.app(),
|
||||
*jtx.stx,
|
||||
disabledEnv.current()->rules(),
|
||||
ApplyFlags::None,
|
||||
TapNone,
|
||||
disabledEnv.journal);
|
||||
auto const pf = Transactor::invokePreflight<Payment>(pfCtx);
|
||||
BEAST_EXPECT(pf == temINVALID_FLAG);
|
||||
@@ -458,12 +459,7 @@ 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(),
|
||||
ApplyFlags::Batch,
|
||||
env.journal);
|
||||
env.app(), *jtx.stx, UInt256{1}, env.current()->rules(), TapBatch, env.journal);
|
||||
auto const pf = Transactor::invokePreflight<Payment>(pfCtx);
|
||||
BEAST_EXPECT(pf == temINVALID_INNER_BATCH);
|
||||
}
|
||||
@@ -1601,7 +1597,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, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, *jt.stx, TapNone, j);
|
||||
BEAST_EXPECT(!result.applied && result.ter == temARRAY_TOO_LARGE);
|
||||
return result.applied;
|
||||
});
|
||||
@@ -2805,6 +2801,7 @@ 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.",
|
||||
@@ -4721,7 +4718,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, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, stx, TapNone, j);
|
||||
BEAST_EXPECT(!result.applied && result.ter == temINVALID_FLAG);
|
||||
return result.applied;
|
||||
});
|
||||
@@ -5412,7 +5409,10 @@ class Batch_test : public beast::unit_test::Suite
|
||||
|
||||
// The delegated payment never applied.
|
||||
BEAST_EXPECT(env.balance(mallory) == preMallory);
|
||||
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5823,7 +5823,10 @@ class Batch_test : public beast::unit_test::Suite
|
||||
validateClosedLedger(env, testCases);
|
||||
|
||||
// verify jv2 is not present in the closed ledger.
|
||||
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6021,7 +6024,7 @@ class Batch_test : public beast::unit_test::Suite
|
||||
obj.setFieldU32(sfFlags, tfInnerBatchTxn);
|
||||
});
|
||||
|
||||
auto const result = xrpl::apply(env.app(), view, stx, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, stx, TapNone, j);
|
||||
// Must NOT be applied — signature was never checked
|
||||
BEAST_EXPECT(!result.applied);
|
||||
return false;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#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>
|
||||
@@ -259,8 +260,9 @@ 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].isMember(jss::error) &&
|
||||
credentials[jss::result][jss::error] == "entryNotFound";
|
||||
return credentials[jss::result][jss::error] == "entryNotFound" &&
|
||||
credentials[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
credentials[jss::result][jss::error_message] == "Entry not found.";
|
||||
};
|
||||
|
||||
// TEST 4: Expired credential with matching depositPreauth entry.
|
||||
|
||||
@@ -1748,8 +1748,7 @@ class ConfidentialTransfer_test : public ConfidentialTransferTestBase
|
||||
(*sle)[sfConfidentialBalanceVersion] = wrappedFrom;
|
||||
view.rawReplace(sle);
|
||||
|
||||
auto const result =
|
||||
xrpl::apply(env.app(), view, *jt.stx, ApplyFlags::None, env.journal);
|
||||
auto const result = xrpl::apply(env.app(), view, *jt.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(result.ter == tesSUCCESS);
|
||||
return result.applied;
|
||||
}));
|
||||
@@ -7945,6 +7944,8 @@ 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.
|
||||
@@ -8052,6 +8053,8 @@ 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.
|
||||
@@ -8155,6 +8158,8 @@ 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.
|
||||
@@ -8279,6 +8284,8 @@ 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.
|
||||
@@ -8369,6 +8376,8 @@ 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());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#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>
|
||||
@@ -124,8 +125,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,8 +175,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,8 +225,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
// resurrection
|
||||
@@ -259,8 +263,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
// resurrection
|
||||
@@ -294,8 +299,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
// resurrection
|
||||
@@ -331,8 +337,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
// resurrection
|
||||
@@ -368,8 +375,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,8 +398,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,8 +419,9 @@ 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].isMember(jss::error) &&
|
||||
jle[jss::result][jss::error] == "entryNotFound");
|
||||
jle[jss::result][jss::error] == "entryNotFound" &&
|
||||
jle[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jle[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -744,8 +754,9 @@ 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].isMember(jss::error) &&
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound");
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jDelCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
|
||||
BEAST_EXPECT(ownerCount(env, issuer) == 0);
|
||||
BEAST_EXPECT(ownerCount(env, subject) == 1);
|
||||
@@ -781,8 +792,9 @@ 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].isMember(jss::error) &&
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound");
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jDelCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -909,7 +921,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::None);
|
||||
std::make_shared<ApplyViewImpl>(env.current().get(), ApplyFlags::TapNone);
|
||||
auto const ter = xrpl::credentials::deleteSLE(*view, {}, env.journal);
|
||||
BEAST_EXPECT(ter == tecNO_ENTRY);
|
||||
}
|
||||
@@ -1132,7 +1144,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, ApplyFlags::None);
|
||||
ApplyViewImpl av(&*open, TapNone);
|
||||
|
||||
// Erase the issuer's account to simulate ledger corruption
|
||||
auto const sleIssuer = av.peek(keylet::account(issuer.id()));
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#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>
|
||||
@@ -159,6 +160,8 @@ 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));
|
||||
@@ -167,6 +170,8 @@ 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
|
||||
@@ -2780,9 +2785,11 @@ 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].asString().contains(
|
||||
"A Signer may not be the transaction's Account"));
|
||||
jrr[jss::error_message] ==
|
||||
"A Signer may not be the transaction's Account (" + bob.human() + ").");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#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>
|
||||
@@ -1143,8 +1144,9 @@ 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].isMember(jss::error) &&
|
||||
jDP[jss::result][jss::error] == "entryNotFound");
|
||||
jDP[jss::result][jss::error] == "entryNotFound" &&
|
||||
jDP[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jDP[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1232,8 +1234,9 @@ 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].isMember(jss::error) &&
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound");
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jDelCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1283,8 +1286,9 @@ 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].isMember(jss::error) &&
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound");
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jDelCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
|
||||
BEAST_EXPECT(ownerCount(env, issuer) == 0);
|
||||
BEAST_EXPECT(ownerCount(env, gw) == 0);
|
||||
@@ -1358,8 +1362,9 @@ 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].isMember(jss::error) &&
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound");
|
||||
jDelCred[jss::result][jss::error] == "entryNotFound" &&
|
||||
jDelCred[jss::result][jss::error_code] == RpcEntryNotFound &&
|
||||
jDelCred[jss::result][jss::error_message] == "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
auto const sleNew =
|
||||
std::make_shared<SLE>(keylet::escrow(alice, SeqProxy::rawSequence(seq1)));
|
||||
MPTIssue const mpt{MPTIssue{makeMptID(1, AccountID(0x4985601))}};
|
||||
|
||||
@@ -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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, 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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, 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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, 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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(pf.ter));
|
||||
BEAST_EXPECT(!pf.consequences.isBlocker());
|
||||
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
|
||||
|
||||
@@ -160,7 +160,7 @@ createInvalidFeeTx(
|
||||
TER
|
||||
applyFeeAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx)
|
||||
{
|
||||
auto const res = apply(env.app(), view, tx, ApplyFlags::None, env.journal);
|
||||
auto const res = apply(env.app(), view, tx, ApplyFlags::TapNone, env.journal);
|
||||
return res.ter;
|
||||
}
|
||||
|
||||
@@ -1473,7 +1473,8 @@ 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::None, env.journal);
|
||||
auto const result =
|
||||
apply(env.app(), accum, amendTx, ApplyFlags::TapNone, env.journal);
|
||||
BEAST_EXPECTS(result.applied && isTesSuccess(result.ter), transToken(result.ter));
|
||||
accum.apply(*ledger);
|
||||
}
|
||||
|
||||
@@ -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(), ApplyFlags::None);
|
||||
PaymentSandbox sb(env.current().get(), TapNone);
|
||||
STPathSet paths;
|
||||
auto const ipe = [](Asset const& asset) {
|
||||
return STPathElement(
|
||||
STPathElementType::Asset | STPathElementType::Issuer,
|
||||
STPathElement::TypeAsset | STPathElement::TypeIssuer,
|
||||
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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
for (auto const& o : flowResult.removableOffers)
|
||||
{
|
||||
if (auto const ok = sb.peek(keylet::offer(o)))
|
||||
|
||||
@@ -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(), ApplyFlags::None);
|
||||
PaymentSandbox sb(env.current().get(), TapNone);
|
||||
STPathSet paths;
|
||||
auto const ipe = [](Issue const& iss) {
|
||||
return STPathElement(
|
||||
STPathElementType::Currency | STPathElementType::Issuer,
|
||||
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
|
||||
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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
for (auto const& o : flowResult.removableOffers)
|
||||
{
|
||||
if (auto const ok = sb.peek(keylet::offer(o)))
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
if (stx)
|
||||
{
|
||||
OpenView accum(&*res);
|
||||
applyTransaction(env.app(), accum, *stx, false, ApplyFlags::None, env.journal);
|
||||
applyTransaction(env.app(), accum, *stx, false, TapNone, env.journal);
|
||||
accum.apply(*res);
|
||||
}
|
||||
res->updateSkipList();
|
||||
|
||||
@@ -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), ApplyFlags::None, env.app(), env.journal);
|
||||
LedgerReplay(lastClosedParent, lastClosed), TapNone, 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), ApplyFlags::None, env.app(), env.journal);
|
||||
LedgerReplay(lastClosedParent, lastClosed), TapNone, env.app(), env.journal);
|
||||
|
||||
BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#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>
|
||||
@@ -1020,6 +1021,7 @@ 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.");
|
||||
@@ -1581,6 +1583,8 @@ 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
|
||||
@@ -1945,6 +1949,8 @@ 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;
|
||||
@@ -1952,9 +1958,13 @@ 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());
|
||||
@@ -3198,6 +3208,9 @@ 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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4118,7 +4131,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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
auto const ter =
|
||||
accountSendMulti(av, issuer.id(), asset, receivers, env.app().getJournal("View"));
|
||||
BEAST_EXPECTS(ter == expectedTer, label);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#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>
|
||||
@@ -586,6 +587,7 @@ 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.");
|
||||
@@ -613,6 +615,7 @@ 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.");
|
||||
}
|
||||
@@ -639,6 +642,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -651,6 +655,8 @@ 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);
|
||||
}
|
||||
@@ -690,12 +696,16 @@ 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.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -706,6 +716,7 @@ 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);
|
||||
@@ -1068,6 +1079,9 @@ 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.");
|
||||
@@ -1082,6 +1096,9 @@ 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.");
|
||||
@@ -1095,6 +1112,9 @@ 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.");
|
||||
@@ -1105,6 +1125,9 @@ 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.");
|
||||
@@ -1116,6 +1139,9 @@ 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.");
|
||||
@@ -1131,6 +1157,9 @@ 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"));
|
||||
@@ -1141,6 +1170,9 @@ 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.");
|
||||
@@ -1186,6 +1218,9 @@ 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.");
|
||||
@@ -1195,6 +1230,9 @@ 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.");
|
||||
@@ -1204,6 +1242,9 @@ 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.");
|
||||
@@ -1217,6 +1258,9 @@ 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.");
|
||||
|
||||
@@ -777,13 +777,7 @@ 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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
|
||||
// Verify that the last page is present and contains one NFT.
|
||||
auto const lastNFTokenPage = ac.view().peek(keylet::nftokenPageMax(alice));
|
||||
@@ -815,13 +809,7 @@ 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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
|
||||
// Verify that the middle page is present.
|
||||
auto const lastNFTokenPage = ac.view().peek(keylet::nftokenPageMax(alice));
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#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>
|
||||
@@ -4653,18 +4654,22 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite
|
||||
if (expect(
|
||||
nftOffers.isMember(jss::result), "expected \"result\"", __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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4860,11 +4865,15 @@ 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
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#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>
|
||||
@@ -2755,6 +2756,8 @@ 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));
|
||||
}
|
||||
@@ -2788,6 +2791,8 @@ 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);
|
||||
}
|
||||
@@ -2847,6 +2852,8 @@ 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
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#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>
|
||||
@@ -1707,6 +1708,8 @@ 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));
|
||||
}
|
||||
@@ -1738,6 +1741,8 @@ 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
|
||||
@@ -1798,6 +1803,8 @@ 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
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#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>
|
||||
@@ -162,7 +163,9 @@ public:
|
||||
g.signal();
|
||||
});
|
||||
BEAST_EXPECT(g.waitFor(5s));
|
||||
BEAST_EXPECT(result.isMember(jss::error));
|
||||
BEAST_EXPECT(result[jss::error] == "srcCurMalformed");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcSrcCurMalformed);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Source currency is malformed.");
|
||||
|
||||
// Test rpc::tuning::max_auto_src_cur source currencies.
|
||||
numSrc.clear();
|
||||
@@ -189,7 +192,9 @@ public:
|
||||
g.signal();
|
||||
});
|
||||
BEAST_EXPECT(g.waitFor(5s));
|
||||
BEAST_EXPECT(result.isMember(jss::error));
|
||||
BEAST_EXPECT(result[jss::error] == "internal");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInternal);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Internal error.");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#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>
|
||||
@@ -318,7 +319,9 @@ public:
|
||||
g.signal();
|
||||
});
|
||||
BEAST_EXPECT(g.waitFor(5s));
|
||||
BEAST_EXPECT(result.isMember(jss::error));
|
||||
BEAST_EXPECT(result[jss::error] == "srcCurMalformed");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcSrcCurMalformed);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Source currency is malformed.");
|
||||
|
||||
// Test rpc::tuning::max_auto_src_cur source currencies.
|
||||
for (auto i = 0; i < (rpc::tuning::kMaxAutoSrcCur - 1); ++i)
|
||||
@@ -341,7 +344,9 @@ public:
|
||||
g.signal();
|
||||
});
|
||||
BEAST_EXPECT(g.waitFor(5s));
|
||||
BEAST_EXPECT(result.isMember(jss::error));
|
||||
BEAST_EXPECT(result[jss::error] == "internal");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInternal);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Internal error.");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1964,9 +1969,9 @@ public:
|
||||
auto const createPathElements = [](auto const& account1, auto const& account2) {
|
||||
auto base = STPath{};
|
||||
base.pushBack(
|
||||
STPathElement{STPathElementType::Account, account1, xrpCurrency(), account1});
|
||||
STPathElement{STPathElement::TypeAccount, account1, xrpCurrency(), account1});
|
||||
auto const tail =
|
||||
STPathElement{STPathElementType::Account, account2, xrpCurrency(), account2};
|
||||
STPathElement{STPathElement::TypeAccount, account2, xrpCurrency(), account2};
|
||||
return std::make_pair(base, tail);
|
||||
};
|
||||
|
||||
@@ -2050,7 +2055,7 @@ public:
|
||||
|
||||
auto const makePath = [](AccountID const& account) {
|
||||
auto p = STPath{};
|
||||
p.pushBack(STPathElement{STPathElementType::Account, account, xrpCurrency(), account});
|
||||
p.pushBack(STPathElement{STPathElement::TypeAccount, account, xrpCurrency(), account});
|
||||
return p;
|
||||
};
|
||||
|
||||
@@ -2174,7 +2179,7 @@ public:
|
||||
},
|
||||
// An explicit type mask vs. one derived from the populated fields.
|
||||
{
|
||||
STPathElement{STPathElementType::Account, kAccount, xrpCurrency(), kIssuer},
|
||||
STPathElement{STPathElement::TypeAccount, kAccount, xrpCurrency(), kIssuer},
|
||||
STPathElement{kAccount, PathAsset{xrpCurrency()}, kIssuer, false},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1058,6 +1058,7 @@ 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));
|
||||
}
|
||||
@@ -1232,7 +1233,9 @@ struct PayChan_test : public beast::unit_test::Suite
|
||||
{
|
||||
// degenerate case
|
||||
auto const r = testLimit(env, alice, 0);
|
||||
BEAST_EXPECT(r.isMember(jss::error_message));
|
||||
BEAST_EXPECT(r[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(r[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(r[jss::error_message] == "Invalid field 'limit'.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1326,7 +1329,12 @@ 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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1415,22 +1423,40 @@ 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
|
||||
@@ -1439,22 +1465,34 @@ 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.
|
||||
@@ -1467,6 +1505,8 @@ 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.
|
||||
@@ -1479,6 +1519,8 @@ 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
|
||||
@@ -1537,6 +1579,8 @@ 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:
|
||||
@@ -1562,10 +1606,16 @@ 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};
|
||||
@@ -1574,6 +1624,8 @@ 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
|
||||
@@ -1583,6 +1635,8 @@ 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.
|
||||
@@ -1592,6 +1646,8 @@ 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.
|
||||
@@ -1603,6 +1659,11 @@ 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.
|
||||
@@ -1613,6 +1674,8 @@ 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
|
||||
@@ -1623,6 +1686,8 @@ 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.
|
||||
@@ -1633,6 +1698,8 @@ 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1883,6 +1950,8 @@ 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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ struct PayStrandMPT_test : public beast::unit_test::Suite
|
||||
usd,
|
||||
STPath({
|
||||
STPathElement{
|
||||
STPathElementType::Currency, xrpAccount(), xrpCurrency(), xrpAccount()},
|
||||
STPathElement::TypeCurrency, 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(), ApplyFlags::None};
|
||||
PaymentSandbox sb{env.current().get(), TapNone};
|
||||
{
|
||||
auto const r = ::xrpl::path::RippleCalc::rippleCalculate(
|
||||
sb,
|
||||
|
||||
@@ -225,7 +225,7 @@ public:
|
||||
else
|
||||
{
|
||||
col.emplace_back(
|
||||
STPathElementType::Boundary,
|
||||
STPathElement::Type::TypeBoundary,
|
||||
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{
|
||||
STPathElementType::Currency, xrpAccount(), xrpCurrency(), xrpAccount()},
|
||||
STPathElement::TypeCurrency, xrpAccount(), xrpCurrency(), xrpAccount()},
|
||||
}),
|
||||
tesSUCCESS,
|
||||
D{.src = alice, .dst = gw, .currency = usdC},
|
||||
@@ -770,8 +770,7 @@ struct PayStrand_test : public beast::unit_test::Suite
|
||||
env,
|
||||
usd,
|
||||
std::nullopt,
|
||||
STPath({STPathElement(
|
||||
STPathElementType::None, xrpAccount(), xrpCurrency(), xrpAccount())}),
|
||||
STPath({STPathElement(0, xrpAccount(), xrpCurrency(), xrpAccount())}),
|
||||
temBAD_PATH);
|
||||
|
||||
// The same account can't appear more than once on a path
|
||||
@@ -1079,7 +1078,7 @@ struct PayStrand_test : public beast::unit_test::Suite
|
||||
inputs.defaultPathsAllowed = true;
|
||||
try
|
||||
{
|
||||
PaymentSandbox sb{env.current().get(), ApplyFlags::None};
|
||||
PaymentSandbox sb{env.current().get(), TapNone};
|
||||
{
|
||||
auto const r = ::xrpl::path::RippleCalc::rippleCalculate(
|
||||
sb,
|
||||
|
||||
@@ -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, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, stx, TapNone, j);
|
||||
BEAST_EXPECT(!result.applied && result.ter == temINVALID);
|
||||
return result.applied;
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#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>
|
||||
@@ -42,8 +43,9 @@ class ReducedOffer_test : public beast::unit_test::Suite
|
||||
{
|
||||
json::Value ledgerOffer = ledgerEntryOffer(env, acct, offerSeq);
|
||||
return !(
|
||||
ledgerOffer.isMember(jss::error) &&
|
||||
ledgerOffer[jss::error].asString() == "entryNotFound");
|
||||
ledgerOffer[jss::error].asString() == "entryNotFound" &&
|
||||
ledgerOffer[jss::error_code] == RpcEntryNotFound &&
|
||||
ledgerOffer[jss::error_message] == "Entry not found.");
|
||||
}
|
||||
|
||||
// Common code to clean up unneeded offers.
|
||||
|
||||
@@ -103,8 +103,7 @@ 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, ApplyFlags::None, env.journal);
|
||||
auto const result = xrpl::apply(env.app(), accum, *jt.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(result.ter));
|
||||
BEAST_EXPECT(result.applied);
|
||||
|
||||
@@ -127,8 +126,7 @@ struct Regression_test : public beast::unit_test::Suite
|
||||
|
||||
OpenView accum(&*next);
|
||||
|
||||
auto const result =
|
||||
xrpl::apply(env.app(), accum, *jt.stx, ApplyFlags::None, env.journal);
|
||||
auto const result = xrpl::apply(env.app(), accum, *jt.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(result.ter == tecINSUFF_FEE);
|
||||
BEAST_EXPECT(result.applied);
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ class SHAMapStore_test : public beast::unit_test::Suite
|
||||
// after the health check that gates it, and kFinished once a rotation has
|
||||
// run to completion. kExpired is logged by healthWait() when the circuit
|
||||
// breaker trips.
|
||||
static constexpr char const* kRotating = "rotating";
|
||||
static constexpr char const* kFinished = "finished rotation";
|
||||
static constexpr char const* kRotating = "ROTATING:";
|
||||
static constexpr char const* kFinished = "FINISHED ROTATION:";
|
||||
static constexpr char const* kExpired = "unable to make progress";
|
||||
|
||||
// A Logs implementation that records every message the store's own
|
||||
@@ -302,10 +302,14 @@ class SHAMapStore_test : public beast::unit_test::Suite
|
||||
}
|
||||
|
||||
static bool
|
||||
bad(json::Value const& json, ErrorCodeI error = RpcLgrNotFound)
|
||||
bad(json::Value const& json,
|
||||
std::string const& token,
|
||||
ErrorCodeI error,
|
||||
std::string const& message)
|
||||
{
|
||||
return json.isMember(jss::result) && rpc::containsError(json[jss::result]) &&
|
||||
json[jss::result][jss::error_code] == error;
|
||||
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;
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -883,7 +887,7 @@ public:
|
||||
std::map<std::uint32_t, json::Value const> ledgers;
|
||||
|
||||
auto ledgerTmp = env.rpc("ledger", "0");
|
||||
BEAST_EXPECT(bad(ledgerTmp));
|
||||
BEAST_EXPECT(bad(ledgerTmp, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound"));
|
||||
|
||||
ledgers.emplace(1, env.rpc("ledger", "1"));
|
||||
BEAST_EXPECT(goodLedger(env, ledgers[1], "1"));
|
||||
@@ -895,10 +899,10 @@ public:
|
||||
BEAST_EXPECT(goodLedger(env, ledgerTmp, "3"));
|
||||
|
||||
ledgerTmp = env.rpc("ledger", "4");
|
||||
BEAST_EXPECT(bad(ledgerTmp));
|
||||
BEAST_EXPECT(bad(ledgerTmp, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound"));
|
||||
|
||||
ledgerTmp = env.rpc("ledger", "100");
|
||||
BEAST_EXPECT(bad(ledgerTmp));
|
||||
BEAST_EXPECT(bad(ledgerTmp, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound"));
|
||||
|
||||
auto const firstSeq = waitForReady(env);
|
||||
auto lastRotated = firstSeq - 1;
|
||||
@@ -987,7 +991,7 @@ public:
|
||||
// Because advisory_delete is unset,
|
||||
// "can_delete" is disabled.
|
||||
auto const canDelete = env.rpc("can_delete");
|
||||
BEAST_EXPECT(bad(canDelete, RpcNotEnabled));
|
||||
BEAST_EXPECT(bad(canDelete, "notEnabled", RpcNotEnabled, "Not enabled in configuration."));
|
||||
|
||||
// Close ledgers without triggering a rotate
|
||||
for (; ledgerSeq < lastRotated + kDeleteInterval; ++ledgerSeq)
|
||||
|
||||
@@ -990,8 +990,8 @@ public:
|
||||
sponsor::SponseeAcc(alice),
|
||||
Seq(1),
|
||||
Fee(baseFee));
|
||||
auto const pf = preflight(
|
||||
env.app(), env.current()->rules(), *jt.stx, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, 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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, 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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jt.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(pf.ter));
|
||||
BEAST_EXPECT(!pf.consequences.isBlocker());
|
||||
BEAST_EXPECT(pf.consequences.fee() == drops(baseFee));
|
||||
@@ -2318,8 +2318,7 @@ public:
|
||||
Seq(env.seq(alice)),
|
||||
sponsor::As(carol, spfSponsorFee));
|
||||
|
||||
auto const result =
|
||||
xrpl::apply(env.app(), overlay, *jt.stx, ApplyFlags::None, env.journal);
|
||||
auto const result = xrpl::apply(env.app(), overlay, *jt.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(result.ter == tecINSUFF_FEE);
|
||||
BEAST_EXPECT(result.applied);
|
||||
|
||||
@@ -2372,8 +2371,7 @@ public:
|
||||
Fee(fixFee),
|
||||
sponsor::As(sponsor, spfSponsorFee));
|
||||
|
||||
auto const pf =
|
||||
preflight(env.app(), overlay.rules(), *jt.stx, ApplyFlags::None, env.journal);
|
||||
auto const pf = preflight(env.app(), overlay.rules(), *jt.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(pf.ter));
|
||||
auto const pc = preclaim(pf, env.app(), overlay);
|
||||
BEAST_EXPECT(isTesSuccess(pc.ter));
|
||||
|
||||
@@ -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(), ApplyFlags::None);
|
||||
PaymentSandbox const sb(closed.get(), TapNone);
|
||||
AMMContext ammContext(rcp.srcAccount, false);
|
||||
|
||||
auto const sendMaxIssue = [&rcp] -> std::optional<Asset> {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#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>
|
||||
@@ -1032,15 +1033,25 @@ struct TransactionProposalCancel_test : public beast::unit_test::Suite
|
||||
{
|
||||
json::Value noTicket;
|
||||
noTicket[jss::account] = target.human();
|
||||
BEAST_EXPECT(ledgerEntry(noTicket)[jss::error] == "malformedRequest");
|
||||
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'.");
|
||||
|
||||
json::Value noAccount;
|
||||
noAccount[jss::ticket_seq] = ticketSeq;
|
||||
BEAST_EXPECT(ledgerEntry(noAccount)[jss::error] == "malformedRequest");
|
||||
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'.");
|
||||
|
||||
json::Value badAccount = byPair;
|
||||
badAccount[jss::account] = "not an account";
|
||||
BEAST_EXPECT(ledgerEntry(badAccount)[jss::error] == "malformedAddress");
|
||||
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.");
|
||||
}
|
||||
|
||||
// Listed for the proposer, who owns it, and not for the target.
|
||||
@@ -1057,6 +1068,8 @@ 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, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, *stx, TapNone, 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, ApplyFlags::None, j);
|
||||
auto const result = xrpl::apply(env.app(), view, *stx, TapNone, j);
|
||||
BEAST_EXPECT(result.ter == temINVALID);
|
||||
BEAST_EXPECT(!result.applied);
|
||||
return result.applied;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#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>
|
||||
@@ -66,6 +67,8 @@ 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)));
|
||||
@@ -100,6 +103,8 @@ 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.
|
||||
|
||||
|
||||
+12
-11
@@ -989,8 +989,7 @@ public:
|
||||
Env::ParsedResult parsed;
|
||||
|
||||
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
|
||||
auto const result =
|
||||
xrpl::apply(env.app(), view, *jt.stx, ApplyFlags::None, env.journal);
|
||||
auto const result = xrpl::apply(env.app(), view, *jt.stx, TapNone, env.journal);
|
||||
parsed.ter = result.ter;
|
||||
return result.applied;
|
||||
});
|
||||
@@ -2429,8 +2428,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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(pf.ter));
|
||||
BEAST_EXPECT(!pf.consequences.isBlocker());
|
||||
BEAST_EXPECT(pf.consequences.fee() == drops(10));
|
||||
@@ -2441,8 +2440,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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(pf.ter));
|
||||
BEAST_EXPECT(!pf.consequences.isBlocker());
|
||||
BEAST_EXPECT(pf.consequences.fee() == drops(10));
|
||||
@@ -2451,8 +2450,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, ApplyFlags::None, env.journal);
|
||||
auto const pf =
|
||||
preflight(env.app(), env.current()->rules(), *jtx.stx, TapNone, env.journal);
|
||||
BEAST_EXPECT(isTesSuccess(pf.ter));
|
||||
BEAST_EXPECT(!pf.consequences.isBlocker());
|
||||
BEAST_EXPECT(pf.consequences.fee() == drops(10));
|
||||
@@ -3232,7 +3231,9 @@ public:
|
||||
|
||||
{
|
||||
auto const info = env.rpc("json", "account_info", to_string(prevLedgerWithQueue));
|
||||
BEAST_EXPECT(info.isMember(jss::result) && rpc::containsError(info[jss::result]));
|
||||
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.");
|
||||
}
|
||||
|
||||
env.close();
|
||||
@@ -4011,7 +4012,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, ApplyFlags::Unlimited, j);
|
||||
auto const result = xrpl::apply(env.app(), view, *tx.stx, TapUnlimited, j);
|
||||
BEAST_EXPECT(isTesSuccess(result.ter) && result.applied);
|
||||
return result.applied;
|
||||
});
|
||||
@@ -4079,7 +4080,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, ApplyFlags::Unlimited, j);
|
||||
auto const result = xrpl::apply(env.app(), view, *tx.stx, TapUnlimited, j);
|
||||
BEAST_EXPECT(isTesSuccess(result.ter) && result.applied);
|
||||
return result.applied;
|
||||
});
|
||||
|
||||
@@ -122,8 +122,7 @@ 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, ApplyFlags::None, jlog};
|
||||
ApplyContext ac{env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
|
||||
// Invariants normally run in the Transaction's "apply" (operator()) context, and can always
|
||||
// access global Rules.
|
||||
|
||||
@@ -845,13 +845,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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -906,13 +900,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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -1035,13 +1023,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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -1525,7 +1507,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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sle = ac.view().peek(vaultKeylet);
|
||||
@@ -1592,7 +1574,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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
// visitEntry only runs for entries the transaction touched, so
|
||||
@@ -1649,8 +1631,7 @@ 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, ApplyFlags::None, jlog};
|
||||
ApplyContext ac{env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, 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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, 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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, 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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleBroker = ac.view().peek(brokerKeylet);
|
||||
|
||||
@@ -1131,13 +1131,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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -1189,7 +1183,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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -1366,13 +1360,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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -1427,13 +1415,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,
|
||||
ApplyFlags::None,
|
||||
jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
auto const sleLoan = ac.view().peek(loanKeylet);
|
||||
@@ -1537,7 +1519,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, ApplyFlags::None, jlog};
|
||||
env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
CurrentTransactionRulesGuard const rulesGuard(ov.rules());
|
||||
|
||||
{
|
||||
|
||||
@@ -1154,6 +1154,8 @@ 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");
|
||||
}
|
||||
|
||||
@@ -1271,8 +1273,7 @@ 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, ApplyFlags::None, jlog};
|
||||
ApplyContext ac{env.app(), ov, tx, tesSUCCESS, env.current()->fees().base, TapNone, jlog};
|
||||
|
||||
if (auto const sleBroker = ac.view().peek(keylet::loanBroker(brokerKeylet.key)))
|
||||
{
|
||||
@@ -1285,7 +1286,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, ApplyFlags::None, jlog};
|
||||
PreclaimContext const pctx{env.app(), ac.view(), tesSUCCESS, tx, TapNone, jlog};
|
||||
(void)LoanBrokerCoverDeposit::preclaim(pctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -190,6 +190,8 @@ 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.");
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#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>
|
||||
@@ -126,12 +127,9 @@ private:
|
||||
return params;
|
||||
}();
|
||||
auto const jSignBorrower = env.rpc("json", "sign", to_string(borrowerSignParams));
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
@@ -196,7 +196,8 @@ 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[jss::error] == "invalidTransaction" && !res.isMember(jss::error_code) &&
|
||||
res[jss::error_message].isNull() &&
|
||||
res[jss::error_exception] ==
|
||||
"fails local checks: Counterparty: Invalid signature.");
|
||||
});
|
||||
|
||||
@@ -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));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "entryNotFound");
|
||||
checkError(jvVault[jss::result], "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -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));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "entryNotFound");
|
||||
checkError(jvVault[jss::result], "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -191,7 +191,11 @@ private:
|
||||
jvParams[jss::ledger_index] = jss::validated;
|
||||
jvParams[jss::vault] = 42;
|
||||
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
|
||||
checkError(
|
||||
jvVault[jss::result],
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'vault', not hex string or object.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -201,7 +205,11 @@ private:
|
||||
jvParams[jss::vault][jss::owner] = 42;
|
||||
jvParams[jss::vault][jss::seq] = sequence;
|
||||
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedOwner");
|
||||
checkError(
|
||||
jvVault[jss::result],
|
||||
"malformedOwner",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'owner', not AccountID.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -211,7 +219,11 @@ private:
|
||||
jvParams[jss::vault][jss::owner] = issuer.human();
|
||||
jvParams[jss::vault][jss::seq] = "foo";
|
||||
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
|
||||
checkError(
|
||||
jvVault[jss::result],
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'seq', not number.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -221,7 +233,11 @@ private:
|
||||
jvParams[jss::vault][jss::owner] = issuer.human();
|
||||
jvParams[jss::vault][jss::seq] = -1;
|
||||
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
|
||||
checkError(
|
||||
jvVault[jss::result],
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'seq', not number.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -231,7 +247,11 @@ private:
|
||||
jvParams[jss::vault][jss::owner] = issuer.human();
|
||||
jvParams[jss::vault][jss::seq] = 1e20;
|
||||
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
|
||||
checkError(
|
||||
jvVault[jss::result],
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'seq', not number.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -241,7 +261,11 @@ private:
|
||||
jvParams[jss::vault][jss::owner] = issuer.human();
|
||||
jvParams[jss::vault][jss::seq] = true;
|
||||
auto jvVault = env.rpc("json", "ledger_entry", to_string(jvParams));
|
||||
BEAST_EXPECT(jvVault[jss::result][jss::error].asString() == "malformedRequest");
|
||||
checkError(
|
||||
jvVault[jss::result],
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'seq', not number.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -500,8 +524,8 @@ private:
|
||||
|
||||
{
|
||||
testcase("RPC vault_info command line invalid index");
|
||||
json::Value jv = env.rpc("vault_info", "foobar", "validated");
|
||||
BEAST_EXPECT(jv[jss::error].asString() == "invalidParams");
|
||||
json::Value const jv = env.rpc("vault_info", "foobar", "validated");
|
||||
checkError(jv, "invalidParams", RpcInvalidParams, "Invalid parameters.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -519,7 +543,7 @@ private:
|
||||
{
|
||||
testcase("RPC vault_info command line invalid ledger");
|
||||
json::Value jv = env.rpc("vault_info", strHex(keylet.key), "0");
|
||||
BEAST_EXPECT(jv[jss::result][jss::error].asString() == "lgrNotFound");
|
||||
checkError(jv[jss::result], "lgrNotFound", RpcLgrNotFound, "ledgerNotFound");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
auto const vault = sb.peek(keylet::vault(keylet.key));
|
||||
if (!BEAST_EXPECT(vault))
|
||||
return false;
|
||||
|
||||
@@ -304,7 +304,7 @@ private:
|
||||
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) {
|
||||
for (auto const field : encryptedBalanceFields)
|
||||
{
|
||||
Sandbox sb(&view, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
auto const token = sb.peek(tokenKeylet);
|
||||
if (!BEAST_EXPECT(token))
|
||||
return false;
|
||||
|
||||
@@ -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::None, env.journal);
|
||||
auto const res = apply(env.app(), view, tx, ApplyFlags::TapNone, env.journal);
|
||||
if (pass)
|
||||
{
|
||||
return isTesSuccess(res.ter);
|
||||
|
||||
@@ -125,7 +125,7 @@ inline TestPath&
|
||||
TestPath::pushBack(Issue const& iss)
|
||||
{
|
||||
path.emplaceBack(
|
||||
STPathElementType::Currency | STPathElementType::Issuer,
|
||||
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
|
||||
beast::kZero,
|
||||
iss.currency,
|
||||
iss.account);
|
||||
@@ -136,7 +136,7 @@ inline TestPath&
|
||||
TestPath::pushBack(MPTIssue const& iss)
|
||||
{
|
||||
path.emplaceBack(
|
||||
STPathElementType::Mpt | STPathElementType::Issuer,
|
||||
STPathElement::TypeMpt | STPathElement::TypeIssuer,
|
||||
beast::kZero,
|
||||
iss.getMptID(),
|
||||
iss.getIssuer());
|
||||
|
||||
@@ -570,10 +570,10 @@ cpe(PathAsset const& pa)
|
||||
{
|
||||
return pa.visit(
|
||||
[](Currency const& currency) {
|
||||
return STPathElement(STPathElementType::Currency, xrpAccount(), currency, xrpAccount());
|
||||
return STPathElement(STPathElement::TypeCurrency, xrpAccount(), currency, xrpAccount());
|
||||
},
|
||||
[](MPTID const& mpt) {
|
||||
return STPathElement(STPathElementType::Mpt, xrpAccount(), mpt, xrpAccount());
|
||||
return STPathElement(STPathElement::TypeMpt, xrpAccount(), mpt, xrpAccount());
|
||||
});
|
||||
};
|
||||
|
||||
@@ -590,14 +590,14 @@ ipe(Asset const& asset)
|
||||
return asset.visit(
|
||||
[](Issue const& issue) {
|
||||
return STPathElement(
|
||||
STPathElementType::Currency | STPathElementType::Issuer,
|
||||
STPathElement::TypeCurrency | STPathElement::TypeIssuer,
|
||||
xrpAccount(),
|
||||
issue.currency,
|
||||
issue.account);
|
||||
},
|
||||
[](MPTIssue const& issue) {
|
||||
return STPathElement(
|
||||
STPathElementType::Mpt | STPathElementType::Issuer,
|
||||
STPathElement::TypeMpt | STPathElement::TypeIssuer,
|
||||
xrpAccount(),
|
||||
issue.getMptID(),
|
||||
issue.getIssuer());
|
||||
@@ -608,14 +608,14 @@ ipe(Asset const& asset)
|
||||
STPathElement
|
||||
iape(AccountID const& account)
|
||||
{
|
||||
return STPathElement(STPathElementType::Issuer, xrpAccount(), xrpCurrency(), account);
|
||||
return STPathElement(STPathElement::TypeIssuer, xrpAccount(), xrpCurrency(), account);
|
||||
};
|
||||
|
||||
// Account path element
|
||||
STPathElement
|
||||
ape(AccountID const& a)
|
||||
{
|
||||
return STPathElement(STPathElementType::Account, a, xrpCurrency(), xrpAccount());
|
||||
return STPathElement(STPathElement::TypeAccount, a, xrpCurrency(), xrpAccount());
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
@@ -32,7 +32,7 @@ bumpLastPage(
|
||||
{
|
||||
std::expected<void, Error> res{};
|
||||
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) -> bool {
|
||||
Sandbox sb(&view, ApplyFlags::None);
|
||||
Sandbox sb(&view, TapNone);
|
||||
|
||||
// Find the root page
|
||||
auto const sleRoot = sb.peek(directory);
|
||||
|
||||
@@ -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(), ApplyFlags::None);
|
||||
Sandbox const sb(env.closed().get(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
Sandbox sb(env.closed().get(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
Sandbox sb(env.closed().get(), TapNone);
|
||||
makePages(sb, kBase, 4);
|
||||
|
||||
// Now add items on pages 1 and 2:
|
||||
|
||||
@@ -131,7 +131,7 @@ class PaymentSandbox_test : public beast::unit_test::Suite
|
||||
STAmount const toDebit(usdGw1(20));
|
||||
{
|
||||
// accountSend, no deferredCredits
|
||||
ApplyViewImpl av(&*env.current(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
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(), ApplyFlags::None);
|
||||
ApplyViewImpl av(&*env.current(), TapNone);
|
||||
PaymentSandbox sb(&av);
|
||||
|
||||
// Test basic owner count hook without sponsor
|
||||
|
||||
@@ -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, ApplyFlags::None);
|
||||
ApplyViewImpl v(&*open, TapNone);
|
||||
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, ApplyFlags::None);
|
||||
ApplyViewImpl v0(&*open, TapNone);
|
||||
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, ApplyFlags::None);
|
||||
ApplyViewImpl v0(&*open, TapNone);
|
||||
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, ApplyFlags::Retry);
|
||||
ApplyViewImpl v2(&v1, TapRetry);
|
||||
BEAST_EXPECT(v2.parentCloseTime() == v1.parentCloseTime());
|
||||
BEAST_EXPECT(v2.seq() == v1.seq());
|
||||
BEAST_EXPECT(v2.flags() == ApplyFlags::Retry);
|
||||
BEAST_EXPECT(v2.flags() == TapRetry);
|
||||
|
||||
Sandbox const v3(&v2);
|
||||
BEAST_EXPECT(v3.seq() == v2.seq());
|
||||
BEAST_EXPECT(v3.parentCloseTime() == v2.parentCloseTime());
|
||||
BEAST_EXPECT(v3.flags() == ApplyFlags::Retry);
|
||||
BEAST_EXPECT(v3.flags() == TapRetry);
|
||||
}
|
||||
{
|
||||
ApplyViewImpl v1(&v0, ApplyFlags::Retry);
|
||||
ApplyViewImpl v1(&v0, TapRetry);
|
||||
PaymentSandbox v2(&v1);
|
||||
BEAST_EXPECT(v2.seq() == v0.seq());
|
||||
BEAST_EXPECT(v2.parentCloseTime() == v0.parentCloseTime());
|
||||
BEAST_EXPECT(v2.flags() == ApplyFlags::Retry);
|
||||
BEAST_EXPECT(v2.flags() == TapRetry);
|
||||
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, ApplyFlags::None);
|
||||
ApplyViewImpl v1(&v0, TapNone);
|
||||
{
|
||||
Sandbox v2(&v1);
|
||||
v2.erase(v2.peek(k(1)));
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#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>
|
||||
@@ -180,6 +181,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -253,6 +255,7 @@ 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.");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#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>
|
||||
@@ -56,12 +57,16 @@ 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.");
|
||||
});
|
||||
|
||||
@@ -69,6 +74,8 @@ 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.");
|
||||
});
|
||||
|
||||
@@ -82,6 +89,8 @@ 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.");
|
||||
});
|
||||
|
||||
@@ -106,6 +115,8 @@ 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.");
|
||||
}
|
||||
});
|
||||
@@ -121,6 +132,8 @@ 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.");
|
||||
}
|
||||
});
|
||||
@@ -137,6 +150,8 @@ 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.");
|
||||
}
|
||||
});
|
||||
@@ -145,6 +160,8 @@ 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.");
|
||||
});
|
||||
|
||||
@@ -169,6 +186,8 @@ 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.");
|
||||
}
|
||||
});
|
||||
@@ -185,6 +204,13 @@ 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.")
|
||||
@@ -383,7 +409,9 @@ public:
|
||||
testAMM([&](AMM& amm, Env&) {
|
||||
auto const resp = amm.ammRpcInfo(
|
||||
std::nullopt, jss::validated.cStr(), std::nullopt, std::nullopt, gw_);
|
||||
BEAST_EXPECT(resp.isMember("error") && resp["error"] == "actNotFound");
|
||||
BEAST_EXPECT(resp[jss::error] == "actNotFound");
|
||||
BEAST_EXPECT(resp[jss::error_code] == RpcActNotFound);
|
||||
BEAST_EXPECT(resp[jss::error_message] == "Account not found.");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ 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'.");
|
||||
}
|
||||
@@ -45,6 +46,7 @@ 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));
|
||||
@@ -56,6 +58,7 @@ 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());
|
||||
@@ -65,6 +68,7 @@ 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.");
|
||||
}
|
||||
@@ -334,6 +338,7 @@ 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));
|
||||
|
||||
@@ -55,6 +55,7 @@ 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] ==
|
||||
@@ -65,6 +66,7 @@ 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] ==
|
||||
@@ -118,6 +120,7 @@ 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] ==
|
||||
@@ -161,6 +164,7 @@ 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] ==
|
||||
@@ -172,6 +176,7 @@ 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");
|
||||
}
|
||||
@@ -305,6 +310,7 @@ 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] ==
|
||||
@@ -344,6 +350,7 @@ 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] ==
|
||||
@@ -382,6 +389,7 @@ 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] ==
|
||||
@@ -393,6 +401,7 @@ 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] ==
|
||||
@@ -404,6 +413,7 @@ 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] ==
|
||||
@@ -548,7 +558,11 @@ 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].isMember(jss::error_message));
|
||||
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]);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -616,6 +630,7 @@ 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] ==
|
||||
@@ -914,6 +929,7 @@ 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] ==
|
||||
@@ -933,6 +949,7 @@ 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] ==
|
||||
@@ -953,6 +970,7 @@ 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] ==
|
||||
@@ -1025,6 +1043,7 @@ 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] ==
|
||||
@@ -1045,6 +1064,7 @@ 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");
|
||||
@@ -1220,6 +1240,7 @@ 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] ==
|
||||
@@ -1240,6 +1261,7 @@ 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] ==
|
||||
@@ -1314,6 +1336,7 @@ 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] ==
|
||||
@@ -1334,6 +1357,7 @@ 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] ==
|
||||
@@ -1492,6 +1516,7 @@ 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] ==
|
||||
|
||||
@@ -140,6 +140,8 @@ 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
|
||||
@@ -149,6 +151,7 @@ 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'.");
|
||||
};
|
||||
|
||||
@@ -164,6 +167,8 @@ 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.
|
||||
@@ -171,6 +176,8 @@ 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"};
|
||||
@@ -180,6 +187,8 @@ 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");
|
||||
}
|
||||
|
||||
@@ -190,6 +199,8 @@ 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.");
|
||||
}
|
||||
@@ -199,6 +210,8 @@ 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
|
||||
@@ -207,6 +220,8 @@ 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.");
|
||||
@@ -217,6 +232,8 @@ 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.");
|
||||
}
|
||||
@@ -238,27 +255,39 @@ 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?
|
||||
@@ -603,7 +632,8 @@ 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].isMember(jss::error) &&
|
||||
return resp[jss::result][jss::error] == "invalidParams" &&
|
||||
resp[jss::result][jss::error_code] == RpcInvalidParams &&
|
||||
resp[jss::result][jss::error_message] == "Invalid field \'type\'.";
|
||||
};
|
||||
|
||||
@@ -1174,7 +1204,9 @@ 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_message] == errorMessage;
|
||||
return resp[jss::result][jss::error] == "invalidParams" &&
|
||||
resp[jss::result][jss::error_code] == RpcInvalidParams &&
|
||||
resp[jss::result][jss::error_message] == errorMessage;
|
||||
};
|
||||
|
||||
// test an invalid marker that is not a string
|
||||
@@ -1427,7 +1459,9 @@ 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_message] == "Invalid field \'marker\'.";
|
||||
return resp[jss::result][jss::error] == "invalidParams" &&
|
||||
resp[jss::result][jss::error_code] == RpcInvalidParams &&
|
||||
resp[jss::result][jss::error_message] == "Invalid field \'marker\'.";
|
||||
};
|
||||
|
||||
auto const markerStr = marker.asString();
|
||||
|
||||
@@ -173,7 +173,9 @@ public:
|
||||
jvParams[jss::limit] = 0u;
|
||||
auto const jrr =
|
||||
env.rpc("json", "account_offers", jvParams.toStyledString())[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::error_message));
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'limit'.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,9 +197,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.");
|
||||
}
|
||||
|
||||
@@ -226,9 +228,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);
|
||||
@@ -237,9 +239,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.");
|
||||
}
|
||||
|
||||
@@ -250,9 +252,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.");
|
||||
}
|
||||
|
||||
@@ -263,9 +265,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());
|
||||
}
|
||||
@@ -277,9 +279,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.");
|
||||
}
|
||||
|
||||
@@ -290,9 +292,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");
|
||||
}
|
||||
|
||||
|
||||
+129
-62
@@ -195,19 +195,27 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
(j[jss::result][jss::transactions].size() == 0);
|
||||
};
|
||||
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
json::Value jParams;
|
||||
jParams[jss::api_version] = apiVersion;
|
||||
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(jParams)), RpcInvalidParams));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(jParams)),
|
||||
RpcInvalidParams,
|
||||
"Missing field 'account'."));
|
||||
|
||||
jParams[jss::account] = "0xDEADBEEF";
|
||||
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(jParams)), RpcActMalformed));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(jParams)),
|
||||
RpcActMalformed,
|
||||
"Account malformed."));
|
||||
|
||||
jParams[jss::account] = a1.human();
|
||||
BEAST_EXPECT(hasTxs(env.rpc(apiVersion, "json", "account_tx", to_string(jParams))));
|
||||
@@ -227,8 +235,10 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrIdxMalformed,
|
||||
"Ledger index malformed."));
|
||||
}
|
||||
|
||||
p[jss::ledger_index_min] = 1;
|
||||
@@ -239,15 +249,18 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrIdxMalformed,
|
||||
"Ledger index malformed."));
|
||||
}
|
||||
|
||||
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 ? RpcLgrIdxsInvalid : RpcInvalidLgrRange),
|
||||
(apiVersion == 1 ? "Ledger indexes invalid." : "Ledger range is invalid.")));
|
||||
}
|
||||
// Ledger index min only
|
||||
{
|
||||
@@ -262,14 +275,17 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrIdxMalformed,
|
||||
"Ledger index malformed."));
|
||||
}
|
||||
|
||||
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 ? RpcLgrIdxsInvalid : RpcInvalidLgrRange),
|
||||
(apiVersion == 1 ? "Ledger indexes invalid." : "Ledger range is invalid.")));
|
||||
}
|
||||
|
||||
// Ledger index max only
|
||||
@@ -285,8 +301,10 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrIdxMalformed,
|
||||
"Ledger index malformed."));
|
||||
}
|
||||
|
||||
p[jss::ledger_index_max] = 3;
|
||||
@@ -310,10 +328,14 @@ 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));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrNotValidated,
|
||||
"Ledger not validated."));
|
||||
|
||||
p[jss::ledger_index] = env.current()->header().seq + 1;
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrNotFound));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)), RpcLgrNotFound, "ledgerNotFound"));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -326,10 +348,16 @@ 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));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrNotValidated,
|
||||
"Ledger not validated."));
|
||||
|
||||
p[jss::ledger_index] = "";
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrNotValidated));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrNotValidated,
|
||||
"Ledger not validated."));
|
||||
}
|
||||
|
||||
// Ledger Hash
|
||||
@@ -360,7 +388,10 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
"invalidParams"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,8 +405,10 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
isErr(env.rpc("json", "account_tx", to_string(p)), RpcLgrIdxMalformed));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcLgrIdxMalformed,
|
||||
"Ledger index malformed."));
|
||||
}
|
||||
}
|
||||
// test account non-string
|
||||
@@ -385,6 +418,7 @@ 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'.");
|
||||
};
|
||||
|
||||
@@ -406,7 +440,10 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'binary'."));
|
||||
}
|
||||
|
||||
p[jss::binary] = true;
|
||||
@@ -420,7 +457,10 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(isErr(env.rpc("json", "account_tx", to_string(p)), RpcInvalidParams));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'forward'."));
|
||||
}
|
||||
|
||||
p[jss::forward] = false;
|
||||
@@ -433,70 +473,83 @@ 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));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'limit'."));
|
||||
|
||||
// Test case: limit = 1.2 should fail (not an integer)
|
||||
p[jss::limit] = 1.2;
|
||||
BEAST_EXPECT(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
|
||||
|
||||
// Test case: limit = "10" should fail (string instead of integer)
|
||||
p[jss::limit] = "10";
|
||||
BEAST_EXPECT(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
|
||||
|
||||
// Test case: limit = true should fail (boolean instead of integer)
|
||||
p[jss::limit] = true;
|
||||
BEAST_EXPECT(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
|
||||
|
||||
// Test case: limit = false should fail (boolean instead of integer)
|
||||
p[jss::limit] = false;
|
||||
BEAST_EXPECT(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
|
||||
|
||||
// Test case: limit = -1 should fail (negative number)
|
||||
p[jss::limit] = -1;
|
||||
BEAST_EXPECT(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
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(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
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(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
|
||||
|
||||
// Test case: limit = "malformed" should fail (malformed string)
|
||||
p[jss::limit] = "malformed";
|
||||
BEAST_EXPECT(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
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(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
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(
|
||||
env.rpc("json", "account_tx", to_string(p))[jss::result][jss::error_message] ==
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer"));
|
||||
BEAST_EXPECT(isErr(
|
||||
env.rpc("json", "account_tx", to_string(p)),
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::limit, "unsigned integer")));
|
||||
|
||||
// Test case: limit = 10 should succeed (valid integer)
|
||||
p[jss::limit] = 10;
|
||||
@@ -985,12 +1038,16 @@ class AccountTx_test : public beast::unit_test::Suite
|
||||
};
|
||||
|
||||
auto const checkError = [&](json::Value const& delegateParams,
|
||||
std::string const& errToken) {
|
||||
std::string const& errToken,
|
||||
ErrorCodeI code,
|
||||
std::string const& errMessage) {
|
||||
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)
|
||||
@@ -1061,27 +1118,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");
|
||||
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate'.");
|
||||
}
|
||||
|
||||
// Missing "delegate_filter" inside object
|
||||
{
|
||||
json::Value const p(json::ValueType::Object);
|
||||
checkError(p, "invalidParams");
|
||||
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate_filter'.");
|
||||
}
|
||||
|
||||
// "delegate_filter" is not a string (e.g., int)
|
||||
{
|
||||
json::Value p;
|
||||
p[jss::delegate_filter] = 123;
|
||||
checkError(p, "invalidParams");
|
||||
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate_filter'.");
|
||||
}
|
||||
|
||||
// "delegate_filter" has invalid value
|
||||
{
|
||||
json::Value p;
|
||||
p[jss::delegate_filter] = "random_string";
|
||||
checkError(p, "invalidParams");
|
||||
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'delegate_filter'.");
|
||||
}
|
||||
|
||||
// "counterparty" is not a string
|
||||
@@ -1089,7 +1146,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");
|
||||
checkError(p, "invalidParams", RpcInvalidParams, "Invalid field 'counter_party'.");
|
||||
}
|
||||
|
||||
// "counterparty" is malformed base58
|
||||
@@ -1097,7 +1154,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");
|
||||
checkError(p, "actMalformed", RpcActMalformed, "Account malformed.");
|
||||
}
|
||||
|
||||
// Multi-signed non-delegated TX: Alice pays Carol via multi-sig.
|
||||
@@ -1181,6 +1238,11 @@ 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.
|
||||
@@ -1205,6 +1267,11 @@ 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#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>
|
||||
@@ -186,32 +187,42 @@ 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
|
||||
@@ -221,7 +232,9 @@ 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.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#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>
|
||||
@@ -77,8 +78,12 @@ 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].isMember(jss::error));
|
||||
BEAST_EXPECT(resp[jss::result][jss::status] != "success");
|
||||
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.");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#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>
|
||||
@@ -1225,6 +1226,7 @@ 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");
|
||||
}
|
||||
|
||||
@@ -1233,6 +1235,7 @@ 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'.");
|
||||
}
|
||||
|
||||
@@ -1242,6 +1245,7 @@ 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'.");
|
||||
}
|
||||
|
||||
@@ -1252,6 +1256,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -1262,6 +1267,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -1272,6 +1278,7 @@ 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'.");
|
||||
}
|
||||
|
||||
@@ -1282,6 +1289,7 @@ 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.");
|
||||
}
|
||||
@@ -1293,6 +1301,7 @@ 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'.");
|
||||
}
|
||||
|
||||
@@ -1303,6 +1312,7 @@ 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.");
|
||||
}
|
||||
@@ -1314,6 +1324,7 @@ 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.");
|
||||
}
|
||||
@@ -1325,6 +1336,7 @@ 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.");
|
||||
}
|
||||
@@ -1337,6 +1349,7 @@ 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.");
|
||||
}
|
||||
@@ -1349,6 +1362,7 @@ 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.");
|
||||
}
|
||||
@@ -1361,6 +1375,7 @@ 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.");
|
||||
}
|
||||
@@ -1373,6 +1388,7 @@ 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.");
|
||||
@@ -1386,6 +1402,7 @@ 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.");
|
||||
}
|
||||
@@ -1398,6 +1415,7 @@ 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.");
|
||||
@@ -1412,6 +1430,7 @@ 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' "
|
||||
@@ -1427,6 +1446,7 @@ 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.");
|
||||
@@ -1441,6 +1461,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -1453,6 +1474,7 @@ 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'.");
|
||||
}
|
||||
|
||||
@@ -1466,6 +1488,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -1479,6 +1502,7 @@ 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.");
|
||||
}
|
||||
|
||||
@@ -1492,6 +1516,7 @@ 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'.");
|
||||
}
|
||||
|
||||
@@ -1503,6 +1528,7 @@ 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', "
|
||||
@@ -1518,6 +1544,7 @@ 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' "
|
||||
@@ -1533,6 +1560,7 @@ 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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
#include <xrpl/beast/unit_test/suite.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -22,8 +23,8 @@ class Connect_test : public beast::unit_test::Suite
|
||||
|
||||
auto const result = env.rpc("json", "connect", "{}");
|
||||
BEAST_EXPECT(result[jss::result][jss::status] == "error");
|
||||
BEAST_EXPECT(result[jss::result].isMember(jss::error));
|
||||
BEAST_EXPECT(result[jss::result][jss::error] == "notSynced");
|
||||
BEAST_EXPECT(result[jss::result][jss::error_code] == RpcNotSynced);
|
||||
BEAST_EXPECT(result[jss::result][jss::error_message] == "Not synced to the network.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <xrpl/beast/unit_test/suite.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Protocol.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
@@ -154,12 +155,16 @@ public:
|
||||
Account const becky{"becky"};
|
||||
|
||||
// Lambda that checks the (error) result of deposit_authorized.
|
||||
auto const verifyErr =
|
||||
[this](json::Value const& result, char const* error, char const* errorMsg) {
|
||||
BEAST_EXPECT(result[jss::result][jss::status] == jss::error);
|
||||
BEAST_EXPECT(result[jss::result][jss::error] == error);
|
||||
BEAST_EXPECT(result[jss::result][jss::error_message] == errorMsg);
|
||||
};
|
||||
auto const verifyErr = [this](
|
||||
json::Value const& result,
|
||||
char const* error,
|
||||
ErrorCodeI code,
|
||||
char const* errorMsg) {
|
||||
BEAST_EXPECT(result[jss::result][jss::status] == jss::error);
|
||||
BEAST_EXPECT(result[jss::result][jss::error] == error);
|
||||
BEAST_EXPECT(result[jss::result][jss::error_code] == code);
|
||||
BEAST_EXPECT(result[jss::result][jss::error_message] == errorMsg);
|
||||
};
|
||||
|
||||
Env env(*this);
|
||||
{
|
||||
@@ -167,28 +172,33 @@ public:
|
||||
json::Value args{depositAuthArgs(alice, becky)};
|
||||
args.removeMember(jss::source_account);
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "invalidParams", "Missing field 'source_account'.");
|
||||
verifyErr(result, "invalidParams", RpcInvalidParams, "Missing field 'source_account'.");
|
||||
}
|
||||
{
|
||||
// Non-string source_account field.
|
||||
json::Value args{depositAuthArgs(alice, becky)};
|
||||
args[jss::source_account] = 7.3;
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "invalidParams", "Invalid field 'source_account', not a string.");
|
||||
verifyErr(
|
||||
result,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'source_account', not a string.");
|
||||
}
|
||||
{
|
||||
// Corrupt source_account field.
|
||||
json::Value args{depositAuthArgs(alice, becky)};
|
||||
args[jss::source_account] = "rG1QQv2nh2gr7RCZ!P8YYcBUKCCN633jCn";
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "actMalformed", "Account malformed.");
|
||||
verifyErr(result, "actMalformed", RpcActMalformed, "Account malformed.");
|
||||
}
|
||||
{
|
||||
// Missing destination_account field.
|
||||
json::Value args{depositAuthArgs(alice, becky)};
|
||||
args.removeMember(jss::destination_account);
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "invalidParams", "Missing field 'destination_account'.");
|
||||
verifyErr(
|
||||
result, "invalidParams", RpcInvalidParams, "Missing field 'destination_account'.");
|
||||
}
|
||||
{
|
||||
// Non-string destination_account field.
|
||||
@@ -196,40 +206,46 @@ public:
|
||||
args[jss::destination_account] = 7.3;
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(
|
||||
result, "invalidParams", "Invalid field 'destination_account', not a string.");
|
||||
result,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'destination_account', not a string.");
|
||||
}
|
||||
{
|
||||
// Corrupt destination_account field.
|
||||
json::Value args{depositAuthArgs(alice, becky)};
|
||||
args[jss::destination_account] = "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "actMalformed", "Account malformed.");
|
||||
verifyErr(result, "actMalformed", RpcActMalformed, "Account malformed.");
|
||||
}
|
||||
{
|
||||
// Request an invalid ledger.
|
||||
json::Value const args{depositAuthArgs(alice, becky, "-1")};
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(
|
||||
result, "invalidParams", "Invalid field 'ledger_index', not string or number.");
|
||||
result,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'ledger_index', not string or number.");
|
||||
}
|
||||
{
|
||||
// Request a ledger that doesn't exist yet as a string.
|
||||
json::Value const args{depositAuthArgs(alice, becky, "17")};
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "lgrNotFound", "ledgerNotFound");
|
||||
verifyErr(result, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound");
|
||||
}
|
||||
{
|
||||
// Request a ledger that doesn't exist yet.
|
||||
json::Value args{depositAuthArgs(alice, becky)};
|
||||
args[jss::ledger_index] = 17;
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "lgrNotFound", "ledgerNotFound");
|
||||
verifyErr(result, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound");
|
||||
}
|
||||
{
|
||||
// alice is not yet funded.
|
||||
json::Value const args{depositAuthArgs(alice, becky)};
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "srcActNotFound", "Source account not found.");
|
||||
verifyErr(result, "srcActNotFound", RpcSrcActNotFound, "Source account not found.");
|
||||
}
|
||||
env.fund(XRP(1000), alice);
|
||||
env.close();
|
||||
@@ -237,7 +253,8 @@ public:
|
||||
// becky is not yet funded.
|
||||
json::Value const args{depositAuthArgs(alice, becky)};
|
||||
json::Value const result{env.rpc("json", "deposit_authorized", args.toStyledString())};
|
||||
verifyErr(result, "dstActNotFound", "Destination account not found.");
|
||||
verifyErr(
|
||||
result, "dstActNotFound", RpcDstActNotFound, "Destination account not found.");
|
||||
}
|
||||
env.fund(XRP(1000), becky);
|
||||
env.close();
|
||||
@@ -256,9 +273,11 @@ public:
|
||||
jtx::Account const& dst,
|
||||
bool authorized,
|
||||
std::vector<std::string> credentialIDs = {},
|
||||
std::string_view error = "")
|
||||
std::string_view error = "",
|
||||
ErrorCodeI code = RpcSuccess,
|
||||
std::string_view errorMessage = "")
|
||||
{
|
||||
BEAST_EXPECT(result[jss::status] == authorized ? jss::success : jss::error);
|
||||
BEAST_EXPECT(result[jss::status] == (authorized ? jss::success : jss::error));
|
||||
if (result.isMember(jss::deposit_authorized))
|
||||
BEAST_EXPECT(result[jss::deposit_authorized] == authorized);
|
||||
if (authorized)
|
||||
@@ -270,7 +289,11 @@ public:
|
||||
|
||||
BEAST_EXPECT(result.isMember(jss::error) == !error.empty());
|
||||
if (!error.empty())
|
||||
{
|
||||
BEAST_EXPECT(result[jss::error].asString() == error);
|
||||
BEAST_EXPECT(result[jss::error_code] == code);
|
||||
BEAST_EXPECT(result[jss::error_message].asString() == errorMessage);
|
||||
}
|
||||
|
||||
if (authorized)
|
||||
{
|
||||
@@ -334,7 +357,15 @@ public:
|
||||
args[jss::credentials] = json::ValueType::Array;
|
||||
|
||||
auto const jv = env.rpc("json", "deposit_authorized", args.toStyledString());
|
||||
checkCredentialsResponse(jv[jss::result], alice, becky, false, {}, "invalidParams");
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{},
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'credentials', not is non-empty array of CredentialID(hash256).");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -348,7 +379,15 @@ public:
|
||||
args[jss::credentials].append(3);
|
||||
|
||||
auto const jv = env.rpc("json", "deposit_authorized", args.toStyledString());
|
||||
checkCredentialsResponse(jv[jss::result], alice, becky, false, {}, "invalidParams");
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{},
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'credentials', not an array of CredentialID(hash256).");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -362,7 +401,14 @@ public:
|
||||
|
||||
auto const jv = env.rpc("json", "deposit_authorized", args.toStyledString());
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], alice, becky, false, {"hello world"}, "invalidParams");
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{"hello world"},
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'credentials', not an array of CredentialID(hash256).");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -389,7 +435,9 @@ public:
|
||||
"0127AB8B4B29CCDBB61AA51C0799A8A6BB80B86A9899807C11ED576AF8516"
|
||||
"473",
|
||||
},
|
||||
"badCredentials");
|
||||
"badCredentials",
|
||||
RpcBadCredentials,
|
||||
"credentials don't exist");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -403,7 +451,14 @@ public:
|
||||
|
||||
auto const jv = env.rpc("json", "deposit_authorized", args.toStyledString());
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], alice, becky, false, {zero}, "badCredentials");
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{zero},
|
||||
"badCredentials",
|
||||
RpcBadCredentials,
|
||||
"credentials don't exist");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,7 +471,14 @@ public:
|
||||
"deposit_authorized",
|
||||
depositAuthArgs(alice, becky, "validated", {credIdx}).toStyledString());
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], alice, becky, false, {credIdx}, "badCredentials");
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{credIdx},
|
||||
"badCredentials",
|
||||
RpcBadCredentials,
|
||||
"credentials aren't accepted");
|
||||
}
|
||||
|
||||
// alice accept credentials
|
||||
@@ -430,7 +492,14 @@ public:
|
||||
"deposit_authorized",
|
||||
depositAuthArgs(alice, becky, "validated", {credIdx, credIdx}).toStyledString());
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], alice, becky, false, {credIdx, credIdx}, "badCredentials");
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{credIdx, credIdx},
|
||||
"badCredentials",
|
||||
RpcBadCredentials,
|
||||
"duplicates in credentials");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -453,7 +522,14 @@ public:
|
||||
"deposit_authorized",
|
||||
depositAuthArgs(alice, becky, "validated", kCredIds).toStyledString());
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], alice, becky, false, kCredIds, "invalidParams");
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
kCredIds,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'credentials', not array too long.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -500,7 +576,14 @@ public:
|
||||
"deposit_authorized",
|
||||
depositAuthArgs(becky, alice, "validated", {credDiana}).toStyledString());
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], becky, alice, false, {credDiana}, "badCredentials");
|
||||
jv[jss::result],
|
||||
becky,
|
||||
alice,
|
||||
false,
|
||||
{credDiana},
|
||||
"badCredentials",
|
||||
RpcBadCredentials,
|
||||
"credentials doesn't belong to the root account");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -549,7 +632,14 @@ public:
|
||||
depositAuthArgs(alice, becky, "validated", {credIdx2}).toStyledString());
|
||||
|
||||
checkCredentialsResponse(
|
||||
jv[jss::result], alice, becky, false, {credIdx2}, "badCredentials");
|
||||
jv[jss::result],
|
||||
alice,
|
||||
becky,
|
||||
false,
|
||||
{credIdx2},
|
||||
"badCredentials",
|
||||
RpcBadCredentials,
|
||||
"credentials are expired");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/AmendmentTable.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
@@ -206,6 +207,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
// feature names are case-sensitive - expect error here
|
||||
jrr = env.rpc("feature", "fMM")[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "badFeature");
|
||||
BEAST_EXPECT(jrr[jss::error_code] == RpcBadFeature);
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "Feature unknown or invalid.");
|
||||
|
||||
// Test feature name size checks
|
||||
@@ -253,6 +255,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
params[jss::feature] = param;
|
||||
auto jrr = env.rpc("json", "feature", 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 parameters.");
|
||||
};
|
||||
|
||||
@@ -266,6 +269,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
{
|
||||
auto jrr = env.rpc("feature", "AllTheThings")[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "badFeature");
|
||||
BEAST_EXPECT(jrr[jss::error_code] == RpcBadFeature);
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "Feature unknown or invalid.");
|
||||
}
|
||||
}
|
||||
@@ -320,6 +324,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
"EF";
|
||||
auto const result = env.rpc("json", "feature", to_string(params))[jss::result];
|
||||
BEAST_EXPECTS(result[jss::error] == "badFeature", result.toStyledString());
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcBadFeature);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Feature unknown or invalid.");
|
||||
}
|
||||
|
||||
@@ -332,6 +337,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
params[jss::vetoed] = true;
|
||||
auto const result = env.rpc("json", "feature", to_string(params))[jss::result];
|
||||
BEAST_EXPECTS(result[jss::error] == "noPermission", result[jss::error].asString());
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcNoPermission);
|
||||
BEAST_EXPECT(
|
||||
result[jss::error_message] == "You don't have permission for this command.");
|
||||
}
|
||||
@@ -513,6 +519,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
|
||||
auto const result = env.rpc("json", "feature", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid parameters.");
|
||||
};
|
||||
|
||||
@@ -521,6 +528,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
// anything other than accept or reject is an error
|
||||
jrr = env.rpc("feature", kFeatureName, "maybe");
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
@@ -584,6 +592,7 @@ class Feature_test : public beast::unit_test::Suite
|
||||
// anything other than accept or reject is an error
|
||||
jrr = env.rpc("feature", featureName, "maybe");
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <xrpl/beast/unit_test/suite.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
@@ -172,7 +173,12 @@ public:
|
||||
|
||||
auto response = jv[jss::result];
|
||||
auto const error = apiVersion < 2u ? "invalidHotWallet" : "invalidParams";
|
||||
auto const errorCode = apiVersion < 2u ? RpcInvalidHotwallet : RpcInvalidParams;
|
||||
auto const errorMessage =
|
||||
apiVersion < 2u ? "Invalid hotwallet." : "Invalid parameters.";
|
||||
BEAST_EXPECT(response[jss::error] == error);
|
||||
BEAST_EXPECT(response[jss::error_code] == errorCode);
|
||||
BEAST_EXPECT(response[jss::error_message] == errorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -201,6 +207,8 @@ public:
|
||||
auto jv = wsc->invoke("gateway_balances", qry);
|
||||
expect(jv[jss::status] == "error");
|
||||
BEAST_EXPECT(jv[jss::result][jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jv[jss::result][jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(jv[jss::result][jss::error_message] == "Invalid field 'account'.");
|
||||
});
|
||||
|
||||
// The same applies to a non-string "ident".
|
||||
@@ -212,6 +220,8 @@ public:
|
||||
auto jv = wsc->invoke("gateway_balances", qry2);
|
||||
expect(jv[jss::status] == "error");
|
||||
BEAST_EXPECT(jv[jss::result][jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jv[jss::result][jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(jv[jss::result][jss::error_message] == "Invalid field 'ident'.");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
@@ -42,10 +43,14 @@ public:
|
||||
auto const baseFee = env.current()->fees().base;
|
||||
// missing base_asset
|
||||
auto ret = Oracle::aggregatePrice(env, std::nullopt, "USD", kOracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Missing field 'base_asset'.");
|
||||
|
||||
// missing quote_asset
|
||||
ret = Oracle::aggregatePrice(env, "XRP", std::nullopt, kOracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Missing field 'quote_asset'.");
|
||||
|
||||
// invalid base_asset, quote_asset
|
||||
@@ -69,28 +74,44 @@ public:
|
||||
{
|
||||
ret = Oracle::aggregatePrice(env, "USD", v, kOracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Invalid parameters.");
|
||||
ret = Oracle::aggregatePrice(env, v, "USD", kOracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Invalid parameters.");
|
||||
ret = Oracle::aggregatePrice(env, v, v, kOracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Invalid parameters.");
|
||||
}
|
||||
|
||||
// missing oracles array
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD");
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Missing field 'oracles'.");
|
||||
|
||||
// empty oracles array
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD", OraclesData{});
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "oracleMalformed");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcOracleMalformed);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Oracle request is malformed.");
|
||||
|
||||
// no token pairs found
|
||||
ret = Oracle::aggregatePrice(env, "YAN", "USD", kOracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "objectNotFound");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcObjectNotFound);
|
||||
BEAST_EXPECT(
|
||||
ret[jss::error_message].asString() == "The requested object was not found.");
|
||||
|
||||
// invalid oracle document id
|
||||
// id doesn't exist
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD", {{{owner, 2}}});
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "objectNotFound");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcObjectNotFound);
|
||||
BEAST_EXPECT(
|
||||
ret[jss::error_message].asString() == "The requested object was not found.");
|
||||
// invalid values
|
||||
std::vector<AnyValue> const invalidDocument = {kNoneTag, 1.2, -1, "", "none", "1.2"};
|
||||
for (auto const& v : invalidDocument)
|
||||
@@ -99,17 +120,26 @@ public:
|
||||
json::Value jv;
|
||||
toJson(jv, v);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Invalid parameters.");
|
||||
}
|
||||
// missing document id
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD", {{{owner, std::nullopt}}});
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "oracleMalformed");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcOracleMalformed);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Oracle request is malformed.");
|
||||
|
||||
// invalid owner
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD", {{{some, 1}}});
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "objectNotFound");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcObjectNotFound);
|
||||
BEAST_EXPECT(
|
||||
ret[jss::error_message].asString() == "The requested object was not found.");
|
||||
// missing account
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD", {{{std::nullopt, 1}}});
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "oracleMalformed");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcOracleMalformed);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Oracle request is malformed.");
|
||||
|
||||
// oracles have wrong asset pair
|
||||
env.fund(XRP(1'000), owner);
|
||||
@@ -122,6 +152,9 @@ public:
|
||||
});
|
||||
ret = Oracle::aggregatePrice(env, "XRP", "USD", {{{owner, oracle.documentID()}}});
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "objectNotFound");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcObjectNotFound);
|
||||
BEAST_EXPECT(
|
||||
ret[jss::error_message].asString() == "The requested object was not found.");
|
||||
|
||||
// invalid trim value
|
||||
std::vector<AnyValue> const invalidTrim = {kNoneTag, 0, 26, -1, 1.2, "", "none", "1.2"};
|
||||
@@ -130,6 +163,8 @@ public:
|
||||
ret =
|
||||
Oracle::aggregatePrice(env, "XRP", "USD", {{{owner, oracle.documentID()}}}, v);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Invalid parameters.");
|
||||
}
|
||||
|
||||
// invalid time threshold value
|
||||
@@ -139,6 +174,8 @@ public:
|
||||
ret = Oracle::aggregatePrice(
|
||||
env, "XRP", "USD", {{{owner, oracle.documentID()}}}, std::nullopt, v);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "invalidParams");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Invalid parameters.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +194,8 @@ public:
|
||||
}
|
||||
auto const ret = Oracle::aggregatePrice(env, "XRP", "USD", oracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "oracleMalformed");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcOracleMalformed);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "Oracle request is malformed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +496,8 @@ public:
|
||||
// a nullptr dereference.
|
||||
auto const ret = Oracle::aggregatePrice(env, "XRP", "USD", oracles);
|
||||
BEAST_EXPECT(ret[jss::error].asString() == "objectNotFound");
|
||||
BEAST_EXPECT(ret[jss::error_code] == RpcObjectNotFound);
|
||||
BEAST_EXPECT(ret[jss::error_message].asString() == "The requested object was not found.");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+638
-343
File diff suppressed because it is too large.
Load diff
@@ -209,7 +209,12 @@ public:
|
||||
params[jss::seed_hex] = strings.masterSeedHex;
|
||||
|
||||
// Secret fields are mutually exclusive.
|
||||
BEAST_EXPECT(containsError(walletPropose(params)));
|
||||
auto const result = walletPropose(params);
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(
|
||||
result[jss::error_message] ==
|
||||
"Exactly one of the following must be specified: passphrase, seed or seed_hex");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -223,7 +228,8 @@ public:
|
||||
params[jss::key_type] = "secp256k1";
|
||||
params[jss::passphrase] = 20160506;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid field 'passphrase', not string.");
|
||||
}
|
||||
|
||||
@@ -232,7 +238,8 @@ public:
|
||||
params[jss::key_type] = "secp256k1";
|
||||
params[jss::seed] = json::ValueType::Object;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid field 'seed', not string.");
|
||||
}
|
||||
|
||||
@@ -241,7 +248,8 @@ public:
|
||||
params[jss::key_type] = "ed25519";
|
||||
params[jss::seed_hex] = json::ValueType::Array;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid field 'seed_hex', not string.");
|
||||
}
|
||||
|
||||
@@ -253,7 +261,8 @@ public:
|
||||
params[jss::seed_hex] = common::gMasterSeedHex;
|
||||
params[jss::seed] = common::gMasterSeed;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(
|
||||
result[jss::error_message] ==
|
||||
"Exactly one of the following must be specified: passphrase, "
|
||||
@@ -266,7 +275,8 @@ public:
|
||||
params[jss::key_type] = "prime256v1";
|
||||
params[jss::passphrase] = common::gMasterKey;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid parameters.");
|
||||
}
|
||||
|
||||
@@ -275,7 +285,8 @@ public:
|
||||
params[jss::key_type] = json::ValueType::Object;
|
||||
params[jss::seed_hex] = common::gMasterSeedHex;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid field 'key_type', not string.");
|
||||
}
|
||||
|
||||
@@ -284,7 +295,8 @@ public:
|
||||
params[jss::key_type] = json::ValueType::Array;
|
||||
params[jss::seed] = common::gMasterSeed;
|
||||
auto result = walletPropose(params);
|
||||
BEAST_EXPECT(containsError(result));
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid field 'key_type', not string.");
|
||||
}
|
||||
}
|
||||
@@ -402,8 +414,9 @@ public:
|
||||
json::Value error;
|
||||
params[jss::secret] = 314159265;
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'secret', not string.");
|
||||
}
|
||||
|
||||
@@ -414,8 +427,9 @@ public:
|
||||
params[jss::secret].append("array:0");
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'secret', not string.");
|
||||
}
|
||||
|
||||
@@ -427,8 +441,9 @@ public:
|
||||
params[jss::secret]["number"] = 702;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'secret', not string.");
|
||||
}
|
||||
|
||||
@@ -440,8 +455,9 @@ public:
|
||||
params[jss::secret] = common::gMasterSeed;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(
|
||||
error[jss::error_message] ==
|
||||
"The secret field is not allowed if key_type is used.");
|
||||
@@ -455,8 +471,9 @@ public:
|
||||
params[jss::passphrase] = common::gMasterKey;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'key_type'.");
|
||||
}
|
||||
|
||||
@@ -467,8 +484,9 @@ public:
|
||||
params[jss::seed_hex] = common::gMasterSeedHex;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'key_type', not string.");
|
||||
}
|
||||
|
||||
@@ -479,8 +497,9 @@ public:
|
||||
params[jss::seed] = common::gMasterSeed;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'key_type', not string.");
|
||||
}
|
||||
|
||||
@@ -492,8 +511,9 @@ public:
|
||||
params[jss::passphrase] = 1234567890;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'passphrase', not string.");
|
||||
}
|
||||
|
||||
@@ -504,8 +524,9 @@ public:
|
||||
params[jss::passphrase] = json::ValueType::Object;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'passphrase', not string.");
|
||||
}
|
||||
|
||||
@@ -516,8 +537,9 @@ public:
|
||||
params[jss::passphrase] = json::ValueType::Array;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'passphrase', not string.");
|
||||
}
|
||||
|
||||
@@ -528,8 +550,9 @@ public:
|
||||
params[jss::passphrase] = "";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -541,8 +564,9 @@ public:
|
||||
params[jss::seed] = 443556;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed', not string.");
|
||||
}
|
||||
|
||||
@@ -553,8 +577,9 @@ public:
|
||||
params[jss::seed] = json::ValueType::Object;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed', not string.");
|
||||
}
|
||||
|
||||
@@ -565,8 +590,9 @@ public:
|
||||
params[jss::seed] = json::ValueType::Array;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed', not string.");
|
||||
}
|
||||
|
||||
@@ -577,8 +603,9 @@ public:
|
||||
params[jss::seed] = "";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -589,8 +616,9 @@ public:
|
||||
params[jss::seed] = "s M V s h z D F p t Z E m h s";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -601,8 +629,9 @@ public:
|
||||
params[jss::seed] = "pnnjkbnobnml43679nbvjdsklnbjs";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -614,8 +643,9 @@ public:
|
||||
params[jss::seed_hex] = 443556;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed_hex', not string.");
|
||||
}
|
||||
|
||||
@@ -626,8 +656,9 @@ public:
|
||||
params[jss::seed_hex] = json::ValueType::Object;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed_hex', not string.");
|
||||
}
|
||||
|
||||
@@ -638,8 +669,9 @@ public:
|
||||
params[jss::seed_hex] = json::ValueType::Array;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcInvalidParams);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed_hex', not string.");
|
||||
}
|
||||
|
||||
@@ -650,8 +682,9 @@ public:
|
||||
params[jss::seed_hex] = "";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -662,8 +695,9 @@ public:
|
||||
params[jss::seed_hex] = "A670A19B";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -674,8 +708,9 @@ public:
|
||||
params[jss::seed_hex] = common::gPassphrase;
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
|
||||
@@ -686,8 +721,9 @@ public:
|
||||
params[jss::seed_hex] = "BE6A670A19B209E112146D0A7ED2AAD72567D0FC913";
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(!ret);
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
|
||||
}
|
||||
}
|
||||
@@ -723,7 +759,8 @@ public:
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(
|
||||
error[jss::error_message] == "Specified seed is for an Ed25519 wallet.");
|
||||
}
|
||||
@@ -754,7 +791,8 @@ public:
|
||||
|
||||
auto const ret = keypairForSignature(params, error);
|
||||
|
||||
BEAST_EXPECT(containsError(error));
|
||||
BEAST_EXPECT(error[jss::error] == "badSeed");
|
||||
BEAST_EXPECT(error[jss::error_code] == RpcBadSeed);
|
||||
BEAST_EXPECT(
|
||||
error[jss::error_message] == "Specified seed is for an Ed25519 wallet.");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
@@ -131,8 +132,9 @@ public:
|
||||
json::Value jvParams;
|
||||
jvParams[jss::limit] = "0"; // NOT an integer
|
||||
auto const jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
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 field 'limit', not integer.");
|
||||
}
|
||||
|
||||
@@ -141,8 +143,9 @@ public:
|
||||
json::Value jvParams;
|
||||
jvParams[jss::marker] = "NOT_A_MARKER";
|
||||
auto const jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
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 field 'marker', not valid.");
|
||||
}
|
||||
|
||||
@@ -151,8 +154,9 @@ public:
|
||||
json::Value jvParams;
|
||||
jvParams[jss::marker] = 1;
|
||||
auto const jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
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 field 'marker', not valid.");
|
||||
}
|
||||
|
||||
@@ -161,8 +165,9 @@ public:
|
||||
json::Value jvParams;
|
||||
jvParams[jss::ledger_index] = 10u;
|
||||
auto const jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
|
||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
|
||||
BEAST_EXPECT(jrr[jss::error_code] == RpcLgrNotFound);
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
|
||||
}
|
||||
|
||||
@@ -171,8 +176,9 @@ public:
|
||||
json::Value jvParams;
|
||||
jvParams[jss::binary] = "true";
|
||||
auto const jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
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 field 'binary', not boolean.");
|
||||
}
|
||||
}
|
||||
@@ -459,8 +465,8 @@ public:
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::type] = "misspelling";
|
||||
auto const jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember("error"));
|
||||
BEAST_EXPECT(jrr["error"] == "invalidParams");
|
||||
BEAST_EXPECT(jrr["error_code"] == RpcInvalidParams);
|
||||
BEAST_EXPECT(jrr["error_message"] == "Invalid field 'type'.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
json::Value const& jv,
|
||||
std::string const& err,
|
||||
ErrorCodeI code,
|
||||
std::string const& msg,
|
||||
std::source_location const location = std::source_location::current())
|
||||
{
|
||||
@@ -165,6 +166,14 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
"Expected error " + err + ", received " + jv[jss::error].asString() + ", at line " +
|
||||
std::to_string(location.line()) + ", " + jv.toStyledString());
|
||||
}
|
||||
if (BEAST_EXPECT(jv.isMember(jss::error_code)))
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
jv[jss::error_code] == code,
|
||||
"Expected error code " + std::to_string(code) + ", received " +
|
||||
jv[jss::error_code].asString() + ", at line " +
|
||||
std::to_string(location.line()) + ", " + jv.toStyledString());
|
||||
}
|
||||
if (msg.empty())
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
@@ -340,12 +349,21 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
apiVersion, "json", "ledger_entry", to_string(correctRequest))[jss::result];
|
||||
if (apiVersion < 2u)
|
||||
{
|
||||
checkErrorValue(jrr, "unknownOption", "", location);
|
||||
BEAST_EXPECTS(jrr[jss::status] == "error", std::to_string(location.line()));
|
||||
BEAST_EXPECTS(
|
||||
jrr[jss::error] == "unknownOption", std::to_string(location.line()));
|
||||
BEAST_EXPECTS(!jrr.isMember(jss::error_code), std::to_string(location.line()));
|
||||
BEAST_EXPECTS(
|
||||
jrr[jss::error_message].isNull(), std::to_string(location.line()));
|
||||
}
|
||||
else
|
||||
{
|
||||
checkErrorValue(
|
||||
jrr, "invalidParams", "No ledger_entry params provided.", location);
|
||||
jrr,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"No ledger_entry params provided.",
|
||||
location);
|
||||
}
|
||||
}
|
||||
auto const tryField = [&](json::Value fieldValue) -> void {
|
||||
@@ -354,7 +372,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
apiVersion, "json", "ledger_entry", to_string(correctRequest))[jss::result];
|
||||
auto const expectedErrMsg = rpc::expectedFieldMessage(
|
||||
fieldName, typeNameOverride.value_or(getTypeName(typeID)));
|
||||
checkErrorValue(jrr, expectedError, expectedErrMsg, location);
|
||||
checkErrorValue(jrr, expectedError, RpcInvalidParams, expectedErrMsg, location);
|
||||
};
|
||||
|
||||
auto const& badValues = getBadValues(typeID);
|
||||
@@ -387,13 +405,21 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
json::Value const jrr = env.rpc(
|
||||
apiVersion, "json", "ledger_entry", to_string(correctRequest))[jss::result];
|
||||
checkErrorValue(
|
||||
jrr, "malformedRequest", rpc::missingFieldMessage(fieldName.cStr()), location);
|
||||
jrr,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::missingFieldMessage(fieldName.cStr()),
|
||||
location);
|
||||
|
||||
correctRequest[parentFieldName][fieldName] = json::ValueType::Null;
|
||||
json::Value const jrr2 = env.rpc(
|
||||
apiVersion, "json", "ledger_entry", to_string(correctRequest))[jss::result];
|
||||
checkErrorValue(
|
||||
jrr2, "malformedRequest", rpc::missingFieldMessage(fieldName.cStr()), location);
|
||||
jrr2,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::missingFieldMessage(fieldName.cStr()),
|
||||
location);
|
||||
}
|
||||
auto const tryField = [&](json::Value fieldValue) -> void {
|
||||
correctRequest[parentFieldName][fieldName] = fieldValue;
|
||||
@@ -403,6 +429,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr,
|
||||
expectedError,
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(fieldName, getTypeName(typeID)),
|
||||
location);
|
||||
};
|
||||
@@ -497,7 +524,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
"AA";
|
||||
auto const jrr = env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "lgrNotFound", "ledgerNotFound");
|
||||
checkErrorValue(jrr, "lgrNotFound", RpcLgrNotFound, "ledgerNotFound");
|
||||
}
|
||||
{
|
||||
// Missing ledger_entry ledger_hash
|
||||
@@ -511,7 +538,10 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
json::Value const jrr = env.rpc(
|
||||
apiVersion, "json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(
|
||||
jrr, "invalidParams", "Invalid field 'ledger_hash', not hex string.");
|
||||
jrr,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'ledger_hash', not hex string.");
|
||||
};
|
||||
|
||||
auto const& badValues = getBadValues(typeId);
|
||||
@@ -530,7 +560,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
"00000000000000000000000000000000000000000000000000000000000000"
|
||||
"00";
|
||||
auto const jrr = env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
forAllApiVersions([&, this](unsigned apiVersion) {
|
||||
@@ -546,11 +576,15 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
|
||||
if (apiVersion < 2u)
|
||||
{
|
||||
checkErrorValue(jrr, "unknownOption", "");
|
||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||
BEAST_EXPECT(jrr[jss::error] == "unknownOption");
|
||||
BEAST_EXPECT(!jrr.isMember(jss::error_code));
|
||||
BEAST_EXPECT(jrr[jss::error_message].isNull());
|
||||
}
|
||||
else
|
||||
{
|
||||
checkErrorValue(jrr, "invalidParams", "No ledger_entry params provided.");
|
||||
checkErrorValue(
|
||||
jrr, "invalidParams", RpcInvalidParams, "No ledger_entry params provided.");
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -655,7 +689,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,7 +888,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Request an index that is not a check. We'll use alice's
|
||||
@@ -872,7 +906,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "unexpectedLedgerType", "Unexpected ledger type.");
|
||||
checkErrorValue(
|
||||
jrr, "unexpectedLedgerType", RpcUnexpectedLedgerType, "Unexpected ledger type.");
|
||||
}
|
||||
{
|
||||
// Check malformed cases
|
||||
@@ -931,7 +966,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
env,
|
||||
"48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
|
||||
"E4");
|
||||
checkErrorValue(jv[jss::result], "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jv[jss::result], "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1126,7 +1161,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
auto const expectedErrMsg = fieldValue.isNull()
|
||||
? rpc::missingFieldMessage(jss::issuer.cStr())
|
||||
: rpc::expectedFieldMessage(jss::issuer, "AccountID");
|
||||
checkErrorValue(jrr, "malformedAuthorizedCredentials", expectedErrMsg);
|
||||
checkErrorValue(
|
||||
jrr, "malformedAuthorizedCredentials", RpcInvalidParams, expectedErrMsg);
|
||||
};
|
||||
|
||||
auto const& badValues = getBadValues(FieldType::AccountField);
|
||||
@@ -1155,6 +1191,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr[jss::result],
|
||||
"malformedAuthorizedCredentials",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::authorized_credentials, "array"));
|
||||
}
|
||||
|
||||
@@ -1177,7 +1214,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
auto const expectedErrMsg = fieldValue.isNull()
|
||||
? rpc::missingFieldMessage(jss::credential_type.cStr())
|
||||
: rpc::expectedFieldMessage(jss::credential_type, "hex string");
|
||||
checkErrorValue(jrr, "malformedAuthorizedCredentials", expectedErrMsg);
|
||||
checkErrorValue(
|
||||
jrr, "malformedAuthorizedCredentials", RpcInvalidParams, expectedErrMsg);
|
||||
};
|
||||
|
||||
auto const& badValues = getBadValues(FieldType::BlobField);
|
||||
@@ -1207,6 +1245,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr[jss::result],
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Must have exactly one of `authorized` and "
|
||||
"`authorized_credentials`.");
|
||||
}
|
||||
@@ -1239,6 +1278,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr[jss::result],
|
||||
"malformedAuthorizedCredentials",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'authorized_credentials', not array of objects.");
|
||||
}
|
||||
|
||||
@@ -1257,6 +1297,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr[jss::result],
|
||||
"malformedAuthorizedCredentials",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'authorized_credentials', not array of objects.");
|
||||
}
|
||||
|
||||
@@ -1271,6 +1312,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr[jss::result],
|
||||
"malformedAuthorizedCredentials",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'authorized_credentials', array empty.");
|
||||
}
|
||||
|
||||
@@ -1308,6 +1350,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr[jss::result],
|
||||
"malformedAuthorizedCredentials",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'authorized_credentials', array too long.");
|
||||
}
|
||||
}
|
||||
@@ -1443,7 +1486,10 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(
|
||||
jrr, "malformedRequest", "Must have exactly one of `owner` and `dir_root` fields.");
|
||||
jrr,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Must have exactly one of `owner` and `dir_root` fields.");
|
||||
}
|
||||
{
|
||||
// Incomplete directory object. Missing both dir_root and owner.
|
||||
@@ -1454,7 +1500,10 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(
|
||||
jrr, "malformedRequest", "Must have exactly one of `owner` and `dir_root` fields.");
|
||||
jrr,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Must have exactly one of `owner` and `dir_root` fields.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1617,7 +1666,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::nft_offer][jss::seq] = offerSeq + 1000;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
// negative tests
|
||||
@@ -1835,7 +1884,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Request an index that is not a payment channel.
|
||||
@@ -1844,7 +1893,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1919,6 +1968,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'accounts', not length-2 array of "
|
||||
"Accounts.");
|
||||
}
|
||||
@@ -1937,6 +1987,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
"Invalid field 'accounts', not length-2 array of "
|
||||
"Accounts.");
|
||||
}
|
||||
@@ -1957,6 +2008,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr,
|
||||
"malformedAddress",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::accounts, "array of Accounts"));
|
||||
}
|
||||
|
||||
@@ -1972,6 +2024,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
checkErrorValue(
|
||||
jrr,
|
||||
"malformedAddress",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::accounts, "array of Accounts"));
|
||||
}
|
||||
};
|
||||
@@ -1994,7 +2047,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "malformedRequest", "Cannot have a trustline to self.");
|
||||
checkErrorValue(
|
||||
jrr, "malformedRequest", RpcInvalidParams, "Cannot have a trustline to self.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2048,7 +2102,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Request an index that is not a signer list.
|
||||
@@ -2057,7 +2111,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2148,7 +2202,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// First real ticket requested by index.
|
||||
@@ -2184,7 +2238,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Request a ticket using an account root entry.
|
||||
@@ -2193,7 +2247,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "unexpectedLedgerType", "Unexpected ledger type.");
|
||||
checkErrorValue(
|
||||
jrr, "unexpectedLedgerType", RpcUnexpectedLedgerType, "Unexpected ledger type.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2261,7 +2316,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::transaction_proposal][jss::ticket_seq] = ticketSeq + 1;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
auto const jrr = env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Lookup by an index of the wrong entry type.
|
||||
@@ -2269,7 +2324,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::transaction_proposal] = to_string(keylet::account(target).key);
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
auto const jrr = env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "unexpectedLedgerType", "Unexpected ledger type.");
|
||||
checkErrorValue(
|
||||
jrr, "unexpectedLedgerType", RpcUnexpectedLedgerType, "Unexpected ledger type.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2333,7 +2389,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Malformed DID index
|
||||
@@ -2455,7 +2511,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Request the MPToken using its owner + mptIssuanceID.
|
||||
@@ -2478,7 +2534,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// Malformed MPTIssuance index
|
||||
@@ -2546,7 +2602,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
"12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
|
||||
"DE";
|
||||
auto const jrr = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkErrorValue(jrr[jss::result], "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(
|
||||
jrr[jss::result], "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// test basic malformed scenarios
|
||||
@@ -2592,7 +2649,9 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
auto checkResult = [&](bool good,
|
||||
json::Value const& jv,
|
||||
json::StaticString const& expectedType,
|
||||
std::optional<std::string> const& expectedError = {}) {
|
||||
std::optional<std::string> const& expectedError = {},
|
||||
ErrorCodeI expectedCode = RpcEntryNotFound,
|
||||
std::string const& expectedMessage = "Entry not found.") {
|
||||
if (good)
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
@@ -2607,9 +2666,10 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
!jv[jss::result].isMember(jss::node) &&
|
||||
jv[jss::result][jss::error] == expectedError.value_or("entryNotFound"),
|
||||
jv[jss::result][jss::error] == expectedError.value_or("entryNotFound") &&
|
||||
jv[jss::result][jss::error_code] == expectedCode &&
|
||||
jv[jss::result][jss::error_message] == expectedMessage,
|
||||
to_string(jv));
|
||||
}
|
||||
};
|
||||
@@ -2640,7 +2700,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[field] = json::ValueType::Null;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, expectedType, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
expectedType,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(field, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2650,7 +2716,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[field] = "arbitrary string";
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, expectedType, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
expectedType,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(field, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2660,7 +2732,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[field] = false;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, expectedType, "invalidParams");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
expectedType,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(field, "true"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2672,7 +2750,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[field] = badKey;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, expectedType, "entryNotFound");
|
||||
checkResult(
|
||||
false, jv, expectedType, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
BEAST_EXPECTS(jv[jss::result][jss::index] == badKey, to_string(jv));
|
||||
}
|
||||
|
||||
@@ -2683,7 +2762,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::index] = field;
|
||||
params[jss::api_version] = 2;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, expectedType, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
expectedType,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::index, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2722,7 +2807,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::index] = field;
|
||||
params[jss::api_version] = 2;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, expectedType, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
expectedType,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::index, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2787,7 +2878,9 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
auto checkResult = [&](bool good,
|
||||
json::Value const& jv,
|
||||
int expectedCount,
|
||||
std::optional<std::string> const& expectedError = {}) {
|
||||
std::optional<std::string> const& expectedError = {},
|
||||
ErrorCodeI expectedCode = RpcEntryNotFound,
|
||||
std::string const& expectedMessage = "Entry not found.") {
|
||||
if (good)
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
@@ -2807,9 +2900,10 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
{
|
||||
BEAST_EXPECTS(
|
||||
jv.isObject() && jv.isMember(jss::result) &&
|
||||
jv[jss::result].isMember(jss::error) &&
|
||||
!jv[jss::result].isMember(jss::node) &&
|
||||
jv[jss::result][jss::error] == expectedError.value_or("entryNotFound"),
|
||||
jv[jss::result][jss::error] == expectedError.value_or("entryNotFound") &&
|
||||
jv[jss::result][jss::error_code] == expectedCode &&
|
||||
jv[jss::result][jss::error_message] == expectedMessage,
|
||||
to_string(jv));
|
||||
}
|
||||
};
|
||||
@@ -2839,7 +2933,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[jss::hashes] = json::ValueType::Null;
|
||||
auto jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, 0, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
0,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::hashes, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2849,7 +2949,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[jss::hashes] = "arbitrary string";
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, 0, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
0,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::hashes, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2859,7 +2965,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[jss::hashes] = "10";
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, 0, "malformedRequest");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
0,
|
||||
"malformedRequest",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::hashes, "hex string"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2869,7 +2981,13 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[jss::hashes] = false;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, 0, "invalidParams");
|
||||
checkResult(
|
||||
false,
|
||||
jv,
|
||||
0,
|
||||
"invalidParams",
|
||||
RpcInvalidParams,
|
||||
rpc::expectedFieldMessage(jss::hashes, "true"));
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2879,7 +2997,7 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[jss::hashes] = -1;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, 0, "internal");
|
||||
checkResult(false, jv, 0, "internal", RpcInternal, "Internal error.");
|
||||
BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
|
||||
}
|
||||
|
||||
@@ -2890,7 +3008,8 @@ class LedgerEntry_test : public beast::unit_test::Suite
|
||||
params[jss::ledger_index] = jss::validated;
|
||||
params[jss::hashes] = badKey;
|
||||
auto const jv = env.rpc("json", "ledger_entry", to_string(params));
|
||||
checkResult(false, jv, 0, "entryNotFound");
|
||||
checkResult(
|
||||
false, jv, 0, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
BEAST_EXPECT(jv[jss::result][jss::index] == badKey);
|
||||
}
|
||||
|
||||
@@ -3028,12 +3147,18 @@ class LedgerEntry_XChain_test : public beast::unit_test::Suite,
|
||||
public test::jtx::XChainBridgeObjects
|
||||
{
|
||||
void
|
||||
checkErrorValue(json::Value const& jv, std::string const& err, std::string const& msg)
|
||||
checkErrorValue(
|
||||
json::Value const& jv,
|
||||
std::string const& err,
|
||||
ErrorCodeI code,
|
||||
std::string const& msg)
|
||||
{
|
||||
if (BEAST_EXPECT(jv.isMember(jss::status)))
|
||||
BEAST_EXPECT(jv[jss::status] == "error");
|
||||
if (BEAST_EXPECT(jv.isMember(jss::error)))
|
||||
BEAST_EXPECT(jv[jss::error] == err);
|
||||
if (BEAST_EXPECT(jv.isMember(jss::error_code)))
|
||||
BEAST_EXPECT(jv[jss::error_code] == code);
|
||||
if (msg.empty())
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
@@ -3110,7 +3235,7 @@ class LedgerEntry_XChain_test : public beast::unit_test::Suite,
|
||||
json::Value const jrr =
|
||||
mcEnv.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
{
|
||||
// create two claim ids and verify that the bridge counter was
|
||||
@@ -3297,7 +3422,7 @@ class LedgerEntry_XChain_test : public beast::unit_test::Suite,
|
||||
[jss::xchain_owned_create_account_claim_id] = 1;
|
||||
json::Value const jrr =
|
||||
scEnv.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
checkErrorValue(jrr, "entryNotFound", "Entry not found.");
|
||||
checkErrorValue(jrr, "entryNotFound", RpcEntryNotFound, "Entry not found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 130 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user