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
26#include <xrpl/basics/IntrusivePointer.ipp>
27#include <xrpl/basics/Slice.h>
28#include <xrpl/basics/contract.h>
29#include <xrpl/basics/safe_cast.h>
30#include <xrpl/protocol/HashPrefix.h>
31#include <xrpl/protocol/digest.h>
32
33namespace ripple {
34
35intr_ptr::SharedPtr<SHAMapTreeNode>
37 Slice data,
38 SHAMapHash const& hash,
39 bool hashValid)
40{
41 auto item =
43
44 if (hashValid)
45 return intr_ptr::make_shared<SHAMapTxLeafNode>(
46 std::move(item), 0, hash);
47
48 return intr_ptr::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 intr_ptr::make_shared<SHAMapTxPlusMetaLeafNode>(
75 std::move(item), 0, hash);
76
77 return intr_ptr::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 intr_ptr::make_shared<SHAMapAccountStateLeafNode>(
107 std::move(item), 0, hash);
108
109 return intr_ptr::make_shared<SHAMapAccountStateLeafNode>(
110 std::move(item), 0);
111}
112
115{
116 if (rawNode.empty())
117 return {};
118
119 auto const type = rawNode[rawNode.size() - 1];
120
121 rawNode.remove_suffix(1);
122
123 bool const hashValid = false;
124 SHAMapHash const hash;
125
126 if (type == wireTypeTransaction)
127 return makeTransaction(rawNode, hash, hashValid);
128
129 if (type == wireTypeAccountState)
130 return makeAccountState(rawNode, hash, hashValid);
131
132 if (type == wireTypeInner)
133 return SHAMapInnerNode::makeFullInner(rawNode, hash, hashValid);
134
135 if (type == wireTypeCompressedInner)
137
138 if (type == wireTypeTransactionWithMeta)
139 return makeTransactionWithMeta(rawNode, hash, hashValid);
140
141 Throw<std::runtime_error>(
142 "wire: Unknown type (" + std::to_string(type) + ")");
143}
144
147{
148 if (rawNode.size() < 4)
149 Throw<std::runtime_error>("prefix: short node");
150
151 // FIXME: Use SerialIter::get32?
152 // Extract the prefix
153 auto const type = safe_cast<HashPrefix>(
154 (safe_cast<std::uint32_t>(rawNode[0]) << 24) +
155 (safe_cast<std::uint32_t>(rawNode[1]) << 16) +
156 (safe_cast<std::uint32_t>(rawNode[2]) << 8) +
157 (safe_cast<std::uint32_t>(rawNode[3])));
158
159 rawNode.remove_prefix(4);
160
161 bool const hashValid = true;
162
163 if (type == HashPrefix::transactionID)
164 return makeTransaction(rawNode, hash, hashValid);
165
166 if (type == HashPrefix::leafNode)
167 return makeAccountState(rawNode, hash, hashValid);
168
169 if (type == HashPrefix::innerNode)
170 return SHAMapInnerNode::makeFullInner(rawNode, hash, hashValid);
171
172 if (type == HashPrefix::txNode)
173 return makeTransactionWithMeta(rawNode, hash, hashValid);
174
175 Throw<std::runtime_error>(
176 "prefix: unknown type (" +
178 ")");
179}
180
183{
184 return to_string(id);
185}
186
187} // 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)