rippled
Loading...
Searching...
No Matches
AmendmentBlocked_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2017 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <test/jtx.h>
21#include <test/jtx/WSClient.h>
22#include <xrpld/app/misc/NetworkOPs.h>
23#include <xrpld/core/ConfigSections.h>
24#include <xrpl/protocol/ErrorCodes.h>
25#include <xrpl/protocol/jss.h>
26
27namespace ripple {
28
30{
31 void
33 {
34 using namespace test::jtx;
35 Env env{*this, envconfig([](std::unique_ptr<Config> cfg) {
36 cfg->loadFromString("[" SECTION_SIGNING_SUPPORT "]\ntrue");
37 return cfg;
38 })};
39 auto const gw = Account{"gateway"};
40 auto const USD = gw["USD"];
41 auto const alice = Account{"alice"};
42 auto const bob = Account{"bob"};
43 Account const ali{"ali", KeyType::secp256k1};
44 env.fund(XRP(10000), alice, bob, gw);
45 env.memoize(ali);
46 // This close() ensures that all the accounts get created and their
47 // default ripple flag gets set before the trust lines are created.
48 // Without it, the ordering manages to create alice's trust line with
49 // noRipple set on gw's end. The existing tests pass either way, but
50 // better to do it right.
51 env.close();
52 env.trust(USD(600), alice);
53 env.trust(USD(700), bob);
54 env(pay(gw, alice, USD(70)));
55 env(pay(gw, bob, USD(50)));
56 env.close();
57
58 auto wsc = test::makeWSClient(env.app().config());
59
60 auto current = env.current();
61 // ledger_accept
62 auto jr = env.rpc("ledger_accept")[jss::result];
63 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
64 BEAST_EXPECT(!jr.isMember(jss::warnings));
65
66 // ledger_current
67 jr = env.rpc("ledger_current")[jss::result];
68 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
69 BEAST_EXPECT(!jr.isMember(jss::warnings));
70
71 // owner_info
72 jr = env.rpc("owner_info", alice.human())[jss::result];
73 BEAST_EXPECT(jr.isMember(jss::accepted) && jr.isMember(jss::current));
74 BEAST_EXPECT(!jr.isMember(jss::warnings));
75
76 // path_find
77 Json::Value pf_req;
78 pf_req[jss::subcommand] = "create";
79 pf_req[jss::source_account] = alice.human();
80 pf_req[jss::destination_account] = bob.human();
81 pf_req[jss::destination_amount] =
82 bob["USD"](20).value().getJson(JsonOptions::none);
83 jr = wsc->invoke("path_find", pf_req)[jss::result];
84 BEAST_EXPECT(
85 jr.isMember(jss::alternatives) && jr[jss::alternatives].isArray() &&
86 jr[jss::alternatives].size() == 1);
87 BEAST_EXPECT(!jr.isMember(jss::warnings));
88
89 // submit
90 auto jt = env.jt(noop(alice));
91 Serializer s;
92 jt.stx->add(s);
93 jr = env.rpc("submit", strHex(s.slice()))[jss::result];
94 BEAST_EXPECT(
95 jr.isMember(jss::engine_result) &&
96 jr[jss::engine_result] == "tesSUCCESS");
97 BEAST_EXPECT(!jr.isMember(jss::warnings));
98
99 // submit_multisigned
100 env(signers(bob, 1, {{alice, 1}}), sig(bob));
101 env(regkey(alice, ali));
102 env.close();
103
104 Json::Value set_tx;
105 set_tx[jss::Account] = bob.human();
106 set_tx[jss::TransactionType] = jss::AccountSet;
107 set_tx[jss::Fee] = (8 * env.current()->fees().base).jsonClipped();
108 set_tx[jss::Sequence] = env.seq(bob);
109 set_tx[jss::SigningPubKey] = "";
110
111 Json::Value sign_for;
112 sign_for[jss::tx_json] = set_tx;
113 sign_for[jss::account] = alice.human();
114 sign_for[jss::secret] = ali.name();
115 jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
116 BEAST_EXPECT(jr[jss::status] == "success");
117 BEAST_EXPECT(!jr.isMember(jss::warnings));
118
119 Json::Value ms_req;
120 ms_req[jss::tx_json] = jr[jss::tx_json];
121 jr = env.rpc(
122 "json", "submit_multisigned", to_string(ms_req))[jss::result];
123 BEAST_EXPECT(
124 jr.isMember(jss::engine_result) &&
125 jr[jss::engine_result] == "tesSUCCESS");
126 BEAST_EXPECT(!jr.isMember(jss::warnings));
127
128 // set up an amendment warning. Nothing changes
129
130 env.app().getOPs().setAmendmentWarned();
131
132 current = env.current();
133 // ledger_accept
134 jr = env.rpc("ledger_accept")[jss::result];
135 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
136 BEAST_EXPECT(!jr.isMember(jss::warnings));
137
138 // ledger_current
139 jr = env.rpc("ledger_current")[jss::result];
140 BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
141 BEAST_EXPECT(!jr.isMember(jss::warnings));
142
143 // owner_info
144 jr = env.rpc("owner_info", alice.human())[jss::result];
145 BEAST_EXPECT(jr.isMember(jss::accepted) && jr.isMember(jss::current));
146 BEAST_EXPECT(!jr.isMember(jss::warnings));
147
148 // path_find
149 pf_req[jss::subcommand] = "create";
150 pf_req[jss::source_account] = alice.human();
151 pf_req[jss::destination_account] = bob.human();
152 pf_req[jss::destination_amount] =
153 bob["USD"](20).value().getJson(JsonOptions::none);
154 jr = wsc->invoke("path_find", pf_req)[jss::result];
155 BEAST_EXPECT(
156 jr.isMember(jss::alternatives) && jr[jss::alternatives].isArray() &&
157 jr[jss::alternatives].size() == 1);
158 BEAST_EXPECT(!jr.isMember(jss::warnings));
159
160 // submit
161 jt = env.jt(noop(alice));
162 s.erase();
163 jt.stx->add(s);
164 jr = env.rpc("submit", strHex(s.slice()))[jss::result];
165 BEAST_EXPECT(
166 jr.isMember(jss::engine_result) &&
167 jr[jss::engine_result] == "tesSUCCESS");
168 BEAST_EXPECT(!jr.isMember(jss::warnings));
169
170 // submit_multisigned
171 env(signers(bob, 1, {{alice, 1}}), sig(bob));
172 env(regkey(alice, ali));
173 env.close();
174
175 set_tx[jss::Account] = bob.human();
176 set_tx[jss::TransactionType] = jss::AccountSet;
177 set_tx[jss::Fee] = (8 * env.current()->fees().base).jsonClipped();
178 set_tx[jss::Sequence] = env.seq(bob);
179 set_tx[jss::SigningPubKey] = "";
180
181 sign_for[jss::tx_json] = set_tx;
182 sign_for[jss::account] = alice.human();
183 sign_for[jss::secret] = ali.name();
184 jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
185 BEAST_EXPECT(jr[jss::status] == "success");
186 BEAST_EXPECT(!jr.isMember(jss::warnings));
187
188 ms_req[jss::tx_json] = jr[jss::tx_json];
189 jr = env.rpc(
190 "json", "submit_multisigned", to_string(ms_req))[jss::result];
191 BEAST_EXPECT(
192 jr.isMember(jss::engine_result) &&
193 jr[jss::engine_result] == "tesSUCCESS");
194 BEAST_EXPECT(!jr.isMember(jss::warnings));
195
196 // make the network amendment blocked...now all the same
197 // requests should fail
198
199 env.app().getOPs().setAmendmentBlocked();
200
201 // ledger_accept
202 jr = env.rpc("ledger_accept")[jss::result];
203 BEAST_EXPECT(
204 jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
205 BEAST_EXPECT(jr[jss::status] == "error");
206 BEAST_EXPECT(!jr.isMember(jss::warnings));
207
208 // ledger_current
209 jr = env.rpc("ledger_current")[jss::result];
210 BEAST_EXPECT(
211 jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
212 BEAST_EXPECT(jr[jss::status] == "error");
213 BEAST_EXPECT(!jr.isMember(jss::warnings));
214
215 // owner_info
216 jr = env.rpc("owner_info", alice.human())[jss::result];
217 BEAST_EXPECT(
218 jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
219 BEAST_EXPECT(jr[jss::status] == "error");
220 BEAST_EXPECT(!jr.isMember(jss::warnings));
221
222 // path_find
223 jr = wsc->invoke("path_find", pf_req)[jss::result];
224 BEAST_EXPECT(
225 jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
226 BEAST_EXPECT(jr[jss::status] == "error");
227 BEAST_EXPECT(!jr.isMember(jss::warnings));
228
229 // submit
230 jr = env.rpc("submit", strHex(s.slice()))[jss::result];
231 BEAST_EXPECT(
232 jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
233 BEAST_EXPECT(jr[jss::status] == "error");
234 BEAST_EXPECT(!jr.isMember(jss::warnings));
235
236 // submit_multisigned
237 set_tx[jss::Sequence] = env.seq(bob);
238 sign_for[jss::tx_json] = set_tx;
239 jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
240 BEAST_EXPECT(jr[jss::status] == "success");
241 ms_req[jss::tx_json] = jr[jss::tx_json];
242 jr = env.rpc(
243 "json", "submit_multisigned", to_string(ms_req))[jss::result];
244 BEAST_EXPECT(
245 jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
246 BEAST_EXPECT(!jr.isMember(jss::warnings));
247 }
248
249public:
250 void
251 run() override
252 {
254 }
255};
256
257BEAST_DEFINE_TESTSUITE(AmendmentBlocked, app, ripple);
258
259} // namespace ripple
Represents a JSON value.
Definition: json_value.h:147
A testsuite class.
Definition: suite.h:53
void run() override
Runs the suite.
Slice slice() const noexcept
Definition: Serializer.h:66
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:300
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
@ current
This was a new validation and was added.
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:629