diff options
Diffstat (limited to 'src/cryptonote_core/blockchain.cpp')
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 25e97f71f..d1ef7d6fe 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -441,6 +441,53 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block()); m_db->block_txn_stop(); + uint64_t num_popped_blocks = 0; + while (true) + { + const uint64_t top_height = m_db->height() - 1; + const crypto::hash top_id = m_db->top_block_hash(); + const block top_block = m_db->get_top_block(); + const uint8_t ideal_hf_version = get_ideal_hard_fork_version(top_height); + if (ideal_hf_version <= 1 || ideal_hf_version == top_block.major_version) + { + if (num_popped_blocks > 0) + MGINFO("Initial popping done, top block: " << top_id << ", top height: " << top_height << ", block version: " << (uint64_t)top_block.major_version); + break; + } + else + { + if (num_popped_blocks == 0) + MGINFO("Current top block " << top_id << " at height " << top_height << " has version " << (uint64_t)top_block.major_version << " which disagrees with the ideal version " << (uint64_t)ideal_hf_version); + if (num_popped_blocks % 100 == 0) + MGINFO("Popping blocks... " << top_height); + ++num_popped_blocks; + block popped_block; + std::vector<transaction> popped_txs; + try + { + m_db->pop_block(popped_block, popped_txs); + } + // anything that could cause this to throw is likely catastrophic, + // so we re-throw + catch (const std::exception& e) + { + MERROR("Error popping block from blockchain: " << e.what()); + throw; + } + catch (...) + { + MERROR("Error popping block from blockchain, throwing!"); + throw; + } + } + } + if (num_popped_blocks > 0) + { + m_timestamps_and_difficulties_height = 0; + m_hardfork->reorganize_from_chain_height(get_current_blockchain_height()); + m_tx_pool.on_blockchain_dec(m_db->height()-1, get_tail_id()); + } + update_next_cumulative_size_limit(); return true; } @@ -584,6 +631,12 @@ block Blockchain::pop_block_from_blockchain() } } } + + m_blocks_longhash_table.clear(); + m_scan_table.clear(); + m_blocks_txs_check.clear(); + m_check_txin_table.clear(); + update_next_cumulative_size_limit(); m_tx_pool.on_blockchain_dec(m_db->height()-1, get_tail_id()); @@ -1903,7 +1956,7 @@ void Blockchain::get_output_key_mask_unlocked(const uint64_t& amount, const uint unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first)); } //------------------------------------------------------------------ -bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const +bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const { // rct outputs don't exist before v3 if (amount == 0) @@ -1924,22 +1977,7 @@ bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height, if (from_height > start_height) start_height = from_height; - distribution.clear(); - uint64_t db_height = m_db->height(); - if (start_height >= db_height) - return false; - distribution.resize(db_height - start_height, 0); - bool r = for_all_outputs(amount, [&](uint64_t height) { - CHECK_AND_ASSERT_MES(height >= real_start_height && height <= db_height, false, "Height not in expected range"); - if (height >= start_height) - distribution[height - start_height]++; - else - base++; - return true; - }); - if (!r) - return false; - return true; + return m_db->get_output_distribution(amount, start_height, to_height, distribution, base); } //------------------------------------------------------------------ // This function takes a list of block hashes from another node |