From 8330e772f1ed680a54833d25c4d17d09a99ab8d6 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 16 Sep 2019 12:18:34 +0000 Subject: monerod can now sync from pruned blocks If the peer (whether pruned or not itself) supports sending pruned blocks to syncing nodes, the pruned version will be sent along with the hash of the pruned data and the block weight. The original tx hashes can be reconstructed from the pruned txes and theur prunable data hash. Those hashes and the block weights are hashes and checked against the set of precompiled hashes, ensuring the data we received is the original data. It is currently not possible to use this system when not using the set of precompiled hashes, since block weights can not otherwise be checked for validity. This is off by default for now, and is enabled by --sync-pruned-blocks --- src/cryptonote_protocol/block_queue.cpp | 43 +++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'src/cryptonote_protocol/block_queue.cpp') diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp index b4f9daa74..67f0b3e5d 100644 --- a/src/cryptonote_protocol/block_queue.cpp +++ b/src/cryptonote_protocol/block_queue.cpp @@ -228,13 +228,14 @@ bool block_queue::have(const crypto::hash &hash) const return have_blocks.find(hash) != have_blocks.end(); } -std::pair block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector &block_hashes, boost::posix_time::ptime time) +std::pair block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, bool sync_pruned_blocks, uint32_t local_pruning_seed, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector> &block_hashes, boost::posix_time::ptime time) { boost::unique_lock lock(mutex); MDEBUG("reserve_span: first_block_height " << first_block_height << ", last_block_height " << last_block_height - << ", max " << max_blocks << ", seed " << epee::string_tools::to_string_hex(pruning_seed) << ", blockchain_height " << - blockchain_height << ", block hashes size " << block_hashes.size()); + << ", max " << max_blocks << ", peer seed " << epee::string_tools::to_string_hex(pruning_seed) << ", blockchain_height " << + blockchain_height << ", block hashes size " << block_hashes.size() << ", local seed " << epee::string_tools::to_string_hex(local_pruning_seed) + << ", sync_pruned_blocks " << sync_pruned_blocks); if (last_block_height < first_block_height || max_blocks == 0) { MDEBUG("reserve_span: early out: first_block_height " << first_block_height << ", last_block_height " << last_block_height << ", max_blocks " << max_blocks); @@ -248,22 +249,25 @@ std::pair block_queue::reserve_span(uint64_t first_block_hei // skip everything we've already requested uint64_t span_start_height = last_block_height - block_hashes.size() + 1; - std::vector::const_iterator i = block_hashes.begin(); - while (i != block_hashes.end() && requested_internal(*i)) + std::vector>::const_iterator i = block_hashes.begin(); + while (i != block_hashes.end() && requested_internal((*i).first)) { ++i; ++span_start_height; } - // if the peer's pruned for the starting block and its unpruned stripe comes next, start downloading from there - const uint32_t next_unpruned_height = tools::get_next_unpruned_block_height(span_start_height, blockchain_height, pruning_seed); - MDEBUG("reserve_span: next_unpruned_height " << next_unpruned_height << " from " << span_start_height << " and seed " - << epee::string_tools::to_string_hex(pruning_seed) << ", limit " << span_start_height + CRYPTONOTE_PRUNING_STRIPE_SIZE); - if (next_unpruned_height > span_start_height && next_unpruned_height < span_start_height + CRYPTONOTE_PRUNING_STRIPE_SIZE) + if (!sync_pruned_blocks) { - MDEBUG("We can download from next span: ideal height " << span_start_height << ", next unpruned height " << next_unpruned_height << - "(+" << next_unpruned_height - span_start_height << "), current seed " << pruning_seed); - span_start_height = next_unpruned_height; + // if the peer's pruned for the starting block and its unpruned stripe comes next, start downloading from there + const uint32_t next_unpruned_height = tools::get_next_unpruned_block_height(span_start_height, blockchain_height, pruning_seed); + MDEBUG("reserve_span: next_unpruned_height " << next_unpruned_height << " from " << span_start_height << " and seed " + << epee::string_tools::to_string_hex(pruning_seed) << ", limit " << span_start_height + CRYPTONOTE_PRUNING_STRIPE_SIZE); + if (next_unpruned_height > span_start_height && next_unpruned_height < span_start_height + CRYPTONOTE_PRUNING_STRIPE_SIZE) + { + MDEBUG("We can download from next span: ideal height " << span_start_height << ", next unpruned height " << next_unpruned_height << + "(+" << next_unpruned_height - span_start_height << "), current seed " << pruning_seed); + span_start_height = next_unpruned_height; + } } MDEBUG("span_start_height: " < block_queue::reserve_span(uint64_t first_block_hei } i = block_hashes.begin() + span_start_height - block_hashes_start_height; - while (i != block_hashes.end() && requested_internal(*i)) + while (i != block_hashes.end() && requested_internal((*i).first)) { ++i; ++span_start_height; @@ -282,9 +286,16 @@ std::pair block_queue::reserve_span(uint64_t first_block_hei uint64_t span_length = 0; std::vector hashes; - while (i != block_hashes.end() && span_length < max_blocks && tools::has_unpruned_block(span_start_height + span_length, blockchain_height, pruning_seed)) + bool first_is_pruned = sync_pruned_blocks && !tools::has_unpruned_block(span_start_height + span_length, blockchain_height, local_pruning_seed); + while (i != block_hashes.end() && span_length < max_blocks && (sync_pruned_blocks || tools::has_unpruned_block(span_start_height + span_length, blockchain_height, pruning_seed))) { - hashes.push_back(*i); + // if we want to sync pruned blocks, stop at the first block for which we need full data + if (sync_pruned_blocks && first_is_pruned == tools::has_unpruned_block(span_start_height + span_length, blockchain_height, local_pruning_seed)) + { + MDEBUG("Stopping at " << span_start_height + span_length << " for peer on stripe " << tools::get_pruning_stripe(pruning_seed) << " as we need full data for " << tools::get_pruning_stripe(local_pruning_seed)); + break; + } + hashes.push_back((*i).first); ++i; ++span_length; } -- cgit v1.2.3