diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index 6c80d133..2c18ae5d 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -2192,6 +2192,11 @@ void BlockchainBDB::check_hard_fork_info() /* FIXME: Some other time */ } +void BlockchainBDB::drop_hard_fork_info() +{ + /* TODO */ +} + void BlockchainBDB::set_hard_fork_version(uint64_t height, uint8_t version) { LOG_PRINT_L3("BlockchainBDB::" << __func__); diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h index 8cac94f6..6db91aa1 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.h +++ b/src/blockchain_db/berkeleydb/db_bdb.h @@ -376,6 +376,7 @@ private: virtual void set_hard_fork_version(uint64_t height, uint8_t version); virtual uint8_t get_hard_fork_version(uint64_t height) const; virtual void check_hard_fork_info(); + virtual void drop_hard_fork_info(); /** * @brief convert a tx output to a blob for storage diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 1f4ee21c..4a140e5f 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -503,6 +503,7 @@ public: virtual void set_hard_fork_version(uint64_t height, uint8_t version) = 0; virtual uint8_t get_hard_fork_version(uint64_t height) const = 0; virtual void check_hard_fork_info() = 0; + virtual void drop_hard_fork_info() = 0; virtual bool is_read_only() const = 0; diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index c18db772..5982b9d9 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -2450,13 +2450,32 @@ void BlockchainLMDB::check_hard_fork_info() throw0(DB_ERROR("Failed to query m_hf_starting_heights")); if (db_stat1.ms_entries != db_stat2.ms_entries) { - mdb_drop(*txn_ptr, m_hf_starting_heights, 1); - mdb_drop(*txn_ptr, m_hf_versions, 1); + // Empty, but don't delete. This allows this function to be called after + // startup, after the subdbs have already been created, and rest of startup + // can proceed. If these don't exist, hard fork's init() will fail. + // + // If these are empty, hard fork's init() will repopulate the hard fork + // data. + mdb_drop(*txn_ptr, m_hf_starting_heights, 0); + mdb_drop(*txn_ptr, m_hf_versions, 0); } TXN_POSTFIX_SUCCESS(); } +void BlockchainLMDB::drop_hard_fork_info() +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX(0); + + mdb_drop(*txn_ptr, m_hf_starting_heights, 1); + mdb_drop(*txn_ptr, m_hf_versions, 1); + + TXN_POSTFIX_SUCCESS(); +} + void BlockchainLMDB::set_hard_fork_starting_height(uint8_t version, uint64_t height) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 48f4adb4..eb0704ab 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -236,6 +236,7 @@ private: virtual void set_hard_fork_version(uint64_t height, uint8_t version); virtual uint8_t get_hard_fork_version(uint64_t height) const; virtual void check_hard_fork_info(); + virtual void drop_hard_fork_info(); /** * @brief convert a tx output to a blob for storage diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 30090bd7..7eb493b6 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -469,6 +469,9 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, try { simple_core.add_block(b, block_size, cumulative_difficulty, coins_generated, txs); + #if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB) + simple_core.m_hardfork->add(b, h-1); + #endif } catch (const std::exception& e) { @@ -500,7 +503,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, catch (const std::exception& e) { std::cout << refresh_string; - LOG_PRINT_RED_L0("exception while reading from file, height=" << h); + LOG_PRINT_RED_L0("exception while reading from file, height=" << h << ": " << e.what()); return 2; } } // while @@ -557,6 +560,7 @@ int main(int argc, char* argv[]) const command_line::arg_descriptor arg_block_stop = {"block-stop", "Stop at block number", block_stop}; const command_line::arg_descriptor arg_batch_size = {"batch-size", "", db_batch_size}; const command_line::arg_descriptor arg_pop_blocks = {"pop-blocks", "Remove blocks from end of blockchain", num_blocks}; + const command_line::arg_descriptor arg_drop_hf = {"drop-hard-fork", "Drop hard fork subdbs", false}; const command_line::arg_descriptor arg_testnet_on = { "testnet" , "Run on testnet." @@ -589,6 +593,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_only, arg_count_blocks); command_line::add_arg(desc_cmd_only, arg_pop_blocks); + command_line::add_arg(desc_cmd_only, arg_drop_hf); command_line::add_arg(desc_cmd_only, command_line::arg_help); // call add_options() directly for these arguments since @@ -761,6 +766,15 @@ int main(int argc, char* argv[]) return 0; } +#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB) + if (! vm["drop-hard-fork"].defaulted()) + { + LOG_PRINT_L0("Dropping hard fork tables..."); + simple_core.m_storage.get_db().drop_hard_fork_info(); + return 0; + } +#endif + import_from_file(simple_core, import_file_path, block_stop); #endif diff --git a/src/blockchain_utilities/fake_core.h b/src/blockchain_utilities/fake_core.h index 245d535f..29f34026 100644 --- a/src/blockchain_utilities/fake_core.h +++ b/src/blockchain_utilities/fake_core.h @@ -36,12 +36,21 @@ using namespace cryptonote; +namespace +{ + // NOTE: These values should match blockchain.cpp + // TODO: Refactor + const uint64_t mainnet_hard_fork_version_1_till = 1009826; + const uint64_t testnet_hard_fork_version_1_till = 624633; +} + #if !defined(BLOCKCHAIN_DB) || BLOCKCHAIN_DB == DB_LMDB struct fake_core_lmdb { Blockchain m_storage; + HardFork* m_hardfork = nullptr; tx_memory_pool m_pool; bool support_batch; bool support_add_block; @@ -75,7 +84,13 @@ struct fake_core_lmdb throw; } - m_storage.init(db, use_testnet); + db->check_hard_fork_info(); + + uint64_t hard_fork_version_1_till = use_testnet ? testnet_hard_fork_version_1_till : mainnet_hard_fork_version_1_till; + m_hardfork = new HardFork(*db, 1, hard_fork_version_1_till); + + m_storage.init(db, m_hardfork, use_testnet); + if (do_batch) m_storage.get_db().set_batch_transactions(do_batch); support_batch = true; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index afc479a4..e43875bd 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -99,7 +99,7 @@ static const uint64_t testnet_hard_fork_version_1_till = 624633; //------------------------------------------------------------------ Blockchain::Blockchain(tx_memory_pool& tx_pool) : - m_db(), m_tx_pool(tx_pool), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), + m_db(), m_tx_pool(tx_pool), m_hardfork(), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false), m_enforce_dns_checkpoints(false), m_max_prepare_blocks_threads(4), m_db_blocks_per_sync(1), m_db_sync_mode(db_async), m_fast_sync(true), m_sync_counter(0) { LOG_PRINT_L3("Blockchain::" << __func__); @@ -271,14 +271,20 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain m_db = db; m_testnet = testnet; - if (m_testnet) { - m_hardfork = new HardFork(*db, 1, testnet_hard_fork_version_1_till); + if (m_hardfork == nullptr) + { + if (m_testnet) + m_hardfork = new HardFork(*db, 1, testnet_hard_fork_version_1_till); + else + m_hardfork = new HardFork(*db, 1, mainnet_hard_fork_version_1_till); + } + if (m_testnet) + { for (size_t n = 0; n < sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]); ++n) m_hardfork->add_fork(testnet_hard_forks[n].version, testnet_hard_forks[n].height, testnet_hard_forks[n].threshold, testnet_hard_forks[n].time); } else { - m_hardfork = new HardFork(*db, 1, mainnet_hard_fork_version_1_till); for (size_t n = 0; n < sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]); ++n) m_hardfork->add_fork(mainnet_hard_forks[n].version, mainnet_hard_forks[n].height, mainnet_hard_forks[n].threshold, mainnet_hard_forks[n].time); } @@ -340,6 +346,16 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain return true; } //------------------------------------------------------------------ +bool Blockchain::init(BlockchainDB* db, HardFork*& hf, const bool testnet, const bool fakechain) +{ + if (hf != nullptr) + m_hardfork = hf; + bool res = init(db, testnet, fakechain); + if (hf == nullptr) + hf = m_hardfork; + return res; +} +//------------------------------------------------------------------ bool Blockchain::store_blockchain() { LOG_PRINT_YELLOW("Blockchain::" << __func__, LOG_LEVEL_3); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 89f623f9..5299fed9 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -92,6 +92,7 @@ namespace cryptonote Blockchain(tx_memory_pool& tx_pool); bool init(BlockchainDB* db, const bool testnet = false, const bool fakechain = false); + bool init(BlockchainDB* db, HardFork*& hf, const bool testnet = false, const bool fakechain = false); bool deinit(); void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; }