diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 3efb8c3c3..ad246d85e 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -605,6 +605,13 @@ public: */ virtual void sync() = 0; + /** + * @brief toggle safe syncs for the DB + * + * Used to switch DBF_SAFE on or off after starting up with DBF_FAST. + */ + virtual void safesyncmode(const bool onoff) = 0; + /** * @brief Remove everything from the BlockchainDB * diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index a756c04c6..4100d9cca 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1318,6 +1318,11 @@ void BlockchainLMDB::sync() } } +void BlockchainLMDB::safesyncmode(const bool onoff) +{ + mdb_env_set_flags(m_env, MDB_NOSYNC|MDB_MAPASYNC, !onoff); +} + void BlockchainLMDB::reset() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 14e5d34e2..3a11ddf0d 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -165,6 +165,8 @@ public: virtual void sync(); + virtual void safesyncmode(const bool onoff); + virtual void reset(); virtual std::vector get_filenames() const; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 7ecdae48c..c1faa703f 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -131,7 +131,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_hardfork(NULL), m_timestamps_and_difficulties_height(0), m_current_block_cumul_sz_limit(0), - 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_show_time_stats(false), m_sync_counter(0), m_cancel(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_db_default_sync(false), m_fast_sync(true), m_show_time_stats(false), m_sync_counter(0), m_cancel(false) { LOG_PRINT_L3("Blockchain::" << __func__); } @@ -4042,12 +4042,29 @@ bool Blockchain::for_all_txpool_txes(std::functionsafesyncmode(onoff); + m_db_sync_mode = onoff ? db_nosync : db_async; + } +} + HardFork::State Blockchain::get_hard_fork_state() const { return m_hardfork->get_state(); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 7fa78584b..b8ea657b4 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -65,6 +65,7 @@ namespace cryptonote */ enum blockchain_db_sync_mode { + db_defaultsync, //!< user didn't specify, use db_async db_sync, //!< handle syncing calls instead of the backing db, synchronously db_async, //!< handle syncing calls instead of the backing db, asynchronously db_nosync //!< Leave syncing up to the backing db (safest, but slowest because of disk I/O) @@ -700,6 +701,11 @@ namespace cryptonote void set_user_options(uint64_t maxthreads, uint64_t blocks_per_sync, blockchain_db_sync_mode sync_mode, bool fast_sync); + /** + * @brief Put DB in safe sync mode + */ + void safesyncmode(const bool onoff); + /** * @brief set whether or not to show/print time statistics * @@ -932,6 +938,7 @@ namespace cryptonote blockchain_db_sync_mode m_db_sync_mode; bool m_fast_sync; bool m_show_time_stats; + bool m_db_default_sync; uint64_t m_db_blocks_per_sync; uint64_t m_max_prepare_blocks_threads; uint64_t m_fake_pow_calc_time; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index a7f6ca36c..c406dd0b4 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -322,7 +322,7 @@ namespace cryptonote const std::string filename = folder.string(); // default to fast:async:1 - blockchain_db_sync_mode sync_mode = db_async; + blockchain_db_sync_mode sync_mode = db_defaultsync; uint64_t blocks_per_sync = 1; try @@ -355,11 +355,15 @@ namespace cryptonote sync_mode = db_nosync; } else if(options[0] == "fast") + { db_flags = DBF_FAST; + sync_mode = db_async; + } else if(options[0] == "fastest") { db_flags = DBF_FASTEST; blocks_per_sync = 1000; // default to fastest:async:1000 + sync_mode = db_async; } else db_flags = DEFAULT_FLAGS; @@ -1039,6 +1043,11 @@ namespace cryptonote m_miner.on_synchronized(); } //----------------------------------------------------------------------------------------------- + void core::safesyncmode(const bool onoff) + { + m_blockchain_storage.safesyncmode(onoff); + } + //----------------------------------------------------------------------------------------------- bool core::add_new_block(const block& b, block_verification_context& bvc) { return m_blockchain_storage.add_new_block(b, bvc); diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 84f59919e..f565afd87 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -620,6 +620,13 @@ namespace cryptonote */ void on_synchronized(); + /** + * @copydoc Blockchain::safesyncmode + * + * 2note see Blockchain::safesyncmode + */ + void safesyncmode(const bool onoff); + /** * @brief sets the target blockchain height * diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index f27a5d7b8..e762cf9c8 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -303,6 +303,7 @@ namespace cryptonote << " [Your node is " << abs_diff << " blocks (" << ((abs_diff - diff_v2) / (24 * 60 * 60 / DIFFICULTY_TARGET_V1)) + (diff_v2 / (24 * 60 * 60 / DIFFICULTY_TARGET_V2)) << " days) " << (0 <= diff ? std::string("behind") : std::string("ahead")) << "] " << ENDL << "SYNCHRONIZATION started"); + m_core.safesyncmode(false); } LOG_PRINT_L1("Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id); context.m_state = cryptonote_connection_context::state_synchronizing; @@ -1513,6 +1514,7 @@ skip: << "**********************************************************************"); m_core.on_synchronized(); } + m_core.safesyncmode(true); return true; } //------------------------------------------------------------------------------------------------------------------------ diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index 516d1f515..c4fb462e3 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -66,6 +66,7 @@ namespace tests public: void on_synchronized(){} + void safesyncmode(const bool){} uint64_t get_current_blockchain_height(){return 1;} void set_target_blockchain_height(uint64_t) {} bool init(const boost::program_options::variables_map& vm); diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index 627e85348..bcffc85c9 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -43,6 +43,7 @@ class test_core { public: void on_synchronized(){} + void safesyncmode(const bool){} uint64_t get_current_blockchain_height() const {return 1;} void set_target_blockchain_height(uint64_t) {} bool init(const boost::program_options::variables_map& vm) {return true ;} diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index 598b3b7b2..c30feb461 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -47,6 +47,7 @@ public: virtual void open(const std::string& filename, const int db_flags = 0) { } virtual void close() {} virtual void sync() {} + virtual void safesyncmode(const bool onoff) {} virtual void reset() {} virtual std::vector get_filenames() const { return std::vector(); } virtual std::string get_db_name() const { return std::string(); }