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 <xrpl/basics/IntrusivePointer.ipp>
21#include <xrpl/basics/Slice.h>
22#include <xrpl/basics/contract.h>
23#include <xrpl/basics/safe_cast.h>
24#include <xrpl/protocol/HashPrefix.h>
25#include <xrpl/protocol/digest.h>
26#include <xrpl/shamap/SHAMapAccountStateLeafNode.h>
27#include <xrpl/shamap/SHAMapInnerNode.h>
28#include <xrpl/shamap/SHAMapTreeNode.h>
29#include <xrpl/shamap/SHAMapTxLeafNode.h>
30#include <xrpl/shamap/SHAMapTxPlusMetaLeafNode.h>
31
32namespace ripple {
33
34intr_ptr::SharedPtr<SHAMapTreeNode>
36 Slice data,
37 SHAMapHash const& hash,
38 bool hashValid)
39{
40 auto item =
42
43 if (hashValid)
44 return intr_ptr::make_shared<SHAMapTxLeafNode>(
45 std::move(item), 0, hash);
46
47 return intr_ptr::make_shared<SHAMapTxLeafNode>(std::move(item), 0);
48}
49
52 Slice data,
53 SHAMapHash const& hash,
54 bool hashValid)
55{
56 Serializer s(data.data(), data.size());
57
58 uint256 tag;
59
60 if (s.size() < tag.bytes)
61 Throw<std::runtime_error>("Short TXN+MD node");
62
63 // FIXME: improve this interface so that the above check isn't needed
64 if (!s.getBitString(tag, s.size() - tag.bytes))
65 Throw<std::out_of_range>(
66 "Short TXN+MD node (" + std::to_string(s.size()) + ")");
67
68 s.chop(tag.bytes);
69
70 auto item = make_shamapitem(tag, s.slice());
71
72 if (hashValid)
73 return intr_ptr::make_shared<SHAMapTxPlusMetaLeafNode>(
74 std::move(item), 0, hash);
75
76 return intr_ptr::make_shared<SHAMapTxPlusMetaLeafNode>(std::move(item), 0);
77}
78
81 Slice data,
82 SHAMapHash const& hash,
83 bool hashValid)
84{
85 Serializer s(data.data(), data.size());
86
87 uint256 tag;
88
89 if (s.size() < tag.bytes)
90 Throw<std::runtime_error>("short AS node");
91
92 // FIXME: improve this interface so that the above check isn't needed
93 if (!s.getBitString(tag, s.size() - tag.bytes))
94 Throw<std::out_of_range>(
95 "Short AS node (" + std::to_string(s.size()) + ")");
96
97 s.chop(tag.bytes);
98
99 if (tag.isZero())
100 Throw<std::runtime_error>("Invalid AS node");
101
102 auto item = make_shamapitem(tag, s.slice());
103
104 if (hashValid)
105 return intr_ptr::make_shared<SHAMapAccountStateLeafNode>(
106 std::move(item), 0, hash);
107
108 return intr_ptr::make_shared<SHAMapAccountStateLeafNode>(
109 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 intr_ptr::SharedPtr< SHAMapTreeNode > makeCompressedInner(Slice data)
static intr_ptr::SharedPtr< SHAMapTreeNode > makeFullInner(Slice data, SHAMapHash const &hash, bool hashValid)
Identifies a node inside a SHAMap.
static intr_ptr::SharedPtr< SHAMapTreeNode > makeAccountState(Slice data, SHAMapHash const &hash, bool hashValid)
virtual std::string getString(SHAMapNodeID const &) const
static intr_ptr::SharedPtr< SHAMapTreeNode > makeTransaction(Slice data, SHAMapHash const &hash, bool hashValid)
static intr_ptr::SharedPtr< SHAMapTreeNode > makeTransactionWithMeta(Slice data, SHAMapHash const &hash, bool hashValid)
static intr_ptr::SharedPtr< SHAMapTreeNode > makeFromPrefix(Slice rawNode, SHAMapHash const &hash)
static intr_ptr::SharedPtr< 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)
A shared intrusive pointer class that supports weak pointers.
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:25
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:41
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:224
T to_string(T... args)