rippled
SHAMapTreeNode.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/Slice.h>
22 #include <ripple/basics/contract.h>
23 #include <ripple/basics/safe_cast.h>
24 #include <ripple/beast/core/LexicalCast.h>
25 #include <ripple/protocol/HashPrefix.h>
26 #include <ripple/protocol/digest.h>
27 #include <ripple/shamap/SHAMapTreeNode.h>
28 #include <mutex>
29 
30 #include <openssl/sha.h>
31 
32 namespace ripple {
33 
35 
37 
40 {
41  auto p = std::make_shared<SHAMapInnerNode>(seq);
42  p->mHash = mHash;
43  p->mIsBranch = mIsBranch;
44  p->mFullBelowGen = mFullBelowGen;
45  p->mHashes = mHashes;
47  for (int i = 0; i < 16; ++i)
48  p->mChildren[i] = mChildren[i];
49  return p;
50 }
51 
54 {
55  return std::make_shared<SHAMapTreeNode>(mItem, mType, seq, mHash);
56 }
57 
60  TNType type,
61  std::uint32_t seq)
62  : SHAMapAbstractNode(type, seq), mItem(std::move(item))
63 {
64  assert(mItem->peekData().size() >= 12);
65  updateHash();
66 }
67 
70  TNType type,
71  std::uint32_t seq,
72  SHAMapHash const& hash)
73  : SHAMapAbstractNode(type, seq, hash), mItem(std::move(item))
74 {
75  assert(mItem->peekData().size() >= 12);
76 }
77 
80  Slice data,
81  std::uint32_t seq,
82  SHAMapHash const& hash,
83  bool hashValid)
84 {
85  // FIXME: using a Serializer results in a copy; avoid it?
86  Serializer s(data.begin(), data.size());
87 
88  auto item = std::make_shared<SHAMapItem const>(
90 
91  if (hashValid)
92  return std::make_shared<SHAMapTreeNode>(
93  std::move(item), tnTRANSACTION_NM, seq, hash);
94 
95  return std::make_shared<SHAMapTreeNode>(
96  std::move(item), tnTRANSACTION_NM, seq);
97 }
98 
101  Slice data,
102  std::uint32_t seq,
103  SHAMapHash const& hash,
104  bool hashValid)
105 {
106  Serializer s(data.data(), data.size());
107 
108  uint256 tag;
109 
110  if (s.size() < tag.bytes)
111  Throw<std::runtime_error>("Short TXN+MD node");
112 
113  // FIXME: improve this interface so that the above check isn't needed
114  if (!s.getBitString(tag, s.size() - tag.bytes))
115  Throw<std::out_of_range>(
116  "Short TXN+MD node (" + std::to_string(s.size()) + ")");
117 
118  s.chop(tag.bytes);
119 
120  auto item = std::make_shared<SHAMapItem const>(tag, s.peekData());
121 
122  if (hashValid)
123  return std::make_shared<SHAMapTreeNode>(
124  std::move(item), tnTRANSACTION_MD, seq, hash);
125 
126  return std::make_shared<SHAMapTreeNode>(
127  std::move(item), tnTRANSACTION_MD, seq);
128 }
129 
132  Slice data,
133  std::uint32_t seq,
134  SHAMapHash const& hash,
135  bool hashValid)
136 {
137  Serializer s(data.data(), data.size());
138 
139  uint256 tag;
140 
141  if (s.size() < tag.bytes)
142  Throw<std::runtime_error>("short AS node");
143 
144  // FIXME: improve this interface so that the above check isn't needed
145  if (!s.getBitString(tag, s.size() - tag.bytes))
146  Throw<std::out_of_range>(
147  "Short AS node (" + std::to_string(s.size()) + ")");
148 
149  s.chop(tag.bytes);
150 
151  if (tag.isZero())
152  Throw<std::runtime_error>("Invalid AS node");
153 
154  auto item = std::make_shared<SHAMapItem const>(tag, s.peekData());
155 
156  if (hashValid)
157  return std::make_shared<SHAMapTreeNode>(
158  std::move(item), tnACCOUNT_STATE, seq, hash);
159 
160  return std::make_shared<SHAMapTreeNode>(
161  std::move(item), tnACCOUNT_STATE, seq);
162 }
163 
166  Slice data,
167  std::uint32_t seq,
168  SHAMapHash const& hash,
169  bool hashValid)
170 {
171  if (data.size() != 512)
172  Throw<std::runtime_error>("Invalid FI node");
173 
174  auto ret = std::make_shared<SHAMapInnerNode>(seq);
175 
176  Serializer s(data.data(), data.size());
177 
178  for (int i = 0; i < 16; ++i)
179  {
180  s.getBitString(ret->mHashes[i].as_uint256(), i * 32);
181 
182  if (ret->mHashes[i].isNonZero())
183  ret->mIsBranch |= (1 << i);
184  }
185 
186  if (hashValid)
187  ret->mHash = hash;
188  else
189  ret->updateHash();
190  return ret;
191 }
192 
195 {
196  Serializer s(data.data(), data.size());
197 
198  int len = s.getLength();
199 
200  auto ret = std::make_shared<SHAMapInnerNode>(seq);
201 
202  for (int i = 0; i < (len / 33); ++i)
203  {
204  int pos;
205 
206  if (!s.get8(pos, 32 + (i * 33)))
207  Throw<std::runtime_error>("short CI node");
208 
209  if ((pos < 0) || (pos >= 16))
210  Throw<std::runtime_error>("invalid CI node");
211 
212  s.getBitString(ret->mHashes[pos].as_uint256(), i * 33);
213 
214  if (ret->mHashes[pos].isNonZero())
215  ret->mIsBranch |= (1 << pos);
216  }
217 
218  ret->updateHash();
219 
220  return ret;
221 }
222 
225 {
226  if (rawNode.empty())
227  return {};
228 
229  auto const type = rawNode[rawNode.size() - 1];
230 
231  rawNode.remove_suffix(1);
232 
233  bool const hashValid = false;
234  SHAMapHash const hash;
235 
236  std::uint32_t const seq = 0;
237 
238  if (type == 0)
239  return makeTransaction(rawNode, seq, hash, hashValid);
240 
241  if (type == 1)
242  return makeAccountState(rawNode, seq, hash, hashValid);
243 
244  if (type == 2)
245  return SHAMapInnerNode::makeFullInner(rawNode, seq, hash, hashValid);
246 
247  if (type == 3)
248  return SHAMapInnerNode::makeCompressedInner(rawNode, seq);
249 
250  if (type == 4)
251  return makeTransactionWithMeta(rawNode, seq, hash, hashValid);
252 
253  Throw<std::runtime_error>(
254  "wire: Unknown type (" + std::to_string(type) + ")");
255 }
256 
259 {
260  if (rawNode.size() < 4)
261  Throw<std::runtime_error>("prefix: short node");
262 
263  // FIXME: Use SerialIter::get32?
264  // Extract the prefix
265  auto const type = safe_cast<HashPrefix>(
266  (safe_cast<std::uint32_t>(rawNode[0]) << 24) +
267  (safe_cast<std::uint32_t>(rawNode[1]) << 16) +
268  (safe_cast<std::uint32_t>(rawNode[2]) << 8) +
269  (safe_cast<std::uint32_t>(rawNode[3])));
270 
271  rawNode.remove_prefix(4);
272 
273  bool const hashValid = true;
274  std::uint32_t const seq = 0;
275 
276  if (type == HashPrefix::transactionID)
277  return makeTransaction(rawNode, seq, hash, hashValid);
278 
279  if (type == HashPrefix::leafNode)
280  return makeAccountState(rawNode, seq, hash, hashValid);
281 
282  if (type == HashPrefix::innerNode)
283  return SHAMapInnerNode::makeFullInner(rawNode, seq, hash, hashValid);
284 
285  if (type == HashPrefix::txNode)
286  return makeTransactionWithMeta(rawNode, seq, hash, hashValid);
287 
288  Throw<std::runtime_error>(
289  "prefix: unknown type (" +
291  ")");
292 }
293 
294 bool
296 {
297  uint256 nh;
298  if (mIsBranch != 0)
299  {
301  using beast::hash_append;
303  for (auto const& hh : mHashes)
304  hash_append(h, hh);
305  nh = static_cast<typename sha512_half_hasher::result_type>(h);
306  }
307  if (nh == mHash.as_uint256())
308  return false;
309  mHash = SHAMapHash{nh};
310  return true;
311 }
312 
313 void
315 {
316  for (auto pos = 0; pos < 16; ++pos)
317  {
318  if (mChildren[pos] != nullptr)
319  mHashes[pos] = mChildren[pos]->getNodeHash();
320  }
321  updateHash();
322 }
323 
324 bool
326 {
327  uint256 nh;
328  if (mType == tnTRANSACTION_NM)
329  {
330  nh =
332  }
333  else if (mType == tnACCOUNT_STATE)
334  {
335  nh = sha512Half(
336  HashPrefix::leafNode, makeSlice(mItem->peekData()), mItem->key());
337  }
338  else if (mType == tnTRANSACTION_MD)
339  {
340  nh = sha512Half(
341  HashPrefix::txNode, makeSlice(mItem->peekData()), mItem->key());
342  }
343  else
344  assert(false);
345 
346  if (nh == mHash.as_uint256())
347  return false;
348 
349  mHash = SHAMapHash{nh};
350  return true;
351 }
352 
353 void
355 {
356  assert((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH));
357 
358  if (mType == tnERROR)
359  Throw<std::runtime_error>("invalid I node type");
360 
361  if (format == snfHASH)
362  {
364  }
365  else if (mType == tnINNER)
366  {
367  assert(!isEmpty());
368 
369  if (format == snfPREFIX)
370  {
372 
373  for (auto const& hh : mHashes)
374  s.addBitString(hh.as_uint256());
375  }
376  else // format == snfWIRE
377  {
378  if (getBranchCount() < 12)
379  {
380  // compressed node
381  for (int i = 0; i < mHashes.size(); ++i)
382  if (!isEmptyBranch(i))
383  {
384  s.addBitString(mHashes[i].as_uint256());
385  s.add8(i);
386  }
387 
388  s.add8(3);
389  }
390  else
391  {
392  for (auto const& hh : mHashes)
393  s.addBitString(hh.as_uint256());
394 
395  s.add8(2);
396  }
397  }
398  }
399  else
400  assert(false);
401 }
402 
403 void
405 {
406  assert((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH));
407 
408  if (mType == tnERROR)
409  Throw<std::runtime_error>("invalid I node type");
410 
411  if (format == snfHASH)
412  {
414  }
415  else if (mType == tnACCOUNT_STATE)
416  {
417  if (format == snfPREFIX)
418  {
420  s.addRaw(mItem->peekData());
421  s.addBitString(mItem->key());
422  }
423  else
424  {
425  s.addRaw(mItem->peekData());
426  s.addBitString(mItem->key());
427  s.add8(1);
428  }
429  }
430  else if (mType == tnTRANSACTION_NM)
431  {
432  if (format == snfPREFIX)
433  {
435  s.addRaw(mItem->peekData());
436  }
437  else
438  {
439  s.addRaw(mItem->peekData());
440  s.add8(0);
441  }
442  }
443  else if (mType == tnTRANSACTION_MD)
444  {
445  if (format == snfPREFIX)
446  {
448  s.addRaw(mItem->peekData());
449  s.addBitString(mItem->key());
450  }
451  else
452  {
453  s.addRaw(mItem->peekData());
454  s.addBitString(mItem->key());
455  s.add8(4);
456  }
457  }
458  else
459  assert(false);
460 }
461 
462 bool
464 {
465  mType = type;
466  mItem = std::move(i);
467  assert(isLeaf());
468  assert(mSeq != 0);
469  return updateHash();
470 }
471 
472 bool
474 {
475  return mIsBranch == 0;
476 }
477 
478 int
480 {
481  assert(isInner());
482  int count = 0;
483 
484  for (int i = 0; i < 16; ++i)
485  if (!isEmptyBranch(i))
486  ++count;
487 
488  return count;
489 }
490 
493 {
494  std::string ret = "NodeID(";
495  ret += beast::lexicalCastThrow<std::string>(id.getDepth());
496  ret += ",";
497  ret += to_string(id.getNodeID());
498  ret += ")";
499  return ret;
500 }
501 
504 {
506  for (int i = 0; i < mHashes.size(); ++i)
507  {
508  if (!isEmptyBranch(i))
509  {
510  ret += "\nb";
511  ret += beast::lexicalCastThrow<std::string>(i);
512  ret += " = ";
513  ret += to_string(mHashes[i]);
514  }
515  }
516  return ret;
517 }
518 
521 {
523  if (mType == tnTRANSACTION_NM)
524  ret += ",txn\n";
525  else if (mType == tnTRANSACTION_MD)
526  ret += ",txn+md\n";
527  else if (mType == tnACCOUNT_STATE)
528  ret += ",as\n";
529  else
530  ret += ",leaf\n";
531 
532  ret += " Tag=";
533  ret += to_string(peekItem()->key());
534  ret += "\n Hash=";
535  ret += to_string(mHash);
536  ret += "/";
537  ret += beast::lexicalCast<std::string>(mItem->size());
538  return ret;
539 }
540 
541 // We are modifying an inner node
542 void
544  int m,
546 {
547  assert((m >= 0) && (m < 16));
548  assert(mType == tnINNER);
549  assert(mSeq != 0);
550  assert(child.get() != this);
551  mHashes[m].zero();
552  mHash.zero();
553  if (child)
554  mIsBranch |= (1 << m);
555  else
556  mIsBranch &= ~(1 << m);
557  mChildren[m] = child;
558 }
559 
560 // finished modifying, now make shareable
561 void
563  int m,
565 {
566  assert((m >= 0) && (m < 16));
567  assert(mType == tnINNER);
568  assert(mSeq != 0);
569  assert(child);
570  assert(child.get() != this);
571 
572  mChildren[m] = child;
573 }
574 
577 {
578  assert(branch >= 0 && branch < 16);
579  assert(isInner());
580 
582  return mChildren[branch].get();
583 }
584 
587 {
588  assert(branch >= 0 && branch < 16);
589  assert(isInner());
590 
592  return mChildren[branch];
593 }
594 
597  int branch,
599 {
600  assert(branch >= 0 && branch < 16);
601  assert(isInner());
602  assert(node);
603  assert(node->getNodeHash() == mHashes[branch]);
604 
606  if (mChildren[branch])
607  {
608  // There is already a node hooked up, return it
609  node = mChildren[branch];
610  }
611  else
612  {
613  // Hook this node up
614  mChildren[branch] = node;
615  }
616  return node;
617 }
618 
619 uint256 const&
621 {
622  Throw<std::logic_error>("SHAMapInnerNode::key() should never be called");
623  static uint256 x;
624  return x;
625 }
626 
627 uint256 const&
629 {
630  return mItem->key();
631 }
632 
633 void
634 SHAMapInnerNode::invariants(bool is_root) const
635 {
636  assert(mType == tnINNER);
637  unsigned count = 0;
638  for (int i = 0; i < 16; ++i)
639  {
640  if (mHashes[i].isNonZero())
641  {
642  assert((mIsBranch & (1 << i)) != 0);
643  if (mChildren[i] != nullptr)
644  mChildren[i]->invariants();
645  ++count;
646  }
647  else
648  {
649  assert((mIsBranch & (1 << i)) == 0);
650  }
651  }
652  if (!is_root)
653  {
654  assert(mHash.isNonZero());
655  assert(count >= 1);
656  }
657  assert((count == 0) ? mHash.isZero() : mHash.isNonZero());
658 }
659 
660 void
662 {
663  assert(mType >= tnTRANSACTION_NM);
664  assert(mHash.isNonZero());
665  assert(mItem != nullptr);
666 }
667 
668 } // namespace ripple
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:79
ripple::SHAMapAbstractNode::makeFromPrefix
static std::shared_ptr< SHAMapAbstractNode > makeFromPrefix(Slice rawNode, SHAMapHash const &hash)
Definition: SHAMapTreeNode.cpp:258
ripple::SHAMapTreeNode::SHAMapTreeNode
SHAMapTreeNode(const SHAMapTreeNode &)=delete
ripple::SHAMapAbstractNode::mHash
SHAMapHash mHash
Definition: SHAMapTreeNode.h:135
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:240
ripple::Serializer::chop
bool chop(int num)
Definition: Serializer.cpp:176
ripple::SHAMapInnerNode::makeFullInner
static std::shared_ptr< SHAMapAbstractNode > makeFullInner(Slice data, std::uint32_t seq, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:165
std::string
STL class.
std::shared_ptr
STL class.
ripple::SHAMapAbstractNode::tnACCOUNT_STATE
@ tnACCOUNT_STATE
Definition: SHAMapTreeNode.h:130
ripple::HashPrefix::txNode
@ txNode
transaction plus metadata
ripple::SHAMapInnerNode::mHashes
std::array< SHAMapHash, 16 > mHashes
Definition: SHAMapTreeNode.h:209
ripple::detail::basic_sha512_half_hasher
Returns the SHA512-Half digest of a message.
Definition: digest.h:175
ripple::SHAMapAbstractNode::tnTRANSACTION_NM
@ tnTRANSACTION_NM
Definition: SHAMapTreeNode.h:128
ripple::SHAMapTreeNode::addRaw
void addRaw(Serializer &, SHANodeFormat format) const override
Definition: SHAMapTreeNode.cpp:404
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::SHAMapTreeNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:325
ripple::SHAMapInnerNode::mFullBelowGen
std::uint32_t mFullBelowGen
Definition: SHAMapTreeNode.h:212
ripple::snfPREFIX
@ snfPREFIX
Definition: SHAMapTreeNode.h:36
ripple::Serializer::add8
int add8(unsigned char i)
Definition: Serializer.cpp:158
ripple::SHAMapInnerNode::key
uint256 const & key() const override
Definition: SHAMapTreeNode.cpp:620
std::lock_guard
STL class.
ripple::SHAMapHash::isZero
bool isZero() const
Definition: SHAMapTreeNode.h:64
ripple::SHAMapAbstractNode::getString
virtual std::string getString(SHAMapNodeID const &) const
Definition: SHAMapTreeNode.cpp:492
ripple::SHAMapInnerNode::addRaw
void addRaw(Serializer &, SHANodeFormat format) const override
Definition: SHAMapTreeNode.cpp:354
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::SHAMapNodeID
Definition: SHAMapNodeID.h:33
ripple::SHAMapHash::isNonZero
bool isNonZero() const
Definition: SHAMapTreeNode.h:69
ripple::Slice::empty
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:68
ripple::SHAMapInnerNode::getChildPointer
SHAMapAbstractNode * getChildPointer(int branch)
Definition: SHAMapTreeNode.cpp:576
ripple::SHAMapHash
Definition: SHAMapTreeNode.h:43
ripple::SHAMapInnerNode::clone
std::shared_ptr< SHAMapAbstractNode > clone(std::uint32_t seq) const override
Definition: SHAMapTreeNode.cpp:39
ripple::SHAMapInnerNode::setChild
void setChild(int m, std::shared_ptr< SHAMapAbstractNode > const &child)
Definition: SHAMapTreeNode.cpp:543
std::underlying_type_t
ripple::SHAMapInnerNode::isEmptyBranch
bool isEmptyBranch(int m) const
Definition: SHAMapTreeNode.h:390
ripple::SHAMapAbstractNode::makeTransaction
static std::shared_ptr< SHAMapAbstractNode > makeTransaction(Slice data, std::uint32_t seq, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:79
ripple::base_uint< 256 >
ripple::SHAMapInnerNode::getString
std::string getString(SHAMapNodeID const &) const override
Definition: SHAMapTreeNode.cpp:503
ripple::SHAMapTreeNode::key
uint256 const & key() const override
Definition: SHAMapTreeNode.cpp:628
ripple::SHAMapTreeNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:661
ripple::SHAMapAbstractNode::isInner
bool isInner() const
Definition: SHAMapTreeNode.h:364
ripple::HashPrefix::innerNode
@ innerNode
inner node in V1 tree
ripple::base_uint::bytes
static constexpr std::size_t bytes
Definition: base_uint.h:86
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:475
ripple::SHAMapInnerNode::makeCompressedInner
static std::shared_ptr< SHAMapAbstractNode > makeCompressedInner(Slice data, std::uint32_t seq)
Definition: SHAMapTreeNode.cpp:194
ripple::SHAMapInnerNode::canonicalizeChild
virtual std::shared_ptr< SHAMapAbstractNode > canonicalizeChild(int branch, std::shared_ptr< SHAMapAbstractNode > node)
Definition: SHAMapTreeNode.cpp:596
ripple::safe_cast
constexpr std::enable_if_t< std::is_same_v< typename Dest::unit_type, typename Src::unit_type > &&std::is_integral_v< typename Dest::value_type > &&std::is_integral_v< typename Src::value_type >, Dest > safe_cast(Src s) noexcept
Definition: FeeUnits.h:537
ripple::SHAMapAbstractNode::mType
TNType mType
Definition: SHAMapTreeNode.h:134
ripple::Serializer::addRaw
int addRaw(Blob const &vector)
Definition: Serializer.cpp:100
std::to_string
T to_string(T... args)
ripple::Serializer::get8
bool get8(int &, int offset) const
Definition: Serializer.cpp:166
ripple::SHAMapInnerNode::updateHashDeep
void updateHashDeep()
Definition: SHAMapTreeNode.cpp:314
ripple::SHAMapTreeNode::setItem
bool setItem(std::shared_ptr< SHAMapItem const > i, TNType type)
Definition: SHAMapTreeNode.cpp:463
ripple::HashPrefix::transactionID
@ transactionID
transaction plus signature to give transaction ID
ripple::SHAMapInnerNode::getBranchCount
int getBranchCount() const
Definition: SHAMapTreeNode.cpp:479
std::uint32_t
ripple::SHAMapAbstractNode::TNType
TNType
Definition: SHAMapTreeNode.h:125
ripple::SHAMapAbstractNode::isLeaf
bool isLeaf() const
Definition: SHAMapTreeNode.h:357
ripple::HashPrefix::leafNode
@ leafNode
account state
ripple::SHAMapTreeNode::mItem
std::shared_ptr< SHAMapItem const > mItem
Definition: SHAMapTreeNode.h:276
ripple::Serializer
Definition: Serializer.h:39
ripple::snfHASH
@ snfHASH
Definition: SHAMapTreeNode.h:38
ripple::SHAMapInnerNode::shareChild
void shareChild(int m, std::shared_ptr< SHAMapAbstractNode > const &child)
Definition: SHAMapTreeNode.cpp:562
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::Serializer::getBitString
bool getBitString(base_uint< Bits, Tag > &data, int offset) const
Definition: Serializer.h:144
ripple::SHAMapAbstractNode::makeFromWire
static std::shared_ptr< SHAMapAbstractNode > makeFromWire(Slice rawNode)
Definition: SHAMapTreeNode.cpp:224
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::SHAMapInnerNode::mIsBranch
int mIsBranch
Definition: SHAMapTreeNode.h:211
ripple::SHAMapTreeNode::getString
std::string getString(SHAMapNodeID const &) const override
Definition: SHAMapTreeNode.cpp:520
ripple::SHAMapHash::zero
void zero()
Definition: SHAMapTreeNode.h:79
ripple::SHAMapAbstractNode::mSeq
std::uint32_t mSeq
Definition: SHAMapTreeNode.h:136
std
STL namespace.
beast::hash_append
std::enable_if_t< is_contiguously_hashable< T, Hasher >::value > hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
Definition: hash_append.h:232
ripple::sha512Half
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:227
ripple::Serializer::peekData
Blob const & peekData() const
Definition: Serializer.h:166
ripple::Slice::remove_prefix
void remove_prefix(std::size_t n)
Shrinks the slice by moving its start forward by n characters.
Definition: Slice.h:131
ripple::snfWIRE
@ snfWIRE
Definition: SHAMapTreeNode.h:37
ripple::hash_append
void hash_append(Hasher &h, Slice const &v)
Definition: Slice.h:195
ripple::SHAMapInnerNode::childLock
static std::mutex childLock
Definition: SHAMapTreeNode.h:214
ripple::SHAMapAbstractNode
Definition: SHAMapTreeNode.h:122
ripple::SHAMapAbstractNode::tnTRANSACTION_MD
@ tnTRANSACTION_MD
Definition: SHAMapTreeNode.h:129
mutex
ripple::SHAMapAbstractNode::tnERROR
@ tnERROR
Definition: SHAMapTreeNode.h:126
ripple::Serializer::add32
int add32(std::uint32_t i)
Definition: Serializer.cpp:38
ripple::SHAMapInnerNode::isEmpty
bool isEmpty() const
Definition: SHAMapTreeNode.cpp:473
ripple::SHAMapInnerNode::mChildren
std::shared_ptr< SHAMapAbstractNode > mChildren[16]
Definition: SHAMapTreeNode.h:210
ripple::SHAMapHash::as_uint256
uint256 const & as_uint256() const
Definition: SHAMapTreeNode.h:54
ripple::Serializer::getLength
int getLength() const
Definition: Serializer.h:197
ripple::Slice::remove_suffix
void remove_suffix(std::size_t n)
Shrinks the slice by moving its end backward by n characters.
Definition: Slice.h:139
ripple::SHAMapInnerNode::getChild
std::shared_ptr< SHAMapAbstractNode > getChild(int branch)
Definition: SHAMapTreeNode.cpp:586
ripple::SHAMapInnerNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:295
ripple::SHAMapAbstractNode::tnINNER
@ tnINNER
Definition: SHAMapTreeNode.h:127
ripple::SHAMapAbstractNode::makeAccountState
static std::shared_ptr< SHAMapAbstractNode > makeAccountState(Slice data, std::uint32_t seq, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:131
ripple::SHAMapAbstractNode::makeTransactionWithMeta
static std::shared_ptr< SHAMapAbstractNode > makeTransactionWithMeta(Slice data, std::uint32_t seq, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:100
ripple::SHAMapInnerNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:634
ripple::SHAMapAbstractNode::~SHAMapAbstractNode
virtual ~SHAMapAbstractNode()=0
ripple::SHANodeFormat
SHANodeFormat
Definition: SHAMapTreeNode.h:35
ripple::SHAMapTreeNode::clone
std::shared_ptr< SHAMapAbstractNode > clone(std::uint32_t seq) const override
Definition: SHAMapTreeNode.cpp:53
ripple::SHAMapTreeNode::peekItem
std::shared_ptr< SHAMapItem const > const & peekItem() const
Definition: SHAMapTreeNode.h:423