aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-08-29 15:43:32 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-08-29 15:43:32 +0100
commitce901fcb3174a2795483fba653a1128ce6b15858 (patch)
treeb8955b4e258d3e62799b820dd0b4e6cc6d4b9caf
parentcore: guard against exceptions in handle_incoming_{block,tx} (diff)
downloadmonero-ce901fcb3174a2795483fba653a1128ce6b15858.tar.xz
Fix blockchain_import wedge on exception in cleanup_handle_incoming_blocks
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp31
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h3
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp6
-rw-r--r--src/cryptonote_core/blockchain.cpp17
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp5
5 files changed, 47 insertions, 15 deletions
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 4100d9cca..b6978bdc4 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -2604,6 +2604,16 @@ void BlockchainLMDB::batch_commit()
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()
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
@@ -2618,15 +2628,18 @@ void BlockchainLMDB::batch_stop()
check_open();
LOG_PRINT_L3("batch transaction: committing...");
TIME_MEASURE_START(time1);
- m_write_txn->commit();
- TIME_MEASURE_FINISH(time1);
- time_commit1 += time1;
- // 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));
+ try
+ {
+ m_write_txn->commit();
+ TIME_MEASURE_FINISH(time1);
+ time_commit1 += time1;
+ cleanup_batch();
+ }
+ catch (const std::exception &e)
+ {
+ cleanup_batch();
+ throw;
+ }
LOG_PRINT_L3("batch transaction: end");
}
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index 3a11ddf0d..90274b904 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -368,6 +368,9 @@ private:
// migrate from DB version 0 to 1
void migrate_0_1();
+ void cleanup_batch();
+
+private:
MDB_env* m_env;
MDB_dbi m_blocks;
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index ded854ca4..14f318768 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -208,7 +208,8 @@ int check_flush(cryptonote::core &core, std::list<block_complete_entry> &blocks,
}
} // each download block
- core.cleanup_handle_incoming_blocks();
+ if (!core.cleanup_handle_incoming_blocks())
+ return 1;
blocks.clear();
return 0;
@@ -394,7 +395,10 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path
blocks.push_back({block, txs});
int ret = check_flush(core, blocks, false);
if (ret)
+ {
+ quit = 2; // make sure we don't commit partial block data
break;
+ }
}
else
{
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index c1faa703f..93a4e26f8 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -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 success = false;
+
MTRACE("Blockchain::" << __func__);
CRITICAL_REGION_BEGIN(m_blockchain_lock);
TIME_MEASURE_START(t1);
- m_db->batch_stop();
- if (m_sync_counter > 0)
+ try
+ {
+ 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)
{
@@ -3622,7 +3633,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
CRITICAL_REGION_END();
m_tx_pool.unlock();
- return true;
+ return success;
}
//------------------------------------------------------------------
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index af0616af0..ac1579066 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1068,12 +1068,13 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool core::cleanup_handle_incoming_blocks(bool force_sync)
{
+ bool success = false;
try {
- m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync);
+ success = m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync);
}
catch (...) {}
m_incoming_tx_lock.unlock();
- return true;
+ return success;
}
//-----------------------------------------------------------------------------------------------