xrpld
Loading...
Searching...
No Matches
TransactionHistory_test.cpp
1#include <test/jtx/Account.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/amount.h>
4#include <test/jtx/envconfig.h>
5#include <test/jtx/offer.h>
6#include <test/jtx/pay.h>
7
8#include <xrpl/beast/unit_test/suite.h>
9#include <xrpl/json/json_value.h>
10#include <xrpl/protocol/SField.h>
11#include <xrpl/protocol/jss.h>
12
13#include <boost/container/static_vector.hpp>
14
15#include <cstddef>
16#include <string>
17#include <unordered_map>
18
19namespace xrpl {
20
22{
23 void
25 {
26 testcase("Invalid request params");
27 using namespace test::jtx;
28 Env env{*this, envconfig(noAdmin)};
29
30 {
31 // no params
32 auto const result = env.client().invoke("tx_history", {})[jss::result];
33 BEAST_EXPECT(result[jss::error] == "invalidParams");
34 BEAST_EXPECT(result[jss::status] == "error");
35 }
36
37 {
38 // test at 1 greater than the allowed non-admin limit
40 params[jss::start] = 10001; // limited to <= 10000 for non admin
41 auto const result = env.client().invoke("tx_history", params)[jss::result];
42 BEAST_EXPECT(result[jss::error] == "noPermission");
43 BEAST_EXPECT(result[jss::status] == "error");
44 }
45 }
46
47 void
49 {
50 testcase("Command retired from API v2");
51 using namespace test::jtx;
52 Env env{*this, envconfig(noAdmin)};
53
55 params[jss::api_version] = 2;
56 auto const result = env.client().invoke("tx_history", params)[jss::result];
57 BEAST_EXPECT(result[jss::error] == "unknownCmd");
58 BEAST_EXPECT(result[jss::status] == "error");
59 }
60
61 void
63 {
64 testcase("Basic request");
65 using namespace test::jtx;
66 Env env{*this};
67
68 // create enough transactions to provide some
69 // history...
70 size_t const numAccounts = 20;
71 boost::container::static_vector<Account, numAccounts> accounts;
72 for (size_t i = 0; i < numAccounts; ++i)
73 {
74 accounts.emplace_back("A" + std::to_string(i));
75 auto const& acct = accounts.back();
76 env.fund(XRP(10000), acct);
77 env.close();
78 if (i > 0)
79 {
80 auto const& prev = accounts[i - 1];
81 env.trust(acct["USD"](1000), prev);
82 env(pay(acct, prev, acct["USD"](5)));
83 }
84 env(offer(acct, XRP(100), acct["USD"](1)));
85 env.close();
86
87 // verify the latest transaction in env (offer)
88 // is available in tx_history.
90 params[jss::start] = 0;
91 auto result = env.client().invoke("tx_history", params)[jss::result];
92 if (!BEAST_EXPECT(result[jss::txs].isArray() && result[jss::txs].size() > 0))
93 return;
94
95 // search for a tx in history matching the last offer
96 bool const txFound = [&] {
97 auto const toFind = env.tx()->getJson(JsonOptions::Values::None);
98 for (auto tx : result[jss::txs])
99 {
100 tx.removeMember(jss::inLedger);
101 tx.removeMember(jss::ledger_index);
102 if (toFind == tx)
103 return true;
104 }
105 return false;
106 }();
107 BEAST_EXPECT(txFound);
108 }
109
110 unsigned int start = 0;
111 unsigned int total = 0;
112 // also summarize the transaction types in this map
114 while (start < 120)
115 {
117 params[jss::start] = start;
118 auto result = env.client().invoke("tx_history", params)[jss::result];
119 if (!BEAST_EXPECT(result[jss::txs].isArray() && result[jss::txs].size() > 0))
120 break;
121 total += result[jss::txs].size();
122 start += 20;
123 for (auto const& t : result[jss::txs])
124 {
125 typeCounts[t[sfTransactionType.fieldName].asString()]++;
126 }
127 }
128 BEAST_EXPECT(total == 117);
129 BEAST_EXPECT(typeCounts[jss::AccountSet.cStr()] == 20);
130 BEAST_EXPECT(typeCounts[jss::TrustSet.cStr()] == 19);
131 BEAST_EXPECT(typeCounts[jss::Payment.cStr()] == 58);
132 BEAST_EXPECT(typeCounts[jss::OfferCreate.cStr()] == 20);
133
134 // also, try a request with max non-admin start value
135 {
137 params[jss::start] = 10000; // limited to <= 10000 for non admin
138 auto const result = 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, xrpl);
155
156} // namespace xrpl
A testsuite class.
Definition suite.h:50
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:149
Represents a JSON value.
Definition json_value.h:130
UInt size() const
Number of values in array or object.
void run() override
Runs the suite.
@ Object
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:5
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl)
T to_string(T... args)