mylmdb.h removed

pull/93/merge
moneroexamples 6 years ago
parent 8f59acd34c
commit 9e10445241

@ -79,7 +79,9 @@ xmreg::MySqlConnector::dbname = config_json["database"]["dbname"];
// have only once instance of this class, which we can easly inject
// and pass around other class which need to access blockchain data
auto current_bc_status = make_shared<xmreg::CurrentBlockchainStatus>(bc_setup);
auto current_bc_status
= make_shared<xmreg::CurrentBlockchainStatus>(
bc_setup, std::make_unique<xmreg::MicroCore>());
// since CurrentBlockchainStatus class monitors current status

@ -18,8 +18,11 @@
namespace xmreg
{
CurrentBlockchainStatus::CurrentBlockchainStatus(BlockchainSetup _bc_setup)
: bc_setup {_bc_setup}
CurrentBlockchainStatus::CurrentBlockchainStatus(
BlockchainSetup _bc_setup,
std::unique_ptr<MicroCore> _mcore)
: bc_setup {_bc_setup},
mcore {std::move(_mcore)}
{
}
@ -57,19 +60,7 @@ CurrentBlockchainStatus::start_monitor_blockchain_thread()
uint64_t
CurrentBlockchainStatus::get_current_blockchain_height()
{
uint64_t previous_height = current_height;
try
{
return xmreg::MyLMDB::get_blockchain_height(bc_setup.blockchain_path) - 1;
}
catch(std::exception& e)
{
cerr << "xmreg::MyLMDB::get_blockchain_height: " << e.what() << endl;
return previous_height;
}
return mcore.get_current_blockchain_height() - 1;
}
@ -87,7 +78,7 @@ CurrentBlockchainStatus::init_monero_blockchain()
mlog_configure(mlog_get_default_log_path(""), true);
// initialize the core using the blockchain path
return mcore.init(bc_setup.blockchain_path, bc_setup.net_type);}
return mcore->init(bc_setup.blockchain_path, bc_setup.net_type);}
bool
@ -143,7 +134,7 @@ CurrentBlockchainStatus::is_tx_spendtime_unlocked(
bool
CurrentBlockchainStatus::get_block(uint64_t height, block &blk)
{
return mcore.get_block_from_height(height, blk);
return mcore->get_block_from_height(height, blk);
}
vector<block>
@ -152,7 +143,7 @@ CurrentBlockchainStatus::get_blocks_range(
{
try
{
return mcore.get_blocks_range(h1, h2);
return mcore->get_blocks_range(h1, h2);
}
catch (BLOCK_DNE& e)
{
@ -173,7 +164,7 @@ CurrentBlockchainStatus::get_block_txs(
// the block i.e. coinbase tx.
blk_txs.push_back(blk.miner_tx);
if (!mcore.get_transactions(blk.tx_hashes, blk_txs, missed_txs))
if (!mcore->get_transactions(blk.tx_hashes, blk_txs, missed_txs))
{
cerr << "Cant get transactions in block: " << get_block_hash(blk) << endl;
return false;
@ -188,7 +179,7 @@ CurrentBlockchainStatus::get_txs(
vector<transaction>& txs,
vector<crypto::hash>& missed_txs)
{
if (!mcore.get_transactions(txs_to_get, txs, missed_txs))
if (!mcore->get_transactions(txs_to_get, txs, missed_txs))
{
cerr << "CurrentBlockchainStatus::get_txs: cant get transactions!\n";
return false;
@ -200,13 +191,13 @@ CurrentBlockchainStatus::get_txs(
bool
CurrentBlockchainStatus::tx_exist(const crypto::hash& tx_hash)
{
return mcore.have_tx(tx_hash);
return mcore->have_tx(tx_hash);
}
bool
CurrentBlockchainStatus::tx_exist(const crypto::hash& tx_hash, uint64_t& tx_index)
{
return mcore.tx_exists(tx_hash, tx_index);
return mcore->tx_exists(tx_hash, tx_index);
}
@ -248,7 +239,7 @@ CurrentBlockchainStatus::get_tx_with_output(
{
// get pair pair<crypto::hash, uint64_t> where first is tx hash
// and second is local index of the output i in that tx
tx_out_idx = mcore.get_output_tx_and_index(amount, output_idx);
tx_out_idx = mcore->get_output_tx_and_index(amount, output_idx);
}
catch (const OUTPUT_DNE &e)
{
@ -265,7 +256,7 @@ CurrentBlockchainStatus::get_tx_with_output(
output_idx_in_tx = tx_out_idx.second;
if (!mcore.get_tx(tx_out_idx.first, tx))
if (!mcore->get_tx(tx_out_idx.first, tx))
{
cerr << "Cant get tx: " << tx_out_idx.first << endl;
@ -282,7 +273,7 @@ CurrentBlockchainStatus::get_output_keys(const uint64_t& amount,
{
try
{
mcore.get_output_key(amount, absolute_offsets, outputs);
mcore->get_output_key(amount, absolute_offsets, outputs);
}
catch (const OUTPUT_DNE& e)
{
@ -324,9 +315,9 @@ CurrentBlockchainStatus::get_amount_specific_indices(const crypto::hash& tx_hash
// this index is lmdb index of a tx, not tx hash
uint64_t tx_index;
if (mcore.tx_exists(tx_hash, tx_index))
if (mcore->tx_exists(tx_hash, tx_index))
{
out_indices = mcore.get_tx_amount_output_indices(tx_index);
out_indices = mcore->get_tx_amount_output_indices(tx_index);
return true;
}
@ -419,8 +410,7 @@ CurrentBlockchainStatus::read_mempool()
std::vector<tx_info> mempool_tx_info;
vector<spent_key_image_info> key_image_infos;
if (mcore.get_mempool().get_transactions_and_spent_keys_info(
mempool_tx_info, key_image_infos))
if (!mcore->get_mempool_txs(mempool_tx_info, key_image_infos))
{
cerr << "Getting mempool failed " << endl;
return false;
@ -570,7 +560,7 @@ CurrentBlockchainStatus::search_if_payment_made(
if (decrypted_payment_id8 != null_hash8)
{
if (!mcore.get_device()->decrypt_payment_id(
if (!mcore->get_device()->decrypt_payment_id(
decrypted_payment_id8, tx_pub_key, bc_setup.import_payment_viewkey))
{
cerr << "Cant decrypt decrypted_payment_id8: "
@ -705,7 +695,7 @@ CurrentBlockchainStatus::get_payment_id_as_string(const transaction& tx)
output_data_t
CurrentBlockchainStatus::get_output_key(uint64_t amount, uint64_t global_amount_index)
{
return mcore.get_output_key(amount, global_amount_index);
return mcore->get_output_key(amount, global_amount_index);
}
bool
@ -925,7 +915,7 @@ CurrentBlockchainStatus::find_key_images_in_mempool(transaction const& tx)
bool
CurrentBlockchainStatus::get_tx(crypto::hash const& tx_hash, transaction& tx)
{
return mcore.get_tx(tx_hash, tx);
return mcore->get_tx(tx_hash, tx);
}
@ -939,7 +929,7 @@ CurrentBlockchainStatus::get_tx(string const& tx_hash_str, transaction& tx)
return false;
}
return mcore.get_tx(tx_hash, tx);
return mcore->get_tx(tx_hash, tx);
}
bool
@ -948,7 +938,7 @@ CurrentBlockchainStatus::get_tx_block_height(crypto::hash const& tx_hash, int64_
if (!tx_exist(tx_hash))
return false;
tx_height = mcore.get_tx_block_height(tx_hash);
tx_height = mcore->get_tx_block_height(tx_hash);
return true;
}

@ -51,9 +51,10 @@ public:
atomic<uint64_t> current_height;
bool is_running;
atomic<bool> is_running;
CurrentBlockchainStatus(BlockchainSetup _bc_setup);
CurrentBlockchainStatus(BlockchainSetup _bc_setup,
std::unique_ptr<MicroCore> _mcore);
virtual void
start_monitor_blockchain_thread();
@ -251,7 +252,10 @@ protected:
// since this class monitors current status
// of the blockchain, its seems logical to
// make object for accessing the blockchain here
MicroCore mcore;
// use pointer for this, so that we can easly
// inject mock MicroCore class in our tests
// as MicroCore is not copabaly nor movable
std::unique_ptr<MicroCore> mcore;
// vector of mempool transactions that all threads
// can refer to

@ -26,8 +26,6 @@ MicroCore::MicroCore():
{
}
/**
* Initialized the MicroCore object.
*
@ -42,13 +40,7 @@ MicroCore::init(const string& _blockchain_path, network_type nt)
nettype = nt;
std::unique_ptr<BlockchainDB> db(new_db("lmdb"));
if (db == nullptr)
{
cerr << "Attempted to use non-existent database type\n";
return false;
}
std::unique_ptr<BlockchainDB> db = std::make_unique<BlockchainLMDB>();
try
{

@ -39,16 +39,23 @@ class MicroCore {
public:
MicroCore();
bool
/**
* Initialized the MicroCore object.
*
* Create BlockchainLMDB on the heap.
* Open database files located in blockchain_path.
* Initialize m_blockchain_storage with the BlockchainLMDB object.
*/
virtual bool
init(const string& _blockchain_path, network_type nt);
Blockchain const&
virtual Blockchain const&
get_core() const;
tx_memory_pool const&
virtual tx_memory_pool const&
get_mempool() const;
hw::device* const
virtual hw::device* const
get_device() const;
template<typename... T>
@ -99,13 +106,23 @@ public:
return core_storage.get_db().get_tx_amount_output_indices(std::forward<T>(args)...);
}
bool
get_block_from_height(uint64_t height, block& blk) const;
template<typename... T>
auto get_mempool_txs(T&&... args) const
{
return m_mempool.get_transactions_and_spent_keys_info(std::forward<T>(args)...);
}
bool
get_tx(crypto::hash const& tx_hash, transaction& tx) const;
virtual uint64_t
get_current_blockchain_height() const
{
return core_storage.get_current_blockchain_height();
}
virtual bool
get_block_from_height(uint64_t height, block& blk) const;
virtual bool
get_tx(crypto::hash const& tx_hash, transaction& tx) const;
};
}

@ -1,755 +0,0 @@
//
// Created by mwo on 27/04/16.
//
#ifndef XMRLMDBCPP_MYLMDB_H
#define XMRLMDBCPP_MYLMDB_H
#include "../ext/lmdb++.h"
#include <iostream>
#include <memory>
namespace xmreg
{
using epee::string_tools::pod_to_hex;
using epee::string_tools::hex_to_pod;
using namespace std;
/**
* Stores info about outputs useful
* for checking which ouputs belong to a
* given address and viewkey
*/
struct output_info
{
crypto::public_key out_pub_key;
crypto::hash tx_hash;
crypto::public_key tx_pub_key;
uint64_t amount;
uint64_t index_in_tx;
};
std::ostream& operator<<(std::ostream& os, const output_info& out_info)
{
os << ", out_pub_key: " << out_info.out_pub_key
<< ", tx_hash: " << out_info.tx_hash
<< ", tx_pub_key: " << out_info.tx_pub_key
<< ", amount: " << XMR_AMOUNT(out_info.amount)
<< ", index_in_tx: " << out_info.index_in_tx;
return os;
}
class MyLMDB
{
static const uint64_t DEFAULT_MAPSIZE = 30UL * 1024UL * 1024UL * 1024UL; /* 30 GiB */
static const uint64_t DEFAULT_NO_DBs = 10;
string m_db_path;
uint64_t m_mapsize;
uint64_t m_no_dbs;
lmdb::env m_env;
public:
MyLMDB(string _path,
uint64_t _mapsize = DEFAULT_MAPSIZE,
uint64_t _no_dbs = DEFAULT_NO_DBs)
: m_db_path {_path},
m_mapsize {_mapsize},
m_no_dbs {_no_dbs},
m_env {nullptr}
{
create_and_open_env();
}
bool
create_and_open_env()
{
try
{ m_env = lmdb::env::create();
m_env.set_mapsize(m_mapsize);
m_env.set_max_dbs(m_no_dbs);
m_env.open(m_db_path.c_str(), MDB_CREATE, 0664);
}
catch (lmdb::error& e )
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
write_key_images(const transaction& tx)
{
crypto::hash tx_hash = get_transaction_hash(tx);
string tx_hash_str = pod_to_hex(tx_hash);
vector<cryptonote::txin_to_key> key_images
= xmreg::get_key_images(tx);
lmdb::txn wtxn {nullptr};
lmdb::dbi wdbi {0};
unsigned int flags = MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED;
try
{
wtxn = lmdb::txn::begin(m_env);
wdbi = lmdb::dbi::open(wtxn, "key_images", flags);
}
catch (lmdb::error& e )
{
cerr << e.what() << endl;
return false;
}
for (const cryptonote::txin_to_key& key_image: key_images)
{
string key_img_str = pod_to_hex(key_image.k_image);
lmdb::val key_img_val {key_img_str};
lmdb::val tx_hash_val {tx_hash_str};
wdbi.put(wtxn, key_img_val, tx_hash_val);
}
try
{
wtxn.commit();
}
catch (lmdb::error& e )
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
write_output_public_keys(const transaction& tx, const block& blk)
{
crypto::hash tx_hash = get_transaction_hash(tx);
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
string tx_hash_str = pod_to_hex(tx_hash);
vector<tuple<txout_to_key, uint64_t, uint64_t>> outputs =
xmreg::get_ouputs_tuple(tx);
lmdb::txn wtxn {nullptr};
lmdb::dbi wdbi1 {0};
lmdb::dbi wdbi2 {0};
lmdb::dbi wdbi3 {0};
unsigned int flags = MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED;
try
{
wtxn = lmdb::txn::begin(m_env);
wdbi1 = lmdb::dbi::open(wtxn, "output_public_keys", flags);
wdbi2 = lmdb::dbi::open(wtxn, "output_amounts", flags);
wdbi3 = lmdb::dbi::open(wtxn, "output_info",
flags | MDB_INTEGERKEY | MDB_INTEGERDUP);
}
catch (lmdb::error& e )
{
cerr << e.what() << endl;
return false;
}
for (auto& output: outputs)
{
public_key out_pub_key = std::get<0>(output).key;
string public_key_str = pod_to_hex(out_pub_key);
lmdb::val public_key_val {public_key_str};
lmdb::val tx_hash_val {tx_hash_str};
uint64_t amount = std::get<1>(output);
lmdb::val amount_val {static_cast<void*>(&amount), sizeof(amount)};
uint64_t index_in_tx = std::get<2>(output);
output_info out_info {out_pub_key, tx_hash,
tx_pub_key, amount,
index_in_tx};
uint64_t out_timestamp = blk.timestamp;
lmdb::val out_timestamp_val {static_cast<void*>(&out_timestamp),
sizeof(out_timestamp)};
lmdb::val out_info_val {static_cast<void*>(&out_info),
sizeof(out_info)};
wdbi1.put(wtxn, public_key_val, tx_hash_val);
wdbi2.put(wtxn, public_key_val, amount_val);
wdbi3.put(wtxn, out_timestamp_val, out_info_val);
}
try
{
wtxn.commit();
}
catch (lmdb::error& e )
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
write_tx_public_key(const transaction& tx)
{
crypto::hash tx_hash = get_transaction_hash(tx);
string tx_hash_str = pod_to_hex(tx_hash);
unsigned int flags = MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED;
public_key pk = get_tx_pub_key_from_extra(tx);
string pk_str = pod_to_hex(pk);
try
{
lmdb::txn wtxn = lmdb::txn::begin(m_env);
lmdb::dbi wdbi = lmdb::dbi::open(wtxn, "tx_public_keys", flags);
//cout << "Saving public_key: " << pk_str << endl;
lmdb::val public_key_val {pk_str};
lmdb::val tx_hash_val {tx_hash_str};
wdbi.put(wtxn, public_key_val, tx_hash_val);
wtxn.commit();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
write_payment_id(const transaction& tx)
{
crypto::hash tx_hash = get_transaction_hash(tx);
string tx_hash_str = pod_to_hex(tx_hash);
crypto::hash payment_id;
crypto::hash8 payment_id8;
get_payment_id(tx, payment_id, payment_id8);
if (payment_id == null_hash)
{
return true;
}
unsigned int flags = MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED;
string payment_id_str = pod_to_hex(payment_id);
try
{
lmdb::txn wtxn = lmdb::txn::begin(m_env);
lmdb::dbi wdbi = lmdb::dbi::open(wtxn, "payments_id", flags);
//cout << "Saving payiment_id: " << payment_id_str << endl;
lmdb::val payment_id_val {payment_id_str};
lmdb::val tx_hash_val {tx_hash_str};
wdbi.put(wtxn, payment_id_val, tx_hash_val);
wtxn.commit();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
write_encrypted_payment_id(const transaction& tx)
{
crypto::hash tx_hash = get_transaction_hash(tx);
string tx_hash_str = pod_to_hex(tx_hash);
crypto::hash payment_id;
crypto::hash8 payment_id8;
get_payment_id(tx, payment_id, payment_id8);
if (payment_id8 == null_hash8)
{
return true;
}
unsigned int flags = MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED;
string payment_id_str = pod_to_hex(payment_id8);
try
{
lmdb::txn wtxn = lmdb::txn::begin(m_env);
lmdb::dbi wdbi = lmdb::dbi::open(wtxn, "encrypted_payments_id", flags);
//cout << "Saving encrypted payiment_id: " << payment_id_str << endl;
//string wait_for_enter;
//cin >> wait_for_enter;
lmdb::val payment_id_val {payment_id_str};
lmdb::val tx_hash_val {tx_hash_str};
wdbi.put(wtxn, payment_id_val, tx_hash_val);
wtxn.commit();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
// // this seems to be not needed as outputs are written based on timestamps
//
// bool
// write_block_timestamp(uint64_t& blk_timestamp, uint64_t& blk_height)
// {
//
// unsigned int flags = MDB_CREATE | MDB_INTEGERKEY;
//
// try
// {
// lmdb::txn wtxn = lmdb::txn::begin(m_env);
// lmdb::dbi wdbi = lmdb::dbi::open(wtxn, "block_timestamps", flags);
//
// lmdb::val blk_timestamp_val {static_cast<void*>(&blk_timestamp),
// sizeof(blk_timestamp)};
// lmdb::val blk_height_val {static_cast<void*>(&blk_height),
// sizeof(blk_height)};
//
// wdbi.put(wtxn, blk_timestamp_val, blk_height_val);
//
// wtxn.commit();
// }
// catch (lmdb::error& e)
// {
// cerr << e.what() << endl;
// return false;
// }
//
// return true;
// }
bool
search(const string& key,
vector<string>& found_tx_hashes,
const string& db_name = "key_images")
{
unsigned int flags = MDB_DUPSORT | MDB_DUPFIXED;
try
{
lmdb::txn rtxn = lmdb::txn::begin(m_env, nullptr, MDB_RDONLY);
lmdb::dbi rdbi = lmdb::dbi::open(rtxn, db_name.c_str(), flags);
lmdb::cursor cr = lmdb::cursor::open(rtxn, rdbi);
lmdb::val key_to_find{key};
lmdb::val tx_hash_val;
// set cursor the the first item
if (cr.get(key_to_find, tx_hash_val, MDB_SET))
{
//cout << key_val_to_str(key_to_find, tx_hash_val) << endl;
found_tx_hashes.push_back(string(tx_hash_val.data(), tx_hash_val.size()));
// process other values for the same key
while (cr.get(key_to_find, tx_hash_val, MDB_NEXT_DUP))
{
//cout << key_val_to_str(key_to_find, tx_hash_val) << endl;
found_tx_hashes.push_back(string(tx_hash_val.data(), tx_hash_val.size()));
}
}
else
{
return false;
}
cr.close();
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
get_output_amount(const string& key,
uint64_t& amount,
const string& db_name = "output_amounts")
{
unsigned int flags = 0;
try
{
lmdb::txn rtxn = lmdb::txn::begin(m_env, nullptr, MDB_RDONLY);
lmdb::dbi rdbi = lmdb::dbi::open(rtxn, db_name.c_str(), flags);
lmdb::val key_to_find{key};
lmdb::val amount_val;
if(!rdbi.get(rtxn, key_to_find, amount_val))
{
return false;
}
amount = *(amount_val.data<uint64_t>());
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
get_output_info(uint64_t key_timestamp,
vector<output_info>& out_infos,
const string& db_name = "output_info")
{
unsigned int flags = 0;
try
{
lmdb::txn rtxn = lmdb::txn::begin(m_env, nullptr, MDB_RDONLY);
lmdb::dbi rdbi = lmdb::dbi::open(rtxn, db_name.c_str(), flags);
lmdb::val key_to_find{static_cast<void*>(&key_timestamp),
sizeof(key_timestamp)};
lmdb::val info_val;
lmdb::cursor cr = lmdb::cursor::open(rtxn, rdbi);
// set cursor the the first item
if (cr.get(key_to_find, info_val, MDB_SET_RANGE))
{
out_infos.push_back(*(info_val.data<output_info>()));
// process other values for the same key
while (cr.get(key_to_find, info_val, MDB_NEXT_DUP))
{
//cout << key_val_to_str(key_to_find, tx_hash_val) << endl;
out_infos.push_back(*(info_val.data<output_info>()));
}
}
else
{
return false;
}
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
bool
get_output_info_range(uint64_t key_timestamp_start,
uint64_t key_timestamp_end,
vector<pair<uint64_t, output_info>>& out_infos,
const string& db_name = "output_info")
{
unsigned int flags = 0;
try
{
lmdb::txn rtxn = lmdb::txn::begin(m_env, nullptr, MDB_RDONLY);
lmdb::dbi rdbi = lmdb::dbi::open(rtxn, db_name.c_str(), flags);
lmdb::val key_to_find{static_cast<void*>(&key_timestamp_start),
sizeof(key_timestamp_start)};
lmdb::val info_val;
lmdb::cursor cr = lmdb::cursor::open(rtxn, rdbi);
uint64_t current_timestamp = key_timestamp_start;
// set cursor the the first item
if (cr.get(key_to_find, info_val, MDB_SET_RANGE))
{
current_timestamp = *key_to_find.data<uint64_t>();
if (current_timestamp > key_timestamp_end)
{
return false;
}
out_infos.push_back(make_pair(
current_timestamp,
*(info_val.data<output_info>())));
// process other values for the same key
while (cr.get(key_to_find, info_val, MDB_NEXT))
{
current_timestamp = *key_to_find.data<uint64_t>();
if (current_timestamp > key_timestamp_end)
{
break;
}
out_infos.push_back(make_pair(
current_timestamp,
*(info_val.data<output_info>())));
}
}
else
{
return false;
}
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return false;
}
return true;
}
/**
* Returns sorted and unique tx hashes withing a
* given timestamp range
*
* @param key_timestamp_start
* @param key_timestamp_end
* @param out_txs
* @return bool
*/
bool
get_txs_from_timestamp_range(uint64_t key_timestamp_start,
uint64_t key_timestamp_end,
vector<crypto::hash>& out_txs)
{
using output_pair = pair<uint64_t, output_info>;
auto sort_by_timestamp = [](const output_pair& l,
const output_pair& r)
{
return l.first < r.first;
};
vector<output_pair> out_infos;
if (get_output_info_range(key_timestamp_start,
key_timestamp_end,
out_infos))
{
set<output_pair, decltype(sort_by_timestamp)> unique_txs(sort_by_timestamp);
for (auto oi: out_infos)
unique_txs.insert(oi);
for (auto ut: unique_txs)
out_txs.push_back(ut.second.tx_hash);
return true;
}
return false;
}
void
for_all_outputs(
std::function<bool(public_key& out_pubkey,
output_info& out_info)> f)
{
unsigned int flags = MDB_DUPSORT | MDB_DUPFIXED;
try
{
lmdb::txn rtxn = lmdb::txn::begin(m_env, nullptr, MDB_RDONLY);
lmdb::dbi rdbi = lmdb::dbi::open(rtxn, "output_info", flags);
lmdb::cursor cr = lmdb::cursor::open(rtxn, rdbi);
lmdb::val key_to_find;
lmdb::val amount_val;
// process all values for the same key
while (cr.get(key_to_find, amount_val, MDB_NEXT))
{
public_key pub_key;
hex_to_pod(string(key_to_find.data(), key_to_find.size()),
pub_key);
output_info out_info = *(amount_val.data<output_info>());
if (f(pub_key, out_info) == false)
{
break;
}
}
cr.close();
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
}
}
void
print_all(const string& db_name)
{
unsigned int flags = MDB_DUPSORT | MDB_DUPFIXED;
try
{
lmdb::txn rtxn = lmdb::txn::begin(m_env, nullptr, MDB_RDONLY);
lmdb::dbi rdbi = lmdb::dbi::open(rtxn, db_name.c_str(), flags);
lmdb::cursor cr = lmdb::cursor::open(rtxn, rdbi);
lmdb::val key_to_find;
lmdb::val tx_hash_val;
// process other values for the same key
while (cr.get(key_to_find, tx_hash_val, MDB_NEXT))
{
cout << key_val_to_str(key_to_find, tx_hash_val) << endl;
}
cr.close();
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
}
}
static uint64_t
get_blockchain_height(string blk_path = "/home/mwo/.blockchain/lmdb")
{
uint64_t height {0};
try
{
auto env = lmdb::env::create();
env.set_mapsize(DEFAULT_MAPSIZE * 3);
env.set_max_dbs(20);
env.open(blk_path.c_str(), MDB_CREATE, 0664);
//auto rtxn = lmdb::txn::begin(env, nullptr, MDB_RDONLY);
auto rtxn = lmdb::txn::begin(env, nullptr);
auto rdbi = lmdb::dbi::open(rtxn, "blocks");
MDB_stat stats = rdbi.stat(rtxn);
height = static_cast<uint64_t>(stats.ms_entries);
rtxn.abort();
}
catch (lmdb::error& e)
{
cerr << e.what() << endl;
return height;
}
catch (exception& e)
{
cerr << e.what() << endl;
return height;
}
//cout << height << endl;
return height;
}
string
key_val_to_str(const lmdb::val& key, const lmdb::val& val)
{
return "key: " + string(key.data(), key.size())
+ ", val: " + string(val.data(), val.size());
}
};
}
#endif //XMRLMDBCPP_MYLMDB_H

@ -20,6 +20,7 @@ resource_dir("./res")
add_om_test(mysql)
add_om_test(microcore)
add_om_test(bcstatus)
SETUP_TARGET_FOR_COVERAGE(
NAME mysql_cov # New target name
@ -29,3 +30,7 @@ SETUP_TARGET_FOR_COVERAGE(
SETUP_TARGET_FOR_COVERAGE(
NAME microcore_cov # New target name
EXECUTABLE microcore_tests)
SETUP_TARGET_FOR_COVERAGE(
NAME bcstatus_cov # New target name
EXECUTABLE bcstatus_tests)

@ -0,0 +1,83 @@
//
// Created by mwo on 15/06/18.
//
#include "../src/MicroCore.h"
#include "../src/CurrentBlockchainStatus.h"
#include "../src/ThreadRAII.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace
{
using json = nlohmann::json;
using namespace std;
using namespace cryptonote;
using namespace epee::string_tools;
using namespace std::chrono_literals;
using ::testing::AllOf;
using ::testing::Ge;
using ::testing::Le;
using ::testing::HasSubstr;
using ::testing::Not;
using ::testing::internal::FilePath;
class BCSTATUS_TEST : public ::testing::Test
{
public:
static void
SetUpTestCase()
{
string config_path {"../config/config.json"};
config_json = xmreg::BlockchainSetup::read_config(config_path);
}
protected:
virtual void
SetUp()
{
bc_setup = xmreg::BlockchainSetup{net_type, do_not_relay, config_json};
}
network_type net_type {network_type::STAGENET};
bool do_not_relay {false};
xmreg::BlockchainSetup bc_setup;
static json config_json;
};
json BCSTATUS_TEST::config_json;
TEST_F(BCSTATUS_TEST, DefaultConstruction)
{
xmreg::CurrentBlockchainStatus bcs {bc_setup, nullptr};
EXPECT_TRUE(true);
}
class MockMicroCore : public xmreg::MicroCore
{
bool
init(const string& _blockchain_path, network_type nt)
{
return true;
}
};
TEST_F(BCSTATUS_TEST, InitMoneroBlockchain)
{
std::unique_ptr<MockMicroCore> mcore = std::make_unique<MockMicroCore>();
xmreg::CurrentBlockchainStatus bcs {bc_setup, std::move(mcore)};
EXPECT_TRUE(bcs.init_monero_blockchain());
}
}

@ -276,4 +276,28 @@ TEST_F(MICROCORE_TEST, InitializationSuccess)
EXPECT_TRUE(mcore.get_core().get_db().is_read_only());
}
//template <bool open_success>
//class MockBlockchainDB : public BlockchainLMDB
//{
// void
// open(const std::string& filename, const int mdb_flags=0) override
// {
// if (open_success == false)
// throw std::runtime_error("Cant open database");
// }
// bool is_open() const
// {
// return false;
// }
//};
//TEST_F(MICROCORE_TEST, InitializationFailure)
//{
// xmreg::MicroCore mcore;
// EXPECT_FALSE(mcore.init<MockBlockchainDB<false>>(bc_setup.blockchain_path, net_type));
// EXPECT_FALSE(mcore.init<MockBlockchainDB<true>>(bc_setup.blockchain_path, net_type));
//}
}

@ -1199,7 +1199,10 @@ class MockCurrentBlockchainStatus1 : public xmreg::CurrentBlockchainStatus
{
public:
MockCurrentBlockchainStatus1()
: xmreg::CurrentBlockchainStatus(xmreg::BlockchainSetup()) {}
: xmreg::CurrentBlockchainStatus(
xmreg::BlockchainSetup(),
nullptr)
{}
bool tx_unlock_state {true};
bool tx_exist_state {true};

Loading…
Cancel
Save