#ifndef XRPL_SHAMAP_SHAMAPNODEID_H_INCLUDED #define XRPL_SHAMAP_SHAMAPNODEID_H_INCLUDED #include #include #include #include #include namespace ripple { /** Identifies a node inside a SHAMap */ class SHAMapNodeID : public CountedObject { private: uint256 id_; unsigned int depth_ = 0; public: SHAMapNodeID() = default; SHAMapNodeID(SHAMapNodeID const& other) = default; SHAMapNodeID(unsigned int depth, uint256 const& hash); SHAMapNodeID& operator=(SHAMapNodeID const& other) = default; bool isRoot() const { return depth_ == 0; } // Get the wire format (256-bit nodeID, 1-byte depth) std::string getRawString() const; unsigned int getDepth() const { return depth_; } uint256 const& getNodeID() const { return id_; } SHAMapNodeID getChildNodeID(unsigned int m) const; /** * Create a SHAMapNodeID of a node with the depth of the node and * the key of a leaf * * @param depth the depth of the node * @param key the key of a leaf * @return SHAMapNodeID of the node */ static SHAMapNodeID createID(int depth, uint256 const& key); // FIXME-C++20: use spaceship and operator synthesis /** Comparison operators */ bool operator<(SHAMapNodeID const& n) const { return std::tie(depth_, id_) < std::tie(n.depth_, n.id_); } bool operator>(SHAMapNodeID const& n) const { return n < *this; } bool operator<=(SHAMapNodeID const& n) const { return !(n < *this); } bool operator>=(SHAMapNodeID const& n) const { return !(*this < n); } bool operator==(SHAMapNodeID const& n) const { return (depth_ == n.depth_) && (id_ == n.id_); } bool operator!=(SHAMapNodeID const& n) const { return !(*this == n); } }; inline std::string to_string(SHAMapNodeID const& node) { if (node.isRoot()) return "NodeID(root)"; return "NodeID(" + std::to_string(node.getDepth()) + "," + to_string(node.getNodeID()) + ")"; } inline std::ostream& operator<<(std::ostream& out, SHAMapNodeID const& node) { return out << to_string(node); } /** Return an object representing a serialized SHAMap Node ID * * @param s A string of bytes * @param data a non-null pointer to a buffer of @param size bytes. * @param size the size, in bytes, of the buffer pointed to by @param data. * @return A seated optional if the buffer contained a serialized SHAMap * node ID and an unseated optional otherwise. */ /** @{ */ [[nodiscard]] std::optional deserializeSHAMapNodeID(void const* data, std::size_t size); [[nodiscard]] inline std::optional deserializeSHAMapNodeID(std::string const& s) { return deserializeSHAMapNodeID(s.data(), s.size()); } /** @} */ /** Returns the branch that would contain the given hash */ [[nodiscard]] unsigned int selectBranch(SHAMapNodeID const& id, uint256 const& hash); } // namespace ripple #endif