rippled
Loading...
Searching...
No Matches
STPathSet.cpp
1#include <xrpl/basics/Log.h>
2#include <xrpl/basics/contract.h>
3#include <xrpl/beast/utility/instrumentation.h>
4#include <xrpl/json/json_value.h>
5#include <xrpl/protocol/AccountID.h>
6#include <xrpl/protocol/SField.h>
7#include <xrpl/protocol/STBase.h>
8#include <xrpl/protocol/STPathSet.h>
9#include <xrpl/protocol/Serializer.h>
10#include <xrpl/protocol/UintTypes.h>
11#include <xrpl/protocol/jss.h>
12
13#include <cstddef>
14#include <stdexcept>
15#include <utility>
16#include <vector>
17
18namespace ripple {
19
22{
23 std::size_t hash_account = 2654435761;
24 std::size_t hash_currency = 2654435761;
25 std::size_t hash_issuer = 2654435761;
26
27 // NIKB NOTE: This doesn't have to be a secure hash as speed is more
28 // important. We don't even really need to fully hash the whole
29 // base_uint here, as a few bytes would do for our use.
30
31 for (auto const x : element.getAccountID())
32 hash_account += (hash_account * 257) ^ x;
33
34 for (auto const x : element.getCurrency())
35 hash_currency += (hash_currency * 509) ^ x;
36
37 for (auto const x : element.getIssuerID())
38 hash_issuer += (hash_issuer * 911) ^ x;
39
40 return (hash_account ^ hash_currency ^ hash_issuer);
41}
42
43STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name)
44{
46 for (;;)
47 {
48 int iType = sit.get8();
49
50 if (iType == STPathElement::typeNone ||
52 {
53 if (path.empty())
54 {
55 JLOG(debugLog().error()) << "Empty path in pathset";
56 Throw<std::runtime_error>("empty path");
57 }
58
59 push_back(path);
60 path.clear();
61
62 if (iType == STPathElement::typeNone)
63 return;
64 }
65 else if (iType & ~STPathElement::typeAll)
66 {
67 JLOG(debugLog().error())
68 << "Bad path element " << iType << " in pathset";
69 Throw<std::runtime_error>("bad path element");
70 }
71 else
72 {
73 auto hasAccount = iType & STPathElement::typeAccount;
74 auto hasCurrency = iType & STPathElement::typeCurrency;
75 auto hasIssuer = iType & STPathElement::typeIssuer;
76
77 AccountID account;
78 Currency currency;
79 AccountID issuer;
80
81 if (hasAccount)
82 account = sit.get160();
83
84 if (hasCurrency)
85 currency = sit.get160();
86
87 if (hasIssuer)
88 issuer = sit.get160();
89
90 path.emplace_back(account, currency, issuer, hasCurrency);
91 }
92 }
93}
94
95STBase*
96STPathSet::copy(std::size_t n, void* buf) const
97{
98 return emplace(n, buf, *this);
99}
100
101STBase*
103{
104 return emplace(n, buf, std::move(*this));
105}
106
107bool
109{ // assemble base+tail and add it to the set if it's not a duplicate
110 value.push_back(base);
111
113
114 STPath& newPath = *it;
115 newPath.push_back(tail);
116
117 while (++it != value.rend())
118 {
119 if (*it == newPath)
120 {
121 value.pop_back();
122 return false;
123 }
124 }
125 return true;
126}
127
128bool
130{
131 STPathSet const* v = dynamic_cast<STPathSet const*>(&t);
132 return v && (value == v->value);
133}
134
135bool
137{
138 return value.empty();
139}
140
141bool
143 AccountID const& account,
144 Currency const& currency,
145 AccountID const& issuer) const
146{
147 for (auto& p : mPath)
148 {
149 if (p.getAccountID() == account && p.getCurrency() == currency &&
150 p.getIssuerID() == issuer)
151 return true;
152 }
153
154 return false;
155}
156
159{
161
162 for (auto it : mPath)
163 {
165 auto const iType = it.getNodeType();
166
167 elem[jss::type] = iType;
168
169 if (iType & STPathElement::typeAccount)
170 elem[jss::account] = to_string(it.getAccountID());
171
172 if (iType & STPathElement::typeCurrency)
173 elem[jss::currency] = to_string(it.getCurrency());
174
175 if (iType & STPathElement::typeIssuer)
176 elem[jss::issuer] = to_string(it.getIssuerID());
177
178 ret.append(elem);
179 }
180
181 return ret;
182}
183
186{
188 for (auto it : value)
189 ret.append(it.getJson(options));
190
191 return ret;
192}
193
196{
197 return STI_PATHSET;
198}
199
200void
202{
203 XRPL_ASSERT(
204 getFName().isBinary(), "ripple::STPathSet::add : field is binary");
205 XRPL_ASSERT(
206 getFName().fieldType == STI_PATHSET,
207 "ripple::STPathSet::add : valid field type");
208 bool first = true;
209
210 for (auto const& spPath : value)
211 {
212 if (!first)
214
215 for (auto const& speElement : spPath)
216 {
217 int iType = speElement.getNodeType();
218
219 s.add8(iType);
220
221 if (iType & STPathElement::typeAccount)
222 s.addBitString(speElement.getAccountID());
223
224 if (iType & STPathElement::typeCurrency)
225 s.addBitString(speElement.getCurrency());
226
227 if (iType & STPathElement::typeIssuer)
228 s.addBitString(speElement.getIssuerID());
229 }
230
231 first = false;
232 }
233
235}
236
237} // namespace ripple
Represents a JSON value.
Definition json_value.h:131
Value & append(Value const &value)
Append value to array at the end.
Identifies fields.
Definition SField.h:127
A type which can be exported to a well known binary format.
Definition STBase.h:116
SField const & getFName() const
Definition STBase.cpp:124
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition STBase.h:214
Currency const & getCurrency() const
Definition STPathSet.h:347
static std::size_t get_hash(STPathElement const &element)
Definition STPathSet.cpp:21
AccountID const & getAccountID() const
Definition STPathSet.h:341
AccountID const & getIssuerID() const
Definition STPathSet.h:353
STBase * move(std::size_t n, void *buf) override
bool isDefault() const override
bool empty() const
Definition STPathSet.h:489
std::vector< STPath > value
Definition STPathSet.h:160
bool isEquivalent(STBase const &t) const override
STBase * copy(std::size_t n, void *buf) const override
Definition STPathSet.cpp:96
void push_back(STPath const &e)
Definition STPathSet.h:495
STPathSet()=default
bool assembleAdd(STPath const &base, STPathElement const &tail)
Json::Value getJson(JsonOptions) const override
SerializedTypeID getSType() const override
void add(Serializer &s) const override
std::vector< STPathElement > mPath
Definition STPathSet.h:102
Json::Value getJson(JsonOptions) const
void push_back(STPathElement const &e)
Definition STPathSet.h:391
bool hasSeen(AccountID const &account, Currency const &currency, AccountID const &issuer) const
unsigned char get8()
int addBitString(base_uint< Bits, Tag > const &v)
Definition Serializer.h:112
int add8(unsigned char i)
@ arrayValue
array value (ordered list)
Definition json_value.h:26
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
SerializedTypeID
Definition SField.h:91
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:457
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
T rbegin(T... args)
T rend(T... args)
Note, should be treated as flags that can be | and &.
Definition STBase.h:18