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  make(
180  Slice const& rawNode,
181  std::uint32_t seq,
182  SHANodeFormat format,
183  SHAMapHash const& hash,
184  bool hashValid,
185  beast::Journal j,
186  SHAMapNodeID const& id = SHAMapNodeID{});
187 };
188 
190 {
193  int mIsBranch = 0;
195 
197 
198 public:
201  clone(std::uint32_t seq) const override;
202 
203  bool
204  isEmpty() const;
205  bool
206  isEmptyBranch(int m) const;
207  int
208  getBranchCount() const;
209  SHAMapHash const&
210  getChildHash(int m) const;
211 
212  void
213  setChild(int m, std::shared_ptr<SHAMapAbstractNode> const& child);
214  void
215  shareChild(int m, std::shared_ptr<SHAMapAbstractNode> const& child);
217  getChildPointer(int branch);
219  getChild(int branch);
222 
223  // sync functions
224  bool
225  isFullBelow(std::uint32_t generation) const;
226  void
228 
229  bool
230  updateHash() override;
231  void
232  updateHashDeep();
233  void
234  addRaw(Serializer&, SHANodeFormat format) const override;
236  getString(SHAMapNodeID const&) const override;
237  uint256 const&
238  key() const override;
239  void
240  invariants(bool is_root = false) const override;
241 
244  Slice const& rawNode,
245  std::uint32_t seq,
246  SHANodeFormat format,
247  SHAMapHash const& hash,
248  bool hashValid,
249  beast::Journal j,
250  SHAMapNodeID const& id);
251 };
252 
253 // SHAMapTreeNode represents a leaf, and may eventually be renamed to reflect
254 // that.
256 {
257 private:
259 
260 public:
261  SHAMapTreeNode(const SHAMapTreeNode&) = delete;
263  operator=(const SHAMapTreeNode&) = delete;
264 
267  TNType type,
268  std::uint32_t seq);
271  TNType type,
272  std::uint32_t seq,
273  SHAMapHash const& hash);
275  clone(std::uint32_t seq) const override;
276 
277  void
278  addRaw(Serializer&, SHANodeFormat format) const override;
279  uint256 const&
280  key() const override;
281  void
282  invariants(bool is_root = false) const override;
283 
284 public: // public only to SHAMap
285  // inner node functions
286  bool
287  isInnerNode() const;
288 
289  // item node function
290  bool
291  hasItem() const;
293  peekItem() const;
294  bool
296 
298  getString(SHAMapNodeID const&) const override;
299  bool
300  updateHash() override;
301 };
302 
303 // SHAMapAbstractNode
304 
306  : mType(type), mSeq(seq)
307 {
308 }
309 
311  TNType type,
312  std::uint32_t seq,
313  SHAMapHash const& hash)
314  : mType(type), mHash(hash), mSeq(seq)
315 {
316 }
317 
318 inline std::uint32_t
320 {
321  return mSeq;
322 }
323 
324 inline void
326 {
327  mSeq = s;
328 }
329 
330 inline SHAMapHash const&
332 {
333  return mHash;
334 }
335 
338 {
339  return mType;
340 }
341 
342 inline bool
344 {
345  return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD) ||
346  (mType == tnACCOUNT_STATE);
347 }
348 
349 inline bool
351 {
352  return mType == tnINNER;
353 }
354 
355 inline bool
357 {
358  return mType != tnERROR;
359 }
360 
361 inline bool
363 {
364  // Nodes at depth 64 must be leaves
365  return (!isInner() || (id.getDepth() < 64));
366 }
367 
368 // SHAMapInnerNode
369 
371  : SHAMapAbstractNode(tnINNER, seq)
372 {
373 }
374 
375 inline bool
377 {
378  return (mIsBranch & (1 << m)) == 0;
379 }
380 
381 inline SHAMapHash const&
383 {
384  assert((m >= 0) && (m < 16) && (getType() == tnINNER));
385  return mHashes[m];
386 }
387 
388 inline bool
390 {
391  return mFullBelowGen == generation;
392 }
393 
394 inline void
396 {
397  mFullBelowGen = gen;
398 }
399 
400 // SHAMapTreeNode
401 
402 inline bool
404 {
405  return !mItem;
406 }
407 
408 inline bool
410 {
411  return bool(mItem);
412 }
413 
416 {
417  return mItem;
418 }
419 
420 } // namespace ripple
421 
422 #endif
ripple::base_uint::signum
int signum() const
Definition: base_uint.h:219
ripple::SHAMapTreeNode::SHAMapTreeNode
SHAMapTreeNode(const SHAMapTreeNode &)=delete
ripple::SHAMapAbstractNode::mHash
SHAMapHash mHash
Definition: SHAMapTreeNode.h:135
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:191
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::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::SHAMapAbstractNode::isInBounds
bool isInBounds(SHAMapNodeID const &id) const
Definition: SHAMapTreeNode.h:362
ripple::SHAMapAbstractNode::key
virtual uint256 const & key() const =0
ripple::SHAMapInnerNode::mFullBelowGen
std::uint32_t mFullBelowGen
Definition: SHAMapTreeNode.h:194
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:619
ripple::SHAMapAbstractNode::getType
TNType getType() const
Definition: SHAMapTreeNode.h:337
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::SHAMapAbstractNode::invariants
virtual void invariants(bool is_root=false) const =0
ripple::SHAMapInnerNode::addRaw
void addRaw(Serializer &, SHANodeFormat format) const override
Definition: SHAMapTreeNode.cpp:353
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: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::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:542
ripple::SHAMapAbstractNode::setSeq
void setSeq(std::uint32_t s)
Definition: SHAMapTreeNode.h:325
ripple::SHAMapInnerNode::isEmptyBranch
bool isEmptyBranch(int m) const
Definition: SHAMapTreeNode.h:376
ripple::SHAMapHash::to_string
friend std::string to_string(SHAMapHash const &x)
Definition: SHAMapTreeNode.h:103
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::SHAMapAbstractNode::addRaw
virtual void addRaw(Serializer &, SHANodeFormat format) const =0
ripple::SHAMapTreeNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:660
ripple::SHAMapAbstractNode::operator=
SHAMapAbstractNode & operator=(SHAMapAbstractNode const &)=delete
ripple::SHAMapInnerNode::SHAMapInnerNode
SHAMapInnerNode(std::uint32_t seq)
Definition: SHAMapTreeNode.h:370
ripple::SHAMapAbstractNode::isInner
bool isInner() const
Definition: SHAMapTreeNode.h:350
ripple::SHAMapInnerNode::getChildHash
SHAMapHash const & getChildHash(int m) const
Definition: SHAMapTreeNode.h:382
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:475
ripple::SHAMapInnerNode
Definition: SHAMapTreeNode.h:189
ripple::SHAMapInnerNode::isFullBelow
bool isFullBelow(std::uint32_t generation) const
Definition: SHAMapTreeNode.h:389
ripple::SHAMapAbstractNode::getNodeHash
SHAMapHash const & getNodeHash() const
Definition: SHAMapTreeNode.h:331
std::ostream
STL class.
ripple::SHAMapInnerNode::canonicalizeChild
virtual std::shared_ptr< SHAMapAbstractNode > canonicalizeChild(int branch, std::shared_ptr< SHAMapAbstractNode > node)
Definition: SHAMapTreeNode.cpp:595
ripple::SHAMapAbstractNode::getSeq
std::uint32_t getSeq() const
Definition: SHAMapTreeNode.h:319
ripple::SHAMapHash::hash_
uint256 hash_
Definition: SHAMapTreeNode.h:45
ripple::SHAMapAbstractNode::mType
TNType mType
Definition: SHAMapTreeNode.h:134
ripple::SHAMapTreeNode::isInnerNode
bool isInnerNode() const
Definition: SHAMapTreeNode.h:403
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:165
ripple::SHAMapAbstractNode::isValid
bool isValid() const
Definition: SHAMapTreeNode.h:356
ripple::SHAMapTreeNode
Definition: SHAMapTreeNode.h:255
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:313
cstdint
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
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:343
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::SHAMapInnerNode::mIsBranch
int mIsBranch
Definition: SHAMapTreeNode.h:193
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:519
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: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::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::SHAMapInnerNode::setFullBelowGen
void setFullBelowGen(std::uint32_t gen)
Definition: SHAMapTreeNode.h:395
ripple::SHAMapInnerNode::getChild
std::shared_ptr< SHAMapAbstractNode > getChild(int branch)
Definition: SHAMapTreeNode.cpp:585
ripple::SHAMapHash::signum
int signum() const
Definition: SHAMapTreeNode.h:74
ripple::SHAMapInnerNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:294
ripple::SHAMapTreeNode::hasItem
bool hasItem() const
Definition: SHAMapTreeNode.h:409
ripple::SHAMapAbstractNode::tnINNER
@ tnINNER
Definition: SHAMapTreeNode.h:127
ripple::SHAMapHash::hash_append
friend void hash_append(H &h, SHAMapHash const &x)
Definition: SHAMapTreeNode.h:110
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::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:415
string