xrpld
Loading...
Searching...
No Matches
STPathSet.cpp
1#include <xrpl/protocol/STPathSet.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/beast/hash/uhash.h>
7#include <xrpl/beast/utility/instrumentation.h>
8#include <xrpl/json/json_value.h>
9#include <xrpl/protocol/AccountID.h>
10#include <xrpl/protocol/SField.h>
11#include <xrpl/protocol/STBase.h>
12#include <xrpl/protocol/Serializer.h>
13#include <xrpl/protocol/UintTypes.h>
14#include <xrpl/protocol/jss.h>
15
16#include <algorithm>
17#include <cstddef>
18#include <stdexcept>
19#include <utility>
20#include <vector>
21
22namespace xrpl {
23
24std::size_t
26{
27 std::size_t hashAccount = 2654435761;
28 std::size_t hashCurrency = 2654435761;
29 std::size_t hashIssuer = 2654435761;
30
31 // NIKB NOTE: This doesn't have to be a secure hash as speed is more
32 // important. We don't even really need to fully hash the whole
33 // base_uint here, as a few bytes would do for our use.
34
35 for (auto const x : element.getAccountID())
36 hashAccount += (hashAccount * 257) ^ x;
37
38 // Check pathAsset type instead of element's type_
39 // In some cases type_ might be account but the asset
40 // is still set to either MPT or currency (see Pathfinder::addLink())
41 element.getPathAsset().visit(
42 [&](MPTID const& mpt) { hashCurrency += beast::Uhash<>{}(mpt); },
43 [&](Currency const& currency) {
44 for (auto const x : currency)
45 hashCurrency += (hashCurrency * 509) ^ x;
46 });
47
48 for (auto const x : element.getIssuerID())
49 hashIssuer += (hashIssuer * 911) ^ x;
50
51 return (hashAccount ^ hashCurrency ^ hashIssuer);
52}
53
54[[nodiscard]] size_t
56{
57 return STPathElement::getHash(*this);
58}
59
60STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name)
61{
63 for (;;)
64 {
65 int const iType = sit.get8();
66
68 {
69 if (path.empty())
70 {
71 JLOG(debugLog().error()) << "Empty path in pathset";
72 Throw<std::runtime_error>("empty path");
73 }
74
76 path.clear();
77
78 if (iType == STPathElement::TypeNone)
79 return;
80 }
81 else if ((iType & ~STPathElement::TypeAll) != 0)
82 {
83 JLOG(debugLog().error()) << "Bad path element " << iType << " in pathset";
84 Throw<std::runtime_error>("bad path element");
85 }
86 else
87 {
88 auto const hasAccount = (iType & STPathElement::TypeAccount) != 0u;
89 auto const hasCurrency = (iType & STPathElement::TypeCurrency) != 0u;
90 auto const hasIssuer = (iType & STPathElement::TypeIssuer) != 0u;
91 auto const hasMPT = (iType & STPathElement::TypeMpt) != 0u;
92
93 AccountID account;
94 PathAsset asset;
95 AccountID issuer;
96
97 if (hasAccount)
98 account = sit.get160();
99
100 if (hasCurrency && hasMPT)
101 {
102 JLOG(debugLog().error()) << "Bad path element MPT and Currency in pathset";
103 Throw<std::runtime_error>("bad path element: MPT and Currency");
104 }
105
106 if (hasCurrency)
107 asset = Currency::fromRaw(sit.get160());
108
109 if (hasMPT)
110 asset = sit.get192();
111
112 if (hasIssuer)
113 issuer = sit.get160();
114
115 path.emplace_back(account, asset, issuer, hasCurrency || hasMPT);
116 }
117 }
118}
119
120STBase*
121STPathSet::copy(std::size_t n, void* buf) const
122{
123 return emplace(n, buf, *this);
124}
125
126STBase*
128{
129 return emplace(n, buf, std::move(*this));
130}
131
132bool
134{ // assemble base+tail and add it to the set if it's not a duplicate
135 STPath combined = base;
136 combined.pushBack(tail);
137
138 if (!seenHashes_.insert(combined).second)
139 {
140 return false;
141 }
142
143 value_.push_back(std::move(combined));
144 return true;
145}
146
147bool
149{
150 auto const* v = dynamic_cast<STPathSet const*>(&t);
151 return (v != nullptr) && (value_ == v->value_);
152}
153
154bool
156{
157 return value_.empty();
158}
159
160bool
161STPath::hasSeen(AccountID const& account, PathAsset const& asset, AccountID const& issuer) const
162{
163 return std::ranges::any_of(path_, [&](auto& p) {
164 return p.getAccountID() == account && p.getPathAsset() == asset &&
165 p.getIssuerID() == issuer;
166 });
167}
168
171{
173
174 for (auto const& it : path_)
175 {
177 auto const iType = it.getNodeType();
178
179 elem[jss::type] = iType;
180
181 if ((iType & STPathElement::TypeAccount) != 0u)
182 elem[jss::account] = to_string(it.getAccountID());
183
184 XRPL_ASSERT(
185 ((iType & STPathElement::TypeCurrency) == 0u) ||
186 ((iType & STPathElement::TypeMpt) == 0u),
187 "xrpl::STPath::getJson : not type Currency and MPT");
188 if ((iType & STPathElement::TypeCurrency) != 0u)
189 elem[jss::currency] = to_string(it.getCurrency());
190
191 if ((iType & STPathElement::TypeMpt) != 0u)
192 elem[jss::mpt_issuance_id] = to_string(it.getMPTID());
193
194 if ((iType & STPathElement::TypeIssuer) != 0u)
195 elem[jss::issuer] = to_string(it.getIssuerID());
196
197 ret.append(elem);
198 }
199
200 return ret;
201}
202
205{
207 for (auto const& it : value_)
208 ret.append(it.getJson(options));
209
210 return ret;
211}
212
215{
216 return STI_PATHSET;
217}
218
219void
221{
222 XRPL_ASSERT(getFName().isBinary(), "xrpl::STPathSet::add : field is binary");
223 XRPL_ASSERT(getFName().fieldType == STI_PATHSET, "xrpl::STPathSet::add : valid field type");
224 bool first = true;
225
226 for (auto const& spPath : value_)
227 {
228 if (!first)
230
231 for (auto const& speElement : spPath)
232 {
233 int const iType = speElement.getNodeType();
234
235 s.add8(iType);
236
237 if ((iType & STPathElement::TypeAccount) != 0u)
238 s.addBitString(speElement.getAccountID());
239
240 if ((iType & STPathElement::TypeMpt) != 0u)
241 s.addBitString(speElement.getMPTID());
242
243 if ((iType & STPathElement::TypeCurrency) != 0u)
244 s.addBitString(speElement.getCurrency());
245
246 if ((iType & STPathElement::TypeIssuer) != 0u)
247 s.addBitString(speElement.getIssuerID());
248 }
249
250 first = false;
251 }
252
254}
255
256} // namespace xrpl
T any_of(T... args)
Represents a JSON value.
Definition json_value.h:117
Value & append(Value const &value)
Append value to array at the end.
static BaseUInt fromRaw(Container const &c)
Definition base_uint.h:302
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
Definition PathAsset.h:50
Identifies fields.
Definition SField.h:132
A type which can be exported to a well known binary format.
Definition STBase.h:129
SField const & getFName() const
Definition STBase.cpp:120
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition STBase.h:226
AccountID const & getAccountID() const
Definition STPathSet.h:396
PathAsset const & getPathAsset() const
Definition STPathSet.h:402
size_t getHash() const
Definition STPathSet.cpp:55
AccountID const & getIssuerID() const
Definition STPathSet.h:420
void add(Serializer &s) const override
STPathSet()=default
bool assembleAdd(STPath const &base, STPathElement const &tail)
STBase * copy(std::size_t n, void *buf) const override
json::Value getJson(JsonOptions) const override
void pushBack(STPath const &e)
Definition STPathSet.h:549
std::vector< STPath > value_
Definition STPathSet.h:190
STBase * move(std::size_t n, void *buf) override
xrpl::hardened_hash_set< STPath > seenHashes_
Definition STPathSet.h:191
bool isEquivalent(STBase const &t) const override
bool isDefault() const override
SerializedTypeID getSType() const override
std::vector< STPathElement > path_
Definition STPathSet.h:125
bool hasSeen(AccountID const &account, PathAsset const &asset, AccountID const &issuer) const
void pushBack(STPathElement const &e)
Definition STPathSet.h:451
json::Value getJson(JsonOptions) const
uint160 get160()
Definition Serializer.h:373
uint192 get192()
Definition Serializer.h:379
int addBitString(BaseUInt< Bits, Tag > const &v)
Definition Serializer.h:106
@ Array
array value (ordered list)
Definition json_value.h:28
@ Object
object value (collection of name/value pairs).
Definition json_value.h:29
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:399
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:42
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
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
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
Note, should be treated as flags that can be | and &.
Definition STBase.h:22