diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp index 8a78c756..583c3abf 100644 --- a/src/cryptonote_protocol/block_queue.cpp +++ b/src/cryptonote_protocol/block_queue.cpp @@ -76,6 +76,22 @@ void block_queue::flush_spans(const boost::uuids::uuid &connection_id, bool all) } } +void block_queue::flush_stale_spans(const std::set &live_connections) +{ + boost::unique_lock lock(mutex); + block_map::iterator i = blocks.begin(); + if (i != blocks.end() && is_blockchain_placeholder(*i)) + ++i; + while (i != blocks.end()) + { + block_map::iterator j = i++; + if (live_connections.find(j->connection_id) == live_connections.end() && j->blocks.size() == 0) + { + blocks.erase(j); + } + } +} + void block_queue::remove_span(uint64_t start_block_height) { boost::unique_lock lock(mutex); diff --git a/src/cryptonote_protocol/block_queue.h b/src/cryptonote_protocol/block_queue.h index 317566b1..c75ebc0b 100644 --- a/src/cryptonote_protocol/block_queue.h +++ b/src/cryptonote_protocol/block_queue.h @@ -70,6 +70,7 @@ namespace cryptonote void add_blocks(uint64_t height, std::list bcel, const boost::uuids::uuid &connection_id, float rate, size_t size); void add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time = boost::date_time::min_date_time); void flush_spans(const boost::uuids::uuid &connection_id, bool all = false); + void flush_stale_spans(const std::set &live_connections); void remove_span(uint64_t start_block_height); void remove_spans(const boost::uuids::uuid &connection_id, uint64_t start_block_height); void mark_last_block(uint64_t last_block_height); diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index da250714..9f44a13b 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -1189,6 +1189,14 @@ skip: { m_block_queue.mark_last_block(m_core.get_current_blockchain_height() - 1); + // flush stale spans + std::set live_connections; + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ + live_connections.insert(context.m_connection_id); + return true; + }); + m_block_queue.flush_stale_spans(live_connections); + // if we don't need to get next span, and the block queue is full enough, wait a bit bool start_from_current_chain = false; if (!force_next_span)