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/SHAMapAccountStateLeafNode.h>
28 #include <ripple/shamap/SHAMapInnerNode.h>
29 #include <ripple/shamap/SHAMapLeafNode.h>
30 #include <ripple/shamap/SHAMapTreeNode.h>
31 #include <ripple/shamap/SHAMapTxLeafNode.h>
32 #include <ripple/shamap/SHAMapTxPlusMetaLeafNode.h>
33 #include <mutex>
34 
35 #include <openssl/sha.h>
36 
37 namespace ripple {
38 
41  Slice data,
42  SHAMapHash const& hash,
43  bool hashValid)
44 {
45  auto item =
47 
48  if (hashValid)
49  return std::make_shared<SHAMapTxLeafNode>(std::move(item), 0, hash);
50 
51  return std::make_shared<SHAMapTxLeafNode>(std::move(item), 0);
52 }
53 
56  Slice data,
57  SHAMapHash const& hash,
58  bool hashValid)
59 {
60  Serializer s(data.data(), data.size());
61 
62  uint256 tag;
63 
64  if (s.size() < tag.bytes)
65  Throw<std::runtime_error>("Short TXN+MD node");
66 
67  // FIXME: improve this interface so that the above check isn't needed
68  if (!s.getBitString(tag, s.size() - tag.bytes))
69  Throw<std::out_of_range>(
70  "Short TXN+MD node (" + std::to_string(s.size()) + ")");
71 
72  s.chop(tag.bytes);
73 
74  auto item = make_shamapitem(tag, s.slice());
75 
76  if (hashValid)
77  return std::make_shared<SHAMapTxPlusMetaLeafNode>(
78  std::move(item), 0, hash);
79 
80  return std::make_shared<SHAMapTxPlusMetaLeafNode>(std::move(item), 0);
81 }
82 
85  Slice data,
86  SHAMapHash const& hash,
87  bool hashValid)
88 {
89  Serializer s(data.data(), data.size());
90 
91  uint256 tag;
92 
93  if (s.size() < tag.bytes)
94  Throw<std::runtime_error>("short AS node");
95 
96  // FIXME: improve this interface so that the above check isn't needed
97  if (!s.getBitString(tag, s.size() - tag.bytes))
98  Throw<std::out_of_range>(
99  "Short AS node (" + std::to_string(s.size()) + ")");
100 
101  s.chop(tag.bytes);
102 
103  if (tag.isZero())
104  Throw<std::runtime_error>("Invalid AS node");
105 
106  auto item = make_shamapitem(tag, s.slice());
107 
108  if (hashValid)
109  return std::make_shared<SHAMapAccountStateLeafNode>(
110  std::move(item), 0, hash);
111 
112  return std::make_shared<SHAMapAccountStateLeafNode>(std::move(item), 0);
113 }
114 
117 {
118  if (rawNode.empty())
119  return {};
120 
121  auto const type = rawNode[rawNode.size() - 1];
122 
123  rawNode.remove_suffix(1);
124 
125  bool const hashValid = false;
126  SHAMapHash const hash;
127 
128  if (type == wireTypeTransaction)
129  return makeTransaction(rawNode, hash, hashValid);
130 
131  if (type == wireTypeAccountState)
132  return makeAccountState(rawNode, hash, hashValid);
133 
134  if (type == wireTypeInner)
135  return SHAMapInnerNode::makeFullInner(rawNode, hash, hashValid);
136 
137  if (type == wireTypeCompressedInner)
138  return SHAMapInnerNode::makeCompressedInner(rawNode);
139 
140  if (type == wireTypeTransactionWithMeta)
141  return makeTransactionWithMeta(rawNode, hash, hashValid);
142 
143  Throw<std::runtime_error>(
144  "wire: Unknown type (" + std::to_string(type) + ")");
145 }
146 
149 {
150  if (rawNode.size() < 4)
151  Throw<std::runtime_error>("prefix: short node");
152 
153  // FIXME: Use SerialIter::get32?
154  // Extract the prefix
155  auto const type = safe_cast<HashPrefix>(
156  (safe_cast<std::uint32_t>(rawNode[0]) << 24) +
157  (safe_cast<std::uint32_t>(rawNode[1]) << 16) +
158  (safe_cast<std::uint32_t>(rawNode[2]) << 8) +
159  (safe_cast<std::uint32_t>(rawNode[3])));
160 
161  rawNode.remove_prefix(4);
162 
163  bool const hashValid = true;
164 
165  if (type == HashPrefix::transactionID)
166  return makeTransaction(rawNode, hash, hashValid);
167 
168  if (type == HashPrefix::leafNode)
169  return makeAccountState(rawNode, hash, hashValid);
170 
171  if (type == HashPrefix::innerNode)
172  return SHAMapInnerNode::makeFullInner(rawNode, hash, hashValid);
173 
174  if (type == HashPrefix::txNode)
175  return makeTransactionWithMeta(rawNode, hash, hashValid);
176 
177  Throw<std::runtime_error>(
178  "prefix: unknown type (" +
180  ")");
181 }
182 
185 {
186  return to_string(id);
187 }
188 
189 } // namespace ripple
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:80
ripple::Serializer::chop
bool chop(int num)
Definition: Serializer.cpp:184
std::string
STL class.
std::shared_ptr
STL class.
ripple::HashPrefix::txNode
@ txNode
transaction plus metadata
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::SHAMapInnerNode::makeFullInner
static std::shared_ptr< SHAMapTreeNode > makeFullInner(Slice data, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapInnerNode.cpp:126
ripple::make_shamapitem
boost::intrusive_ptr< SHAMapItem > make_shamapitem(uint256 const &tag, Slice data)
Definition: SHAMapItem.h:160
ripple::wireTypeTransaction
static constexpr unsigned const char wireTypeTransaction
Definition: SHAMapTreeNode.h:40
ripple::wireTypeInner
static constexpr unsigned const char wireTypeInner
Definition: SHAMapTreeNode.h:42
ripple::SHAMapTreeNode::makeFromWire
static std::shared_ptr< SHAMapTreeNode > makeFromWire(Slice rawNode)
Definition: SHAMapTreeNode.cpp:116
ripple::SHAMapNodeID
Identifies a node inside a SHAMap.
Definition: SHAMapNodeID.h:33
ripple::SHAMapTreeNode::getString
virtual std::string getString(SHAMapNodeID const &) const
Definition: SHAMapTreeNode.cpp:184
ripple::Slice::empty
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:69
ripple::SHAMapHash
Definition: SHAMapHash.h:32
ripple::wireTypeTransactionWithMeta
static constexpr unsigned const char wireTypeTransactionWithMeta
Definition: SHAMapTreeNode.h:44
std::underlying_type_t
ripple::wireTypeAccountState
static constexpr unsigned const char wireTypeAccountState
Definition: SHAMapTreeNode.h:41
ripple::base_uint< 256 >
ripple::SHAMapTreeNode::makeTransaction
static std::shared_ptr< SHAMapTreeNode > makeTransaction(Slice data, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:40
ripple::HashPrefix::innerNode
@ innerNode
inner node in V1 tree
ripple::base_uint::bytes
static constexpr std::size_t bytes
Definition: base_uint.h:105
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:532
ripple::SHAMapTreeNode::makeTransactionWithMeta
static std::shared_ptr< SHAMapTreeNode > makeTransactionWithMeta(Slice data, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:55
ripple::safe_cast
constexpr std::enable_if_t< std::is_same_v< typename Dest::unit_type, typename Src::unit_type > &&std::is_integral_v< typename Dest::value_type > &&std::is_integral_v< typename Src::value_type >, Dest > safe_cast(Src s) noexcept
Definition: FeeUnits.h:532
std::to_string
T to_string(T... args)
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
ripple::HashPrefix::transactionID
@ transactionID
transaction plus signature to give transaction ID
ripple::HashPrefix::leafNode
@ leafNode
account state
ripple::Serializer
Definition: Serializer.h:39
ripple::wireTypeCompressedInner
static constexpr unsigned const char wireTypeCompressedInner
Definition: SHAMapTreeNode.h:43
ripple::SHAMapTreeNode::makeFromPrefix
static std::shared_ptr< SHAMapTreeNode > makeFromPrefix(Slice rawNode, SHAMapHash const &hash)
Definition: SHAMapTreeNode.cpp:148
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Serializer::getBitString
bool getBitString(base_uint< Bits, Tag > &data, int offset) const
Definition: Serializer.h:146
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::sha512Half
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:216
ripple::Slice::remove_prefix
void remove_prefix(std::size_t n)
Shrinks the slice by moving its start forward by n characters.
Definition: Slice.h:132
mutex
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::SHAMapInnerNode::makeCompressedInner
static std::shared_ptr< SHAMapTreeNode > makeCompressedInner(Slice data)
Definition: SHAMapInnerNode.cpp:160
ripple::Slice::remove_suffix
void remove_suffix(std::size_t n)
Shrinks the slice by moving its end backward by n characters.
Definition: Slice.h:140
ripple::SHAMapTreeNode::makeAccountState
static std::shared_ptr< SHAMapTreeNode > makeAccountState(Slice data, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapTreeNode.cpp:84