diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index 635ff58..95bb0c3 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -2012,12 +2012,23 @@ bool P2PServer::P2PClient::on_block_request(const uint8_t* buf) P2PServer* server = static_cast(m_owner); std::vector blob; - if (!server->m_pool->side_chain().get_block_blob(id, blob) && !id.empty()) { + const PoolBlock* block = server->m_pool->side_chain().get_block_blob(id, blob); + + if (!block && !id.empty()) { LOGWARN(5, "got a request for block with id " << id << " but couldn't find it"); } + // Notifications about parent and uncle blocks to speed up syncing + std::vector notify_blocks; + + if (block && (m_protocolVersion >= PROTOCOL_VERSION_1_2)) { + notify_blocks.reserve(block->m_uncles.size() + 1); + notify_blocks.push_back(block->m_parent); + notify_blocks.insert(notify_blocks.end(), block->m_uncles.begin(), block->m_uncles.end()); + } + return server->send(this, - [this, &blob](uint8_t* buf, size_t buf_size) -> size_t + [this, &blob, ¬ify_blocks](uint8_t* buf, size_t buf_size) -> size_t { LOGINFO(5, "sending BLOCK_RESPONSE to " << static_cast(m_addrString)); @@ -2029,6 +2040,17 @@ bool P2PServer::P2PClient::on_block_request(const uint8_t* buf) uint8_t* p = buf; + if (buf_size >= 1 + sizeof(uint32_t) + len + notify_blocks.size() * (1 + HASH_SIZE)) { + for (const hash& id : notify_blocks) { + LOGINFO(5, "sending BLOCK_NOTIFY for " << id << " to " << static_cast(m_addrString)); + + *(p++) = static_cast(MessageId::BLOCK_NOTIFY); + + memcpy(p, id.h, HASH_SIZE); + p += HASH_SIZE; + } + } + *(p++) = static_cast(MessageId::BLOCK_RESPONSE); memcpy(p, &len, sizeof(uint32_t)); diff --git a/src/side_chain.cpp b/src/side_chain.cpp index ea5d9c9..b33fab8 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -739,7 +739,7 @@ void SideChain::watch_mainchain_block(const ChainMain& data, const hash& possibl m_watchBlockSidechainId = possible_id; } -bool SideChain::get_block_blob(const hash& id, std::vector& blob) const +const PoolBlock* SideChain::get_block_blob(const hash& id, std::vector& blob) const { ReadLock lock(m_sidechainLock); @@ -751,7 +751,7 @@ bool SideChain::get_block_blob(const hash& id, std::vector& blob) const // Don't return stale chain tip if (block && (block->m_txinGenHeight + 2 < m_pool->miner_data().height)) { - return false; + return nullptr; } } else { @@ -762,14 +762,14 @@ bool SideChain::get_block_blob(const hash& id, std::vector& blob) const } if (!block) { - return false; + return nullptr; } blob = block->serialize_mainchain_data(); const std::vector sidechain_data = block->serialize_sidechain_data(); blob.insert(blob.end(), sidechain_data.begin(), sidechain_data.end()); - return true; + return block; } bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::vector& blob, uv_loop_t* loop) const diff --git a/src/side_chain.h b/src/side_chain.h index 5b2b51b..d1f2d33 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -57,7 +57,7 @@ public: PoolBlock* find_block(const hash& id) const; void watch_mainchain_block(const ChainMain& data, const hash& possible_id); - bool get_block_blob(const hash& id, std::vector& blob) const; + const PoolBlock* get_block_blob(const hash& id, std::vector& blob) const; bool get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::vector& blob, uv_loop_t* loop) const; void print_status(bool obtain_sidechain_lock = true) const;