#pragma once #include #include #include class IMMR; class MMRUtil { public: static mw::Hash CalcParentHash(const mmr::Index& index, const mw::Hash& left_hash, const mw::Hash& right_hash); static std::vector CalcPeakIndices(const uint64_t num_nodes); static boost::optional CalcBaggedPeak(const IMMR& mmr, const mmr::Index& peak_idx); static BitSet BuildCompactBitSet(const uint64_t num_leaves, const BitSet& unspent_leaf_indices); static BitSet DiffCompactBitSet(const BitSet& prev_compact, const BitSet& new_compact); /// /// An MMR can be rebuilt from the leaves and a small set of carefully chosen parent hashes. /// This calculates the positions of those parent hashes. /// /// The unspent leaf indices. /// The pruned parent positions. static BitSet CalcPrunedParents(const BitSet& unspent_leaf_indices); }; /// /// Iterates through MMR index positions at a single height, starting from left to right. /// struct SiblingIter { public: SiblingIter(const uint64_t height, const mmr::Index& last_node); bool Next(); const mmr::Index& Get() const noexcept { return m_next; } uint64_t GetPosition() const noexcept { return m_next.GetPosition(); } private: uint64_t m_height; mmr::Index m_lastNode; uint64_t m_baseInc; uint64_t m_siblingNum; mmr::Index m_next; };