rippled
SHAMapTreeNode.h
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 #ifndef RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
21 #define RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
22 
23 #include <ripple/basics/TaggedCache.h>
24 #include <ripple/beast/utility/Journal.h>
25 #include <ripple/shamap/SHAMapItem.h>
26 #include <ripple/shamap/SHAMapNodeID.h>
27 
28 #include <cstdint>
29 #include <memory>
30 #include <mutex>
31 #include <string>
32 
33 namespace ripple {
34 
36  snfPREFIX = 1, // Form that hashes to its official hash
37  snfWIRE = 2, // Compressed form used on the wire
38  snfHASH = 3, // just the hash
39 };
40 
41 // A SHAMapHash is the hash of a node in a SHAMap, and also the
42 // type of the hash of the entire SHAMap.
44 {
46 
47 public:
48  SHAMapHash() = default;
49  explicit SHAMapHash(uint256 const& hash) : hash_(hash)
50  {
51  }
52 
53  uint256 const&
54  as_uint256() const
55  {
56  return hash_;
57  }
58  uint256&
60  {
61  return hash_;
62  }
63  bool
64  isZero() const
65  {
66  return hash_.isZero();
67  }
68  bool
69  isNonZero() const
70  {
71  return hash_.isNonZero();
72  }
73  int
74  signum() const
75  {
76  return hash_.signum();
77  }
78  void
79  zero()
80  {
81  hash_.zero();
82  }
83 
84  friend bool
85  operator==(SHAMapHash const& x, SHAMapHash const& y)
86  {
87  return x.hash_ == y.hash_;
88  }
89 
90  friend bool
91  operator<(SHAMapHash const& x, SHAMapHash const& y)
92  {
93  return x.hash_ < y.hash_;
94  }
95 
96  friend std::ostream&
98  {
99  return os << x.hash_;
100  }
101 
102  friend std::string
104  {
105  return to_string(x.hash_);
106  }
107 
108  template <class H>
109  friend void
110  hash_append(H& h, SHAMapHash const& x)
111  {
112  hash_append(h, x.hash_);
113  }
114 };
115 
116 inline bool
117 operator!=(SHAMapHash const& x, SHAMapHash const& y)
118 {
119  return !(x == y);
120 }
121 
123 {
124 public:
125  enum TNType {
126  tnERROR = 0,
127  tnINNER = 1,
128  tnTRANSACTION_NM = 2, // transaction, no metadata
129  tnTRANSACTION_MD = 3, // transaction, with metadata
131  };
132 
133 protected:
137 
138 protected:
139  virtual ~SHAMapAbstractNode() = 0;
140  SHAMapAbstractNode(SHAMapAbstractNode const&) = delete;
142  operator=(SHAMapAbstractNode const&) = delete;
143 
145  SHAMapAbstractNode(TNType type, std::uint32_t seq, SHAMapHash const& hash);
146 
147 public:
149  getSeq() const;
150  void
152  SHAMapHash const&
153  getNodeHash() const;
154  TNType
155  getType() const;
156  bool
157  isLeaf() const;
158  bool
159  isInner() const;
160  bool
161  isValid() const;
162  bool
163  isInBounds(SHAMapNodeID const& id) const;
164 
165  virtual bool
166  updateHash() = 0;
167  virtual void
168  addRaw(Serializer&, SHANodeFormat format) const = 0;
169  virtual std::string
170  getString(SHAMapNodeID const&) const;
172  clone(std::uint32_t seq) const = 0;
173  virtual uint256 const&
174  key() const = 0;
175  virtual void
176  invariants(bool is_root = false) const = 0;
177 
179  makeFromPrefix(Slice rawNode, SHAMapHash const& hash);
180 
182  makeFromWire(Slice rawNode);
183 
184 private:
187  Slice data,
188  std::uint32_t seq,
189  SHAMapHash const& hash,
190  bool hashValid);
191 
194  Slice data,
195  std::uint32_t seq,
196  SHAMapHash const& hash,
197  bool hashValid);
198 
201  Slice data,
202  std::uint32_t seq,
203  SHAMapHash const& hash,
204  bool hashValid);
205 };
206 
208 {
211  int mIsBranch = 0;
213 
215 
216 public:
219  clone(std::uint32_t seq) const override;
220 
221  bool
222  isEmpty() const;
223  bool
224  isEmptyBranch(int m) const;
225  int
226  getBranchCount() const;
227  SHAMapHash const&
228  getChildHash(int m) const;
229 
230  void
231  setChild(int m, std::shared_ptr<SHAMapAbstractNode> const& child);
232  void
233  shareChild(int m, std::shared_ptr<SHAMapAbstractNode> const& child);
235  getChildPointer(int branch);
237  getChild(int branch);
240 
241  // sync functions
242  bool
243  isFullBelow(std::uint32_t generation) const;
244  void
246 
247  bool
248  updateHash() override;
249  void
250  updateHashDeep();
251  void
252  addRaw(Serializer&, SHANodeFormat format) const override;
254  getString(SHAMapNodeID const&) const override;
255  uint256 const&
256  key() const override;
257  void
258  invariants(bool is_root = false) const override;
259 
262  Slice data,
263  std::uint32_t seq,
264  SHAMapHash const& hash,
265  bool hashValid);
266 
269 };
270 
271 // SHAMapTreeNode represents a leaf, and may eventually be renamed to reflect
272 // that.
274 {
275 private:
277 
278 public:
279  SHAMapTreeNode(const SHAMapTreeNode&) = delete;
281  operator=(const SHAMapTreeNode&) = delete;
282 
285  TNType type,
286  std::uint32_t seq);
289  TNType type,
290  std::uint32_t seq,
291  SHAMapHash const& hash);
293  clone(std::uint32_t seq) const override;
294 
295  void
296  addRaw(Serializer&, SHANodeFormat format) const override;
297  uint256 const&
298  key() const override;
299  void
300  invariants(bool is_root = false) const override;
301 
302 public: // public only to SHAMap
303  // item node function
304  bool
305  hasItem() const;
307  peekItem() const;
308  bool
310 
312  getString(SHAMapNodeID const&) const override;
313  bool
314  updateHash() override;
315 };
316 
317 // SHAMapAbstractNode
318 
320  : mType(type), mSeq(seq)
321 {
322 }
323 
325  TNType type,
326  std::uint32_t seq,
327  SHAMapHash const& hash)
328  : mType(type), mHash(hash), mSeq(seq)
329 {
330 }
331 
332 inline std::uint32_t
334 {
335  return mSeq;
336 }
337 
338 inline void
340 {
341  mSeq = s;
342 }
343 
344 inline SHAMapHash const&
346 {
347  return mHash;
348 }
349 
352 {
353  return mType;
354 }
355 
356 inline bool
358 {
359  return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD) ||
360  (mType == tnACCOUNT_STATE);
361 }
362 
363 inline bool
365 {
366  return mType == tnINNER;
367 }
368 
369 inline bool
371 {
372  return mType != tnERROR;
373 }
374 
375 inline bool
377 {
378  // Nodes at depth 64 must be leaves
379  return (!isInner() || (id.getDepth() < 64));
380 }
381 
382 // SHAMapInnerNode
383 
385  : SHAMapAbstractNode(tnINNER, seq)
386 {
387 }
388 
389 inline bool
391 {
392  return (mIsBranch & (1 << m)) == 0;
393 }
394 
395 inline SHAMapHash const&
397 {
398  assert((m >= 0) && (m < 16) && (getType() == tnINNER));
399  return mHashes[m];
400 }
401 
402 inline bool
404 {
405  return mFullBelowGen == generation;
406 }
407 
408 inline void
410 {
411  mFullBelowGen = gen;
412 }
413 
414 // SHAMapTreeNode
415 
416 inline bool
418 {
419  return bool(mItem);
420 }
421 
424 {
425  return mItem;
426 }
427 
428 } // namespace ripple
429 
430 #endif
ripple::base_uint::signum
int signum() const
Definition: base_uint.h:219
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::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::SHAMapInnerNode::mHashes
std::array< SHAMapHash, 16 > mHashes
Definition: SHAMapTreeNode.h:209
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:480
ripple::SHAMapHash::operator<
friend bool operator<(SHAMapHash const &x, SHAMapHash const &y)
Definition: SHAMapTreeNode.h:91
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::SHAMapAbstractNode::isInBounds
bool isInBounds(SHAMapNodeID const &id) const
Definition: SHAMapTreeNode.h:376
ripple::SHAMapAbstractNode::key
virtual uint256 const & key() const =0
ripple::SHAMapInnerNode::mFullBelowGen
std::uint32_t mFullBelowGen
Definition: SHAMapTreeNode.h:212
ripple::SHAMapTreeNode::operator=
SHAMapTreeNode & operator=(const SHAMapTreeNode &)=delete
ripple::snfPREFIX
@ snfPREFIX
Definition: SHAMapTreeNode.h:36
ripple::SHAMapHash::as_uint256
uint256 & as_uint256()
Definition: SHAMapTreeNode.h:59
ripple::SHAMapInnerNode::key
uint256 const & key() const override
Definition: SHAMapTreeNode.cpp:620
ripple::SHAMapAbstractNode::getType
TNType getType() const
Definition: SHAMapTreeNode.h:351
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::SHAMapAbstractNode::invariants
virtual void invariants(bool is_root=false) const =0
ripple::SHAMapInnerNode::addRaw
void addRaw(Serializer &, SHANodeFormat format) const override
Definition: SHAMapTreeNode.cpp:354
ripple::SHAMapNodeID
Definition: SHAMapNodeID.h:33
ripple::SHAMapHash::isNonZero
bool isNonZero() const
Definition: SHAMapTreeNode.h:69
ripple::SHAMapHash::SHAMapHash
SHAMapHash()=default
ripple::SHAMapAbstractNode::SHAMapAbstractNode
SHAMapAbstractNode(SHAMapAbstractNode const &)=delete
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::SHAMapAbstractNode::clone
virtual std::shared_ptr< SHAMapAbstractNode > clone(std::uint32_t seq) const =0
ripple::SHAMapInnerNode::setChild
void setChild(int m, std::shared_ptr< SHAMapAbstractNode > const &child)
Definition: SHAMapTreeNode.cpp:543
ripple::SHAMapAbstractNode::setSeq
void setSeq(std::uint32_t s)
Definition: SHAMapTreeNode.h:339
ripple::SHAMapInnerNode::isEmptyBranch
bool isEmptyBranch(int m) const
Definition: SHAMapTreeNode.h:390
ripple::SHAMapHash::to_string
friend std::string to_string(SHAMapHash const &x)
Definition: SHAMapTreeNode.h:103
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::SHAMapAbstractNode::addRaw
virtual void addRaw(Serializer &, SHANodeFormat format) const =0
ripple::SHAMapTreeNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:661
ripple::SHAMapAbstractNode::operator=
SHAMapAbstractNode & operator=(SHAMapAbstractNode const &)=delete
ripple::SHAMapInnerNode::SHAMapInnerNode
SHAMapInnerNode(std::uint32_t seq)
Definition: SHAMapTreeNode.h:384
ripple::SHAMapAbstractNode::isInner
bool isInner() const
Definition: SHAMapTreeNode.h:364
ripple::SHAMapInnerNode::getChildHash
SHAMapHash const & getChildHash(int m) const
Definition: SHAMapTreeNode.h:396
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
Definition: SHAMapTreeNode.h:207
ripple::SHAMapInnerNode::isFullBelow
bool isFullBelow(std::uint32_t generation) const
Definition: SHAMapTreeNode.h:403
ripple::SHAMapAbstractNode::getNodeHash
SHAMapHash const & getNodeHash() const
Definition: SHAMapTreeNode.h:345
std::ostream
STL class.
ripple::SHAMapInnerNode::canonicalizeChild
virtual std::shared_ptr< SHAMapAbstractNode > canonicalizeChild(int branch, std::shared_ptr< SHAMapAbstractNode > node)
Definition: SHAMapTreeNode.cpp:596
ripple::SHAMapAbstractNode::getSeq
std::uint32_t getSeq() const
Definition: SHAMapTreeNode.h:333
ripple::SHAMapHash::hash_
uint256 hash_
Definition: SHAMapTreeNode.h:45
ripple::SHAMapAbstractNode::mType
TNType mType
Definition: SHAMapTreeNode.h:134
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:165
ripple::SHAMapAbstractNode::isValid
bool isValid() const
Definition: SHAMapTreeNode.h:370
ripple::SHAMapTreeNode
Definition: SHAMapTreeNode.h:273
ripple::SHAMapHash::operator<<
friend std::ostream & operator<<(std::ostream &os, SHAMapHash const &x)
Definition: SHAMapTreeNode.h:97
std::array
STL class.
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
cstdint
ripple::SHAMapInnerNode::getBranchCount
int getBranchCount() const
Definition: SHAMapTreeNode.cpp:479
std::uint32_t
ripple::SHAMapAbstractNode::TNType
TNType
Definition: SHAMapTreeNode.h:125
memory
ripple::SHAMapHash::operator==
friend bool operator==(SHAMapHash const &x, SHAMapHash const &y)
Definition: SHAMapTreeNode.h:85
ripple::SHAMapAbstractNode::isLeaf
bool isLeaf() const
Definition: SHAMapTreeNode.h:357
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::SHAMapAbstractNode::makeFromWire
static std::shared_ptr< SHAMapAbstractNode > makeFromWire(Slice rawNode)
Definition: SHAMapTreeNode.cpp:224
ripple::SHAMapInnerNode::mIsBranch
int mIsBranch
Definition: SHAMapTreeNode.h:211
ripple::SHAMapHash::SHAMapHash
SHAMapHash(uint256 const &hash)
Definition: SHAMapTreeNode.h:49
ripple::base_uint::zero
void zero()
Definition: base_uint.h:485
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
ripple::snfWIRE
@ snfWIRE
Definition: SHAMapTreeNode.h:37
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::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::SHAMapInnerNode::setFullBelowGen
void setFullBelowGen(std::uint32_t gen)
Definition: SHAMapTreeNode.h:409
ripple::SHAMapInnerNode::getChild
std::shared_ptr< SHAMapAbstractNode > getChild(int branch)
Definition: SHAMapTreeNode.cpp:586
ripple::SHAMapHash::signum
int signum() const
Definition: SHAMapTreeNode.h:74
ripple::SHAMapInnerNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:295
ripple::SHAMapTreeNode::hasItem
bool hasItem() const
Definition: SHAMapTreeNode.h:417
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::SHAMapHash::hash_append
friend void hash_append(H &h, SHAMapHash const &x)
Definition: SHAMapTreeNode.h:110
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::SHAMapAbstractNode::updateHash
virtual bool updateHash()=0
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
string