21#include <test/jtx/TrustedPublisherServer.h>
23#include <xrpld/app/main/BasicApp.h>
24#include <xrpld/app/misc/ValidatorSite.h>
25#include <xrpld/core/ConfigSections.h>
27#include <xrpl/beast/unit_test.h>
28#include <xrpl/json/json_value.h>
29#include <xrpl/protocol/jss.h>
45 using namespace test::jtx;
47 for (
bool const isAdmin : {
true,
false})
49 for (
std::string cmd : {
"validators",
"validator_list_sites"})
52 env.set_retries(
isAdmin ? 5 : 0);
53 auto const jrr = env.rpc(cmd)[jss::result];
56 BEAST_EXPECT(!jrr.isMember(jss::error));
57 BEAST_EXPECT(jrr[jss::status] ==
"success");
65 BEAST_EXPECT(jrr.isNull());
71 auto const jrr = env.rpc(
"server_info")[jss::result];
72 BEAST_EXPECT(jrr[jss::status] ==
"success");
74 jrr[jss::info].isMember(jss::validator_list) ==
isAdmin);
79 auto const jrr = env.rpc(
"server_state")[jss::result];
80 BEAST_EXPECT(jrr[jss::status] ==
"success");
82 jrr[jss::state].isMember(jss::validator_list_expires) ==
91 using namespace test::jtx;
94 "n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7",
95 "n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj"};
99 for (
auto const& key : keys)
100 cfg->section(SECTION_VALIDATORS).append(key);
107 auto const jrr = env.rpc(
"server_info")[jss::result];
109 jrr[jss::info][jss::validator_list][jss::expiration] ==
113 auto const jrr = env.rpc(
"server_state")[jss::result];
115 jrr[jss::state][jss::validator_list_expires].asUInt() ==
120 auto const jrr = env.rpc(
"validators")[jss::result];
121 BEAST_EXPECT(jrr[jss::validator_list][jss::expiration] ==
"never");
122 BEAST_EXPECT(jrr[jss::validation_quorum].asUInt() == keys.
size());
124 jrr[jss::trusted_validator_keys].size() == keys.
size());
125 BEAST_EXPECT(jrr[jss::publisher_lists].size() == 0);
126 BEAST_EXPECT(jrr[jss::local_static_keys].size() == keys.
size());
127 for (
auto const& jKey : jrr[jss::local_static_keys])
129 BEAST_EXPECT(keys.
count(jKey.asString()) == 1);
131 BEAST_EXPECT(jrr[jss::signing_keys].size() == 0);
135 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
136 BEAST_EXPECT(jrr[jss::validator_sites].size() == 0);
140 auto const jrr = env.rpc(
"validators")[jss::result];
141 BEAST_EXPECT(jrr[jss::NegativeUNL].isNull());
150 env.app().validators().setNegativeUNL(disabledKeys);
152 auto const jrr = env.rpc(
"validators")[jss::result];
153 auto& jrrnUnl = jrr[jss::NegativeUNL];
154 auto jrrnUnlSize = jrrnUnl.size();
155 BEAST_EXPECT(jrrnUnlSize == 2);
158 auto parsedKey = parseBase58<PublicKey>(
160 BEAST_EXPECT(parsedKey);
163 disabledKeys.
find(*parsedKey) != disabledKeys.
end());
166 disabledKeys.
clear();
167 env.app().validators().setNegativeUNL(disabledKeys);
168 auto const jrrUpdated = env.rpc(
"validators")[jss::result];
169 BEAST_EXPECT(jrrUpdated[jss::NegativeUNL].isNull());
176 using namespace test::jtx;
178 auto toStr = [](
PublicKey const& publicKey) {
187 for (
auto const& val : validators)
188 expectedKeys.
insert(toStr(val.masterPublic));
192 using namespace std::chrono_literals;
197 worker.get_io_service(),
200 {{validFrom2, validUntil2}},
209 using namespace std::string_literals;
216 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
217 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
218 .append(
strHex(server->publisherPublic()));
223 env.app().validatorSites().start();
224 env.app().validatorSites().join();
227 auto const jrr = env.rpc(
"server_info")[jss::result];
229 jrr[jss::info][jss::validator_list][jss::expiration] ==
233 auto const jrr = env.rpc(
"server_state")[jss::result];
235 jrr[jss::state][jss::validator_list_expires].asInt() == 0);
238 auto const jrr = env.rpc(
"validators")[jss::result];
240 jrr[jss::validation_quorum].
asUInt() ==
242 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
243 BEAST_EXPECT(jrr[jss::trusted_validator_keys].
size() == 0);
245 jrr[jss::validator_list][jss::expiration] ==
"unknown");
247 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
249 auto jp = jrr[jss::publisher_lists][0u];
250 BEAST_EXPECT(jp[jss::available] ==
false);
251 BEAST_EXPECT(jp[jss::list].
size() == 0);
252 BEAST_EXPECT(!jp.isMember(jss::seq));
253 BEAST_EXPECT(!jp.isMember(jss::expiration));
254 BEAST_EXPECT(!jp.isMember(jss::version));
256 jp[jss::pubkey_publisher] ==
257 strHex(server->publisherPublic()));
259 BEAST_EXPECT(jrr[jss::signing_keys].
size() == 0);
262 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
263 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
265 auto js = jrr[jss::validator_sites][0u];
266 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
267 BEAST_EXPECT(js[jss::uri] == siteURI);
268 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
269 BEAST_EXPECT(js[jss::last_refresh_status] ==
"invalid");
276 using namespace std::string_literals;
283 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
284 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
285 .append(
strHex(server->publisherPublic()));
290 env.app().validatorSites().start();
291 env.app().validatorSites().join();
294 auto const jrr = env.rpc(
"server_info")[jss::result];
296 jrr[jss::info][jss::validator_list][jss::expiration] ==
300 auto const jrr = env.rpc(
"server_state")[jss::result];
302 jrr[jss::state][jss::validator_list_expires].asInt() == 0);
305 auto const jrr = env.rpc(
"validators")[jss::result];
307 jrr[jss::validation_quorum].
asUInt() ==
309 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
310 BEAST_EXPECT(jrr[jss::trusted_validator_keys].
size() == 0);
312 jrr[jss::validator_list][jss::expiration] ==
"unknown");
314 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
316 auto jp = jrr[jss::publisher_lists][0u];
317 BEAST_EXPECT(jp[jss::available] ==
false);
318 BEAST_EXPECT(jp[jss::list].
size() == 0);
319 BEAST_EXPECT(!jp.isMember(jss::seq));
320 BEAST_EXPECT(!jp.isMember(jss::expiration));
321 BEAST_EXPECT(!jp.isMember(jss::version));
323 jp[jss::pubkey_publisher] ==
324 strHex(server->publisherPublic()));
326 BEAST_EXPECT(jrr[jss::signing_keys].
size() == 0);
329 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
330 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
332 auto js = jrr[jss::validator_sites][0u];
333 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
334 BEAST_EXPECT(js[jss::uri] == siteURI);
335 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
336 BEAST_EXPECT(js[jss::last_refresh_status] ==
"invalid");
346 uri <<
"http://" << server->local_endpoint() <<
"/validators";
347 auto siteURI = uri.
str();
352 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
353 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
354 .append(
strHex(server->publisherPublic()));
359 env.app().validatorSites().start();
360 env.app().validatorSites().join();
361 hash_set<NodeID> startKeys;
362 for (
auto const& val : validators)
363 startKeys.insert(
calcNodeID(val.masterPublic));
365 env.app().validators().updateTrusted(
367 env.timeKeeper().now(),
370 env.app().getHashRouter());
373 auto const jrr = env.rpc(
"server_info")[jss::result];
375 jrr[jss::info][jss::validator_list][jss::expiration] ==
379 auto const jrr = env.rpc(
"server_state")[jss::result];
381 jrr[jss::state][jss::validator_list_expires].
asUInt() ==
382 validUntil.time_since_epoch().count());
385 auto const jrr = env.rpc(
"validators")[jss::result];
386 BEAST_EXPECT(jrr[jss::validation_quorum].
asUInt() == 2);
388 jrr[jss::validator_list][jss::expiration] ==
390 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
393 jrr[jss::trusted_validator_keys].
size() ==
394 expectedKeys.size());
395 for (
auto const& jKey : jrr[jss::trusted_validator_keys])
397 BEAST_EXPECT(expectedKeys.count(jKey.asString()) == 1);
400 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
402 auto jp = jrr[jss::publisher_lists][0u];
403 BEAST_EXPECT(jp[jss::available] ==
true);
404 if (BEAST_EXPECT(jp[jss::list].
size() == 2))
408 for (
auto const& k : jp[jss::list])
410 foundKeys.
insert(k.asString());
412 BEAST_EXPECT(foundKeys == expectedKeys);
414 BEAST_EXPECT(jp[jss::seq].
asUInt() == 1);
416 jp[jss::pubkey_publisher] ==
417 strHex(server->publisherPublic()));
418 BEAST_EXPECT(jp[jss::expiration] ==
to_string(validUntil));
419 BEAST_EXPECT(jp[jss::version] == 1);
421 auto jsk = jrr[jss::signing_keys];
422 BEAST_EXPECT(jsk.size() == 2);
423 for (
auto const& val : validators)
425 BEAST_EXPECT(jsk.isMember(toStr(val.masterPublic)));
427 jsk[toStr(val.masterPublic)] ==
428 toStr(val.signingPublic));
432 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
433 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
435 auto js = jrr[jss::validator_sites][0u];
436 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
437 BEAST_EXPECT(js[jss::uri] == siteURI);
438 BEAST_EXPECT(js[jss::last_refresh_status] ==
"accepted");
441 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
448 uri <<
"http://" << server->local_endpoint() <<
"/validators2";
449 auto siteURI = uri.
str();
454 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
455 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
456 .append(
strHex(server->publisherPublic()));
461 env.app().validatorSites().start();
462 env.app().validatorSites().join();
463 hash_set<NodeID> startKeys;
464 for (
auto const& val : validators)
465 startKeys.insert(
calcNodeID(val.masterPublic));
467 env.app().validators().updateTrusted(
469 env.timeKeeper().now(),
472 env.app().getHashRouter());
475 auto const jrr = env.rpc(
"server_info")[jss::result];
477 jrr[jss::info][jss::validator_list][jss::expiration] ==
481 auto const jrr = env.rpc(
"server_state")[jss::result];
483 jrr[jss::state][jss::validator_list_expires].
asUInt() ==
484 validUntil2.time_since_epoch().count());
487 auto const jrr = env.rpc(
"validators")[jss::result];
488 BEAST_EXPECT(jrr[jss::validation_quorum].
asUInt() == 2);
490 jrr[jss::validator_list][jss::expiration] ==
492 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
495 jrr[jss::trusted_validator_keys].
size() ==
496 expectedKeys.size());
497 for (
auto const& jKey : jrr[jss::trusted_validator_keys])
499 BEAST_EXPECT(expectedKeys.count(jKey.asString()) == 1);
502 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
504 auto jp = jrr[jss::publisher_lists][0u];
505 BEAST_EXPECT(jp[jss::available] ==
true);
506 if (BEAST_EXPECT(jp[jss::list].
size() == 2))
510 for (
auto const& k : jp[jss::list])
512 foundKeys.
insert(k.asString());
514 BEAST_EXPECT(foundKeys == expectedKeys);
516 BEAST_EXPECT(jp[jss::seq].
asUInt() == 1);
518 jp[jss::pubkey_publisher] ==
519 strHex(server->publisherPublic()));
520 BEAST_EXPECT(jp[jss::expiration] ==
to_string(validUntil));
521 BEAST_EXPECT(jp[jss::version] == 2);
522 if (BEAST_EXPECT(jp.isMember(jss::remaining)) &&
523 BEAST_EXPECT(jp[jss::remaining].isArray()) &&
524 BEAST_EXPECT(jp[jss::remaining].
size() == 1))
526 auto const& r = jp[jss::remaining][0u];
527 if (BEAST_EXPECT(r[jss::list].
size() == 2))
531 for (
auto const& k : r[jss::list])
533 foundKeys.
insert(k.asString());
535 BEAST_EXPECT(foundKeys == expectedKeys);
537 BEAST_EXPECT(r[jss::seq].
asUInt() == 2);
539 r[jss::effective] ==
to_string(validFrom2));
541 r[jss::expiration] ==
to_string(validUntil2));
544 auto jsk = jrr[jss::signing_keys];
545 BEAST_EXPECT(jsk.size() == 2);
546 for (
auto const& val : validators)
548 BEAST_EXPECT(jsk.isMember(toStr(val.masterPublic)));
550 jsk[toStr(val.masterPublic)] ==
551 toStr(val.signingPublic));
555 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
556 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
558 auto js = jrr[jss::validator_sites][0u];
559 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
560 BEAST_EXPECT(js[jss::uri] == siteURI);
561 BEAST_EXPECT(js[jss::last_refresh_status] ==
"accepted");
564 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
573 using namespace test::jtx;
575 auto result = env.
rpc(
"validation_create");
577 result.isMember(jss::result) &&
578 result[jss::result][jss::status] ==
"success");
581 "BAWL MAN JADE MOON DOVE GEM SON NOW HAD ADEN GLOW TIRE");
583 result.isMember(jss::result) &&
584 result[jss::result][jss::status] ==
"success");
593 test_validation_create();
597BEAST_DEFINE_TESTSUITE(ValidatorRPC, app,
ripple);
static Validator randomValidator()
void test_validation_create()
void run() override
Runs the suite.
A transaction testing environment.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
std::uint32_t asUInt(AnyValue const &v)
std::unique_ptr< Config > no_admin(std::unique_ptr< Config >)
adjust config so no admin ports are enabled
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
std::shared_ptr< TrustedPublisherServer > make_TrustedPublisherServer(boost::asio::io_context &ioc, std::vector< TrustedPublisherServer::Validator > const &validators, NetClock::time_point validUntil, std::vector< std::pair< NetClock::time_point, NetClock::time_point > > const &futures, bool useSSL=false, int version=1, bool immediateStart=true, int sequence=1)
char const * getEnvLocalhostAddr()
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
bool isAdmin(Port const &port, Json::Value const ¶ms, beast::IP::Address const &remoteIp)
std::string strHex(FwdIt begin, FwdIt end)
NodeID calcNodeID(PublicKey const &)
Calculate the 160-bit node ID from a node public key.
std::string to_string(base_uint< Bits, Tag > const &a)
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.