@ -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 ;
}