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 #include <cstddef>
27 
28 namespace ripple {
29 
32 {
33  std::size_t hash_account = 2654435761;
34  std::size_t hash_currency = 2654435761;
35  std::size_t hash_issuer = 2654435761;
36 
37  // NIKB NOTE: This doesn't have to be a secure hash as speed is more
38  // important. We don't even really need to fully hash the whole
39  // base_uint here, as a few bytes would do for our use.
40 
41  for (auto const x : element.getAccountID())
42  hash_account += (hash_account * 257) ^ x;
43 
44  for (auto const x : element.getCurrency())
45  hash_currency += (hash_currency * 509) ^ x;
46 
47  for (auto const x : element.getIssuerID())
48  hash_issuer += (hash_issuer * 911) ^ x;
49 
50  return (hash_account ^ hash_currency ^ hash_issuer);
51 }
52 
53 STPathSet::STPathSet(SerialIter& sit, SField const& name) : STBase(name)
54 {
56  for (;;)
57  {
58  int iType = sit.get8();
59 
60  if (iType == STPathElement::typeNone ||
62  {
63  if (path.empty())
64  {
65  JLOG(debugLog().error()) << "Empty path in pathset";
66  Throw<std::runtime_error>("empty path");
67  }
68 
69  push_back(path);
70  path.clear();
71 
72  if (iType == STPathElement::typeNone)
73  return;
74  }
75  else if (iType & ~STPathElement::typeAll)
76  {
77  JLOG(debugLog().error())
78  << "Bad path element " << iType << " in pathset";
79  Throw<std::runtime_error>("bad path element");
80  }
81  else
82  {
83  auto hasAccount = iType & STPathElement::typeAccount;
84  auto hasCurrency = iType & STPathElement::typeCurrency;
85  auto hasIssuer = iType & STPathElement::typeIssuer;
86 
87  AccountID account;
88  Currency currency;
89  AccountID issuer;
90 
91  if (hasAccount)
92  account = sit.get160();
93 
94  if (hasCurrency)
95  currency = sit.get160();
96 
97  if (hasIssuer)
98  issuer = sit.get160();
99 
100  path.emplace_back(account, currency, issuer, hasCurrency);
101  }
102  }
103 }
104 
105 bool
106 STPathSet::assembleAdd(STPath const& base, STPathElement const& tail)
107 { // assemble base+tail and add it to the set if it's not a duplicate
108  value.push_back(base);
109 
111 
112  STPath& newPath = *it;
113  newPath.push_back(tail);
114 
115  while (++it != value.rend())
116  {
117  if (*it == newPath)
118  {
119  value.pop_back();
120  return false;
121  }
122  }
123  return true;
124 }
125 
126 bool
128 {
129  const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
130  return v && (value == v->value);
131 }
132 
133 bool
135  AccountID const& account,
136  Currency const& currency,
137  AccountID const& issuer) const
138 {
139  for (auto& p : mPath)
140  {
141  if (p.getAccountID() == account && p.getCurrency() == currency &&
142  p.getIssuerID() == issuer)
143  return true;
144  }
145 
146  return false;
147 }
148 
150 {
152 
153  for (auto it : mPath)
154  {
156  auto const iType = it.getNodeType();
157 
158  elem[jss::type] = iType;
159  elem[jss::type_hex] = strHex(iType);
160 
161  if (iType & STPathElement::typeAccount)
162  elem[jss::account] = to_string(it.getAccountID());
163 
164  if (iType & STPathElement::typeCurrency)
165  elem[jss::currency] = to_string(it.getCurrency());
166 
167  if (iType & STPathElement::typeIssuer)
168  elem[jss::issuer] = to_string(it.getIssuerID());
169 
170  ret.append(elem);
171  }
172 
173  return ret;
174 }
175 
178 {
180  for (auto it : value)
181  ret.append(it.getJson(options));
182 
183  return ret;
184 }
185 
186 void
188 {
189  assert(fName->isBinary());
190  assert(fName->fieldType == STI_PATHSET);
191  bool first = true;
192 
193  for (auto const& spPath : value)
194  {
195  if (!first)
197 
198  for (auto const& speElement : spPath)
199  {
200  int iType = speElement.getNodeType();
201 
202  s.add8(iType);
203 
204  if (iType & STPathElement::typeAccount)
205  s.addBitString(speElement.getAccountID());
206 
207  if (iType & STPathElement::typeCurrency)
208  s.addBitString(speElement.getCurrency());
209 
210  if (iType & STPathElement::typeIssuer)
211  s.addBitString(speElement.getIssuerID());
212  }
213 
214  first = false;
215  }
216 
218 }
219 
220 } // namespace ripple
ripple::STPath::push_back
void push_back(STPathElement const &e)
Definition: STPathSet.h:234
ripple::STPathElement::get_hash
static std::size_t get_hash(STPathElement const &element)
Definition: STPathSet.cpp:31
ripple::JsonOptions
JsonOptions
Definition: STBase.h:34
ripple::SField::isBinary
bool isBinary() const
Definition: SField.h:210
ripple::STPathElement::typeAll
@ typeAll
Definition: STPathSet.h:43
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::STPath::mPath
std::vector< STPathElement > mPath
Definition: STPathSet.h:303
std::vector
STL class.
ripple::STI_PATHSET
@ STI_PATHSET
Definition: SField.h:74
ripple::Serializer::add8
int add8(unsigned char i)
Definition: Serializer.cpp:158
ripple::STPathElement::typeBoundary
@ typeBoundary
Definition: STPathSet.h:42
ripple::STPathElement::getCurrency
Currency const & getCurrency() const
Definition: STPathSet.h:177
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::STPathSet::STPathSet
STPathSet()=default
ripple::STPathElement::typeCurrency
@ typeCurrency
Definition: STPathSet.h:40
ripple::STPathSet
Definition: STPathSet.h:309
ripple::debugLog
beast::Journal debugLog()
Returns a debug journal.
Definition: Log.cpp:452
ripple::STPathElement::typeIssuer
@ typeIssuer
Definition: STPathSet.h:41
ripple::STPathSet::isEquivalent
bool isEquivalent(const STBase &t) const override
Definition: STPathSet.cpp:127
ripple::SField::fieldType
const SerializedTypeID fieldType
Definition: SField.h:127
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:354
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::SerialIter::get160
uint160 get160()
Definition: Serializer.h:368
cstddef
ripple::STPathElement::getIssuerID
AccountID const & getIssuerID() const
Definition: STPathSet.h:183
ripple::STPathSet::add
void add(Serializer &s) const override
Definition: STPathSet.cpp:187
ripple::STPathElement::getAccountID
AccountID const & getAccountID() const
Definition: STPathSet.h:171
ripple::SerialIter
Definition: Serializer.h:308
ripple::STPath::getJson
Json::Value getJson(JsonOptions) const
Definition: STPathSet.cpp:149
ripple::Serializer
Definition: Serializer.h:39
ripple::STPath::hasSeen
bool hasSeen(AccountID const &account, Currency const &currency, AccountID const &issuer) const
Definition: STPathSet.cpp:134
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:406
ripple::SField
Identifies fields.
Definition: SField.h:109
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:62
ripple::STPathElement
Definition: STPathSet.h:33
ripple::STPathElement::typeNone
@ typeNone
Definition: STPathSet.h:37
ripple::STPathSet::getJson
Json::Value getJson(JsonOptions) const override
Definition: STPathSet.cpp:177
ripple::STPathElement::typeAccount
@ typeAccount
Definition: STPathSet.h:38
ripple::STBase::fName
SField const * fName
Definition: STBase.h:145
std::size_t
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:67
ripple::STPathSet::assembleAdd
bool assembleAdd(STPath const &base, STPathElement const &tail)
Definition: STPathSet.cpp:106
ripple::STPath
Definition: STPathSet.h:212
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::STPathSet::push_back
void push_back(STPath const &e)
Definition: STPathSet.h:393