xrpld
Loading...
Searching...
No Matches
LedgerNodeHelpers.cpp
1#include <xrpld/app/ledger/LedgerNodeHelpers.h>
2
3#include <xrpl/basics/Slice.h>
4#include <xrpl/beast/utility/instrumentation.h>
5#include <xrpl/shamap/SHAMap.h>
6#include <xrpl/shamap/SHAMapLeafNode.h>
7#include <xrpl/shamap/SHAMapNodeID.h>
8#include <xrpl/shamap/SHAMapTreeNode.h>
9
10#include <xrpl.pb.h>
11
12#include <exception>
13#include <optional>
14#include <string_view>
15
16namespace xrpl {
17
20{
21 auto const slice = makeSlice(data);
22 try
23 {
24 return SHAMapTreeNode::makeFromWire(slice);
25 }
26 catch (std::exception const&)
27 {
28 return {};
29 }
30}
31
33getSHAMapNodeID(protocol::TMLedgerNode const& ledgerNode, SHAMapTreeNode const& treeNode)
34{
35 if (ledgerNode.has_id() || ledgerNode.has_depth())
36 {
37 // Reject ambiguous messages that mix the legacy and new reference fields.
38 if (ledgerNode.has_nodeid())
39 return std::nullopt;
40
41 if (treeNode.isInner())
42 {
43 if (!ledgerNode.has_id())
44 return std::nullopt;
45
46 REACHABLE("xrpl::getSHAMapNodeID : inner node ID from id field");
47 return deserializeSHAMapNodeID(ledgerNode.id());
48 }
49
50 if (treeNode.isLeaf())
51 {
52 SOMETIMES(
53 ledgerNode.has_depth() && ledgerNode.depth() > SHAMap::kLeafDepth,
54 "xrpl::getSHAMapNodeID : leaf depth exceeds max");
55 if (!ledgerNode.has_depth() || ledgerNode.depth() > SHAMap::kLeafDepth)
56 return std::nullopt;
57
58 auto const key = leafKey(treeNode);
59 REACHABLE("xrpl::getSHAMapNodeID : leaf node ID reconstructed from depth");
60 return SHAMapNodeID::createID(ledgerNode.depth(), key);
61 }
62 // LCOV_EXCL_START
63 UNREACHABLE("xrpl::getSHAMapNodeID : tree node is neither inner nor leaf");
64 return std::nullopt;
65 // LCOV_EXCL_STOP
66 }
67
68 if (!ledgerNode.has_nodeid())
69 return std::nullopt;
70
71 auto nodeID = deserializeSHAMapNodeID(ledgerNode.nodeid());
72 if (!nodeID.has_value())
73 return std::nullopt;
74
75 if (treeNode.isLeaf())
76 {
77 auto const key = leafKey(treeNode);
78 auto const expectedID = SHAMapNodeID::createID(static_cast<int>(nodeID->getDepth()), key);
79 SOMETIMES(
80 nodeID->getNodeID() != expectedID.getNodeID(),
81 "xrpl::getSHAMapNodeID : legacy leaf ID inconsistent with key");
82 if (nodeID->getNodeID() != expectedID.getNodeID())
83 return std::nullopt;
84 }
85
86 return nodeID;
87}
88
89} // namespace xrpl
static SHAMapNodeID createID(int depth, uint256 const &key)
Create a SHAMapNodeID of a node with the depth of the node and the key of a leaf.
static SHAMapTreeNodePtr makeFromWire(Slice rawNode)
virtual bool isLeaf() const =0
Determines if this is a leaf node.
virtual bool isInner() const =0
Determines if this is an inner node.
static constexpr unsigned int kLeafDepth
The depth of the hash map: data is only present in the leaves.
Definition SHAMap.h:144
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
intr_ptr::SharedPtr< SHAMapTreeNode > SHAMapTreeNodePtr
uint256 const & leafKey(SHAMapTreeNode const &node)
Return the key of the item held by a SHAMap leaf node.
std::optional< SHAMapNodeID > getSHAMapNodeID(protocol::TMLedgerNode const &ledgerNode, SHAMapTreeNode const &treeNode)
Extracts or reconstructs the SHAMapNodeID from a ledger node proto message.
SHAMapTreeNodePtr getTreeNode(std::string_view data)
Deserializes a SHAMapTreeNode from wire format data.
Slice makeSlice(std::array< T, N > const &a)
Definition Slice.h:228
std::optional< SHAMapNodeID > deserializeSHAMapNodeID(void const *data, std::size_t size)
Return an object representing a serialized SHAMap Node ID.