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