mirror of
https://github.com/monero-project/monero.git
synced 2024-12-30 14:26:13 -05:00
Merge pull request #2373
a3662bae
cryptonote_protocol: error handling on cleanup_handle_incoming_blocks (moneromooo-monero)cf4aa653
Fix blockchain_import wedge on exception in cleanup_handle_incoming_blocks (moneromooo-monero)0ffad5a3
core: guard against exceptions in handle_incoming_{block,tx} (moneromooo-monero)
This commit is contained in:
commit
7369d746fd
@ -2604,6 +2604,16 @@ void BlockchainLMDB::batch_commit()
|
|||||||
memset(&m_wcursors, 0, sizeof(m_wcursors));
|
memset(&m_wcursors, 0, sizeof(m_wcursors));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlockchainLMDB::cleanup_batch()
|
||||||
|
{
|
||||||
|
// for destruction of batch transaction
|
||||||
|
m_write_txn = nullptr;
|
||||||
|
delete m_write_batch_txn;
|
||||||
|
m_write_batch_txn = nullptr;
|
||||||
|
m_batch_active = false;
|
||||||
|
memset(&m_wcursors, 0, sizeof(m_wcursors));
|
||||||
|
}
|
||||||
|
|
||||||
void BlockchainLMDB::batch_stop()
|
void BlockchainLMDB::batch_stop()
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
@ -2618,15 +2628,18 @@ void BlockchainLMDB::batch_stop()
|
|||||||
check_open();
|
check_open();
|
||||||
LOG_PRINT_L3("batch transaction: committing...");
|
LOG_PRINT_L3("batch transaction: committing...");
|
||||||
TIME_MEASURE_START(time1);
|
TIME_MEASURE_START(time1);
|
||||||
m_write_txn->commit();
|
try
|
||||||
TIME_MEASURE_FINISH(time1);
|
{
|
||||||
time_commit1 += time1;
|
m_write_txn->commit();
|
||||||
// for destruction of batch transaction
|
TIME_MEASURE_FINISH(time1);
|
||||||
m_write_txn = nullptr;
|
time_commit1 += time1;
|
||||||
delete m_write_batch_txn;
|
cleanup_batch();
|
||||||
m_write_batch_txn = nullptr;
|
}
|
||||||
m_batch_active = false;
|
catch (const std::exception &e)
|
||||||
memset(&m_wcursors, 0, sizeof(m_wcursors));
|
{
|
||||||
|
cleanup_batch();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
LOG_PRINT_L3("batch transaction: end");
|
LOG_PRINT_L3("batch transaction: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +368,9 @@ private:
|
|||||||
// migrate from DB version 0 to 1
|
// migrate from DB version 0 to 1
|
||||||
void migrate_0_1();
|
void migrate_0_1();
|
||||||
|
|
||||||
|
void cleanup_batch();
|
||||||
|
|
||||||
|
private:
|
||||||
MDB_env* m_env;
|
MDB_env* m_env;
|
||||||
|
|
||||||
MDB_dbi m_blocks;
|
MDB_dbi m_blocks;
|
||||||
|
@ -208,7 +208,8 @@ int check_flush(cryptonote::core &core, std::list<block_complete_entry> &blocks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // each download block
|
} // each download block
|
||||||
core.cleanup_handle_incoming_blocks();
|
if (!core.cleanup_handle_incoming_blocks())
|
||||||
|
return 1;
|
||||||
|
|
||||||
blocks.clear();
|
blocks.clear();
|
||||||
return 0;
|
return 0;
|
||||||
@ -394,7 +395,10 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path
|
|||||||
blocks.push_back({block, txs});
|
blocks.push_back({block, txs});
|
||||||
int ret = check_flush(core, blocks, false);
|
int ret = check_flush(core, blocks, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
{
|
||||||
|
quit = 2; // make sure we don't commit partial block data
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3582,12 +3582,23 @@ void Blockchain::block_longhash_worker(uint64_t height, const std::vector<block>
|
|||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
|
bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
|
||||||
{
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
MTRACE("Blockchain::" << __func__);
|
MTRACE("Blockchain::" << __func__);
|
||||||
CRITICAL_REGION_BEGIN(m_blockchain_lock);
|
CRITICAL_REGION_BEGIN(m_blockchain_lock);
|
||||||
TIME_MEASURE_START(t1);
|
TIME_MEASURE_START(t1);
|
||||||
|
|
||||||
m_db->batch_stop();
|
try
|
||||||
if (m_sync_counter > 0)
|
{
|
||||||
|
m_db->batch_stop();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
MERROR("Exception in cleanup_handle_incoming_blocks: " << e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success && m_sync_counter > 0)
|
||||||
{
|
{
|
||||||
if (force_sync)
|
if (force_sync)
|
||||||
{
|
{
|
||||||
@ -3622,7 +3633,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
|
|||||||
CRITICAL_REGION_END();
|
CRITICAL_REGION_END();
|
||||||
m_tx_pool.unlock();
|
m_tx_pool.unlock();
|
||||||
|
|
||||||
return true;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
@ -585,6 +585,8 @@ namespace cryptonote
|
|||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
bool core::handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
|
bool core::handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
|
||||||
{
|
{
|
||||||
|
TRY_ENTRY();
|
||||||
|
|
||||||
struct result { bool res; cryptonote::transaction tx; crypto::hash hash; crypto::hash prefix_hash; bool in_txpool; bool in_blockchain; };
|
struct result { bool res; cryptonote::transaction tx; crypto::hash hash; crypto::hash prefix_hash; bool in_txpool; bool in_blockchain; };
|
||||||
std::vector<result> results(tx_blobs.size());
|
std::vector<result> results(tx_blobs.size());
|
||||||
|
|
||||||
@ -638,6 +640,8 @@ namespace cryptonote
|
|||||||
MDEBUG("tx added: " << results[i].hash);
|
MDEBUG("tx added: " << results[i].hash);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
|
||||||
|
CATCH_ENTRY_L0("core::handle_incoming_txs()", false);
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
|
bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
|
||||||
@ -1064,17 +1068,20 @@ namespace cryptonote
|
|||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
bool core::cleanup_handle_incoming_blocks(bool force_sync)
|
bool core::cleanup_handle_incoming_blocks(bool force_sync)
|
||||||
{
|
{
|
||||||
|
bool success = false;
|
||||||
try {
|
try {
|
||||||
m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync);
|
success = m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync);
|
||||||
}
|
}
|
||||||
catch (...) {}
|
catch (...) {}
|
||||||
m_incoming_tx_lock.unlock();
|
m_incoming_tx_lock.unlock();
|
||||||
return true;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
bool core::handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate)
|
bool core::handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate)
|
||||||
{
|
{
|
||||||
|
TRY_ENTRY();
|
||||||
|
|
||||||
// load json & DNS checkpoints every 10min/hour respectively,
|
// load json & DNS checkpoints every 10min/hour respectively,
|
||||||
// and verify them with respect to what blocks we already have
|
// and verify them with respect to what blocks we already have
|
||||||
CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
|
CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
|
||||||
@ -1098,6 +1105,8 @@ namespace cryptonote
|
|||||||
if(update_miner_blocktemplate && bvc.m_added_to_main_chain)
|
if(update_miner_blocktemplate && bvc.m_added_to_main_chain)
|
||||||
update_miner_block_template();
|
update_miner_block_template();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
CATCH_ENTRY_L0("core::handle_incoming_block()", false);
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
// Used by the RPC server to check the size of an incoming
|
// Used by the RPC server to check the size of an incoming
|
||||||
|
@ -364,7 +364,12 @@ namespace cryptonote
|
|||||||
|
|
||||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||||
m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
|
m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
|
||||||
m_core.cleanup_handle_incoming_blocks(true);
|
if (!m_core.cleanup_handle_incoming_blocks(true))
|
||||||
|
{
|
||||||
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
m_core.resume_mine();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
m_core.resume_mine();
|
m_core.resume_mine();
|
||||||
if(bvc.m_verifivation_failed)
|
if(bvc.m_verifivation_failed)
|
||||||
{
|
{
|
||||||
@ -623,7 +628,12 @@ namespace cryptonote
|
|||||||
|
|
||||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
||||||
m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
|
m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
|
||||||
m_core.cleanup_handle_incoming_blocks(true);
|
if (!m_core.cleanup_handle_incoming_blocks(true))
|
||||||
|
{
|
||||||
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
m_core.resume_mine();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
m_core.resume_mine();
|
m_core.resume_mine();
|
||||||
|
|
||||||
if( bvc.m_verifivation_failed )
|
if( bvc.m_verifivation_failed )
|
||||||
@ -1056,7 +1066,11 @@ skip:
|
|||||||
}))
|
}))
|
||||||
LOG_ERROR_CCONTEXT("span connection id not found");
|
LOG_ERROR_CCONTEXT("span connection id not found");
|
||||||
|
|
||||||
m_core.cleanup_handle_incoming_blocks();
|
if (!m_core.cleanup_handle_incoming_blocks())
|
||||||
|
{
|
||||||
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
|
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
|
||||||
m_block_queue.remove_spans(span_connection_id, start_height);
|
m_block_queue.remove_spans(span_connection_id, start_height);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1081,7 +1095,12 @@ skip:
|
|||||||
}))
|
}))
|
||||||
LOG_ERROR_CCONTEXT("span connection id not found");
|
LOG_ERROR_CCONTEXT("span connection id not found");
|
||||||
|
|
||||||
m_core.cleanup_handle_incoming_blocks();
|
if (!m_core.cleanup_handle_incoming_blocks())
|
||||||
|
{
|
||||||
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
|
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
|
||||||
m_block_queue.remove_spans(span_connection_id, start_height);
|
m_block_queue.remove_spans(span_connection_id, start_height);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1095,7 +1114,12 @@ skip:
|
|||||||
}))
|
}))
|
||||||
LOG_ERROR_CCONTEXT("span connection id not found");
|
LOG_ERROR_CCONTEXT("span connection id not found");
|
||||||
|
|
||||||
m_core.cleanup_handle_incoming_blocks();
|
if (!m_core.cleanup_handle_incoming_blocks())
|
||||||
|
{
|
||||||
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
|
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
|
||||||
m_block_queue.remove_spans(span_connection_id, start_height);
|
m_block_queue.remove_spans(span_connection_id, start_height);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1108,7 +1132,11 @@ skip:
|
|||||||
|
|
||||||
MCINFO("sync-info", "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms");
|
MCINFO("sync-info", "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms");
|
||||||
|
|
||||||
m_core.cleanup_handle_incoming_blocks();
|
if (!m_core.cleanup_handle_incoming_blocks())
|
||||||
|
{
|
||||||
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
m_block_queue.remove_spans(span_connection_id, start_height);
|
m_block_queue.remove_spans(span_connection_id, start_height);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user