21#include <test/jtx/Env.h>
22#include <test/jtx/PathSet.h>
24#include <xrpl/beast/core/LexicalCast.h>
25#include <xrpl/beast/unit_test.h>
26#include <xrpl/protocol/Feature.h>
27#include <xrpl/protocol/SField.h>
28#include <xrpl/protocol/jss.h>
42 testcase(
"Discrepancy test : XRP Discrepancy");
43 using namespace test::jtx;
44 Env env{*
this, features};
54 env.fund(XRP(2000), A1);
55 env.fund(XRP(1000), A2, A6, A7);
56 env.fund(XRP(5000), A3);
57 env.fund(XRP(1000000), A4);
58 env.fund(XRP(600000), A5);
61 env(trust(A1, A3[
"CNY"](200000)));
62 env(pay(A3, A1, A3[
"CNY"](31)));
65 env(trust(A1, A2[
"JPY"](1000000)));
66 env(pay(A2, A1, A2[
"JPY"](729117)));
69 env(trust(A4, A2[
"JPY"](10000000)));
70 env(pay(A2, A4, A2[
"JPY"](470056)));
73 env(trust(A5, A3[
"CNY"](50000)));
74 env(pay(A3, A5, A3[
"CNY"](8683)));
77 env(trust(A6, A3[
"CNY"](3000)));
78 env(pay(A3, A6, A3[
"CNY"](293)));
81 env(trust(A7, A6[
"CNY"](50000)));
82 env(pay(A6, A7, A6[
"CNY"](261)));
85 env(offer(A4, XRP(49147), A2[
"JPY"](34501)));
86 env(offer(A5, A3[
"CNY"](3150), XRP(80086)));
87 env(offer(A7, XRP(1233), A6[
"CNY"](25)));
95 env(pay(A1, A1, A2[
"JPY"](1000)),
96 json(payPaths.json()),
98 sendmax(A3[
"CNY"](56)));
102 jrq2[jss::binary] =
false;
103 jrq2[jss::transaction] =
106 auto jrr = env.rpc(
"json",
"tx",
to_string(jrq2))[jss::result];
107 uint64_t fee{jrr[jss::Fee].
asUInt()};
108 auto meta = jrr[jss::meta];
110 uint64_t sumFinal{0};
111 BEAST_EXPECT(meta[sfAffectedNodes.fieldName].size() == 9);
112 for (
auto const& an : meta[sfAffectedNodes.fieldName])
115 if (an.isMember(sfCreatedNode.fieldName))
116 node = an[sfCreatedNode.fieldName];
117 else if (an.isMember(sfModifiedNode.fieldName))
118 node = an[sfModifiedNode.fieldName];
119 else if (an.isMember(sfDeletedNode.fieldName))
120 node = an[sfDeletedNode.fieldName];
122 if (node && node[sfLedgerEntryType.fieldName] == jss::AccountRoot)
125 node.
isMember(sfPreviousFields.fieldName)
126 ? node[sfPreviousFields.fieldName]
127 : node[sfNewFields.fieldName];
129 ? node[sfFinalFields.fieldName]
130 : node[sfNewFields.fieldName];
132 sumPrev += beast::lexicalCastThrow<std::uint64_t>(
133 prevFields[sfBalance.fieldName].
asString());
135 sumFinal += beast::lexicalCastThrow<std::uint64_t>(
136 finalFields[sfBalance.fieldName].
asString());
141 BEAST_EXPECT(sumPrev - sumFinal == fee);
148 using namespace test::jtx;
149 auto const sa = supported_amendments();
156BEAST_DEFINE_TESTSUITE(Discrepancy, app,
ripple);
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
testcase_t testcase
Memberspace for declaring test cases.
void testXRPDiscrepancy(FeatureBitset features)
void run() override
Runs the suite.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t tfPartialPayment
std::string to_string(base_uint< Bits, Tag > const &a)