git / moonbite-core / src/libmw/test/tests/mmr/Test_Segment.cpp · raw
// Copyright (c) 2022 The Litecoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <mw/mmr/MMR.h>#include <mw/mmr/MMRUtil.h>#include <mw/mmr/LeafSet.h>#include <mw/mmr/Segment.h>#include <boost/optional/optional_io.hpp>#include <test_framework/TestMWEB.h>namespace std {ostream& operator<<(ostream& os, const mw::Hash& hash){ os << hash.ToHex(); return os;}ostream& operator<<(ostream& os, const mmr::Leaf& leaf){ os << leaf.GetHash().ToHex(); return os;}} // namespace stdusing namespace mmr;struct MMRWithLeafset { IMMR::Ptr mmr; ILeafSet::Ptr leafset;};static mmr::Leaf DeterministicLeaf(const uint64_t i){ std::vector<uint8_t> serialized{ uint8_t(i >> 24), uint8_t(i >> 16), uint8_t(i >> 8), uint8_t(i)}; return mmr::Leaf::Create(mmr::LeafIndex::At(i), serialized);}static MMRWithLeafset BuildDetermininisticMMR(const uint64_t num_leaves){ auto mmr = std::make_shared<MemMMR>(); auto leafset = LeafSet::Open(GetDataDir(), 0); for (size_t i = 0; i < num_leaves; i++) { mmr->AddLeaf(DeterministicLeaf(i)); leafset->Add(mmr::LeafIndex::At(i)); } return MMRWithLeafset{mmr, leafset};}BOOST_FIXTURE_TEST_SUITE(TestSegment, MWEBTestingSetup)BOOST_AUTO_TEST_CASE(AssembleSegment){ auto mmr_with_leafset = BuildDetermininisticMMR(15); auto mmr = mmr_with_leafset.mmr; auto leafset = mmr_with_leafset.leafset; Segment segment = SegmentFactory::Assemble( *mmr, *leafset, mmr::LeafIndex::At(0), 4 ); std::vector<mmr::Leaf> expected_leaves{ DeterministicLeaf(0), DeterministicLeaf(1), DeterministicLeaf(2), DeterministicLeaf(3) }; BOOST_REQUIRE_EQUAL_COLLECTIONS(segment.leaves.begin(), segment.leaves.end(), expected_leaves.begin(), expected_leaves.end()); std::vector<mw::Hash> expected_hashes{ mmr->GetHash(mmr::Index::At(13)) }; BOOST_REQUIRE_EQUAL_COLLECTIONS(segment.hashes.begin(), segment.hashes.end(), expected_hashes.begin(), expected_hashes.end()); boost::optional<mw::Hash> expected_lower_peak = MMRUtil::CalcBaggedPeak(*mmr, mmr::Index::At(21)); BOOST_REQUIRE_EQUAL(expected_lower_peak, segment.lower_peak); // Verify PMMR root can be fully recomputed mw::Hash n2 = MMRUtil::CalcParentHash(mmr::Index::At(2), segment.leaves[0].GetHash(), segment.leaves[1].GetHash()); mw::Hash n5 = MMRUtil::CalcParentHash(mmr::Index::At(5), segment.leaves[2].GetHash(), segment.leaves[3].GetHash()); mw::Hash n6 = MMRUtil::CalcParentHash(mmr::Index::At(6), n2, n5); mw::Hash n14 = MMRUtil::CalcParentHash(mmr::Index::At(14), n6, segment.hashes[0]); mw::Hash root = MMRUtil::CalcParentHash(Index::At(26), n14, *segment.lower_peak); BOOST_REQUIRE_EQUAL(root, mmr->Root());}BOOST_AUTO_TEST_SUITE_END()