21#include <test/jtx/TrustedPublisherServer.h>
22#include <xrpld/app/main/BasicApp.h>
23#include <xrpld/app/misc/ValidatorSite.h>
24#include <xrpld/core/ConfigSections.h>
25#include <xrpl/beast/unit_test.h>
26#include <xrpl/json/json_value.h>
27#include <xrpl/protocol/jss.h>
43 using namespace test::jtx;
45 for (
bool const isAdmin : {
true,
false})
47 for (
std::string cmd : {
"validators",
"validator_list_sites"})
50 env.set_retries(
isAdmin ? 5 : 0);
51 auto const jrr = env.rpc(cmd)[jss::result];
54 BEAST_EXPECT(!jrr.isMember(jss::error));
55 BEAST_EXPECT(jrr[jss::status] ==
"success");
63 BEAST_EXPECT(jrr.isNull());
69 auto const jrr = env.rpc(
"server_info")[jss::result];
70 BEAST_EXPECT(jrr[jss::status] ==
"success");
72 jrr[jss::info].isMember(jss::validator_list) ==
isAdmin);
77 auto const jrr = env.rpc(
"server_state")[jss::result];
78 BEAST_EXPECT(jrr[jss::status] ==
"success");
80 jrr[jss::state].isMember(jss::validator_list_expires) ==
89 using namespace test::jtx;
92 "n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7",
93 "n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj"};
97 for (
auto const& key : keys)
98 cfg->section(SECTION_VALIDATORS).append(key);
105 auto const jrr = env.rpc(
"server_info")[jss::result];
107 jrr[jss::info][jss::validator_list][jss::expiration] ==
111 auto const jrr = env.rpc(
"server_state")[jss::result];
113 jrr[jss::state][jss::validator_list_expires].asUInt() ==
118 auto const jrr = env.rpc(
"validators")[jss::result];
119 BEAST_EXPECT(jrr[jss::validator_list][jss::expiration] ==
"never");
120 BEAST_EXPECT(jrr[jss::validation_quorum].asUInt() == keys.
size());
122 jrr[jss::trusted_validator_keys].size() == keys.
size());
123 BEAST_EXPECT(jrr[jss::publisher_lists].size() == 0);
124 BEAST_EXPECT(jrr[jss::local_static_keys].size() == keys.
size());
125 for (
auto const& jKey : jrr[jss::local_static_keys])
127 BEAST_EXPECT(keys.
count(jKey.asString()) == 1);
129 BEAST_EXPECT(jrr[jss::signing_keys].size() == 0);
133 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
134 BEAST_EXPECT(jrr[jss::validator_sites].size() == 0);
138 auto const jrr = env.rpc(
"validators")[jss::result];
139 BEAST_EXPECT(jrr[jss::NegativeUNL].isNull());
148 env.app().validators().setNegativeUNL(disabledKeys);
150 auto const jrr = env.rpc(
"validators")[jss::result];
151 auto& jrrnUnl = jrr[jss::NegativeUNL];
152 auto jrrnUnlSize = jrrnUnl.size();
153 BEAST_EXPECT(jrrnUnlSize == 2);
156 auto parsedKey = parseBase58<PublicKey>(
158 BEAST_EXPECT(parsedKey);
161 disabledKeys.
find(*parsedKey) != disabledKeys.
end());
164 disabledKeys.
clear();
165 env.app().validators().setNegativeUNL(disabledKeys);
166 auto const jrrUpdated = env.rpc(
"validators")[jss::result];
167 BEAST_EXPECT(jrrUpdated[jss::NegativeUNL].isNull());
174 using namespace test::jtx;
176 auto toStr = [](
PublicKey const& publicKey) {
185 for (
auto const& val : validators)
186 expectedKeys.
insert(toStr(val.masterPublic));
190 using namespace std::chrono_literals;
195 worker.get_io_service(),
198 {{validFrom2, validUntil2}},
207 using namespace std::string_literals;
214 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
215 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
216 .append(
strHex(server->publisherPublic()));
221 env.app().validatorSites().start();
222 env.app().validatorSites().join();
225 auto const jrr = env.rpc(
"server_info")[jss::result];
227 jrr[jss::info][jss::validator_list][jss::expiration] ==
231 auto const jrr = env.rpc(
"server_state")[jss::result];
233 jrr[jss::state][jss::validator_list_expires].asInt() == 0);
236 auto const jrr = env.rpc(
"validators")[jss::result];
238 jrr[jss::validation_quorum].
asUInt() ==
240 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
241 BEAST_EXPECT(jrr[jss::trusted_validator_keys].
size() == 0);
243 jrr[jss::validator_list][jss::expiration] ==
"unknown");
245 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
247 auto jp = jrr[jss::publisher_lists][0u];
248 BEAST_EXPECT(jp[jss::available] ==
false);
249 BEAST_EXPECT(jp[jss::list].
size() == 0);
250 BEAST_EXPECT(!jp.isMember(jss::seq));
251 BEAST_EXPECT(!jp.isMember(jss::expiration));
252 BEAST_EXPECT(!jp.isMember(jss::version));
254 jp[jss::pubkey_publisher] ==
255 strHex(server->publisherPublic()));
257 BEAST_EXPECT(jrr[jss::signing_keys].
size() == 0);
260 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
261 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
263 auto js = jrr[jss::validator_sites][0u];
264 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
265 BEAST_EXPECT(js[jss::uri] == siteURI);
266 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
267 BEAST_EXPECT(js[jss::last_refresh_status] ==
"invalid");
274 using namespace std::string_literals;
281 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
282 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
283 .append(
strHex(server->publisherPublic()));
288 env.app().validatorSites().start();
289 env.app().validatorSites().join();
292 auto const jrr = env.rpc(
"server_info")[jss::result];
294 jrr[jss::info][jss::validator_list][jss::expiration] ==
298 auto const jrr = env.rpc(
"server_state")[jss::result];
300 jrr[jss::state][jss::validator_list_expires].asInt() == 0);
303 auto const jrr = env.rpc(
"validators")[jss::result];
305 jrr[jss::validation_quorum].
asUInt() ==
307 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
308 BEAST_EXPECT(jrr[jss::trusted_validator_keys].
size() == 0);
310 jrr[jss::validator_list][jss::expiration] ==
"unknown");
312 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
314 auto jp = jrr[jss::publisher_lists][0u];
315 BEAST_EXPECT(jp[jss::available] ==
false);
316 BEAST_EXPECT(jp[jss::list].
size() == 0);
317 BEAST_EXPECT(!jp.isMember(jss::seq));
318 BEAST_EXPECT(!jp.isMember(jss::expiration));
319 BEAST_EXPECT(!jp.isMember(jss::version));
321 jp[jss::pubkey_publisher] ==
322 strHex(server->publisherPublic()));
324 BEAST_EXPECT(jrr[jss::signing_keys].
size() == 0);
327 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
328 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
330 auto js = jrr[jss::validator_sites][0u];
331 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
332 BEAST_EXPECT(js[jss::uri] == siteURI);
333 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
334 BEAST_EXPECT(js[jss::last_refresh_status] ==
"invalid");
344 uri <<
"http://" << server->local_endpoint() <<
"/validators";
345 auto siteURI = uri.
str();
350 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
351 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
352 .append(
strHex(server->publisherPublic()));
357 env.app().validatorSites().start();
358 env.app().validatorSites().join();
359 hash_set<NodeID> startKeys;
360 for (
auto const& val : validators)
361 startKeys.insert(
calcNodeID(val.masterPublic));
363 env.app().validators().updateTrusted(
365 env.timeKeeper().now(),
368 env.app().getHashRouter());
371 auto const jrr = env.rpc(
"server_info")[jss::result];
373 jrr[jss::info][jss::validator_list][jss::expiration] ==
377 auto const jrr = env.rpc(
"server_state")[jss::result];
379 jrr[jss::state][jss::validator_list_expires].
asUInt() ==
380 validUntil.time_since_epoch().count());
383 auto const jrr = env.rpc(
"validators")[jss::result];
384 BEAST_EXPECT(jrr[jss::validation_quorum].
asUInt() == 2);
386 jrr[jss::validator_list][jss::expiration] ==
388 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
391 jrr[jss::trusted_validator_keys].
size() ==
392 expectedKeys.size());
393 for (
auto const& jKey : jrr[jss::trusted_validator_keys])
395 BEAST_EXPECT(expectedKeys.count(jKey.asString()) == 1);
398 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
400 auto jp = jrr[jss::publisher_lists][0u];
401 BEAST_EXPECT(jp[jss::available] ==
true);
402 if (BEAST_EXPECT(jp[jss::list].
size() == 2))
406 for (
auto const& k : jp[jss::list])
408 foundKeys.
insert(k.asString());
410 BEAST_EXPECT(foundKeys == expectedKeys);
412 BEAST_EXPECT(jp[jss::seq].
asUInt() == 1);
414 jp[jss::pubkey_publisher] ==
415 strHex(server->publisherPublic()));
416 BEAST_EXPECT(jp[jss::expiration] ==
to_string(validUntil));
417 BEAST_EXPECT(jp[jss::version] == 1);
419 auto jsk = jrr[jss::signing_keys];
420 BEAST_EXPECT(jsk.size() == 2);
421 for (
auto const& val : validators)
423 BEAST_EXPECT(jsk.isMember(toStr(val.masterPublic)));
425 jsk[toStr(val.masterPublic)] ==
426 toStr(val.signingPublic));
430 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
431 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
433 auto js = jrr[jss::validator_sites][0u];
434 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
435 BEAST_EXPECT(js[jss::uri] == siteURI);
436 BEAST_EXPECT(js[jss::last_refresh_status] ==
"accepted");
439 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
446 uri <<
"http://" << server->local_endpoint() <<
"/validators2";
447 auto siteURI = uri.
str();
452 cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI);
453 cfg->section(SECTION_VALIDATOR_LIST_KEYS)
454 .append(
strHex(server->publisherPublic()));
459 env.app().validatorSites().start();
460 env.app().validatorSites().join();
461 hash_set<NodeID> startKeys;
462 for (
auto const& val : validators)
463 startKeys.insert(
calcNodeID(val.masterPublic));
465 env.app().validators().updateTrusted(
467 env.timeKeeper().now(),
470 env.app().getHashRouter());
473 auto const jrr = env.rpc(
"server_info")[jss::result];
475 jrr[jss::info][jss::validator_list][jss::expiration] ==
479 auto const jrr = env.rpc(
"server_state")[jss::result];
481 jrr[jss::state][jss::validator_list_expires].
asUInt() ==
482 validUntil2.time_since_epoch().count());
485 auto const jrr = env.rpc(
"validators")[jss::result];
486 BEAST_EXPECT(jrr[jss::validation_quorum].
asUInt() == 2);
488 jrr[jss::validator_list][jss::expiration] ==
490 BEAST_EXPECT(jrr[jss::local_static_keys].
size() == 0);
493 jrr[jss::trusted_validator_keys].
size() ==
494 expectedKeys.size());
495 for (
auto const& jKey : jrr[jss::trusted_validator_keys])
497 BEAST_EXPECT(expectedKeys.count(jKey.asString()) == 1);
500 if (BEAST_EXPECT(jrr[jss::publisher_lists].
size() == 1))
502 auto jp = jrr[jss::publisher_lists][0u];
503 BEAST_EXPECT(jp[jss::available] ==
true);
504 if (BEAST_EXPECT(jp[jss::list].
size() == 2))
508 for (
auto const& k : jp[jss::list])
510 foundKeys.
insert(k.asString());
512 BEAST_EXPECT(foundKeys == expectedKeys);
514 BEAST_EXPECT(jp[jss::seq].
asUInt() == 1);
516 jp[jss::pubkey_publisher] ==
517 strHex(server->publisherPublic()));
518 BEAST_EXPECT(jp[jss::expiration] ==
to_string(validUntil));
519 BEAST_EXPECT(jp[jss::version] == 2);
520 if (BEAST_EXPECT(jp.isMember(jss::remaining)) &&
521 BEAST_EXPECT(jp[jss::remaining].isArray()) &&
522 BEAST_EXPECT(jp[jss::remaining].
size() == 1))
524 auto const& r = jp[jss::remaining][0u];
525 if (BEAST_EXPECT(r[jss::list].
size() == 2))
529 for (
auto const& k : r[jss::list])
531 foundKeys.
insert(k.asString());
533 BEAST_EXPECT(foundKeys == expectedKeys);
535 BEAST_EXPECT(r[jss::seq].
asUInt() == 2);
537 r[jss::effective] ==
to_string(validFrom2));
539 r[jss::expiration] ==
to_string(validUntil2));
542 auto jsk = jrr[jss::signing_keys];
543 BEAST_EXPECT(jsk.size() == 2);
544 for (
auto const& val : validators)
546 BEAST_EXPECT(jsk.isMember(toStr(val.masterPublic)));
548 jsk[toStr(val.masterPublic)] ==
549 toStr(val.signingPublic));
553 auto const jrr = env.rpc(
"validator_list_sites")[jss::result];
554 if (BEAST_EXPECT(jrr[jss::validator_sites].
size() == 1))
556 auto js = jrr[jss::validator_sites][0u];
557 BEAST_EXPECT(js[jss::refresh_interval_min].
asUInt() == 5);
558 BEAST_EXPECT(js[jss::uri] == siteURI);
559 BEAST_EXPECT(js[jss::last_refresh_status] ==
"accepted");
562 BEAST_EXPECT(js.isMember(jss::last_refresh_time));
571 using namespace test::jtx;
573 auto result = env.
rpc(
"validation_create");
575 result.isMember(jss::result) &&
576 result[jss::result][jss::status] ==
"success");
579 "BAWL MAN JADE MOON DOVE GEM SON NOW HAD ADEN GLOW TIRE");
581 result.isMember(jss::result) &&
582 result[jss::result][jss::status] ==
"success");
591 test_validation_create();
595BEAST_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
const char * getEnvLocalhostAddr()
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)
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.