From 9a859844f496158b8237bbd08ff0f608dc5a6385 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 19 Aug 2017 19:36:51 +0100 Subject: [PATCH] Toggle SAFE syncmode on and off automatically If monerod is started with default sync mode, set it to SAFE after synchronization completes. Set it back to FAST if synchronization restarts (e.g. because another peer has a longer blockchain). If monerod is started with an explicit sync mode, none of this automation takes effect. --- src/blockchain_db/blockchain_db.h | 7 +++++++ src/blockchain_db/lmdb/db_lmdb.cpp | 5 +++++ src/blockchain_db/lmdb/db_lmdb.h | 2 ++ src/cryptonote_core/blockchain.cpp | 19 ++++++++++++++++++- src/cryptonote_core/blockchain.h | 7 +++++++ src/cryptonote_core/cryptonote_core.cpp | 6 +++++- .../cryptonote_protocol_handler.inl | 2 ++ tests/unit_tests/hardfork.cpp | 1 + 8 files changed, 47 insertions(+), 2 deletions(-) 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 14a990131..b3096e473 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -126,7 +126,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__); } @@ -4034,12 +4034,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 314f37246..a002f19a3 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -316,7 +316,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 @@ -349,11 +349,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; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index daefe88b7..87c02709a 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -295,6 +295,7 @@ namespace cryptonote << " [Your node is " << std::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.get_blockchain_storage().safesyncmode(false); } LOG_PRINT_L1("Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id); context.m_state = cryptonote_connection_context::state_synchronizing; @@ -1473,6 +1474,7 @@ skip: << "**********************************************************************"); m_core.on_synchronized(); } + m_core.get_blockchain_storage().safesyncmode(true); 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(); }