rippled
app/misc/impl/Manifest.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/Manifest.h>
21 #include <ripple/app/rdb/Wallet.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/basics/StringUtilities.h>
24 #include <ripple/basics/base64.h>
25 #include <ripple/core/DatabaseCon.h>
26 #include <ripple/json/json_reader.h>
27 #include <ripple/protocol/PublicKey.h>
28 #include <ripple/protocol/Sign.h>
29 
30 #include <boost/algorithm/string/trim.hpp>
31 
32 #include <numeric>
33 #include <stdexcept>
34 
35 namespace ripple {
36 
39 {
40  auto const mk = toBase58(TokenType::NodePublic, m.masterKey);
41 
42  if (m.revoked())
43  return "Revocation Manifest " + mk;
44 
45  if (!m.signingKey)
46  Throw<std::runtime_error>("No SigningKey in manifest " + mk);
47 
48  return "Manifest " + mk + " (" + std::to_string(m.sequence) + ": " +
50 }
51 
54 {
55  if (s.empty())
56  return std::nullopt;
57 
58  static SOTemplate const manifestFormat{
59  // A manifest must include:
60  // - the master public key
62 
63  // - a signature with that public key
65 
66  // - a sequence number
68 
69  // It may, optionally, contain:
70  // - a version number which defaults to 0
72 
73  // - a domain name
75 
76  // - an ephemeral signing key that can be changed as necessary
78 
79  // - a signature using the ephemeral signing key, if it is present
81  };
82 
83  try
84  {
85  SerialIter sit{s};
86  STObject st{sit, sfGeneric};
87 
88  st.applyTemplate(manifestFormat);
89 
90  // We only understand "version 0" manifests at this time:
91  if (st.isFieldPresent(sfVersion) && st.getFieldU16(sfVersion) != 0)
92  return std::nullopt;
93 
94  auto const pk = st.getFieldVL(sfPublicKey);
95 
96  if (!publicKeyType(makeSlice(pk)))
97  return std::nullopt;
98 
99  PublicKey const masterKey = PublicKey(makeSlice(pk));
100  std::uint32_t const seq = st.getFieldU32(sfSequence);
101 
102  std::string domain;
103 
104  std::optional<PublicKey> signingKey;
105 
106  if (st.isFieldPresent(sfDomain))
107  {
108  auto const d = st.getFieldVL(sfDomain);
109 
110  domain.assign(reinterpret_cast<char const*>(d.data()), d.size());
111 
112  if (!isProperlyFormedTomlDomain(domain))
113  return std::nullopt;
114  }
115 
116  bool const hasEphemeralKey = st.isFieldPresent(sfSigningPubKey);
117  bool const hasEphemeralSig = st.isFieldPresent(sfSignature);
118 
119  if (Manifest::revoked(seq))
120  {
121  // Revocation manifests should not specify a new signing key
122  // or a signing key signature.
123  if (hasEphemeralKey)
124  return std::nullopt;
125 
126  if (hasEphemeralSig)
127  return std::nullopt;
128  }
129  else
130  {
131  // Regular manifests should contain a signing key and an
132  // associated signature.
133  if (!hasEphemeralKey)
134  return std::nullopt;
135 
136  if (!hasEphemeralSig)
137  return std::nullopt;
138 
139  auto const spk = st.getFieldVL(sfSigningPubKey);
140 
141  if (!publicKeyType(makeSlice(spk)))
142  return std::nullopt;
143 
144  signingKey.emplace(makeSlice(spk));
145 
146  // The signing and master keys can't be the same
147  if (*signingKey == masterKey)
148  return std::nullopt;
149  }
150 
151  std::string const serialized(
152  reinterpret_cast<char const*>(s.data()), s.size());
153 
154  // If the manifest is revoked, then the signingKey will be unseated
155  return Manifest(serialized, masterKey, signingKey, seq, domain);
156  }
157  catch (std::exception const& ex)
158  {
159  JLOG(journal.error())
160  << "Exception in " << __func__ << ": " << ex.what();
161  return std::nullopt;
162  }
163 }
164 
165 template <class Stream>
166 Stream&
168  Stream& s,
169  std::string const& action,
170  PublicKey const& pk,
171  std::uint32_t seq)
172 {
173  s << "Manifest: " << action
174  << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
175  << ";";
176  return s;
177 }
178 
179 template <class Stream>
180 Stream&
182  Stream& s,
183  std::string const& action,
184  PublicKey const& pk,
185  std::uint32_t seq,
186  std::uint32_t oldSeq)
187 {
188  s << "Manifest: " << action
189  << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
190  << ";OldSeq: " << oldSeq << ";";
191  return s;
192 }
193 
194 bool
196 {
197  STObject st(sfGeneric);
199  st.set(sit);
200 
201  // The manifest must either have a signing key or be revoked. This check
202  // prevents us from accessing an unseated signingKey in the next check.
203  if (!revoked() && !signingKey)
204  return false;
205 
206  // Signing key and signature are not required for
207  // master key revocations
209  return false;
210 
211  return ripple::verify(
213 }
214 
215 uint256
217 {
218  STObject st(sfGeneric);
220  st.set(sit);
221  return st.getHash(HashPrefix::manifest);
222 }
223 
224 bool
226 {
227  /*
228  The maximum possible sequence number means that the master key
229  has been revoked.
230  */
231  return revoked(sequence);
232 }
233 
234 bool
236 {
237  // The maximum possible sequence number means that the master key has
238  // been revoked.
240 }
241 
244 {
245  STObject st(sfGeneric);
247  st.set(sit);
248  if (!get(st, sfSignature))
249  return std::nullopt;
250  return st.getFieldVL(sfSignature);
251 }
252 
253 Blob
255 {
256  STObject st(sfGeneric);
258  st.set(sit);
259  return st.getFieldVL(sfMasterSignature);
260 }
261 
264 {
265  try
266  {
267  std::string tokenStr;
268 
269  tokenStr.reserve(std::accumulate(
270  blob.cbegin(),
271  blob.cend(),
272  std::size_t(0),
273  [](std::size_t init, std::string const& s) {
274  return init + s.size();
275  }));
276 
277  for (auto const& line : blob)
278  tokenStr += boost::algorithm::trim_copy(line);
279 
280  tokenStr = base64_decode(tokenStr);
281 
282  Json::Reader r;
283  Json::Value token;
284 
285  if (r.parse(tokenStr, token))
286  {
287  auto const m = token.get("manifest", Json::Value{});
288  auto const k = token.get("validation_secret_key", Json::Value{});
289 
290  if (m.isString() && k.isString())
291  {
292  auto const key = strUnHex(k.asString());
293 
294  if (key && key->size() == 32)
295  return ValidatorToken{m.asString(), makeSlice(*key)};
296  }
297  }
298 
299  return std::nullopt;
300  }
301  catch (std::exception const& ex)
302  {
303  JLOG(journal.error())
304  << "Exception in " << __func__ << ": " << ex.what();
305  return std::nullopt;
306  }
307 }
308 
311 {
312  std::shared_lock lock{mutex_};
313  auto const iter = map_.find(pk);
314 
315  if (iter != map_.end() && !iter->second.revoked())
316  return iter->second.signingKey;
317 
318  return pk;
319 }
320 
321 PublicKey
323 {
324  std::shared_lock lock{mutex_};
325 
326  if (auto const iter = signingToMasterKeys_.find(pk);
327  iter != signingToMasterKeys_.end())
328  return iter->second;
329 
330  return pk;
331 }
332 
335 {
336  std::shared_lock lock{mutex_};
337  auto const iter = map_.find(pk);
338 
339  if (iter != map_.end() && !iter->second.revoked())
340  return iter->second.sequence;
341 
342  return std::nullopt;
343 }
344 
347 {
348  std::shared_lock lock{mutex_};
349  auto const iter = map_.find(pk);
350 
351  if (iter != map_.end() && !iter->second.revoked())
352  return iter->second.domain;
353 
354  return std::nullopt;
355 }
356 
359 {
360  std::shared_lock lock{mutex_};
361  auto const iter = map_.find(pk);
362 
363  if (iter != map_.end() && !iter->second.revoked())
364  return iter->second.serialized;
365 
366  return std::nullopt;
367 }
368 
369 bool
371 {
372  std::shared_lock lock{mutex_};
373  auto const iter = map_.find(pk);
374 
375  if (iter != map_.end())
376  return iter->second.revoked();
377 
378  return false;
379 }
380 
383 {
384  // Check the manifest against the conditions that do not require a
385  // `unique_lock` (write lock) on the `mutex_`. Since the signature can be
386  // relatively expensive, the `checkSignature` parameter determines if the
387  // signature should be checked. Since `prewriteCheck` is run twice (see
388  // comment below), `checkSignature` only needs to be set to true on the
389  // first run.
390  auto prewriteCheck =
391  [this, &m](auto const& iter, bool checkSignature, auto const& lock)
393  assert(lock.owns_lock());
394  (void)lock; // not used. parameter is present to ensure the mutex is
395  // locked when the lambda is called.
396  if (iter != map_.end() && m.sequence <= iter->second.sequence)
397  {
398  // We received a manifest whose sequence number is not strictly
399  // greater than the one we already know about. This can happen in
400  // several cases including when we receive manifests from a peer who
401  // doesn't have the latest data.
402  if (auto stream = j_.debug())
403  logMftAct(
404  stream,
405  "Stale",
406  m.masterKey,
407  m.sequence,
408  iter->second.sequence);
410  }
411 
412  if (checkSignature && !m.verify())
413  {
414  if (auto stream = j_.warn())
415  logMftAct(stream, "Invalid", m.masterKey, m.sequence);
417  }
418 
419  // If the master key associated with a manifest is or might be
420  // compromised and is, therefore, no longer trustworthy.
421  //
422  // A manifest revocation essentially marks a manifest as compromised. By
423  // setting the sequence number to the highest value possible, the
424  // manifest is effectively neutered and cannot be superseded by a forged
425  // one.
426  bool const revoked = m.revoked();
427 
428  if (auto stream = j_.warn(); stream && revoked)
429  logMftAct(stream, "Revoked", m.masterKey, m.sequence);
430 
431  // Sanity check: the master key of this manifest should not be used as
432  // the ephemeral key of another manifest:
433  if (auto const x = signingToMasterKeys_.find(m.masterKey);
434  x != signingToMasterKeys_.end())
435  {
436  JLOG(j_.warn()) << to_string(m)
437  << ": Master key already used as ephemeral key for "
438  << toBase58(TokenType::NodePublic, x->second);
439 
441  }
442 
443  if (!revoked)
444  {
445  if (!m.signingKey)
446  {
447  JLOG(j_.warn()) << to_string(m)
448  << ": is not revoked and the manifest has no "
449  "signing key. Hence, the manifest is "
450  "invalid";
452  }
453 
454  // Sanity check: the ephemeral key of this manifest should not be
455  // used as the master or ephemeral key of another manifest:
456  if (auto const x = signingToMasterKeys_.find(*m.signingKey);
457  x != signingToMasterKeys_.end())
458  {
459  JLOG(j_.warn())
460  << to_string(m)
461  << ": Ephemeral key already used as ephemeral key for "
462  << toBase58(TokenType::NodePublic, x->second);
463 
465  }
466 
467  if (auto const x = map_.find(*m.signingKey); x != map_.end())
468  {
469  JLOG(j_.warn())
470  << to_string(m) << ": Ephemeral key used as master key for "
471  << to_string(x->second);
472 
474  }
475  }
476 
477  return std::nullopt;
478  };
479 
480  {
482  if (auto d =
483  prewriteCheck(map_.find(m.masterKey), /*checkSig*/ true, sl))
484  return *d;
485  }
486 
488  auto const iter = map_.find(m.masterKey);
489  // Since we released the previously held read lock, it's possible that the
490  // collections have been written to. This means we need to run
491  // `prewriteCheck` again. This re-does work, but `prewriteCheck` is
492  // relatively inexpensive to run, and doing it this way allows us to run
493  // `prewriteCheck` under a `shared_lock` above.
494  // Note, the signature has already been checked above, so it
495  // doesn't need to happen again (signature checks are somewhat expensive).
496  // Note: It's a mistake to use an upgradable lock. This is a recipe for
497  // deadlock.
498  if (auto d = prewriteCheck(iter, /*checkSig*/ false, sl))
499  return *d;
500 
501  bool const revoked = m.revoked();
502  // This is the first manifest we are seeing for a master key. This should
503  // only ever happen once per validator run.
504  if (iter == map_.end())
505  {
506  if (auto stream = j_.info())
507  logMftAct(stream, "AcceptedNew", m.masterKey, m.sequence);
508 
509  if (!revoked)
511 
512  auto masterKey = m.masterKey;
513  map_.emplace(std::move(masterKey), std::move(m));
515  }
516 
517  // An ephemeral key was revoked and superseded by a new key. This is
518  // expected, but should happen infrequently.
519  if (auto stream = j_.info())
520  logMftAct(
521  stream,
522  "AcceptedUpdate",
523  m.masterKey,
524  m.sequence,
525  iter->second.sequence);
526 
527  signingToMasterKeys_.erase(*iter->second.signingKey);
528 
529  if (!revoked)
531 
532  iter->second = std::move(m);
533 
534  // Something has changed. Keep track of it.
535  seq_++;
536 
538 }
539 
540 void
542 {
543  auto db = dbCon.checkoutDb();
544  ripple::getManifests(*db, dbTable, *this, j_);
545 }
546 
547 bool
549  DatabaseCon& dbCon,
550  std::string const& dbTable,
551  std::string const& configManifest,
552  std::vector<std::string> const& configRevocation)
553 {
554  load(dbCon, dbTable);
555 
556  if (!configManifest.empty())
557  {
558  auto mo = deserializeManifest(base64_decode(configManifest));
559  if (!mo)
560  {
561  JLOG(j_.error()) << "Malformed validator_token in config";
562  return false;
563  }
564 
565  if (mo->revoked())
566  {
567  JLOG(j_.warn()) << "Configured manifest revokes public key";
568  }
569 
570  if (applyManifest(std::move(*mo)) == ManifestDisposition::invalid)
571  {
572  JLOG(j_.error()) << "Manifest in config was rejected";
573  return false;
574  }
575  }
576 
577  if (!configRevocation.empty())
578  {
579  std::string revocationStr;
580  revocationStr.reserve(std::accumulate(
581  configRevocation.cbegin(),
582  configRevocation.cend(),
583  std::size_t(0),
584  [](std::size_t init, std::string const& s) {
585  return init + s.size();
586  }));
587 
588  for (auto const& line : configRevocation)
589  revocationStr += boost::algorithm::trim_copy(line);
590 
591  auto mo = deserializeManifest(base64_decode(revocationStr));
592 
593  if (!mo || !mo->revoked() ||
594  applyManifest(std::move(*mo)) == ManifestDisposition::invalid)
595  {
596  JLOG(j_.error()) << "Invalid validator key revocation in config";
597  return false;
598  }
599  }
600 
601  return true;
602 }
603 
604 void
606  DatabaseCon& dbCon,
607  std::string const& dbTable,
608  std::function<bool(PublicKey const&)> const& isTrusted)
609 {
610  std::shared_lock lock{mutex_};
611  auto db = dbCon.checkoutDb();
612 
613  saveManifests(*db, dbTable, isTrusted, map_, j_);
614 }
615 } // namespace ripple
ripple::ManifestCache::mutex_
std::shared_mutex mutex_
Definition: Manifest.h:259
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:80
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:241
ripple::ManifestCache::getSigningKey
std::optional< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
Definition: app/misc/impl/Manifest.cpp:310
std::string
STL class.
ripple::ManifestDisposition
ManifestDisposition
Definition: Manifest.h:215
ripple::ManifestCache::getMasterKey
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Definition: app/misc/impl/Manifest.cpp:322
std::exception
STL class.
ripple::sfGeneric
const SField sfGeneric(access, 0)
Definition: SField.h:359
ripple::loadValidatorToken
std::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob, beast::Journal journal)
Definition: app/misc/impl/Manifest.cpp:263
ripple::Manifest
Definition: Manifest.h:80
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
std::string::reserve
T reserve(T... args)
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::HashPrefix::manifest
@ manifest
Manifest.
Json::Value::get
Value get(UInt index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
Definition: json_value.cpp:834
ripple::verify
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical) noexcept
Verify a signature on a message.
Definition: PublicKey.cpp:272
std::vector< unsigned char >
ripple::Manifest::serialized
std::string serialized
The manifest in serialized form.
Definition: Manifest.h:83
std::string::size
T size(T... args)
ripple::Manifest::masterKey
PublicKey masterKey
The master key associated with this manifest.
Definition: Manifest.h:86
ripple::Manifest::verify
bool verify() const
Returns true if manifest signature is valid.
Definition: app/misc/impl/Manifest.cpp:195
ripple::sfSigningPubKey
const SF_VL sfSigningPubKey
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:97
ripple::ValidatorToken
Definition: Manifest.h:204
std::optional::emplace
T emplace(T... args)
beast::Journal::warn
Stream warn() const
Definition: Journal.h:326
ripple::ManifestCache::map_
hash_map< PublicKey, Manifest > map_
Active manifests stored by master public key.
Definition: Manifest.h:262
ripple::soeREQUIRED
@ soeREQUIRED
Definition: SOTemplate.h:35
ripple::ManifestDisposition::badEphemeralKey
@ badEphemeralKey
The ephemeral key is not acceptable to us.
ripple::Manifest::revoked
static bool revoked(std::uint32_t sequence)
Returns true if manifest revokes master key.
Definition: app/misc/impl/Manifest.cpp:235
std::function
ripple::STObject::getFieldVL
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:611
Json::Reader
Unserialize a JSON document into a Value.
Definition: json_reader.h:36
ripple::Slice::empty
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:69
ripple::Manifest::revoked
bool revoked() const
Returns true if manifest revokes master key.
Definition: app/misc/impl/Manifest.cpp:225
ripple::ManifestCache::save
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted)
Save cached manifests to database.
Definition: app/misc/impl/Manifest.cpp:605
ripple::sfVersion
const SF_UINT16 sfVersion
ripple::publicKeyType
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
stdexcept
ripple::base_uint< 256 >
ripple::SOTemplate
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:84
ripple::DatabaseCon::checkoutDb
LockedSociSession checkoutDb()
Definition: DatabaseCon.h:178
ripple::ManifestCache::signingToMasterKeys_
hash_map< PublicKey, PublicKey > signingToMasterKeys_
Master public keys stored by current ephemeral public key.
Definition: Manifest.h:265
ripple::ManifestDisposition::badMasterKey
@ badMasterKey
The master key is not acceptable to us.
ripple::PublicKey
A public key.
Definition: PublicKey.h:61
ripple::sfMasterSignature
const SF_VL sfMasterSignature
ripple::getManifests
void getManifests(soci::session &session, std::string const &dbTable, ManifestCache &mCache, beast::Journal j)
getManifests Loads a manifest from the wallet database and stores it in the cache.
Definition: Wallet.cpp:42
ripple::soeOPTIONAL
@ soeOPTIONAL
Definition: SOTemplate.h:36
std::unique_lock
STL class.
ripple::Manifest::getSignature
std::optional< Blob > getSignature() const
Returns manifest signature.
Definition: app/misc/impl/Manifest.cpp:243
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:370
ripple::base64_decode
std::string base64_decode(std::string const &data)
Definition: base64.cpp:245
beast::Journal::error
Stream error() const
Definition: Journal.h:332
beast::Journal::info
Stream info() const
Definition: Journal.h:320
ripple::ManifestCache::j_
beast::Journal j_
Definition: Manifest.h:258
ripple::ManifestCache::seq_
std::atomic< std::uint32_t > seq_
Definition: Manifest.h:267
std::accumulate
T accumulate(T... args)
ripple::SerialIter
Definition: Serializer.h:311
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::Manifest::getMasterSignature
Blob getMasterSignature() const
Returns manifest master key signature.
Definition: app/misc/impl/Manifest.cpp:254
ripple::ManifestDisposition::invalid
@ invalid
Timely, but invalid signature.
ripple::ManifestCache::getSequence
std::optional< std::uint32_t > getSequence(PublicKey const &pk) const
Returns master key's current manifest sequence.
Definition: app/misc/impl/Manifest.cpp:334
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
ripple::Manifest::sequence
std::uint32_t sequence
The sequence number of this manifest.
Definition: Manifest.h:95
ripple::STObject
Definition: STObject.h:55
ripple::ManifestCache::getManifest
std::optional< std::string > getManifest(PublicKey const &pk) const
Returns mainfest corresponding to a given public key.
Definition: app/misc/impl/Manifest.cpp:358
ripple::ManifestCache::getDomain
std::optional< std::string > getDomain(PublicKey const &pk) const
Returns domain claimed by a given public key.
Definition: app/misc/impl/Manifest.cpp:346
ripple::ManifestDisposition::stale
@ stale
Sequence is too old.
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::vector::cbegin
T cbegin(T... args)
ripple::logMftAct
Stream & logMftAct(Stream &s, std::string const &action, PublicKey const &pk, std::uint32_t seq)
Definition: app/misc/impl/Manifest.cpp:167
Json::Reader::parse
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
Definition: json_reader.cpp:73
ripple::DatabaseCon
Definition: DatabaseCon.h:81
ripple::sfSignature
const SF_VL sfSignature
ripple::Manifest::hash
uint256 hash() const
Returns hash of serialized manifest data.
Definition: app/misc/impl/Manifest.cpp:216
std::string::empty
T empty(T... args)
std::string::assign
T assign(T... args)
ripple::TokenType::NodePublic
@ NodePublic
std::optional
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
std::size_t
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:38
ripple::isProperlyFormedTomlDomain
bool isProperlyFormedTomlDomain(std::string const &domain)
Determines if the given string looks like a TOML-file hosting domain.
std::vector::cend
T cend(T... args)
ripple::Manifest::signingKey
std::optional< PublicKey > signingKey
The ephemeral key associated with this manifest.
Definition: Manifest.h:92
ripple::deserializeManifest
std::optional< Manifest > deserializeManifest(Slice s, beast::Journal journal)
Constructs Manifest from serialized string.
Definition: app/misc/impl/Manifest.cpp:53
numeric
std::numeric_limits::max
T max(T... args)
ripple::ManifestCache::load
bool load(DatabaseCon &dbCon, std::string const &dbTable, std::string const &configManifest, std::vector< std::string > const &configRevocation)
Populate manifest cache with manifests in database and config.
Definition: app/misc/impl/Manifest.cpp:548
ripple::sfDomain
const SF_VL sfDomain
ripple::ManifestCache::applyManifest
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
Definition: app/misc/impl/Manifest.cpp:382
ripple::strUnHex
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Definition: StringUtilities.h:52
ripple::STObject::set
void set(const SOTemplate &)
Definition: STObject.cpp:116
ripple::saveManifests
void saveManifests(soci::session &session, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted, hash_map< PublicKey, Manifest > const &map, beast::Journal j)
saveManifests Saves all given manifests to the database.
Definition: Wallet.cpp:90
std::string::data
T data(T... args)
ripple::sfPublicKey
const SF_VL sfPublicKey
ripple::soeDEFAULT
@ soeDEFAULT
Definition: SOTemplate.h:37
std::shared_lock
STL class.
std::exception::what
T what(T... args)
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::get
T & get(EitherAmount &amt)
Definition: AmountSpec.h:118
ripple::STObject::getHash
uint256 getHash(HashPrefix prefix) const
Definition: STObject.cpp:355