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(item)
63 {
64  assert(item->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(item)
74 {
75  assert(item->peekData().size() >= 12);
76 }
77 
80  Slice const& rawNode,
81  std::uint32_t seq,
82  SHANodeFormat format,
83  SHAMapHash const& hash,
84  bool hashValid,
86  SHAMapNodeID const& id)
87 {
88  if (format == snfWIRE)
89  {
90  if (rawNode.empty())
91  return {};
92 
93  Serializer s(rawNode.data(), rawNode.size() - 1);
94  int type = rawNode[rawNode.size() - 1];
95  int len = s.getLength();
96 
97  if ((type < 0) || (type > 6))
98  return {};
99  if (type == 0)
100  {
101  // transaction
102  auto item = std::make_shared<SHAMapItem const>(
103  sha512Half(
105  s.peekData());
106  if (hashValid)
107  return std::make_shared<SHAMapTreeNode>(
108  item, tnTRANSACTION_NM, seq, hash);
109  return std::make_shared<SHAMapTreeNode>(
110  item, tnTRANSACTION_NM, seq);
111  }
112  else if (type == 1)
113  {
114  // account state
115  if (len < (256 / 8))
116  Throw<std::runtime_error>("short AS node");
117 
118  uint256 u;
119  s.getBitString(u, len - (256 / 8));
120  s.chop(256 / 8);
121 
122  if (u.isZero())
123  Throw<std::runtime_error>("invalid AS node");
124 
125  auto item = std::make_shared<SHAMapItem const>(u, s.peekData());
126  if (hashValid)
127  return std::make_shared<SHAMapTreeNode>(
128  item, tnACCOUNT_STATE, seq, hash);
129  return std::make_shared<SHAMapTreeNode>(item, tnACCOUNT_STATE, seq);
130  }
131  else if (type == 2)
132  {
133  // full inner
134  if (len != 512)
135  Throw<std::runtime_error>("invalid FI node");
136 
137  auto ret = std::make_shared<SHAMapInnerNode>(seq);
138  for (int i = 0; i < 16; ++i)
139  {
140  s.getBitString(ret->mHashes[i].as_uint256(), i * 32);
141 
142  if (ret->mHashes[i].isNonZero())
143  ret->mIsBranch |= (1 << i);
144  }
145  if (hashValid)
146  ret->mHash = hash;
147  else
148  ret->updateHash();
149  return ret;
150  }
151  else if (type == 3)
152  {
153  auto ret = std::make_shared<SHAMapInnerNode>(seq);
154  // compressed inner
155  for (int i = 0; i < (len / 33); ++i)
156  {
157  int pos;
158  if (!s.get8(pos, 32 + (i * 33)))
159  Throw<std::runtime_error>("short CI node");
160  if ((pos < 0) || (pos >= 16))
161  Throw<std::runtime_error>("invalid CI node");
162  s.getBitString(ret->mHashes[pos].as_uint256(), i * 33);
163  if (ret->mHashes[pos].isNonZero())
164  ret->mIsBranch |= (1 << pos);
165  }
166  if (hashValid)
167  ret->mHash = hash;
168  else
169  ret->updateHash();
170  return ret;
171  }
172  else if (type == 4)
173  {
174  // transaction with metadata
175  if (len < (256 / 8))
176  Throw<std::runtime_error>("short TM node");
177 
178  uint256 u;
179  s.getBitString(u, len - (256 / 8));
180  s.chop(256 / 8);
181 
182  if (u.isZero())
183  Throw<std::runtime_error>("invalid TM node");
184 
185  auto item = std::make_shared<SHAMapItem const>(u, s.peekData());
186  if (hashValid)
187  return std::make_shared<SHAMapTreeNode>(
188  item, tnTRANSACTION_MD, seq, hash);
189  return std::make_shared<SHAMapTreeNode>(
190  item, tnTRANSACTION_MD, seq);
191  }
192  }
193 
194  else if (format == snfPREFIX)
195  {
196  if (rawNode.size() < 4)
197  {
198  JLOG(j.info()) << "size < 4";
199  Throw<std::runtime_error>("invalid P node");
200  }
201 
202  std::uint32_t prefix = rawNode[0];
203  prefix <<= 8;
204  prefix |= rawNode[1];
205  prefix <<= 8;
206  prefix |= rawNode[2];
207  prefix <<= 8;
208  prefix |= rawNode[3];
209  Serializer s(rawNode.data() + 4, rawNode.size() - 4);
210 
211  if (safe_cast<HashPrefix>(prefix) == HashPrefix::transactionID)
212  {
213  auto item = std::make_shared<SHAMapItem const>(
214  sha512Half(rawNode), s.peekData());
215  if (hashValid)
216  return std::make_shared<SHAMapTreeNode>(
217  item, tnTRANSACTION_NM, seq, hash);
218  return std::make_shared<SHAMapTreeNode>(
219  item, tnTRANSACTION_NM, seq);
220  }
221  else if (safe_cast<HashPrefix>(prefix) == HashPrefix::leafNode)
222  {
223  if (s.getLength() < 32)
224  Throw<std::runtime_error>("short PLN node");
225 
226  uint256 u;
227  s.getBitString(u, s.getLength() - 32);
228  s.chop(32);
229 
230  if (u.isZero())
231  {
232  JLOG(j.info()) << "invalid PLN node";
233  Throw<std::runtime_error>("invalid PLN node");
234  }
235 
236  auto item = std::make_shared<SHAMapItem const>(u, s.peekData());
237  if (hashValid)
238  return std::make_shared<SHAMapTreeNode>(
239  item, tnACCOUNT_STATE, seq, hash);
240  return std::make_shared<SHAMapTreeNode>(item, tnACCOUNT_STATE, seq);
241  }
242  else if (safe_cast<HashPrefix>(prefix) == HashPrefix::innerNode)
243  {
244  auto len = s.getLength();
245 
246  if (len != 512)
247  Throw<std::runtime_error>("invalid PIN node");
248 
249  auto ret = std::make_shared<SHAMapInnerNode>(seq);
250 
251  for (int i = 0; i < 16; ++i)
252  {
253  s.getBitString(ret->mHashes[i].as_uint256(), i * 32);
254 
255  if (ret->mHashes[i].isNonZero())
256  ret->mIsBranch |= (1 << i);
257  }
258 
259  if (hashValid)
260  ret->mHash = hash;
261  else
262  ret->updateHash();
263  return ret;
264  }
265  else if (safe_cast<HashPrefix>(prefix) == HashPrefix::txNode)
266  {
267  // transaction with metadata
268  if (s.getLength() < 32)
269  Throw<std::runtime_error>("short TXN node");
270 
271  uint256 txID;
272  s.getBitString(txID, s.getLength() - 32);
273  s.chop(32);
274  auto item = std::make_shared<SHAMapItem const>(txID, s.peekData());
275  if (hashValid)
276  return std::make_shared<SHAMapTreeNode>(
277  item, tnTRANSACTION_MD, seq, hash);
278  return std::make_shared<SHAMapTreeNode>(
279  item, tnTRANSACTION_MD, seq);
280  }
281  else
282  {
283  JLOG(j.info()) << "Unknown node prefix " << std::hex << prefix
284  << std::dec;
285  Throw<std::runtime_error>("invalid node prefix");
286  }
287  }
288  assert(false);
289  Throw<std::runtime_error>("Unknown format");
290  return {}; // Silence compiler warning.
291 }
292 
293 bool
295 {
296  uint256 nh;
297  if (mIsBranch != 0)
298  {
300  using beast::hash_append;
302  for (auto const& hh : mHashes)
303  hash_append(h, hh);
304  nh = static_cast<typename sha512_half_hasher::result_type>(h);
305  }
306  if (nh == mHash.as_uint256())
307  return false;
308  mHash = SHAMapHash{nh};
309  return true;
310 }
311 
312 void
314 {
315  for (auto pos = 0; pos < 16; ++pos)
316  {
317  if (mChildren[pos] != nullptr)
318  mHashes[pos] = mChildren[pos]->getNodeHash();
319  }
320  updateHash();
321 }
322 
323 bool
325 {
326  uint256 nh;
327  if (mType == tnTRANSACTION_NM)
328  {
329  nh =
331  }
332  else if (mType == tnACCOUNT_STATE)
333  {
334  nh = sha512Half(
335  HashPrefix::leafNode, makeSlice(mItem->peekData()), mItem->key());
336  }
337  else if (mType == tnTRANSACTION_MD)
338  {
339  nh = sha512Half(
340  HashPrefix::txNode, makeSlice(mItem->peekData()), mItem->key());
341  }
342  else
343  assert(false);
344 
345  if (nh == mHash.as_uint256())
346  return false;
347 
348  mHash = SHAMapHash{nh};
349  return true;
350 }
351 
352 void
354 {
355  assert((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH));
356 
357  if (mType == tnERROR)
358  Throw<std::runtime_error>("invalid I node type");
359 
360  if (format == snfHASH)
361  {
363  }
364  else if (mType == tnINNER)
365  {
366  assert(!isEmpty());
367 
368  if (format == snfPREFIX)
369  {
371 
372  for (auto const& hh : mHashes)
373  s.addBitString(hh.as_uint256());
374  }
375  else // format == snfWIRE
376  {
377  if (getBranchCount() < 12)
378  {
379  // compressed node
380  for (int i = 0; i < mHashes.size(); ++i)
381  if (!isEmptyBranch(i))
382  {
383  s.addBitString(mHashes[i].as_uint256());
384  s.add8(i);
385  }
386 
387  s.add8(3);
388  }
389  else
390  {
391  for (auto const& hh : mHashes)
392  s.addBitString(hh.as_uint256());
393 
394  s.add8(2);
395  }
396  }
397  }
398  else
399  assert(false);
400 }
401 
402 void
404 {
405  assert((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH));
406 
407  if (mType == tnERROR)
408  Throw<std::runtime_error>("invalid I node type");
409 
410  if (format == snfHASH)
411  {
413  }
414  else if (mType == tnACCOUNT_STATE)
415  {
416  if (format == snfPREFIX)
417  {
419  s.addRaw(mItem->peekData());
420  s.addBitString(mItem->key());
421  }
422  else
423  {
424  s.addRaw(mItem->peekData());
425  s.addBitString(mItem->key());
426  s.add8(1);
427  }
428  }
429  else if (mType == tnTRANSACTION_NM)
430  {
431  if (format == snfPREFIX)
432  {
434  s.addRaw(mItem->peekData());
435  }
436  else
437  {
438  s.addRaw(mItem->peekData());
439  s.add8(0);
440  }
441  }
442  else if (mType == tnTRANSACTION_MD)
443  {
444  if (format == snfPREFIX)
445  {
447  s.addRaw(mItem->peekData());
448  s.addBitString(mItem->key());
449  }
450  else
451  {
452  s.addRaw(mItem->peekData());
453  s.addBitString(mItem->key());
454  s.add8(4);
455  }
456  }
457  else
458  assert(false);
459 }
460 
461 bool
463 {
464  mType = type;
465  mItem = i;
466  assert(isLeaf());
467  assert(mSeq != 0);
468  return updateHash();
469 }
470 
471 bool
473 {
474  return mIsBranch == 0;
475 }
476 
477 int
479 {
480  assert(isInner());
481  int count = 0;
482 
483  for (int i = 0; i < 16; ++i)
484  if (!isEmptyBranch(i))
485  ++count;
486 
487  return count;
488 }
489 
492 {
493  std::string ret = "NodeID(";
494  ret += beast::lexicalCastThrow<std::string>(id.getDepth());
495  ret += ",";
496  ret += to_string(id.getNodeID());
497  ret += ")";
498  return ret;
499 }
500 
503 {
505  for (int i = 0; i < mHashes.size(); ++i)
506  {
507  if (!isEmptyBranch(i))
508  {
509  ret += "\nb";
510  ret += beast::lexicalCastThrow<std::string>(i);
511  ret += " = ";
512  ret += to_string(mHashes[i]);
513  }
514  }
515  return ret;
516 }
517 
520 {
522  if (mType == tnTRANSACTION_NM)
523  ret += ",txn\n";
524  else if (mType == tnTRANSACTION_MD)
525  ret += ",txn+md\n";
526  else if (mType == tnACCOUNT_STATE)
527  ret += ",as\n";
528  else
529  ret += ",leaf\n";
530 
531  ret += " Tag=";
532  ret += to_string(peekItem()->key());
533  ret += "\n Hash=";
534  ret += to_string(mHash);
535  ret += "/";
536  ret += beast::lexicalCast<std::string>(mItem->size());
537  return ret;
538 }
539 
540 // We are modifying an inner node
541 void
543  int m,
545 {
546  assert((m >= 0) && (m < 16));
547  assert(mType == tnINNER);
548  assert(mSeq != 0);
549  assert(child.get() != this);
550  mHashes[m].zero();
551  mHash.zero();
552  if (child)
553  mIsBranch |= (1 << m);
554  else
555  mIsBranch &= ~(1 << m);
556  mChildren[m] = child;
557 }
558 
559 // finished modifying, now make shareable
560 void
562  int m,
564 {
565  assert((m >= 0) && (m < 16));
566  assert(mType == tnINNER);
567  assert(mSeq != 0);
568  assert(child);
569  assert(child.get() != this);
570 
571  mChildren[m] = child;
572 }
573 
576 {
577  assert(branch >= 0 && branch < 16);
578  assert(isInner());
579 
581  return mChildren[branch].get();
582 }
583 
586 {
587  assert(branch >= 0 && branch < 16);
588  assert(isInner());
589 
591  return mChildren[branch];
592 }
593 
596  int branch,
598 {
599  assert(branch >= 0 && branch < 16);
600  assert(isInner());
601  assert(node);
602  assert(node->getNodeHash() == mHashes[branch]);
603 
605  if (mChildren[branch])
606  {
607  // There is already a node hooked up, return it
608  node = mChildren[branch];
609  }
610  else
611  {
612  // Hook this node up
613  mChildren[branch] = node;
614  }
615  return node;
616 }
617 
618 uint256 const&
620 {
621  Throw<std::logic_error>("SHAMapInnerNode::key() should never be called");
622  static uint256 x;
623  return x;
624 }
625 
626 uint256 const&
628 {
629  return mItem->key();
630 }
631 
632 void
633 SHAMapInnerNode::invariants(bool is_root) const
634 {
635  assert(mType == tnINNER);
636  unsigned count = 0;
637  for (int i = 0; i < 16; ++i)
638  {
639  if (mHashes[i].isNonZero())
640  {
641  assert((mIsBranch & (1 << i)) != 0);
642  if (mChildren[i] != nullptr)
643  mChildren[i]->invariants();
644  ++count;
645  }
646  else
647  {
648  assert((mIsBranch & (1 << i)) == 0);
649  }
650  }
651  if (!is_root)
652  {
653  assert(mHash.isNonZero());
654  assert(count >= 1);
655  }
656  assert((count == 0) ? mHash.isZero() : mHash.isNonZero());
657 }
658 
659 void
661 {
662  assert(mType >= tnTRANSACTION_NM);
663  assert(mHash.isNonZero());
664  assert(mItem != nullptr);
665 }
666 
667 } // namespace ripple
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:77
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:194
ripple::Serializer::chop
bool chop(int num)
Definition: Serializer.cpp:176
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:191
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::setItem
bool setItem(std::shared_ptr< SHAMapItem const > const &i, TNType type)
Definition: SHAMapTreeNode.cpp:462
ripple::SHAMapTreeNode::addRaw
void addRaw(Serializer &, SHANodeFormat format) const override
Definition: SHAMapTreeNode.cpp:403
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:43
ripple::SHAMapAbstractNode::make
static std::shared_ptr< SHAMapAbstractNode > make(Slice const &rawNode, std::uint32_t seq, SHANodeFormat format, SHAMapHash const &hash, bool hashValid, beast::Journal j, SHAMapNodeID const &id=SHAMapNodeID{})
Definition: SHAMapTreeNode.cpp:79
ripple::SHAMapTreeNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:324
ripple::SHAMapInnerNode::mFullBelowGen
std::uint32_t mFullBelowGen
Definition: SHAMapTreeNode.h:194
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:619
ripple::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:87
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:491
ripple::SHAMapInnerNode::addRaw
void addRaw(Serializer &, SHANodeFormat format) const override
Definition: SHAMapTreeNode.cpp:353
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
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:67
ripple::SHAMapInnerNode::getChildPointer
SHAMapAbstractNode * getChildPointer(int branch)
Definition: SHAMapTreeNode.cpp:575
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:542
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:75
std::hex
T hex(T... args)
ripple::SHAMapInnerNode::isEmptyBranch
bool isEmptyBranch(int m) const
Definition: SHAMapTreeNode.h:376
ripple::base_uint< 256 >
ripple::SHAMapInnerNode::getString
std::string getString(SHAMapNodeID const &) const override
Definition: SHAMapTreeNode.cpp:502
ripple::SHAMapTreeNode::key
uint256 const & key() const override
Definition: SHAMapTreeNode.cpp:627
ripple::SHAMapTreeNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:660
ripple::SHAMapAbstractNode::isInner
bool isInner() const
Definition: SHAMapTreeNode.h:350
ripple::HashPrefix::innerNode
@ innerNode
inner node in V1 tree
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:475
ripple::SHAMapInnerNode::canonicalizeChild
virtual std::shared_ptr< SHAMapAbstractNode > canonicalizeChild(int branch, std::shared_ptr< SHAMapAbstractNode > node)
Definition: SHAMapTreeNode.cpp:595
ripple::SHAMapAbstractNode::mType
TNType mType
Definition: SHAMapTreeNode.h:134
ripple::Serializer::addRaw
int addRaw(Blob const &vector)
Definition: Serializer.cpp:100
ripple::Serializer::get8
bool get8(int &, int offset) const
Definition: Serializer.cpp:166
ripple::SHAMapInnerNode::updateHashDeep
void updateHashDeep()
Definition: SHAMapTreeNode.cpp:313
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::HashPrefix::transactionID
@ transactionID
transaction plus signature to give transaction ID
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::SHAMapInnerNode::getBranchCount
int getBranchCount() const
Definition: SHAMapTreeNode.cpp:478
std::uint32_t
ripple::SHAMapAbstractNode::TNType
TNType
Definition: SHAMapTreeNode.h:125
ripple::SHAMapAbstractNode::isLeaf
bool isLeaf() const
Definition: SHAMapTreeNode.h:343
ripple::HashPrefix::leafNode
@ leafNode
account state
ripple::SHAMapTreeNode::mItem
std::shared_ptr< SHAMapItem const > mItem
Definition: SHAMapTreeNode.h:258
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:561
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::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::SHAMapInnerNode::mIsBranch
int mIsBranch
Definition: SHAMapTreeNode.h:193
ripple::SHAMapTreeNode::getString
std::string getString(SHAMapNodeID const &) const override
Definition: SHAMapTreeNode.cpp:519
ripple::SHAMapHash::zero
void zero()
Definition: SHAMapTreeNode.h:79
ripple::SHAMapAbstractNode::mSeq
std::uint32_t mSeq
Definition: SHAMapTreeNode.h:136
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::snfWIRE
@ snfWIRE
Definition: SHAMapTreeNode.h:37
ripple::hash_append
void hash_append(Hasher &h, Slice const &v)
Definition: Slice.h:149
ripple::SHAMapInnerNode::childLock
static std::mutex childLock
Definition: SHAMapTreeNode.h:196
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:472
ripple::SHAMapInnerNode::mChildren
std::shared_ptr< SHAMapAbstractNode > mChildren[16]
Definition: SHAMapTreeNode.h:192
ripple::SHAMapHash::as_uint256
uint256 const & as_uint256() const
Definition: SHAMapTreeNode.h:54
ripple::Serializer::getLength
int getLength() const
Definition: Serializer.h:197
ripple::SHAMapInnerNode::getChild
std::shared_ptr< SHAMapAbstractNode > getChild(int branch)
Definition: SHAMapTreeNode.cpp:585
ripple::SHAMapInnerNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:294
ripple::SHAMapAbstractNode::tnINNER
@ tnINNER
Definition: SHAMapTreeNode.h:127
ripple::SHAMapInnerNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:633
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:415