3#include <xrpl/basics/Blob.h>
4#include <xrpl/basics/IntrusivePointer.h>
5#include <xrpl/basics/SHAMapHash.h>
6#include <xrpl/basics/base_uint.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/beast/utility/instrumentation.h>
9#include <xrpl/nodestore/NodeObject.h>
10#include <xrpl/protocol/Serializer.h>
11#include <xrpl/shamap/Family.h>
12#include <xrpl/shamap/SHAMapAddNode.h>
13#include <xrpl/shamap/SHAMapInnerNode.h>
14#include <xrpl/shamap/SHAMapItem.h>
15#include <xrpl/shamap/SHAMapLeafNode.h>
16#include <xrpl/shamap/SHAMapMissingNode.h>
17#include <xrpl/shamap/SHAMapNodeID.h>
18#include <xrpl/shamap/SHAMapTreeNode.h>
237 boost::intrusive_ptr<SHAMapItem const>
const&
239 boost::intrusive_ptr<SHAMapItem const>
const&
418 dump(
bool withHashes =
false)
const;
450 XRPL_ASSERT(!
stack_.empty(),
"xrpl::SHAMap::NodePathStack::top : non-empty stack");
457 XRPL_ASSERT(!
stack_.empty(),
"xrpl::SHAMap::NodePathStack::pop : non-empty stack");
473 XRPL_ASSERT(
stack_.empty(),
"xrpl::SHAMap::NodePathStack::pushRoot : empty stack");
486 XRPL_ASSERT(node,
"xrpl::SHAMap::NodePathStack::pushChild : non-null node input");
488 !
stack_.empty(),
"xrpl::SHAMap::NodePathStack::pushChild : non-empty stack");
489 auto childID =
stack_.top().second.getChildNodeID(branch);
493 "xrpl::SHAMap::NodePathStack::pushChild : inner node above leaf depth");
496 childID.isPrefixOf(
leafKey(*node)),
497 "xrpl::SHAMap::NodePathStack::pushChild : leaf key below branch");
498 stack_.emplace(std::move(node), std::move(childID));
568 template <
class Node>
575 template <
class Node>
646 boost::intrusive_ptr<SHAMapItem const>
const&
661 boost::intrusive_ptr<SHAMapItem const>
const& otherMapItem,
664 int& maxCount)
const;
837 XRPL_ASSERT(
map_,
"xrpl::SHAMap::ConstIterator::ConstIterator : non-null input");
840 item_ = temp->peekItem().get();
869 item_ = temp->peekItem().get();
891 "xrpl::operator==(SHAMap::const_iterator, SHAMap::const_iterator) : "
892 "inputs map do match");
A generic endpoint for log messages.
static constexpr unsigned int kBranchFactor
Each inner node has 16 children (the 'radix tree' part of the map).
Identifies a node inside a SHAMap.
pointer operator->() const
ConstIterator(ConstIterator const &other)=default
value_type const & reference
ConstIterator & operator=(ConstIterator const &other)=default
friend bool operator==(ConstIterator const &x, ConstIterator const &y)
std::forward_iterator_tag iterator_category
ConstIterator & operator++()
value_type const * pointer
reference operator*() const
std::ptrdiff_t difference_type
A path from the root of the map down to some node, pairing each node with the ID naming its position.
std::pair< SHAMapTreeNodePtr, SHAMapNodeID > const & top() const
std::stack< std::pair< SHAMapTreeNodePtr, SHAMapNodeID > > stack_
void pushChild(SHAMapTreeNodePtr node, unsigned int branch)
Extend the path to the child of the current node reached by branch.
void pushRoot(SHAMapTreeNodePtr node)
Start a path at the root of the map, whose ID is the zero-depth ID by definition.
void pushNode(SHAMapTreeNodePtr node, UInt256 const &target)
Extend the path to a node lying on the path to target.
bool fetchRoot(SHAMapHash const &hash, SHAMapSyncFilter const *filter)
bool addItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
Family const & family() const
SHAMapTreeNode * descendAsync(SHAMapInnerNode *parent, unsigned int branch, SHAMapSyncFilter const *filter, bool &pending, DescendCallback &&) const
bool hasLeafNode(UInt256 const &tag, SHAMapHash const &hash) const
Does this map have this leaf node?
SHAMapTreeNode * descend(SHAMapInnerNode *, unsigned int branch) const
ConstIterator upperBound(UInt256 const &id) const
Find the first item after the given item.
std::uint32_t cowid_
ID to distinguish this map for all others we're sharing nodes with.
SHAMapTreeNodePtr finishFetch(SHAMapHash const &hash, std::shared_ptr< NodeObject > const &object) const
void setLedgerSeq(std::uint32_t lseq)
static constexpr unsigned int kLeafDepth
The depth of the hash map: data is only present in the leaves.
SHAMapTreeNodePtr fetchNodeFromDB(SHAMapHash const &hash) const
bool getNodeFat(SHAMapNodeID const &wanted, std::vector< SHAMapNodeData > &data, bool fatLeaves, std::uint32_t depth) const
std::pair< boost::intrusive_ptr< SHAMapItem const >, boost::intrusive_ptr< SHAMapItem const > > DeltaItem
SHAMapTreeNodePtr cacheLookup(SHAMapHash const &hash) const
bool hasItem(UInt256 const &id) const
Does the tree have an item with the given ID?
int flushDirty(NodeObjectType t)
Flush modified nodes to the nodestore and convert them to shared.
static void gmnProcessDeferredReads(MissingNodes &)
static constexpr unsigned int kBranchFactor
Number of children each non-leaf node has (the 'radix tree' part of the map).
SHAMapTreeNodePtr descendNoStore(SHAMapInnerNode &, unsigned int branch) const
std::pair< boost::intrusive_ptr< SHAMapItem const >, boost::intrusive_ptr< SHAMapItem const > > DeltaRef
void dirtyUp(NodePathStack &stack, UInt256 const &target, SHAMapTreeNodePtr terminal)
Update hashes up to the root.
void visitDifferences(SHAMap const *have, std::function< bool(SHAMapTreeNode const &)> const &) const
Visit every node in this SHAMap that is not present in the specified SHAMap.
SHAMapTreeNodePtr fetchNode(SHAMapHash const &hash) const
bool walkMapParallel(std::vector< SHAMapMissingNode > &missingNodes, int maxMissing) const
void walkMap(std::vector< SHAMapMissingNode > &missingNodes, int maxMissing) const
bool hasInnerNode(SHAMapNodeID const &nodeID, SHAMapHash const &hash) const
Does this map have this inner node?
SHAMap(SHAMap const &)=delete
bool deepCompare(SHAMap &other) const
void gmnProcessNodes(MissingNodes &, MissingNodes::StackEntry &node)
SHAMap & operator=(SHAMap const &)=delete
SHAMapLeafNode const * peekFirstItem(NodePathStack &stack) const
void dump(bool withHashes=false) const
std::map< UInt256, DeltaItem > Delta
bool compare(SHAMap const &otherMap, Delta &differences, int maxCount) const
SHAMapTreeNode * descendThrow(SHAMapInnerNode *, unsigned int branch) const
SHAMapAddNode addRootNode(SHAMapHash const &hash, SHAMapTreeNodePtr rootNode, SHAMapSyncFilter const *filter)
Add a root node to the SHAMap during synchronization.
void serializeRoot(Serializer &s) const
Serializes the root in a format appropriate for sending over the wire.
std::shared_ptr< SHAMap > snapShot(bool isMutable) const
int unshare()
Convert any modified nodes to shared.
bool delItem(UInt256 const &id)
void visitLeaves(std::function< void(boost::intrusive_ptr< SHAMapItem const > const &)> const &) const
Visit every leaf node in this SHAMap.
SHAMapLeafNode * walkTowardsKey(UInt256 const &id, NodePathStack *stack=nullptr) const
Walk towards the specified id, returning the node.
bool updateGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
SHAMapAddNode addKnownNode(SHAMapNodeID const &nodeID, SHAMapTreeNodePtr treeNode, SHAMapSyncFilter const *filter)
Add a known node at a specific position in the SHAMap during synchronization.
void canonicalize(SHAMapHash const &hash, SHAMapTreeNodePtr &) const
SHAMapTreeNodePtr fetchNodeNT(SHAMapHash const &hash) const
SHAMapTreeNodePtr checkFilter(SHAMapHash const &hash, SHAMapSyncFilter const *filter) const
bool addGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
std::function< void(SHAMapTreeNodePtr, SHAMapHash const &)> DescendCallback
ConstIterator end() const
SHAMapTreeNodePtr writeNode(NodeObjectType t, SHAMapTreeNodePtr node) const
write and canonicalize modified node
SHAMapLeafNode * belowHelper(NodePathStack &stack, BelowDirection direction) const
Returns the first or last item at or below the node already on top of stack, extending stack with the...
ConstIterator boundHelper(UInt256 const &id, BelowDirection direction) const
Returns the nearest item strictly past id, in the given direction.
ConstIterator lowerBound(UInt256 const &id) const
Find the object with the greatest object id smaller than the input id.
intr_ptr::SharedPtr< Node > preFlushNode(intr_ptr::SharedPtr< Node > node) const
prepare a node to be modified before flushing
SHAMapLeafNode * findKey(UInt256 const &id) const
Return nullptr if key not found.
intr_ptr::SharedPtr< Node > unshareNode(intr_ptr::SharedPtr< Node >, SHAMapNodeID const &nodeID)
Unshare the node, allowing it to be modified.
boost::intrusive_ptr< SHAMapItem const > const & onlyBelow(SHAMapTreeNode *) const
If there is only one leaf below this node, get its contents.
std::uint32_t ledgerSeq_
The sequence of the ledger that this map references, if any.
int walkSubTree(bool doWrite, NodeObjectType t)
std::vector< std::pair< SHAMapNodeID, UInt256 > > getMissingNodes(int maxNodes, SHAMapSyncFilter const *filter)
Check for nodes in the SHAMap not available.
SHAMapHash getHash() const
ConstIterator begin() const
void visitNodes(std::function< bool(SHAMapTreeNode &)> const &function) const
Visit every node in this SHAMap.
std::optional< std::vector< Blob > > getProofPath(UInt256 const &key) const
Get the proof path of the key.
bool walkBranch(SHAMapTreeNode *node, boost::intrusive_ptr< SHAMapItem const > const &otherMapItem, bool isFirstMap, Delta &differences, int &maxCount) const
boost::intrusive_ptr< SHAMapItem const > const & peekItem(UInt256 const &id) const
SHAMapLeafNode const * peekNextItem(UInt256 const &id, NodePathStack &stack) const
static bool verifyProofPath(UInt256 const &rootHash, UInt256 const &key, std::vector< Blob > const &path)
Verify the proof path.
SharedIntrusive< T > SharedPtr
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
intr_ptr::SharedPtr< SHAMapTreeNode > SHAMapTreeNodePtr
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
NodeObjectType
The types of node objects.
UInt256 const & leafKey(SHAMapTreeNode const &node)
Return the key of the item held by a SHAMap leaf node.
unsigned int selectBranch(SHAMapNodeID const &id, UInt256 const &hash)
Returns the branch that would contain the given hash.
SHAMapState
Describes the current state of a given SHAMap.
@ Immutable
The map is set in stone and cannot be changed.
@ Invalid
The map is known to not be valid.
@ Synching
The map's hash is fixed but valid nodes may be missing and can be added.
@ Modifying
The map is in flux and objects can be added and removed.
std::vector< unsigned char > Blob
Storage for linear binary data.
@ Invalid
Timely, but invalid signature.
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
std::tuple< SHAMapInnerNode *, SHAMapNodeID, unsigned int, unsigned int, bool > StackEntry
std::vector< std::pair< SHAMapNodeID, UInt256 > > missingNodes
std::set< SHAMapHash > missingHashes
std::tuple< SHAMapInnerNode *, SHAMapNodeID, unsigned int, SHAMapTreeNodePtr > DeferredNode
std::vector< DeferredNode > finishedReads
MissingNodes & operator=(MissingNodes const &)=delete
MissingNodes(int max, SHAMapSyncFilter const *filter, int maxDefer, std::uint32_t generation)
MissingNodes(MissingNodes const &)=delete
SHAMapSyncFilter const * filter
std::map< SHAMapInnerNode *, SHAMapNodeID > resumes
std::stack< StackEntry, std::deque< StackEntry > > stack
std::condition_variable deferCondVar