rippled
Loading...
Searching...
No Matches
AmendmentBlocked_test.cpp
1#include <test/jtx.h>
2#include <test/jtx/WSClient.h>
3
4#include <xrpld/core/ConfigSections.h>
5
6#include <xrpl/protocol/jss.h>
7#include <xrpl/server/NetworkOPs.h>
8
9namespace xrpl {
10
12{
13 void
15 {
16 using namespace test::jtx;
17 Env env{*this, envconfig([](std::unique_ptr<Config> cfg) {
18 cfg->loadFromString("[" SECTION_SIGNING_SUPPORT "]\ntrue");
19 return cfg;
20 })};
21 auto const gw = Account{"gateway"};
22 auto const USD = gw["USD"];
23 auto const alice = Account{"alice"};
24 auto const bob = Account{"bob"};
25 Account const ali{"ali", KeyType::secp256k1};
26 env.fund(XRP(10000), alice, bob, gw);
27 env.memoize(ali);
28 // This close() ensures that all the accounts get created and their
29 // default ripple flag gets set before the trust lines are created.
30 // Without it, the ordering manages to create alice's trust line with
31 // noRipple set on gw's end. The existing tests pass either way, but
32 // better to do it right.
33 env.close();
34 env.trust(USD(600), alice);
35 env.trust(USD(700), bob);
36 env(pay(gw, alice, USD(70)));
37 env(pay(gw, bob, USD(50)));
38 env.close();
39
40 auto wsc = test::makeWSClient(env.app().config());
41
42 auto current = env.current();
43 // ledger_accept
44 auto jr = env.rpc("ledger_accept")[jss::result];
45 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
46 BEAST_EXPECT(!jr.isMember(jss::warnings));
47
48 // ledger_current
49 jr = env.rpc("ledger_current")[jss::result];
50 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
51 BEAST_EXPECT(!jr.isMember(jss::warnings));
52
53 // owner_info
54 jr = env.rpc("owner_info", alice.human())[jss::result];
55 BEAST_EXPECT(jr.isMember(jss::accepted) && jr.isMember(jss::current));
56 BEAST_EXPECT(!jr.isMember(jss::warnings));
57
58 // path_find
59 Json::Value pf_req;
60 pf_req[jss::subcommand] = "create";
61 pf_req[jss::source_account] = alice.human();
62 pf_req[jss::destination_account] = bob.human();
63 pf_req[jss::destination_amount] = bob["USD"](20).value().getJson(JsonOptions::none);
64 jr = wsc->invoke("path_find", pf_req)[jss::result];
65 BEAST_EXPECT(
66 jr.isMember(jss::alternatives) && jr[jss::alternatives].isArray() &&
67 jr[jss::alternatives].size() == 1);
68 BEAST_EXPECT(!jr.isMember(jss::warnings));
69
70 // submit
71 auto jt = env.jt(noop(alice));
72 Serializer s;
73 jt.stx->add(s);
74 jr = env.rpc("submit", strHex(s.slice()))[jss::result];
75 BEAST_EXPECT(jr.isMember(jss::engine_result) && jr[jss::engine_result] == "tesSUCCESS");
76 BEAST_EXPECT(!jr.isMember(jss::warnings));
77
78 // submit_multisigned
79 env(signers(bob, 1, {{alice, 1}}), sig(bob));
80 env(regkey(alice, ali));
81 env.close();
82
83 Json::Value set_tx;
84 set_tx[jss::Account] = bob.human();
85 set_tx[jss::TransactionType] = jss::AccountSet;
86 set_tx[jss::Fee] = (8 * env.current()->fees().base).jsonClipped();
87 set_tx[jss::Sequence] = env.seq(bob);
88 set_tx[jss::SigningPubKey] = "";
89
90 Json::Value sign_for;
91 sign_for[jss::tx_json] = set_tx;
92 sign_for[jss::account] = alice.human();
93 sign_for[jss::secret] = ali.name();
94 jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
95 BEAST_EXPECT(jr[jss::status] == "success");
96 BEAST_EXPECT(!jr.isMember(jss::warnings));
97
98 Json::Value ms_req;
99 ms_req[jss::tx_json] = jr[jss::tx_json];
100 jr = env.rpc("json", "submit_multisigned", to_string(ms_req))[jss::result];
101 BEAST_EXPECT(jr.isMember(jss::engine_result) && jr[jss::engine_result] == "tesSUCCESS");
102 BEAST_EXPECT(!jr.isMember(jss::warnings));
103
104 // set up an amendment warning. Nothing changes
105
106 env.app().getOPs().setAmendmentWarned();
107
108 current = env.current();
109 // ledger_accept
110 jr = env.rpc("ledger_accept")[jss::result];
111 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
112 BEAST_EXPECT(!jr.isMember(jss::warnings));
113
114 // ledger_current
115 jr = env.rpc("ledger_current")[jss::result];
116 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
117 BEAST_EXPECT(!jr.isMember(jss::warnings));
118
119 // owner_info
120 jr = env.rpc("owner_info", alice.human())[jss::result];
121 BEAST_EXPECT(jr.isMember(jss::accepted) && jr.isMember(jss::current));
122 BEAST_EXPECT(!jr.isMember(jss::warnings));
123
124 // path_find
125 pf_req[jss::subcommand] = "create";
126 pf_req[jss::source_account] = alice.human();
127 pf_req[jss::destination_account] = bob.human();
128 pf_req[jss::destination_amount] = bob["USD"](20).value().getJson(JsonOptions::none);
129 jr = wsc->invoke("path_find", pf_req)[jss::result];
130 BEAST_EXPECT(
131 jr.isMember(jss::alternatives) && jr[jss::alternatives].isArray() &&
132 jr[jss::alternatives].size() == 1);
133 BEAST_EXPECT(!jr.isMember(jss::warnings));
134
135 // submit
136 jt = env.jt(noop(alice));
137 s.erase();
138 jt.stx->add(s);
139 jr = env.rpc("submit", strHex(s.slice()))[jss::result];
140 BEAST_EXPECT(jr.isMember(jss::engine_result) && jr[jss::engine_result] == "tesSUCCESS");
141 BEAST_EXPECT(!jr.isMember(jss::warnings));
142
143 // submit_multisigned
144 env(signers(bob, 1, {{alice, 1}}), sig(bob));
145 env(regkey(alice, ali));
146 env.close();
147
148 set_tx[jss::Account] = bob.human();
149 set_tx[jss::TransactionType] = jss::AccountSet;
150 set_tx[jss::Fee] = (8 * env.current()->fees().base).jsonClipped();
151 set_tx[jss::Sequence] = env.seq(bob);
152 set_tx[jss::SigningPubKey] = "";
153
154 sign_for[jss::tx_json] = set_tx;
155 sign_for[jss::account] = alice.human();
156 sign_for[jss::secret] = ali.name();
157 jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
158 BEAST_EXPECT(jr[jss::status] == "success");
159 BEAST_EXPECT(!jr.isMember(jss::warnings));
160
161 ms_req[jss::tx_json] = jr[jss::tx_json];
162 jr = env.rpc("json", "submit_multisigned", to_string(ms_req))[jss::result];
163 BEAST_EXPECT(jr.isMember(jss::engine_result) && jr[jss::engine_result] == "tesSUCCESS");
164 BEAST_EXPECT(!jr.isMember(jss::warnings));
165
166 // make the network amendment blocked...now all the same
167 // requests should fail
168
169 env.app().getOPs().setAmendmentBlocked();
170
171 // ledger_accept
172 jr = env.rpc("ledger_accept")[jss::result];
173 BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
174 BEAST_EXPECT(jr[jss::status] == "error");
175 BEAST_EXPECT(!jr.isMember(jss::warnings));
176
177 // ledger_current
178 jr = env.rpc("ledger_current")[jss::result];
179 BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
180 BEAST_EXPECT(jr[jss::status] == "error");
181 BEAST_EXPECT(!jr.isMember(jss::warnings));
182
183 // owner_info
184 jr = env.rpc("owner_info", alice.human())[jss::result];
185 BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
186 BEAST_EXPECT(jr[jss::status] == "error");
187 BEAST_EXPECT(!jr.isMember(jss::warnings));
188
189 // path_find
190 jr = wsc->invoke("path_find", pf_req)[jss::result];
191 BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
192 BEAST_EXPECT(jr[jss::status] == "error");
193 BEAST_EXPECT(!jr.isMember(jss::warnings));
194
195 // submit
196 jr = env.rpc("submit", strHex(s.slice()))[jss::result];
197 BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
198 BEAST_EXPECT(jr[jss::status] == "error");
199 BEAST_EXPECT(!jr.isMember(jss::warnings));
200
201 // submit_multisigned
202 set_tx[jss::Sequence] = env.seq(bob);
203 sign_for[jss::tx_json] = set_tx;
204 jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
205 BEAST_EXPECT(jr[jss::status] == "success");
206 ms_req[jss::tx_json] = jr[jss::tx_json];
207 jr = env.rpc("json", "submit_multisigned", to_string(ms_req))[jss::result];
208 BEAST_EXPECT(jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
209 BEAST_EXPECT(!jr.isMember(jss::warnings));
210 }
211
212public:
213 void
214 run() override
215 {
217 }
218};
219
220BEAST_DEFINE_TESTSUITE(AmendmentBlocked, rpc, xrpl);
221
222} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
A testsuite class.
Definition suite.h:51
void run() override
Runs the suite.
Slice slice() const noexcept
Definition Serializer.h:44
std::unique_ptr< WSClient > makeWSClient(Config const &cfg, bool v2, unsigned rpc_version, std::unordered_map< std::string, std::string > const &headers)
Returns a client operating through WebSockets/S.
Definition WSClient.cpp:296
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:602
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
@ current
This was a new validation and was added.