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 bool
105 STPathSet::assembleAdd(STPath const& base, STPathElement const& tail)
106 { // assemble base+tail and add it to the set if it's not a duplicate
107  value.push_back(base);
108 
110 
111  STPath& newPath = *it;
112  newPath.push_back(tail);
113 
114  while (++it != value.rend())
115  {
116  if (*it == newPath)
117  {
118  value.pop_back();
119  return false;
120  }
121  }
122  return true;
123 }
124 
125 bool
127 {
128  const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
129  return v && (value == v->value);
130 }
131 
132 bool
134  AccountID const& account,
135  Currency const& currency,
136  AccountID const& issuer) const
137 {
138  for (auto& p : mPath)
139  {
140  if (p.getAccountID() == account && p.getCurrency() == currency &&
141  p.getIssuerID() == issuer)
142  return true;
143  }
144 
145  return false;
146 }
147 
149 {
151 
152  for (auto it : mPath)
153  {
155  auto const iType = it.getNodeType();
156 
157  elem[jss::type] = iType;
158 
159  if (iType & STPathElement::typeAccount)
160  elem[jss::account] = to_string(it.getAccountID());
161 
162  if (iType & STPathElement::typeCurrency)
163  elem[jss::currency] = to_string(it.getCurrency());
164 
165  if (iType & STPathElement::typeIssuer)
166  elem[jss::issuer] = to_string(it.getIssuerID());
167 
168  ret.append(elem);
169  }
170 
171  return ret;
172 }
173 
176 {
178  for (auto it : value)
179  ret.append(it.getJson(options));
180 
181  return ret;
182 }
183 
184 void
186 {
187  assert(fName->isBinary());
188  assert(fName->fieldType == STI_PATHSET);
189  bool first = true;
190 
191  for (auto const& spPath : value)
192  {
193  if (!first)
195 
196  for (auto const& speElement : spPath)
197  {
198  int iType = speElement.getNodeType();
199 
200  s.add8(iType);
201 
202  if (iType & STPathElement::typeAccount)
203  s.addBitString(speElement.getAccountID());
204 
205  if (iType & STPathElement::typeCurrency)
206  s.addBitString(speElement.getCurrency());
207 
208  if (iType & STPathElement::typeIssuer)
209  s.addBitString(speElement.getIssuerID());
210  }
211 
212  first = false;
213  }
214 
216 }
217 
218 } // 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:30
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:166
ripple::STPathElement::typeBoundary
@ typeBoundary
Definition: STPathSet.h:42
ripple::STPathElement::getCurrency
Currency const & getCurrency() const
Definition: STPathSet.h:177
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:126
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:362
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::SerialIter::get160
uint160 get160()
Definition: Serializer.h:370
ripple::STPathElement::getIssuerID
AccountID const & getIssuerID() const
Definition: STPathSet.h:183
ripple::STPathSet::add
void add(Serializer &s) const override
Definition: STPathSet.cpp:185
ripple::STPathElement::getAccountID
AccountID const & getAccountID() const
Definition: STPathSet.h:171
ripple::SerialIter
Definition: Serializer.h:310
ripple::STPath::getJson
Json::Value getJson(JsonOptions) const
Definition: STPathSet.cpp:148
ripple::Serializer
Definition: Serializer.h:39
ripple::STPath::hasSeen
bool hasSeen(AccountID const &account, Currency const &currency, AccountID const &issuer) const
Definition: STPathSet.cpp:133
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:175
ripple::STPathElement::typeAccount
@ typeAccount
Definition: STPathSet.h:38
ripple::STBase::fName
SField const * fName
Definition: STBase.h:145
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:38
ripple::STPathSet::assembleAdd
bool assembleAdd(STPath const &base, STPathElement const &tail)
Definition: STPathSet.cpp:105
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