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