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