rippled
Loading...
Searching...
No Matches
TransactionHistory_test.cpp
1#include <test/jtx.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/envconfig.h>
4
5#include <xrpl/protocol/jss.h>
6
7#include <boost/container/static_vector.hpp>
8
9#include <algorithm>
10
11namespace ripple {
12
14{
15 void
17 {
18 testcase("Invalid request params");
19 using namespace test::jtx;
20 Env env{*this, envconfig(no_admin)};
21
22 {
23 // no params
24 auto const result =
25 env.client().invoke("tx_history", {})[jss::result];
26 BEAST_EXPECT(result[jss::error] == "invalidParams");
27 BEAST_EXPECT(result[jss::status] == "error");
28 }
29
30 {
31 // test at 1 greater than the allowed non-admin limit
33 params[jss::start] = 10001; // limited to <= 10000 for non admin
34 auto const result =
35 env.client().invoke("tx_history", params)[jss::result];
36 BEAST_EXPECT(result[jss::error] == "noPermission");
37 BEAST_EXPECT(result[jss::status] == "error");
38 }
39 }
40
41 void
43 {
44 testcase("Command retired from API v2");
45 using namespace test::jtx;
46 Env env{*this, envconfig(no_admin)};
47
49 params[jss::api_version] = 2;
50 auto const result =
51 env.client().invoke("tx_history", params)[jss::result];
52 BEAST_EXPECT(result[jss::error] == "unknownCmd");
53 BEAST_EXPECT(result[jss::status] == "error");
54 }
55
56 void
58 {
59 testcase("Basic request");
60 using namespace test::jtx;
61 Env env{*this};
62
63 // create enough transactions to provide some
64 // history...
65 size_t const numAccounts = 20;
66 boost::container::static_vector<Account, numAccounts> accounts;
67 for (size_t i = 0; i < numAccounts; ++i)
68 {
69 accounts.emplace_back("A" + std::to_string(i));
70 auto const& acct = accounts.back();
71 env.fund(XRP(10000), acct);
72 env.close();
73 if (i > 0)
74 {
75 auto const& prev = accounts[i - 1];
76 env.trust(acct["USD"](1000), prev);
77 env(pay(acct, prev, acct["USD"](5)));
78 }
79 env(offer(acct, XRP(100), acct["USD"](1)));
80 env.close();
81
82 // verify the latest transaction in env (offer)
83 // is available in tx_history.
85 params[jss::start] = 0;
86 auto result =
87 env.client().invoke("tx_history", params)[jss::result];
88 if (!BEAST_EXPECT(
89 result[jss::txs].isArray() && result[jss::txs].size() > 0))
90 return;
91
92 // search for a tx in history matching the last offer
93 bool const txFound = [&] {
94 auto const toFind = env.tx()->getJson(JsonOptions::none);
95 for (auto tx : result[jss::txs])
96 {
97 tx.removeMember(jss::inLedger);
98 tx.removeMember(jss::ledger_index);
99 if (toFind == tx)
100 return true;
101 }
102 return false;
103 }();
104 BEAST_EXPECT(txFound);
105 }
106
107 unsigned int start = 0;
108 unsigned int total = 0;
109 // also summarize the transaction types in this map
111 while (start < 120)
112 {
114 params[jss::start] = start;
115 auto result =
116 env.client().invoke("tx_history", params)[jss::result];
117 if (!BEAST_EXPECT(
118 result[jss::txs].isArray() && result[jss::txs].size() > 0))
119 break;
120 total += result[jss::txs].size();
121 start += 20;
122 for (auto const& t : result[jss::txs])
123 {
124 typeCounts[t[sfTransactionType.fieldName].asString()]++;
125 }
126 }
127 BEAST_EXPECT(total == 117);
128 BEAST_EXPECT(typeCounts[jss::AccountSet.c_str()] == 20);
129 BEAST_EXPECT(typeCounts[jss::TrustSet.c_str()] == 19);
130 BEAST_EXPECT(typeCounts[jss::Payment.c_str()] == 58);
131 BEAST_EXPECT(typeCounts[jss::OfferCreate.c_str()] == 20);
132
133 // also, try a request with max non-admin start value
134 {
136 params[jss::start] = 10000; // limited to <= 10000 for non admin
137 auto const result =
138 env.client().invoke("tx_history", params)[jss::result];
139 BEAST_EXPECT(result[jss::status] == "success");
140 BEAST_EXPECT(result[jss::index] == 10000);
141 }
142 }
143
144public:
145 void
146 run() override
147 {
148 testBadInput();
149 testRequest();
151 }
152};
153
154BEAST_DEFINE_TESTSUITE(TransactionHistory, rpc, ripple);
155
156} // namespace ripple
Represents a JSON value.
Definition json_value.h:130
UInt size() const
Number of values in array or object.
Value removeMember(char const *key)
Remove and return the named member.
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
void run() override
Runs the suite.
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
T to_string(T... args)