rippled
Loading...
Searching...
No Matches
STPathSet.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Log.h>
21#include <xrpl/basics/contract.h>
22#include <xrpl/beast/utility/instrumentation.h>
23#include <xrpl/json/json_value.h>
24#include <xrpl/protocol/AccountID.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/STBase.h>
27#include <xrpl/protocol/STPathSet.h>
28#include <xrpl/protocol/Serializer.h>
29#include <xrpl/protocol/UintTypes.h>
30#include <xrpl/protocol/jss.h>
31
32#include <cstddef>
33#include <stdexcept>
34#include <utility>
35#include <vector>
36
37namespace ripple {
38
41{
42 std::size_t hash_account = 2654435761;
43 std::size_t hash_currency = 2654435761;
44 std::size_t hash_issuer = 2654435761;
45
46 // NIKB NOTE: This doesn't have to be a secure hash as speed is more
47 // important. We don't even really need to fully hash the whole
48 // base_uint here, as a few bytes would do for our use.
49
50 for (auto const x : element.getAccountID())
51 hash_account += (hash_account * 257) ^ x;
52
53 for (auto const x : element.getCurrency())
54 hash_currency += (hash_currency * 509) ^ x;
55
56 for (auto const x : element.getIssuerID())
57 hash_issuer += (hash_issuer * 911) ^ x;
58
59 return (hash_account ^ hash_currency ^ hash_issuer);
60}
61
62STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name)
63{
65 for (;;)
66 {
67 int iType = sit.get8();
68
69 if (iType == STPathElement::typeNone ||
71 {
72 if (path.empty())
73 {
74 JLOG(debugLog().error()) << "Empty path in pathset";
75 Throw<std::runtime_error>("empty path");
76 }
77
78 push_back(path);
79 path.clear();
80
81 if (iType == STPathElement::typeNone)
82 return;
83 }
84 else if (iType & ~STPathElement::typeAll)
85 {
86 JLOG(debugLog().error())
87 << "Bad path element " << iType << " in pathset";
88 Throw<std::runtime_error>("bad path element");
89 }
90 else
91 {
92 auto hasAccount = iType & STPathElement::typeAccount;
93 auto hasCurrency = iType & STPathElement::typeCurrency;
94 auto hasIssuer = iType & STPathElement::typeIssuer;
95
96 AccountID account;
97 Currency currency;
98 AccountID issuer;
99
100 if (hasAccount)
101 account = sit.get160();
102
103 if (hasCurrency)
104 currency = sit.get160();
105
106 if (hasIssuer)
107 issuer = sit.get160();
108
109 path.emplace_back(account, currency, issuer, hasCurrency);
110 }
111 }
112}
113
114STBase*
115STPathSet::copy(std::size_t n, void* buf) const
116{
117 return emplace(n, buf, *this);
118}
119
120STBase*
122{
123 return emplace(n, buf, std::move(*this));
124}
125
126bool
128{ // assemble base+tail and add it to the set if it's not a duplicate
129 value.push_back(base);
130
132
133 STPath& newPath = *it;
134 newPath.push_back(tail);
135
136 while (++it != value.rend())
137 {
138 if (*it == newPath)
139 {
140 value.pop_back();
141 return false;
142 }
143 }
144 return true;
145}
146
147bool
149{
150 STPathSet const* v = dynamic_cast<STPathSet const*>(&t);
151 return v && (value == v->value);
152}
153
154bool
156{
157 return value.empty();
158}
159
160bool
162 AccountID const& account,
163 Currency const& currency,
164 AccountID const& issuer) const
165{
166 for (auto& p : mPath)
167 {
168 if (p.getAccountID() == account && p.getCurrency() == currency &&
169 p.getIssuerID() == issuer)
170 return true;
171 }
172
173 return false;
174}
175
178{
180
181 for (auto it : mPath)
182 {
184 auto const iType = it.getNodeType();
185
186 elem[jss::type] = iType;
187
188 if (iType & STPathElement::typeAccount)
189 elem[jss::account] = to_string(it.getAccountID());
190
191 if (iType & STPathElement::typeCurrency)
192 elem[jss::currency] = to_string(it.getCurrency());
193
194 if (iType & STPathElement::typeIssuer)
195 elem[jss::issuer] = to_string(it.getIssuerID());
196
197 ret.append(elem);
198 }
199
200 return ret;
201}
202
205{
207 for (auto 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(
223 getFName().isBinary(), "ripple::STPathSet::add : field is binary");
224 XRPL_ASSERT(
225 getFName().fieldType == STI_PATHSET,
226 "ripple::STPathSet::add : valid field type");
227 bool first = true;
228
229 for (auto const& spPath : value)
230 {
231 if (!first)
233
234 for (auto const& speElement : spPath)
235 {
236 int iType = speElement.getNodeType();
237
238 s.add8(iType);
239
240 if (iType & STPathElement::typeAccount)
241 s.addBitString(speElement.getAccountID());
242
243 if (iType & STPathElement::typeCurrency)
244 s.addBitString(speElement.getCurrency());
245
246 if (iType & STPathElement::typeIssuer)
247 s.addBitString(speElement.getIssuerID());
248 }
249
250 first = false;
251 }
252
254}
255
256} // namespace ripple
Represents a JSON value.
Definition json_value.h:149
Value & append(Value const &value)
Append value to array at the end.
Identifies fields.
Definition SField.h:146
A type which can be exported to a well known binary format.
Definition STBase.h:135
SField const & getFName() const
Definition STBase.cpp:143
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition STBase.h:233
Currency const & getCurrency() const
Definition STPathSet.h:366
static std::size_t get_hash(STPathElement const &element)
Definition STPathSet.cpp:40
AccountID const & getAccountID() const
Definition STPathSet.h:360
AccountID const & getIssuerID() const
Definition STPathSet.h:372
STBase * move(std::size_t n, void *buf) override
bool isDefault() const override
bool empty() const
Definition STPathSet.h:508
std::vector< STPath > value
Definition STPathSet.h:179
bool isEquivalent(STBase const &t) const override
STBase * copy(std::size_t n, void *buf) const override
void push_back(STPath const &e)
Definition STPathSet.h:514
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:121
Json::Value getJson(JsonOptions) const
void push_back(STPathElement const &e)
Definition STPathSet.h:410
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:131
int add8(unsigned char i)
@ arrayValue
array value (ordered list)
Definition json_value.h:44
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:45
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
SerializedTypeID
Definition SField.h:110
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:476
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
T rbegin(T... args)
T rend(T... args)
Note, should be treated as flags that can be | and &.
Definition STBase.h:37