rippled
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 <ripple/basics/Log.h>
21 #include <ripple/basics/StringUtilities.h>
22 #include <ripple/basics/contract.h>
23 #include <ripple/basics/strHex.h>
24 #include <ripple/protocol/STPathSet.h>
25 #include <ripple/protocol/jss.h>
26 
27 namespace 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 
52 STPathSet::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 
104 STBase*
105 STPathSet::copy(std::size_t n, void* buf) const
106 {
107  return emplace(n, buf, *this);
108 }
109 
110 STBase*
112 {
113  return emplace(n, buf, std::move(*this));
114 }
115 
116 bool
117 STPathSet::assembleAdd(STPath const& base, STPathElement const& tail)
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 
137 bool
139 {
140  const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
141  return v && (value == v->value);
142 }
143 
144 bool
146 {
147  return value.empty();
148 }
149 
150 bool
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 
167 {
169 
170  for (auto it : mPath)
171  {
173  auto const iType = it.getNodeType();
174 
175  elem[jss::type] = iType;
176 
177  if (iType & STPathElement::typeAccount)
178  elem[jss::account] = to_string(it.getAccountID());
179 
180  if (iType & STPathElement::typeCurrency)
181  elem[jss::currency] = to_string(it.getCurrency());
182 
183  if (iType & STPathElement::typeIssuer)
184  elem[jss::issuer] = to_string(it.getIssuerID());
185 
186  ret.append(elem);
187  }
188 
189  return ret;
190 }
191 
194 {
196  for (auto it : value)
197  ret.append(it.getJson(options));
198 
199  return ret;
200 }
201 
204 {
205  return STI_PATHSET;
206 }
207 
208 void
210 {
211  assert(getFName().isBinary());
212  assert(getFName().fieldType == STI_PATHSET);
213  bool first = true;
214 
215  for (auto const& spPath : value)
216  {
217  if (!first)
219 
220  for (auto const& speElement : spPath)
221  {
222  int iType = speElement.getNodeType();
223 
224  s.add8(iType);
225 
226  if (iType & STPathElement::typeAccount)
227  s.addBitString(speElement.getAccountID());
228 
229  if (iType & STPathElement::typeCurrency)
230  s.addBitString(speElement.getCurrency());
231 
232  if (iType & STPathElement::typeIssuer)
233  s.addBitString(speElement.getIssuerID());
234  }
235 
236  first = false;
237  }
238 
240 }
241 
242 } // namespace ripple
ripple::STPath::push_back
void push_back(STPathElement const &e)
Definition: STPathSet.h:405
ripple::STPathElement::get_hash
static std::size_t get_hash(STPathElement const &element)
Definition: STPathSet.cpp:30
ripple::JsonOptions
JsonOptions
Definition: STBase.h:34
ripple::STPathElement::typeAll
@ typeAll
Definition: STPathSet.h:52
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::STPath::mPath
std::vector< STPathElement > mPath
Definition: STPathSet.h:120
ripple::STPathSet::getSType
SerializedTypeID getSType() const override
Definition: STPathSet.cpp:203
std::vector
STL class.
ripple::STI_PATHSET
@ STI_PATHSET
Definition: SField.h:73
ripple::STPathElement::getCurrency
Currency const & getCurrency() const
Definition: STPathSet.h:361
ripple::SerializedTypeID
SerializedTypeID
Definition: SField.h:52
ripple::Serializer::add8
int add8(unsigned char i)
Definition: Serializer.cpp:166
ripple::STPathSet::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STPathSet.cpp:105
ripple::STPathElement::typeBoundary
@ typeBoundary
Definition: STPathSet.h:51
ripple::STPathSet::STPathSet
STPathSet()=default
ripple::STPathElement::typeCurrency
@ typeCurrency
Definition: STPathSet.h:49
ripple::STPathSet
Definition: STPathSet.h:176
ripple::debugLog
beast::Journal debugLog()
Returns a debug journal.
Definition: Log.cpp:452
ripple::STPathElement::typeIssuer
@ typeIssuer
Definition: STPathSet.h:50
ripple::STPathSet::isEquivalent
bool isEquivalent(const STBase &t) const override
Definition: STPathSet.cpp:138
ripple::base_uint< 160, detail::AccountIDTag >
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::SerialIter::get8
unsigned char get8()
Definition: Serializer.cpp:362
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::STBase::emplace
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition: STBase.h:165
ripple::SerialIter::get160
uint160 get160()
Definition: Serializer.h:370
ripple::STPathSet::add
void add(Serializer &s) const override
Definition: STPathSet.cpp:209
ripple::STPathSet::isDefault
bool isDefault() const override
Definition: STPathSet.cpp:145
ripple::SerialIter
Definition: Serializer.h:310
ripple::STPathElement::getIssuerID
AccountID const & getIssuerID() const
Definition: STPathSet.h:367
ripple::STBase::getFName
SField const & getFName() const
Definition: STBase.cpp:132
ripple::STPath::getJson
Json::Value getJson(JsonOptions) const
Definition: STPathSet.cpp:166
ripple::Serializer
Definition: Serializer.h:39
ripple::STPath::hasSeen
bool hasSeen(AccountID const &account, Currency const &currency, AccountID const &issuer) const
Definition: STPathSet.cpp:151
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Serializer::addBitString
int addBitString(base_uint< Bits, Tag > const &v)
Definition: Serializer.h:97
ripple::STPathSet::value
std::vector< STPath > value
Definition: STPathSet.h:178
ripple::SField
Identifies fields.
Definition: SField.h:112
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:66
ripple::STPathElement
Definition: STPathSet.h:34
ripple::STPathElement::typeNone
@ typeNone
Definition: STPathSet.h:46
ripple::STPathSet::getJson
Json::Value getJson(JsonOptions) const override
Definition: STPathSet.cpp:193
ripple::STPathElement::typeAccount
@ typeAccount
Definition: STPathSet.h:47
std::size_t
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::STPathSet::assembleAdd
bool assembleAdd(STPath const &base, STPathElement const &tail)
Definition: STPathSet.cpp:117
ripple::STPath
Definition: STPathSet.h:118
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::STPathSet::move
STBase * move(std::size_t n, void *buf) override
Definition: STPathSet.cpp:111
ripple::STPathSet::push_back
void push_back(STPath const &e)
Definition: STPathSet.h:509
ripple::STPathElement::getAccountID
AccountID const & getAccountID() const
Definition: STPathSet.h:355