xrpld
Loading...
Searching...
No Matches
STPathSet.h
1#pragma once
2
3#include <xrpl/basics/CountedObject.h>
4#include <xrpl/basics/UnorderedContainers.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/json/json_value.h>
7#include <xrpl/protocol/AccountID.h>
8#include <xrpl/protocol/PathAsset.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STBase.h>
11#include <xrpl/protocol/Serializer.h>
12#include <xrpl/protocol/UintTypes.h>
13
14#include <cstddef>
15#include <cstdint>
16#include <memory>
17#include <optional>
18#include <utility>
19#include <vector>
20
21namespace xrpl {
22
23class STPathElement final : public CountedObject<STPathElement>
24{
25 unsigned int type_;
29
32
33public:
34 // Bitwise values (typeCurrency | typeMPT)
35 // NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
36 enum Type {
37 TypeNone = 0x00,
38 TypeAccount = 0x01, // Rippling through an account (vs taking an offer).
39 TypeCurrency = 0x10, // Currency follows.
40 TypeIssuer = 0x20, // Issuer follows.
41 TypeMpt = 0x40, // MPT follows.
42 TypeBoundary = 0xFF, // Boundary between alternate paths.
45 // Combination of all types.
46 };
47
49 STPathElement(STPathElement const&) = default;
51 operator=(STPathElement const&) = default;
52
54 std::optional<AccountID> const& account,
55 std::optional<PathAsset> const& asset,
56 std::optional<AccountID> const& issuer);
57
59 AccountID const& account,
60 PathAsset const& asset,
61 AccountID const& issuer,
62 bool forceAsset = false);
63
65 unsigned int uType,
66 AccountID const& account,
67 PathAsset const& asset,
68 AccountID const& issuer);
69
70 [[nodiscard]] std::uint32_t
71 getNodeType() const;
72
73 [[nodiscard]] bool
74 isOffer() const;
75
76 [[nodiscard]] bool
77 isAccount() const;
78
79 [[nodiscard]] bool
80 hasIssuer() const;
81
82 [[nodiscard]] bool
83 hasCurrency() const;
84
85 [[nodiscard]] bool
86 hasMPT() const;
87
88 [[nodiscard]] bool
89 hasAsset() const;
90
91 [[nodiscard]] bool
92 isNone() const;
93
94 // Nodes are either an account ID or a offer prefix. Offer prefixs denote a
95 // class of offers.
96 [[nodiscard]] AccountID const&
97 getAccountID() const;
98
99 [[nodiscard]] PathAsset const&
100 getPathAsset() const;
101
102 [[nodiscard]] Currency const&
103 getCurrency() const;
104
105 [[nodiscard]] MPTID const&
106 getMPTID() const;
107
108 [[nodiscard]] AccountID const&
109 getIssuerID() const;
110
111 [[nodiscard]] bool
112 isType(Type const& pe) const;
113
114 bool
115 operator==(STPathElement const& t) const;
116
117private:
118 static std::size_t
119 getHash(STPathElement const& element);
120};
121
122template <class Hasher>
123void
124hash_append(Hasher& h, STPathElement const& e) noexcept
125{
126 using beast::hash_append;
127 hash_append(h, (e.getNodeType() & STPathElement::TypeAccount) != 0u);
128 hash_append(h, e.getAccountID());
129 hash_append(h, e.getPathAsset());
130 hash_append(h, e.getIssuerID());
131}
132
133class STPath final : public CountedObject<STPath>
134{
136
137public:
138 STPath() = default;
139
141
143 size() const;
144
145 [[nodiscard]] bool
146 empty() const;
147
148 void
149 pushBack(STPathElement const& e);
150
151 template <typename... Args>
152 void
153 emplaceBack(Args&&... args);
154
155 [[nodiscard]] bool
156 hasSeen(AccountID const& account, PathAsset const& asset, AccountID const& issuer) const;
157
158 [[nodiscard]] json::Value getJson(JsonOptions) const;
159
160 [[nodiscard]] std::vector<STPathElement>::const_iterator
161 begin() const;
162
163 [[nodiscard]] std::vector<STPathElement>::const_iterator
164 end() const;
165
166 bool
167 operator==(STPath const& t) const;
168
170 back() const;
171
173 front() const;
174
176 operator[](int i);
177
178 STPathElement const&
179 operator[](int i) const;
180
181 void
182 reserve(size_t s);
183};
184
185template <class Hasher>
186void
187hash_append(Hasher& h, STPath const& p) noexcept
188{
189 using beast::hash_append;
190 for (auto const& e : p)
191 {
192 hash_append(h, e);
193 }
194}
195
196//------------------------------------------------------------------------------
197
198// A set of zero or more payment paths
199class STPathSet final : public STBase, public CountedObject<STPathSet>
200{
202
211
212public:
214 {
215 };
216
217 STPathSet() = default;
218
223 explicit STPathSet(DeduplicationTag);
224
225 STPathSet(SField const& n);
226 STPathSet(SerialIter& sit, SField const& name);
227 STPathSet(STPathSet const& other);
228 STPathSet(STPathSet&&) = default;
229
230 STPathSet&
231 operator=(STPathSet const& other);
232 STPathSet&
233 operator=(STPathSet&&) = default;
234
235 ~STPathSet() override = default;
236
237 void
238 add(Serializer& s) const override;
239
240 [[nodiscard]] json::Value getJson(JsonOptions) const override;
241
242 [[nodiscard]] SerializedTypeID
243 getSType() const override;
244
255 bool
256 assembleAdd(STPath const& base, STPathElement const& tail);
257
258 [[nodiscard]] bool
259 isEquivalent(STBase const& t) const override;
260
261 [[nodiscard]] bool
262 isDefault() const override;
263
264 // std::vector like interface:
267
268 [[nodiscard]] std::vector<STPath>::const_iterator
269 begin() const;
270
271 [[nodiscard]] std::vector<STPath>::const_iterator
272 end() const;
273
275 size() const;
276
277 [[nodiscard]] bool
278 empty() const;
279
291 bool
292 pushBack(STPath const& e);
293
309 template <typename... Args>
310 bool
311 emplaceBack(Args&&... args);
312
313private:
314 STBase*
315 copy(std::size_t n, void* buf) const override;
316 STBase*
317 move(std::size_t n, void* buf) override;
318
331 template <typename Append>
332 bool
333 appendUnique(Append&& append);
334
335 friend class detail::STVar;
336};
337
338// ------------ STPathElement ------------
339
341{
342 // hashValue_ is derived from the whole object, so it is computed in the body
343 // once every other member is initialized (as in the other constructors).
344 // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
345 hashValue_ = getHash(*this);
346}
347
349 std::optional<AccountID> const& account,
350 std::optional<PathAsset> const& asset,
351 std::optional<AccountID> const& issuer)
352 : type_(TypeNone)
353{
354 if (!account)
355 {
356 isOffer_ = true;
357 }
358 else
359 {
360 isOffer_ = false;
361 accountID_ = *account;
363 XRPL_ASSERT(
364 accountID_ != noAccount(), "xrpl::STPathElement::STPathElement : account is set");
365 }
366
367 if (asset)
368 {
369 assetID_ = *asset;
371 }
372
373 if (issuer)
374 {
375 issuerID_ = *issuer;
376 type_ |= TypeIssuer;
377 XRPL_ASSERT(issuerID_ != noAccount(), "xrpl::STPathElement::STPathElement : issuer is set");
378 }
379
380 hashValue_ = getHash(*this);
381}
382
384 AccountID const& account,
385 PathAsset const& asset,
386 AccountID const& issuer,
387 bool forceAsset)
388 : type_(TypeNone)
389 , accountID_(account)
390 , assetID_(asset)
391 , issuerID_(issuer)
393{
394 if (!isOffer_)
396
397 if (forceAsset || !isXRP(assetID_))
398 type_ |= asset.holds<Currency>() ? TypeCurrency : TypeMpt;
399
400 if (!isXRP(issuer))
401 type_ |= TypeIssuer;
402
403 hashValue_ = getHash(*this);
404}
405
407 unsigned int uType,
408 AccountID const& account,
409 PathAsset const& asset,
410 AccountID const& issuer)
411 : type_(uType)
412 , accountID_(account)
413 , assetID_(asset)
414 , issuerID_(issuer)
416{
417 assetID_.visit(
418 [&](Currency const&) { type_ = type_ & (~Type::TypeMpt); },
419 [&](MPTID const&) { type_ = type_ & (~Type::TypeCurrency); });
420 // hashValue_ must be computed after type_ is adjusted above, so this cannot
421 // be a member initializer.
422 // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
423 hashValue_ = getHash(*this);
424}
425
426inline std::uint32_t
428{
429 return type_;
430}
431
432inline bool
434{
435 return isOffer_;
436}
437
438inline bool
440{
441 return !isOffer();
442}
443
444inline bool
446{
447 return (type_ & pe) != 0u;
448}
449
450inline bool
455
456inline bool
461
462inline bool
467
468inline bool
473
474inline bool
479
480// Nodes are either an account ID or a offer prefix. Offer prefixs denote a
481// class of offers.
482inline AccountID const&
484{
485 return accountID_;
486}
487
488inline PathAsset const&
490{
491 return assetID_;
492}
493
494inline Currency const&
496{
497 return assetID_.get<Currency>();
498}
499
500inline MPTID const&
502{
503 return assetID_.get<MPTID>();
504}
505
506inline AccountID const&
508{
509 return issuerID_;
510}
511
512inline bool
514{
515 return (type_ & TypeAccount) == (t.type_ & TypeAccount) && hashValue_ == t.hashValue_ &&
517}
518
519// ------------ STPath ------------
520
522{
523}
524
527{
528 return path_.size();
529}
530
531inline bool
533{
534 return path_.empty();
535}
536
537inline void
539{
540 path_.push_back(e);
541}
542
543template <typename... Args>
544inline void
545STPath::emplaceBack(Args&&... args)
546{
547 path_.emplace_back(std::forward<Args>(args)...);
548}
549
550inline std::vector<STPathElement>::const_iterator
552{
553 return path_.begin();
554}
555
556inline std::vector<STPathElement>::const_iterator
558{
559 return path_.end();
560}
561
562inline bool
564{
565 return path_ == t.path_;
566}
567
570{
571 return path_.back();
572}
573
576{
577 return path_.front();
578}
579
580inline STPathElement&
582{
583 return path_[i];
584}
585
586inline STPathElement const&
588{
589 return path_[i];
590}
591
592inline void
594{
595 path_.reserve(s);
596}
597
598// ------------ STPathSet ------------
599
600inline STPathSet::STPathSet(SField const& n) : STBase(n)
601{
602}
603
604// std::vector like interface:
610
611inline std::vector<STPath>::const_iterator
613{
614 return value_.begin();
615}
616
617inline std::vector<STPath>::const_iterator
619{
620 return value_.end();
621}
622
625{
626 return value_.size();
627}
628
629inline bool
631{
632 return value_.empty();
633}
634
635template <typename Append>
636inline bool
638{
639 // Append to the vector first, so that a failed allocation there leaves both
640 // containers untouched rather than leaving the index holding a path the
641 // vector does not.
642 append(value_);
643
644 if (seen_ == nullptr)
645 {
646 return true;
647 }
648
649 try
650 {
651 if (!seen_->insert(value_.back()).second)
652 {
653 // Already present: roll back the append.
654 value_.pop_back();
655 return false;
656 }
657 }
658 catch (...)
659 {
660 // The index insert failed, so roll back the append to keep the vector
661 // and the index consistent.
662 value_.pop_back();
663 throw;
664 }
665 return true;
666}
667
668inline bool
670{
671 return appendUnique([&](auto& value) { value.push_back(e); });
672}
673
674template <typename... Args>
675inline bool
677{
678 return appendUnique([&](auto& value) { value.emplace_back(std::forward<Args>(args)...); });
679}
680
681} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
constexpr bool holds() const
Definition PathAsset.h:78
Identifies fields.
Definition SField.h:132
std::size_t hashValue_
Definition STPathSet.h:31
static std::size_t getHash(STPathElement const &element)
Definition STPathSet.cpp:29
std::uint32_t getNodeType() const
Definition STPathSet.h:427
AccountID const & getAccountID() const
Definition STPathSet.h:483
bool isOffer() const
Definition STPathSet.h:433
AccountID issuerID_
Definition STPathSet.h:28
unsigned int type_
Definition STPathSet.h:25
bool isNone() const
Definition STPathSet.h:475
PathAsset const & getPathAsset() const
Definition STPathSet.h:489
AccountID accountID_
Definition STPathSet.h:26
MPTID const & getMPTID() const
Definition STPathSet.h:501
STPathElement(STPathElement const &)=default
bool hasAsset() const
Definition STPathSet.h:469
Currency const & getCurrency() const
Definition STPathSet.h:495
bool operator==(STPathElement const &t) const
Definition STPathSet.h:513
STPathElement & operator=(STPathElement const &)=default
bool hasMPT() const
Definition STPathSet.h:463
AccountID const & getIssuerID() const
Definition STPathSet.h:507
bool isAccount() const
Definition STPathSet.h:439
bool hasIssuer() const
Definition STPathSet.h:451
PathAsset assetID_
Definition STPathSet.h:27
bool isType(Type const &pe) const
Definition STPathSet.h:445
bool hasCurrency() const
Definition STPathSet.h:457
void add(Serializer &s) const override
std::vector< STPath >::const_iterator begin() const
Definition STPathSet.h:612
STPathSet()=default
bool assembleAdd(STPath const &base, STPathElement const &tail)
assembleAdd adds a path to the set by combining a base path and a tail element.
~STPathSet() override=default
std::vector< STPath >::const_reference operator[](std::vector< STPath >::size_type n) const
Definition STPathSet.h:606
STBase * copy(std::size_t n, void *buf) const override
std::vector< STPath >::size_type size() const
Definition STPathSet.h:624
json::Value getJson(JsonOptions) const override
bool pushBack(STPath const &e)
pushBack adds a path to the set.
Definition STPathSet.h:669
std::vector< STPath > value_
Definition STPathSet.h:201
STBase * move(std::size_t n, void *buf) override
bool emplaceBack(Args &&... args)
emplaceBack adds a path to the set.
Definition STPathSet.h:676
std::vector< STPath >::const_iterator end() const
Definition STPathSet.h:618
STPathSet & operator=(STPathSet &&)=default
bool empty() const
Definition STPathSet.h:630
bool isEquivalent(STBase const &t) const override
std::unique_ptr< HardenedHashSet< STPath > > seen_
Deduplication index over value_, for pathfinding.
Definition STPathSet.h:210
bool isDefault() const override
SerializedTypeID getSType() const override
STPathSet(STPathSet &&)=default
STPathSet & operator=(STPathSet const &other)
Definition STPathSet.cpp:92
bool appendUnique(Append &&append)
Append a path via append, then register it in the deduplication index.
Definition STPathSet.h:637
std::vector< STPathElement > path_
Definition STPathSet.h:135
std::vector< STPathElement >::size_type size() const
Definition STPathSet.h:526
bool hasSeen(AccountID const &account, PathAsset const &asset, AccountID const &issuer) const
bool empty() const
Definition STPathSet.h:532
bool operator==(STPath const &t) const
Definition STPathSet.h:563
STPathElement & operator[](int i)
Definition STPathSet.h:581
void pushBack(STPathElement const &e)
Definition STPathSet.h:538
std::vector< STPathElement >::const_iterator end() const
Definition STPathSet.h:557
std::vector< STPathElement >::const_reference front() const
Definition STPathSet.h:575
void reserve(size_t s)
Definition STPathSet.h:593
void emplaceBack(Args &&... args)
Definition STPathSet.h:545
std::vector< STPathElement >::const_reference back() const
Definition STPathSet.h:569
STPath()=default
std::vector< STPathElement >::const_iterator begin() const
Definition STPathSet.h:551
json::Value getJson(JsonOptions) const
T forward(T... args)
void hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool isXRP(AccountID const &c)
Definition AccountID.h:84
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:42
SerializedTypeID
Definition SField.h:94
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:54
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
AccountID const & noAccount()
A placeholder for empty accounts.
void hash_append(Hasher &h, Slice const &v)
Definition Slice.h:194
Note, should be treated as flags that can be | and &.
Definition STBase.h:22