xrpld
Loading...
Searching...
No Matches
libxrpl/server/Manifest.cpp
1#include <xrpl/server/Manifest.h>
2
3#include <xrpl/basics/Blob.h>
4#include <xrpl/basics/Log.h>
5#include <xrpl/basics/Slice.h>
6#include <xrpl/basics/StringUtilities.h>
7#include <xrpl/basics/base64.h>
8#include <xrpl/basics/base_uint.h>
9#include <xrpl/basics/contract.h>
10#include <xrpl/beast/utility/Journal.h>
11#include <xrpl/beast/utility/instrumentation.h>
12#include <xrpl/json/json_reader.h>
13#include <xrpl/json/json_value.h>
14#include <xrpl/protocol/HashPrefix.h>
15#include <xrpl/protocol/PublicKey.h>
16#include <xrpl/protocol/SField.h>
17#include <xrpl/protocol/SOTemplate.h>
18#include <xrpl/protocol/STExchange.h>
19#include <xrpl/protocol/STObject.h>
20#include <xrpl/protocol/Serializer.h>
21#include <xrpl/protocol/Sign.h>
22#include <xrpl/protocol/tokens.h>
23#include <xrpl/rdb/DatabaseCon.h>
24#include <xrpl/server/Wallet.h>
25
26#include <cstddef>
27#include <cstdint>
28#include <exception>
29#include <functional>
30#include <limits>
31#include <mutex>
32#include <numeric>
33#include <optional>
34#include <shared_mutex>
35#include <stdexcept>
36#include <string>
37#include <utility>
38#include <vector>
39
40namespace xrpl {
41
42std::string
44{
45 auto const mk = toBase58(TokenType::NodePublic, m.masterKey);
46
47 if (m.revoked())
48 return "Revocation Manifest " + mk;
49
50 if (!m.signingKey)
51 Throw<std::runtime_error>("No SigningKey in manifest " + mk);
52
53 return "Manifest " + mk + " (" + std::to_string(m.sequence) + ": " +
55}
56
59{
60 if (s.empty())
61 return std::nullopt;
62
63 // A valid manifest has a fixed maximum size, so reject anything larger
64 // before parsing it.
65 if (s.size() > kMaxManifestBytes)
66 return std::nullopt;
67
68 static SOTemplate const kManifestFormat{
69 // A manifest must include:
70 // - the master public key
71 {sfPublicKey, SoeRequired},
72
73 // - a signature with that public key
74 {sfMasterSignature, SoeRequired},
75
76 // - a sequence number
77 {sfSequence, SoeRequired},
78
79 // It may, optionally, contain:
80 // - a version number which defaults to 0
81 {sfVersion, SoeDefault},
82
83 // - a domain name
84 {sfDomain, SoeOptional},
85
86 // - an ephemeral signing key that can be changed as necessary
87 {sfSigningPubKey, SoeOptional},
88
89 // - a signature using the ephemeral signing key, if it is present
90 {sfSignature, SoeOptional},
91 };
92
93 try
94 {
95 SerialIter sit{s};
96 STObject st{sit, sfGeneric};
97
98 st.applyTemplate(kManifestFormat);
99
100 // We only understand "version 0" manifests at this time:
101 if (st.isFieldPresent(sfVersion) && st.getFieldU16(sfVersion) != 0)
102 return std::nullopt;
103
104 auto const pk = st.getFieldVL(sfPublicKey);
105
106 if (!publicKeyType(makeSlice(pk)))
107 return std::nullopt;
108
109 PublicKey const masterKey = PublicKey(makeSlice(pk));
110 std::uint32_t const seq = st.getFieldU32(sfSequence);
111
112 std::string domain;
113
114 std::optional<PublicKey> signingKey;
115
116 if (st.isFieldPresent(sfDomain))
117 {
118 auto const d = st.getFieldVL(sfDomain);
119
120 domain.assign(reinterpret_cast<char const*>(d.data()), d.size());
121
122 if (!isProperlyFormedTomlDomain(domain))
123 return std::nullopt;
124 }
125
126 bool const hasEphemeralKey = st.isFieldPresent(sfSigningPubKey);
127 bool const hasEphemeralSig = st.isFieldPresent(sfSignature);
128
129 if (Manifest::revoked(seq))
130 {
131 // Revocation manifests should not specify a new signing key
132 // or a signing key signature.
133 if (hasEphemeralKey)
134 return std::nullopt;
135
136 if (hasEphemeralSig)
137 return std::nullopt;
138 }
139 else
140 {
141 // Regular manifests should contain a signing key and an
142 // associated signature.
143 if (!hasEphemeralKey)
144 return std::nullopt;
145
146 if (!hasEphemeralSig)
147 return std::nullopt;
148
149 auto const spk = st.getFieldVL(sfSigningPubKey);
150
151 if (!publicKeyType(makeSlice(spk)))
152 return std::nullopt;
153
154 signingKey.emplace(makeSlice(spk));
155
156 // The signing and master keys can't be the same
157 if (*signingKey == masterKey)
158 return std::nullopt;
159 }
160
161 std::string const serialized(reinterpret_cast<char const*>(s.data()), s.size());
162
163 // If the manifest is revoked, then the signingKey will be unseated
164 return Manifest(serialized, masterKey, signingKey, seq, domain);
165 }
166 catch (std::exception const& ex)
167 {
168 JLOG(journal.error()) << "Exception in " << __func__ << ": " << ex.what();
169 return std::nullopt;
170 }
171}
172
173template <class Stream>
174Stream&
175logMftAct(Stream& s, std::string const& action, PublicKey const& pk, std::uint32_t seq)
176{
177 s << "Manifest: " << action << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
178 << ";";
179 return s;
180}
181
182template <class Stream>
183Stream&
185 Stream& s,
186 std::string const& action,
187 PublicKey const& pk,
188 std::uint32_t seq,
189 std::uint32_t oldSeq)
190{
191 s << "Manifest: " << action << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
192 << ";OldSeq: " << oldSeq << ";";
193 return s;
194}
195
196bool
198{
200 SerialIter sit(serialized.data(), serialized.size());
201 st.set(sit);
202
203 // The manifest must either have a signing key or be revoked. This check
204 // prevents us from accessing an unseated signingKey in the next check.
205 if (!revoked() && !signingKey)
206 return false;
207
208 // Signing key and signature are not required for
209 // master key revocations
211 return false;
212
213 return xrpl::verify(st, HashPrefix::Manifest, masterKey, sfMasterSignature);
214}
215
218{
220 SerialIter sit(serialized.data(), serialized.size());
221 st.set(sit);
222 return st.getHash(HashPrefix::Manifest);
223}
224
225bool
227{
228 /*
229 The maximum possible sequence number means that the master key
230 has been revoked.
231 */
232 return revoked(sequence);
233}
234
235bool
237{
238 // The maximum possible sequence number means that the master key has
239 // been revoked.
241}
242
245{
247 SerialIter sit(serialized.data(), serialized.size());
248 st.set(sit);
249 if (!get(st, sfSignature))
250 return std::nullopt;
251 return st.getFieldVL(sfSignature);
252}
253
254Blob
256{
258 SerialIter sit(serialized.data(), serialized.size());
259 st.set(sit);
260 return st.getFieldVL(sfMasterSignature);
261}
262
265{
266 try
267 {
268 std::string tokenStr;
269
270 tokenStr.reserve(
272 blob.cbegin(),
273 blob.cend(),
274 std::size_t(0),
275 [](std::size_t init, std::string const& s) { return init + s.size(); }));
276
277 for (auto const& line : blob)
278 tokenStr += trimWhitespace(line);
279
280 tokenStr = base64Decode(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 {
296 return ValidatorToken{
297 .manifest = m.asString(), .validationSecret = makeSlice(*key)};
298 }
299 }
300 }
301
302 return std::nullopt;
303 }
304 catch (std::exception const& ex)
305 {
306 JLOG(journal.error()) << "Exception in " << __func__ << ": " << ex.what();
307 return std::nullopt;
308 }
309}
310
313{
314 std::shared_lock const lock{mutex_};
315 auto const iter = map_.find(pk);
316
317 if (iter != map_.end() && !iter->second.revoked())
318 return iter->second.signingKey;
319
320 return pk;
321}
322
325{
326 std::shared_lock const lock{mutex_};
327
328 if (auto const iter = signingToMasterKeys_.find(pk); iter != signingToMasterKeys_.end())
329 return iter->second;
330
331 return pk;
332}
333
336{
337 std::shared_lock const lock{mutex_};
338 auto const iter = map_.find(pk);
339
340 if (iter != map_.end() && !iter->second.revoked())
341 return iter->second.sequence;
342
343 return std::nullopt;
344}
345
348{
349 std::shared_lock const lock{mutex_};
350 auto const iter = map_.find(pk);
351
352 if (iter != map_.end() && !iter->second.revoked())
353 return iter->second.domain;
354
355 return std::nullopt;
356}
357
360{
361 std::shared_lock const lock{mutex_};
362 auto const iter = map_.find(pk);
363
364 if (iter != map_.end() && !iter->second.revoked())
365 return iter->second.serialized;
366
367 return std::nullopt;
368}
369
370bool
372{
373 std::shared_lock const lock{mutex_};
374 auto const iter = map_.find(pk);
375
376 if (iter != map_.end())
377 return iter->second.revoked();
378
379 return false;
380}
381
384{
385 bool const uncapped = cap == ManifestRateLimitCapPolicy::Uncapped;
386
387 // The signature is checked only on the first `prewriteCheck` run (under the
388 // read lock). It is expensive, so `checkSignature` is cleared the first
389 // time it is read; the second run (under the write lock) skips it.
390 bool checkSignature = true;
391
392 // Check the manifest against the conditions that do not require a
393 // `unique_lock` (write lock) on the `mutex_`.
394 auto prewriteCheck = [this, &m, &checkSignature](
395 auto const& iter,
396 auto const& lock) -> std::optional<ManifestDisposition> {
397 XRPL_ASSERT(lock.owns_lock(), "xrpl::ManifestCache::applyManifest::prewriteCheck : locked");
398 (void)lock; // not used. parameter is present to ensure the mutex is
399 // locked when the lambda is called.
400 if (iter != map_.end() && m.sequence <= iter->second.sequence)
401 {
402 // We received a manifest whose sequence number is not strictly
403 // greater than the one we already know about. This can happen in
404 // several cases including when we receive manifests from a peer who
405 // doesn't have the latest data.
406 if (auto stream = j_.debug())
407 logMftAct(stream, "Stale", m.masterKey, m.sequence, iter->second.sequence);
409 }
410
411 if (checkSignature)
412 {
413 checkSignature = false;
414 if (!m.verify())
415 {
416 if (auto stream = j_.warn())
417 logMftAct(stream, "Invalid", m.masterKey, m.sequence);
419 }
420 }
421
422 // If the master key associated with a manifest is or might be
423 // compromised and is, therefore, no longer trustworthy.
424 //
425 // A manifest revocation essentially marks a manifest as compromised. By
426 // setting the sequence number to the highest value possible, the
427 // manifest is effectively neutered and cannot be superseded by a forged
428 // one.
429 bool const revoked = m.revoked();
430
431 if (auto stream = j_.warn(); stream && revoked)
432 logMftAct(stream, "Revoked", m.masterKey, m.sequence);
433
434 // Sanity check: the master key of this manifest should not be used as
435 // the ephemeral key of another manifest:
436 if (auto const x = signingToMasterKeys_.find(m.masterKey); x != signingToMasterKeys_.end())
437 {
438 JLOG(j_.warn()) << to_string(m) << ": Master key already used as ephemeral key for "
439 << toBase58(TokenType::NodePublic, x->second);
440
442 }
443
444 if (!revoked)
445 {
446 if (!m.signingKey)
447 {
448 JLOG(j_.warn()) << to_string(m)
449 << ": is not revoked and the manifest has no "
450 "signing key. Hence, the manifest is "
451 "invalid";
453 }
454
455 // Sanity check: the ephemeral key of this manifest should not be
456 // used as the master or ephemeral key of another manifest:
457 if (auto const x = signingToMasterKeys_.find(*m.signingKey);
458 x != signingToMasterKeys_.end())
459 {
460 JLOG(j_.warn()) << 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()) << to_string(m) << ": Ephemeral key used as master key for "
470 << to_string(x->second);
471
473 }
474 }
475
476 return std::nullopt;
477 };
478
479 // Reject a brand-new manifest for an unlisted key once the untrusted cap
480 // is full. Updates to a cached key and uncapped manifests always pass.
481 // Called under both the read and write lock, since the cap can be reached
482 // between the two. The lock param enforces that.
483 auto atUntrustedCap = [this, &m, uncapped](auto const& iter, auto const& lock) {
484 XRPL_ASSERT(
485 lock.owns_lock(), "xrpl::ManifestCache::applyManifest::atUntrustedCap : locked");
486 (void)lock; // not used. parameter is present to ensure the mutex is
487 // locked when the lambda is called.
488 if (iter == map_.end() && !uncapped && untrustedKeys_.size() >= maxUntrustedCount_)
489 {
490 // Log each rejection at debug, but warn only once per interval so a
491 // flood does not fill the log.
492 if (auto stream = j_.debug())
493 logMftAct(stream, "UntrustedCapacity", m.masterKey, m.sequence);
494 if (auto const n = untrustedRejectCount_.fetch_add(1) + 1;
495 n % kUntrustedRejectCount == 0)
496 {
497 JLOG(j_.warn()) << "Untrusted manifest cap reached; " << n
498 << " manifests rejected so far";
499 }
500 return true;
501 }
502 return false;
503 };
504
505 {
506 std::shared_lock const sl{mutex_};
507 auto const iter = map_.find(m.masterKey);
508
509 if (atUntrustedCap(iter, sl))
511
512 if (auto d = prewriteCheck(iter, sl); d.has_value())
513 return *d;
514 }
515
516 std::unique_lock const sl{mutex_};
517 auto const iter = map_.find(m.masterKey);
518
519 // Re-check the cap under the write lock: the cache may have grown while the
520 // read lock above was released.
521 if (atUntrustedCap(iter, sl))
523
524 // Since we released the previously held read lock, it's possible that the
525 // collections have been written to. This means we need to run
526 // `prewriteCheck` again. This re-does work, but `prewriteCheck` is
527 // relatively inexpensive to run, and doing it this way allows us to run
528 // `prewriteCheck` under a `shared_lock` above.
529 // Note, the signature has already been checked above, so it
530 // doesn't need to happen again (signature checks are somewhat expensive).
531 // Note: It's a mistake to use an upgradable lock. This is a recipe for
532 // deadlock.
533 if (auto d = prewriteCheck(iter, sl); d.has_value())
534 return *d;
535
536 bool const revoked = m.revoked();
537 // This is the first manifest we are seeing for a master key. This should
538 // only ever happen once per validator run.
539 if (iter == map_.end())
540 {
541 if (auto stream = j_.info())
542 logMftAct(stream, "AcceptedNew", m.masterKey, m.sequence);
543
544 if (!revoked)
545 {
546 signingToMasterKeys_.emplace(
547 *m.signingKey, m.masterKey); // NOLINT(bugprone-unchecked-optional-access)
548 // non-revoked manifest always has signingKey
549 }
550
551 auto masterKey = m.masterKey;
552
553 // Count this key against the untrusted cap. Uncapped keys (listed,
554 // configured, or DB-loaded) are not tracked.
555 if (!uncapped)
556 untrustedKeys_.insert(masterKey);
557
558 map_.emplace(std::move(masterKey), std::move(m));
559
560 // Something has changed. Keep track of it.
561 seq_++;
562
564 }
565
566 // An ephemeral key was revoked and superseded by a new key. This is
567 // expected, but should happen infrequently.
568 if (auto stream = j_.info())
569 logMftAct(stream, "AcceptedUpdate", m.masterKey, m.sequence, iter->second.sequence);
570
571 // If this key was counted against the cap but now arrives uncapped, free
572 // its slot without waiting for promoteToTrusted.
573 if (uncapped)
574 untrustedKeys_.erase(m.masterKey);
575
577 *iter->second.signingKey); // NOLINT(bugprone-unchecked-optional-access) prewriteCheck
578 // ensures old manifest is not revoked
579
580 if (!revoked)
581 {
582 signingToMasterKeys_.emplace(
583 *m.signingKey, m.masterKey); // NOLINT(bugprone-unchecked-optional-access)
584 // non-revoked manifest always has signingKey
585 }
586
587 iter->second = std::move(m);
588
589 // Something has changed. Keep track of it.
590 seq_++;
591
593}
594
595void
597{
598 // Frees the key's untrusted slot; a no-op (and idempotent) if the key was
599 // never counted. Not re-added on de-listing, so list/de-list cannot grow
600 // the count.
601 std::unique_lock const sl{mutex_};
602 untrustedKeys_.erase(pk);
603}
604
605void
607{
608 auto db = dbCon.checkoutDb();
609 xrpl::getManifests(*db, dbTable, *this, j_);
610}
611
612bool
614 DatabaseCon& dbCon,
615 std::string const& dbTable,
616 std::string const& configManifest,
617 std::vector<std::string> const& configRevocation)
618{
619 load(dbCon, dbTable);
620
621 if (!configManifest.empty())
622 {
623 auto mo = deserializeManifest(base64Decode(configManifest));
624 if (!mo)
625 {
626 JLOG(j_.error()) << "Malformed validator_token in config";
627 return false;
628 }
629
630 if (mo->revoked())
631 {
632 JLOG(j_.warn()) << "Configured manifest revokes public key";
633 }
634
637 {
638 JLOG(j_.error()) << "Manifest in config was rejected";
639 return false;
640 }
641 }
642
643 if (!configRevocation.empty())
644 {
645 std::string revocationStr;
646 revocationStr.reserve(
648 configRevocation.cbegin(),
649 configRevocation.cend(),
650 std::size_t(0),
651 [](std::size_t init, std::string const& s) { return init + s.size(); }));
652
653 for (auto const& line : configRevocation)
654 revocationStr += trimWhitespace(line);
655
656 auto mo = deserializeManifest(base64Decode(revocationStr));
657
658 if (!mo || !mo->revoked() ||
661 {
662 JLOG(j_.error()) << "Invalid validator key revocation in config";
663 return false;
664 }
665 }
666
667 return true;
668}
669
670void
672 DatabaseCon& dbCon,
673 std::string const& dbTable,
674 std::function<bool(PublicKey const&)> const& isTrusted)
675{
676 std::shared_lock const lock{mutex_};
677 auto db = dbCon.checkoutDb();
678
679 saveManifests(*db, dbTable, isTrusted, map_, j_);
680}
681} // namespace xrpl
T accumulate(T... args)
T assign(T... args)
T cbegin(T... args)
A generic endpoint for log messages.
Definition Journal.h:44
Stream error() const
Definition Journal.h:362
Unserialize a JSON document into a Value.
Definition json_reader.h:20
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
Represents a JSON value.
Definition json_value.h:117
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
LockedSociSession checkoutDb()
std::size_t const maxUntrustedCount_
Maximum number of untrusted master keys kept in the cache.
Definition Manifest.h:407
std::atomic< std::uint32_t > seq_
Definition Manifest.h:389
std::shared_mutex mutex_
Definition Manifest.h:377
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.
std::optional< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
ManifestDisposition applyManifest(Manifest m, ManifestRateLimitCapPolicy cap)
Add manifest to cache.
static constexpr std::uint64_t kUntrustedRejectCount
Number of cap rejections between summary warnings.
Definition Manifest.h:422
hash_set< PublicKey > untrustedKeys_
Master keys of cached manifests for validators this node does not list.
Definition Manifest.h:399
std::optional< std::string > getDomain(PublicKey const &pk) const
Returns domain claimed by a given public key.
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
hash_map< PublicKey, PublicKey > signingToMasterKeys_
Master public keys stored by current ephemeral public key.
Definition Manifest.h:387
std::optional< std::string > getManifest(PublicKey const &pk) const
Returns manifest corresponding to a given public key.
hash_map< PublicKey, Manifest > map_
Active manifests stored by master public key.
Definition Manifest.h:382
std::optional< std::uint32_t > getSequence(PublicKey const &pk) const
Returns master key's current manifest sequence.
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted)
Save cached manifests to database.
std::atomic< std::uint64_t > untrustedRejectCount_
Running count of manifests rejected because the untrusted cap was full.
Definition Manifest.h:415
beast::Journal j_
Definition Manifest.h:376
void promoteToTrusted(PublicKey const &pk)
Stop counting a master key against the untrusted cap.
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
A public key.
Definition PublicKey.h:53
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:105
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:649
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:601
void applyTemplate(SOTemplate const &type)
Definition STObject.cpp:158
uint256 getHash(HashPrefix prefix) const
Definition STObject.cpp:375
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
void set(SOTemplate const &)
Definition STObject.cpp:138
std::uint16_t getFieldU16(SField const &field) const
Definition STObject.cpp:595
An immutable linear range of bytes.
Definition Slice.h:28
bool empty() const noexcept
Return true if the byte range is empty.
Definition Slice.h:58
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:88
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:70
T emplace(T... args)
T empty(T... args)
T cend(T... args)
T max(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
Stream & logMftAct(Stream &s, std::string const &action, PublicKey const &pk, std::uint32_t seq)
std::string base64Decode(std::string_view data)
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:104
bool isProperlyFormedTomlDomain(std::string_view domain)
Determines if the given string looks like a TOML-file hosting domain.
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
@ SoeDefault
Definition SOTemplate.h:24
@ SoeOptional
Definition SOTemplate.h:23
@ SoeRequired
Definition SOTemplate.h:22
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
SField const sfGeneric
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
constexpr std::size_t kMaxManifestBytes
Largest a valid manifest can be, in decoded bytes.
Definition Manifest.h:191
std::string trimWhitespace(std::string str)
Remove leading and trailing ASCII whitespace.
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
std::optional< Manifest > deserializeManifest(Slice s, beast::Journal journal)
Constructs Manifest from serialized string.
ManifestRateLimitCapPolicy
Whether a manifest counts against the 'untrusted' cache cap.
Definition Manifest.h:363
@ Uncapped
Bypasses the cap (listed/trusted or config manifests).
Definition Manifest.h:365
Slice makeSlice(std::array< T, N > const &a)
Definition Slice.h:228
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
@ Manifest
Manifest.
Definition HashPrefix.h:84
void getManifests(soci::session &session, std::string const &dbTable, ManifestCache &cache, beast::Journal j)
getManifests Loads a manifest from the wallet database and stores it in the cache.
Definition Wallet.cpp:58
std::vector< unsigned char > Blob
Storage for linear binary data.
Definition Blob.h:11
BaseUInt< 256 > uint256
Definition base_uint.h:580
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
std::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob, beast::Journal journal=beast::Journal(beast::Journal::getNullSink()))
ManifestDisposition
Definition Manifest.h:320
@ BadMasterKey
The master key is not acceptable to us.
Definition Manifest.h:325
@ Accepted
Manifest is valid.
Definition Manifest.h:321
@ Invalid
Timely, but invalid signature.
Definition Manifest.h:329
@ BadEphemeralKey
The ephemeral key is not acceptable to us.
Definition Manifest.h:327
@ Stale
Sequence is too old.
Definition Manifest.h:323
@ UntrustedCapacity
Unlisted and limit reached.
Definition Manifest.h:331
T reserve(T... args)
static bool revoked(std::uint32_t sequence)
Returns true if manifest revokes master key.
PublicKey masterKey
The master key associated with this manifest.
Definition Manifest.h:84
std::string serialized
The manifest in serialized form.
Definition Manifest.h:79
Blob getMasterSignature() const
Returns manifest master key signature.
std::optional< Blob > getSignature() const
Returns manifest signature.
std::optional< PublicKey > signingKey
The ephemeral key associated with this manifest.
Definition Manifest.h:92
std::uint32_t sequence
The sequence number of this manifest.
Definition Manifest.h:97
bool revoked() const
Returns true if manifest revokes master key.
uint256 hash() const
Returns hash of serialized manifest data.
bool verify() const
Returns true if manifest signature is valid.
T to_string(T... args)
T what(T... args)