rippled
Loading...
Searching...
No Matches
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 <xrpld/shamap/SHAMapAccountStateLeafNode.h>
21#include <xrpld/shamap/SHAMapInnerNode.h>
22#include <xrpld/shamap/SHAMapLeafNode.h>
23#include <xrpld/shamap/SHAMapTreeNode.h>
24#include <xrpld/shamap/SHAMapTxLeafNode.h>
25#include <xrpld/shamap/SHAMapTxPlusMetaLeafNode.h>
26#include <xrpl/basics/Log.h>
27#include <xrpl/basics/Slice.h>
28#include <xrpl/basics/contract.h>
29#include <xrpl/basics/safe_cast.h>
30#include <xrpl/beast/core/LexicalCast.h>
31#include <xrpl/protocol/HashPrefix.h>
32#include <xrpl/protocol/digest.h>
33#include <mutex>
34
35#include <openssl/sha.h>
36
37namespace 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)
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
static std::shared_ptr< SHAMapTreeNode > makeCompressedInner(Slice data)
static std::shared_ptr< SHAMapTreeNode > makeFullInner(Slice data, SHAMapHash const &hash, bool hashValid)
Identifies a node inside a SHAMap.
Definition: SHAMapNodeID.h:34
static std::shared_ptr< SHAMapTreeNode > makeTransactionWithMeta(Slice data, SHAMapHash const &hash, bool hashValid)
virtual std::string getString(SHAMapNodeID const &) const
static std::shared_ptr< SHAMapTreeNode > makeAccountState(Slice data, SHAMapHash const &hash, bool hashValid)
static std::shared_ptr< SHAMapTreeNode > makeFromPrefix(Slice rawNode, SHAMapHash const &hash)
static std::shared_ptr< SHAMapTreeNode > makeTransaction(Slice data, SHAMapHash const &hash, bool hashValid)
static std::shared_ptr< SHAMapTreeNode > makeFromWire(Slice rawNode)
std::size_t size() const noexcept
Definition: Serializer.h:72
bool getBitString(base_uint< Bits, Tag > &data, int offset) const
Definition: Serializer.h:180
Slice slice() const noexcept
Definition: Serializer.h:66
bool chop(int num)
Definition: Serializer.cpp:161
An immutable linear range of bytes.
Definition: Slice.h:45
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:69
void remove_suffix(std::size_t n)
Shrinks the slice by moving its end backward by n characters.
Definition: Slice.h:142
void remove_prefix(std::size_t n)
Shrinks the slice by moving its start forward by n characters.
Definition: Slice.h:134
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:80
static std::size_t constexpr bytes
Definition: base_uint.h:107
bool isZero() const
Definition: base_uint.h:539
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
static constexpr unsigned char const wireTypeAccountState
static constexpr unsigned char const wireTypeCompressedInner
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safe_cast(Src s) noexcept
Definition: safe_cast.h:42
boost::intrusive_ptr< SHAMapItem > make_shamapitem(uint256 const &tag, Slice data)
Definition: SHAMapItem.h:160
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:629
static constexpr unsigned char const wireTypeInner
static constexpr unsigned char const wireTypeTransaction
static constexpr unsigned char const wireTypeTransactionWithMeta
@ leafNode
account state
@ txNode
transaction plus metadata
@ transactionID
transaction plus signature to give transaction ID
@ innerNode
inner node in V1 tree
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:223
T to_string(T... args)