From 1208cc8fa4fc46f73d8963163a8815fde0a67927 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 23 Aug 2015 11:20:56 +0100 Subject: [PATCH 1/9] blockchain: match original code early out in rollback_blockchain_switching --- src/cryptonote_core/blockchain.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 09f8f8d7f..830335ff4 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -690,6 +690,12 @@ bool Blockchain::rollback_blockchain_switching(std::list& original_chain, LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); + // fail if rollback_height passed is too high + if (rollback_height > m_db->height()) + { + return true; + } + m_timestamps_and_difficulties_height = 0; // remove blocks from blockchain until we get back to where we should be. From a33dcdd400c5af96ab6fc254602a1fa89802e031 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 23 Aug 2015 11:21:39 +0100 Subject: [PATCH 2/9] blockchain: fix rollback height in failure path The original code rolls back to split_height, which can be different from the current height if a block was succesfully added but a subsequent one fails. --- src/cryptonote_core/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 830335ff4..d3044993a 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -768,7 +768,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::listheight()); + rollback_blockchain_switching(disconnected_chain, split_height); // FIXME: Why do we keep invalid blocks around? Possibly in case we hear // about them again so we can immediately dismiss them, but needs some From 5e3d56d6e398d69e16a552f8e8190143805c55e8 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 23 Aug 2015 11:23:03 +0100 Subject: [PATCH 3/9] blockchain: match original code's error return in switch_to_alternative_blockchain --- src/cryptonote_core/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index d3044993a..cf50a6cc4 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -797,8 +797,8 @@ bool Blockchain::switch_to_alternative_blockchain(std::list Date: Sun, 23 Aug 2015 11:24:12 +0100 Subject: [PATCH 4/9] blockchain: fix sizing of timestamps and cumulative_difficulty vectors --- src/cryptonote_core/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index cf50a6cc4..60b3938c9 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -856,8 +856,8 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std: // and timestamps from it alone else { - timestamps.resize(static_cast(DIFFICULTY_BLOCKS_COUNT)); - cumulative_difficulties.resize(static_cast(DIFFICULTY_BLOCKS_COUNT)); + timestamps.resize(std::min(alt_chain.size(), static_cast(DIFFICULTY_BLOCKS_COUNT))); + cumulative_difficulties.resize(std::min(alt_chain.size(), static_cast(DIFFICULTY_BLOCKS_COUNT))); size_t count = 0; size_t max_i = timestamps.size()-1; // get difficulties and timestamps from most recent blocks in alt chain From d16611360debef979c52d4dd0de941ce9dfa4936 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 23 Aug 2015 11:25:06 +0100 Subject: [PATCH 5/9] blockchain: rework loop to match the original code in complete_timestamps_vector --- src/cryptonote_core/blockchain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 60b3938c9..449ec9591 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1119,11 +1119,13 @@ bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vect size_t need_elements = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - timestamps.size(); CHECK_AND_ASSERT_MES(start_top_height < m_db->height(), false, "internal error: passed start_height not < " << " m_db->height() -- " << start_top_height << " >= " << m_db->height()); size_t stop_offset = start_top_height > need_elements ? start_top_height - need_elements : 0; - while (start_top_height != stop_offset) + do { timestamps.push_back(m_db->get_block_timestamp(start_top_height)); + if (start_top_height == 0) + break; --start_top_height; - } + } while (start_top_height != stop_offset); return true; } //------------------------------------------------------------------ From d28ca8ef4102f319450b19d9e5f3cd6effaf44f2 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 24 Aug 2015 18:35:34 +0100 Subject: [PATCH 6/9] blockchain: make some flag setting code closer to the original code It should not matter in practice, but it makes for simpler double checking when comparing both. --- src/cryptonote_core/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 449ec9591..2c65f70ff 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1279,8 +1279,8 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id bool r = switch_to_alternative_blockchain(alt_chain, true); - bvc.m_added_to_main_chain = r; - bvc.m_verifivation_failed = !r; + if (r) bvc.m_added_to_main_chain = true; + else bvc.m_verifivation_failed = true; return r; } From a474d66c980a9a8f7938340cc2d26ad063494248 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 24 Aug 2015 18:36:39 +0100 Subject: [PATCH 7/9] blockchain: fix offset/height comparisons in get_blocks --- src/cryptonote_core/blockchain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 2c65f70ff..d992176a8 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1316,7 +1316,7 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list m_db->height()) + if(start_offset >= m_db->height()) return false; if (!get_blocks(start_offset, count, blocks)) @@ -1338,10 +1338,10 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list m_db->height()) + if(start_offset >= m_db->height()) return false; - for(size_t i = start_offset; i < start_offset + count && i <= m_db->height();i++) + for(size_t i = start_offset; i < start_offset + count && i < m_db->height();i++) { blocks.push_back(m_db->get_block_from_height(i)); } From 0c8523711b86f18cb1ed5b93b0b171252ad26215 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 24 Aug 2015 18:39:08 +0100 Subject: [PATCH 8/9] blockchain: fix return value on out of range start offset The original code would go through the normal code and end up returning true with an empty set. --- src/cryptonote_core/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index d992176a8..56eae7901 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1712,7 +1712,7 @@ bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, cons // if requested height is higher than our chain, return false -- we can't help if (req_start_block >= m_db->height()) { - return false; + return true; } start_height = req_start_block; } From 008a54ddc4c2e8d914ea3d63e0d11679da0e427b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 24 Aug 2015 18:40:19 +0100 Subject: [PATCH 9/9] blockchain: change code to mirror original CN code I'm not quite sure the two are equivalent, so use the original CN expression for safety and verification purposes. --- src/cryptonote_core/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 56eae7901..5620466fc 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1195,7 +1195,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id // make sure block connects correctly to the main chain auto h = m_db->get_block_hash_from_height(alt_chain.front()->second.height - 1); CHECK_AND_ASSERT_MES(h == alt_chain.front()->second.bl.prev_id, false, "alternative chain has wrong connection to main chain"); - complete_timestamps_vector(m_db->get_block_height(alt_chain.front()->second.bl.prev_id), timestamps); + complete_timestamps_vector(alt_chain.front()->second.height - 1, timestamps); } // if block not associated with known alternate chain else