diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 3d92818fe2..d61c23737e 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -251,6 +251,7 @@ struct controller_impl { named_thread_pool thread_pool; deep_mind_handler* deep_mind_logger = nullptr; bool okay_to_print_integrity_hash_on_stop = false; + std::atomic writing_snapshot = false; thread_local static platform_timer timer; // a copy for main thread and each read-only thread #if defined(EOSIO_EOS_VM_RUNTIME_ENABLED) || defined(EOSIO_EOS_VM_JIT_RUNTIME_ENABLED) @@ -3246,7 +3247,15 @@ fc::sha256 controller::calculate_integrity_hash() { try { void controller::write_snapshot( const snapshot_writer_ptr& snapshot ) { EOS_ASSERT( !my->pending, block_validate_exception, "cannot take a consistent snapshot with a pending block" ); - return my->add_to_snapshot(snapshot); + my->writing_snapshot.store(true, std::memory_order_release); + fc::scoped_exit> e = [&] { + my->writing_snapshot.store(false, std::memory_order_release); + }; + my->add_to_snapshot(snapshot); +} + +bool controller::is_writing_snapshot() const { + return my->writing_snapshot.load(std::memory_order_acquire); } int64_t controller::set_proposed_producers( vector producers ) { diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index e25a201050..b601b2f6c4 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -256,6 +256,8 @@ namespace eosio { namespace chain { fc::sha256 calculate_integrity_hash(); void write_snapshot( const snapshot_writer_ptr& snapshot ); + // thread-safe + bool is_writing_snapshot()const; bool sender_avoids_whitelist_blacklist_enforcement( account_name sender )const; void check_actor_list( const flat_set& actors )const; diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 984e3ce365..0e0d73defd 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -537,6 +537,14 @@ namespace eosio { void start_expire_timer(); void start_monitors(); + // we currently pause on snapshot generation + void wait_if_paused() const { + controller& cc = chain_plug->chain(); + while (cc.is_writing_snapshot()) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + void expire(); /** \name Peer Timestamps * Time message handling @@ -2897,6 +2905,8 @@ namespace eosio { return; } + my_impl->wait_if_paused(); + boost::asio::async_read( *socket, pending_message_buffer.get_buffer_sequence_for_boost_async_read(), completion_handler, boost::asio::bind_executor( strand,