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