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()),
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;
155BEAST_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.
Immutable cryptographic account descriptor.
A transaction testing environment.
Sets the SendMax on a JTx.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
XRP_t const XRP
Converts to XRP Issue or STAmount.
FeatureBitset supported_amendments()
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)