Skip to content

Commit f7efb9c

Browse files
committed
Fix merge_merkle().
1 parent 2d137e2 commit f7efb9c

2 files changed

Lines changed: 15 additions & 15 deletions

File tree

include/bitcoin/database/impl/query/merkle.ipp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define LIBBITCOIN_DATABASE_QUERY_MERKLE_IPP
2121

2222
#include <algorithm>
23+
#include <iterator>
2324
#include <ranges>
2425
#include <utility>
2526
#include <bitcoin/database/define.hpp>
@@ -77,17 +78,18 @@ CLASS::hash_option CLASS::get_confirmed_interval(size_t height) const NOEXCEPT
7778
TEMPLATE
7879
void CLASS::merge_merkle(hashes& to, hashes&& from, size_t first) NOEXCEPT
7980
{
80-
// from is either even or has one additional element of reserved space.
81+
// From is either even or has one additional element of reserved space.
8182
if (!is_one(from.size()) && is_odd(from.size()))
8283
from.push_back(from.back());
8384

84-
using namespace system;
8585
for (const auto& row: block::merkle_branch(first, from.size()))
8686
{
87-
BC_ASSERT(add1(row.sibling) * row.width <= from.size());
88-
const auto it = std::next(from.begin(), row.sibling * row.width);
89-
const auto mover = std::make_move_iterator(it);
90-
to.push_back(merkle_root({ mover, std::next(mover, row.width) }));
87+
if (const auto start = row.sibling * row.width; start < from.size())
88+
{
89+
const auto count = std::min(row.width, from.size() - start);
90+
auto it = std::make_move_iterator(std::next(from.begin(), start));
91+
to.push_back(partial_subroot({ it, std::next(it, count) }, row.width));
92+
}
9193
}
9294
}
9395

test/query/merkle.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,8 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_subroots__waypoint_zero__genesis)
408408
BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 0), error::success);
409409
BOOST_CHECK_EQUAL(roots.size(), 1u);
410410

411-
// At depth 2, 1 hash must be elevated twice, and paired twice.
412-
constexpr auto root00 = system::sha256::double_hash(test::block0_hash, test::block0_hash);
413-
constexpr auto root0000 = system::sha256::double_hash(root00, root00);
414-
BOOST_CHECK_EQUAL(roots[0], root0000);
411+
// At depth 2, the 1st position (block 0) the hash is the root.
412+
BOOST_CHECK_EQUAL(roots[0], test::block0_hash);
415413
}
416414

417415
BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_subroots__one_full_interval__expected_root)
@@ -434,7 +432,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_subroots__one_full_interval__expec
434432
BOOST_CHECK_EQUAL(query.get_merkle_subroots(roots, 3), error::success);
435433
BOOST_CHECK_EQUAL(roots.size(), 1u);
436434

437-
// At depth 2, the 4th position (block 3) results in a simple root.
435+
// At depth 2, the 4th position (block 3) results in an interval subroot as the root.
438436
BOOST_CHECK_EQUAL(roots[0], root03);
439437
}
440438

@@ -573,7 +571,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_
573571
BOOST_CHECK_EQUAL(proof[0], test::block4_hash);
574572
BOOST_CHECK_EQUAL(proof[1], sub67);
575573
BOOST_CHECK_EQUAL(proof[2], sub03);
576-
BOOST_CHECK_EQUAL(proof[3], sub88);
574+
BOOST_CHECK_EQUAL(proof[3], sub88); // << FAIL
577575
}
578576

579577
BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_1__success)
@@ -621,7 +619,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_
621619
BOOST_CHECK_EQUAL(proof[0], test::block4_hash);
622620
BOOST_CHECK_EQUAL(proof[1], sub67);
623621
BOOST_CHECK_EQUAL(proof[2], sub03);
624-
BOOST_CHECK_EQUAL(proof[3], sub88);
622+
BOOST_CHECK_EQUAL(proof[3], sub88); // << FAIL
625623
}
626624

627625
BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_2__success)
@@ -756,7 +754,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_
756754
BOOST_CHECK_EQUAL(proof[0], test::block4_hash);
757755
BOOST_CHECK_EQUAL(proof[1], sub67);
758756
BOOST_CHECK_EQUAL(proof[2], sub03);
759-
BOOST_CHECK_EQUAL(proof[3], sub88);
757+
BOOST_CHECK_EQUAL(proof[3], sub88); // << FAIL
760758
}
761759

762760
BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_depth_11__success)
@@ -800,7 +798,7 @@ BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__electrumx_example_
800798
BOOST_CHECK_EQUAL(proof[0], test::block4_hash);
801799
BOOST_CHECK_EQUAL(proof[1], sub67);
802800
BOOST_CHECK_EQUAL(proof[2], sub03);
803-
BOOST_CHECK_EQUAL(proof[3], sub88);
801+
BOOST_CHECK_EQUAL(proof[3], sub88); // << FAIL
804802
}
805803

806804
BOOST_AUTO_TEST_CASE(query_merkle__get_merkle_root_and_proof__target_greater_than_waypoint__error_invalid_argument)

0 commit comments

Comments
 (0)