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 <format>
30#include <functional>
31#include <limits>
32#include <mutex>
33#include <numeric>
34#include <optional>
35#include <shared_mutex>
36#include <stdexcept>
37#include <string>
38#include <utility>
39#include <vector>
40
41namespace xrpl {
42
43std::string
45{
46 auto const mk = toBase58(TokenType::NodePublic, m.masterKey);
47
48 if (m.revoked())
49 return "Revocation Manifest " + mk;
50
51 if (!m.signingKey)
52 Throw<std::runtime_error>(std::format("No SigningKey in manifest {}", mk));
53
54 return "Manifest " + mk + " (" + std::to_string(m.sequence) + ": " +
56}
57
60{
61 if (s.empty())
62 return std::nullopt;
63
64 // A valid manifest has a fixed maximum size, so reject anything larger
65 // before parsing it.
66 if (s.size() > kMaxManifestBytes)
67 return std::nullopt;
68
69 static SOTemplate const kManifestFormat{
70 // A manifest must include:
71 // - the master public key
72 {sfPublicKey, SoeRequired},
73
74 // - a signature with that public key
75 {sfMasterSignature, SoeRequired},
76
77 // - a sequence number
78 {sfSequence, SoeRequired},
79
80 // It may, optionally, contain:
81 // - a version number which defaults to 0
82 {sfVersion, SoeDefault},
83
84 // - a domain name
85 {sfDomain, SoeOptional},
86
87 // - an ephemeral signing key that can be changed as necessary
88 {sfSigningPubKey, SoeOptional},
89
90 // - a signature using the ephemeral signing key, if it is present
91 {sfSignature, SoeOptional},
92 };
93
94 try
95 {
96 SerialIter sit{s};
97 STObject st{sit, sfGeneric};
98
99 st.applyTemplate(kManifestFormat);
100
101 // We only understand "version 0" manifests at this time:
102 if (st.isFieldPresent(sfVersion) && st.getFieldU16(sfVersion) != 0)
103 return std::nullopt;
104
105 auto const pk = st.getFieldVL(sfPublicKey);
106
107 if (!publicKeyType(makeSlice(pk)))
108 return std::nullopt;
109
110 PublicKey const masterKey = PublicKey(makeSlice(pk));
111 std::uint32_t const seq = st.getFieldU32(sfSequence);
112
113 std::string domain;
114
115 std::optional<PublicKey> signingKey;
116
117 if (st.isFieldPresent(sfDomain))
118 {
119 auto const d = st.getFieldVL(sfDomain);
120
121 domain.assign(reinterpret_cast<char const*>(d.data()), d.size());
122
123 if (!isProperlyFormedTomlDomain(domain))
124 return std::nullopt;
125 }
126
127 bool const hasEphemeralKey = st.isFieldPresent(sfSigningPubKey);
128 bool const hasEphemeralSig = st.isFieldPresent(sfSignature);
129
130 if (Manifest::revoked(seq))
131 {
132 // Revocation manifests should not specify a new signing key
133 // or a signing key signature.
134 if (hasEphemeralKey)
135 return std::nullopt;
136
137 if (hasEphemeralSig)
138 return std::nullopt;
139 }
140 else
141 {
142 // Regular manifests should contain a signing key and an
143 // associated signature.
144 if (!hasEphemeralKey)
145 return std::nullopt;
146
147 if (!hasEphemeralSig)
148 return std::nullopt;
149
150 auto const spk = st.getFieldVL(sfSigningPubKey);
151
152 if (!publicKeyType(makeSlice(spk)))
153 return std::nullopt;
154
155 signingKey.emplace(makeSlice(spk));
156
157 // The signing and master keys can't be the same
158 if (*signingKey == masterKey)
159 return std::nullopt;
160 }
161
162 std::string const serialized(reinterpret_cast<char const*>(s.data()), s.size());
163
164 // If the manifest is revoked, then the signingKey will be unseated
165 return Manifest(serialized, masterKey, signingKey, seq, domain);
166 }
167 catch (std::exception const& ex)
168 {
169 JLOG(journal.error()) << "Exception in " << __func__ << ": " << ex.what();
170 return std::nullopt;
171 }
172}
173
174template <class Stream>
175Stream&
176logMftAct(Stream& s, std::string const& action, PublicKey const& pk, std::uint32_t seq)
177{
178 s << "Manifest: " << action << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
179 << ";";
180 return s;
181}
182
183template <class Stream>
184Stream&
186 Stream& s,
187 std::string const& action,
188 PublicKey const& pk,
189 std::uint32_t seq,
190 std::uint32_t oldSeq)
191{
192 s << "Manifest: " << action << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
193 << ";OldSeq: " << oldSeq << ";";
194 return s;
195}
196
197bool
199{
201 SerialIter sit(serialized.data(), serialized.size());
202 st.set(sit);
203
204 // The manifest must either have a signing key or be revoked. This check
205 // prevents us from accessing an unseated signingKey in the next check.
206 if (!revoked() && !signingKey)
207 return false;
208
209 // Signing key and signature are not required for
210 // master key revocations
212 return false;
213
214 return xrpl::verify(st, HashPrefix::Manifest, masterKey, sfMasterSignature);
215}
216
219{
221 SerialIter sit(serialized.data(), serialized.size());
222 st.set(sit);
223 return st.getHash(HashPrefix::Manifest);
224}
225
226bool
228{
229 /*
230 The maximum possible sequence number means that the master key
231 has been revoked.
232 */
233 return revoked(sequence);
234}
235
236bool
238{
239 // The maximum possible sequence number means that the master key has
240 // been revoked.
242}
243
246{
248 SerialIter sit(serialized.data(), serialized.size());
249 st.set(sit);
250 if (!get(st, sfSignature))
251 return std::nullopt;
252 return st.getFieldVL(sfSignature);
253}
254
255Blob
257{
259 SerialIter sit(serialized.data(), serialized.size());
260 st.set(sit);
261 return st.getFieldVL(sfMasterSignature);
262}
263
266{
267 try
268 {
269 std::string tokenStr;
270
271 tokenStr.reserve(
273 blob.cbegin(),
274 blob.cend(),
275 std::size_t(0),
276 [](std::size_t init, std::string const& s) { return init + s.size(); }));
277
278 for (auto const& line : blob)
279 tokenStr += trimWhitespace(line);
280
281 tokenStr = base64Decode(tokenStr);
282
283 json::Reader r;
284 json::Value token;
285
286 if (r.parse(tokenStr, token))
287 {
288 auto const m = token.get("manifest", json::Value{});
289 auto const k = token.get("validation_secret_key", json::Value{});
290
291 if (m.isString() && k.isString())
292 {
293 auto const key = strUnHex(k.asString());
294
295 if (key && key->size() == 32)
296 {
297 return ValidatorToken{
298 .manifest = m.asString(), .validationSecret = makeSlice(*key)};
299 }
300 }
301 }
302
303 return std::nullopt;
304 }
305 catch (std::exception const& ex)
306 {
307 JLOG(journal.error()) << "Exception in " << __func__ << ": " << ex.what();
308 return std::nullopt;
309 }
310}
311
314{
315 std::shared_lock const lock{mutex_};
316 auto const iter = map_.find(pk);
317
318 if (iter != map_.end() && !iter->second.revoked())
319 return iter->second.signingKey;
320
321 return pk;
322}
323
326{
327 std::shared_lock const lock{mutex_};
328
329 if (auto const iter = signingToMasterKeys_.find(pk); iter != signingToMasterKeys_.end())
330 return iter->second;
331
332 return pk;
333}
334
337{
338 std::shared_lock const lock{mutex_};
339 auto const iter = map_.find(pk);
340
341 if (iter != map_.end() && !iter->second.revoked())
342 return iter->second.sequence;
343
344 return std::nullopt;
345}
346
349{
350 std::shared_lock const lock{mutex_};
351 auto const iter = map_.find(pk);
352
353 if (iter != map_.end() && !iter->second.revoked())
354 return iter->second.domain;
355
356 return std::nullopt;
357}
358
361{
362 std::shared_lock const lock{mutex_};
363 auto const iter = map_.find(pk);
364
365 if (iter != map_.end() && !iter->second.revoked())
366 return iter->second.serialized;
367
368 return std::nullopt;
369}
370
371bool
373{
374 std::shared_lock const lock{mutex_};
375 auto const iter = map_.find(pk);
376
377 if (iter != map_.end())
378 return iter->second.revoked();
379
380 return false;
381}
382
385{
386 bool const uncapped = cap == ManifestRateLimitCapPolicy::Uncapped;
387
388 // The signature is checked only on the first `prewriteCheck` run (under the
389 // read lock). It is expensive, so `checkSignature` is cleared the first
390 // time it is read; the second run (under the write lock) skips it.
391 bool checkSignature = true;
392
393 // Check the manifest against the conditions that do not require a
394 // `unique_lock` (write lock) on the `mutex_`.
395 auto prewriteCheck = [this, &m, &checkSignature](
396 auto const& iter,
397 auto const& lock) -> std::optional<ManifestDisposition> {
398 XRPL_ASSERT(lock.owns_lock(), "xrpl::ManifestCache::applyManifest::prewriteCheck : locked");
399 (void)lock; // not used. parameter is present to ensure the mutex is
400 // locked when the lambda is called.
401 if (iter != map_.end() && m.sequence <= iter->second.sequence)
402 {
403 // We received a manifest whose sequence number is not strictly
404 // greater than the one we already know about. This can happen in
405 // several cases including when we receive manifests from a peer who
406 // doesn't have the latest data.
407 if (auto stream = j_.debug())
408 logMftAct(stream, "Stale", m.masterKey, m.sequence, iter->second.sequence);
410 }
411
412 if (checkSignature)
413 {
414 checkSignature = false;
415 if (!m.verify())
416 {
417 if (auto stream = j_.warn())
418 logMftAct(stream, "Invalid", m.masterKey, m.sequence);
420 }
421 }
422
423 // If the master key associated with a manifest is or might be
424 // compromised and is, therefore, no longer trustworthy.
425 //
426 // A manifest revocation essentially marks a manifest as compromised. By
427 // setting the sequence number to the highest value possible, the
428 // manifest is effectively neutered and cannot be superseded by a forged
429 // one.
430 bool const revoked = m.revoked();
431
432 if (auto stream = j_.warn(); stream && revoked)
433 logMftAct(stream, "Revoked", m.masterKey, m.sequence);
434
435 // Sanity check: the master key of this manifest should not be used as
436 // the ephemeral key of another manifest:
437 if (auto const x = signingToMasterKeys_.find(m.masterKey); x != signingToMasterKeys_.end())
438 {
439 JLOG(j_.warn()) << to_string(m) << ": Master key already used as ephemeral key for "
440 << toBase58(TokenType::NodePublic, x->second);
441
443 }
444
445 if (!revoked)
446 {
447 if (!m.signingKey)
448 {
449 JLOG(j_.warn()) << to_string(m)
450 << ": is not revoked and the manifest has no "
451 "signing key. Hence, the manifest is "
452 "invalid";
454 }
455
456 // Sanity check: the ephemeral key of this manifest should not be
457 // used as the master or ephemeral key of another manifest:
458 if (auto const x = signingToMasterKeys_.find(*m.signingKey);
459 x != signingToMasterKeys_.end())
460 {
461 JLOG(j_.warn()) << to_string(m)
462 << ": Ephemeral key already used as ephemeral key for "
463 << toBase58(TokenType::NodePublic, x->second);
464
466 }
467
468 if (auto const x = map_.find(*m.signingKey); x != map_.end())
469 {
470 JLOG(j_.warn()) << 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 // Reject a brand-new manifest for an unlisted key once the untrusted cap
481 // is full. Updates to a cached key and uncapped manifests always pass.
482 // Called under both the read and write lock, since the cap can be reached
483 // between the two. The lock param enforces that.
484 auto atUntrustedCap = [this, &m, uncapped](auto const& iter, auto const& lock) {
485 XRPL_ASSERT(
486 lock.owns_lock(), "xrpl::ManifestCache::applyManifest::atUntrustedCap : locked");
487 (void)lock; // not used. parameter is present to ensure the mutex is
488 // locked when the lambda is called.
489 if (iter == map_.end() && !uncapped && untrustedKeys_.size() >= maxUntrustedCount_)
490 {
491 // Log each rejection at debug, but warn only once per interval so a
492 // flood does not fill the log.
493 if (auto stream = j_.debug())
494 logMftAct(stream, "UntrustedCapacity", m.masterKey, m.sequence);
495 if (auto const n = untrustedRejectCount_.fetch_add(1) + 1;
496 n % kUntrustedRejectCount == 0)
497 {
498 JLOG(j_.warn()) << "Untrusted manifest cap reached; " << n
499 << " manifests rejected so far";
500 }
501 return true;
502 }
503 return false;
504 };
505
506 {
507 std::shared_lock const sl{mutex_};
508 auto const iter = map_.find(m.masterKey);
509
510 if (atUntrustedCap(iter, sl))
512
513 if (auto d = prewriteCheck(iter, sl); d.has_value())
514 return *d;
515 }
516
517 std::unique_lock const sl{mutex_};
518 auto const iter = map_.find(m.masterKey);
519
520 // Re-check the cap under the write lock: the cache may have grown while the
521 // read lock above was released.
522 if (atUntrustedCap(iter, sl))
524
525 // Since we released the previously held read lock, it's possible that the
526 // collections have been written to. This means we need to run
527 // `prewriteCheck` again. This re-does work, but `prewriteCheck` is
528 // relatively inexpensive to run, and doing it this way allows us to run
529 // `prewriteCheck` under a `shared_lock` above.
530 // Note, the signature has already been checked above, so it
531 // doesn't need to happen again (signature checks are somewhat expensive).
532 // Note: It's a mistake to use an upgradable lock. This is a recipe for
533 // deadlock.
534 if (auto d = prewriteCheck(iter, sl); d.has_value())
535 return *d;
536
537 bool const revoked = m.revoked();
538 // This is the first manifest we are seeing for a master key. This should
539 // only ever happen once per validator run.
540 if (iter == map_.end())
541 {
542 if (auto stream = j_.info())
543 logMftAct(stream, "AcceptedNew", m.masterKey, m.sequence);
544
545 if (!revoked)
546 {
547 signingToMasterKeys_.emplace(
548 *m.signingKey, m.masterKey); // NOLINT(bugprone-unchecked-optional-access)
549 // non-revoked manifest always has signingKey
550 }
551
552 auto masterKey = m.masterKey;
553
554 // Count this key against the untrusted cap. Uncapped keys (listed,
555 // configured, or DB-loaded) are not tracked.
556 if (!uncapped)
557 untrustedKeys_.insert(masterKey);
558
559 map_.emplace(std::move(masterKey), std::move(m));
560
561 // Something has changed. Keep track of it.
562 seq_++;
563
565 }
566
567 // An ephemeral key was revoked and superseded by a new key. This is
568 // expected, but should happen infrequently.
569 if (auto stream = j_.info())
570 logMftAct(stream, "AcceptedUpdate", m.masterKey, m.sequence, iter->second.sequence);
571
572 // If this key was counted against the cap but now arrives uncapped, free
573 // its slot without waiting for promoteToTrusted.
574 if (uncapped)
575 untrustedKeys_.erase(m.masterKey);
576
578 *iter->second.signingKey); // NOLINT(bugprone-unchecked-optional-access) prewriteCheck
579 // ensures old manifest is not revoked
580
581 if (!revoked)
582 {
583 signingToMasterKeys_.emplace(
584 *m.signingKey, m.masterKey); // NOLINT(bugprone-unchecked-optional-access)
585 // non-revoked manifest always has signingKey
586 }
587
588 iter->second = std::move(m);
589
590 // Something has changed. Keep track of it.
591 seq_++;
592
594}
595
596void
598{
599 // Frees the key's untrusted slot; a no-op (and idempotent) if the key was
600 // never counted. Not re-added on de-listing, so list/de-list cannot grow
601 // the count.
602 std::unique_lock const sl{mutex_};
603 untrustedKeys_.erase(pk);
604}
605
606void
608{
609 auto db = dbCon.checkoutDb();
610 xrpl::getManifests(*db, dbTable, *this, j_);
611}
612
613bool
615 DatabaseCon& dbCon,
616 std::string const& dbTable,
617 std::string const& configManifest,
618 std::vector<std::string> const& configRevocation)
619{
620 load(dbCon, dbTable);
621
622 if (!configManifest.empty())
623 {
624 auto mo = deserializeManifest(base64Decode(configManifest));
625 if (!mo)
626 {
627 JLOG(j_.error()) << "Malformed validator_token in config";
628 return false;
629 }
630
631 if (mo->revoked())
632 {
633 JLOG(j_.warn()) << "Configured manifest revokes public key";
634 }
635
638 {
639 JLOG(j_.error()) << "Manifest in config was rejected";
640 return false;
641 }
642 }
643
644 if (!configRevocation.empty())
645 {
646 std::string revocationStr;
647 revocationStr.reserve(
649 configRevocation.cbegin(),
650 configRevocation.cend(),
651 std::size_t(0),
652 [](std::size_t init, std::string const& s) { return init + s.size(); }));
653
654 for (auto const& line : configRevocation)
655 revocationStr += trimWhitespace(line);
656
657 auto mo = deserializeManifest(base64Decode(revocationStr));
658
659 if (!mo || !mo->revoked() ||
662 {
663 JLOG(j_.error()) << "Invalid validator key revocation in config";
664 return false;
665 }
666 }
667
668 return true;
669}
670
671void
673 DatabaseCon& dbCon,
674 std::string const& dbTable,
675 std::function<bool(PublicKey const&)> const& isTrusted)
676{
677 std::shared_lock const lock{mutex_};
678 auto db = dbCon.checkoutDb();
679
680 saveManifests(*db, dbTable, isTrusted, map_, j_);
681}
682} // 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()
HashMap< PublicKey, Manifest > map_
Active manifests stored by master public key.
Definition Manifest.h:382
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.
HashMap< PublicKey, PublicKey > signingToMasterKeys_
Master public keys stored by current ephemeral public key.
Definition Manifest.h:387
std::optional< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
HashSet< PublicKey > untrustedKeys_
Master keys of cached manifests for validators this node does not list.
Definition Manifest.h:399
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
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.
std::optional< std::string > getManifest(PublicKey const &pk) const
Returns manifest corresponding to a given public key.
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
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
void set(SOTemplate const &)
Definition STObject.cpp:138
UInt256 getHash(HashPrefix prefix) const
Definition STObject.cpp:375
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 format(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, HashMap< 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:657
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
BaseUInt< 256 > UInt256
Definition base_uint.h:580
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
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.
UInt256 hash() const
Returns hash of serialized manifest data.
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.
bool verify() const
Returns true if manifest signature is valid.
T to_string(T... args)
T what(T... args)