1
0
Fork 0
forked from lthn/blockchain

daemon: checking for free space (--disable-stop-on-low-free-space was also added) + minor refactoring on critical errors handling

This commit is contained in:
sowle 2019-07-02 18:38:35 +03:00
parent 97e721f5f5
commit 9fc42dac53
8 changed files with 87 additions and 22 deletions

View file

@ -28,4 +28,5 @@ namespace command_line
const arg_descriptor<bool> arg_disable_upnp = { "disable-upnp", "Disable UPnP (enhances local network privacy)", false, true };
const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync = { "disable-stop-if-time-out-of-sync", "Do not stop the daemon if serious time synchronization problem is detected", false, true };
const arg_descriptor<bool> arg_disable_stop_on_low_free_space = { "disable-stop-on-low-free-space", "Do not stop the daemon if free space at data dir is critically low", false, true };
}

View file

@ -186,4 +186,5 @@ namespace command_line
extern const arg_descriptor<bool> arg_show_rpc_autodoc;
extern const arg_descriptor<bool> arg_disable_upnp;
extern const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync;
extern const arg_descriptor<bool> arg_disable_stop_on_low_free_space;
}

View file

@ -33,7 +33,7 @@ namespace currency
m_miner(this, m_blockchain_storage),
m_miner_address(boost::value_initialized<account_public_address>()),
m_starter_message_showed(false),
m_stop_handler(nullptr)
m_critical_error_handler(nullptr)
{
set_currency_protocol(pprotocol);
}
@ -48,9 +48,9 @@ namespace currency
m_mempool.set_protocol(m_pprotocol);
}
//-----------------------------------------------------------------------------------
void core::set_stop_handler(i_stop_handler *handler)
void core::set_critical_error_handler(i_critical_error_handler* handler)
{
m_stop_handler = handler;
m_critical_error_handler = handler;
}
//-----------------------------------------------------------------------------------
bool core::set_checkpoints(checkpoints&& chk_pts)
@ -685,6 +685,7 @@ namespace currency
}
m_prune_alt_blocks_interval.do_call([this](){return m_blockchain_storage.prune_aged_alt_blocks();});
m_check_free_space_interval.do_call([this](){ check_free_space(); return true; });
m_miner.on_idle();
m_mempool.on_idle();
return true;
@ -709,6 +710,17 @@ namespace currency
l->on_blockchain_update();
}
//-----------------------------------------------------------------------------------------------
#define MINIMUM_REQUIRED_FREE_SPACE_BYTES (1024 * 1024 * 100)
void core::check_free_space()
{
boost::filesystem::space_info si = boost::filesystem::space(m_config_folder);
if (si.available < MINIMUM_REQUIRED_FREE_SPACE_BYTES)
{
m_critical_error_handler->on_critical_low_free_space(si.available, MINIMUM_REQUIRED_FREE_SPACE_BYTES);
}
}
//-----------------------------------------------------------------------------------------------
}
#undef LOG_DEFAULT_CHANNEL

View file

@ -81,8 +81,8 @@ namespace currency
size_t get_alternative_blocks_count();
void set_currency_protocol(i_currency_protocol* pprotocol);
void set_stop_handler(i_stop_handler *handler);
i_stop_handler* get_stop_handler() const { return m_stop_handler; }
void set_critical_error_handler(i_critical_error_handler *handler);
i_critical_error_handler* get_critical_error_handler() const { return m_critical_error_handler; }
bool set_checkpoints(checkpoints&& chk_pts);
bool get_pool_transactions(std::list<transaction>& txs);
@ -136,17 +136,20 @@ namespace currency
void notify_blockchain_update_listeners();
void check_free_space();
blockchain_storage m_blockchain_storage;
tx_memory_pool m_mempool;
i_currency_protocol* m_pprotocol;
i_stop_handler* m_stop_handler;
i_critical_error_handler* m_critical_error_handler;
critical_section m_incoming_tx_lock;
miner m_miner;
account_public_address m_miner_address;
std::string m_config_folder;
currency_protocol_stub m_protocol_stub;
math_helper::once_a_time_seconds<60*60*12, false> m_prune_alt_blocks_interval;
math_helper::once_a_time_seconds<60, true> m_check_free_space_interval;
friend class tx_validate_inputs;
std::atomic<bool> m_starter_message_showed;

View file

@ -131,12 +131,10 @@ namespace currency
if (!add_time_delta_and_check_time_sync(context.m_time_delta))
{
// serious time sync problem detected
i_stop_handler* ish(m_core.get_stop_handler());
if (ish != nullptr)
i_critical_error_handler* ceh(m_core.get_critical_error_handler());
if (ceh != nullptr && ceh->on_critical_time_sync_error())
{
// this is daemon -- stop immediately
ish->stop_handling();
LOG_ERROR(ENDL << ENDL << "Serious time sync problem detected, daemon will stop immediately" << ENDL << ENDL);
// error is handled by a callee, should not be ignored here, stop processing immideately
return true;
}
}

View file

@ -40,9 +40,13 @@ namespace currency
/************************************************************************/
/* */
/************************************************************************/
struct i_stop_handler
struct i_critical_error_handler
{
virtual void stop_handling() = 0;
// called by currency protocol when the time is critically out of sync
// return true if the error is not ignored and the called should not proceed
virtual bool on_critical_time_sync_error() = 0;
virtual bool on_critical_low_free_space(uint64_t available, uint64_t required) = 0;
};

View file

@ -43,6 +43,49 @@ namespace po = boost::program_options;
bool command_line_preprocessor(const boost::program_options::variables_map& vm);
template<typename p2psrv_t>
struct core_critical_error_handler_t : public currency::i_critical_error_handler
{
core_critical_error_handler_t(daemon_commands_handler& dch, p2psrv_t& p2psrv, bool dont_stop_on_time_error, bool dont_stop_on_low_space)
: dch(dch)
, p2psrv(p2psrv)
, dont_stop_on_time_error(dont_stop_on_time_error)
, dont_stop_on_low_space(dont_stop_on_low_space)
{}
// interface currency::i_critical_error_handler
virtual bool on_critical_time_sync_error() override
{
if (dont_stop_on_time_error)
return false; // ignore such errors
LOG_ERROR(ENDL << ENDL << "Serious time sync problem detected, daemon will stop immediately" << ENDL << ENDL);
// stop handling
dch.stop_handling();
return true; // the caller must stop processing
}
// interface currency::i_critical_error_handler
virtual bool on_critical_low_free_space(uint64_t available, uint64_t required) override
{
if (dont_stop_on_low_space)
return false; // ignore such errors
LOG_ERROR(ENDL << ENDL << "Free space at data directory is critically low (" << available / (1024 * 1024) << " MB, while " << required / (1024 * 1024) << " MB is required), daemon will stop immediately" << ENDL << ENDL);
// stop handling
dch.stop_handling();
p2psrv.send_stop_signal();
return true; // the caller must stop processing
}
daemon_commands_handler& dch;
p2psrv_t& p2psrv;
bool dont_stop_on_time_error;
bool dont_stop_on_low_space;
};
int main(int argc, char* argv[])
{
try
@ -82,6 +125,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_cmd_sett, command_line::arg_show_details);
command_line::add_arg(desc_cmd_sett, command_line::arg_show_rpc_autodoc);
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_if_time_out_of_sync);
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_on_low_free_space);
arg_market_disable.default_value = true;
@ -89,7 +133,8 @@ int main(int argc, char* argv[])
currency::core::init_options(desc_cmd_sett);
currency::core_rpc_server::init_options(desc_cmd_sett);
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> >::init_options(desc_cmd_sett);
typedef nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > p2psrv_t;
p2psrv_t::init_options(desc_cmd_sett);
currency::miner::init_options(desc_cmd_sett);
bc_services::bc_offers_service::init_options(desc_cmd_sett);
currency::stratum_server::init_options(desc_cmd_sett);
@ -163,14 +208,16 @@ int main(int argc, char* argv[])
offers_service.set_disabled(true);
currency::core ccore(NULL);
currency::t_currency_protocol_handler<currency::core> cprotocol(ccore, NULL );
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > p2psrv(cprotocol);
p2psrv_t p2psrv(cprotocol);
currency::core_rpc_server rpc_server(ccore, p2psrv, offers_service);
cprotocol.set_p2p_endpoint(&p2psrv);
ccore.set_currency_protocol(&cprotocol);
daemon_commands_handler dch(p2psrv, rpc_server);
if (!command_line::get_arg(vm, command_line::arg_disable_stop_if_time_out_of_sync))
ccore.set_stop_handler(&dch);
core_critical_error_handler_t<p2psrv_t> cceh(dch, p2psrv,
command_line::get_arg(vm, command_line::arg_disable_stop_if_time_out_of_sync),
command_line::get_arg(vm, command_line::arg_disable_stop_on_low_free_space));
ccore.set_critical_error_handler(&cceh);
//ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service);
std::shared_ptr<currency::stratum_server> stratum_server_ptr;
@ -309,7 +356,7 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Deinitializing p2p...");
p2psrv.deinit();
ccore.set_stop_handler(nullptr);
ccore.set_critical_error_handler(nullptr);
ccore.set_currency_protocol(NULL);
cprotocol.set_p2p_endpoint(NULL);

View file

@ -20,7 +20,7 @@
PUSH_WARNINGS
DISABLE_VS_WARNINGS(4100)
class daemon_commands_handler : public currency::i_stop_handler
class daemon_commands_handler
{
typedef nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > srv_type;
srv_type& m_srv;
@ -75,8 +75,7 @@ public:
return true;
}
// interface currency::i_stop_handler
virtual void stop_handling() override
void stop_handling()
{
m_cmd_binder.stop_handling();
}