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/SHAMapTreeNode.h>
23#include <xrpld/shamap/SHAMapTxLeafNode.h>
24#include <xrpld/shamap/SHAMapTxPlusMetaLeafNode.h>
25#include <xrpl/basics/Log.h>
26#include <xrpl/basics/Slice.h>
27#include <xrpl/basics/contract.h>
28#include <xrpl/basics/safe_cast.h>
29#include <xrpl/protocol/HashPrefix.h>
30#include <xrpl/protocol/digest.h>
31
32#include <openssl/sha.h>
33
34namespace ripple {
35
38 Slice data,
39 SHAMapHash const& hash,
40 bool hashValid)
41{
42 auto item =
44
45 if (hashValid)
46 return std::make_shared<SHAMapTxLeafNode>(std::move(item), 0, hash);
47
48 return std::make_shared<SHAMapTxLeafNode>(std::move(item), 0);
49}
50
53 Slice data,
54 SHAMapHash const& hash,
55 bool hashValid)
56{
57 Serializer s(data.data(), data.size());
58
59 uint256 tag;
60
61 if (s.size() < tag.bytes)
62 Throw<std::runtime_error>("Short TXN+MD node");
63
64 // FIXME: improve this interface so that the above check isn't needed
65 if (!s.getBitString(tag, s.size() - tag.bytes))
66 Throw<std::out_of_range>(
67 "Short TXN+MD node (" + std::to_string(s.size()) + ")");
68
69 s.chop(tag.bytes);
70
71 auto item = make_shamapitem(tag, s.slice());
72
73 if (hashValid)
74 return std::make_shared<SHAMapTxPlusMetaLeafNode>(
75 std::move(item), 0, hash);
76
77 return std::make_shared<SHAMapTxPlusMetaLeafNode>(std::move(item), 0);
78}
79
82 Slice data,
83 SHAMapHash const& hash,
84 bool hashValid)
85{
86 Serializer s(data.data(), data.size());
87
88 uint256 tag;
89
90 if (s.size() < tag.bytes)
91 Throw<std::runtime_error>("short AS node");
92
93 // FIXME: improve this interface so that the above check isn't needed
94 if (!s.getBitString(tag, s.size() - tag.bytes))
95 Throw<std::out_of_range>(
96 "Short AS node (" + std::to_string(s.size()) + ")");
97
98 s.chop(tag.bytes);
99
100 if (tag.isZero())
101 Throw<std::runtime_error>("Invalid AS node");
102
103 auto item = make_shamapitem(tag, s.slice());
104
105 if (hashValid)
106 return std::make_shared<SHAMapAccountStateLeafNode>(
107 std::move(item), 0, hash);
108
109 return std::make_shared<SHAMapAccountStateLeafNode>(std::move(item), 0);
110}
111
114{
115 if (rawNode.empty())
116 return {};
117
118 auto const type = rawNode[rawNode.size() - 1];
119
120 rawNode.remove_suffix(1);
121
122 bool const hashValid = false;
123 SHAMapHash const hash;
124
125 if (type == wireTypeTransaction)
126 return makeTransaction(rawNode, hash, hashValid);
127
128 if (type == wireTypeAccountState)
129 return makeAccountState(rawNode, hash, hashValid);
130
131 if (type == wireTypeInner)
132 return SHAMapInnerNode::makeFullInner(rawNode, hash, hashValid);
133
134 if (type == wireTypeCompressedInner)
136
137 if (type == wireTypeTransactionWithMeta)
138 return makeTransactionWithMeta(rawNode, hash, hashValid);
139
140 Throw<std::runtime_error>(
141 "wire: Unknown type (" + std::to_string(type) + ")");
142}
143
146{
147 if (rawNode.size() < 4)
148 Throw<std::runtime_error>("prefix: short node");
149
150 // FIXME: Use SerialIter::get32?
151 // Extract the prefix
152 auto const type = safe_cast<HashPrefix>(
153 (safe_cast<std::uint32_t>(rawNode[0]) << 24) +
154 (safe_cast<std::uint32_t>(rawNode[1]) << 16) +
155 (safe_cast<std::uint32_t>(rawNode[2]) << 8) +
156 (safe_cast<std::uint32_t>(rawNode[3])));
157
158 rawNode.remove_prefix(4);
159
160 bool const hashValid = true;
161
162 if (type == HashPrefix::transactionID)
163 return makeTransaction(rawNode, hash, hashValid);
164
165 if (type == HashPrefix::leafNode)
166 return makeAccountState(rawNode, hash, hashValid);
167
168 if (type == HashPrefix::innerNode)
169 return SHAMapInnerNode::makeFullInner(rawNode, hash, hashValid);
170
171 if (type == HashPrefix::txNode)
172 return makeTransactionWithMeta(rawNode, hash, hashValid);
173
174 Throw<std::runtime_error>(
175 "prefix: unknown type (" +
177 ")");
178}
179
182{
183 return to_string(id);
184}
185
186} // 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:73
bool getBitString(base_uint< Bits, Tag > &data, int offset) const
Definition: Serializer.h:181
Slice slice() const noexcept
Definition: Serializer.h:67
bool chop(int num)
Definition: Serializer.cpp:174
An immutable linear range of bytes.
Definition: Slice.h:46
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:70
void remove_suffix(std::size_t n)
Shrinks the slice by moving its end backward by n characters.
Definition: Slice.h:143
void remove_prefix(std::size_t n)
Shrinks the slice by moving its start forward by n characters.
Definition: Slice.h:135
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:81
static std::size_t constexpr bytes
Definition: base_uint.h:108
bool isZero() const
Definition: base_uint.h:540
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:161
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
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:225
T to_string(T... args)