mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Warn operators about upcoming unknown amendments:
* When an unknown amendment reaches majority, log an error-level message, and return a `warnings` array on all successful admin-level RPC calls to `server_info` and `server_state` with a message describing the problem, and the expected deadline. * In addition to the `amendment_blocked` flag returned by `server_info` and `server_state`, return a warning with a more verbose description when the server is amendment blocked. * Check on every flag ledger to see if the amendment(s) lose majority. Logs again if they don't, resumes normal operations if they did. The intention is to give operators earlier warning that their instances are in danger of being amendment blocked, which will hopefully motivate them to update ahead of time.
This commit is contained in:
committed by
Manoj doshi
parent
4315913a5d
commit
5ff23f8f31
@@ -20,6 +20,7 @@
|
||||
#include <test/jtx.h>
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <ripple/protocol/ErrorCodes.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <test/jtx/WSClient.h>
|
||||
|
||||
@@ -39,7 +40,9 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
auto const USD = gw["USD"];
|
||||
auto const alice = Account {"alice"};
|
||||
auto const bob = Account {"bob"};
|
||||
Account const ali {"ali", KeyType::secp256k1};
|
||||
env.fund (XRP(10000), alice, bob, gw);
|
||||
env.memoize(ali);
|
||||
env.trust (USD(600), alice);
|
||||
env.trust (USD(700), bob);
|
||||
env(pay (gw, alice, USD(70)));
|
||||
@@ -52,14 +55,17 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
// ledger_accept
|
||||
auto jr = env.rpc ("ledger_accept") [jss::result];
|
||||
BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// ledger_current
|
||||
jr = env.rpc ("ledger_current") [jss::result];
|
||||
BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// owner_info
|
||||
jr = env.rpc ("owner_info", alice.human()) [jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::accepted) && jr.isMember (jss::current));
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// path_find
|
||||
Json::Value pf_req;
|
||||
@@ -72,6 +78,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT (jr.isMember (jss::alternatives) &&
|
||||
jr[jss::alternatives].isArray() &&
|
||||
jr[jss::alternatives].size () == 1);
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// submit
|
||||
auto jt = env.jt (noop (alice));
|
||||
@@ -80,10 +87,10 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
jr = env.rpc ("submit", strHex (s.slice ())) [jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::engine_result) &&
|
||||
jr[jss::engine_result] == "tesSUCCESS");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// submit_multisigned
|
||||
env(signers(bob, 1, {{alice, 1}}), sig (bob));
|
||||
Account const ali {"ali", KeyType::secp256k1};
|
||||
env(regkey (alice, ali));
|
||||
env.close();
|
||||
|
||||
@@ -101,6 +108,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
sign_for[jss::secret] = ali.name();
|
||||
jr = env.rpc("json", "sign_for", to_string(sign_for)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::status] == "success");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
Json::Value ms_req;
|
||||
ms_req[jss::tx_json] = jr[jss::tx_json];
|
||||
@@ -108,6 +116,74 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
[jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::engine_result) &&
|
||||
jr[jss::engine_result] == "tesSUCCESS");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// set up an amendment warning. Nothing changes
|
||||
|
||||
env.app ().getOPs ().setAmendmentWarned ();
|
||||
|
||||
current = env.current ();
|
||||
// ledger_accept
|
||||
jr = env.rpc ("ledger_accept") [jss::result];
|
||||
BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// ledger_current
|
||||
jr = env.rpc ("ledger_current") [jss::result];
|
||||
BEAST_EXPECT (jr[jss::ledger_current_index] == current->seq ()+1);
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// owner_info
|
||||
jr = env.rpc ("owner_info", alice.human()) [jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::accepted) && jr.isMember (jss::current));
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// path_find
|
||||
pf_req[jss::subcommand] = "create";
|
||||
pf_req[jss::source_account] = alice.human();
|
||||
pf_req[jss::destination_account] = bob.human();
|
||||
pf_req[jss::destination_amount] =
|
||||
bob["USD"](20).value ().getJson (JsonOptions::none);
|
||||
jr = wsc->invoke("path_find", pf_req) [jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::alternatives) &&
|
||||
jr[jss::alternatives].isArray() &&
|
||||
jr[jss::alternatives].size () == 1);
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// submit
|
||||
jt = env.jt (noop (alice));
|
||||
s.erase();
|
||||
jt.stx->add (s);
|
||||
jr = env.rpc ("submit", strHex (s.slice ())) [jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::engine_result) &&
|
||||
jr[jss::engine_result] == "tesSUCCESS");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// submit_multisigned
|
||||
env(signers(bob, 1, {{alice, 1}}), sig (bob));
|
||||
env(regkey (alice, ali));
|
||||
env.close();
|
||||
|
||||
set_tx[jss::Account] = bob.human();
|
||||
set_tx[jss::TransactionType] = jss::AccountSet;
|
||||
set_tx[jss::Fee] =
|
||||
(8 * env.current()->fees().base).jsonClipped();
|
||||
set_tx[jss::Sequence] = env.seq(bob);
|
||||
set_tx[jss::SigningPubKey] = "";
|
||||
|
||||
sign_for[jss::tx_json] = set_tx;
|
||||
sign_for[jss::account] = alice.human();
|
||||
sign_for[jss::secret] = ali.name();
|
||||
jr = env.rpc("json", "sign_for", to_string(sign_for)) [jss::result];
|
||||
BEAST_EXPECT(jr[jss::status] == "success");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
ms_req[jss::tx_json] = jr[jss::tx_json];
|
||||
jr = env.rpc("json", "submit_multisigned", to_string(ms_req))
|
||||
[jss::result];
|
||||
BEAST_EXPECT (jr.isMember (jss::engine_result) &&
|
||||
jr[jss::engine_result] == "tesSUCCESS");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// make the network amendment blocked...now all the same
|
||||
// requests should fail
|
||||
@@ -120,6 +196,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
jr.isMember (jss::error) &&
|
||||
jr[jss::error] == "amendmentBlocked");
|
||||
BEAST_EXPECT(jr[jss::status] == "error");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// ledger_current
|
||||
jr = env.rpc ("ledger_current") [jss::result];
|
||||
@@ -127,6 +204,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
jr.isMember (jss::error) &&
|
||||
jr[jss::error] == "amendmentBlocked");
|
||||
BEAST_EXPECT(jr[jss::status] == "error");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// owner_info
|
||||
jr = env.rpc ("owner_info", alice.human()) [jss::result];
|
||||
@@ -134,6 +212,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
jr.isMember (jss::error) &&
|
||||
jr[jss::error] == "amendmentBlocked");
|
||||
BEAST_EXPECT(jr[jss::status] == "error");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// path_find
|
||||
jr = wsc->invoke("path_find", pf_req) [jss::result];
|
||||
@@ -141,6 +220,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
jr.isMember (jss::error) &&
|
||||
jr[jss::error] == "amendmentBlocked");
|
||||
BEAST_EXPECT(jr[jss::status] == "error");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// submit
|
||||
jr = env.rpc("submit", strHex(s.slice())) [jss::result];
|
||||
@@ -148,6 +228,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
jr.isMember (jss::error) &&
|
||||
jr[jss::error] == "amendmentBlocked");
|
||||
BEAST_EXPECT(jr[jss::status] == "error");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
|
||||
// submit_multisigned
|
||||
set_tx[jss::Sequence] = env.seq(bob);
|
||||
@@ -160,6 +241,7 @@ class AmendmentBlocked_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(
|
||||
jr.isMember (jss::error) &&
|
||||
jr[jss::error] == "amendmentBlocked");
|
||||
BEAST_EXPECT(!jr.isMember(jss::warnings));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user