diff --git a/src/merkle.cpp b/src/merkle.cpp index 11f800a..4b30c1c 100644 --- a/src/merkle.cpp +++ b/src/merkle.cpp @@ -26,6 +26,12 @@ namespace p2pool { void merkle_hash(const std::vector& hashes, root_hash& root) { const size_t count = hashes.size(); + + if (count == 0) { + root.clear(); + return; + } + const uint8_t* h = hashes[0].h; if (count == 1) { @@ -62,10 +68,15 @@ void merkle_hash(const std::vector& hashes, root_hash& root) void merkle_hash_full_tree(const std::vector& hashes, std::vector>& tree) { const size_t count = hashes.size(); - const uint8_t* h = hashes[0].h; tree.clear(); + if (count == 0) { + return; + } + + const uint8_t* h = hashes[0].h; + if (count == 1) { tree.push_back(hashes); } diff --git a/src/util.h b/src/util.h index ca5b681..d295834 100644 --- a/src/util.h +++ b/src/util.h @@ -175,6 +175,8 @@ template<> FORCEINLINE bool out_of_range(uint64_t) { return false; } template const uint8_t* readVarint(const uint8_t* data, const uint8_t* data_end, T& b) { + static_assert(std::is_unsigned_v, "readVarint works only with unsigned types"); + uint64_t result = 0; int k = 0; diff --git a/tests/src/block_template_tests.cpp b/tests/src/block_template_tests.cpp index 853c8a2..1a67cbc 100644 --- a/tests/src/block_template_tests.cpp +++ b/tests/src/block_template_tests.cpp @@ -236,6 +236,7 @@ TEST(block_template, submit_sidechain_block) ASSERT_EQ(sidechain.difficulty(), 219467); ASSERT_EQ(sidechain.blocksById().size(), 4487); + ASSERT_TRUE(sidechain.precalcFinished()); const PoolBlock* tip = sidechain.chainTip(); diff --git a/tests/src/main.cpp b/tests/src/main.cpp index 8a240e3..ba79e30 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -28,6 +28,7 @@ using namespace p2pool; int main(int argc, char** argv) { set_main_thread(); + p2pool_usage(); PoolBlock::s_precalculatedSharesLock = new ReadWriteLock(); diff --git a/tests/src/merkle_tests.cpp b/tests/src/merkle_tests.cpp index 87efbde..a9caff0 100644 --- a/tests/src/merkle_tests.cpp +++ b/tests/src/merkle_tests.cpp @@ -168,6 +168,17 @@ TEST(merkle, tree) } }; + // 0 leaves + uint32_t path_monero; + ASSERT_FALSE(tree_path(0, 0, &path_monero)); + + merkle_hash(std::vector(), root); + ASSERT_TRUE(root.empty()); + + std::vector> tree; + merkle_hash_full_tree(std::vector(), tree); + ASSERT_TRUE(tree.empty()); + // 1 leaf merkle_hash(hashes, root); ASSERT_EQ(root, input[0]); diff --git a/tests/src/util_tests.cpp b/tests/src/util_tests.cpp index 6977088..389f92b 100644 --- a/tests/src/util_tests.cpp +++ b/tests/src/util_tests.cpp @@ -80,6 +80,16 @@ TEST(util, varint) // Invalid value 2 uint8_t buf2[1] = { 0x80 }; ASSERT_EQ(readVarint(buf2, buf2 + 1, check), nullptr); + + // Invalid value 3 + uint8_t buf3[16]; + memset(buf3, 128, sizeof(buf3)); + ASSERT_EQ(readVarint(buf3, buf3 + sizeof(buf3), check), nullptr); + + // Invalid value 4 + uint32_t check2; + uint8_t buf4[] = {255, 255, 255, 255, 127}; + ASSERT_EQ(readVarint(buf4, buf4 + sizeof(buf4), check2), nullptr); } TEST(util, bsr)