rippled
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 <ripple/core/ConfigSections.h>
22 #include <ripple/protocol/jss.h>
23 #include <ripple/protocol/ErrorCodes.h>
24 #include <ripple/app/misc/NetworkOPs.h>
25 #include <test/jtx/WSClient.h>
26 
27 namespace ripple {
28 
29 class AmendmentBlocked_test : public beast::unit_test::suite
30 {
32  {
33  using namespace test::jtx;
34  Env env {*this, envconfig([](std::unique_ptr<Config> cfg)
35  {
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  env.trust (USD(600), alice);
47  env.trust (USD(700), bob);
48  env(pay (gw, alice, USD(70)));
49  env(pay (gw, bob, USD(50)));
50  env.close();
51 
52  auto wsc = test::makeWSClient(env.app().config());
53 
54  auto current = env.current ();
55  // ledger_accept
56  auto jr = env.rpc ("ledger_accept") [jss::result];
57  BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
58  BEAST_EXPECT(!jr.isMember(jss::warnings));
59 
60  // ledger_current
61  jr = env.rpc ("ledger_current") [jss::result];
62  BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
63  BEAST_EXPECT(!jr.isMember(jss::warnings));
64 
65  // owner_info
66  jr = env.rpc ("owner_info", alice.human()) [jss::result];
67  BEAST_EXPECT (jr.isMember (jss::accepted) && jr.isMember (jss::current));
68  BEAST_EXPECT(!jr.isMember(jss::warnings));
69 
70  // path_find
71  Json::Value pf_req;
72  pf_req[jss::subcommand] = "create";
73  pf_req[jss::source_account] = alice.human();
74  pf_req[jss::destination_account] = bob.human();
75  pf_req[jss::destination_amount] =
76  bob["USD"](20).value ().getJson (JsonOptions::none);
77  jr = wsc->invoke("path_find", pf_req) [jss::result];
78  BEAST_EXPECT (jr.isMember (jss::alternatives) &&
79  jr[jss::alternatives].isArray() &&
80  jr[jss::alternatives].size () == 1);
81  BEAST_EXPECT(!jr.isMember(jss::warnings));
82 
83  // submit
84  auto jt = env.jt (noop (alice));
85  Serializer s;
86  jt.stx->add (s);
87  jr = env.rpc ("submit", strHex (s.slice ())) [jss::result];
88  BEAST_EXPECT (jr.isMember (jss::engine_result) &&
89  jr[jss::engine_result] == "tesSUCCESS");
90  BEAST_EXPECT(!jr.isMember(jss::warnings));
91 
92  // submit_multisigned
93  env(signers(bob, 1, {{alice, 1}}), sig (bob));
94  env(regkey (alice, ali));
95  env.close();
96 
97  Json::Value set_tx;
98  set_tx[jss::Account] = bob.human();
99  set_tx[jss::TransactionType] = jss::AccountSet;
100  set_tx[jss::Fee] =
101  (8 * env.current()->fees().base).jsonClipped();
102  set_tx[jss::Sequence] = env.seq(bob);
103  set_tx[jss::SigningPubKey] = "";
104 
105  Json::Value sign_for;
106  sign_for[jss::tx_json] = set_tx;
107  sign_for[jss::account] = alice.human();
108  sign_for[jss::secret] = ali.name();
109  jr = env.rpc("json", "sign_for", to_string(sign_for)) [jss::result];
110  BEAST_EXPECT(jr[jss::status] == "success");
111  BEAST_EXPECT(!jr.isMember(jss::warnings));
112 
113  Json::Value ms_req;
114  ms_req[jss::tx_json] = jr[jss::tx_json];
115  jr = env.rpc("json", "submit_multisigned", to_string(ms_req))
116  [jss::result];
117  BEAST_EXPECT (jr.isMember (jss::engine_result) &&
118  jr[jss::engine_result] == "tesSUCCESS");
119  BEAST_EXPECT(!jr.isMember(jss::warnings));
120 
121  // set up an amendment warning. Nothing changes
122 
123  env.app ().getOPs ().setAmendmentWarned ();
124 
125  current = env.current ();
126  // ledger_accept
127  jr = env.rpc ("ledger_accept") [jss::result];
128  BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
129  BEAST_EXPECT(!jr.isMember(jss::warnings));
130 
131  // ledger_current
132  jr = env.rpc ("ledger_current") [jss::result];
133  BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
134  BEAST_EXPECT(!jr.isMember(jss::warnings));
135 
136  // owner_info
137  jr = env.rpc ("owner_info", alice.human()) [jss::result];
138  BEAST_EXPECT (jr.isMember (jss::accepted) && jr.isMember (jss::current));
139  BEAST_EXPECT(!jr.isMember(jss::warnings));
140 
141  // path_find
142  pf_req[jss::subcommand] = "create";
143  pf_req[jss::source_account] = alice.human();
144  pf_req[jss::destination_account] = bob.human();
145  pf_req[jss::destination_amount] =
146  bob["USD"](20).value ().getJson (JsonOptions::none);
147  jr = wsc->invoke("path_find", pf_req) [jss::result];
148  BEAST_EXPECT (jr.isMember (jss::alternatives) &&
149  jr[jss::alternatives].isArray() &&
150  jr[jss::alternatives].size () == 1);
151  BEAST_EXPECT(!jr.isMember(jss::warnings));
152 
153  // submit
154  jt = env.jt (noop (alice));
155  s.erase();
156  jt.stx->add (s);
157  jr = env.rpc ("submit", strHex (s.slice ())) [jss::result];
158  BEAST_EXPECT (jr.isMember (jss::engine_result) &&
159  jr[jss::engine_result] == "tesSUCCESS");
160  BEAST_EXPECT(!jr.isMember(jss::warnings));
161 
162  // submit_multisigned
163  env(signers(bob, 1, {{alice, 1}}), sig (bob));
164  env(regkey (alice, ali));
165  env.close();
166 
167  set_tx[jss::Account] = bob.human();
168  set_tx[jss::TransactionType] = jss::AccountSet;
169  set_tx[jss::Fee] =
170  (8 * env.current()->fees().base).jsonClipped();
171  set_tx[jss::Sequence] = env.seq(bob);
172  set_tx[jss::SigningPubKey] = "";
173 
174  sign_for[jss::tx_json] = set_tx;
175  sign_for[jss::account] = alice.human();
176  sign_for[jss::secret] = ali.name();
177  jr = env.rpc("json", "sign_for", to_string(sign_for)) [jss::result];
178  BEAST_EXPECT(jr[jss::status] == "success");
179  BEAST_EXPECT(!jr.isMember(jss::warnings));
180 
181  ms_req[jss::tx_json] = jr[jss::tx_json];
182  jr = env.rpc("json", "submit_multisigned", to_string(ms_req))
183  [jss::result];
184  BEAST_EXPECT (jr.isMember (jss::engine_result) &&
185  jr[jss::engine_result] == "tesSUCCESS");
186  BEAST_EXPECT(!jr.isMember(jss::warnings));
187 
188  // make the network amendment blocked...now all the same
189  // requests should fail
190 
191  env.app ().getOPs ().setAmendmentBlocked ();
192 
193  // ledger_accept
194  jr = env.rpc ("ledger_accept") [jss::result];
195  BEAST_EXPECT(
196  jr.isMember (jss::error) &&
197  jr[jss::error] == "amendmentBlocked");
198  BEAST_EXPECT(jr[jss::status] == "error");
199  BEAST_EXPECT(!jr.isMember(jss::warnings));
200 
201  // ledger_current
202  jr = env.rpc ("ledger_current") [jss::result];
203  BEAST_EXPECT(
204  jr.isMember (jss::error) &&
205  jr[jss::error] == "amendmentBlocked");
206  BEAST_EXPECT(jr[jss::status] == "error");
207  BEAST_EXPECT(!jr.isMember(jss::warnings));
208 
209  // owner_info
210  jr = env.rpc ("owner_info", alice.human()) [jss::result];
211  BEAST_EXPECT(
212  jr.isMember (jss::error) &&
213  jr[jss::error] == "amendmentBlocked");
214  BEAST_EXPECT(jr[jss::status] == "error");
215  BEAST_EXPECT(!jr.isMember(jss::warnings));
216 
217  // path_find
218  jr = wsc->invoke("path_find", pf_req) [jss::result];
219  BEAST_EXPECT(
220  jr.isMember (jss::error) &&
221  jr[jss::error] == "amendmentBlocked");
222  BEAST_EXPECT(jr[jss::status] == "error");
223  BEAST_EXPECT(!jr.isMember(jss::warnings));
224 
225  // submit
226  jr = env.rpc("submit", strHex(s.slice())) [jss::result];
227  BEAST_EXPECT(
228  jr.isMember (jss::error) &&
229  jr[jss::error] == "amendmentBlocked");
230  BEAST_EXPECT(jr[jss::status] == "error");
231  BEAST_EXPECT(!jr.isMember(jss::warnings));
232 
233  // submit_multisigned
234  set_tx[jss::Sequence] = env.seq(bob);
235  sign_for[jss::tx_json] = set_tx;
236  jr = env.rpc("json", "sign_for", to_string(sign_for)) [jss::result];
237  BEAST_EXPECT(jr[jss::status] == "success");
238  ms_req[jss::tx_json] = jr[jss::tx_json];
239  jr = env.rpc("json", "submit_multisigned", to_string(ms_req))
240  [jss::result];
241  BEAST_EXPECT(
242  jr.isMember (jss::error) &&
243  jr[jss::error] == "amendmentBlocked");
244  BEAST_EXPECT(!jr.isMember(jss::warnings));
245  }
246 
247 public:
248  void run() override
249  {
251  }
252 };
253 
254 BEAST_DEFINE_TESTSUITE(AmendmentBlocked,app,ripple);
255 
256 }
257 
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::Serializer::erase
void erase()
Definition: Serializer.h:211
ripple::AmendmentBlocked_test::testBlockedMethods
void testBlockedMethods()
Definition: AmendmentBlocked_test.cpp:31
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::AmendmentBlocked_test
Definition: AmendmentBlocked_test.cpp:29
ripple::JsonOptions::none
@ none
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:67
ripple::ValStatus::current
@ current
This was a new validation and was added.
ripple::KeyType::secp256k1
@ secp256k1
ripple::Serializer
Definition: Serializer.h:43
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::makeWSClient
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:307
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:70
ripple::AmendmentBlocked_test::run
void run() override
Definition: AmendmentBlocked_test.cpp:248
std::unique_ptr
STL class.
Json::Value
Represents a JSON value.
Definition: json_value.h:141