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/shamap/SHAMapItem.h>
24 #include <ripple/shamap/SHAMapNodeID.h>
25 #include <ripple/basics/TaggedCache.h>
26 #include <ripple/beast/utility/Journal.h>
27 
28 #include <cstdint>
29 #include <memory>
30 #include <mutex>
31 #include <string>
32 
33 namespace ripple {
34 
36 {
37  snfPREFIX = 1, // Form that hashes to its official hash
38  snfWIRE = 2, // Compressed form used on the wire
39  snfHASH = 3, // just the hash
40 };
41 
42 // A SHAMapHash is the hash of a node in a SHAMap, and also the
43 // type of the hash of the entire SHAMap.
45 {
47 public:
48  SHAMapHash() = default;
49  explicit SHAMapHash(uint256 const& hash)
50  : hash_(hash)
51  {}
52 
53  uint256 const& as_uint256() const {return hash_;}
54  uint256& as_uint256() {return hash_;}
55  bool isZero() const {return hash_.isZero();}
56  bool isNonZero() const {return hash_.isNonZero();}
57  int signum() const {return hash_.signum();}
58  void zero() {hash_.zero();}
59 
60  friend bool operator==(SHAMapHash const& x, SHAMapHash const& y)
61  {
62  return x.hash_ == y.hash_;
63  }
64 
65  friend bool operator<(SHAMapHash const& x, SHAMapHash const& y)
66  {
67  return x.hash_ < y.hash_;
68  }
69 
71  {
72  return os << x.hash_;
73  }
74 
75  friend std::string to_string(SHAMapHash const& x) {return to_string(x.hash_);}
76 
77  template <class H>
78  friend
79  void
80  hash_append(H& h, SHAMapHash const& x)
81  {
82  hash_append(h, x.hash_);
83  }
84 };
85 
86 inline
87 bool operator!=(SHAMapHash const& x, SHAMapHash const& y)
88 {
89  return !(x == y);
90 }
91 
93 {
94 public:
95  enum TNType
96  {
97  tnERROR = 0,
98  tnINNER = 1,
99  tnTRANSACTION_NM = 2, // transaction, no metadata
100  tnTRANSACTION_MD = 3, // transaction, with metadata
102  };
103 
104 protected:
108 
109 protected:
110  virtual ~SHAMapAbstractNode() = 0;
111  SHAMapAbstractNode(SHAMapAbstractNode const&) = delete;
113 
115  SHAMapAbstractNode(TNType type, std::uint32_t seq, SHAMapHash const& hash);
116 
117 public:
118  std::uint32_t getSeq () const;
119  void setSeq (std::uint32_t s);
120  SHAMapHash const& getNodeHash () const;
121  TNType getType () const;
122  bool isLeaf () const;
123  bool isInner () const;
124  bool isValid () const;
125  bool isInBounds (SHAMapNodeID const &id) const;
126 
127  virtual bool updateHash () = 0;
128  virtual void addRaw (Serializer&, SHANodeFormat format) const = 0;
129  virtual std::string getString (SHAMapNodeID const&) const;
131  virtual uint256 const& key() const = 0;
132  virtual void invariants(bool is_root = false) const = 0;
133 
135  make(Slice const& rawNode, std::uint32_t seq, SHANodeFormat format,
136  SHAMapHash const& hash, bool hashValid, beast::Journal j,
137  SHAMapNodeID const& id = SHAMapNodeID{});
138 };
139 
141  : public SHAMapAbstractNode
142 {
145  int mIsBranch = 0;
147 
149 public:
152 
153  bool isEmpty () const;
154  bool isEmptyBranch (int m) const;
155  int getBranchCount () const;
156  SHAMapHash const& getChildHash (int m) const;
157 
158  void setChild(int m, std::shared_ptr<SHAMapAbstractNode> const& child);
159  void shareChild (int m, std::shared_ptr<SHAMapAbstractNode> const& child);
160  SHAMapAbstractNode* getChildPointer (int branch);
164 
165  // sync functions
166  bool isFullBelow (std::uint32_t generation) const;
167  void setFullBelowGen (std::uint32_t gen);
168 
169  bool updateHash () override;
170  void updateHashDeep();
171  void addRaw (Serializer&, SHANodeFormat format) const override;
172  std::string getString (SHAMapNodeID const&) const override;
173  uint256 const& key() const override;
174  void invariants(bool is_root = false) const override;
175 
177  SHAMapAbstractNode::make(Slice const& rawNode, std::uint32_t seq,
178  SHANodeFormat format, SHAMapHash const& hash, bool hashValid,
179  beast::Journal j, SHAMapNodeID const& id);
180 };
181 
182 // SHAMapTreeNode represents a leaf, and may eventually be renamed to reflect that.
184  : public SHAMapAbstractNode
185 {
186 private:
188 
189 public:
190  SHAMapTreeNode (const SHAMapTreeNode&) = delete;
191  SHAMapTreeNode& operator= (const SHAMapTreeNode&) = delete;
192 
194  TNType type, std::uint32_t seq);
196  std::uint32_t seq, SHAMapHash const& hash);
198 
199  void addRaw (Serializer&, SHANodeFormat format) const override;
200  uint256 const& key() const override;
201  void invariants(bool is_root = false) const override;
202 
203 public: // public only to SHAMap
204 
205  // inner node functions
206  bool isInnerNode () const;
207 
208  // item node function
209  bool hasItem () const;
211  bool setItem (std::shared_ptr<SHAMapItem const> const& i, TNType type);
212 
213  std::string getString (SHAMapNodeID const&) const override;
214  bool updateHash () override;
215 };
216 
217 // SHAMapAbstractNode
218 
219 inline
221  : mType(type)
222  , mSeq(seq)
223 {
224 }
225 
226 inline
228  SHAMapHash const& hash)
229  : mType(type)
230  , mHash(hash)
231  , mSeq(seq)
232 {
233 }
234 
235 inline
238 {
239  return mSeq;
240 }
241 
242 inline
243 void
245 {
246  mSeq = s;
247 }
248 
249 inline
250 SHAMapHash const&
252 {
253  return mHash;
254 }
255 
256 inline
259 {
260  return mType;
261 }
262 
263 inline
264 bool
266 {
267  return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD) ||
268  (mType == tnACCOUNT_STATE);
269 }
270 
271 inline
272 bool
274 {
275  return mType == tnINNER;
276 }
277 
278 inline
279 bool
281 {
282  return mType != tnERROR;
283 }
284 
285 inline
286 bool
288 {
289  // Nodes at depth 64 must be leaves
290  return (!isInner() || (id.getDepth() < 64));
291 }
292 
293 // SHAMapInnerNode
294 
295 inline
297  : SHAMapAbstractNode(tnINNER, seq)
298 {
299 }
300 
301 inline
302 bool
304 {
305  return (mIsBranch & (1 << m)) == 0;
306 }
307 
308 inline
309 SHAMapHash const&
311 {
312  assert ((m >= 0) && (m < 16) && (getType() == tnINNER));
313  return mHashes[m];
314 }
315 
316 inline
317 bool
319 {
320  return mFullBelowGen == generation;
321 }
322 
323 inline
324 void
326 {
327  mFullBelowGen = gen;
328 }
329 
330 // SHAMapTreeNode
331 
332 inline
333 bool
335 {
336  return !mItem;
337 }
338 
339 inline
340 bool
342 {
343  return bool(mItem);
344 }
345 
346 inline
349 {
350  return mItem;
351 }
352 
353 } // ripple
354 
355 #endif
ripple::base_uint::signum
int signum() const
Definition: base_uint.h:189
ripple::SHAMapTreeNode::SHAMapTreeNode
SHAMapTreeNode(const SHAMapTreeNode &)=delete
ripple::SHAMapAbstractNode::mHash
SHAMapHash mHash
Definition: SHAMapTreeNode.h:106
std::string
STL class.
std::shared_ptr
STL class.
ripple::SHAMapAbstractNode::tnACCOUNT_STATE
@ tnACCOUNT_STATE
Definition: SHAMapTreeNode.h:101
ripple::SHAMapInnerNode::mHashes
std::array< SHAMapHash, 16 > mHashes
Definition: SHAMapTreeNode.h:143
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:430
ripple::SHAMapHash::operator<
friend bool operator<(SHAMapHash const &x, SHAMapHash const &y)
Definition: SHAMapTreeNode.h:65
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::SHAMapAbstractNode::isInBounds
bool isInBounds(SHAMapNodeID const &id) const
Definition: SHAMapTreeNode.h:287
ripple::SHAMapAbstractNode::key
virtual uint256 const & key() const =0
ripple::SHAMapInnerNode::mFullBelowGen
std::uint32_t mFullBelowGen
Definition: SHAMapTreeNode.h:146
ripple::SHAMapTreeNode::operator=
SHAMapTreeNode & operator=(const SHAMapTreeNode &)=delete
ripple::snfPREFIX
@ snfPREFIX
Definition: SHAMapTreeNode.h:37
ripple::SHAMapHash::as_uint256
uint256 & as_uint256()
Definition: SHAMapTreeNode.h:54
ripple::SHAMapInnerNode::key
uint256 const & key() const override
Definition: SHAMapTreeNode.cpp:593
ripple::SHAMapAbstractNode::getType
TNType getType() const
Definition: SHAMapTreeNode.h:258
ripple::SHAMapHash::isZero
bool isZero() const
Definition: SHAMapTreeNode.h:55
ripple::SHAMapAbstractNode::getString
virtual std::string getString(SHAMapNodeID const &) const
Definition: SHAMapTreeNode.cpp:472
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:337
ripple::SHAMapNodeID
Definition: SHAMapNodeID.h:33
ripple::SHAMapHash::isNonZero
bool isNonZero() const
Definition: SHAMapTreeNode.h:56
ripple::SHAMapHash::SHAMapHash
SHAMapHash()=default
ripple::SHAMapAbstractNode::SHAMapAbstractNode
SHAMapAbstractNode(SHAMapAbstractNode const &)=delete
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::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:523
ripple::SHAMapAbstractNode::setSeq
void setSeq(std::uint32_t s)
Definition: SHAMapTreeNode.h:244
ripple::SHAMapInnerNode::isEmptyBranch
bool isEmptyBranch(int m) const
Definition: SHAMapTreeNode.h:303
ripple::SHAMapHash::to_string
friend std::string to_string(SHAMapHash const &x)
Definition: SHAMapTreeNode.h:75
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::SHAMapAbstractNode::addRaw
virtual void addRaw(Serializer &, SHANodeFormat format) const =0
ripple::SHAMapTreeNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapTreeNode.cpp:634
ripple::SHAMapAbstractNode::operator=
SHAMapAbstractNode & operator=(SHAMapAbstractNode const &)=delete
ripple::SHAMapInnerNode::SHAMapInnerNode
SHAMapInnerNode(std::uint32_t seq)
Definition: SHAMapTreeNode.h:296
ripple::SHAMapAbstractNode::isInner
bool isInner() const
Definition: SHAMapTreeNode.h:273
ripple::SHAMapInnerNode::getChildHash
SHAMapHash const & getChildHash(int m) const
Definition: SHAMapTreeNode.h:310
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:429
ripple::SHAMapInnerNode
Definition: SHAMapTreeNode.h:140
ripple::SHAMapInnerNode::isFullBelow
bool isFullBelow(std::uint32_t generation) const
Definition: SHAMapTreeNode.h:318
ripple::SHAMapAbstractNode::getNodeHash
SHAMapHash const & getNodeHash() const
Definition: SHAMapTreeNode.h:251
std::ostream
STL class.
ripple::SHAMapInnerNode::canonicalizeChild
virtual std::shared_ptr< SHAMapAbstractNode > canonicalizeChild(int branch, std::shared_ptr< SHAMapAbstractNode > node)
Definition: SHAMapTreeNode.cpp:571
ripple::SHAMapAbstractNode::getSeq
std::uint32_t getSeq() const
Definition: SHAMapTreeNode.h:237
ripple::SHAMapHash::hash_
uint256 hash_
Definition: SHAMapTreeNode.h:46
ripple::SHAMapAbstractNode::mType
TNType mType
Definition: SHAMapTreeNode.h:105
ripple::SHAMapTreeNode::isInnerNode
bool isInnerNode() const
Definition: SHAMapTreeNode.h:334
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:161
ripple::SHAMapAbstractNode::isValid
bool isValid() const
Definition: SHAMapTreeNode.h:280
ripple::SHAMapTreeNode
Definition: SHAMapTreeNode.h:183
ripple::SHAMapHash::operator<<
friend std::ostream & operator<<(std::ostream &os, SHAMapHash const &x)
Definition: SHAMapTreeNode.h:70
std::array
STL class.
ripple::SHAMapInnerNode::updateHashDeep
void updateHashDeep()
Definition: SHAMapTreeNode.cpp:295
cstdint
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
memory
ripple::SHAMapHash::operator==
friend bool operator==(SHAMapHash const &x, SHAMapHash const &y)
Definition: SHAMapTreeNode.h:60
ripple::SHAMapAbstractNode::isLeaf
bool isLeaf() const
Definition: SHAMapTreeNode.h:265
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::SHAMapInnerNode::mIsBranch
int mIsBranch
Definition: SHAMapTreeNode.h:145
ripple::SHAMapHash::SHAMapHash
SHAMapHash(uint256 const &hash)
Definition: SHAMapTreeNode.h:49
ripple::base_uint::zero
void zero()
Definition: base_uint.h:431
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::snfWIRE
@ snfWIRE
Definition: SHAMapTreeNode.h:38
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::SHAMapInnerNode::setFullBelowGen
void setFullBelowGen(std::uint32_t gen)
Definition: SHAMapTreeNode.h:325
ripple::SHAMapInnerNode::getChild
std::shared_ptr< SHAMapAbstractNode > getChild(int branch)
Definition: SHAMapTreeNode.cpp:561
ripple::SHAMapHash::signum
int signum() const
Definition: SHAMapTreeNode.h:57
ripple::SHAMapInnerNode::updateHash
bool updateHash() override
Definition: SHAMapTreeNode.cpp:275
ripple::SHAMapTreeNode::hasItem
bool hasItem() const
Definition: SHAMapTreeNode.h:341
ripple::SHAMapAbstractNode::tnINNER
@ tnINNER
Definition: SHAMapTreeNode.h:98
ripple::SHAMapHash::hash_append
friend void hash_append(H &h, SHAMapHash const &x)
Definition: SHAMapTreeNode.h:80
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::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:348
string