aboutsummaryrefslogtreecommitdiff
path: root/src/blockchain_db
diff options
context:
space:
mode:
Diffstat (limited to 'src/blockchain_db')
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp417
1 files changed, 127 insertions, 290 deletions
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index b941fe6b1..f76fee87a 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -29,6 +29,7 @@
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
+#include <boost/current_function.hpp>
#include <memory> // std::unique_ptr
#include <cstring> // memcpy
#include <random>
@@ -1232,28 +1233,45 @@ void BlockchainLMDB::unlock()
check_open();
}
+#define TXN_PREFIX(flags); \
+ mdb_txn_safe auto_txn; \
+ mdb_txn_safe* txn_ptr = &auto_txn; \
+ if (m_batch_active) \
+ txn_ptr = m_write_txn; \
+ else \
+ { \
+ if (auto mdb_res = mdb_txn_begin(m_env, NULL, flags, auto_txn)) \
+ throw0(DB_ERROR(lmdb_error(std::string("Failed to create a transaction for the db in ")+__FUNCTION__+": ", mdb_res).c_str())); \
+ } \
+
+#define TXN_PREFIX_RDONLY(); TXN_PREFIX(MDB_RDONLY);
+
+#define TXN_POSTFIX_SUCCESS() \
+ do { \
+ if (! m_batch_active) \
+ auto_txn.commit(); \
+ } while(0)
+
bool BlockchainLMDB::block_exists(const crypto::hash& h) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::hash> key(h);
MDB_val result;
- auto get_result = mdb_get(txn, m_block_heights, &key, &result);
+ auto get_result = mdb_get(*txn_ptr, m_block_heights, &key, &result);
if (get_result == MDB_NOTFOUND)
{
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
LOG_PRINT_L3("Block with hash " << epee::string_tools::pod_to_hex(h) << " not found in db");
return false;
}
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch block index from hash"));
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return true;
}
@@ -1270,21 +1288,18 @@ uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint64_t ret;
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::hash> key(h);
MDB_val result;
- auto get_result = mdb_get(txn, m_block_heights, &key, &result);
+ auto get_result = mdb_get(*txn_ptr, m_block_heights, &key, &result);
if (get_result == MDB_NOTFOUND)
throw1(BLOCK_DNE("Attempted to retrieve non-existent block height"));
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve a block height from the db"));
- ret = *(const uint64_t *)result.mv_data;
- txn.commit();
+ uint64_t ret = *(const uint64_t *)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1302,13 +1317,11 @@ block BlockchainLMDB::get_block_from_height(const uint64_t& height) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val_copy<uint64_t> key(height);
MDB_val result;
- auto get_result = mdb_get(txn, m_blocks, &key, &result);
+ auto get_result = mdb_get(*txn_ptr, m_blocks, &key, &result);
if (get_result == MDB_NOTFOUND)
{
throw0(BLOCK_DNE(std::string("Attempt to get block from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- block not in db").c_str()));
@@ -1323,7 +1336,7 @@ block BlockchainLMDB::get_block_from_height(const uint64_t& height) const
if (!parse_and_validate_block_from_blob(bd, b))
throw0(DB_ERROR("Failed to parse block from blob retrieved from the db"));
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return b;
}
@@ -1333,16 +1346,8 @@ uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint64_t ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
+
MDB_val_copy<uint64_t> key(height);
MDB_val result;
auto get_result = mdb_get(*txn_ptr, m_block_timestamps, &key, &result);
@@ -1353,9 +1358,8 @@ uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) const
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve a timestamp from the db"));
- ret = *(const uint64_t *)result.mv_data;
- if (! m_batch_active)
- txn.commit();
+ uint64_t ret = *(const uint64_t *)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1378,17 +1382,8 @@ size_t BlockchainLMDB::get_block_size(const uint64_t& height) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
- size_t ret;
MDB_val_copy<uint64_t> key(height);
MDB_val result;
auto get_result = mdb_get(*txn_ptr, m_block_sizes, &key, &result);
@@ -1399,9 +1394,8 @@ size_t BlockchainLMDB::get_block_size(const uint64_t& height) const
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve a block size from the db"));
- ret = *(const size_t *)result.mv_data;
- if (! m_batch_active)
- txn.commit();
+ size_t ret = *(const size_t *)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1410,16 +1404,8 @@ difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t&
LOG_PRINT_L3("BlockchainLMDB::" << __func__ << " height: " << height);
check_open();
- difficulty_type ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
+
MDB_val_copy<uint64_t> key(height);
MDB_val result;
auto get_result = mdb_get(*txn_ptr, m_block_diffs, &key, &result);
@@ -1430,9 +1416,8 @@ difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t&
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve a cumulative difficulty from the db"));
- ret = *(difficulty_type*)result.mv_data;
- if (! m_batch_active)
- txn.commit();
+ difficulty_type ret = *(const difficulty_type*)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1458,16 +1443,7 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint64_t ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<uint64_t> key(height);
MDB_val result;
@@ -1479,9 +1455,8 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve a total generated coins from the db"));
- ret = *(const uint64_t*)result.mv_data;
- if (! m_batch_active)
- txn.commit();
+ uint64_t ret = *(const uint64_t*)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1490,16 +1465,7 @@ crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height)
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- crypto::hash ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<uint64_t> key(height);
MDB_val result;
@@ -1512,9 +1478,8 @@ crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height)
throw0(DB_ERROR(std::string("Error attempting to retrieve a block hash from the db: ").
append(mdb_strerror(get_result)).c_str()));
- ret = *(crypto::hash*)result.mv_data;
- if (! m_batch_active)
- txn.commit();
+ crypto::hash ret = *(const crypto::hash*)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1585,15 +1550,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::hash> key(h);
MDB_val result;
@@ -1602,8 +1559,9 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) const
auto get_result = mdb_get(*txn_ptr, m_txs, &key, &result);
TIME_MEASURE_FINISH(time1);
time_tx_exists += time1;
- if (! m_batch_active)
- txn.commit();
+
+ TXN_POSTFIX_SUCCESS();
+
if (get_result == MDB_NOTFOUND)
{
LOG_PRINT_L1("transaction with hash " << epee::string_tools::pod_to_hex(h) << " not found in db");
@@ -1620,21 +1578,18 @@ uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint64_t ret;
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::hash> key(h);
MDB_val result;
- auto get_result = mdb_get(txn, m_tx_unlocks, &key, &result);
+ auto get_result = mdb_get(*txn_ptr, m_tx_unlocks, &key, &result);
if (get_result == MDB_NOTFOUND)
throw1(TX_DNE(std::string("tx unlock time with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()));
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch tx unlock time from hash"));
- ret = *(const uint64_t*)result.mv_data;
- txn.commit();
+ uint64_t ret = *(const uint64_t*)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1643,15 +1598,7 @@ transaction BlockchainLMDB::get_tx(const crypto::hash& h) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::hash> key(h);
MDB_val result;
@@ -1667,8 +1614,8 @@ transaction BlockchainLMDB::get_tx(const crypto::hash& h) const
transaction tx;
if (!parse_and_validate_tx_from_blob(bd, tx))
throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
- if (! m_batch_active)
- txn.commit();
+
+ TXN_POSTFIX_SUCCESS();
return tx;
}
@@ -1678,15 +1625,13 @@ uint64_t BlockchainLMDB::get_tx_count() const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_stat db_stats;
- if (mdb_stat(txn, m_txs, &db_stats))
+ if (mdb_stat(*txn_ptr, m_txs, &db_stats))
throw0(DB_ERROR("Failed to query m_txs"));
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return db_stats.ms_entries;
}
@@ -1710,16 +1655,7 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint64_t ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::hash> key(h);
MDB_val result;
@@ -1731,10 +1667,8 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch tx height from hash"));
- ret = *(const uint64_t*)result.mv_data;
- if (! m_batch_active)
- txn.commit();
-
+ uint64_t ret = *(const uint64_t*)result.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1743,17 +1677,16 @@ uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
- lmdb_cur cur(txn, m_output_amounts);
+ lmdb_cur cur(*txn_ptr, m_output_amounts);
MDB_val_copy<uint64_t> k(amount);
MDB_val v;
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
if (result == MDB_NOTFOUND)
{
+ TXN_POSTFIX_SUCCESS();
return 0;
}
else if (result)
@@ -1762,7 +1695,7 @@ uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) const
size_t num_elems = 0;
mdb_cursor_count(cur, &num_elems);
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return num_elems;
}
@@ -1772,21 +1705,18 @@ output_data_t BlockchainLMDB::get_output_key(const uint64_t &global_index) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- output_data_t ret;
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
- MDB_val_copy<uint64_t> k(global_index);
+ MDB_val_copy<uint64_t> k(global_index);
MDB_val v;
- auto get_result = mdb_get(txn, m_output_keys, &k, &v);
+ auto get_result = mdb_get(*txn_ptr, m_output_keys, &k, &v);
if (get_result == MDB_NOTFOUND)
throw1(OUTPUT_DNE("Attempting to get output pubkey by global index, but key does not exist"));
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve an output pubkey from the db"));
- ret = *(output_data_t *) v.mv_data;
- txn.commit();
- return ret;
+ output_data_t ret = *(const output_data_t *) v.mv_data;
+ TXN_POSTFIX_SUCCESS();
+ return ret;
}
output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint64_t& index)
@@ -1803,16 +1733,8 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t&
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- tx_out_index ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
+
MDB_val_copy<uint64_t> k(index);
MDB_val v;
@@ -1822,7 +1744,7 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t&
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch output tx hash"));
- crypto::hash tx_hash = *(crypto::hash*)v.mv_data;
+ crypto::hash tx_hash = *(const crypto::hash*)v.mv_data;
get_result = mdb_get(*txn_ptr, m_output_indices, &k, &v);
if (get_result == MDB_NOTFOUND)
@@ -1830,10 +1752,8 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t&
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch output tx index"));
- ret = tx_out_index(tx_hash, *(const uint64_t *)v.mv_data);
- if (! m_batch_active)
- txn.commit();
-
+ tx_out_index ret = tx_out_index(tx_hash, *(const uint64_t *)v.mv_data);
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -1856,11 +1776,9 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash&
check_open();
std::vector<uint64_t> index_vec;
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
- lmdb_cur cur(txn, m_tx_outputs);
+ lmdb_cur cur(*txn_ptr, m_tx_outputs);
MDB_val_copy<crypto::hash> k(h);
MDB_val v;
@@ -1883,7 +1801,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash&
}
cur.close();
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return index_vec;
}
@@ -1901,9 +1819,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_amount_output_indices(const crypto:
transaction tx = get_tx(h);
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
uint64_t i = 0;
uint64_t global_index;
@@ -1913,7 +1829,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_amount_output_indices(const crypto:
global_index = index_vec[i];
- lmdb_cur cur(txn, m_output_amounts);
+ lmdb_cur cur(*txn_ptr, m_output_amounts);
MDB_val_copy<uint64_t> k(amount);
MDB_val v;
@@ -1952,7 +1868,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_amount_output_indices(const crypto:
{
// not found
cur.close();
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
throw1(OUTPUT_DNE("specified output not found in db"));
}
@@ -1960,7 +1876,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_amount_output_indices(const crypto:
++i;
}
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return index_vec2;
}
@@ -1972,19 +1888,17 @@ bool BlockchainLMDB::has_key_image(const crypto::key_image& img) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val_copy<crypto::key_image> val_key(img);
MDB_val unused;
- if (mdb_get(txn, m_spent_keys, &val_key, &unused) == 0)
+ if (mdb_get(*txn_ptr, m_spent_keys, &val_key, &unused) == 0)
{
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return true;
}
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return false;
}
@@ -1993,15 +1907,13 @@ bool BlockchainLMDB::for_all_key_images(std::function<bool(const crypto::key_ima
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val k;
MDB_val v;
bool ret = true;
- lmdb_cur cur(txn, m_spent_keys);
+ lmdb_cur cur(*txn_ptr, m_spent_keys);
MDB_cursor_op op = MDB_FIRST;
while (1)
{
@@ -2011,7 +1923,7 @@ bool BlockchainLMDB::for_all_key_images(std::function<bool(const crypto::key_ima
break;
if (ret < 0)
throw0(DB_ERROR("Failed to enumerate key images"));
- const crypto::key_image k_image = *(crypto::key_image*)k.mv_data;
+ const crypto::key_image k_image = *(const crypto::key_image*)k.mv_data;
if (!f(k_image)) {
ret = false;
break;
@@ -2019,7 +1931,7 @@ bool BlockchainLMDB::for_all_key_images(std::function<bool(const crypto::key_ima
}
cur.close();
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -2029,15 +1941,13 @@ bool BlockchainLMDB::for_all_blocks(std::function<bool(uint64_t, const crypto::h
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val k;
MDB_val v;
bool ret = true;
- lmdb_cur cur(txn, m_blocks);
+ lmdb_cur cur(*txn_ptr, m_blocks);
MDB_cursor_op op = MDB_FIRST;
while (1)
{
@@ -2047,7 +1957,7 @@ bool BlockchainLMDB::for_all_blocks(std::function<bool(uint64_t, const crypto::h
break;
if (ret)
throw0(DB_ERROR("Failed to enumerate blocks"));
- uint64_t height = *(uint64_t*)k.mv_data;
+ uint64_t height = *(const uint64_t*)k.mv_data;
blobdata bd;
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
block b;
@@ -2063,7 +1973,7 @@ bool BlockchainLMDB::for_all_blocks(std::function<bool(uint64_t, const crypto::h
}
cur.close();
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -2073,15 +1983,13 @@ bool BlockchainLMDB::for_all_transactions(std::function<bool(const crypto::hash&
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val k;
MDB_val v;
bool ret = true;
- lmdb_cur cur(txn, m_txs);
+ lmdb_cur cur(*txn_ptr, m_txs);
MDB_cursor_op op = MDB_FIRST;
while (1)
{
@@ -2091,7 +1999,7 @@ bool BlockchainLMDB::for_all_transactions(std::function<bool(const crypto::hash&
break;
if (ret)
throw0(DB_ERROR("Failed to enumerate transactions"));
- const crypto::hash hash = *(crypto::hash*)k.mv_data;
+ const crypto::hash hash = *(const crypto::hash*)k.mv_data;
blobdata bd;
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
transaction tx;
@@ -2104,7 +2012,7 @@ bool BlockchainLMDB::for_all_transactions(std::function<bool(const crypto::hash&
}
cur.close();
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -2114,15 +2022,13 @@ bool BlockchainLMDB::for_all_outputs(std::function<bool(uint64_t amount, const c
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
+ TXN_PREFIX_RDONLY();
MDB_val k;
MDB_val v;
bool ret = true;
- lmdb_cur cur(txn, m_output_amounts);
+ lmdb_cur cur(*txn_ptr, m_output_amounts);
MDB_cursor_op op = MDB_FIRST;
while (1)
{
@@ -2132,8 +2038,8 @@ bool BlockchainLMDB::for_all_outputs(std::function<bool(uint64_t amount, const c
break;
if (ret)
throw0(DB_ERROR("Failed to enumerate outputs"));
- uint64_t amount = *(uint64_t*)k.mv_data;
- uint64_t global_index = *(uint64_t*)v.mv_data;
+ uint64_t amount = *(const uint64_t*)k.mv_data;
+ uint64_t global_index = *(const uint64_t*)v.mv_data;
tx_out_index toi = get_output_tx_and_index_from_global(global_index);
if (!f(amount, toi.first, toi.second)) {
ret = false;
@@ -2142,7 +2048,7 @@ bool BlockchainLMDB::for_all_outputs(std::function<bool(uint64_t amount, const c
}
cur.close();
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -2335,15 +2241,7 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
check_open();
tx_out_indices.clear();
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
for (const uint64_t &index : global_indices)
{
@@ -2356,7 +2254,7 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch output tx hash"));
- crypto::hash tx_hash = *(crypto::hash*) v.mv_data;
+ crypto::hash tx_hash = *(const crypto::hash*) v.mv_data;
get_result = mdb_get(*txn_ptr, m_output_indices, &k, &v);
if (get_result == MDB_NOTFOUND)
@@ -2368,8 +2266,7 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
tx_out_indices.push_back(result);
}
- if (!m_batch_active)
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
}
void BlockchainLMDB::get_output_global_indices(const uint64_t& amount, const std::vector<uint64_t> &offsets,
@@ -2387,15 +2284,7 @@ void BlockchainLMDB::get_output_global_indices(const uint64_t& amount, const std
max = index;
}
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if(m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
lmdb_cur cur(*txn_ptr, m_output_amounts);
@@ -2474,8 +2363,7 @@ void BlockchainLMDB::get_output_global_indices(const uint64_t& amount, const std
}
cur.close();
- if(!m_batch_active)
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
TIME_MEASURE_FINISH(txx);
LOG_PRINT_L3("txx: " << txx << " db1: " << t_dbmul << " db2: " << t_dbscan);
@@ -2493,15 +2381,8 @@ void BlockchainLMDB::get_output_key(const uint64_t &amount, const std::vector<ui
if (global_indices.size() > 0)
{
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- }
+ TXN_PREFIX_RDONLY();
+
for (const uint64_t &index : global_indices)
{
MDB_val_copy<uint64_t> k(index);
@@ -2513,12 +2394,11 @@ void BlockchainLMDB::get_output_key(const uint64_t &amount, const std::vector<ui
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve an output pubkey from the db"));
- output_data_t data = *(output_data_t *) v.mv_data;
+ output_data_t data = *(const output_data_t *) v.mv_data;
outputs.push_back(data);
}
- if (!m_batch_active)
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
}
TIME_MEASURE_FINISH(db3);
@@ -2548,24 +2428,14 @@ void BlockchainLMDB::set_hard_fork_starting_height(uint8_t version, uint64_t hei
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, 0, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- txn_ptr = &txn;
- }
+ TXN_PREFIX(0);
MDB_val_copy<uint8_t> val_key(version);
MDB_val_copy<uint64_t> val_value(height);
if (auto result = mdb_put(*txn_ptr, m_hf_starting_heights, &val_key, &val_value, 0))
throw1(DB_ERROR(std::string("Error adding hard fork starting height to db transaction: ").append(mdb_strerror(result)).c_str()));
- if (!m_batch_active)
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
}
uint64_t BlockchainLMDB::get_hard_fork_starting_height(uint8_t version) const
@@ -2573,17 +2443,7 @@ uint64_t BlockchainLMDB::get_hard_fork_starting_height(uint8_t version) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint64_t ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- txn_ptr = &txn;
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<uint8_t> val_key(version);
MDB_val val_ret;
@@ -2593,9 +2453,8 @@ uint64_t BlockchainLMDB::get_hard_fork_starting_height(uint8_t version) const
if (result)
throw0(DB_ERROR("Error attempting to retrieve a hard fork starting height from the db"));
- ret = *(const uint64_t*)val_ret.mv_data;
- if (!m_batch_active)
- txn.commit();
+ uint64_t ret = *(const uint64_t*)val_ret.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}
@@ -2604,25 +2463,14 @@ void BlockchainLMDB::set_hard_fork_version(uint64_t height, uint8_t version)
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
-//LOG_PRINT_L1("BlockchainLMDB::set_hard_fork_version: batch " << m_batch_active << ", height " << height << ", version " << (int)version);
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, 0, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- txn_ptr = &txn;
- }
+ TXN_PREFIX(0);
MDB_val_copy<uint64_t> val_key(height);
MDB_val_copy<uint8_t> val_value(version);
if (auto result = mdb_put(*txn_ptr, m_hf_versions, &val_key, &val_value, 0))
throw1(DB_ERROR(std::string("Error adding hard fork version to db transaction: ").append(mdb_strerror(result)).c_str()));
- if (!m_batch_active)
- txn.commit();
+ TXN_POSTFIX_SUCCESS();
}
uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
@@ -2630,17 +2478,7 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
- uint8_t ret;
- mdb_txn_safe txn;
- mdb_txn_safe* txn_ptr = &txn;
- if (m_batch_active)
- txn_ptr = m_write_txn;
- else
- {
- if (auto mdb_res = mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
- throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
- txn_ptr = &txn;
- }
+ TXN_PREFIX_RDONLY();
MDB_val_copy<uint64_t> val_key(height);
MDB_val val_ret;
@@ -2648,9 +2486,8 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
if (result == MDB_NOTFOUND || result)
throw0(DB_ERROR("Error attempting to retrieve a hard fork version from the db"));
- ret = *(const uint8_t*)val_ret.mv_data;
- if (!m_batch_active)
- txn.commit();
+ uint8_t ret = *(const uint8_t*)val_ret.mv_data;
+ TXN_POSTFIX_SUCCESS();
return ret;
}