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 <ripple/app/misc/NetworkOPs.h>
21 #include <ripple/core/ConfigSections.h>
22 #include <ripple/protocol/ErrorCodes.h>
23 #include <ripple/protocol/jss.h>
24 #include <test/jtx.h>
25 #include <test/jtx/WSClient.h>
26 
27 namespace ripple {
28 
29 class AmendmentBlocked_test : public beast::unit_test::suite
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  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(
79  jr.isMember(jss::alternatives) && 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(
89  jr.isMember(jss::engine_result) &&
90  jr[jss::engine_result] == "tesSUCCESS");
91  BEAST_EXPECT(!jr.isMember(jss::warnings));
92 
93  // submit_multisigned
94  env(signers(bob, 1, {{alice, 1}}), sig(bob));
95  env(regkey(alice, ali));
96  env.close();
97 
98  Json::Value set_tx;
99  set_tx[jss::Account] = bob.human();
100  set_tx[jss::TransactionType] = jss::AccountSet;
101  set_tx[jss::Fee] = (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(
116  "json", "submit_multisigned", to_string(ms_req))[jss::result];
117  BEAST_EXPECT(
118  jr.isMember(jss::engine_result) &&
119  jr[jss::engine_result] == "tesSUCCESS");
120  BEAST_EXPECT(!jr.isMember(jss::warnings));
121 
122  // set up an amendment warning. Nothing changes
123 
124  env.app().getOPs().setAmendmentWarned();
125 
126  current = env.current();
127  // ledger_accept
128  jr = env.rpc("ledger_accept")[jss::result];
129  BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
130  BEAST_EXPECT(!jr.isMember(jss::warnings));
131 
132  // ledger_current
133  jr = env.rpc("ledger_current")[jss::result];
134  BEAST_EXPECT(jr[jss::ledger_current_index] == current->seq() + 1);
135  BEAST_EXPECT(!jr.isMember(jss::warnings));
136 
137  // owner_info
138  jr = env.rpc("owner_info", alice.human())[jss::result];
139  BEAST_EXPECT(jr.isMember(jss::accepted) && jr.isMember(jss::current));
140  BEAST_EXPECT(!jr.isMember(jss::warnings));
141 
142  // path_find
143  pf_req[jss::subcommand] = "create";
144  pf_req[jss::source_account] = alice.human();
145  pf_req[jss::destination_account] = bob.human();
146  pf_req[jss::destination_amount] =
147  bob["USD"](20).value().getJson(JsonOptions::none);
148  jr = wsc->invoke("path_find", pf_req)[jss::result];
149  BEAST_EXPECT(
150  jr.isMember(jss::alternatives) && jr[jss::alternatives].isArray() &&
151  jr[jss::alternatives].size() == 1);
152  BEAST_EXPECT(!jr.isMember(jss::warnings));
153 
154  // submit
155  jt = env.jt(noop(alice));
156  s.erase();
157  jt.stx->add(s);
158  jr = env.rpc("submit", strHex(s.slice()))[jss::result];
159  BEAST_EXPECT(
160  jr.isMember(jss::engine_result) &&
161  jr[jss::engine_result] == "tesSUCCESS");
162  BEAST_EXPECT(!jr.isMember(jss::warnings));
163 
164  // submit_multisigned
165  env(signers(bob, 1, {{alice, 1}}), sig(bob));
166  env(regkey(alice, ali));
167  env.close();
168 
169  set_tx[jss::Account] = bob.human();
170  set_tx[jss::TransactionType] = jss::AccountSet;
171  set_tx[jss::Fee] = (8 * env.current()->fees().base).jsonClipped();
172  set_tx[jss::Sequence] = env.seq(bob);
173  set_tx[jss::SigningPubKey] = "";
174 
175  sign_for[jss::tx_json] = set_tx;
176  sign_for[jss::account] = alice.human();
177  sign_for[jss::secret] = ali.name();
178  jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
179  BEAST_EXPECT(jr[jss::status] == "success");
180  BEAST_EXPECT(!jr.isMember(jss::warnings));
181 
182  ms_req[jss::tx_json] = jr[jss::tx_json];
183  jr = env.rpc(
184  "json", "submit_multisigned", to_string(ms_req))[jss::result];
185  BEAST_EXPECT(
186  jr.isMember(jss::engine_result) &&
187  jr[jss::engine_result] == "tesSUCCESS");
188  BEAST_EXPECT(!jr.isMember(jss::warnings));
189 
190  // make the network amendment blocked...now all the same
191  // requests should fail
192 
193  env.app().getOPs().setAmendmentBlocked();
194 
195  // ledger_accept
196  jr = env.rpc("ledger_accept")[jss::result];
197  BEAST_EXPECT(
198  jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
199  BEAST_EXPECT(jr[jss::status] == "error");
200  BEAST_EXPECT(!jr.isMember(jss::warnings));
201 
202  // ledger_current
203  jr = env.rpc("ledger_current")[jss::result];
204  BEAST_EXPECT(
205  jr.isMember(jss::error) && 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) && jr[jss::error] == "amendmentBlocked");
213  BEAST_EXPECT(jr[jss::status] == "error");
214  BEAST_EXPECT(!jr.isMember(jss::warnings));
215 
216  // path_find
217  jr = wsc->invoke("path_find", pf_req)[jss::result];
218  BEAST_EXPECT(
219  jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
220  BEAST_EXPECT(jr[jss::status] == "error");
221  BEAST_EXPECT(!jr.isMember(jss::warnings));
222 
223  // submit
224  jr = env.rpc("submit", strHex(s.slice()))[jss::result];
225  BEAST_EXPECT(
226  jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
227  BEAST_EXPECT(jr[jss::status] == "error");
228  BEAST_EXPECT(!jr.isMember(jss::warnings));
229 
230  // submit_multisigned
231  set_tx[jss::Sequence] = env.seq(bob);
232  sign_for[jss::tx_json] = set_tx;
233  jr = env.rpc("json", "sign_for", to_string(sign_for))[jss::result];
234  BEAST_EXPECT(jr[jss::status] == "success");
235  ms_req[jss::tx_json] = jr[jss::tx_json];
236  jr = env.rpc(
237  "json", "submit_multisigned", to_string(ms_req))[jss::result];
238  BEAST_EXPECT(
239  jr.isMember(jss::error) && jr[jss::error] == "amendmentBlocked");
240  BEAST_EXPECT(!jr.isMember(jss::warnings));
241  }
242 
243 public:
244  void
245  run() override
246  {
248  }
249 };
250 
251 BEAST_DEFINE_TESTSUITE(AmendmentBlocked, app, ripple);
252 
253 } // namespace ripple
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::Serializer::erase
void erase()
Definition: Serializer.h:209
ripple::AmendmentBlocked_test::testBlockedMethods
void testBlockedMethods()
Definition: AmendmentBlocked_test.cpp:32
ripple::AmendmentBlocked_test
Definition: AmendmentBlocked_test.cpp:29
ripple::JsonOptions::none
@ none
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
ripple::ValStatus::current
@ current
This was a new validation and was added.
ripple::KeyType::secp256k1
@ secp256k1
ripple::Serializer
Definition: Serializer.h:39
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:300
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:39
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
ripple::AmendmentBlocked_test::run
void run() override
Definition: AmendmentBlocked_test.cpp:245
std::unique_ptr
STL class.
Json::Value
Represents a JSON value.
Definition: json_value.h:145