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 
160  if (iType & STPathElement::typeAccount)
161  elem[jss::account] = to_string(it.getAccountID());
162 
163  if (iType & STPathElement::typeCurrency)
164  elem[jss::currency] = to_string(it.getCurrency());
165 
166  if (iType & STPathElement::typeIssuer)
167  elem[jss::issuer] = to_string(it.getIssuerID());
168 
169  ret.append(elem);
170  }
171 
172  return ret;
173 }
174 
177 {
179  for (auto it : value)
180  ret.append(it.getJson(options));
181 
182  return ret;
183 }
184 
185 void
187 {
188  assert(fName->isBinary());
189  assert(fName->fieldType == STI_PATHSET);
190  bool first = true;
191 
192  for (auto const& spPath : value)
193  {
194  if (!first)
196 
197  for (auto const& speElement : spPath)
198  {
199  int iType = speElement.getNodeType();
200 
201  s.add8(iType);
202 
203  if (iType & STPathElement::typeAccount)
204  s.addBitString(speElement.getAccountID());
205 
206  if (iType & STPathElement::typeCurrency)
207  s.addBitString(speElement.getCurrency());
208 
209  if (iType & STPathElement::typeIssuer)
210  s.addBitString(speElement.getIssuerID());
211  }
212 
213  first = false;
214  }
215 
217 }
218 
219 } // 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:42
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:186
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:176
ripple::STPathElement::typeAccount
@ typeAccount
Definition: STPathSet.h:38
ripple::STBase::fName
SField const * fName
Definition: STBase.h:145
std::size_t
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