Merge pull request #15 from moneromooo-monero/blockchain

many const-correctness changes and code quality enhancements.  minor bugfix on block removal.
This commit is contained in:
Thomas Winget 2014-12-12 16:08:37 -05:00 committed by warptangent
commit 81c28c211c
3 changed files with 106 additions and 223 deletions

View file

@ -50,18 +50,17 @@ struct fake_core
blockchain_storage m_storage; blockchain_storage m_storage;
fake_core() : m_pool(dummy), dummy(m_pool), m_storage(&m_pool) fake_core(const boost::filesystem::path &path) : m_pool(dummy), dummy(m_pool), m_storage(&m_pool)
{ {
boost::filesystem::path default_data_path {tools::get_default_data_dir()}; m_pool.init(path.string());
m_pool.init(default_data_path.string()); m_storage.init(path.string(), false);
m_storage.init(default_data_path.string(), false);
} }
}; };
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
fake_core c;
boost::filesystem::path default_data_path {tools::get_default_data_dir()}; boost::filesystem::path default_data_path {tools::get_default_data_dir()};
fake_core c(default_data_path);
BlockchainDB *blockchain; BlockchainDB *blockchain;
@ -69,9 +68,13 @@ int main(int argc, char* argv[])
blockchain->open(default_data_path.string()); blockchain->open(default_data_path.string());
for (uint64_t i = 0; i < c.m_storage.get_current_blockchain_height(); ++i) for (uint64_t height, i = 0; i < (height = c.m_storage.get_current_blockchain_height()); ++i)
{ {
if (i % 10 == 0) std::cout << "block " << i << std::endl; if (i % 10 == 0)
{
std::cout << "\r \r" << "block " << i << "/" << height
<< " (" << (i+1)*100/height<< "%)" << std::flush;
}
block b = c.m_storage.get_block(i); block b = c.m_storage.get_block(i);
size_t bsize = c.m_storage.get_block_size(i); size_t bsize = c.m_storage.get_block_size(i);
difficulty_type bdiff = c.m_storage.get_block_cumulative_difficulty(i); difficulty_type bdiff = c.m_storage.get_block_cumulative_difficulty(i);
@ -82,6 +85,7 @@ int main(int argc, char* argv[])
c.m_storage.get_transactions(b.tx_hashes, txs, missed); c.m_storage.get_transactions(b.tx_hashes, txs, missed);
if (missed.size()) if (missed.size())
{ {
std::cout << std::endl;
std::cerr << "Missed transaction(s) for block at height " << i << ", exiting" << std::endl; std::cerr << "Missed transaction(s) for block at height " << i << ", exiting" << std::endl;
delete blockchain; delete blockchain;
return 1; return 1;
@ -93,12 +97,14 @@ int main(int argc, char* argv[])
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
std::cout << std::endl;
std::cerr << "Error adding block to new blockchain: " << e.what() << std::endl; std::cerr << "Error adding block to new blockchain: " << e.what() << std::endl;
delete blockchain; delete blockchain;
return 2; return 2;
} }
} }
std::cout << std::endl;
delete blockchain; delete blockchain;
return 0; return 0;
} }

View file

@ -72,9 +72,34 @@ private:
bool done; bool done;
}; };
template<typename T>
struct MDB_val_copy: public MDB_val
{
MDB_val_copy(const T &t): t_copy(t)
{
mv_size = sizeof (T);
mv_data = &t_copy;
}
private:
T t_copy;
};
template<>
struct MDB_val_copy<cryptonote::blobdata>: public MDB_val
{
MDB_val_copy(const cryptonote::blobdata &bd): data(new char[bd.size()])
{
memcpy(data.get(), bd.data(), bd.size());
mv_size = bd.size();
mv_data = data.get();
}
private:
std::unique_ptr<char[]> data;
};
auto compare_uint64 = [](const MDB_val *a, const MDB_val *b) { auto compare_uint64 = [](const MDB_val *a, const MDB_val *b) {
uint64_t va = *(uint64_t*)a->mv_data; const uint64_t va = *(const uint64_t*)a->mv_data;
uint64_t vb = *(uint64_t*)b->mv_data; const uint64_t vb = *(const uint64_t*)b->mv_data;
if (va < vb) return -1; if (va < vb) return -1;
else if (va == vb) return 0; else if (va == vb) return 0;
else return 1; else return 1;
@ -124,11 +149,7 @@ void BlockchainLMDB::add_block( const block& blk
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
crypto::hash h = get_block_hash(blk); MDB_val_copy<crypto::hash> val_h(get_block_hash(blk));
MDB_val val_h;
val_h.mv_size = sizeof(crypto::hash);
val_h.mv_data = &h;
MDB_val unused; MDB_val unused;
if (mdb_get(*m_write_txn, m_block_heights, &val_h, &unused) == 0) if (mdb_get(*m_write_txn, m_block_heights, &val_h, &unused) == 0)
{ {
@ -138,11 +159,7 @@ void BlockchainLMDB::add_block( const block& blk
if (m_height > 0) if (m_height > 0)
{ {
MDB_val parent_key; MDB_val_copy<crypto::hash> parent_key(blk.prev_id);
crypto::hash parent = blk.prev_id;
parent_key.mv_size = sizeof(crypto::hash);
parent_key.mv_data = &parent;
MDB_val parent_h; MDB_val parent_h;
if (mdb_get(*m_write_txn, m_block_heights, &parent_key, &parent_h)) if (mdb_get(*m_write_txn, m_block_heights, &parent_key, &parent_h))
{ {
@ -150,7 +167,7 @@ void BlockchainLMDB::add_block( const block& blk
throw DB_ERROR("Failed to get top block hash to check for new block's parent"); throw DB_ERROR("Failed to get top block hash to check for new block's parent");
} }
uint64_t parent_height = *(uint64_t *)parent_h.mv_data; uint64_t parent_height = *(const uint64_t *)parent_h.mv_data;
if (parent_height != m_height - 1) if (parent_height != m_height - 1)
{ {
LOG_PRINT_L0("Top block is not new block's parent"); LOG_PRINT_L0("Top block is not new block's parent");
@ -158,57 +175,38 @@ void BlockchainLMDB::add_block( const block& blk
} }
} }
MDB_val key; MDB_val_copy<uint64_t> key(m_height);
key.mv_size = sizeof(uint64_t);
key.mv_data = &m_height;
auto bd = block_to_blob(blk); MDB_val_copy<blobdata> blob(block_to_blob(blk));
// const-correctness be trolling, yo
std::unique_ptr<char[]> bd_cpy(new char[bd.size()]);
memcpy(bd_cpy.get(), bd.data(), bd.size());
MDB_val blob;
blob.mv_size = bd.size();
blob.mv_data = bd_cpy.get();
if (mdb_put(*m_write_txn, m_blocks, &key, &blob, 0)) if (mdb_put(*m_write_txn, m_blocks, &key, &blob, 0))
{ {
LOG_PRINT_L0("Failed to add block blob to db transaction"); LOG_PRINT_L0("Failed to add block blob to db transaction");
throw DB_ERROR("Failed to add block blob to db transaction"); throw DB_ERROR("Failed to add block blob to db transaction");
} }
size_t size_cpy = block_size; MDB_val_copy<size_t> sz(block_size);
MDB_val sz;
sz.mv_size = sizeof(block_size);
sz.mv_data = &size_cpy;
if (mdb_put(*m_write_txn, m_block_sizes, &key, &sz, 0)) if (mdb_put(*m_write_txn, m_block_sizes, &key, &sz, 0))
{ {
LOG_PRINT_L0("Failed to add block size to db transaction"); LOG_PRINT_L0("Failed to add block size to db transaction");
throw DB_ERROR("Failed to add block size to db transaction"); throw DB_ERROR("Failed to add block size to db transaction");
} }
uint64_t time_cpy = blk.timestamp; MDB_val_copy<uint64_t> ts(blk.timestamp);
sz.mv_size = sizeof(time_cpy); if (mdb_put(*m_write_txn, m_block_timestamps, &key, &ts, 0))
sz.mv_data = &time_cpy;
if (mdb_put(*m_write_txn, m_block_timestamps, &key, &sz, 0))
{ {
LOG_PRINT_L0("Failed to add block timestamp to db transaction"); LOG_PRINT_L0("Failed to add block timestamp to db transaction");
throw DB_ERROR("Failed to add block timestamp to db transaction"); throw DB_ERROR("Failed to add block timestamp to db transaction");
} }
difficulty_type diff_cpy = cumulative_difficulty; MDB_val_copy<difficulty_type> diff(cumulative_difficulty);
sz.mv_size = sizeof(cumulative_difficulty); if (mdb_put(*m_write_txn, m_block_diffs, &key, &diff, 0))
sz.mv_data = &diff_cpy;
if (mdb_put(*m_write_txn, m_block_diffs, &key, &sz, 0))
{ {
LOG_PRINT_L0("Failed to add block cumulative difficulty to db transaction"); LOG_PRINT_L0("Failed to add block cumulative difficulty to db transaction");
throw DB_ERROR("Failed to add block cumulative difficulty to db transaction"); throw DB_ERROR("Failed to add block cumulative difficulty to db transaction");
} }
uint64_t coins_cpy = coins_generated; MDB_val_copy<uint64_t> coinsgen(coins_generated);
sz.mv_size = sizeof(coins_generated); if (mdb_put(*m_write_txn, m_block_coins, &key, &coinsgen, 0))
sz.mv_data = &coins_cpy;
if (mdb_put(*m_write_txn, m_block_coins, &key, &sz, 0))
{ {
LOG_PRINT_L0("Failed to add block total generated coins to db transaction"); LOG_PRINT_L0("Failed to add block total generated coins to db transaction");
throw DB_ERROR("Failed to add block total generated coins to db transaction"); throw DB_ERROR("Failed to add block total generated coins to db transaction");
@ -233,11 +231,7 @@ void BlockchainLMDB::remove_block()
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
MDB_val k; MDB_val_copy<uint64_t> k(m_height - 1);
uint64_t height = m_height - 1;
k.mv_size = sizeof(uint64_t);
k.mv_data = &height;
MDB_val h; MDB_val h;
if (mdb_get(*m_write_txn, m_block_hashes, &k, &h)) if (mdb_get(*m_write_txn, m_block_hashes, &k, &h))
{ {
@ -269,6 +263,12 @@ void BlockchainLMDB::remove_block()
throw DB_ERROR("Failed to add removal of block total generated coins to db transaction"); throw DB_ERROR("Failed to add removal of block total generated coins to db transaction");
} }
if (mdb_del(*m_write_txn, m_block_timestamps, &k, NULL))
{
LOG_PRINT_L1("Failed to add removal of block timestamp to db transaction");
throw DB_ERROR("Failed to add removal of block timestamp to db transaction");
}
if (mdb_del(*m_write_txn, m_block_heights, &h, NULL)) if (mdb_del(*m_write_txn, m_block_heights, &h, NULL))
{ {
LOG_PRINT_L1("Failed to add removal of block height by hash to db transaction"); LOG_PRINT_L1("Failed to add removal of block height by hash to db transaction");
@ -287,11 +287,7 @@ void BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, const tr
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
crypto::hash h = get_transaction_hash(tx); MDB_val_copy<crypto::hash> val_h(get_transaction_hash(tx));
MDB_val val_h;
val_h.mv_size = sizeof(crypto::hash);
val_h.mv_data = &h;
MDB_val unused; MDB_val unused;
if (mdb_get(*m_write_txn, m_txs, &val_h, &unused) == 0) if (mdb_get(*m_write_txn, m_txs, &val_h, &unused) == 0)
{ {
@ -299,34 +295,22 @@ void BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, const tr
throw TX_EXISTS("Attempting to add transaction that's already in the db"); throw TX_EXISTS("Attempting to add transaction that's already in the db");
} }
auto bd = tx_to_blob(tx); MDB_val_copy<blobdata> blob(tx_to_blob(tx));
// const-correctness be trolling, yo
std::unique_ptr<char[]> bd_cpy(new char[bd.size()]);
memcpy(bd_cpy.get(), bd.data(), bd.size());
MDB_val blob;
blob.mv_size = bd.size();
blob.mv_data = bd_cpy.get();
if (mdb_put(*m_write_txn, m_txs, &val_h, &blob, 0)) if (mdb_put(*m_write_txn, m_txs, &val_h, &blob, 0))
{ {
LOG_PRINT_L0("Failed to add tx blob to db transaction"); LOG_PRINT_L0("Failed to add tx blob to db transaction");
throw DB_ERROR("Failed to add tx blob to db transaction"); throw DB_ERROR("Failed to add tx blob to db transaction");
} }
MDB_val height; MDB_val_copy<uint64_t> height(m_height);
height.mv_size = sizeof(uint64_t);
height.mv_data = &m_height;
if (mdb_put(*m_write_txn, m_tx_heights, &val_h, &height, 0)) if (mdb_put(*m_write_txn, m_tx_heights, &val_h, &height, 0))
{ {
LOG_PRINT_L0("Failed to add tx block height to db transaction"); LOG_PRINT_L0("Failed to add tx block height to db transaction");
throw DB_ERROR("Failed to add tx block height to db transaction"); throw DB_ERROR("Failed to add tx block height to db transaction");
} }
uint64_t unlock_cpy = tx.unlock_time; MDB_val_copy<uint64_t> unlock_time(tx.unlock_time);
height.mv_size = sizeof(unlock_cpy); if (mdb_put(*m_write_txn, m_tx_unlocks, &val_h, &unlock_time, 0))
height.mv_data = &unlock_cpy;
if (mdb_put(*m_write_txn, m_tx_unlocks, &val_h, &height, 0))
{ {
LOG_PRINT_L0("Failed to add tx unlock time to db transaction"); LOG_PRINT_L0("Failed to add tx unlock time to db transaction");
throw DB_ERROR("Failed to add tx unlock time to db transaction"); throw DB_ERROR("Failed to add tx unlock time to db transaction");
@ -338,11 +322,7 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash)
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
crypto::hash h = tx_hash; MDB_val_copy<crypto::hash> val_h(tx_hash);
MDB_val val_h;
val_h.mv_size = sizeof(crypto::hash);
val_h.mv_data = &h;
MDB_val unused; MDB_val unused;
if (mdb_get(*m_write_txn, m_txs, &val_h, &unused)) if (mdb_get(*m_write_txn, m_txs, &val_h, &unused))
{ {
@ -381,14 +361,9 @@ void BlockchainLMDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_ou
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
MDB_val k; MDB_val_copy<uint64_t> k(m_num_outputs);
MDB_val v; MDB_val_copy<crypto::hash> v(tx_hash);
k.mv_size = sizeof(uint64_t);
k.mv_data = &m_num_outputs;
crypto::hash h_cpy = tx_hash;
v.mv_size = sizeof(crypto::hash);
v.mv_data = &h_cpy;
if (mdb_put(*m_write_txn, m_output_txs, &k, &v, 0)) if (mdb_put(*m_write_txn, m_output_txs, &k, &v, 0))
{ {
LOG_PRINT_L0("Failed to add output tx hash to db transaction"); LOG_PRINT_L0("Failed to add output tx hash to db transaction");
@ -400,19 +375,15 @@ void BlockchainLMDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_ou
throw DB_ERROR("Failed to add tx output index to db transaction"); throw DB_ERROR("Failed to add tx output index to db transaction");
} }
uint64_t index_cpy = local_index; MDB_val_copy<uint64_t> val_local_index(local_index);
v.mv_size = sizeof(uint64_t); if (mdb_put(*m_write_txn, m_output_indices, &k, &val_local_index, 0))
v.mv_data = &index_cpy;
if (mdb_put(*m_write_txn, m_output_indices, &k, &v, 0))
{ {
LOG_PRINT_L0("Failed to add tx output index to db transaction"); LOG_PRINT_L0("Failed to add tx output index to db transaction");
throw DB_ERROR("Failed to add tx output index to db transaction"); throw DB_ERROR("Failed to add tx output index to db transaction");
} }
uint64_t amount = tx_output.amount; MDB_val_copy<uint64_t> val_amount(tx_output.amount);
v.mv_size = sizeof(uint64_t); if (auto result = mdb_put(*m_write_txn, m_output_amounts, &val_amount, &k, 0))
v.mv_data = &amount;
if (auto result = mdb_put(*m_write_txn, m_output_amounts, &v, &k, 0))
{ {
LOG_PRINT_L0("Failed to add output amount to db transaction"); LOG_PRINT_L0("Failed to add output amount to db transaction");
LOG_PRINT_L0("E: " << mdb_strerror(result)); LOG_PRINT_L0("E: " << mdb_strerror(result));
@ -421,11 +392,8 @@ void BlockchainLMDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_ou
if (tx_output.target.type() == typeid(txout_to_key)) if (tx_output.target.type() == typeid(txout_to_key))
{ {
crypto::public_key pubkey = boost::get<txout_to_key>(tx_output.target).key; MDB_val_copy<crypto::public_key> val_pubkey(boost::get<txout_to_key>(tx_output.target).key);
if (mdb_put(*m_write_txn, m_output_keys, &k, &val_pubkey, 0))
v.mv_size = sizeof(pubkey);
v.mv_data = &pubkey;
if (mdb_put(*m_write_txn, m_output_keys, &k, &v, 0))
{ {
LOG_PRINT_L0("Failed to add output pubkey to db transaction"); LOG_PRINT_L0("Failed to add output pubkey to db transaction");
throw DB_ERROR("Failed to add output pubkey to db transaction"); throw DB_ERROR("Failed to add output pubkey to db transaction");
@ -459,11 +427,7 @@ void BlockchainLMDB::remove_tx_outputs(const crypto::hash& tx_hash)
lmdb_cur cur(*m_write_txn, m_tx_outputs); lmdb_cur cur(*m_write_txn, m_tx_outputs);
crypto::hash h_cpy = tx_hash; MDB_val_copy<crypto::hash> k(tx_hash);
MDB_val k;
k.mv_size = sizeof(h_cpy);
k.mv_data = &h_cpy;
MDB_val v; MDB_val v;
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET); auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
@ -485,7 +449,7 @@ void BlockchainLMDB::remove_tx_outputs(const crypto::hash& tx_hash)
for (uint64_t i = 0; i < num_elems; ++i) for (uint64_t i = 0; i < num_elems; ++i)
{ {
remove_output(*(uint64_t*)v.mv_data); remove_output(*(const uint64_t*)v.mv_data);
if (i < num_elems - 1) if (i < num_elems - 1)
{ {
mdb_cursor_get(cur, &k, &v, MDB_NEXT_DUP); mdb_cursor_get(cur, &k, &v, MDB_NEXT_DUP);
@ -578,11 +542,7 @@ void BlockchainLMDB::add_spent_key(const crypto::key_image& k_image)
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
crypto::key_image key = k_image; MDB_val_copy<crypto::key_image> val_key(k_image);
MDB_val val_key;
val_key.mv_size = sizeof(crypto::key_image);
val_key.mv_data = &key;
MDB_val unused; MDB_val unused;
if (mdb_get(*m_write_txn, m_spent_keys, &val_key, &unused) == 0) if (mdb_get(*m_write_txn, m_spent_keys, &val_key, &unused) == 0)
{ {
@ -605,10 +565,7 @@ void BlockchainLMDB::remove_spent_key(const crypto::key_image& k_image)
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
crypto::key_image key_cpy = k_image; MDB_val_copy<crypto::key_image> k(k_image);
MDB_val k;
k.mv_size = sizeof(crypto::key_image);
k.mv_data = &key_cpy;
auto result = mdb_del(*m_write_txn, m_spent_keys, &k, NULL); auto result = mdb_del(*m_write_txn, m_spent_keys, &k, NULL);
if (result != 0 && result != MDB_NOTFOUND) if (result != 0 && result != MDB_NOTFOUND)
{ {
@ -866,11 +823,7 @@ bool BlockchainLMDB::block_exists(const crypto::hash& h) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::hash key_cpy = h; MDB_val_copy<crypto::hash> key(h);
MDB_val key;
key.mv_size = sizeof(crypto::hash);
key.mv_data = &key_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_heights, &key, &result); auto get_result = mdb_get(txn, m_block_heights, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -909,11 +862,7 @@ uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::hash key_cpy = h; MDB_val_copy<crypto::hash> key(h);
MDB_val key;
key.mv_size = sizeof(crypto::hash);
key.mv_data = &key_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_heights, &key, &result); auto get_result = mdb_get(txn, m_block_heights, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -928,7 +877,7 @@ uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) const
} }
txn.commit(); txn.commit();
return *(uint64_t*)result.mv_data; return *(const uint64_t*)result.mv_data;
} }
block_header BlockchainLMDB::get_block_header(const crypto::hash& h) const block_header BlockchainLMDB::get_block_header(const crypto::hash& h) const
@ -952,10 +901,7 @@ block BlockchainLMDB::get_block_from_height(const uint64_t& height) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t height_cpy = height; MDB_val_copy<uint64_t> key(height);
MDB_val key;
key.mv_size = sizeof(uint64_t);
key.mv_data = &height_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_blocks, &key, &result); auto get_result = mdb_get(txn, m_blocks, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -996,10 +942,7 @@ uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t height_cpy = height; MDB_val_copy<uint64_t> key(height);
MDB_val key;
key.mv_size = sizeof(uint64_t);
key.mv_data = &height_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_timestamps, &key, &result); auto get_result = mdb_get(txn, m_block_timestamps, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1014,7 +957,7 @@ uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) const
} }
txn.commit(); txn.commit();
return *(uint64_t*)result.mv_data; return *(const uint64_t*)result.mv_data;
} }
uint64_t BlockchainLMDB::get_top_block_timestamp() const uint64_t BlockchainLMDB::get_top_block_timestamp() const
@ -1043,10 +986,7 @@ size_t BlockchainLMDB::get_block_size(const uint64_t& height) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t height_cpy = height; MDB_val_copy<uint64_t> key(height);
MDB_val key;
key.mv_size = sizeof(uint64_t);
key.mv_data = &height_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_sizes, &key, &result); auto get_result = mdb_get(txn, m_block_sizes, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1061,7 +1001,7 @@ size_t BlockchainLMDB::get_block_size(const uint64_t& height) const
} }
txn.commit(); txn.commit();
return *(size_t*)result.mv_data; return *(const size_t*)result.mv_data;
} }
difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t& height) const difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t& height) const
@ -1076,10 +1016,7 @@ difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t&
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t height_cpy = height; MDB_val_copy<uint64_t> key(height);
MDB_val key;
key.mv_size = sizeof(uint64_t);
key.mv_data = &height_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_diffs, &key, &result); auto get_result = mdb_get(txn, m_block_diffs, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1126,10 +1063,7 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t height_cpy = height; MDB_val_copy<uint64_t> key(height);
MDB_val key;
key.mv_size = sizeof(uint64_t);
key.mv_data = &height_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_coins, &key, &result); auto get_result = mdb_get(txn, m_block_coins, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1144,7 +1078,7 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh
} }
txn.commit(); txn.commit();
return *(uint64_t*)result.mv_data; return *(const uint64_t*)result.mv_data;
} }
crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) const crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) const
@ -1159,10 +1093,7 @@ crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height)
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t height_cpy = height; MDB_val_copy<uint64_t> key(height);
MDB_val key;
key.mv_size = sizeof(uint64_t);
key.mv_data = &height_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_block_hashes, &key, &result); auto get_result = mdb_get(txn, m_block_hashes, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1255,11 +1186,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::hash key_cpy = h; MDB_val_copy<crypto::hash> key(h);
MDB_val key;
key.mv_size = sizeof(crypto::hash);
key.mv_data = &key_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_txs, &key, &result); auto get_result = mdb_get(txn, m_txs, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1289,11 +1216,7 @@ uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::hash key_cpy = h; MDB_val_copy<crypto::hash> key(h);
MDB_val key;
key.mv_size = sizeof(crypto::hash);
key.mv_data = &key_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_tx_unlocks, &key, &result); auto get_result = mdb_get(txn, m_tx_unlocks, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1307,7 +1230,7 @@ uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) const
throw DB_ERROR("DB error attempting to fetch tx unlock time from hash"); throw DB_ERROR("DB error attempting to fetch tx unlock time from hash");
} }
return *(uint64_t*)result.mv_data; return *(const uint64_t*)result.mv_data;
} }
transaction BlockchainLMDB::get_tx(const crypto::hash& h) const transaction BlockchainLMDB::get_tx(const crypto::hash& h) const
@ -1322,11 +1245,7 @@ transaction BlockchainLMDB::get_tx(const crypto::hash& h) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::hash key_cpy = h; MDB_val_copy<crypto::hash> key(h);
MDB_val key;
key.mv_size = sizeof(crypto::hash);
key.mv_data = &key_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_txs, &key, &result); auto get_result = mdb_get(txn, m_txs, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1403,11 +1322,7 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::hash key_cpy = h; MDB_val_copy<crypto::hash> key(h);
MDB_val key;
key.mv_size = sizeof(crypto::hash);
key.mv_data = &key_cpy;
MDB_val result; MDB_val result;
auto get_result = mdb_get(txn, m_tx_heights, &key, &result); auto get_result = mdb_get(txn, m_tx_heights, &key, &result);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1421,7 +1336,7 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const
throw DB_ERROR("DB error attempting to fetch tx height from hash"); throw DB_ERROR("DB error attempting to fetch tx height from hash");
} }
return *(uint64_t*)result.mv_data; return *(const uint64_t*)result.mv_data;
} }
//FIXME: make sure the random method used here is appropriate //FIXME: make sure the random method used here is appropriate
@ -1454,11 +1369,7 @@ uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) const
lmdb_cur cur(txn, m_output_amounts); lmdb_cur cur(txn, m_output_amounts);
uint64_t amount_cpy = amount; MDB_val_copy<uint64_t> k(amount);
MDB_val k;
k.mv_size = sizeof(amount_cpy);
k.mv_data = &amount_cpy;
MDB_val v; MDB_val v;
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET); auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
if (result == MDB_NOTFOUND) if (result == MDB_NOTFOUND)
@ -1484,8 +1395,6 @@ crypto::public_key BlockchainLMDB::get_output_key(const uint64_t& amount, const
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open(); check_open();
uint64_t global = get_output_global_index(amount, index);
txn_safe txn; txn_safe txn;
if (mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn)) if (mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn))
{ {
@ -1493,10 +1402,7 @@ crypto::public_key BlockchainLMDB::get_output_key(const uint64_t& amount, const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
MDB_val k; MDB_val_copy<uint64_t> k(get_output_global_index(amount, index));
k.mv_size = sizeof(global);
k.mv_data = &global;
MDB_val v; MDB_val v;
auto get_result = mdb_get(txn, m_output_keys, &k, &v); auto get_result = mdb_get(txn, m_output_keys, &k, &v);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1525,15 +1431,10 @@ tx_out BlockchainLMDB::get_output(const crypto::hash& h, const uint64_t& index)
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
MDB_val k;
crypto::hash h_cpy = h;
k.mv_size = sizeof(h_cpy);
k.mv_data = &h_cpy;
lmdb_cur cur(txn, m_tx_outputs); lmdb_cur cur(txn, m_tx_outputs);
MDB_val_copy<crypto::hash> k(h);
MDB_val v; MDB_val v;
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET); auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
if (result == MDB_NOTFOUND) if (result == MDB_NOTFOUND)
{ {
@ -1590,11 +1491,7 @@ tx_out BlockchainLMDB::get_output(const uint64_t& index) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
uint64_t index_cpy = index; MDB_val_copy<uint64_t> k(index);
MDB_val k;
k.mv_size = sizeof(index_cpy);
k.mv_data = &index_cpy;
MDB_val v; MDB_val v;
auto get_result = mdb_get(txn, m_outputs, &k, &v); auto get_result = mdb_get(txn, m_outputs, &k, &v);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
@ -1627,11 +1524,7 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
lmdb_cur cur(txn, m_output_amounts); lmdb_cur cur(txn, m_output_amounts);
uint64_t amount_cpy = amount; MDB_val_copy<uint64_t> k(amount);
MDB_val k;
k.mv_size = sizeof(amount_cpy);
k.mv_data = &amount_cpy;
MDB_val v; MDB_val v;
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET); auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
@ -1666,12 +1559,11 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
mdb_cursor_get(cur, &k, &v, MDB_GET_CURRENT); mdb_cursor_get(cur, &k, &v, MDB_GET_CURRENT);
uint64_t glob_index = *(uint64_t*)v.mv_data; uint64_t glob_index = *(const uint64_t*)v.mv_data;
cur.close(); cur.close();
k.mv_size = sizeof(glob_index); k = MDB_val_copy<uint64_t>(glob_index);
k.mv_data = &glob_index;
auto get_result = mdb_get(txn, m_output_txs, &k, &v); auto get_result = mdb_get(txn, m_output_txs, &k, &v);
if (get_result == MDB_NOTFOUND) if (get_result == MDB_NOTFOUND)
{ {
@ -1700,7 +1592,7 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
txn.commit(); txn.commit();
return tx_out_index(tx_hash, *(uint64_t *)v.mv_data); return tx_out_index(tx_hash, *(const uint64_t *)v.mv_data);
} }
std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash& h) const std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash& h) const
@ -1716,15 +1608,10 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash&
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
MDB_val k;
crypto::hash h_cpy = h;
k.mv_size = sizeof(h_cpy);
k.mv_data = &h_cpy;
lmdb_cur cur(txn, m_tx_outputs); lmdb_cur cur(txn, m_tx_outputs);
MDB_val_copy<crypto::hash> k(h);
MDB_val v; MDB_val v;
auto result = mdb_cursor_get(cur, &k, &v, MDB_SET); auto result = mdb_cursor_get(cur, &k, &v, MDB_SET);
if (result == MDB_NOTFOUND) if (result == MDB_NOTFOUND)
{ {
@ -1746,7 +1633,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash&
{ {
mdb_cursor_get(cur, &k, &v, MDB_NEXT_DUP); mdb_cursor_get(cur, &k, &v, MDB_NEXT_DUP);
mdb_cursor_get(cur, &k, &v, MDB_GET_CURRENT); mdb_cursor_get(cur, &k, &v, MDB_GET_CURRENT);
index_vec.push_back(*(uint64_t *)v.mv_data); index_vec.push_back(*(const uint64_t *)v.mv_data);
} }
cur.close(); cur.close();
@ -1767,11 +1654,7 @@ bool BlockchainLMDB::has_key_image(const crypto::key_image& img) const
throw DB_ERROR("Failed to create a transaction for the db"); throw DB_ERROR("Failed to create a transaction for the db");
} }
crypto::key_image key = img; MDB_val_copy<crypto::key_image> val_key(img);
MDB_val val_key;
val_key.mv_size = sizeof(crypto::key_image);
val_key.mv_data = &key;
MDB_val unused; MDB_val unused;
if (mdb_get(txn, m_spent_keys, &val_key, &unused) == 0) if (mdb_get(txn, m_spent_keys, &val_key, &unused) == 0)
{ {

View file

@ -238,12 +238,6 @@ bool Blockchain::init(const std::string& config_folder, bool testnet)
boost::filesystem::path folder(m_config_folder); boost::filesystem::path folder(m_config_folder);
// append "testnet" directory as needed
if (testnet)
{
folder /= "testnet";
}
LOG_PRINT_L0("Loading blockchain..."); LOG_PRINT_L0("Loading blockchain...");
//FIXME: update filename for BlockchainDB //FIXME: update filename for BlockchainDB