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