diff options
Diffstat (limited to 'src/blockchain_db/lmdb')
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 417 |
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; } |