rippled
ValidatorList_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright 2015 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/ValidatorList.h>
21 #include <ripple/basics/base64.h>
22 #include <ripple/basics/Slice.h>
23 #include <ripple/basics/strHex.h>
24 #include <test/jtx.h>
25 #include <ripple/protocol/digest.h>
26 #include <ripple/protocol/HashPrefix.h>
27 #include <ripple/protocol/PublicKey.h>
28 #include <ripple/protocol/SecretKey.h>
29 #include <ripple/protocol/Sign.h>
30 
31 
32 namespace ripple {
33 namespace test {
34 
35 class ValidatorList_test : public beast::unit_test::suite
36 {
37 private:
38  struct Validator
39  {
43  };
44 
45  static
46  PublicKey
48  {
50  }
51 
52  static
53  PublicKey
55  {
57  }
58 
59  static
62  PublicKey const& pk,
63  SecretKey const& sk,
64  PublicKey const& spk,
65  SecretKey const& ssk,
66  int seq)
67  {
68  STObject st(sfGeneric);
69  st[sfSequence] = seq;
70  st[sfPublicKey] = pk;
71 
73  {
74  st[sfSigningPubKey] = spk;
75  sign(st, HashPrefix::manifest, *publicKeyType(spk), ssk);
76  }
77 
79 
80  Serializer s;
81  st.add(s);
82 
83  return std::string(static_cast<char const*> (s.data()), s.size());
84  }
85 
86  static
89  PublicKey const& pk,
90  SecretKey const& sk)
91  {
92  STObject st(sfGeneric);
94  st[sfPublicKey] = pk;
95 
97 
98  Serializer s;
99  st.add(s);
100 
101  return std::string(static_cast<char const*> (s.data()), s.size());
102  }
103 
104  static
105  Validator
107  {
108  auto const secret = randomSecretKey();
109  auto const masterPublic =
111  auto const signingKeys = randomKeyPair(KeyType::secp256k1);
112  return { masterPublic, signingKeys.first,
114  masterPublic, secret, signingKeys.first, signingKeys.second, 1)) };
115  }
116 
119  std::vector <Validator> const& validators,
120  std::size_t sequence,
122  {
123  std::string data =
124  "{\"sequence\":" + std::to_string(sequence) +
125  ",\"expiration\":" + std::to_string(expiration) +
126  ",\"validators\":[";
127 
128  for (auto const& val : validators)
129  {
130  data += "{\"validation_public_key\":\"" + strHex(val.masterPublic) +
131  "\",\"manifest\":\"" + val.manifest + "\"},";
132  }
133 
134  data.pop_back();
135  data += "]}";
136  return base64_encode(data);
137  }
138 
141  std::string const& blob,
143  {
144  auto const data = base64_decode (blob);
145  return strHex(sign(
146  keys.first, keys.second, makeSlice(data)));
147  }
148 
149  static hash_set<NodeID>
151  {
152  hash_set<NodeID> res;
153  res.reserve(pks.size());
154  for (auto const& pk : pks)
155  res.insert(calcNodeID(pk));
156  return res;
157  }
158 
159  void
161  {
162  testcase ("Genesis Quorum");
163 
164  ManifestCache manifests;
165  jtx::Env env (*this);
166  auto& app = env.app();
167  {
168  auto trustedKeys = std::make_unique <ValidatorList> (
169  manifests, manifests, env.timeKeeper(),
170  app.config().legacy("database_path"),
171  env.journal);
172  BEAST_EXPECT(trustedKeys->quorum () == 1);
173  }
174  {
175  std::size_t minQuorum = 0;
176  auto trustedKeys = std::make_unique <ValidatorList> (
177  manifests, manifests, env.timeKeeper(),
178  app.config().legacy("database_path"),
179  env.journal, minQuorum);
180  BEAST_EXPECT(trustedKeys->quorum () == minQuorum);
181  }
182  }
183 
184  void
186  {
187  testcase ("Config Load");
188 
189  jtx::Env env (*this);
190  auto& app = env.app();
191  PublicKey emptyLocalKey;
192  std::vector<std::string> const emptyCfgKeys;
193  std::vector<std::string> const emptyCfgPublishers;
194 
195  auto const localSigningKeys = randomKeyPair(KeyType::secp256k1);
196  auto const localSigningPublicOuter = localSigningKeys.first;
197  auto const localSigningSecret = localSigningKeys.second;
198  auto const localMasterSecret = randomSecretKey();
199  auto const localMasterPublic = derivePublicKey(
200  KeyType::ed25519, localMasterSecret);
201 
202  std::string const cfgManifest (makeManifestString (
203  localMasterPublic, localMasterSecret,
204  localSigningPublicOuter, localSigningSecret, 1));
205 
206  auto format = [](
207  PublicKey const &publicKey,
208  char const* comment = nullptr)
209  {
210  auto ret = toBase58 (TokenType::NodePublic, publicKey);
211 
212  if (comment)
213  ret += comment;
214 
215  return ret;
216  };
217 
218  std::vector<PublicKey> configList;
219  configList.reserve(8);
220 
221  while (configList.size () != 8)
222  configList.push_back (randomNode());
223 
224  // Correct configuration
225  std::vector<std::string> cfgKeys ({
226  format (configList[0]),
227  format (configList[1], " Comment"),
228  format (configList[2], " Multi Word Comment"),
229  format (configList[3], " Leading Whitespace"),
230  format (configList[4], " Trailing Whitespace "),
231  format (configList[5], " Leading & Trailing Whitespace "),
232  format (configList[6], " Leading, Trailing & Internal Whitespace "),
233  format (configList[7], " ")
234  });
235 
236  {
237  ManifestCache manifests;
238  auto trustedKeys = std::make_unique <ValidatorList> (
239  manifests, manifests, env.timeKeeper(),
240  app.config().legacy("database_path"),
241  env.journal);
242 
243  // Correct (empty) configuration
244  BEAST_EXPECT(trustedKeys->load (
245  emptyLocalKey, emptyCfgKeys, emptyCfgPublishers));
246 
247  // load local validator key with or without manifest
248  BEAST_EXPECT(trustedKeys->load (
249  localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
250  BEAST_EXPECT(trustedKeys->listed (localSigningPublicOuter));
251 
252  manifests.applyManifest (*deserializeManifest(cfgManifest));
253  BEAST_EXPECT(trustedKeys->load (
254  localSigningPublicOuter, emptyCfgKeys, emptyCfgPublishers));
255 
256  BEAST_EXPECT(trustedKeys->listed (localMasterPublic));
257  BEAST_EXPECT(trustedKeys->listed (localSigningPublicOuter));
258  }
259  {
260  // load should add validator keys from config
261  ManifestCache manifests;
262  auto trustedKeys = std::make_unique <ValidatorList> (
263  manifests, manifests, env.timeKeeper(),
264  app.config().legacy("database_path"),
265  env.journal);
266 
267  BEAST_EXPECT(trustedKeys->load (
268  emptyLocalKey, cfgKeys, emptyCfgPublishers));
269 
270  for (auto const& n : configList)
271  BEAST_EXPECT(trustedKeys->listed (n));
272 
273  // load should accept Ed25519 master public keys
274  auto const masterNode1 = randomMasterKey ();
275  auto const masterNode2 = randomMasterKey ();
276 
277  std::vector<std::string> cfgMasterKeys({
278  format (masterNode1),
279  format (masterNode2, " Comment")
280  });
281  BEAST_EXPECT(trustedKeys->load (
282  emptyLocalKey, cfgMasterKeys, emptyCfgPublishers));
283  BEAST_EXPECT(trustedKeys->listed (masterNode1));
284  BEAST_EXPECT(trustedKeys->listed (masterNode2));
285 
286  // load should reject invalid config keys
287  BEAST_EXPECT(!trustedKeys->load (emptyLocalKey,
288  { "NotAPublicKey" }, emptyCfgPublishers));
289  BEAST_EXPECT(!trustedKeys->load (emptyLocalKey,
290  { format (randomNode(), "!") }, emptyCfgPublishers));
291 
292  // load terminates when encountering an invalid entry
293  auto const goodKey = randomNode();
294  BEAST_EXPECT(!trustedKeys->load (emptyLocalKey,
295  { format (randomNode(), "!"), format (goodKey) },
296  emptyCfgPublishers));
297  BEAST_EXPECT(!trustedKeys->listed (goodKey));
298  }
299  {
300  // local validator key on config list
301  ManifestCache manifests;
302  auto trustedKeys = std::make_unique <ValidatorList> (
303  manifests, manifests, env.timeKeeper(),
304  app.config().legacy("database_path"),
305  env.journal);
306 
307  auto const localSigningPublic = parseBase58<PublicKey> (
308  TokenType::NodePublic, cfgKeys.front());
309 
310  BEAST_EXPECT(trustedKeys->load (
311  *localSigningPublic, cfgKeys, emptyCfgPublishers));
312 
313  BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
314  BEAST_EXPECT(trustedKeys->listed (*localSigningPublic));
315  for (auto const& n : configList)
316  BEAST_EXPECT(trustedKeys->listed (n));
317  }
318  {
319  // local validator key not on config list
320  ManifestCache manifests;
321  auto trustedKeys = std::make_unique <ValidatorList> (
322  manifests, manifests, env.timeKeeper(),
323  app.config().legacy("database_path"),
324  env.journal);
325 
326  auto const localSigningPublic = randomNode();
327  BEAST_EXPECT(trustedKeys->load (
328  localSigningPublic, cfgKeys, emptyCfgPublishers));
329 
330  BEAST_EXPECT(trustedKeys->localPublicKey() == localSigningPublic);
331  BEAST_EXPECT(trustedKeys->listed (localSigningPublic));
332  for (auto const& n : configList)
333  BEAST_EXPECT(trustedKeys->listed (n));
334  }
335  {
336  // local validator key (with manifest) not on config list
337  ManifestCache manifests;
338  auto trustedKeys = std::make_unique <ValidatorList> (
339  manifests, manifests, env.timeKeeper(),
340  app.config().legacy("database_path"),
341  env.journal);
342 
343  manifests.applyManifest (*deserializeManifest(cfgManifest));
344 
345  BEAST_EXPECT(trustedKeys->load (
346  localSigningPublicOuter, cfgKeys, emptyCfgPublishers));
347 
348  BEAST_EXPECT(trustedKeys->localPublicKey() == localMasterPublic);
349  BEAST_EXPECT(trustedKeys->listed (localSigningPublicOuter));
350  BEAST_EXPECT(trustedKeys->listed (localMasterPublic));
351  for (auto const& n : configList)
352  BEAST_EXPECT(trustedKeys->listed (n));
353  }
354  {
355  ManifestCache manifests;
356  auto trustedKeys = std::make_unique <ValidatorList> (
357  manifests, manifests, env.timeKeeper(),
358  app.config().legacy("database_path"),
359  env.journal);
360 
361  // load should reject invalid validator list signing keys
362  std::vector<std::string> badPublishers(
363  {"NotASigningKey"});
364  BEAST_EXPECT(!trustedKeys->load (
365  emptyLocalKey, emptyCfgKeys, badPublishers));
366 
367  // load should reject validator list signing keys with invalid encoding
368  std::vector<PublicKey> keys ({
370  badPublishers.clear();
371  for (auto const& key : keys)
372  badPublishers.push_back (
374 
375  BEAST_EXPECT(! trustedKeys->load (
376  emptyLocalKey, emptyCfgKeys, badPublishers));
377  for (auto const& key : keys)
378  BEAST_EXPECT(!trustedKeys->trustedPublisher (key));
379 
380  // load should accept valid validator list publisher keys
381  std::vector<std::string> cfgPublishers;
382  for (auto const& key : keys)
383  cfgPublishers.push_back (strHex(key));
384 
385  BEAST_EXPECT(trustedKeys->load (
386  emptyLocalKey, emptyCfgKeys, cfgPublishers));
387  for (auto const& key : keys)
388  BEAST_EXPECT(trustedKeys->trustedPublisher (key));
389  }
390  {
391  // Attempt to load a publisher key that has been revoked.
392  // Should fail
393  ManifestCache valManifests;
394  ManifestCache pubManifests;
395  auto trustedKeys = std::make_unique <ValidatorList> (
396  valManifests, pubManifests, env.timeKeeper(),
397  app.config().legacy("database_path"),
398  env.journal);
399 
400  auto const pubRevokedSecret = randomSecretKey();
401  auto const pubRevokedPublic =
402  derivePublicKey(KeyType::ed25519, pubRevokedSecret);
403  auto const pubRevokedSigning = randomKeyPair(KeyType::secp256k1);
404  // make this manifest revoked (seq num = max)
405  // -- thus should not be loaded
406  pubManifests.applyManifest (*deserializeManifest (
408  pubRevokedPublic,
409  pubRevokedSecret,
410  pubRevokedSigning.first,
411  pubRevokedSigning.second,
413 
414  // this one is not revoked (and not in manifest cache at all.)
415  auto legitKey = randomMasterKey();
416 
417  std::vector<std::string> cfgPublishers = {
418  strHex(pubRevokedPublic),
419  strHex(legitKey) };
420  BEAST_EXPECT(trustedKeys->load (
421  emptyLocalKey, emptyCfgKeys, cfgPublishers));
422 
423  BEAST_EXPECT(!trustedKeys->trustedPublisher (pubRevokedPublic));
424  BEAST_EXPECT(trustedKeys->trustedPublisher (legitKey));
425  }
426  }
427 
428  void
430  {
431  testcase ("Apply list");
432 
433  std::string const siteUri = "testApplyList.test";
434 
435  ManifestCache manifests;
436  jtx::Env env (*this);
437  auto& app = env.app();
438  auto trustedKeys = std::make_unique<ValidatorList> (
439  manifests, manifests, env.app().timeKeeper(),
440  app.config().legacy("database_path"),
441  env.journal);
442 
443  auto const publisherSecret = randomSecretKey();
444  auto const publisherPublic =
445  derivePublicKey(KeyType::ed25519, publisherSecret);
446  auto const pubSigningKeys1 = randomKeyPair(KeyType::secp256k1);
447  auto const manifest1 = base64_encode(makeManifestString (
448  publisherPublic, publisherSecret,
449  pubSigningKeys1.first, pubSigningKeys1.second, 1));
450 
451  std::vector<std::string> cfgKeys1({
452  strHex(publisherPublic)});
453  PublicKey emptyLocalKey;
454  std::vector<std::string> emptyCfgKeys;
455 
456  BEAST_EXPECT(trustedKeys->load (
457  emptyLocalKey, emptyCfgKeys, cfgKeys1));
458 
459  auto constexpr listSize = 20;
461  list1.reserve (listSize);
462  while (list1.size () < listSize)
463  list1.push_back (randomValidator());
464 
466  list2.reserve (listSize);
467  while (list2.size () < listSize)
468  list2.push_back (randomValidator());
469 
470  // do not apply expired list
471  auto const version = 1;
472  auto const sequence = 1;
473  auto const expiredblob = makeList (
474  list1, sequence, env.timeKeeper().now().time_since_epoch().count());
475  auto const expiredSig = signList (expiredblob, pubSigningKeys1);
476 
477  BEAST_EXPECT(ListDisposition::stale ==
478  trustedKeys->applyList (
479  manifest1, expiredblob, expiredSig,
480  version, siteUri).disposition);
481 
482  // apply single list
483  using namespace std::chrono_literals;
485  env.timeKeeper().now() + 3600s;
486  auto const blob1 = makeList (
487  list1, sequence, expiration.time_since_epoch().count());
488  auto const sig1 = signList (blob1, pubSigningKeys1);
489 
490  BEAST_EXPECT(ListDisposition::accepted ==
491  trustedKeys->applyList ( manifest1, blob1,
492  sig1, version, siteUri).disposition);
493 
494  for (auto const& val : list1)
495  {
496  BEAST_EXPECT(trustedKeys->listed (val.masterPublic));
497  BEAST_EXPECT(trustedKeys->listed (val.signingPublic));
498  }
499 
500  // do not use list from untrusted publisher
501  auto const untrustedManifest = base64_encode(
503  randomMasterKey(), publisherSecret,
504  pubSigningKeys1.first, pubSigningKeys1.second, 1));
505 
506  BEAST_EXPECT(ListDisposition::untrusted == trustedKeys->applyList (
507  untrustedManifest, blob1, sig1, version, siteUri).disposition);
508 
509  // do not use list with unhandled version
510  auto const badVersion = 666;
512  trustedKeys->applyList (
513  manifest1, blob1, sig1, badVersion, siteUri).disposition);
514 
515  // apply list with highest sequence number
516  auto const sequence2 = 2;
517  auto const blob2 = makeList (
518  list2, sequence2, expiration.time_since_epoch().count());
519  auto const sig2 = signList (blob2, pubSigningKeys1);
520 
521  BEAST_EXPECT(ListDisposition::accepted ==
522  trustedKeys->applyList (
523  manifest1, blob2, sig2, version, siteUri).disposition);
524 
525  for (auto const& val : list1)
526  {
527  BEAST_EXPECT(! trustedKeys->listed (val.masterPublic));
528  BEAST_EXPECT(! trustedKeys->listed (val.signingPublic));
529  }
530 
531  for (auto const& val : list2)
532  {
533  BEAST_EXPECT(trustedKeys->listed (val.masterPublic));
534  BEAST_EXPECT(trustedKeys->listed (val.signingPublic));
535  }
536 
537  // do not re-apply lists with past or current sequence numbers
538  BEAST_EXPECT(ListDisposition::stale ==
539  trustedKeys->applyList (
540  manifest1, blob1, sig1, version, siteUri).disposition);
541 
542  BEAST_EXPECT(ListDisposition::same_sequence ==
543  trustedKeys->applyList (
544  manifest1, blob2, sig2, version, siteUri).disposition);
545 
546  // apply list with new publisher key updated by manifest
547  auto const pubSigningKeys2 = randomKeyPair(KeyType::secp256k1);
548  auto manifest2 = base64_encode(makeManifestString (
549  publisherPublic, publisherSecret,
550  pubSigningKeys2.first, pubSigningKeys2.second, 2));
551 
552  auto const sequence3 = 3;
553  auto const blob3 = makeList (
554  list1, sequence3, expiration.time_since_epoch().count());
555  auto const sig3 = signList (blob3, pubSigningKeys2);
556 
557  BEAST_EXPECT(ListDisposition::accepted ==
558  trustedKeys->applyList (
559  manifest2, blob3, sig3, version, siteUri).disposition);
560 
561  auto const sequence4 = 4;
562  auto const blob4 = makeList (
563  list1, sequence4, expiration.time_since_epoch().count());
564  auto const badSig = signList (blob4, pubSigningKeys1);
565  BEAST_EXPECT(ListDisposition::invalid ==
566  trustedKeys->applyList (
567  manifest1, blob4, badSig, version, siteUri).disposition);
568 
569  // do not apply list with revoked publisher key
570  // applied list is removed due to revoked publisher key
571  auto const signingKeysMax = randomKeyPair(KeyType::secp256k1);
572  auto maxManifest = base64_encode(makeRevocationString (
573  publisherPublic, publisherSecret));
574 
575  auto const sequence5 = 5;
576  auto const blob5 = makeList (
577  list1, sequence5, expiration.time_since_epoch().count());
578  auto const sig5 = signList (blob5, signingKeysMax);
579 
580  BEAST_EXPECT(ListDisposition::untrusted ==
581  trustedKeys->applyList (
582  maxManifest, blob5, sig5, version, siteUri).disposition);
583 
584  BEAST_EXPECT(! trustedKeys->trustedPublisher(publisherPublic));
585  for (auto const& val : list1)
586  {
587  BEAST_EXPECT(! trustedKeys->listed (val.masterPublic));
588  BEAST_EXPECT(! trustedKeys->listed (val.signingPublic));
589  }
590  }
591 
592  void
594  {
595  testcase ("Update trusted");
596 
597  std::string const siteUri = "testUpdateTrusted.test";
598 
599  PublicKey emptyLocalKeyOuter;
600  ManifestCache manifestsOuter;
601  jtx::Env env (*this);
602  auto& app = env.app();
603  auto trustedKeysOuter = std::make_unique <ValidatorList> (
604  manifestsOuter, manifestsOuter, env.timeKeeper(),
605  app.config().legacy("database_path"),
606  env.journal);
607 
608  std::vector<std::string> cfgPublishersOuter;
609  hash_set<NodeID> activeValidatorsOuter;
610 
611  std::size_t const maxKeys = 40;
612  {
613  std::vector<std::string> cfgKeys;
614  cfgKeys.reserve(maxKeys);
615  hash_set<NodeID> unseenValidators;
616 
617  while (cfgKeys.size () != maxKeys)
618  {
619  auto const valKey = randomNode();
620  cfgKeys.push_back (toBase58(
621  TokenType::NodePublic, valKey));
622  if (cfgKeys.size () <= maxKeys - 5)
623  activeValidatorsOuter.emplace (calcNodeID(valKey));
624  else
625  unseenValidators.emplace (calcNodeID(valKey));
626  }
627 
628  BEAST_EXPECT(trustedKeysOuter->load (
629  emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
630 
631  // updateTrusted should make all configured validators trusted
632  // even if they are not active/seen
633  TrustChanges changes =
634  trustedKeysOuter->updateTrusted(activeValidatorsOuter);
635 
636  for (auto const& val : unseenValidators)
637  activeValidatorsOuter.emplace (val);
638 
639  BEAST_EXPECT(changes.added == activeValidatorsOuter);
640  BEAST_EXPECT(changes.removed.empty());
641  BEAST_EXPECT(trustedKeysOuter->quorum () ==
642  std::ceil(cfgKeys.size() * 0.8f));
643  for (auto const& val : cfgKeys)
644  {
645  if (auto const valKey = parseBase58<PublicKey>(
646  TokenType::NodePublic, val))
647  {
648  BEAST_EXPECT(trustedKeysOuter->listed (*valKey));
649  BEAST_EXPECT(trustedKeysOuter->trusted (*valKey));
650  }
651  else
652  fail ();
653  }
654 
655  changes =
656  trustedKeysOuter->updateTrusted(activeValidatorsOuter);
657  BEAST_EXPECT(changes.added.empty());
658  BEAST_EXPECT(changes.removed.empty());
659  BEAST_EXPECT(trustedKeysOuter->quorum () ==
660  std::ceil(cfgKeys.size() * 0.8f));
661  }
662  {
663  // update with manifests
664  auto const masterPrivate = randomSecretKey();
665  auto const masterPublic =
666  derivePublicKey(KeyType::ed25519, masterPrivate);
667 
668  std::vector<std::string> cfgKeys ({
669  toBase58 (TokenType::NodePublic, masterPublic)});
670 
671  BEAST_EXPECT(trustedKeysOuter->load (
672  emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
673 
674  auto const signingKeys1 = randomKeyPair(KeyType::secp256k1);
675  auto const signingPublic1 = signingKeys1.first;
676  activeValidatorsOuter.emplace (calcNodeID(masterPublic));
677 
678  // Should not trust ephemeral signing key if there is no manifest
679  TrustChanges changes =
680  trustedKeysOuter->updateTrusted(activeValidatorsOuter);
681  BEAST_EXPECT(changes.added == asNodeIDs({masterPublic}));
682  BEAST_EXPECT(changes.removed.empty());
683  BEAST_EXPECT(trustedKeysOuter->quorum () == std::ceil((maxKeys + 1) * 0.8f));
684  BEAST_EXPECT(trustedKeysOuter->listed (masterPublic));
685  BEAST_EXPECT(trustedKeysOuter->trusted (masterPublic));
686  BEAST_EXPECT(!trustedKeysOuter->listed (signingPublic1));
687  BEAST_EXPECT(!trustedKeysOuter->trusted (signingPublic1));
688 
689  // Should trust the ephemeral signing key from the applied manifest
691  masterPublic, masterPrivate,
692  signingPublic1, signingKeys1.second, 1));
693 
694  BEAST_EXPECT(
695  manifestsOuter.applyManifest(std::move (*m1)) ==
697  BEAST_EXPECT(trustedKeysOuter->listed (masterPublic));
698  BEAST_EXPECT(trustedKeysOuter->trusted (masterPublic));
699  BEAST_EXPECT(trustedKeysOuter->listed (signingPublic1));
700  BEAST_EXPECT(trustedKeysOuter->trusted (signingPublic1));
701 
702  // Should only trust the ephemeral signing key
703  // from the newest applied manifest
704  auto const signingKeys2 = randomKeyPair(KeyType::secp256k1);
705  auto const signingPublic2 = signingKeys2.first;
707  masterPublic, masterPrivate,
708  signingPublic2, signingKeys2.second, 2));
709  BEAST_EXPECT(
710  manifestsOuter.applyManifest(std::move (*m2)) ==
712  BEAST_EXPECT(trustedKeysOuter->listed (masterPublic));
713  BEAST_EXPECT(trustedKeysOuter->trusted (masterPublic));
714  BEAST_EXPECT(trustedKeysOuter->listed (signingPublic2));
715  BEAST_EXPECT(trustedKeysOuter->trusted (signingPublic2));
716  BEAST_EXPECT(!trustedKeysOuter->listed (signingPublic1));
717  BEAST_EXPECT(!trustedKeysOuter->trusted (signingPublic1));
718 
719  // Should not trust keys from revoked master public key
720  auto const signingKeysMax = randomKeyPair(KeyType::secp256k1);
721  auto const signingPublicMax = signingKeysMax.first;
722  activeValidatorsOuter.emplace (calcNodeID(signingPublicMax));
724  masterPublic, masterPrivate));
725 
726  BEAST_EXPECT(mMax->revoked ());
727  BEAST_EXPECT(
728  manifestsOuter.applyManifest(std::move (*mMax)) ==
730  BEAST_EXPECT(manifestsOuter.getSigningKey (masterPublic) == masterPublic);
731  BEAST_EXPECT(manifestsOuter.revoked (masterPublic));
732 
733  // Revoked key remains trusted until list is updated
734  BEAST_EXPECT(trustedKeysOuter->listed (masterPublic));
735  BEAST_EXPECT(trustedKeysOuter->trusted (masterPublic));
736 
737  changes = trustedKeysOuter->updateTrusted (activeValidatorsOuter);
738  BEAST_EXPECT(changes.removed == asNodeIDs({masterPublic}));
739  BEAST_EXPECT(changes.added.empty());
740  BEAST_EXPECT(trustedKeysOuter->quorum () == std::ceil(maxKeys * 0.8f));
741  BEAST_EXPECT(trustedKeysOuter->listed (masterPublic));
742  BEAST_EXPECT(!trustedKeysOuter->trusted (masterPublic));
743  BEAST_EXPECT(!trustedKeysOuter->listed (signingPublicMax));
744  BEAST_EXPECT(!trustedKeysOuter->trusted (signingPublicMax));
745  BEAST_EXPECT(!trustedKeysOuter->listed (signingPublic2));
746  BEAST_EXPECT(!trustedKeysOuter->trusted (signingPublic2));
747  BEAST_EXPECT(!trustedKeysOuter->listed (signingPublic1));
748  BEAST_EXPECT(!trustedKeysOuter->trusted (signingPublic1));
749  }
750  {
751  // Make quorum unattainable if lists from any publishers are unavailable
752  auto trustedKeys = std::make_unique <ValidatorList> (
753  manifestsOuter, manifestsOuter, env.timeKeeper(),
754  app.config().legacy("database_path"),
755  env.journal);
756  auto const publisherSecret = randomSecretKey();
757  auto const publisherPublic =
758  derivePublicKey(KeyType::ed25519, publisherSecret);
759 
760  std::vector<std::string> cfgPublishers({
761  strHex(publisherPublic)});
762  std::vector<std::string> emptyCfgKeys;
763 
764  BEAST_EXPECT(trustedKeys->load (
765  emptyLocalKeyOuter, emptyCfgKeys, cfgPublishers));
766 
767  TrustChanges changes =
768  trustedKeys->updateTrusted(activeValidatorsOuter);
769  BEAST_EXPECT(changes.removed.empty());
770  BEAST_EXPECT(changes.added.empty());
771  BEAST_EXPECT(trustedKeys->quorum () ==
773  }
774  {
775  // Should use custom minimum quorum
776  std::size_t const minQuorum = 1;
777  ManifestCache manifests;
778  auto trustedKeys = std::make_unique <ValidatorList> (
779  manifests, manifests, env.timeKeeper(),
780  app.config().legacy("database_path"),
781  env.journal, minQuorum);
782 
783  std::size_t n = 10;
784  std::vector<std::string> cfgKeys;
785  cfgKeys.reserve(n);
786  hash_set<NodeID> expectedTrusted;
787  hash_set<NodeID> activeValidators;
788  NodeID toBeSeen;
789 
790  while (cfgKeys.size () < n)
791  {
792  auto const valKey = randomNode();
793  cfgKeys.push_back (toBase58(
794  TokenType::NodePublic, valKey));
795  expectedTrusted.emplace (calcNodeID(valKey));
796  if (cfgKeys.size () < std::ceil(n*0.8f))
797  activeValidators.emplace (calcNodeID(valKey));
798  else if (cfgKeys.size () < std::ceil(n*0.8f))
799  toBeSeen = calcNodeID(valKey);
800  }
801 
802  BEAST_EXPECT(trustedKeys->load (
803  emptyLocalKeyOuter, cfgKeys, cfgPublishersOuter));
804 
805  TrustChanges changes =
806  trustedKeys->updateTrusted(activeValidators);
807  BEAST_EXPECT(changes.removed.empty());
808  BEAST_EXPECT(changes.added == expectedTrusted);
809  BEAST_EXPECT(trustedKeys->quorum () == minQuorum);
810 
811  // Use normal quorum when seen validators >= quorum
812  activeValidators.emplace (toBeSeen);
813  changes = trustedKeys->updateTrusted(activeValidators);
814  BEAST_EXPECT(changes.removed.empty());
815  BEAST_EXPECT(changes.added.empty());
816  BEAST_EXPECT(trustedKeys->quorum () == std::ceil(n * 0.8f));
817  }
818  {
819  // Remove expired published list
820  auto trustedKeys = std::make_unique<ValidatorList> (
821  manifestsOuter, manifestsOuter, env.app().timeKeeper(),
822  app.config().legacy("database_path"),
823  env.journal);
824 
825  PublicKey emptyLocalKey;
826  std::vector<std::string> emptyCfgKeys;
827  auto const publisherKeys = randomKeyPair(KeyType::secp256k1);
828  auto const pubSigningKeys = randomKeyPair(KeyType::secp256k1);
829  auto const manifest = base64_encode (
831  publisherKeys.first, publisherKeys.second,
832  pubSigningKeys.first, pubSigningKeys.second, 1));
833 
834  std::vector<std::string> cfgKeys ({
835  strHex(publisherKeys.first)});
836 
837  BEAST_EXPECT(trustedKeys->load (
838  emptyLocalKey, emptyCfgKeys, cfgKeys));
839 
841  hash_set<NodeID> activeValidators(
842  asNodeIDs({list[0].masterPublic, list[1].masterPublic}));
843 
844  // do not apply expired list
845  auto const version = 1;
846  auto const sequence = 1;
847  using namespace std::chrono_literals;
849  env.timeKeeper().now() + 60s;
850  auto const blob = makeList (
851  list, sequence, expiration.time_since_epoch().count());
852  auto const sig = signList (blob, pubSigningKeys);
853 
854  BEAST_EXPECT(ListDisposition::accepted ==
855  trustedKeys->applyList (
856  manifest, blob, sig, version, siteUri).disposition);
857 
858  TrustChanges changes =
859  trustedKeys->updateTrusted(activeValidators);
860  BEAST_EXPECT(changes.removed.empty());
861  BEAST_EXPECT(changes.added == activeValidators);
862  for(Validator const & val : list)
863  {
864  BEAST_EXPECT(trustedKeys->trusted (val.masterPublic));
865  BEAST_EXPECT(trustedKeys->trusted (val.signingPublic));
866  }
867  BEAST_EXPECT(trustedKeys->quorum () == 2);
868 
869  env.timeKeeper().set(expiration);
870  changes = trustedKeys->updateTrusted (activeValidators);
871  BEAST_EXPECT(changes.removed == activeValidators);
872  BEAST_EXPECT(changes.added.empty());
873  BEAST_EXPECT(! trustedKeys->trusted (list[0].masterPublic));
874  BEAST_EXPECT(! trustedKeys->trusted (list[1].masterPublic));
875  BEAST_EXPECT(trustedKeys->quorum () ==
877 
878  // (Re)trust validators from new valid list
879  std::vector<Validator> list2 ({list[0], randomValidator()});
880  activeValidators.insert(calcNodeID(list2[1].masterPublic));
881  auto const sequence2 = 2;
882  NetClock::time_point const expiration2 =
883  env.timeKeeper().now() + 60s;
884  auto const blob2 = makeList (
885  list2, sequence2, expiration2.time_since_epoch().count());
886  auto const sig2 = signList (blob2, pubSigningKeys);
887 
888  BEAST_EXPECT(ListDisposition::accepted ==
889  trustedKeys->applyList (
890  manifest, blob2, sig2, version, siteUri).disposition);
891 
892  changes = trustedKeys->updateTrusted (activeValidators);
893  BEAST_EXPECT(changes.removed.empty());
894  BEAST_EXPECT(
895  changes.added ==
896  asNodeIDs({list2[0].masterPublic, list2[1].masterPublic}));
897  for(Validator const & val : list2)
898  {
899  BEAST_EXPECT(trustedKeys->trusted (val.masterPublic));
900  BEAST_EXPECT(trustedKeys->trusted (val.signingPublic));
901  }
902  BEAST_EXPECT(! trustedKeys->trusted (list[1].masterPublic));
903  BEAST_EXPECT(! trustedKeys->trusted (list[1].signingPublic));
904  BEAST_EXPECT(trustedKeys->quorum () == 2);
905  }
906  {
907  // Test 1-9 configured validators
908  auto trustedKeys = std::make_unique <ValidatorList> (
909  manifestsOuter, manifestsOuter, env.timeKeeper(),
910  app.config().legacy("database_path"),
911  env.journal);
912 
913  std::vector<std::string> cfgPublishers;
914  hash_set<NodeID> activeValidators;
915  hash_set<PublicKey> activeKeys;
916 
917  std::vector<std::string> cfgKeys;
918  cfgKeys.reserve(9);
919 
920  while (cfgKeys.size() < cfgKeys.capacity())
921  {
922  auto const valKey = randomNode();
923  cfgKeys.push_back (toBase58(
924  TokenType::NodePublic, valKey));
925  activeValidators.emplace (calcNodeID(valKey));
926  activeKeys.emplace(valKey);
927  BEAST_EXPECT(trustedKeys->load (
928  emptyLocalKeyOuter, cfgKeys, cfgPublishers));
929  TrustChanges changes =
930  trustedKeys->updateTrusted(activeValidators);
931  BEAST_EXPECT(changes.removed.empty());
932  BEAST_EXPECT(changes.added == asNodeIDs({valKey}));
933  BEAST_EXPECT(trustedKeys->quorum () ==
934  std::ceil(cfgKeys.size() * 0.8f));
935  for (auto const& key : activeKeys)
936  BEAST_EXPECT(trustedKeys->trusted (key));
937  }
938  }
939  {
940  // Test 2-9 configured validators as validator
941  auto trustedKeys = std::make_unique <ValidatorList> (
942  manifestsOuter, manifestsOuter, env.timeKeeper(),
943  app.config().legacy("database_path"),
944  env.journal);
945 
946  auto const localKey = randomNode();
947  std::vector<std::string> cfgPublishers;
948  hash_set<NodeID> activeValidators;
949  hash_set<PublicKey> activeKeys;
950  std::vector<std::string> cfgKeys {
951  toBase58(TokenType::NodePublic, localKey)};
952  cfgKeys.reserve(9);
953 
954  while (cfgKeys.size() < cfgKeys.capacity())
955  {
956  auto const valKey = randomNode();
957  cfgKeys.push_back (toBase58(
958  TokenType::NodePublic, valKey));
959  activeValidators.emplace (calcNodeID(valKey));
960  activeKeys.emplace(valKey);
961 
962  BEAST_EXPECT(trustedKeys->load (
963  localKey, cfgKeys, cfgPublishers));
964  TrustChanges changes =
965  trustedKeys->updateTrusted(activeValidators);
966  BEAST_EXPECT(changes.removed.empty());
967  if (cfgKeys.size() > 2)
968  BEAST_EXPECT(changes.added == asNodeIDs({valKey}));
969  else
970  BEAST_EXPECT(
971  changes.added == asNodeIDs({localKey, valKey}));
972 
973  BEAST_EXPECT(trustedKeys->quorum () ==
974  std::ceil(cfgKeys.size() * 0.8f));
975 
976  for (auto const& key : activeKeys)
977  BEAST_EXPECT(trustedKeys->trusted (key));
978  }
979  }
980  {
981  // Trusted set should include all validators from multiple lists
982  ManifestCache manifests;
983  auto trustedKeys = std::make_unique <ValidatorList> (
984  manifests, manifests, env.timeKeeper(),
985  app.config().legacy("database_path"),
986  env.journal);
987 
988  hash_set<NodeID> activeValidators;
989  std::vector<Validator> valKeys;
990  valKeys.reserve(maxKeys);
991 
992  while (valKeys.size () != maxKeys)
993  {
994  valKeys.push_back (randomValidator());
995  activeValidators.emplace(
996  calcNodeID(valKeys.back().masterPublic));
997  }
998 
999  auto addPublishedList = [this, &env, &trustedKeys, &valKeys, &siteUri]()
1000  {
1001  auto const publisherSecret = randomSecretKey();
1002  auto const publisherPublic =
1003  derivePublicKey(KeyType::ed25519, publisherSecret);
1004  auto const pubSigningKeys = randomKeyPair(KeyType::secp256k1);
1006  publisherPublic, publisherSecret,
1007  pubSigningKeys.first, pubSigningKeys.second, 1));
1008 
1009  std::vector<std::string> cfgPublishers({
1010  strHex(publisherPublic)});
1011  PublicKey emptyLocalKey;
1012  std::vector<std::string> emptyCfgKeys;
1013 
1014  BEAST_EXPECT(trustedKeys->load (
1015  emptyLocalKey, emptyCfgKeys, cfgPublishers));
1016 
1017  auto const version = 1;
1018  auto const sequence = 1;
1019  using namespace std::chrono_literals;
1021  env.timeKeeper().now() + 3600s;
1022  auto const blob = makeList (
1023  valKeys, sequence, expiration.time_since_epoch().count());
1024  auto const sig = signList (blob, pubSigningKeys);
1025 
1026  BEAST_EXPECT(ListDisposition::accepted ==
1027  trustedKeys->applyList (manifest, blob, sig, version,
1028  siteUri).disposition);
1029  };
1030 
1031  // Apply multiple published lists
1032  for (auto i = 0; i < 3; ++i)
1033  addPublishedList();
1034 
1035  TrustChanges changes =
1036  trustedKeys->updateTrusted(activeValidators);
1037 
1038  BEAST_EXPECT(trustedKeys->quorum () ==
1039  std::ceil(valKeys.size() * 0.8f));
1040 
1041  hash_set<NodeID> added;
1042  for (auto const& val : valKeys)
1043  {
1044  BEAST_EXPECT(trustedKeys->trusted (val.masterPublic));
1045  added.insert(calcNodeID(val.masterPublic));
1046  }
1047  BEAST_EXPECT(changes.added == added);
1048  BEAST_EXPECT(changes.removed.empty());
1049  }
1050  }
1051 
1052  void
1054  {
1055  testcase("Expires");
1056 
1057  std::string const siteUri = "testExpires.test";
1058 
1059  jtx::Env env(*this);
1060  auto& app = env.app();
1061 
1062  auto toStr = [](PublicKey const& publicKey) {
1063  return toBase58(TokenType::NodePublic, publicKey);
1064  };
1065 
1066  // Config listed keys
1067  {
1068  ManifestCache manifests;
1069  auto trustedKeys = std::make_unique<ValidatorList>(
1070  manifests, manifests, env.timeKeeper(),
1071  app.config().legacy("database_path"),
1072  env.journal);
1073 
1074  // Empty list has no expiration
1075  BEAST_EXPECT(trustedKeys->expires() == boost::none);
1076 
1077  // Config listed keys have maximum expiry
1078  PublicKey emptyLocalKey;
1079  PublicKey localCfgListed = randomNode();
1080  trustedKeys->load(emptyLocalKey, {toStr(localCfgListed)}, {});
1081  BEAST_EXPECT(
1082  trustedKeys->expires() &&
1083  trustedKeys->expires().get() == NetClock::time_point::max());
1084  BEAST_EXPECT(trustedKeys->listed(localCfgListed));
1085  }
1086 
1087  // Published keys with expirations
1088  {
1089  ManifestCache manifests;
1090  auto trustedKeys = std::make_unique<ValidatorList>(
1091  manifests, manifests, env.app().timeKeeper(),
1092  app.config().legacy("database_path"),
1093  env.journal);
1094 
1095  std::vector<Validator> validators = {randomValidator()};
1096  hash_set<NodeID> activeValidators;
1097  for(Validator const & val : validators)
1098  activeValidators.insert(calcNodeID(val.masterPublic));
1099  // Store prepared list data to control when it is applied
1100  struct PreparedList
1101  {
1103  std::string blob;
1104  std::string sig;
1105  int version;
1107  };
1108 
1109  using namespace std::chrono_literals;
1110  auto addPublishedList = [this, &env, &trustedKeys, &validators]()
1111  {
1112  auto const publisherSecret = randomSecretKey();
1113  auto const publisherPublic =
1114  derivePublicKey(KeyType::ed25519, publisherSecret);
1115  auto const pubSigningKeys = randomKeyPair(KeyType::secp256k1);
1117  publisherPublic, publisherSecret,
1118  pubSigningKeys.first, pubSigningKeys.second, 1));
1119 
1120  std::vector<std::string> cfgPublishers({
1121  strHex(publisherPublic)});
1122  PublicKey emptyLocalKey;
1123  std::vector<std::string> emptyCfgKeys;
1124 
1125  BEAST_EXPECT(trustedKeys->load (
1126  emptyLocalKey, emptyCfgKeys, cfgPublishers));
1127 
1128  auto const version = 1;
1129  auto const sequence = 1;
1131  env.timeKeeper().now() + 3600s;
1132  auto const blob = makeList(
1133  validators,
1134  sequence,
1135  expiration.time_since_epoch().count());
1136  auto const sig = signList (blob, pubSigningKeys);
1137 
1138  return PreparedList{manifest, blob, sig, version, expiration};
1139  };
1140 
1141 
1142  // Configure two publishers and prepare 2 lists
1143  PreparedList prep1 = addPublishedList();
1144  env.timeKeeper().set(env.timeKeeper().now() + 200s);
1145  PreparedList prep2 = addPublishedList();
1146 
1147  // Initially, no list has been published, so no known expiration
1148  BEAST_EXPECT(trustedKeys->expires() == boost::none);
1149 
1150  // Apply first list
1151  BEAST_EXPECT(
1152  ListDisposition::accepted == trustedKeys->applyList(
1153  prep1.manifest, prep1.blob, prep1.sig,
1154  prep1.version, siteUri).disposition);
1155 
1156  // One list still hasn't published, so expiration is still unknown
1157  BEAST_EXPECT(trustedKeys->expires() == boost::none);
1158 
1159  // Apply second list
1160  BEAST_EXPECT(
1161  ListDisposition::accepted == trustedKeys->applyList(
1162  prep2.manifest, prep2.blob, prep2.sig,
1163  prep2.version, siteUri).disposition);
1164 
1165  // We now have loaded both lists, so expiration is known
1166  BEAST_EXPECT(
1167  trustedKeys->expires() &&
1168  trustedKeys->expires().get() == prep1.expiration);
1169 
1170  // Advance past the first list's expiration, but it remains the
1171  // earliest expiration
1172  env.timeKeeper().set(prep1.expiration + 1s);
1173  trustedKeys->updateTrusted(activeValidators);
1174  BEAST_EXPECT(
1175  trustedKeys->expires() &&
1176  trustedKeys->expires().get() == prep1.expiration);
1177  }
1178 }
1179 public:
1180  void
1181  run() override
1182  {
1183  testGenesisQuorum ();
1184  testConfigLoad ();
1185  testApplyList ();
1186  testUpdateTrusted ();
1187  testExpires ();
1188  }
1189 };
1190 
1192 
1193 } // test
1194 } // ripple
ripple::test::ValidatorList_test::Validator
Definition: ValidatorList_test.cpp:38
ripple::test::ValidatorList_test::randomNode
static PublicKey randomNode()
Definition: ValidatorList_test.cpp:47
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:199
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
std::string
STL class.
ripple::test::ValidatorList_test::Validator::manifest
std::string manifest
Definition: ValidatorList_test.cpp:42
ripple::calcNodeID
NodeID calcNodeID(PublicKey const &pk)
Calculate the 160-bit node ID from a node public key.
Definition: PublicKey.cpp:307
ripple::sfGeneric
const SField sfGeneric(access, 0)
Definition: SField.h:317
ripple::publicKeyType
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
ripple::test::ValidatorList_test::testConfigLoad
void testConfigLoad()
Definition: ValidatorList_test.cpp:185
ripple::TrustChanges
Changes in trusted nodes after updating validator list.
Definition: ValidatorList.h:68
ripple::ListDisposition::stale
@ stale
Trusted publisher key, but seq is too old.
std::unordered_set
STL class.
std::pair
std::unordered_set::reserve
T reserve(T... args)
ripple::HashPrefix::manifest
@ manifest
Manifest.
ripple::sfSigningPubKey
const SF_Blob sfSigningPubKey(access, STI_VL, 3, "SigningPubKey")
Definition: SField.h:442
std::vector
STL class.
std::initializer_list::size
T size(T... args)
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:340
ripple::base64_encode
std::string base64_encode(std::uint8_t const *data, std::size_t len)
Definition: base64.cpp:227
ripple::test::ValidatorList_test::makeManifestString
static std::string makeManifestString(PublicKey const &pk, SecretKey const &sk, PublicKey const &spk, SecretKey const &ssk, int seq)
Definition: ValidatorList_test.cpp:61
ripple::sfMasterSignature
const SF_Blob sfMasterSignature(access, STI_VL, 18, "MasterSignature", SField::sMD_Default, SField::notSigning)
Definition: SField.h:457
ripple::test::ValidatorList_test::run
void run() override
Definition: ValidatorList_test.cpp:1181
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::test::ValidatorList_test
Definition: ValidatorList_test.cpp:35
ripple::test::ValidatorList_test::testApplyList
void testApplyList()
Definition: ValidatorList_test.cpp:429
std::unordered_set::emplace
T emplace(T... args)
ripple::test::jtx::Env::journal
const beast::Journal journal
Definition: Env.h:143
ripple::test::jtx::Env::timeKeeper
ManualTimeKeeper & timeKeeper()
Definition: Env.h:249
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:237
std::vector::back
T back(T... args)
ripple::Application::timeKeeper
virtual TimeKeeper & timeKeeper()=0
std::vector::clear
T clear(T... args)
ripple::test::ValidatorList_test::testExpires
void testExpires()
Definition: ValidatorList_test.cpp:1053
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:79
std::vector::push_back
T push_back(T... args)
ripple::KeyType::ed25519
@ ed25519
ripple::test::jtx::expiration
Set Expiration on a JTx.
Definition: Check_test.cpp:29
ripple::base_uint< 160, detail::NodeIDTag >
std::vector::capacity
T capacity(T... args)
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::test::ValidatorList_test::testGenesisQuorum
void testGenesisQuorum()
Definition: ValidatorList_test.cpp:160
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::test::ValidatorList_test::makeList
std::string makeList(std::vector< Validator > const &validators, std::size_t sequence, std::size_t expiration)
Definition: ValidatorList_test.cpp:118
ripple::derivePublicKey
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
Definition: SecretKey.cpp:228
ripple::ValidatorList
Definition: ValidatorList.h:119
ripple::TrustChanges::removed
hash_set< NodeID > removed
Definition: ValidatorList.h:73
ripple::test::ValidatorList_test::randomValidator
static Validator randomValidator()
Definition: ValidatorList_test.cpp:106
ripple::test::ValidatorList_test::makeRevocationString
static std::string makeRevocationString(PublicKey const &pk, SecretKey const &sk)
Definition: ValidatorList_test.cpp:88
std::to_string
T to_string(T... args)
ripple::ManifestCache::revoked
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
Definition: app/misc/impl/Manifest.cpp:349
ripple::base64_decode
std::string base64_decode(std::string const &data)
Definition: base64.cpp:237
std::chrono::time_point
ripple::ListDisposition::untrusted
@ untrusted
List signed by untrusted publisher key.
ripple::ManifestCache::getSigningKey
PublicKey getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
Definition: app/misc/impl/Manifest.cpp:289
ripple::test::ValidatorList_test::randomMasterKey
static PublicKey randomMasterKey()
Definition: ValidatorList_test.cpp:54
ripple::test::jtx::sig
Set the regular signature on a JTx.
Definition: sig.h:33
ripple::SecretKey
A secret key.
Definition: SecretKey.h:36
ripple::ListDisposition::unsupported_version
@ unsupported_version
List version is not supported.
std::ceil
T ceil(T... args)
ripple::test::ValidatorList_test::Validator::masterPublic
PublicKey masterPublic
Definition: ValidatorList_test.cpp:40
ripple::KeyType::secp256k1
@ secp256k1
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
ripple::Serializer
Definition: Serializer.h:43
ripple::randomKeyPair
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Definition: SecretKey.cpp:286
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:32
ripple::ManifestCache
Remembers manifests with the highest sequence number.
Definition: Manifest.h:213
ripple::STObject
Definition: STObject.h:51
ripple::sfPublicKey
const SF_Blob sfPublicKey(access, STI_VL, 1, "PublicKey")
Definition: SField.h:440
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::deserializeManifest
boost::optional< Manifest > deserializeManifest(Slice s)
Constructs Manifest from serialized string.
Definition: app/misc/impl/Manifest.cpp:37
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:73
ripple::STObject::add
virtual void add(Serializer &s) const override
Definition: STObject.h:343
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:132
ripple::test::ValidatorList_test::Validator::signingPublic
PublicKey signingPublic
Definition: ValidatorList_test.cpp:41
ripple::ListDisposition::same_sequence
@ same_sequence
Same sequence as current list.
std::unordered_set::insert
T insert(T... args)
ripple::ListDisposition::invalid
@ invalid
Invalid format or signature.
ripple::test::ValidatorList_test::asNodeIDs
static hash_set< NodeID > asNodeIDs(std::initializer_list< PublicKey > const &pks)
Definition: ValidatorList_test.cpp:150
ripple::test::ValidatorList_test::testUpdateTrusted
void testUpdateTrusted()
Definition: ValidatorList_test.cpp:593
ripple::TrustChanges::added
hash_set< NodeID > added
Definition: ValidatorList.h:72
ripple::TokenType::NodePublic
@ NodePublic
std::size_t
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:70
ripple::test::ManualTimeKeeper::now
time_point now() const override
Returns the estimate of wall time, in network time.
Definition: ManualTimeKeeper.cpp:39
std::numeric_limits::max
T max(T... args)
ripple::test::ManualTimeKeeper::set
void set(time_point now)
Definition: ManualTimeKeeper.cpp:86
ripple::ManifestCache::applyManifest
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
Definition: app/misc/impl/Manifest.cpp:361
ripple::test::ValidatorList_test::signList
std::string signList(std::string const &blob, std::pair< PublicKey, SecretKey > const &keys)
Definition: ValidatorList_test.cpp:140
std::numeric_limits
ripple::ListDisposition::accepted
@ accepted
List is valid.
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:117
ripple::randomSecretKey
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:184
std::initializer_list