diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 6b801a1..cd9a594 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -57,6 +57,7 @@ static constexpr uint8_t default_consensus_id[HASH_SIZE] = { SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) : m_pool(pool) + , m_p2pServer(pool ? pool->p2p_server() : nullptr) , m_networkType(type) , m_chainTip(nullptr) , m_poolName(pool_name ? pool_name : "default") @@ -492,8 +493,8 @@ void SideChain::add_block(const PoolBlock& block) ); // Save it for faster syncing on the next p2pool start - if (m_pool->p2p_server()) { - m_pool->p2p_server()->store_in_cache(block); + if (m_p2pServer) { + m_p2pServer->store_in_cache(block); } PoolBlock* new_block = new PoolBlock(block); @@ -973,14 +974,14 @@ void SideChain::verify_loop(PoolBlock* block) // If it came through a broadcast, send it to our peers if (block->m_wantBroadcast && !block->m_broadcasted) { block->m_broadcasted = true; - if (m_pool->p2p_server() && (block->m_depth < UNCLE_BLOCK_DEPTH)) { - m_pool->p2p_server()->broadcast(*block); + if (m_p2pServer && (block->m_depth < UNCLE_BLOCK_DEPTH)) { + m_p2pServer->broadcast(*block); } } // Save it for faster syncing on the next p2pool start - if (m_pool->p2p_server()) { - m_pool->p2p_server()->store_in_cache(*block); + if (m_p2pServer) { + m_p2pServer->store_in_cache(*block); } // Try to verify blocks on top of this one @@ -1316,7 +1317,9 @@ void SideChain::update_chain_tip(PoolBlock* block) ", main chain height = " << log::Gray() << m_chainTip->m_txinGenHeight); block->m_wantBroadcast = true; - m_pool->update_block_template_async(); + if (m_pool) { + m_pool->update_block_template_async(); + } prune_old_blocks(); } } @@ -1332,7 +1335,7 @@ void SideChain::update_chain_tip(PoolBlock* block) m_pool->update_block_template_async(); } - if (m_pool->p2p_server() && block->m_wantBroadcast && !block->m_broadcasted) { + if (m_p2pServer && block->m_wantBroadcast && !block->m_broadcasted) { block->m_broadcasted = true; #ifdef DEBUG_BROADCAST_DELAY_MS struct Work @@ -1343,7 +1346,7 @@ void SideChain::update_chain_tip(PoolBlock* block) }; Work* work = new Work{}; work->req.data = work; - work->server = m_pool->p2p_server(); + work->server = m_p2pServer; work->block = block; const int err = uv_queue_work(uv_default_loop(), &work->req, [](uv_work_t*) @@ -1362,7 +1365,7 @@ void SideChain::update_chain_tip(PoolBlock* block) LOGERR(1, "update_chain_tip: uv_queue_work failed, error " << uv_err_name(err)); } #else - m_pool->p2p_server()->broadcast(*block); + m_p2pServer->broadcast(*block); #endif } } @@ -1583,7 +1586,9 @@ void SideChain::prune_old_blocks() // If side-chain started pruning blocks it means the initial sync is complete // It's now safe to delete cached blocks - m_pool->p2p_server()->clear_cached_blocks(); + if (m_p2pServer) { + m_p2pServer->clear_cached_blocks(); + } } } diff --git a/src/side_chain.h b/src/side_chain.h index f406533..ec7292d 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -23,6 +23,7 @@ namespace p2pool { class p2pool; +class P2PServer; struct DifficultyData; struct PoolBlock; class Wallet; @@ -71,10 +72,13 @@ public: time_t last_updated() const; bool is_default() const; + const PoolBlock* chainTip() const { return m_chainTip; } + static bool split_reward(uint64_t reward, const std::vector& shares, std::vector& rewards); private: p2pool* m_pool; + P2PServer* m_p2pServer; NetworkType m_networkType; private: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b2a1915..04575e0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -152,3 +152,4 @@ add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES}) target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} ${LIBS}) add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/crypto_tests.txt" $) add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/mainnet_test2_block.dat" $) +add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/sidechain_dump.dat" $) diff --git a/tests/src/pool_block_tests.cpp b/tests/src/pool_block_tests.cpp index 37e43f6..2fba68c 100644 --- a/tests/src/pool_block_tests.cpp +++ b/tests/src/pool_block_tests.cpp @@ -16,6 +16,7 @@ */ #include "common.h" +#include "crypto.h" #include "pool_block.h" #include "pow_hash.h" #include "side_chain.h" @@ -100,4 +101,43 @@ TEST(pool_block, deserialize) ASSERT_EQ(b.m_difficulty.check_pow(pow_hash), true); } +TEST(pool_block, verify) +{ + init_crypto_cache(); + + PoolBlock b; + SideChain sidechain(nullptr, NetworkType::Mainnet); + + std::ifstream f("sidechain_dump.dat", std::ios::binary | std::ios::ate); + ASSERT_EQ(f.good() && f.is_open(), true); + + std::vector buf(f.tellg()); + f.seekg(0); + f.read(reinterpret_cast(buf.data()), buf.size()); + ASSERT_EQ(f.good(), true); + + for (const uint8_t *p = buf.data(), *e = buf.data() + buf.size(); p < e;) { + ASSERT_TRUE(p + sizeof(uint32_t) <= e); + const uint32_t n = *reinterpret_cast(p); + p += sizeof(uint32_t); + + ASSERT_TRUE(p + n <= e); + ASSERT_EQ(b.deserialize(p, n, sidechain), 0); + p += n; + + sidechain.add_block(b); + ASSERT_TRUE(sidechain.has_block(b.m_sidechainId)); + } + + const PoolBlock* tip = sidechain.chainTip(); + ASSERT_TRUE(tip != nullptr); + ASSERT_TRUE(tip->m_verified); + ASSERT_FALSE(tip->m_invalid); + + ASSERT_EQ(tip->m_txinGenHeight, 2483901); + ASSERT_EQ(tip->m_sidechainHeight, 522805); + + destroy_crypto_cache(); +} + } diff --git a/tests/src/sidechain_dump.dat b/tests/src/sidechain_dump.dat new file mode 100644 index 0000000..124312e Binary files /dev/null and b/tests/src/sidechain_dump.dat differ