Skip to content

Commit dacae0c

Browse files
committed
the root node has no sibling
1 parent 498e16f commit dacae0c

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

src/merkle_tree.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,9 @@ namespace {
384384
// already-known hash is backed by downloaded data (set_block()),
385385
// and only that may be reported as passed below.
386386
bool const insert_root_already_known = has_node(insert_root_idx);
387+
// insert_root_idx > 0 since the root node has no sibling.
387388
bool const sibling_already_known = !uncle_hashes.empty() && insert_root_idx >= first_leaf
389+
&& insert_root_idx > 0
388390
&& insert_root_idx - first_leaf < m_num_blocks
389391
&& has_node(merkle_get_sibling(insert_root_idx));
390392

@@ -398,13 +400,10 @@ namespace {
398400
// successful return means anything touched is proven correct. With
399401
// no uncle hashes there was no walk, so the sibling wasn't touched
400402
// and nothing was learned about it.
401-
if (!uncle_hashes.empty()
403+
if (!uncle_hashes.empty() && insert_root_idx > 0
402404
&& insert_root_idx >= first_leaf && insert_root_idx - first_leaf < m_num_blocks)
403405
{
404-
// insert_root_idx == 0 only happens for a single-block tree, where
405-
// the root is the leaf itself and has no sibling. callers (e.g.
406-
// hash_picker) are expected to reject such requests before they
407-
// reach here.
406+
// the root node has no sibling.
408407
TORRENT_ASSERT(insert_root_idx > 0);
409408
int const sibling_idx = merkle_get_sibling(insert_root_idx);
410409
int const sibling_block = sibling_idx - first_leaf;

test/test_merkle_tree.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,3 +1176,17 @@ TORRENT_TEST(single_block_tree_allocate_full_preserves_verified_bit)
11761176

11771177
TEST_CHECK(t.blocks_verified(0, 1));
11781178
}
1179+
1180+
// insert_root_idx == 0 only happens for a single-block tree, where the root
1181+
// is the leaf itself and has no sibling. merkle_get_sibling() asserts
1182+
// tree_node > 0, so add_hashes() must not evaluate it for this tree's lone
1183+
// leaf, even when a peer sends a (bogus, since none can exist) non-empty
1184+
// uncle_hashes list for it.
1185+
TORRENT_TEST(add_hashes_single_block_tree_rejects_uncle_hashes)
1186+
{
1187+
aux::merkle_tree t(1, 1, f[0].data());
1188+
1189+
std::vector<sha256_hash> const bogus_proof{rand_sha256()};
1190+
auto const result = t.add_hashes(0, pdiff(0), range(f, 0, 1), bogus_proof);
1191+
TEST_CHECK(!result);
1192+
}

0 commit comments

Comments
 (0)