Electroneum
cryptonote::BlockchainLMDB Class Reference

#include <db_lmdb.h>

Inheritance diagram for cryptonote::BlockchainLMDB:
Collaboration diagram for cryptonote::BlockchainLMDB:

Public Member Functions

 BlockchainLMDB (bool batch_transactions=true)
 
 ~BlockchainLMDB ()
 
virtual void open (const std::string &filename, const int mdb_flags=0)
 open a db, or create it if necessary. More...
 
virtual void close ()
 close the BlockchainDB More...
 
virtual void sync ()
 sync the BlockchainDB with disk More...
 
virtual void safesyncmode (const bool onoff)
 toggle safe syncs for the DB More...
 
virtual void reset ()
 Remove everything from the BlockchainDB. More...
 
virtual std::vector< std::string > get_filenames () const
 get all files used by the BlockchainDB (if any) More...
 
virtual bool remove_data_file (const std::string &folder) const
 remove file(s) storing the database More...
 
virtual std::string get_db_name () const
 gets the name of the folder the BlockchainDB's file(s) should be in More...
 
virtual bool lock ()
 acquires the BlockchainDB lock More...
 
virtual void unlock ()
 This function releases the BlockchainDB lock. More...
 
virtual bool block_exists (const crypto::hash &h, uint64_t *height=NULL) const
 checks if a block exists More...
 
virtual uint64_t get_block_height (const crypto::hash &h) const
 gets the height of the block with a given hash More...
 
virtual block_header get_block_header (const crypto::hash &h) const
 fetch a block header More...
 
virtual cryptonote::blobdata get_block_blob (const crypto::hash &h) const
 fetches the block with the given hash More...
 
virtual cryptonote::blobdata get_block_blob_from_height (const uint64_t &height) const
 fetch a block blob by height More...
 
virtual std::vector< uint64_tget_block_cumulative_rct_outputs (const std::vector< uint64_t > &heights) const
 fetch a block's cumulative number of rct outputs More...
 
virtual uint64_t get_block_timestamp (const uint64_t &height) const
 fetch a block's timestamp More...
 
virtual uint64_t get_top_block_timestamp () const
 fetch the top block's timestamp More...
 
virtual size_t get_block_weight (const uint64_t &height) const
 fetch a block's weight More...
 
virtual std::vector< uint64_tget_block_weights (uint64_t start_height, size_t count) const
 fetch the last N blocks' weights More...
 
virtual void set_block_cumulative_difficulty (uint64_t height, difficulty_type diff)
 sets a block's cumulative difficulty More...
 
virtual difficulty_type get_block_cumulative_difficulty (const uint64_t &height) const
 fetch a block's cumulative difficulty More...
 
virtual difficulty_type get_block_difficulty (const uint64_t &height) const
 fetch a block's difficulty More...
 
virtual uint64_t get_block_already_generated_coins (const uint64_t &height) const
 fetch a block's already generated coins More...
 
virtual uint64_t get_block_long_term_weight (const uint64_t &height) const
 fetch a block's long term weight More...
 
virtual std::vector< uint64_tget_long_term_block_weights (uint64_t start_height, size_t count) const
 fetch the last N blocks' long term weights More...
 
virtual crypto::hash get_block_hash_from_height (const uint64_t &height) const
 fetch a block's hash More...
 
virtual std::vector< blockget_blocks_range (const uint64_t &h1, const uint64_t &h2) const
 fetch a list of blocks More...
 
virtual std::vector< crypto::hashget_hashes_range (const uint64_t &h1, const uint64_t &h2) const
 fetch a list of block hashes More...
 
virtual crypto::hash top_block_hash (uint64_t *block_height=NULL) const
 fetch the top block's hash More...
 
virtual block get_top_block () const
 fetch the top block More...
 
virtual uint64_t height () const
 fetch the current blockchain height More...
 
virtual bool tx_exists (const crypto::hash &h) const
 check if a transaction with a given hash exists More...
 
virtual bool tx_exists (const crypto::hash &h, uint64_t &tx_index) const
 
virtual uint64_t get_tx_unlock_time (const crypto::hash &h) const
 fetch a transaction's unlock time/height More...
 
virtual bool get_tx_blob (const crypto::hash &h, cryptonote::blobdata &tx) const
 fetches the transaction blob with the given hash More...
 
virtual bool get_pruned_tx_blob (const crypto::hash &h, cryptonote::blobdata &tx) const
 fetches the pruned transaction blob with the given hash More...
 
virtual bool get_prunable_tx_blob (const crypto::hash &h, cryptonote::blobdata &tx) const
 fetches the prunable transaction blob with the given hash More...
 
virtual bool get_prunable_tx_hash (const crypto::hash &tx_hash, crypto::hash &prunable_hash) const
 fetches the prunable transaction hash More...
 
virtual uint64_t get_tx_count () const
 fetches the total number of transactions ever More...
 
virtual std::vector< transactionget_tx_list (const std::vector< crypto::hash > &hlist) const
 fetches a list of transactions based on their hashes More...
 
virtual uint64_t get_tx_block_height (const crypto::hash &h) const
 fetches the height of a transaction's block More...
 
virtual uint64_t get_num_outputs (const uint64_t &amount) const
 fetches the number of outputs of a given amount More...
 
virtual output_data_t get_output_key (const uint64_t &amount, const uint64_t &index, bool include_commitmemt) const
 get some of an output's data More...
 
virtual void get_output_key (const epee::span< const uint64_t > &amounts, const std::vector< uint64_t > &offsets, std::vector< output_data_t > &outputs, bool allow_partial=false) const
 gets outputs' data More...
 
virtual tx_out_index get_output_tx_and_index_from_global (const uint64_t &index) const
 gets an output's tx hash and index More...
 
virtual void get_output_tx_and_index_from_global (const std::vector< uint64_t > &global_indices, std::vector< tx_out_index > &tx_out_indices) const
 
virtual tx_out_index get_output_tx_and_index (const uint64_t &amount, const uint64_t &index) const
 gets an output's tx hash and index More...
 
virtual void get_output_tx_and_index (const uint64_t &amount, const std::vector< uint64_t > &offsets, std::vector< tx_out_index > &indices) const
 gets some outputs' tx hashes and indices More...
 
virtual std::vector< std::vector< uint64_t > > get_tx_amount_output_indices (const uint64_t tx_id, size_t n_txes) const
 gets output indices (amount-specific) for a transaction's outputs More...
 
virtual bool has_key_image (const crypto::key_image &img) const
 check if a key image is stored as spent More...
 
virtual void add_txpool_tx (const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta)
 add a txpool transaction More...
 
virtual void update_txpool_tx (const crypto::hash &txid, const txpool_tx_meta_t &meta)
 update a txpool transaction's metadata More...
 
virtual uint64_t get_txpool_tx_count (bool include_unrelayed_txes=true) const
 get the number of transactions in the txpool More...
 
virtual bool txpool_has_tx (const crypto::hash &txid) const
 check whether a txid is in the txpool More...
 
virtual void remove_txpool_tx (const crypto::hash &txid)
 remove a txpool transaction More...
 
virtual bool get_txpool_tx_meta (const crypto::hash &txid, txpool_tx_meta_t &meta) const
 get a txpool transaction's metadata More...
 
virtual bool get_txpool_tx_blob (const crypto::hash &txid, cryptonote::blobdata &bd) const
 get a txpool transaction's blob More...
 
virtual cryptonote::blobdata get_txpool_tx_blob (const crypto::hash &txid) const
 get a txpool transaction's blob More...
 
virtual uint32_t get_blockchain_pruning_seed () const
 get the blockchain pruning seed More...
 
virtual bool prune_blockchain (uint32_t pruning_seed=0)
 prunes the blockchain More...
 
virtual bool update_pruning ()
 prunes recent blockchain changes as needed, iff pruning is enabled More...
 
virtual bool check_pruning ()
 checks pruning was done correctly, iff enabled More...
 
virtual bool for_all_txpool_txes (std::function< bool(const crypto::hash &, const txpool_tx_meta_t &, const cryptonote::blobdata *)> f, bool include_blob=false, bool include_unrelayed_txes=true) const
 runs a function over all txpool transactions More...
 
virtual bool for_all_key_images (std::function< bool(const crypto::key_image &)>) const
 runs a function over all key images stored More...
 
virtual bool for_blocks_range (const uint64_t &h1, const uint64_t &h2, std::function< bool(uint64_t, const crypto::hash &, const cryptonote::block &)>) const
 runs a function over a range of blocks More...
 
virtual bool for_all_transactions (std::function< bool(const crypto::hash &, const cryptonote::transaction &)>, bool pruned) const
 runs a function over all transactions stored More...
 
virtual bool for_all_outputs (std::function< bool(uint64_t amount, const crypto::hash &tx_hash, uint64_t height, size_t tx_idx)> f) const
 runs a function over all outputs stored More...
 
virtual bool for_all_outputs (uint64_t amount, const std::function< bool(uint64_t height)> &f) const
 
virtual uint64_t add_block (const std::pair< block, blobdata > &blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type &cumulative_difficulty, const uint64_t &coins_generated, const std::vector< std::pair< transaction, blobdata >> &txs)
 handles the addition of a new block to BlockchainDB More...
 
virtual void set_batch_transactions (bool batch_transactions)
 sets whether or not to batch transactions More...
 
virtual bool batch_start (uint64_t batch_num_blocks=0, uint64_t batch_bytes=0)
 tells the BlockchainDB to start a new "batch" of blocks More...
 
virtual void batch_commit ()
 
virtual void batch_stop ()
 ends a batch transaction More...
 
virtual void batch_abort ()
 aborts a batch transaction More...
 
virtual void block_wtxn_start ()
 
virtual void block_wtxn_stop ()
 
virtual void block_wtxn_abort ()
 
virtual bool block_rtxn_start () const
 
virtual void block_rtxn_stop () const
 
virtual void block_rtxn_abort () const
 
bool block_rtxn_start (MDB_txn **mtxn, mdb_txn_cursors **mcur) const
 
virtual void pop_block (block &blk, std::vector< transaction > &txs)
 pops the top block off the blockchain More...
 
virtual bool can_thread_bulk_indices () const
 
std::map< uint64_t, std::tuple< uint64_t, uint64_t, uint64_t > > get_output_histogram (const std::vector< uint64_t > &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const
 return a histogram of outputs on the blockchain More...
 
bool get_output_distribution (uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector< uint64_t > &distribution, uint64_t &base) const
 
virtual std::vector< address_outputsget_addr_output_all (const crypto::public_key &combined_key)
 
virtual std::vector< address_outputsget_addr_output_batch (const crypto::public_key &combined_key, uint64_t start_db_index=0, uint64_t batch_size=100, bool desc=false)
 
virtual std::vector< address_txsget_addr_tx_all (const crypto::public_key &combined_key)
 
virtual std::vector< address_txsget_addr_tx_batch (const crypto::public_key &combined_key, uint64_t start_db_index=0, uint64_t batch_size=100, bool desc=false)
 
virtual uint64_t get_balance (const crypto::public_key &combined_key)
 
virtual tx_input_t get_tx_input (const crypto::hash tx_hash, const uint32_t relative_out_index)
 
- Public Member Functions inherited from cryptonote::BlockchainDB
 BlockchainDB ()
 An empty constructor. More...
 
virtual ~BlockchainDB ()
 An empty destructor. More...
 
void reset_stats ()
 reset profiling stats More...
 
void show_stats ()
 show profiling stats More...
 
bool is_open () const
 Gets the current open/ready state of the BlockchainDB. More...
 
virtual void set_hard_fork (HardFork *hf)
 
virtual block get_block (const crypto::hash &h) const
 fetches the block with the given hash More...
 
virtual block get_block_from_height (const uint64_t &height) const
 fetch a block by height More...
 
virtual transaction get_tx (const crypto::hash &h) const
 fetches the transaction with the given hash More...
 
virtual transaction get_pruned_tx (const crypto::hash &h) const
 fetches the transaction base with the given hash More...
 
virtual bool get_tx (const crypto::hash &h, transaction &tx) const
 fetches the transaction with the given hash More...
 
virtual bool get_pruned_tx (const crypto::hash &h, transaction &tx) const
 fetches the transaction base with the given hash More...
 
virtual uint64_t get_indexing_base () const
 return index of the first element (should be hidden, but isn't) More...
 
void set_auto_remove_logs (bool auto_remove)
 set whether or not to automatically remove logs More...
 

Static Public Member Functions

static int compare_uint64 (const MDB_val *a, const MDB_val *b)
 
static int compare_hash32 (const MDB_val *a, const MDB_val *b)
 
static int compare_string (const MDB_val *a, const MDB_val *b)
 
static int compare_data (const MDB_val *a, const MDB_val *b)
 
static int compare_publickey (const MDB_val *a, const MDB_val *b)
 
- Static Public Member Functions inherited from cryptonote::BlockchainDB
static void init_options (boost::program_options::options_description &desc)
 init command line options More...
 

Additional Inherited Members

- Public Attributes inherited from cryptonote::BlockchainDB
bool m_open
 Whether or not the BlockchainDB is open/ready for use. More...
 
epee::critical_section m_synchronization_lock
 A lock, currently for when BlockchainLMDB needs to resize the backing db file. More...
 
- Protected Member Functions inherited from cryptonote::BlockchainDB
void add_transaction (const crypto::hash &blk_hash, const std::pair< transaction, blobdata > &tx, const crypto::hash *tx_hash_ptr=NULL, const crypto::hash *tx_prunable_hash_ptr=NULL)
 helper function for add_transactions, to add each individual transaction More...
 
- Protected Attributes inherited from cryptonote::BlockchainDB
uint64_t time_tx_exists = 0
 a performance metric More...
 
uint64_t time_commit1 = 0
 a performance metric More...
 
bool m_auto_remove_logs = true
 whether or not to automatically remove old logs More...
 
HardForkm_hardfork
 

Detailed Description

Definition at line 194 of file db_lmdb.h.

Constructor & Destructor Documentation

◆ BlockchainLMDB()

cryptonote::BlockchainLMDB::BlockchainLMDB ( bool  batch_transactions = true)

Definition at line 1338 of file db_lmdb.cpp.

1338  : BlockchainDB()
1339 {
1340  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1341  // initialize folder to something "safe" just in case
1342  // someone accidentally misuses this class...
1343  m_folder = "thishsouldnotexistbecauseitisgibberish";
1344 
1345  m_batch_transactions = batch_transactions;
1346  m_write_txn = nullptr;
1347  m_write_batch_txn = nullptr;
1348  m_batch_active = false;
1349  m_cum_size = 0;
1350  m_cum_count = 0;
1351 
1352  // reset may also need changing when initialize things here
1353 
1354  m_hardfork = nullptr;
1355 }
BlockchainDB()
An empty constructor.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102

◆ ~BlockchainLMDB()

cryptonote::BlockchainLMDB::~BlockchainLMDB ( )

Definition at line 1324 of file db_lmdb.cpp.

1325 {
1326  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1327 
1328  // batch transaction shouldn't be active at this point. If it is, consider it aborted.
1329  if (m_batch_active)
1330  {
1331  try { batch_abort(); }
1332  catch (...) { /* ignore */ }
1333  }
1334  if (m_open)
1335  close();
1336 }
virtual void close()
close the BlockchainDB
Definition: db_lmdb.cpp:1624
bool m_open
Whether or not the BlockchainDB is open/ready for use.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual void batch_abort()
aborts a batch transaction
Definition: db_lmdb.cpp:4320

Member Function Documentation

◆ add_block()

uint64_t cryptonote::BlockchainLMDB::add_block ( const std::pair< block, blobdata > &  blk,
size_t  block_weight,
uint64_t  long_term_block_weight,
const difficulty_type cumulative_difficulty,
const uint64_t coins_generated,
const std::vector< std::pair< transaction, blobdata >> &  txs 
)
virtual

handles the addition of a new block to BlockchainDB

This function organizes block addition and calls various functions as necessary.

NOTE: subclass implementations of this (or the functions it calls) need to handle undoing any partially-added blocks in the event of a failure.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Parameters
blkthe block to be added
block_weightthe size of the block (transactions and all)
long_term_block_weightthe long term weight of the block (transactions and all)
cumulative_difficultythe accumulated difficulty after this block
coins_generatedthe number of coins generated total after this block
txsthe transactions in the block
Returns
the height of the chain post-addition

Reimplemented from cryptonote::BlockchainDB.

Definition at line 4484 of file db_lmdb.cpp.

4486 {
4487  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4488  check_open();
4489  uint64_t m_height = height();
4490 
4491  if (m_height % 1024 == 0)
4492  {
4493  // for batch mode, DB resize check is done at start of batch transaction
4494  if (! m_batch_active && need_resize())
4495  {
4496  LOG_PRINT_L0("LMDB memory map needs to be resized, doing that now.");
4497  do_resize();
4498  }
4499  }
4500 
4501  try
4502  {
4503  BlockchainDB::add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, txs);
4504  }
4505  catch (const DB_ERROR_TXN_START& e)
4506  {
4507  throw;
4508  }
4509 
4510  return ++m_height;
4511 }
#define LOG_PRINT_L0(x)
Definition: misc_log_ex.h:99
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ add_txpool_tx()

void cryptonote::BlockchainLMDB::add_txpool_tx ( const crypto::hash txid,
const cryptonote::blobdata blob,
const txpool_tx_meta_t details 
)
virtual

add a txpool transaction

Parameters
detailsthe details of the transaction to add

Implements cryptonote::BlockchainDB.

Definition at line 2415 of file db_lmdb.cpp.

2416 {
2417  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2418  check_open();
2419  mdb_txn_cursors *m_cursors = &m_wcursors;
2420 
2421  CURSOR(txpool_meta)
2422  CURSOR(txpool_blob)
2423 
2424  MDB_val k = {sizeof(txid), (void *)&txid};
2425  MDB_val v = {sizeof(meta), (void *)&meta};
2426  if (auto result = mdb_cursor_put(m_cur_txpool_meta, &k, &v, MDB_NODUPDATA)) {
2427  if (result == MDB_KEYEXIST)
2428  throw1(DB_ERROR("Attempting to add txpool tx metadata that's already in the db"));
2429  else
2430  throw1(DB_ERROR(lmdb_error("Error adding txpool tx metadata to db transaction: ", result).c_str()));
2431  }
2432  MDB_val_sized(blob_val, blob);
2433  if (auto result = mdb_cursor_put(m_cur_txpool_blob, &k, &blob_val, MDB_NODUPDATA)) {
2434  if (result == MDB_KEYEXIST)
2435  throw1(DB_ERROR("Attempting to add txpool tx blob that's already in the db"));
2436  else
2437  throw1(DB_ERROR(lmdb_error("Error adding txpool tx blob to db transaction: ", result).c_str()));
2438  }
2439 }
#define MDB_NODUPDATA
Definition: lmdb.h:369
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Store by cursor.
#define m_cur_txpool_blob
Definition: db_lmdb.h:95
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define MDB_val_sized(var, val)
Definition: db_lmdb.cpp:91
#define MDB_KEYEXIST
Definition: lmdb.h:437
struct cryptonote::mdb_txn_cursors mdb_txn_cursors
#define CURSOR(name)
Definition: db_lmdb.cpp:285
Here is the call graph for this function:

◆ batch_abort()

void cryptonote::BlockchainLMDB::batch_abort ( )
virtual

aborts a batch transaction

If the subclass implements batching, this function should abort the batch it is currently on.

If no batch is in-progress, this function should throw a DB_ERROR. This exception may change in the future if it is deemed necessary to have a more granular exception type for this scenario.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Implements cryptonote::BlockchainDB.

Definition at line 4320 of file db_lmdb.cpp.

4321 {
4322  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4323  if (! m_batch_transactions)
4324  throw0(DB_ERROR("batch transactions not enabled"));
4325  if (! m_batch_active)
4326  throw1(DB_ERROR("batch transaction not in progress"));
4327  if (m_write_batch_txn == nullptr)
4328  throw1(DB_ERROR("batch transaction not in progress"));
4329  if (m_writer != boost::this_thread::get_id())
4330  throw1(DB_ERROR("batch transaction owned by other thread"));
4331  check_open();
4332  // for destruction of batch transaction
4333  m_write_txn = nullptr;
4334  // explicitly call in case mdb_env_close() (BlockchainLMDB::close()) called before BlockchainLMDB destructor called.
4335  m_write_batch_txn->abort();
4336  delete m_write_batch_txn;
4337  m_write_batch_txn = nullptr;
4338  m_batch_active = false;
4339  memset(&m_wcursors, 0, sizeof(m_wcursors));
4340  LOG_PRINT_L3("batch transaction: aborted");
4341 }
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:
Here is the caller graph for this function:

◆ batch_commit()

void cryptonote::BlockchainLMDB::batch_commit ( )
virtual

Definition at line 4254 of file db_lmdb.cpp.

4255 {
4256  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4257  if (! m_batch_transactions)
4258  throw0(DB_ERROR("batch transactions not enabled"));
4259  if (! m_batch_active)
4260  throw1(DB_ERROR("batch transaction not in progress"));
4261  if (m_write_batch_txn == nullptr)
4262  throw1(DB_ERROR("batch transaction not in progress"));
4263  if (m_writer != boost::this_thread::get_id())
4264  throw1(DB_ERROR("batch transaction owned by other thread"));
4265 
4266  check_open();
4267 
4268  LOG_PRINT_L3("batch transaction: committing...");
4269  TIME_MEASURE_START(time1);
4270  m_write_txn->commit();
4271  TIME_MEASURE_FINISH(time1);
4272  time_commit1 += time1;
4273  LOG_PRINT_L3("batch transaction: committed");
4274 
4275  m_write_txn = nullptr;
4276  delete m_write_batch_txn;
4277  m_write_batch_txn = nullptr;
4278  memset(&m_wcursors, 0, sizeof(m_wcursors));
4279 }
void commit(std::string message="")
Definition: db_lmdb.cpp:453
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
uint64_t time_commit1
a performance metric
Here is the call graph for this function:

◆ batch_start()

bool cryptonote::BlockchainLMDB::batch_start ( uint64_t  batch_num_blocks = 0,
uint64_t  batch_bytes = 0 
)
virtual

tells the BlockchainDB to start a new "batch" of blocks

If the subclass implements a batching method of caching blocks in RAM to be added to a backing store in groups, it should start a batch which will end either when <batch_num_blocks> has been added or batch_stop() has been called. In either case, it should end the batch and write to its backing store.

If a batch is already in-progress, this function must return false. If a batch was started by this call, it must return true.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Parameters
batch_num_blocksnumber of blocks to batch together
Returns
true if we started the batch, false if already started

Implements cryptonote::BlockchainDB.

Definition at line 4211 of file db_lmdb.cpp.

4212 {
4213  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4214  if (! m_batch_transactions)
4215  throw0(DB_ERROR("batch transactions not enabled"));
4216  if (m_batch_active)
4217  return false;
4218  if (m_write_batch_txn != nullptr)
4219  return false;
4220  if (m_write_txn)
4221  throw0(DB_ERROR("batch transaction attempted, but m_write_txn already in use"));
4222  check_open();
4223 
4224  m_writer = boost::this_thread::get_id();
4225  check_and_resize_for_batch(batch_num_blocks, batch_bytes);
4226 
4227  m_write_batch_txn = new mdb_txn_safe();
4228 
4229  // NOTE: need to make sure it's destroyed properly when done
4230  if (auto mdb_res = lmdb_txn_begin(m_env, NULL, 0, *m_write_batch_txn))
4231  {
4232  delete m_write_batch_txn;
4233  m_write_batch_txn = nullptr;
4234  throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
4235  }
4236  // indicates this transaction is for batch transactions, but not whether it's
4237  // active
4238  m_write_batch_txn->m_batch_txn = true;
4239  m_write_txn = m_write_batch_txn;
4240 
4241  m_batch_active = true;
4242  memset(&m_wcursors, 0, sizeof(m_wcursors));
4243  if (m_tinfo.get())
4244  {
4245  if (m_tinfo->m_ti_rflags.m_rf_txn)
4246  mdb_txn_reset(m_tinfo->m_ti_rtxn);
4247  memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags));
4248  }
4249 
4250  LOG_PRINT_L3("batch transaction: begin");
4251  return true;
4252 }
int lmdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: db_lmdb.cpp:527
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:

◆ batch_stop()

void cryptonote::BlockchainLMDB::batch_stop ( )
virtual

ends a batch transaction

If the subclass implements batching, this function should store the batch it is currently on and mark it finished.

If no batch is in-progress, this function should throw a DB_ERROR. This exception may change in the future if it is deemed necessary to have a more granular exception type for this scenario.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Implements cryptonote::BlockchainDB.

Definition at line 4291 of file db_lmdb.cpp.

4292 {
4293  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4294  if (! m_batch_transactions)
4295  throw0(DB_ERROR("batch transactions not enabled"));
4296  if (! m_batch_active)
4297  throw1(DB_ERROR("batch transaction not in progress"));
4298  if (m_write_batch_txn == nullptr)
4299  throw1(DB_ERROR("batch transaction not in progress"));
4300  if (m_writer != boost::this_thread::get_id())
4301  throw1(DB_ERROR("batch transaction owned by other thread"));
4302  check_open();
4303  LOG_PRINT_L3("batch transaction: committing...");
4304  TIME_MEASURE_START(time1);
4305  try
4306  {
4307  m_write_txn->commit();
4308  TIME_MEASURE_FINISH(time1);
4309  time_commit1 += time1;
4310  cleanup_batch();
4311  }
4312  catch (const std::exception &e)
4313  {
4314  cleanup_batch();
4315  throw;
4316  }
4317  LOG_PRINT_L3("batch transaction: end");
4318 }
void commit(std::string message="")
Definition: db_lmdb.cpp:453
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
uint64_t time_commit1
a performance metric
Here is the call graph for this function:

◆ block_exists()

bool cryptonote::BlockchainLMDB::block_exists ( const crypto::hash h,
uint64_t height = NULL 
) const
virtual

checks if a block exists

Parameters
hthe hash of the requested block
heightif non NULL, returns the block's height if found
Returns
true of the block exists, otherwise false

Implements cryptonote::BlockchainDB.

Definition at line 2993 of file db_lmdb.cpp.

2994 {
2995  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2996  check_open();
2997 
2999  RCURSOR(block_heights);
3000 
3001  bool ret = false;
3002  MDB_val_set(key, h);
3003  auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
3004  if (get_result == MDB_NOTFOUND)
3005  {
3006  LOG_PRINT_L3("Block with hash " << epee::string_tools::pod_to_hex(h) << " not found in db");
3007  }
3008  else if (get_result)
3009  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch block index from hash", get_result).c_str()));
3010  else
3011  {
3012  if (height)
3013  {
3014  const blk_height *bhp = (const blk_height *)key.mv_data;
3015  *height = bhp->bh_height;
3016  }
3017  ret = true;
3018  }
3019 
3021  return ret;
3022 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_block_heights
Definition: db_lmdb.h:82
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
const char * key
Definition: hmac_keccak.cpp:39
struct cryptonote::blk_height blk_height
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ block_rtxn_abort()

void cryptonote::BlockchainLMDB::block_rtxn_abort ( ) const
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4477 of file db_lmdb.cpp.

4478 {
4479  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4480  mdb_txn_reset(m_tinfo->m_ti_rtxn);
4481  memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags));
4482 }
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:

◆ block_rtxn_start() [1/2]

bool cryptonote::BlockchainLMDB::block_rtxn_start ( ) const
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4399 of file db_lmdb.cpp.

4400 {
4401  MDB_txn *mtxn;
4402  mdb_txn_cursors *mcur;
4403  return block_rtxn_start(&mtxn, &mcur);
4404 }
virtual bool block_rtxn_start() const
Definition: db_lmdb.cpp:4399
struct MDB_txn MDB_txn
Opaque structure for a transaction handle.
Definition: lmdb.h:267
struct cryptonote::mdb_txn_cursors mdb_txn_cursors

◆ block_rtxn_start() [2/2]

bool cryptonote::BlockchainLMDB::block_rtxn_start ( MDB_txn **  mtxn,
mdb_txn_cursors **  mcur 
) const

Definition at line 4355 of file db_lmdb.cpp.

4356 {
4357  bool ret = false;
4358  mdb_threadinfo *tinfo;
4359  if (m_write_txn && m_writer == boost::this_thread::get_id()) {
4360  *mtxn = m_write_txn->m_txn;
4361  *mcur = (mdb_txn_cursors *)&m_wcursors;
4362  return ret;
4363  }
4364  /* Check for existing info and force reset if env doesn't match -
4365  * only happens if env was opened/closed multiple times in same process
4366  */
4367  if (!(tinfo = m_tinfo.get()) || mdb_txn_env(tinfo->m_ti_rtxn) != m_env)
4368  {
4369  tinfo = new mdb_threadinfo;
4370  m_tinfo.reset(tinfo);
4371  memset(&tinfo->m_ti_rcursors, 0, sizeof(tinfo->m_ti_rcursors));
4372  memset(&tinfo->m_ti_rflags, 0, sizeof(tinfo->m_ti_rflags));
4373  if (auto mdb_res = lmdb_txn_begin(m_env, NULL, MDB_RDONLY, &tinfo->m_ti_rtxn))
4374  throw0(DB_ERROR_TXN_START(lmdb_error("Failed to create a read transaction for the db: ", mdb_res).c_str()));
4375  ret = true;
4376  } else if (!tinfo->m_ti_rflags.m_rf_txn)
4377  {
4378  if (auto mdb_res = lmdb_txn_renew(tinfo->m_ti_rtxn))
4379  throw0(DB_ERROR_TXN_START(lmdb_error("Failed to renew a read transaction for the db: ", mdb_res).c_str()));
4380  ret = true;
4381  }
4382  if (ret)
4383  tinfo->m_ti_rflags.m_rf_txn = true;
4384  *mtxn = tinfo->m_ti_rtxn;
4385  *mcur = &tinfo->m_ti_rcursors;
4386 
4387  if (ret)
4388  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4389  return ret;
4390 }
int lmdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: db_lmdb.cpp:527
#define MDB_RDONLY
Definition: lmdb.h:320
MDB_env * mdb_txn_env(MDB_txn *txn)
Returns the transaction&#39;s MDB_env.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int lmdb_txn_renew(MDB_txn *txn)
Definition: db_lmdb.cpp:537
struct cryptonote::mdb_txn_cursors mdb_txn_cursors
struct cryptonote::mdb_threadinfo mdb_threadinfo
Here is the call graph for this function:

◆ block_rtxn_stop()

void cryptonote::BlockchainLMDB::block_rtxn_stop ( ) const
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4392 of file db_lmdb.cpp.

4393 {
4394  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4395  mdb_txn_reset(m_tinfo->m_ti_rtxn);
4396  memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags));
4397 }
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:

◆ block_wtxn_abort()

void cryptonote::BlockchainLMDB::block_wtxn_abort ( )
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4461 of file db_lmdb.cpp.

4462 {
4463  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4464  if (!m_write_txn)
4465  throw0(DB_ERROR_TXN_START((std::string("Attempted to abort write txn when no such txn exists in ")+__FUNCTION__).c_str()));
4466  if (m_writer != boost::this_thread::get_id())
4467  throw0(DB_ERROR_TXN_START((std::string("Attempted to abort write txn from the wrong thread in ")+__FUNCTION__).c_str()));
4468 
4469  if (! m_batch_active)
4470  {
4471  delete m_write_txn;
4472  m_write_txn = nullptr;
4473  memset(&m_wcursors, 0, sizeof(m_wcursors));
4474  }
4475 }
::std::string string
Definition: gtest-port.h:1097
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the caller graph for this function:

◆ block_wtxn_start()

void cryptonote::BlockchainLMDB::block_wtxn_start ( )
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4406 of file db_lmdb.cpp.

4407 {
4408  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4409  // Distinguish the exceptions here from exceptions that would be thrown while
4410  // using the txn and committing it.
4411  //
4412  // If an exception is thrown in this setup, we don't want the caller to catch
4413  // it and proceed as if there were an existing write txn, such as trying to
4414  // call block_txn_abort(). It also indicates a serious issue which will
4415  // probably be thrown up another layer.
4416  if (! m_batch_active && m_write_txn)
4417  throw0(DB_ERROR_TXN_START((std::string("Attempted to start new write txn when write txn already exists in ")+__FUNCTION__).c_str()));
4418  if (! m_batch_active)
4419  {
4420  m_writer = boost::this_thread::get_id();
4421  m_write_txn = new mdb_txn_safe();
4422  if (auto mdb_res = lmdb_txn_begin(m_env, NULL, 0, *m_write_txn))
4423  {
4424  delete m_write_txn;
4425  m_write_txn = nullptr;
4426  throw0(DB_ERROR_TXN_START(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
4427  }
4428  memset(&m_wcursors, 0, sizeof(m_wcursors));
4429  if (m_tinfo.get())
4430  {
4431  if (m_tinfo->m_ti_rflags.m_rf_txn)
4432  mdb_txn_reset(m_tinfo->m_ti_rtxn);
4433  memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags));
4434  }
4435  } else if (m_writer != boost::this_thread::get_id())
4436  throw0(DB_ERROR_TXN_START((std::string("Attempted to start new write txn when batch txn already exists in ")+__FUNCTION__).c_str()));
4437 }
int lmdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: db_lmdb.cpp:527
::std::string string
Definition: gtest-port.h:1097
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:
Here is the caller graph for this function:

◆ block_wtxn_stop()

void cryptonote::BlockchainLMDB::block_wtxn_stop ( )
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4439 of file db_lmdb.cpp.

4440 {
4441  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4442  if (!m_write_txn)
4443  throw0(DB_ERROR_TXN_START((std::string("Attempted to stop write txn when no such txn exists in ")+__FUNCTION__).c_str()));
4444  if (m_writer != boost::this_thread::get_id())
4445  throw0(DB_ERROR_TXN_START((std::string("Attempted to stop write txn from the wrong thread in ")+__FUNCTION__).c_str()));
4446  {
4447  if (! m_batch_active)
4448  {
4449  TIME_MEASURE_START(time1);
4450  m_write_txn->commit();
4451  TIME_MEASURE_FINISH(time1);
4452  time_commit1 += time1;
4453 
4454  delete m_write_txn;
4455  m_write_txn = nullptr;
4456  memset(&m_wcursors, 0, sizeof(m_wcursors));
4457  }
4458  }
4459 }
::std::string string
Definition: gtest-port.h:1097
void commit(std::string message="")
Definition: db_lmdb.cpp:453
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
uint64_t time_commit1
a performance metric
Here is the call graph for this function:
Here is the caller graph for this function:

◆ can_thread_bulk_indices()

virtual bool cryptonote::BlockchainLMDB::can_thread_bulk_indices ( ) const
inlinevirtual

Implements cryptonote::BlockchainDB.

Definition at line 342 of file db_lmdb.h.

342 { return true; }

◆ check_pruning()

bool cryptonote::BlockchainLMDB::check_pruning ( )
virtual

checks pruning was done correctly, iff enabled

Returns
success iff true

Implements cryptonote::BlockchainDB.

Definition at line 2936 of file db_lmdb.cpp.

2937 {
2938  return prune_worker(prune_mode_check, 0);
2939 }

◆ close()

void cryptonote::BlockchainLMDB::close ( )
virtual

close the BlockchainDB

At minimum, this call ensures that further use of the BlockchainDB instance will not have effect. In any case where it is necessary to do so, a subclass implementing this will sync with disk.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Implements cryptonote::BlockchainDB.

Definition at line 1624 of file db_lmdb.cpp.

1625 {
1626  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1627  if (m_batch_active)
1628  {
1629  LOG_PRINT_L3("close() first calling batch_abort() due to active batch transaction");
1630  batch_abort();
1631  }
1632  this->sync();
1633  m_tinfo.reset();
1634 
1635  // FIXME: not yet thread safe!!! Use with care.
1636  mdb_env_close(m_env);
1637  m_open = false;
1638 }
bool m_open
Whether or not the BlockchainDB is open/ready for use.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual void batch_abort()
aborts a batch transaction
Definition: db_lmdb.cpp:4320
virtual void sync()
sync the BlockchainDB with disk
Definition: db_lmdb.cpp:1640
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
Here is the call graph for this function:

◆ compare_data()

int cryptonote::BlockchainLMDB::compare_data ( const MDB_val a,
const MDB_val b 
)
static

Definition at line 172 of file db_lmdb.cpp.

173 {
174  size_t size = std::max(a->mv_size, b->mv_size);
175 
176  uint8_t *va = (uint8_t*) a->mv_data;
177  uint8_t *vb = (uint8_t*) b->mv_data;
178  for (size_t n = 0; n < size; ++n)
179  {
180  if (va[n] == vb[n])
181  continue;
182  return va[n] < vb[n] ? -1 : 1;
183  }
184 
185  return 0;
186 }
unsigned char uint8_t
Definition: stdint.h:124
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124

◆ compare_hash32()

int cryptonote::BlockchainLMDB::compare_hash32 ( const MDB_val a,
const MDB_val b 
)
static

Definition at line 151 of file db_lmdb.cpp.

152 {
153  uint32_t *va = (uint32_t*) a->mv_data;
154  uint32_t *vb = (uint32_t*) b->mv_data;
155  for (int n = 7; n >= 0; n--)
156  {
157  if (va[n] == vb[n])
158  continue;
159  return va[n] < vb[n] ? -1 : 1;
160  }
161 
162  return 0;
163 }
void * mv_data
Definition: lmdb.h:288
unsigned int uint32_t
Definition: stdint.h:126
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124

◆ compare_publickey()

int cryptonote::BlockchainLMDB::compare_publickey ( const MDB_val a,
const MDB_val b 
)
static

Definition at line 188 of file db_lmdb.cpp.

189 {
190  uint8_t *va = (uint8_t*) a->mv_data;
191  uint8_t *vb = (uint8_t*) b->mv_data;
192  for (int n = 0; n < 32; ++n)
193  {
194  if (va[n] == vb[n])
195  continue;
196  return va[n] < vb[n] ? -1 : 1;
197  }
198 
199  return 0;
200 }
unsigned char uint8_t
Definition: stdint.h:124
void * mv_data
Definition: lmdb.h:288
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124

◆ compare_string()

int cryptonote::BlockchainLMDB::compare_string ( const MDB_val a,
const MDB_val b 
)
static

Definition at line 165 of file db_lmdb.cpp.

166 {
167  const char *va = (const char*) a->mv_data;
168  const char *vb = (const char*) b->mv_data;
169  return strcmp(va, vb);
170 }
void * mv_data
Definition: lmdb.h:288
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124

◆ compare_uint64()

int cryptonote::BlockchainLMDB::compare_uint64 ( const MDB_val a,
const MDB_val b 
)
static

Definition at line 143 of file db_lmdb.cpp.

144 {
145  uint64_t va, vb;
146  memcpy(&va, a->mv_data, sizeof(va));
147  memcpy(&vb, b->mv_data, sizeof(vb));
148  return (va < vb) ? -1 : va > vb;
149 }
void * mv_data
Definition: lmdb.h:288
unsigned __int64 uint64_t
Definition: stdint.h:136
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
void * memcpy(void *a, const void *b, size_t c)
Here is the call graph for this function:

◆ for_all_key_images()

bool cryptonote::BlockchainLMDB::for_all_key_images ( std::function< bool(const crypto::key_image &)>  ) const
virtual

runs a function over all key images stored

The subclass should run the passed function for each key image it has stored, passing the key image as its parameter.

If any call to the function returns false, the subclass should return false. Otherwise, the subclass returns true.

Parameters
std::functionfn the function to run
Returns
false if the function returns false for any key image, otherwise true

Implements cryptonote::BlockchainDB.

Definition at line 3989 of file db_lmdb.cpp.

3990 {
3991  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3992  check_open();
3993 
3995  RCURSOR(spent_keys);
3996 
3997  MDB_val k, v;
3998  bool fret = true;
3999 
4000  k = zerokval;
4001  MDB_cursor_op op = MDB_FIRST;
4002  while (1)
4003  {
4004  int ret = mdb_cursor_get(m_cur_spent_keys, &k, &v, op);
4005  op = MDB_NEXT;
4006  if (ret == MDB_NOTFOUND)
4007  break;
4008  if (ret < 0)
4009  throw0(DB_ERROR("Failed to enumerate key images"));
4010  const crypto::key_image k_image = *(const crypto::key_image*)v.mv_data;
4011  if (!f(k_image)) {
4012  fret = false;
4013  break;
4014  }
4015  }
4016 
4018 
4019  return fret;
4020 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
Definition: lmdb.h:411
#define m_cur_spent_keys
Definition: db_lmdb.h:93
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
POD_CLASS key_image
Definition: crypto.h:102
else if(0==res)

◆ for_all_outputs() [1/2]

bool cryptonote::BlockchainLMDB::for_all_outputs ( std::function< bool(uint64_t amount, const crypto::hash &tx_hash, uint64_t height, size_t tx_idx)>  f) const
virtual

runs a function over all outputs stored

The subclass should run the passed function for each output it has stored, passing (amount, transaction_hash, tx_local_output_index) as its parameters.

If any call to the function returns false, the subclass should return false. Otherwise, the subclass returns true.

The subclass should throw DB_ERROR if any of the expected values are not found. Current implementations simply return false.

Parameters
std::functionf the function to run
Returns
false if the function returns false for any output, otherwise true

Implements cryptonote::BlockchainDB.

Definition at line 4135 of file db_lmdb.cpp.

4136 {
4137  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4138  check_open();
4139 
4141  RCURSOR(output_amounts);
4142 
4143  MDB_val k;
4144  MDB_val v;
4145  bool fret = true;
4146 
4147  MDB_cursor_op op = MDB_FIRST;
4148  while (1)
4149  {
4150  int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op);
4151  op = MDB_NEXT;
4152  if (ret == MDB_NOTFOUND)
4153  break;
4154  if (ret)
4155  throw0(DB_ERROR("Failed to enumerate outputs"));
4156  uint64_t amount = *(const uint64_t*)k.mv_data;
4157  outkey *ok = (outkey *)v.mv_data;
4159  if (!f(amount, toi.first, ok->data.height, toi.second)) {
4160  fret = false;
4161  break;
4162  }
4163  }
4164 
4166 
4167  return fret;
4168 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
Definition: lmdb.h:411
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
virtual tx_out_index get_output_tx_and_index_from_global(const uint64_t &index) const
gets an output&#39;s tx hash and index
Definition: db_lmdb.cpp:3893
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
struct cryptonote::outkey outkey
std::pair< crypto::hash, uint64_t > tx_out_index
Here is the call graph for this function:

◆ for_all_outputs() [2/2]

bool cryptonote::BlockchainLMDB::for_all_outputs ( uint64_t  amount,
const std::function< bool(uint64_t height)> &  f 
) const
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4170 of file db_lmdb.cpp.

4171 {
4172  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4173  check_open();
4174 
4176  RCURSOR(output_amounts);
4177 
4178  MDB_val_set(k, amount);
4179  MDB_val v;
4180  bool fret = true;
4181 
4182  MDB_cursor_op op = MDB_SET;
4183  while (1)
4184  {
4185  int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op);
4186  op = MDB_NEXT_DUP;
4187  if (ret == MDB_NOTFOUND)
4188  break;
4189  if (ret)
4190  throw0(DB_ERROR("Failed to enumerate outputs"));
4191  uint64_t out_amount = *(const uint64_t*)k.mv_data;
4192  if (amount != out_amount)
4193  {
4194  MERROR("Amount is not the expected amount");
4195  fret = false;
4196  break;
4197  }
4198  const outkey *ok = (const outkey *)v.mv_data;
4199  if (!f(ok->data.height)) {
4200  fret = false;
4201  break;
4202  }
4203  }
4204 
4206 
4207  return fret;
4208 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define MERROR(x)
Definition: misc_log_ex.h:73
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
struct cryptonote::outkey outkey
else if(0==res)
Here is the call graph for this function:

◆ for_all_transactions()

bool cryptonote::BlockchainLMDB::for_all_transactions ( std::function< bool(const crypto::hash &, const cryptonote::transaction &)>  ,
bool  pruned 
) const
virtual

runs a function over all transactions stored

The subclass should run the passed function for each transaction it has stored, passing (transaction_hash, transaction) as its parameters.

If any call to the function returns false, the subclass should return false. Otherwise, the subclass returns true.

The subclass should throw DB_ERROR if any of the expected values are not found. Current implementations simply return false.

Parameters
std::functionfn the function to run
boolpruned whether to only get pruned tx data, or the whole
Returns
false if the function returns false for any transaction, otherwise true

Implements cryptonote::BlockchainDB.

Definition at line 4073 of file db_lmdb.cpp.

4074 {
4075  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4076  check_open();
4077 
4079  RCURSOR(txs_pruned);
4080  RCURSOR(txs_prunable);
4081  RCURSOR(tx_indices);
4082 
4083  MDB_val k;
4084  MDB_val v;
4085  bool fret = true;
4086 
4087  MDB_cursor_op op = MDB_FIRST;
4088  while (1)
4089  {
4090  int ret = mdb_cursor_get(m_cur_tx_indices, &k, &v, op);
4091  op = MDB_NEXT;
4092  if (ret == MDB_NOTFOUND)
4093  break;
4094  if (ret)
4095  throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str()));
4096 
4097  txindex *ti = (txindex *)v.mv_data;
4098  const crypto::hash hash = ti->key;
4099  k.mv_data = (void *)&ti->data.tx_id;
4100  k.mv_size = sizeof(ti->data.tx_id);
4101 
4102  ret = mdb_cursor_get(m_cur_txs_pruned, &k, &v, MDB_SET);
4103  if (ret == MDB_NOTFOUND)
4104  break;
4105  if (ret)
4106  throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str()));
4107  transaction tx;
4108  blobdata bd;
4109  bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
4110  if (pruned)
4111  {
4113  throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
4114  }
4115  else
4116  {
4117  ret = mdb_cursor_get(m_cur_txs_prunable, &k, &v, MDB_SET);
4118  if (ret)
4119  throw0(DB_ERROR(lmdb_error("Failed to get prunable tx data the db: ", ret).c_str()));
4120  bd.append(reinterpret_cast<char*>(v.mv_data), v.mv_size);
4121  if (!parse_and_validate_tx_from_blob(bd, tx))
4122  throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
4123  }
4124  if (!f(hash, tx)) {
4125  fret = false;
4126  break;
4127  }
4128  }
4129 
4131 
4132  return fret;
4133 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
Definition: lmdb.h:411
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_txs_pruned
Definition: db_lmdb.h:87
bool parse_and_validate_tx_base_from_blob(const blobdata &tx_blob, transaction &tx)
bool parse_and_validate_tx_from_blob(const blobdata &tx_blob, transaction &tx)
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
std::string blobdata
Definition: blobdatatype.h:39
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
POD_CLASS hash
Definition: hash.h:50
#define m_cur_tx_indices
Definition: db_lmdb.h:91
#define m_cur_txs_prunable
Definition: db_lmdb.h:88
Here is the call graph for this function:

◆ for_all_txpool_txes()

bool cryptonote::BlockchainLMDB::for_all_txpool_txes ( std::function< bool(const crypto::hash &, const txpool_tx_meta_t &, const cryptonote::blobdata *)>  ,
bool  include_blob = false,
bool  include_unrelayed_txes = true 
) const
virtual

runs a function over all txpool transactions

The subclass should run the passed function for each txpool tx it has stored, passing the tx id and metadata as its parameters.

If any call to the function returns false, the subclass should return false. Otherwise, the subclass returns true.

Parameters
std::functionfn the function to run
Returns
false if the function returns false for any transaction, otherwise true

Implements cryptonote::BlockchainDB.

Definition at line 2941 of file db_lmdb.cpp.

2942 {
2943  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2944  check_open();
2945 
2947  RCURSOR(txpool_meta);
2948  RCURSOR(txpool_blob);
2949 
2950  MDB_val k;
2951  MDB_val v;
2952  bool ret = true;
2953 
2954  MDB_cursor_op op = MDB_FIRST;
2955  while (1)
2956  {
2957  int result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, op);
2958  op = MDB_NEXT;
2959  if (result == MDB_NOTFOUND)
2960  break;
2961  if (result)
2962  throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str()));
2963  const crypto::hash txid = *(const crypto::hash*)k.mv_data;
2964  const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
2965  if (!include_unrelayed_txes && meta.do_not_relay)
2966  // Skipping that tx
2967  continue;
2968  const cryptonote::blobdata *passed_bd = NULL;
2970  if (include_blob)
2971  {
2972  MDB_val b;
2973  result = mdb_cursor_get(m_cur_txpool_blob, &k, &b, MDB_SET);
2974  if (result == MDB_NOTFOUND)
2975  throw0(DB_ERROR("Failed to find txpool tx blob to match metadata"));
2976  if (result)
2977  throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx blob: ", result).c_str()));
2978  bd.assign(reinterpret_cast<const char*>(b.mv_data), b.mv_size);
2979  passed_bd = &bd;
2980  }
2981 
2982  if (!f(txid, meta, passed_bd)) {
2983  ret = false;
2984  break;
2985  }
2986  }
2987 
2989 
2990  return ret;
2991 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
Definition: lmdb.h:411
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define m_cur_txpool_blob
Definition: db_lmdb.h:95
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
std::string blobdata
Definition: blobdatatype.h:39
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
POD_CLASS hash
Definition: hash.h:50
Here is the call graph for this function:

◆ for_blocks_range()

bool cryptonote::BlockchainLMDB::for_blocks_range ( const uint64_t h1,
const uint64_t h2,
std::function< bool(uint64_t, const crypto::hash &, const cryptonote::block &)>   
) const
virtual

runs a function over a range of blocks

The subclass should run the passed function for each block in the specified range, passing (block_height, block_hash, block) as its parameters.

If any call to the function returns false, the subclass should return false. Otherwise, the subclass returns true.

The subclass should throw DB_ERROR if any of the expected values are not found. Current implementations simply return false.

Parameters
h1the start height
h2the end height
std::functionfn the function to run
Returns
false if the function returns false for any block, otherwise true

Implements cryptonote::BlockchainDB.

Definition at line 4022 of file db_lmdb.cpp.

4023 {
4024  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4025  check_open();
4026 
4028  RCURSOR(blocks);
4029 
4030  MDB_val k;
4031  MDB_val v;
4032  bool fret = true;
4033 
4034  MDB_cursor_op op;
4035  if (h1)
4036  {
4037  k = MDB_val{sizeof(h1), (void*)&h1};
4038  op = MDB_SET;
4039  } else
4040  {
4041  op = MDB_FIRST;
4042  }
4043  while (1)
4044  {
4045  int ret = mdb_cursor_get(m_cur_blocks, &k, &v, op);
4046  op = MDB_NEXT;
4047  if (ret == MDB_NOTFOUND)
4048  break;
4049  if (ret)
4050  throw0(DB_ERROR("Failed to enumerate blocks"));
4051  uint64_t height = *(const uint64_t*)k.mv_data;
4052  blobdata bd;
4053  bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
4054  block b;
4056  throw0(DB_ERROR("Failed to parse block from blob retrieved from the db"));
4058  if (!get_block_hash(b, hash))
4059  throw0(DB_ERROR("Failed to get block hash from blob retrieved from the db"));
4060  if (!f(height, hash, b)) {
4061  fret = false;
4062  break;
4063  }
4064  if (height >= h2)
4065  break;
4066  }
4067 
4069 
4070  return fret;
4071 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
Definition: lmdb.h:411
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
bool get_block_hash(const block &b, crypto::hash &res)
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
std::string blobdata
Definition: blobdatatype.h:39
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
POD_CLASS hash
Definition: hash.h:50
#define m_cur_blocks
Definition: db_lmdb.h:81
bool parse_and_validate_block_from_blob(const blobdata &b_blob, block &b, crypto::hash *block_hash)
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_addr_output_all()

std::vector< address_outputs > cryptonote::BlockchainLMDB::get_addr_output_all ( const crypto::public_key combined_key)
virtual

Implements cryptonote::BlockchainDB.

Definition at line 2071 of file db_lmdb.cpp.

2072 {
2073  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2074  check_open();
2075 
2077  RCURSOR(addr_outputs);
2078 
2079  int result = 0;
2080  std::vector<address_outputs> address_outputs;
2081 
2082  MDB_val k = {sizeof(combined_key), (void *)&combined_key};
2083 
2085  while (1) {
2086  MDB_val v;
2087  int ret = mdb_cursor_get(m_cur_addr_outputs, &k, &v, op);
2088  op = MDB_NEXT_DUP;
2089  if (ret == MDB_NOTFOUND)
2090  break;
2091  if (ret)
2092  throw0(DB_ERROR("Failed to enumerate address outputs"));
2093 
2094  const acc_outs_t res = *(const acc_outs_t *) v.mv_data;
2095 
2096  cryptonote::address_outputs addr_out;
2097  addr_out.out_id = res.db_index;
2098  addr_out.tx_hash = res.tx_hash;
2099  addr_out.relative_out_index = res.relative_out_index;
2100  addr_out.amount = res.amount;
2101  addr_out.spent = !check_chainstate_utxo(res.tx_hash, res.relative_out_index);
2102 
2103  address_outputs.push_back(addr_out);
2104 
2105  }
2106 
2108 
2109  return address_outputs;
2110 }
const char * res
Definition: hmac_keccak.cpp:41
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
struct cryptonote::acc_outs_t acc_outs_t
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_addr_outputs
Definition: db_lmdb.h:100
Here is the call graph for this function:

◆ get_addr_output_batch()

std::vector< address_outputs > cryptonote::BlockchainLMDB::get_addr_output_batch ( const crypto::public_key combined_key,
uint64_t  start_db_index = 0,
uint64_t  batch_size = 100,
bool  desc = false 
)
virtual

Implements cryptonote::BlockchainDB.

Definition at line 2112 of file db_lmdb.cpp.

2113 {
2114  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2115  check_open();
2116 
2118  RCURSOR(addr_outputs);
2119 
2120  std::vector<address_outputs> address_outputs;
2121 
2122  MDB_val k = {sizeof(combined_key), (void *)&combined_key};
2123  MDB_val v;
2124 
2125  MDB_cursor_op op;
2126  if (start_db_index)
2127  op = MDB_GET_BOTH;
2128  else
2129  {
2130  op = desc ? MDB_LAST_DUP : MDB_FIRST_DUP;
2131  int result = mdb_cursor_get(m_cur_addr_outputs, &k, &v, MDB_SET_KEY);
2132  if (result != 0 && result != MDB_NOTFOUND)
2133  throw1(DB_ERROR(lmdb_error("Failed to enumerate address outputs", result).c_str()));
2134  }
2135 
2136  std::set<std::string> tx_hashes;
2137  for(size_t i = 0; i < batch_size + 1; ++i) {
2138  if(op == MDB_GET_BOTH)
2139  v = MDB_val{sizeof(start_db_index), (void*)&start_db_index};
2140 
2141  int ret = mdb_cursor_get(m_cur_addr_outputs, &k, &v, op);
2142  op = desc ? MDB_PREV_DUP : MDB_NEXT_DUP;
2143  if (ret == MDB_NOTFOUND)
2144  break;
2145  if (ret)
2146  throw0(DB_ERROR("Failed to enumerate address outputs"));
2147 
2148  const acc_outs_t res = *(const acc_outs_t *) v.mv_data;
2149 
2150  std::string tx_hash_hex = epee::string_tools::pod_to_hex(res.tx_hash);
2151  if(tx_hashes.find(tx_hash_hex) != tx_hashes.end())
2152  {
2153  --i;
2154  continue;
2155  }
2156 
2157  cryptonote::address_outputs addr_out;
2158  addr_out.out_id = res.db_index;
2159  addr_out.tx_hash = res.tx_hash;
2160  addr_out.relative_out_index = res.relative_out_index;
2161  addr_out.amount = res.amount;
2162  addr_out.spent = !check_chainstate_utxo(res.tx_hash, res.relative_out_index);
2163 
2164  address_outputs.push_back(addr_out);
2165  tx_hashes.emplace(tx_hash_hex);
2166  }
2167 
2169  return address_outputs;
2170 }
const char * res
Definition: hmac_keccak.cpp:41
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
struct cryptonote::acc_outs_t acc_outs_t
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_addr_outputs
Definition: db_lmdb.h:100
Here is the call graph for this function:

◆ get_addr_tx_all()

std::vector< address_txs > cryptonote::BlockchainLMDB::get_addr_tx_all ( const crypto::public_key combined_key)
virtual

Implements cryptonote::BlockchainDB.

Definition at line 2214 of file db_lmdb.cpp.

2215 {
2216  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2217  check_open();
2218 
2220  RCURSOR(addr_txs);
2221 
2222  int result = 0;
2223  std::vector<address_txs> address_txs;
2224 
2225  MDB_val k = {sizeof(combined_key), (void *)&combined_key};
2226 
2228  while (1) {
2229  MDB_val v;
2230  int ret = mdb_cursor_get(m_cur_addr_txs, &k, &v, op);
2231  op = MDB_NEXT_DUP;
2232  if (ret == MDB_NOTFOUND)
2233  break;
2234  if (ret)
2235  throw0(DB_ERROR("Failed to enumerate address txs"));
2236 
2237  const acc_addr_tx_t res = *(const acc_addr_tx_t *) v.mv_data;
2238 
2239  cryptonote::address_txs addr_tx;
2240  addr_tx.addr_tx_id = res.db_index;
2241  addr_tx.tx_hash = res.tx_hash;
2242  address_txs.push_back(addr_tx);
2243  }
2244 
2246  return address_txs;
2247 }
const char * res
Definition: hmac_keccak.cpp:41
#define MDB_NOTFOUND
Definition: lmdb.h:439
struct cryptonote::acc_addr_tx_t acc_addr_tx_t
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_addr_txs
Definition: db_lmdb.h:101
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ get_addr_tx_batch()

std::vector< address_txs > cryptonote::BlockchainLMDB::get_addr_tx_batch ( const crypto::public_key combined_key,
uint64_t  start_db_index = 0,
uint64_t  batch_size = 100,
bool  desc = false 
)
virtual

Implements cryptonote::BlockchainDB.

Definition at line 2249 of file db_lmdb.cpp.

2250 {
2251  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2252  check_open();
2253 
2255  RCURSOR(addr_txs);
2256 
2257  std::vector<address_txs> address_txs;
2258 
2259  MDB_val k = {sizeof(combined_key), (void *)&combined_key};
2260  MDB_val v;
2261 
2262  MDB_cursor_op op;
2263  if (start_db_index)
2264  op = MDB_GET_BOTH;
2265  else
2266  {
2267  op = desc ? MDB_LAST_DUP : MDB_FIRST_DUP;
2268  int result = mdb_cursor_get(m_cur_addr_txs, &k, &v, MDB_SET_KEY);
2269  if (result != 0 && result != MDB_NOTFOUND)
2270  throw1(DB_ERROR(lmdb_error("Failed to enumerate address txs", result).c_str()));
2271  }
2272 
2273  std::set<std::string> tx_hashes;
2274  for(size_t i = 0; i < batch_size + 1; ++i) {
2275  if(op == MDB_GET_BOTH)
2276  v = MDB_val{sizeof(start_db_index), (void*)&start_db_index};
2277 
2278  int ret = mdb_cursor_get(m_cur_addr_txs, &k, &v, op);
2279  op = desc ? MDB_PREV_DUP : MDB_NEXT_DUP;
2280  if (ret == MDB_NOTFOUND)
2281  break;
2282  if (ret)
2283  throw0(DB_ERROR("Failed to enumerate address txs"));
2284 
2285  const acc_addr_tx_t res = *(const acc_addr_tx_t *) v.mv_data;
2286 
2287  cryptonote::address_txs addr_tx;
2288  addr_tx.addr_tx_id = res.db_index;
2289  addr_tx.tx_hash = res.tx_hash;
2290 
2291  address_txs.push_back(addr_tx);
2292  }
2293 
2295  return address_txs;
2296 }
const char * res
Definition: hmac_keccak.cpp:41
#define MDB_NOTFOUND
Definition: lmdb.h:439
struct cryptonote::acc_addr_tx_t acc_addr_tx_t
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_addr_txs
Definition: db_lmdb.h:101
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ get_balance()

uint64_t cryptonote::BlockchainLMDB::get_balance ( const crypto::public_key combined_key)
virtual

Implements cryptonote::BlockchainDB.

Definition at line 2298 of file db_lmdb.cpp.

2299 {
2300  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2301  check_open();
2302 
2304  RCURSOR(addr_outputs);
2305 
2306  uint64_t balance = 0;
2307 
2308  MDB_val k = {sizeof(combined_key), (void *)&combined_key};
2309 
2311  while (1) {
2312  MDB_val v;
2313  int ret = mdb_cursor_get(m_cur_addr_outputs, &k, &v, op);
2314  op = MDB_NEXT_DUP;
2315  if (ret == MDB_NOTFOUND)
2316  break;
2317  if (ret)
2318  throw0(DB_ERROR("Failed to enumerate address outputs"));
2319 
2320  const acc_outs_t res = *(const acc_outs_t *) v.mv_data;
2321 
2322  if(check_chainstate_utxo(res.tx_hash, res.relative_out_index))
2323  balance += res.amount;
2324  }
2325 
2327 
2328  return balance;
2329 }
const char * res
Definition: hmac_keccak.cpp:41
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
struct cryptonote::acc_outs_t acc_outs_t
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_addr_outputs
Definition: db_lmdb.h:100
Here is the call graph for this function:

◆ get_block_already_generated_coins()

uint64_t cryptonote::BlockchainLMDB::get_block_already_generated_coins ( const uint64_t height) const
virtual

fetch a block's already generated coins

The subclass should return the total coins generated as of the block with the given height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the already generated coins

Implements cryptonote::BlockchainDB.

Definition at line 3405 of file db_lmdb.cpp.

3406 {
3407  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3408  check_open();
3409 
3411  RCURSOR(block_info);
3412 
3413  MDB_val_set(result, height);
3414  auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);
3415  if (get_result == MDB_NOTFOUND)
3416  {
3417  throw0(BLOCK_DNE(std::string("Attempt to get generated coins from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- block size not in db").c_str()));
3418  }
3419  else if (get_result)
3420  throw0(DB_ERROR("Error attempting to retrieve a total generated coins from the db"));
3421 
3422  mdb_block_info *bi = (mdb_block_info *)result.mv_data;
3423  uint64_t ret = bi->bi_coins;
3425  return ret;
3426 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_block_blob()

cryptonote::blobdata cryptonote::BlockchainLMDB::get_block_blob ( const crypto::hash h) const
virtual

fetches the block with the given hash

The subclass should return the requested block.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
hthe hash to look for
Returns
the block requested

Implements cryptonote::BlockchainDB.

Definition at line 3024 of file db_lmdb.cpp.

3025 {
3026  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3027  check_open();
3028 
3030 }
virtual uint64_t get_block_height(const crypto::hash &h) const
gets the height of the block with a given hash
Definition: db_lmdb.cpp:3032
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual cryptonote::blobdata get_block_blob_from_height(const uint64_t &height) const
fetch a block blob by height
Definition: db_lmdb.cpp:3062
Here is the call graph for this function:

◆ get_block_blob_from_height()

cryptonote::blobdata cryptonote::BlockchainLMDB::get_block_blob_from_height ( const uint64_t height) const
virtual

fetch a block blob by height

The subclass should return the block at the given height.

If the block does not exist, that is to say if the blockchain is not that high, then the subclass should throw BLOCK_DNE

Parameters
heightthe height to look for
Returns
the block blob

Implements cryptonote::BlockchainDB.

Definition at line 3062 of file db_lmdb.cpp.

3063 {
3064  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3065  check_open();
3066 
3068  RCURSOR(blocks);
3069 
3070  MDB_val_copy<uint64_t> key(height);
3071  MDB_val result;
3072  auto get_result = mdb_cursor_get(m_cur_blocks, &key, &result, MDB_SET);
3073  if (get_result == MDB_NOTFOUND)
3074  {
3075  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()));
3076  }
3077  else if (get_result)
3078  throw0(DB_ERROR("Error attempting to retrieve a block from the db"));
3079 
3080  blobdata bd;
3081  bd.assign(reinterpret_cast<char*>(result.mv_data), result.mv_size);
3082 
3084 
3085  return bd;
3086 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
const char * key
Definition: hmac_keccak.cpp:39
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
std::string blobdata
Definition: blobdatatype.h:39
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_blocks
Definition: db_lmdb.h:81
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_block_cumulative_difficulty()

difficulty_type cryptonote::BlockchainLMDB::get_block_cumulative_difficulty ( const uint64_t height) const
virtual

fetch a block's cumulative difficulty

The subclass should return the cumulative difficulty of the block with the given height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the cumulative difficulty

Implements cryptonote::BlockchainDB.

Definition at line 3363 of file db_lmdb.cpp.

3364 {
3365  LOG_PRINT_L3("BlockchainLMDB::" << __func__ << " height: " << height);
3366  check_open();
3367 
3369  RCURSOR(block_info);
3370 
3371  MDB_val_set(result, height);
3372  auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);
3373  if (get_result == MDB_NOTFOUND)
3374  {
3375  throw0(BLOCK_DNE(std::string("Attempt to get cumulative difficulty from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- difficulty not in db").c_str()));
3376  }
3377  else if (get_result)
3378  throw0(DB_ERROR("Error attempting to retrieve a cumulative difficulty from the db"));
3379 
3380  mdb_block_info *bi = (mdb_block_info *)result.mv_data;
3381  difficulty_type ret = bi->bi_diff_hi;
3382  ret <<= 64;
3383  ret |= bi->bi_diff_lo;
3385  return ret;
3386 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
boost::multiprecision::uint128_t difficulty_type
Definition: difficulty.h:43
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_block_cumulative_rct_outputs()

std::vector< uint64_t > cryptonote::BlockchainLMDB::get_block_cumulative_rct_outputs ( const std::vector< uint64_t > &  heights) const
virtual

fetch a block's cumulative number of rct outputs

The subclass should return the numer of rct outputs in the blockchain up to the block with the given height (inclusive).

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the cumulative number of rct outputs

Implements cryptonote::BlockchainDB.

Definition at line 3111 of file db_lmdb.cpp.

3112 {
3113  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3114  check_open();
3115  std::vector<uint64_t> res;
3116  int result;
3117 
3118  if (heights.empty())
3119  return {};
3120  res.reserve(heights.size());
3121 
3123  RCURSOR(block_info);
3124 
3125  MDB_stat db_stats;
3126  if ((result = mdb_stat(m_txn, m_blocks, &db_stats)))
3127  throw0(DB_ERROR(lmdb_error("Failed to query m_blocks: ", result).c_str()));
3128  for (size_t i = 0; i < heights.size(); ++i)
3129  if (heights[i] >= db_stats.ms_entries)
3130  throw0(BLOCK_DNE(std::string("Attempt to get rct distribution from height " + std::to_string(heights[i]) + " failed -- block size not in db").c_str()));
3131 
3132  MDB_val v;
3133 
3134  uint64_t prev_height = heights[0];
3135  uint64_t range_begin = 0, range_end = 0;
3136  for (uint64_t height: heights)
3137  {
3138  if (height >= range_begin && height < range_end)
3139  {
3140  // nohting to do
3141  }
3142  else
3143  {
3144  if (height == prev_height + 1)
3145  {
3146  MDB_val k2;
3148  range_begin = ((const mdb_block_info*)v.mv_data)->bi_height;
3149  range_end = range_begin + v.mv_size / sizeof(mdb_block_info); // whole records please
3150  if (height < range_begin || height >= range_end)
3151  throw0(DB_ERROR(("Height " + std::to_string(height) + " not included in multuple record range: " + std::to_string(range_begin) + "-" + std::to_string(range_end)).c_str()));
3152  }
3153  else
3154  {
3155  v.mv_size = sizeof(uint64_t);
3156  v.mv_data = (void*)&height;
3157  result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3158  range_begin = height;
3159  range_end = range_begin + 1;
3160  }
3161  if (result)
3162  throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct distribution from the db: ", result).c_str()));
3163  }
3164  const mdb_block_info *bi = ((const mdb_block_info *)v.mv_data) + (height - range_begin);
3165  res.push_back(bi->bi_cum_rct);
3166  prev_height = height;
3167  }
3168 
3170  return res;
3171 }
const char * res
Definition: hmac_keccak.cpp:41
::std::string string
Definition: gtest-port.h:1097
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
Statistics for a database in the environment.
Definition: lmdb.h:490
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
std::string to_string(t_connection_type type)
mdb_size_t ms_entries
Definition: lmdb.h:497
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_block_difficulty()

difficulty_type cryptonote::BlockchainLMDB::get_block_difficulty ( const uint64_t height) const
virtual

fetch a block's difficulty

The subclass should return the difficulty of the block with the given height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the difficulty

Implements cryptonote::BlockchainDB.

Definition at line 3388 of file db_lmdb.cpp.

3389 {
3390  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3391  check_open();
3392 
3393  difficulty_type diff1 = 0;
3394  difficulty_type diff2 = 0;
3395 
3397  if (height != 0)
3398  {
3400  }
3401 
3402  return diff1 - diff2;
3403 }
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual difficulty_type get_block_cumulative_difficulty(const uint64_t &height) const
fetch a block&#39;s cumulative difficulty
Definition: db_lmdb.cpp:3363
boost::multiprecision::uint128_t difficulty_type
Definition: difficulty.h:43
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_block_hash_from_height()

crypto::hash cryptonote::BlockchainLMDB::get_block_hash_from_height ( const uint64_t height) const
virtual

fetch a block's hash

The subclass should return hash of the block with the given height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the hash

Implements cryptonote::BlockchainDB.

Definition at line 3451 of file db_lmdb.cpp.

3452 {
3453  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3454  check_open();
3455 
3457  RCURSOR(block_info);
3458 
3459  MDB_val_set(result, height);
3460  auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);
3461  if (get_result == MDB_NOTFOUND)
3462  {
3463  throw0(BLOCK_DNE(std::string("Attempt to get hash from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- hash not in db").c_str()));
3464  }
3465  else if (get_result)
3466  throw0(DB_ERROR(lmdb_error("Error attempting to retrieve a block hash from the db: ", get_result).c_str()));
3467 
3468  mdb_block_info *bi = (mdb_block_info *)result.mv_data;
3469  crypto::hash ret = bi->bi_hash;
3471  return ret;
3472 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
POD_CLASS hash
Definition: hash.h:50
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_block_header()

block_header cryptonote::BlockchainLMDB::get_block_header ( const crypto::hash h) const
virtual

fetch a block header

The subclass should return the block header from the block with the given hash.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
hthe hash to look for
Returns
the block header

Implements cryptonote::BlockchainDB.

Definition at line 3053 of file db_lmdb.cpp.

3054 {
3055  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3056  check_open();
3057 
3058  // block_header object is automatically cast from block object
3059  return get_block(h);
3060 }
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual block get_block(const crypto::hash &h) const
fetches the block with the given hash
Here is the call graph for this function:

◆ get_block_height()

uint64_t cryptonote::BlockchainLMDB::get_block_height ( const crypto::hash h) const
virtual

gets the height of the block with a given hash

The subclass should return the requested height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
hthe hash to look for
Returns
the height

Implements cryptonote::BlockchainDB.

Definition at line 3032 of file db_lmdb.cpp.

3033 {
3034  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3035  check_open();
3036 
3038  RCURSOR(block_heights);
3039 
3040  MDB_val_set(key, h);
3041  auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
3042  if (get_result == MDB_NOTFOUND)
3043  throw1(BLOCK_DNE("Attempted to retrieve non-existent block height"));
3044  else if (get_result)
3045  throw0(DB_ERROR("Error attempting to retrieve a block height from the db"));
3046 
3047  blk_height *bhp = (blk_height *)key.mv_data;
3048  uint64_t ret = bhp->bh_height;
3050  return ret;
3051 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_block_heights
Definition: db_lmdb.h:82
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
const char * key
Definition: hmac_keccak.cpp:39
struct cryptonote::blk_height blk_height
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_block_long_term_weight()

uint64_t cryptonote::BlockchainLMDB::get_block_long_term_weight ( const uint64_t height) const
virtual

fetch a block's long term weight

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the long term weight

Implements cryptonote::BlockchainDB.

Definition at line 3428 of file db_lmdb.cpp.

3429 {
3430  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3431  check_open();
3432 
3434  RCURSOR(block_info);
3435 
3436  MDB_val_set(result, height);
3437  auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);
3438  if (get_result == MDB_NOTFOUND)
3439  {
3440  throw0(BLOCK_DNE(std::string("Attempt to get block long term weight from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- block info not in db").c_str()));
3441  }
3442  else if (get_result)
3443  throw0(DB_ERROR("Error attempting to retrieve a long term block weight from the db"));
3444 
3445  mdb_block_info *bi = (mdb_block_info *)result.mv_data;
3448  return ret;
3449 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_block_timestamp()

uint64_t cryptonote::BlockchainLMDB::get_block_timestamp ( const uint64_t height) const
virtual

fetch a block's timestamp

The subclass should return the timestamp of the block with the given height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the timestamp

Implements cryptonote::BlockchainDB.

Definition at line 3088 of file db_lmdb.cpp.

3089 {
3090  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3091  check_open();
3092 
3094  RCURSOR(block_info);
3095 
3096  MDB_val_set(result, height);
3097  auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);
3098  if (get_result == MDB_NOTFOUND)
3099  {
3100  throw0(BLOCK_DNE(std::string("Attempt to get timestamp from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- timestamp not in db").c_str()));
3101  }
3102  else if (get_result)
3103  throw0(DB_ERROR("Error attempting to retrieve a timestamp from the db"));
3104 
3105  mdb_block_info *bi = (mdb_block_info *)result.mv_data;
3106  uint64_t ret = bi->bi_timestamp;
3108  return ret;
3109 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_block_weight()

size_t cryptonote::BlockchainLMDB::get_block_weight ( const uint64_t height) const
virtual

fetch a block's weight

The subclass should return the weight of the block with the given height.

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
Returns
the weight

Implements cryptonote::BlockchainDB.

Definition at line 3188 of file db_lmdb.cpp.

3189 {
3190  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3191  check_open();
3192 
3194  RCURSOR(block_info);
3195 
3196  MDB_val_set(result, height);
3197  auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);
3198  if (get_result == MDB_NOTFOUND)
3199  {
3200  throw0(BLOCK_DNE(std::string("Attempt to get block size from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- block size not in db").c_str()));
3201  }
3202  else if (get_result)
3203  throw0(DB_ERROR("Error attempting to retrieve a block size from the db"));
3204 
3205  mdb_block_info *bi = (mdb_block_info *)result.mv_data;
3206  size_t ret = bi->bi_weight;
3208  return ret;
3209 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_block_weights()

std::vector< uint64_t > cryptonote::BlockchainLMDB::get_block_weights ( uint64_t  start_height,
size_t  count 
) const
virtual

fetch the last N blocks' weights

If there are fewer than N blocks, the returned array will be smaller than N

Parameters
countthe number of blocks requested
Returns
the weights

Implements cryptonote::BlockchainDB.

Definition at line 3317 of file db_lmdb.cpp.

3318 {
3319  return get_block_info_64bit_fields(start_height, count, offsetof(mdb_block_info, bi_weight));
3320 }
mdb_size_t count(MDB_cursor *cur)
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
Here is the call graph for this function:

◆ get_blockchain_pruning_seed()

uint32_t cryptonote::BlockchainLMDB::get_blockchain_pruning_seed ( ) const
virtual

get the blockchain pruning seed

Returns
the blockchain pruning seed

Implements cryptonote::BlockchainDB.

Definition at line 2608 of file db_lmdb.cpp.

2609 {
2610  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2611  check_open();
2612 
2614  RCURSOR(properties)
2615  MDB_val_str(k, "pruning_seed");
2616  MDB_val v;
2617  int result = mdb_cursor_get(m_cur_properties, &k, &v, MDB_SET);
2618  if (result == MDB_NOTFOUND)
2619  return 0;
2620  if (result)
2621  throw0(DB_ERROR(lmdb_error("Failed to retrieve pruning seed: ", result).c_str()));
2622  if (v.mv_size != sizeof(uint32_t))
2623  throw0(DB_ERROR("Failed to retrieve or create pruning seed: unexpected value size"));
2624  uint32_t pruning_seed;
2625  memcpy(&pruning_seed, v.mv_data, sizeof(pruning_seed));
2627  return pruning_seed;
2628 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
unsigned int uint32_t
Definition: stdint.h:126
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
void * memcpy(void *a, const void *b, size_t c)
#define MDB_val_str(var, val)
Definition: db_lmdb.cpp:93
#define m_cur_properties
Definition: db_lmdb.h:97
Here is the call graph for this function:

◆ get_blocks_range()

std::vector< block > cryptonote::BlockchainLMDB::get_blocks_range ( const uint64_t h1,
const uint64_t h2 
) const
virtual

fetch a list of blocks

The subclass should return a vector of blocks with heights starting at h1 and ending at h2, inclusively.

If the height range requested goes past the end of the blockchain, the subclass should throw BLOCK_DNE. (current implementations simply don't catch this exception as thrown by methods called within)

Parameters
h1the start height
h2the end height
Returns
a vector of blocks

Implements cryptonote::BlockchainDB.

Definition at line 3474 of file db_lmdb.cpp.

3475 {
3476  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3477  check_open();
3478  std::vector<block> v;
3479 
3480  for (uint64_t height = h1; height <= h2; ++height)
3481  {
3482  v.push_back(get_block_from_height(height));
3483  }
3484 
3485  return v;
3486 }
virtual block get_block_from_height(const uint64_t &height) const
fetch a block by height
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_db_name()

std::string cryptonote::BlockchainLMDB::get_db_name ( ) const
virtual

gets the name of the folder the BlockchainDB's file(s) should be in

The subclass implementation should return the name of the folder in which it stores files, or an empty string if there is none.

Returns
the name of the folder with the BlockchainDB's files, if any.

Implements cryptonote::BlockchainDB.

Definition at line 1755 of file db_lmdb.cpp.

1756 {
1757  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1758 
1759  return std::string("lmdb");
1760 }
::std::string string
Definition: gtest-port.h:1097
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102

◆ get_filenames()

std::vector< std::string > cryptonote::BlockchainLMDB::get_filenames ( ) const
virtual

get all files used by the BlockchainDB (if any)

This function is largely for ease of automation, namely for unit tests.

The subclass implementation should return all filenames it uses.

Returns
a list of filenames

Implements cryptonote::BlockchainDB.

Definition at line 1724 of file db_lmdb.cpp.

1725 {
1726  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1727  std::vector<std::string> filenames;
1728 
1729  boost::filesystem::path datafile(m_folder);
1731  boost::filesystem::path lockfile(m_folder);
1733 
1734  filenames.push_back(datafile.string());
1735  filenames.push_back(lockfile.string());
1736 
1737  return filenames;
1738 }
#define CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME
#define CRYPTONOTE_BLOCKCHAINDATA_FILENAME
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102

◆ get_hashes_range()

std::vector< crypto::hash > cryptonote::BlockchainLMDB::get_hashes_range ( const uint64_t h1,
const uint64_t h2 
) const
virtual

fetch a list of block hashes

The subclass should return a vector of block hashes from blocks with heights starting at h1 and ending at h2, inclusively.

If the height range requested goes past the end of the blockchain, the subclass should throw BLOCK_DNE. (current implementations simply don't catch this exception as thrown by methods called within)

Parameters
h1the start height
h2the end height
Returns
a vector of block hashes

Implements cryptonote::BlockchainDB.

Definition at line 3488 of file db_lmdb.cpp.

3489 {
3490  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3491  check_open();
3492  std::vector<crypto::hash> v;
3493 
3494  for (uint64_t height = h1; height <= h2; ++height)
3495  {
3496  v.push_back(get_block_hash_from_height(height));
3497  }
3498 
3499  return v;
3500 }
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual crypto::hash get_block_hash_from_height(const uint64_t &height) const
fetch a block&#39;s hash
Definition: db_lmdb.cpp:3451
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_long_term_block_weights()

std::vector< uint64_t > cryptonote::BlockchainLMDB::get_long_term_block_weights ( uint64_t  start_height,
size_t  count 
) const
virtual

fetch the last N blocks' long term weights

If there are fewer than N blocks, the returned array will be smaller than N

Parameters
countthe number of blocks requested
Returns
the weights

Implements cryptonote::BlockchainDB.

Definition at line 3322 of file db_lmdb.cpp.

3323 {
3324  return get_block_info_64bit_fields(start_height, count, offsetof(mdb_block_info, bi_long_term_block_weight));
3325 }
mdb_size_t count(MDB_cursor *cur)
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
Here is the call graph for this function:

◆ get_num_outputs()

uint64_t cryptonote::BlockchainLMDB::get_num_outputs ( const uint64_t amount) const
virtual

fetches the number of outputs of a given amount

The subclass should return a count of outputs of the given amount, or zero if there are none.

Parameters
amountthe output amount being looked up
Returns
the number of outputs of the given amount

Implements cryptonote::BlockchainDB.

Definition at line 3835 of file db_lmdb.cpp.

3836 {
3837  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3838  check_open();
3839 
3841  RCURSOR(output_amounts);
3842 
3843  MDB_val_copy<uint64_t> k(amount);
3844  MDB_val v;
3845  mdb_size_t num_elems = 0;
3846  auto result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_SET);
3847  if (result == MDB_SUCCESS)
3848  {
3850  }
3851  else if (result != MDB_NOTFOUND)
3852  throw0(DB_ERROR("DB error attempting to get number of outputs of an amount"));
3853 
3855 
3856  return num_elems;
3857 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
int mdb_cursor_count(MDB_cursor *cursor, mdb_size_t *countp)
Return count of duplicates for current key.
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_SUCCESS
Definition: lmdb.h:435
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
size_t mdb_size_t
Definition: lmdb.h:196
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_output_distribution()

bool cryptonote::BlockchainLMDB::get_output_distribution ( uint64_t  amount,
uint64_t  from_height,
uint64_t  to_height,
std::vector< uint64_t > &  distribution,
uint64_t base 
) const
virtual

Implements cryptonote::BlockchainDB.

Definition at line 4744 of file db_lmdb.cpp.

4745 {
4746  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4747  check_open();
4748 
4750  RCURSOR(output_amounts);
4751 
4752  distribution.clear();
4753  const uint64_t db_height = height();
4754  if (from_height >= db_height)
4755  return false;
4756  distribution.resize(db_height - from_height, 0);
4757 
4758  bool fret = true;
4759  MDB_val_set(k, amount);
4760  MDB_val v;
4761  MDB_cursor_op op = MDB_SET;
4762  base = 0;
4763  while (1)
4764  {
4765  int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op);
4766  op = MDB_NEXT_DUP;
4767  if (ret == MDB_NOTFOUND)
4768  break;
4769  if (ret)
4770  throw0(DB_ERROR("Failed to enumerate outputs"));
4771  const outkey *ok = (const outkey *)v.mv_data;
4772  const uint64_t height = ok->data.height;
4773  if (height >= from_height)
4774  distribution[height - from_height]++;
4775  else
4776  base++;
4777  if (to_height > 0 && height > to_height)
4778  break;
4779  }
4780 
4781  distribution[0] += base;
4782  for (size_t n = 1; n < distribution.size(); ++n)
4783  distribution[n] += distribution[n - 1];
4784  base = 0;
4785 
4787 
4788  return true;
4789 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
struct cryptonote::outkey outkey
else if(0==res)
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_output_histogram()

std::map< uint64_t, std::tuple< uint64_t, uint64_t, uint64_t > > cryptonote::BlockchainLMDB::get_output_histogram ( const std::vector< uint64_t > &  amounts,
bool  unlocked,
uint64_t  recent_cutoff,
uint64_t  min_count 
) const
virtual

return a histogram of outputs on the blockchain

Parameters
amountsoptional set of amounts to lookup
unlockedwhether to restrict count to unlocked outputs
recent_cutofftimestamp to determine which outputs are recent
min_countreturn only amounts with at least that many instances
Returns
a set of amount/instances

Implements cryptonote::BlockchainDB.

Definition at line 4651 of file db_lmdb.cpp.

4652 {
4653  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4654  check_open();
4655 
4657  RCURSOR(output_amounts);
4658 
4659  std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> histogram;
4660  MDB_val k;
4661  MDB_val v;
4662 
4663  if (amounts.empty())
4664  {
4665  MDB_cursor_op op = MDB_FIRST;
4666  while (1)
4667  {
4668  int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op);
4669  op = MDB_NEXT_NODUP;
4670  if (ret == MDB_NOTFOUND)
4671  break;
4672  if (ret)
4673  throw0(DB_ERROR(lmdb_error("Failed to enumerate outputs: ", ret).c_str()));
4674  mdb_size_t num_elems = 0;
4676  uint64_t amount = *(const uint64_t*)k.mv_data;
4677  if (num_elems >= min_count)
4678  histogram[amount] = std::make_tuple(num_elems, 0, 0);
4679  }
4680  }
4681  else
4682  {
4683  for (const auto &amount: amounts)
4684  {
4685  MDB_val_copy<uint64_t> k(amount);
4686  int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_SET);
4687  if (ret == MDB_NOTFOUND)
4688  {
4689  if (0 >= min_count)
4690  histogram[amount] = std::make_tuple(0, 0, 0);
4691  }
4692  else if (ret == MDB_SUCCESS)
4693  {
4694  mdb_size_t num_elems = 0;
4696  if (num_elems >= min_count)
4697  histogram[amount] = std::make_tuple(num_elems, 0, 0);
4698  }
4699  else
4700  {
4701  throw0(DB_ERROR(lmdb_error("Failed to enumerate outputs: ", ret).c_str()));
4702  }
4703  }
4704  }
4705 
4706  if (unlocked || recent_cutoff > 0) {
4707  const uint64_t blockchain_height = height();
4708  for (std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>>::iterator i = histogram.begin(); i != histogram.end(); ++i) {
4709  uint64_t amount = i->first;
4710  uint64_t num_elems = std::get<0>(i->second);
4711  while (num_elems > 0) {
4712  const tx_out_index toi = get_output_tx_and_index(amount, num_elems - 1);
4713  const uint64_t height = get_tx_block_height(toi.first);
4714  if (height + (get_hard_fork_version(height) > 7 ? ETN_DEFAULT_TX_SPENDABLE_AGE_V8 : CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE) <= blockchain_height)
4715  break;
4716  --num_elems;
4717  }
4718  // modifying second does not invalidate the iterator
4719  std::get<1>(i->second) = num_elems;
4720 
4721  if (recent_cutoff > 0)
4722  {
4723  uint64_t recent = 0;
4724  while (num_elems > 0) {
4725  const tx_out_index toi = get_output_tx_and_index(amount, num_elems - 1);
4726  const uint64_t height = get_tx_block_height(toi.first);
4727  const uint64_t ts = get_block_timestamp(height);
4728  if (ts < recent_cutoff)
4729  break;
4730  --num_elems;
4731  ++recent;
4732  }
4733  // modifying second does not invalidate the iterator
4734  std::get<2>(i->second) = recent;
4735  }
4736  }
4737  }
4738 
4740 
4741  return histogram;
4742 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
int mdb_cursor_count(MDB_cursor *cursor, mdb_size_t *countp)
Return count of duplicates for current key.
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define ETN_DEFAULT_TX_SPENDABLE_AGE_V8
tuple make_tuple()
Definition: gtest-tuple.h:675
void * mv_data
Definition: lmdb.h:288
#define MDB_SUCCESS
Definition: lmdb.h:435
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
unsigned __int64 uint64_t
Definition: stdint.h:136
virtual uint64_t get_block_timestamp(const uint64_t &height) const
fetch a block&#39;s timestamp
Definition: db_lmdb.cpp:3088
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE
std::pair< crypto::hash, uint64_t > tx_out_index
else if(0==res)
size_t mdb_size_t
Definition: lmdb.h:196
virtual uint64_t get_tx_block_height(const crypto::hash &h) const
fetches the height of a transaction&#39;s block
Definition: db_lmdb.cpp:3812
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
virtual tx_out_index get_output_tx_and_index(const uint64_t &amount, const uint64_t &index) const
gets an output&#39;s tx hash and index
Definition: db_lmdb.cpp:3916
Here is the call graph for this function:

◆ get_output_key() [1/2]

output_data_t cryptonote::BlockchainLMDB::get_output_key ( const uint64_t amount,
const uint64_t index,
bool  include_commitmemt 
) const
virtual

get some of an output's data

The subclass should return the public key, unlock time, and block height for the output with the given amount and index, collected in a struct.

If the output cannot be found, the subclass should throw OUTPUT_DNE.

If any of these parts cannot be found, but some are, the subclass should throw DB_ERROR with a message stating as much.

Parameters
amountthe output amount
indexthe output's index (indexed by amount)
Returns
the requested output data

Implements cryptonote::BlockchainDB.

Definition at line 3859 of file db_lmdb.cpp.

3860 {
3861  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3862  check_open();
3863 
3865  RCURSOR(output_amounts);
3866 
3867  MDB_val_set(k, amount);
3868  MDB_val_set(v, index);
3869  auto get_result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_GET_BOTH);
3870  if (get_result == MDB_NOTFOUND)
3871  throw1(OUTPUT_DNE(std::string("Attempting to get output pubkey by index, but key does not exist: amount " +
3872  std::to_string(amount) + ", index " + std::to_string(index)).c_str()));
3873  else if (get_result)
3874  throw0(DB_ERROR("Error attempting to retrieve an output pubkey from the db"));
3875 
3876  output_data_t ret;
3877  if (amount == 0)
3878  {
3879  const outkey *okp = (const outkey *)v.mv_data;
3880  ret = okp->data;
3881  }
3882  else
3883  {
3884  const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data;
3885  memcpy(&ret, &okp->data, sizeof(pre_rct_output_data_t));;
3886  if (include_commitmemt)
3887  ret.commitment = rct::zeroCommit(amount);
3888  }
3890  return ret;
3891 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
output_data_t data
Definition: db_lmdb.cpp:371
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
struct cryptonote::outkey outkey
void * memcpy(void *a, const void *b, size_t c)
key zeroCommit(etn_amount amount)
Definition: rctOps.cpp:322
std::string to_string(t_connection_type type)
struct cryptonote::pre_rct_outkey pre_rct_outkey
Here is the call graph for this function:

◆ get_output_key() [2/2]

void cryptonote::BlockchainLMDB::get_output_key ( const epee::span< const uint64_t > &  amounts,
const std::vector< uint64_t > &  offsets,
std::vector< output_data_t > &  outputs,
bool  allow_partial = false 
) const
virtual

gets outputs' data

This function is a mirror of get_output_data(const uint64_t& amount, const uint64_t& index) but for a list of outputs rather than just one.

Parameters
amountsan output amount, or as many as offsets
offsetsa list of amount-specific output indices
outputsreturn-by-reference a list of outputs' metadata

Implements cryptonote::BlockchainDB.

Definition at line 4560 of file db_lmdb.cpp.

4561 {
4562  if (amounts.size() != 1 && amounts.size() != offsets.size())
4563  throw0(DB_ERROR("Invalid sizes of amounts and offets"));
4564 
4565  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4566  TIME_MEASURE_START(db3);
4567  check_open();
4568  outputs.clear();
4569  outputs.reserve(offsets.size());
4570 
4572 
4573  RCURSOR(output_amounts);
4574 
4575  for (size_t i = 0; i < offsets.size(); ++i)
4576  {
4577  const uint64_t amount = amounts.size() == 1 ? amounts[0] : amounts[i];
4578  MDB_val_set(k, amount);
4579  MDB_val_set(v, offsets[i]);
4580 
4581  auto get_result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_GET_BOTH);
4582  if (get_result == MDB_NOTFOUND)
4583  {
4584  if (allow_partial)
4585  {
4586  MDEBUG("Partial result: " << outputs.size() << "/" << offsets.size());
4587  break;
4588  }
4589  throw1(OUTPUT_DNE((std::string("Attempting to get output pubkey by global index (amount ") + boost::lexical_cast<std::string>(amount) + ", index " + boost::lexical_cast<std::string>(offsets[i]) + ", count " + boost::lexical_cast<std::string>(get_num_outputs(amount)) + "), but key does not exist (current height " + boost::lexical_cast<std::string>(height()) + ")").c_str()));
4590  }
4591  else if (get_result)
4592  throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output pubkey from the db", get_result).c_str()));
4593 
4594  if (amount == 0)
4595  {
4596  const outkey *okp = (const outkey *)v.mv_data;
4597  outputs.push_back(okp->data);
4598  }
4599  else
4600  {
4601  const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data;
4602  outputs.resize(outputs.size() + 1);
4603  output_data_t &data = outputs.back();
4604  memcpy(&data, &okp->data, sizeof(pre_rct_output_data_t));
4605  data.commitment = rct::zeroCommit(amount);
4606  }
4607  }
4608 
4610 
4611  TIME_MEASURE_FINISH(db3);
4612  LOG_PRINT_L3("db3: " << db3);
4613 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDEBUG(x)
Definition: misc_log_ex.h:76
constexpr std::size_t size() const noexcept
Definition: span.h:111
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
unsigned __int64 uint64_t
Definition: stdint.h:136
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
struct cryptonote::outkey outkey
void * memcpy(void *a, const void *b, size_t c)
key zeroCommit(etn_amount amount)
Definition: rctOps.cpp:322
virtual uint64_t get_num_outputs(const uint64_t &amount) const
fetches the number of outputs of a given amount
Definition: db_lmdb.cpp:3835
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
struct cryptonote::pre_rct_outkey pre_rct_outkey
Here is the call graph for this function:

◆ get_output_tx_and_index() [1/2]

tx_out_index cryptonote::BlockchainLMDB::get_output_tx_and_index ( const uint64_t amount,
const uint64_t index 
) const
virtual

gets an output's tx hash and index

The subclass should return the hash of the transaction which created the output with the amount and index given, as well as its index in that transaction.

Parameters
amountan output amount
indexan output's amount-specific index
Returns
the tx hash and output index

Implements cryptonote::BlockchainDB.

Definition at line 3916 of file db_lmdb.cpp.

3917 {
3918  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3919  std::vector < uint64_t > offsets;
3920  std::vector<tx_out_index> indices;
3921  offsets.push_back(index);
3922  get_output_tx_and_index(amount, offsets, indices);
3923  if (!indices.size())
3924  throw1(OUTPUT_DNE("Attempting to get an output index by amount and amount index, but amount not found"));
3925 
3926  return indices[0];
3927 }
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual tx_out_index get_output_tx_and_index(const uint64_t &amount, const uint64_t &index) const
gets an output&#39;s tx hash and index
Definition: db_lmdb.cpp:3916
Here is the caller graph for this function:

◆ get_output_tx_and_index() [2/2]

void cryptonote::BlockchainLMDB::get_output_tx_and_index ( const uint64_t amount,
const std::vector< uint64_t > &  offsets,
std::vector< tx_out_index > &  indices 
) const
virtual

gets some outputs' tx hashes and indices

This function is a mirror of get_output_tx_and_index(const uint64_t& amount, const uint64_t& index), but for a list of outputs rather than just one.

Parameters
amountan output amount
offsetsa list of amount-specific output indices
indicesreturn-by-reference a list of tx hashes and output indices (as pairs)

Implements cryptonote::BlockchainDB.

Definition at line 4615 of file db_lmdb.cpp.

4616 {
4617  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4618  check_open();
4619  indices.clear();
4620 
4621  std::vector <uint64_t> tx_indices;
4622  tx_indices.reserve(offsets.size());
4624 
4625  RCURSOR(output_amounts);
4626 
4627  MDB_val_set(k, amount);
4628  for (const uint64_t &index : offsets)
4629  {
4630  MDB_val_set(v, index);
4631 
4632  auto get_result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_GET_BOTH);
4633  if (get_result == MDB_NOTFOUND)
4634  throw1(OUTPUT_DNE("Attempting to get output by index, but key does not exist"));
4635  else if (get_result)
4636  throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output from the db", get_result).c_str()));
4637 
4638  const outkey *okp = (const outkey *)v.mv_data;
4639  tx_indices.push_back(okp->output_id);
4640  }
4641 
4642  TIME_MEASURE_START(db3);
4643  if(tx_indices.size() > 0)
4644  {
4645  get_output_tx_and_index_from_global(tx_indices, indices);
4646  }
4647  TIME_MEASURE_FINISH(db3);
4648  LOG_PRINT_L3("db3: " << db3);
4649 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
virtual tx_out_index get_output_tx_and_index_from_global(const uint64_t &index) const
gets an output&#39;s tx hash and index
Definition: db_lmdb.cpp:3893
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_output_amounts
Definition: db_lmdb.h:85
unsigned __int64 uint64_t
Definition: stdint.h:136
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
struct cryptonote::outkey outkey
Here is the call graph for this function:

◆ get_output_tx_and_index_from_global() [1/2]

tx_out_index cryptonote::BlockchainLMDB::get_output_tx_and_index_from_global ( const uint64_t index) const
virtual

gets an output's tx hash and index

The subclass should return the hash of the transaction which created the output with the global index given, as well as its index in that transaction.

Parameters
indexan output's global index
Returns
the tx hash and output index

Implements cryptonote::BlockchainDB.

Definition at line 3893 of file db_lmdb.cpp.

3894 {
3895  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3896  check_open();
3897 
3899  RCURSOR(output_txs);
3900 
3901  MDB_val_set(v, output_id);
3902 
3903  auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3904  if (get_result == MDB_NOTFOUND)
3905  throw1(OUTPUT_DNE("output with given index not in db"));
3906  else if (get_result)
3907  throw0(DB_ERROR("DB error attempting to fetch output tx hash"));
3908 
3909  outtx *ot = (outtx *)v.mv_data;
3910  tx_out_index ret = tx_out_index(ot->tx_hash, ot->local_index);
3911 
3913  return ret;
3914 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_output_txs
Definition: db_lmdb.h:84
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
struct cryptonote::outtx outtx
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
std::pair< crypto::hash, uint64_t > tx_out_index
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_output_tx_and_index_from_global() [2/2]

void cryptonote::BlockchainLMDB::get_output_tx_and_index_from_global ( const std::vector< uint64_t > &  global_indices,
std::vector< tx_out_index > &  tx_out_indices 
) const
virtual

Definition at line 4532 of file db_lmdb.cpp.

4534 {
4535  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4536  check_open();
4537  tx_out_indices.clear();
4538  tx_out_indices.reserve(global_indices.size());
4539 
4541  RCURSOR(output_txs);
4542 
4543  for (const uint64_t &output_id : global_indices)
4544  {
4545  MDB_val_set(v, output_id);
4546 
4547  auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
4548  if (get_result == MDB_NOTFOUND)
4549  throw1(OUTPUT_DNE("output with given index not in db"));
4550  else if (get_result)
4551  throw0(DB_ERROR("DB error attempting to fetch output tx hash"));
4552 
4553  const outtx *ot = (const outtx *)v.mv_data;
4554  tx_out_indices.push_back(tx_out_index(ot->tx_hash, ot->local_index));
4555  }
4556 
4558 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_output_txs
Definition: db_lmdb.h:84
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
struct cryptonote::outtx outtx
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
std::pair< crypto::hash, uint64_t > tx_out_index
Here is the call graph for this function:

◆ get_prunable_tx_blob()

bool cryptonote::BlockchainLMDB::get_prunable_tx_blob ( const crypto::hash h,
cryptonote::blobdata tx 
) const
virtual

fetches the prunable transaction blob with the given hash

The subclass should return the prunable transaction stored which has the given hash.

If the transaction does not exist, or if we do not have that prunable data, the subclass should return false.

Parameters
hthe hash to look for
Returns
true iff the transaction was found and we have its prunable data

Implements cryptonote::BlockchainDB.

Definition at line 3721 of file db_lmdb.cpp.

3722 {
3723  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3724  check_open();
3725 
3727  RCURSOR(tx_indices);
3728  RCURSOR(txs_prunable);
3729 
3730  MDB_val_set(v, h);
3731  MDB_val result;
3732  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3733  if (get_result == 0)
3734  {
3735  const txindex *tip = (const txindex *)v.mv_data;
3736  MDB_val_set(val_tx_id, tip->data.tx_id);
3737  get_result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, &result, MDB_SET);
3738  }
3739  if (get_result == MDB_NOTFOUND)
3740  return false;
3741  else if (get_result)
3742  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", get_result).c_str()));
3743 
3744  bd.assign(reinterpret_cast<char*>(result.mv_data), result.mv_size);
3745 
3747 
3748  return true;
3749 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
#define m_cur_txs_prunable
Definition: db_lmdb.h:88
Here is the call graph for this function:

◆ get_prunable_tx_hash()

bool cryptonote::BlockchainLMDB::get_prunable_tx_hash ( const crypto::hash tx_hash,
crypto::hash prunable_hash 
) const
virtual

fetches the prunable transaction hash

The subclass should return the hash of the prunable transaction data.

If the transaction hash does not exist, the subclass should return false.

Parameters
hthe tx hash to look for
Returns
true iff the transaction was found

Implements cryptonote::BlockchainDB.

Definition at line 3751 of file db_lmdb.cpp.

3752 {
3753  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3754  check_open();
3755 
3757  RCURSOR(tx_indices);
3758  RCURSOR(txs_prunable_hash);
3759 
3760  MDB_val_set(v, tx_hash);
3761  MDB_val result, val_tx_prunable_hash;
3762  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3763  if (get_result == 0)
3764  {
3765  txindex *tip = (txindex *)v.mv_data;
3766  MDB_val_set(val_tx_id, tip->data.tx_id);
3767  get_result = mdb_cursor_get(m_cur_txs_prunable_hash, &val_tx_id, &result, MDB_SET);
3768  }
3769  if (get_result == MDB_NOTFOUND)
3770  return false;
3771  else if (get_result)
3772  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx prunable hash from tx hash", get_result).c_str()));
3773 
3774  prunable_hash = *(const crypto::hash*)result.mv_data;
3775 
3777 
3778  return true;
3779 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define m_cur_txs_prunable_hash
Definition: db_lmdb.h:89
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
POD_CLASS hash
Definition: hash.h:50
#define m_cur_tx_indices
Definition: db_lmdb.h:91
Here is the call graph for this function:

◆ get_pruned_tx_blob()

bool cryptonote::BlockchainLMDB::get_pruned_tx_blob ( const crypto::hash h,
cryptonote::blobdata tx 
) const
virtual

fetches the pruned transaction blob with the given hash

The subclass should return the pruned transaction stored which has the given hash.

If the transaction does not exist, the subclass should return false.

Parameters
hthe hash to look for
Returns
true iff the transaction was found

Implements cryptonote::BlockchainDB.

Definition at line 3691 of file db_lmdb.cpp.

3692 {
3693  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3694  check_open();
3695 
3697  RCURSOR(tx_indices);
3698  RCURSOR(txs_pruned);
3699 
3700  MDB_val_set(v, h);
3701  MDB_val result;
3702  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3703  if (get_result == 0)
3704  {
3705  txindex *tip = (txindex *)v.mv_data;
3706  MDB_val_set(val_tx_id, tip->data.tx_id);
3707  get_result = mdb_cursor_get(m_cur_txs_pruned, &val_tx_id, &result, MDB_SET);
3708  }
3709  if (get_result == MDB_NOTFOUND)
3710  return false;
3711  else if (get_result)
3712  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", get_result).c_str()));
3713 
3714  bd.assign(reinterpret_cast<char*>(result.mv_data), result.mv_size);
3715 
3717 
3718  return true;
3719 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_txs_pruned
Definition: db_lmdb.h:87
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
Here is the call graph for this function:

◆ get_top_block()

block cryptonote::BlockchainLMDB::get_top_block ( ) const
virtual

fetch the top block

The subclass should return most recent block

Returns
the top block

Implements cryptonote::BlockchainDB.

Definition at line 3517 of file db_lmdb.cpp.

3518 {
3519  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3520  check_open();
3521  uint64_t m_height = height();
3522 
3523  if (m_height != 0)
3524  {
3525  return get_block_from_height(m_height - 1);
3526  }
3527 
3528  block b;
3529  return b;
3530 }
virtual block get_block_from_height(const uint64_t &height) const
fetch a block by height
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_top_block_timestamp()

uint64_t cryptonote::BlockchainLMDB::get_top_block_timestamp ( ) const
virtual

fetch the top block's timestamp

The subclass should return the timestamp of the most recent block.

Returns
the top block's timestamp

Implements cryptonote::BlockchainDB.

Definition at line 3173 of file db_lmdb.cpp.

3174 {
3175  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3176  check_open();
3177  uint64_t m_height = height();
3178 
3179  // if no blocks, return 0
3180  if (m_height == 0)
3181  {
3182  return 0;
3183  }
3184 
3185  return get_block_timestamp(m_height - 1);
3186 }
unsigned __int64 uint64_t
Definition: stdint.h:136
virtual uint64_t get_block_timestamp(const uint64_t &height) const
fetch a block&#39;s timestamp
Definition: db_lmdb.cpp:3088
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ get_tx_amount_output_indices()

std::vector< std::vector< uint64_t > > cryptonote::BlockchainLMDB::get_tx_amount_output_indices ( const uint64_t  tx_id,
size_t  n_txes 
) const
virtual

gets output indices (amount-specific) for a transaction's outputs

The subclass should fetch the amount-specific output indices for each output in the transaction with the given ID.

If the transaction does not exist, the subclass should throw TX_DNE.

If an output cannot be found, the subclass should throw OUTPUT_DNE.

Parameters
tx_ida transaction ID
n_txeshow many txes to get data for, starting with tx_id
Returns
a list of amount-specific output indices

Implements cryptonote::BlockchainDB.

Definition at line 3929 of file db_lmdb.cpp.

3930 {
3931  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3932 
3933  check_open();
3934 
3936  RCURSOR(tx_outputs);
3937 
3938  MDB_val_set(k_tx_id, tx_id);
3939  MDB_val v;
3940  std::vector<std::vector<uint64_t>> amount_output_indices_set;
3941  amount_output_indices_set.reserve(n_txes);
3942 
3943  MDB_cursor_op op = MDB_SET;
3944  while (n_txes-- > 0)
3945  {
3946  int result = mdb_cursor_get(m_cur_tx_outputs, &k_tx_id, &v, op);
3947  if (result == MDB_NOTFOUND)
3948  LOG_PRINT_L0("WARNING: Unexpected: tx has no amount indices stored in "
3949  "tx_outputs, but it should have an empty entry even if it's a tx without "
3950  "outputs");
3951  else if (result)
3952  throw0(DB_ERROR(lmdb_error("DB error attempting to get data for tx_outputs[tx_index]", result).c_str()));
3953 
3954  op = MDB_NEXT;
3955 
3956  const uint64_t* indices = (const uint64_t*)v.mv_data;
3957  size_t num_outputs = v.mv_size / sizeof(uint64_t);
3958 
3959  amount_output_indices_set.resize(amount_output_indices_set.size() + 1);
3960  std::vector<uint64_t> &amount_output_indices = amount_output_indices_set.back();
3961  amount_output_indices.reserve(num_outputs);
3962  for (size_t i = 0; i < num_outputs; ++i)
3963  {
3964  amount_output_indices.push_back(indices[i]);
3965  }
3966  }
3967 
3969  return amount_output_indices_set;
3970 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_tx_outputs
Definition: db_lmdb.h:92
Definition: lmdb.h:411
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define LOG_PRINT_L0(x)
Definition: misc_log_ex.h:99
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ get_tx_blob()

bool cryptonote::BlockchainLMDB::get_tx_blob ( const crypto::hash h,
cryptonote::blobdata tx 
) const
virtual

fetches the transaction blob with the given hash

The subclass should return the transaction stored which has the given hash.

If the transaction does not exist, the subclass should return false.

Parameters
hthe hash to look for
Returns
true iff the transaction was found

Implements cryptonote::BlockchainDB.

Definition at line 3655 of file db_lmdb.cpp.

3656 {
3657  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3658  check_open();
3659 
3661  RCURSOR(tx_indices);
3662  RCURSOR(txs_pruned);
3663  RCURSOR(txs_prunable);
3664 
3665  MDB_val_set(v, h);
3666  MDB_val result0, result1;
3667  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3668  if (get_result == 0)
3669  {
3670  txindex *tip = (txindex *)v.mv_data;
3671  MDB_val_set(val_tx_id, tip->data.tx_id);
3672  get_result = mdb_cursor_get(m_cur_txs_pruned, &val_tx_id, &result0, MDB_SET);
3673  if (get_result == 0)
3674  {
3675  get_result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, &result1, MDB_SET);
3676  }
3677  }
3678  if (get_result == MDB_NOTFOUND)
3679  return false;
3680  else if (get_result)
3681  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", get_result).c_str()));
3682 
3683  bd.assign(reinterpret_cast<char*>(result0.mv_data), result0.mv_size);
3684  bd.append(reinterpret_cast<char*>(result1.mv_data), result1.mv_size);
3685 
3687 
3688  return true;
3689 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define m_cur_txs_pruned
Definition: db_lmdb.h:87
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
#define m_cur_txs_prunable
Definition: db_lmdb.h:88
Here is the call graph for this function:

◆ get_tx_block_height()

uint64_t cryptonote::BlockchainLMDB::get_tx_block_height ( const crypto::hash h) const
virtual

fetches the height of a transaction's block

The subclass should attempt to return the height of the block containing the transaction with the given hash.

If the transaction cannot be found, the subclass should throw TX_DNE.

Parameters
hthe hash of the transaction
Returns
the height of the transaction's block

Implements cryptonote::BlockchainDB.

Definition at line 3812 of file db_lmdb.cpp.

3813 {
3814  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3815  check_open();
3816 
3818  RCURSOR(tx_indices);
3819 
3820  MDB_val_set(v, h);
3821  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3822  if (get_result == MDB_NOTFOUND)
3823  {
3824  throw1(TX_DNE(std::string("tx_data_t with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()));
3825  }
3826  else if (get_result)
3827  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx height from hash", get_result).c_str()));
3828 
3829  txindex *tip = (txindex *)v.mv_data;
3830  uint64_t ret = tip->data.block_id;
3832  return ret;
3833 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
tx_data_t data
Definition: db_lmdb.h:46
::std::string string
Definition: gtest-port.h:1097
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_tx_count()

uint64_t cryptonote::BlockchainLMDB::get_tx_count ( ) const
virtual

fetches the total number of transactions ever

The subclass should return a count of all the transactions from all blocks.

Returns
the number of transactions in the blockchain

Implements cryptonote::BlockchainDB.

Definition at line 3781 of file db_lmdb.cpp.

3782 {
3783  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3784  check_open();
3785 
3787  int result;
3788 
3789  MDB_stat db_stats;
3790  if ((result = mdb_stat(m_txn, m_txs_pruned, &db_stats)))
3791  throw0(DB_ERROR(lmdb_error("Failed to query m_txs_pruned: ", result).c_str()));
3792 
3794 
3795  return db_stats.ms_entries;
3796 }
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
Statistics for a database in the environment.
Definition: lmdb.h:490
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
mdb_size_t ms_entries
Definition: lmdb.h:497
Here is the call graph for this function:

◆ get_tx_input()

tx_input_t cryptonote::BlockchainLMDB::get_tx_input ( const crypto::hash  tx_hash,
const uint32_t  relative_out_index 
)
virtual

Implements cryptonote::BlockchainDB.

Definition at line 1973 of file db_lmdb.cpp.

1974 {
1975  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1976  check_open();
1977 
1978  std::string hex_hash;
1979  hex_hash = epee::string_tools::pod_to_hex(tx_hash);
1981  RCURSOR(tx_inputs)
1982 
1983  chainstate_key_t key;
1984  key.tx_hash = tx_hash;
1985  key.relative_out_index = relative_out_index;
1986 
1987  MDB_val k = {sizeof(key), (void *)&key};
1988  MDB_val v;
1989  auto result = mdb_cursor_get(m_cur_tx_inputs, &k, &v, MDB_SET_KEY);
1990  if (result == MDB_NOTFOUND)
1991  return tx_input_t();
1992  if (result != 0)
1993  throw1(DB_ERROR(lmdb_error("Error finding tx input: ", result).c_str()));
1994 
1996  return *(const tx_input_t *) v.mv_data;
1997 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_tx_inputs
Definition: db_lmdb.h:102
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
const char * key
Definition: hmac_keccak.cpp:39
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
void * mv_data
Definition: lmdb.h:288
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ get_tx_list()

std::vector< transaction > cryptonote::BlockchainLMDB::get_tx_list ( const std::vector< crypto::hash > &  hlist) const
virtual

fetches a list of transactions based on their hashes

The subclass should attempt to fetch each transaction referred to by the hashes passed.

Currently, if any of the transactions is not in BlockchainDB, the call to get_tx in the implementation will throw TX_DNE.

Parameters
hlista list of hashes
Returns
the list of transactions

Implements cryptonote::BlockchainDB.

Definition at line 3798 of file db_lmdb.cpp.

3799 {
3800  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3801  check_open();
3802  std::vector<transaction> v;
3803 
3804  for (auto& h : hlist)
3805  {
3806  v.push_back(get_tx(h));
3807  }
3808 
3809  return v;
3810 }
virtual transaction get_tx(const crypto::hash &h) const
fetches the transaction with the given hash
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:

◆ get_tx_unlock_time()

uint64_t cryptonote::BlockchainLMDB::get_tx_unlock_time ( const crypto::hash h) const
virtual

fetch a transaction's unlock time/height

The subclass should return the stored unlock time for the transaction with the given hash.

If no such transaction exists, the subclass should throw TX_DNE.

Parameters
hthe hash of the requested transaction
Returns
the unlock time/height

Implements cryptonote::BlockchainDB.

Definition at line 3634 of file db_lmdb.cpp.

3635 {
3636  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3637  check_open();
3638 
3640  RCURSOR(tx_indices);
3641 
3642  MDB_val_set(v, h);
3643  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3644  if (get_result == MDB_NOTFOUND)
3645  throw1(TX_DNE(lmdb_error(std::string("tx data with hash ") + epee::string_tools::pod_to_hex(h) + " not found in db: ", get_result).c_str()));
3646  else if (get_result)
3647  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx data from hash: ", get_result).c_str()));
3648 
3649  txindex *tip = (txindex *)v.mv_data;
3650  uint64_t ret = tip->data.unlock_time;
3652  return ret;
3653 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
tx_data_t data
Definition: db_lmdb.h:46
::std::string string
Definition: gtest-port.h:1097
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
Here is the call graph for this function:

◆ get_txpool_tx_blob() [1/2]

bool cryptonote::BlockchainLMDB::get_txpool_tx_blob ( const crypto::hash txid,
cryptonote::blobdata bd 
) const
virtual

get a txpool transaction's blob

Parameters
txidthe transaction id of the transation to lookup
bdthe blob to return
Returns
true if the txid was in the txpool, false otherwise

Implements cryptonote::BlockchainDB.

Definition at line 2579 of file db_lmdb.cpp.

2580 {
2581  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2582  check_open();
2583 
2585  RCURSOR(txpool_blob)
2586 
2587  MDB_val k = {sizeof(txid), (void *)&txid};
2588  MDB_val v;
2589  auto result = mdb_cursor_get(m_cur_txpool_blob, &k, &v, MDB_SET);
2590  if (result == MDB_NOTFOUND)
2591  return false;
2592  if (result != 0)
2593  throw1(DB_ERROR(lmdb_error("Error finding txpool tx blob: ", result).c_str()));
2594 
2595  bd.assign(reinterpret_cast<const char*>(v.mv_data), v.mv_size);
2597  return true;
2598 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define m_cur_txpool_blob
Definition: db_lmdb.h:95
void * mv_data
Definition: lmdb.h:288
size_t mv_size
Definition: lmdb.h:287
Definition: lmdb.h:422
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_txpool_tx_blob() [2/2]

cryptonote::blobdata cryptonote::BlockchainLMDB::get_txpool_tx_blob ( const crypto::hash txid) const
virtual

get a txpool transaction's blob

Parameters
txidthe transaction id of the transation to lookup
Returns
the blob for that transaction

Implements cryptonote::BlockchainDB.

Definition at line 2600 of file db_lmdb.cpp.

2601 {
2603  if (!get_txpool_tx_blob(txid, bd))
2604  throw1(DB_ERROR("Tx not found in txpool: "));
2605  return bd;
2606 }
virtual bool get_txpool_tx_blob(const crypto::hash &txid, cryptonote::blobdata &bd) const
get a txpool transaction&#39;s blob
Definition: db_lmdb.cpp:2579
std::string blobdata
Definition: blobdatatype.h:39
Here is the call graph for this function:

◆ get_txpool_tx_count()

uint64_t cryptonote::BlockchainLMDB::get_txpool_tx_count ( bool  include_unrelayed_txes = true) const
virtual

get the number of transactions in the txpool

Implements cryptonote::BlockchainDB.

Definition at line 2467 of file db_lmdb.cpp.

2468 {
2469  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2470  check_open();
2471 
2472  int result;
2473  uint64_t num_entries = 0;
2474 
2476 
2477  if (include_unrelayed_txes)
2478  {
2479  // No filtering, we can get the number of tx the "fast" way
2480  MDB_stat db_stats;
2481  if ((result = mdb_stat(m_txn, m_txpool_meta, &db_stats)))
2482  throw0(DB_ERROR(lmdb_error("Failed to query m_txpool_meta: ", result).c_str()));
2483  num_entries = db_stats.ms_entries;
2484  }
2485  else
2486  {
2487  // Filter unrelayed tx out of the result, so we need to loop over transactions and check their meta data
2488  RCURSOR(txpool_meta);
2489  RCURSOR(txpool_blob);
2490 
2491  MDB_val k;
2492  MDB_val v;
2493  MDB_cursor_op op = MDB_FIRST;
2494  while (1)
2495  {
2496  result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, op);
2497  op = MDB_NEXT;
2498  if (result == MDB_NOTFOUND)
2499  break;
2500  if (result)
2501  throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str()));
2502  const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
2503  if (!meta.do_not_relay)
2504  ++num_entries;
2505  }
2506  }
2508 
2509  return num_entries;
2510 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
Definition: lmdb.h:411
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
Statistics for a database in the environment.
Definition: lmdb.h:490
void * mv_data
Definition: lmdb.h:288
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
else if(0==res)
mdb_size_t ms_entries
Definition: lmdb.h:497
Here is the call graph for this function:

◆ get_txpool_tx_meta()

bool cryptonote::BlockchainLMDB::get_txpool_tx_meta ( const crypto::hash txid,
txpool_tx_meta_t meta 
) const
virtual

get a txpool transaction's metadata

Parameters
txidthe transaction id of the transation to lookup
metathe metadata to return
Returns
true if the tx meta was found, false otherwise

Implements cryptonote::BlockchainDB.

Definition at line 2558 of file db_lmdb.cpp.

2559 {
2560  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2561  check_open();
2562 
2564  RCURSOR(txpool_meta)
2565 
2566  MDB_val k = {sizeof(txid), (void *)&txid};
2567  MDB_val v;
2568  auto result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, MDB_SET);
2569  if (result == MDB_NOTFOUND)
2570  return false;
2571  if (result != 0)
2572  throw1(DB_ERROR(lmdb_error("Error finding txpool tx meta: ", result).c_str()));
2573 
2574  meta = *(const txpool_tx_meta_t*)v.mv_data;
2576  return true;
2577 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
void * mv_data
Definition: lmdb.h:288
Definition: lmdb.h:422
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ has_key_image()

bool cryptonote::BlockchainLMDB::has_key_image ( const crypto::key_image img) const
virtual

check if a key image is stored as spent

Parameters
imgthe key image to check for
Returns
true if the image is present, otherwise false

Implements cryptonote::BlockchainDB.

Definition at line 3972 of file db_lmdb.cpp.

3973 {
3974  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3975  check_open();
3976 
3977  bool ret;
3978 
3980  RCURSOR(spent_keys);
3981 
3982  MDB_val k = {sizeof(img), (void *)&img};
3983  ret = (mdb_cursor_get(m_cur_spent_keys, (MDB_val *)&zerokval, &k, MDB_GET_BOTH) == 0);
3984 
3986  return ret;
3987 }
#define m_cur_spent_keys
Definition: db_lmdb.h:93
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ height()

uint64_t cryptonote::BlockchainLMDB::height ( ) const
virtual

fetch the current blockchain height

The subclass should return the current blockchain height

Returns
the current blockchain height

Implements cryptonote::BlockchainDB.

Definition at line 3532 of file db_lmdb.cpp.

3533 {
3534  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3535  check_open();
3537  int result;
3538 
3539  // get current height
3540  MDB_stat db_stats;
3541  if ((result = mdb_stat(m_txn, m_blocks, &db_stats)))
3542  throw0(DB_ERROR(lmdb_error("Failed to query m_blocks: ", result).c_str()));
3543  return db_stats.ms_entries;
3544 }
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
Statistics for a database in the environment.
Definition: lmdb.h:490
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
mdb_size_t ms_entries
Definition: lmdb.h:497
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lock()

bool cryptonote::BlockchainLMDB::lock ( )
virtual

acquires the BlockchainDB lock

This function is a stub until such a time as locking is implemented at this level.

The subclass implementation should return true unless implementing a locking scheme of some sort, in which case it should return true upon acquisition of the lock and block until then.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Returns
true, unless at a future time false makes sense (timeout, etc)

Implements cryptonote::BlockchainDB.

Definition at line 1763 of file db_lmdb.cpp.

1764 {
1765  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1766  check_open();
1767  return false;
1768 }
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102

◆ open()

void cryptonote::BlockchainLMDB::open ( const std::string &  filename,
const int  db_flags = 0 
)
virtual

open a db, or create it if necessary.

This function opens an existing database or creates it if it does not exist.

The subclass implementing this will handle all file opening/creation, and is responsible for maintaining its state.

The parameter <filename> may not refer to a file name, necessarily, but could be an IP:PORT for a database which needs it, and so on. Calling it <filename> is convenient and should be descriptive enough, however.

For now, db_flags are specific to the subclass being instantiated. This is subject to change, and the db_flags parameter may be deprecated.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Parameters
filenamea string referring to the BlockchainDB to open
db_flagsflags relevant to how to open/use the BlockchainDB

Implements cryptonote::BlockchainDB.

Definition at line 1357 of file db_lmdb.cpp.

1358 {
1359  int result;
1360  int mdb_flags = MDB_NORDAHEAD;
1361 
1362  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1363 
1364  if (m_open)
1365  throw0(DB_OPEN_FAILURE("Attempted to open db, but it's already open"));
1366 
1367  boost::filesystem::path direc(filename);
1368  if (boost::filesystem::exists(direc))
1369  {
1370  if (!boost::filesystem::is_directory(direc))
1371  throw0(DB_OPEN_FAILURE("LMDB needs a directory path, but a file was passed"));
1372  }
1373  else
1374  {
1375  if (!boost::filesystem::create_directories(direc))
1376  throw0(DB_OPEN_FAILURE(std::string("Failed to create directory ").append(filename).c_str()));
1377  }
1378 
1379  // check for existing LMDB files in base directory
1380  boost::filesystem::path old_files = direc.parent_path();
1381  if (boost::filesystem::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_FILENAME)
1382  || boost::filesystem::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME))
1383  {
1384  LOG_PRINT_L0("Found existing LMDB files in " << old_files.string());
1385  LOG_PRINT_L0("Move " << CRYPTONOTE_BLOCKCHAINDATA_FILENAME << " and/or " << CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME << " to " << filename << ", or delete them, and then restart");
1386  throw DB_ERROR("Database could not be opened");
1387  }
1388 
1389  boost::optional<bool> is_hdd_result = tools::is_hdd(filename.c_str());
1390  if (is_hdd_result)
1391  {
1392  if (is_hdd_result.value())
1393  MCLOG_RED(el::Level::Warning, "global", "The blockchain is on a rotating drive: this will be very slow, use an SSD if possible");
1394  }
1395 
1396  m_folder = filename;
1397 
1398 #ifdef __OpenBSD__
1399  if ((mdb_flags & MDB_WRITEMAP) == 0) {
1400  MCLOG_RED(el::Level::Info, "global", "Running on OpenBSD: forcing WRITEMAP");
1401  mdb_flags |= MDB_WRITEMAP;
1402  }
1403 #endif
1404  // set up lmdb environment
1405  if ((result = mdb_env_create(&m_env)))
1406  throw0(DB_ERROR(lmdb_error("Failed to create lmdb environment: ", result).c_str()));
1407  if ((result = mdb_env_set_maxdbs(m_env, 26)))
1408  throw0(DB_ERROR(lmdb_error("Failed to set max number of dbs: ", result).c_str()));
1409 
1410  int threads = tools::get_max_concurrency();
1411  if (threads > 110 && /* maxreaders default is 126, leave some slots for other read processes */
1412  (result = mdb_env_set_maxreaders(m_env, threads+16)))
1413  throw0(DB_ERROR(lmdb_error("Failed to set max number of readers: ", result).c_str()));
1414 
1415  size_t mapsize = DEFAULT_MAPSIZE;
1416 
1417  if (db_flags & DBF_FAST)
1418  mdb_flags |= MDB_NOSYNC;
1419  if (db_flags & DBF_FASTEST)
1420  mdb_flags |= MDB_NOSYNC | MDB_WRITEMAP | MDB_MAPASYNC;
1421  if (db_flags & DBF_RDONLY)
1422  mdb_flags = MDB_RDONLY;
1423  if (db_flags & DBF_SALVAGE)
1424  mdb_flags |= MDB_PREVSNAPSHOT;
1425 
1426  if (auto result = mdb_env_open(m_env, filename.c_str(), mdb_flags, 0644))
1427  throw0(DB_ERROR(lmdb_error("Failed to open lmdb environment: ", result).c_str()));
1428 
1429  MDB_envinfo mei;
1430  mdb_env_info(m_env, &mei);
1431  uint64_t cur_mapsize = (uint64_t)mei.me_mapsize;
1432 
1433  if (cur_mapsize < mapsize)
1434  {
1435  if (auto result = mdb_env_set_mapsize(m_env, mapsize))
1436  throw0(DB_ERROR(lmdb_error("Failed to set max memory map size: ", result).c_str()));
1437  mdb_env_info(m_env, &mei);
1438  cur_mapsize = (uint64_t)mei.me_mapsize;
1439  LOG_PRINT_L1("LMDB memory map size: " << cur_mapsize);
1440  }
1441 
1442  if (need_resize())
1443  {
1444  LOG_PRINT_L0("LMDB memory map needs to be resized, doing that now.");
1445  do_resize();
1446  }
1447 
1448  int txn_flags = 0;
1449  if (mdb_flags & MDB_RDONLY)
1450  txn_flags |= MDB_RDONLY;
1451 
1452  // get a read/write MDB_txn, depending on mdb_flags
1453  mdb_txn_safe txn;
1454  if (auto mdb_res = mdb_txn_begin(m_env, NULL, txn_flags, txn))
1455  throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", mdb_res).c_str()));
1456 
1457  // open necessary databases, and set properties as needed
1458  // uses macros to avoid having to change things too many places
1459  // also change blockchain_prune.cpp to match
1460  lmdb_db_open(txn, LMDB_BLOCKS, MDB_INTEGERKEY | MDB_CREATE, m_blocks, "Failed to open db handle for m_blocks");
1461 
1462  lmdb_db_open(txn, LMDB_BLOCK_INFO, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for m_block_info");
1463  lmdb_db_open(txn, LMDB_BLOCK_HEIGHTS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_heights, "Failed to open db handle for m_block_heights");
1464 
1465  lmdb_db_open(txn, LMDB_TXS, MDB_INTEGERKEY | MDB_CREATE, m_txs, "Failed to open db handle for m_txs");
1466  lmdb_db_open(txn, LMDB_TXS_PRUNED, MDB_INTEGERKEY | MDB_CREATE, m_txs_pruned, "Failed to open db handle for m_txs_pruned");
1467  lmdb_db_open(txn, LMDB_TXS_PRUNABLE, MDB_INTEGERKEY | MDB_CREATE, m_txs_prunable, "Failed to open db handle for m_txs_prunable");
1468  lmdb_db_open(txn, LMDB_TXS_PRUNABLE_HASH, MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_CREATE, m_txs_prunable_hash, "Failed to open db handle for m_txs_prunable_hash");
1469  if (!(mdb_flags & MDB_RDONLY))
1470  lmdb_db_open(txn, LMDB_TXS_PRUNABLE_TIP, MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_CREATE, m_txs_prunable_tip, "Failed to open db handle for m_txs_prunable_tip");
1471  lmdb_db_open(txn, LMDB_TX_INDICES, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_tx_indices, "Failed to open db handle for m_tx_indices");
1472  lmdb_db_open(txn, LMDB_TX_OUTPUTS, MDB_INTEGERKEY | MDB_CREATE, m_tx_outputs, "Failed to open db handle for m_tx_outputs");
1473 
1474  lmdb_db_open(txn, LMDB_OUTPUT_TXS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_output_txs, "Failed to open db handle for m_output_txs");
1475  lmdb_db_open(txn, LMDB_OUTPUT_AMOUNTS, MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_CREATE, m_output_amounts, "Failed to open db handle for m_output_amounts");
1476 
1477  lmdb_db_open(txn, LMDB_SPENT_KEYS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_spent_keys, "Failed to open db handle for m_spent_keys");
1478 
1479  lmdb_db_open(txn, LMDB_TXPOOL_META, MDB_CREATE, m_txpool_meta, "Failed to open db handle for m_txpool_meta");
1480  lmdb_db_open(txn, LMDB_TXPOOL_BLOB, MDB_CREATE, m_txpool_blob, "Failed to open db handle for m_txpool_blob");
1481 
1482  // this subdb is dropped on sight, so it may not be present when we open the DB.
1483  // Since we use MDB_CREATE, we'll get an exception if we open read-only and it does not exist.
1484  // So we don't open for read-only, and also not drop below. It is not used elsewhere.
1485  if (!(mdb_flags & MDB_RDONLY))
1486  lmdb_db_open(txn, LMDB_HF_STARTING_HEIGHTS, MDB_CREATE, m_hf_starting_heights, "Failed to open db handle for m_hf_starting_heights");
1487 
1488  lmdb_db_open(txn, LMDB_HF_VERSIONS, MDB_INTEGERKEY | MDB_CREATE, m_hf_versions, "Failed to open db handle for m_hf_versions");
1489 
1490  lmdb_db_open(txn, LMDB_VALIDATORS, MDB_INTEGERKEY | MDB_CREATE, m_validators, "Failed to open db handle for m_validators");
1491  lmdb_db_open(txn, LMDB_UTXOS, MDB_CREATE, m_utxos, "Failed to open db handle for m_utxos");
1492  lmdb_db_open(txn, LMDB_ADDR_OUTPUTS, MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_addr_outputs, "Failed to open db handle for m_addr_outputs");
1493  lmdb_db_open(txn, LMDB_ADDR_TXS, MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_addr_txs, "Failed to open db handle for m_addr_txs");
1494  lmdb_db_open(txn, LMDB_ADDR_TXS_OLD, MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_addr_txs_old, "Failed to open db handle for m_addr_txs_old");
1495  if(db_flags & DBF_ADDR_TX_SALVAGE) {
1496  mdb_drop(txn, m_addr_txs, 0);
1497  mdb_drop(txn, m_addr_txs_old, 1);
1498  }
1499  lmdb_db_open(txn, LMDB_TX_INPUTS, MDB_CREATE, m_tx_inputs, "Failed to open db handle for m_tx_inputs");
1500  lmdb_db_open(txn, LMDB_PROPERTIES, MDB_CREATE, m_properties, "Failed to open db handle for m_properties");
1501 
1502  mdb_set_dupsort(txn, m_spent_keys, compare_hash32);
1503  mdb_set_dupsort(txn, m_block_heights, compare_hash32);
1504  mdb_set_dupsort(txn, m_tx_indices, compare_hash32);
1505  mdb_set_dupsort(txn, m_output_amounts, compare_uint64);
1506  mdb_set_dupsort(txn, m_output_txs, compare_uint64);
1507  mdb_set_dupsort(txn, m_block_info, compare_uint64);
1508  if (!(mdb_flags & MDB_RDONLY))
1509  mdb_set_dupsort(txn, m_txs_prunable_tip, compare_uint64);
1510  mdb_set_compare(txn, m_txs_prunable, compare_uint64);
1511  mdb_set_dupsort(txn, m_txs_prunable_hash, compare_uint64);
1512 
1513  mdb_set_compare(txn, m_utxos, compare_data);
1514  mdb_set_compare(txn, m_txpool_meta, compare_hash32);
1515  mdb_set_compare(txn, m_txpool_blob, compare_hash32);
1516  mdb_set_compare(txn, m_properties, compare_string);
1517 
1518  mdb_set_dupsort(txn, m_addr_outputs, compare_uint64);
1519  mdb_set_compare(txn, m_addr_outputs, compare_publickey);
1520 
1521  mdb_set_dupsort(txn, m_addr_txs, compare_uint64);
1522  mdb_set_compare(txn, m_addr_txs, compare_publickey);
1523 
1524  mdb_set_dupsort(txn, m_addr_txs_old, compare_uint64);
1525  mdb_set_compare(txn, m_addr_txs_old, compare_publickey);
1526 
1527  mdb_set_compare(txn, m_tx_inputs, compare_data);
1528 
1529 
1530  if (!(mdb_flags & MDB_RDONLY))
1531  {
1532  result = mdb_drop(txn, m_hf_starting_heights, 1);
1533  if (result && result != MDB_NOTFOUND)
1534  throw0(DB_ERROR(lmdb_error("Failed to drop m_hf_starting_heights: ", result).c_str()));
1535  }
1536 
1537  // get and keep current height
1538  MDB_stat db_stats;
1539  if ((result = mdb_stat(txn, m_blocks, &db_stats)))
1540  throw0(DB_ERROR(lmdb_error("Failed to query m_blocks: ", result).c_str()));
1541  LOG_PRINT_L2("Setting m_height to: " << db_stats.ms_entries);
1542  uint64_t m_height = db_stats.ms_entries;
1543 
1544  bool compatible = true;
1545 
1546  MDB_val_str(k, "version");
1547  MDB_val v;
1548  auto get_result = mdb_get(txn, m_properties, &k, &v);
1549  if(get_result == MDB_SUCCESS)
1550  {
1551  const uint32_t db_version = *(const uint32_t*)v.mv_data;
1552  if (db_version > VERSION)
1553  {
1554  MWARNING("Existing lmdb database was made by a later version (" << db_version << "). We don't know how it will change yet.");
1555  compatible = false;
1556  }
1557 #if VERSION > 0
1558  else if (db_version < VERSION)
1559  {
1560  if (mdb_flags & MDB_RDONLY)
1561  {
1562  txn.abort();
1563  mdb_env_close(m_env);
1564  m_open = false;
1565  MFATAL("Existing lmdb database needs to be converted, which cannot be done on a read-only database.");
1566  MFATAL("Please run electroneumd once to convert the database.");
1567  return;
1568  }
1569  // Note that there was a schema change within version 0 as well.
1570  // See commit e5d2680094ee15889934fe28901e4e133cda56f2 2015/07/10
1571  // We don't handle the old format previous to that commit.
1572  txn.commit();
1573  m_open = true;
1574  migrate(db_version);
1575  return;
1576  }
1577 #endif
1578  }
1579  else
1580  {
1581  // if not found, and the DB is non-empty, this is probably
1582  // an "old" version 0, which we don't handle. If the DB is
1583  // empty it's fine.
1584  if (VERSION > 0 && m_height > 0)
1585  compatible = false;
1586  }
1587 
1588  if (!compatible)
1589  {
1590  txn.abort();
1591  mdb_env_close(m_env);
1592  m_open = false;
1593  MFATAL("Existing lmdb database is incompatible with this version.");
1594  MFATAL("Please delete the existing database and resync.");
1595  return;
1596  }
1597 
1598  if (!(mdb_flags & MDB_RDONLY))
1599  {
1600  // only write version on an empty DB
1601  if (m_height == 0)
1602  {
1603  MDB_val_str(k, "version");
1604  MDB_val_copy<uint32_t> v(VERSION);
1605  auto put_result = mdb_put(txn, m_properties, &k, &v, 0);
1606  if (put_result != MDB_SUCCESS)
1607  {
1608  txn.abort();
1609  mdb_env_close(m_env);
1610  m_open = false;
1611  MERROR("Failed to write version to database.");
1612  return;
1613  }
1614  }
1615  }
1616 
1617  // commit the transaction
1618  txn.commit();
1619 
1620  m_open = true;
1621  // from here, init should be finished
1622 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define MERROR(x)
Definition: misc_log_ex.h:73
#define MDB_PREVSNAPSHOT
Definition: lmdb.h:336
#define LOG_PRINT_L2(x)
Definition: misc_log_ex.h:101
int mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
Set the size of the memory map to use for this environment.
#define MDB_RDONLY
Definition: lmdb.h:320
#define DBF_RDONLY
#define CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME
#define LOG_PRINT_L1(x)
Definition: misc_log_ex.h:100
#define DBF_SALVAGE
static int compare_hash32(const MDB_val *a, const MDB_val *b)
Definition: db_lmdb.cpp:151
#define MFATAL(x)
Definition: misc_log_ex.h:72
::std::string string
Definition: gtest-port.h:1097
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
#define DBF_FASTEST
int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom data comparison function for a MDB_DUPSORT database.
#define MCLOG_RED(level, cat, x)
Definition: misc_log_ex.h:58
#define LOG_PRINT_L0(x)
Definition: misc_log_ex.h:99
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
Set the maximum number of named databases for the environment.
#define CRYPTONOTE_BLOCKCHAINDATA_FILENAME
static int compare_data(const MDB_val *a, const MDB_val *b)
Definition: db_lmdb.cpp:172
#define DBF_FAST
#define MDB_MAPASYNC
Definition: lmdb.h:326
#define MDB_CREATE
Definition: lmdb.h:357
unsigned get_max_concurrency()
Definition: util.cpp:868
int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
Empty or delete+close a database.
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
Open an environment handle.
Statistics for a database in the environment.
Definition: lmdb.h:490
Information about the environment.
Definition: lmdb.h:501
void * mv_data
Definition: lmdb.h:288
#define MDB_SUCCESS
Definition: lmdb.h:435
unsigned int uint32_t
Definition: stdint.h:126
#define MDB_WRITEMAP
Definition: lmdb.h:324
static int compare_uint64(const MDB_val *a, const MDB_val *b)
Definition: db_lmdb.cpp:143
unsigned __int64 uint64_t
Definition: stdint.h:136
#define MDB_INTEGERKEY
Definition: lmdb.h:349
#define MDB_DUPFIXED
Definition: lmdb.h:351
int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom key comparison function for a database.
bool m_open
Whether or not the BlockchainDB is open/ready for use.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Create a transaction for use with the environment.
Useful when application has potentially harmful situtaions.
#define MWARNING(x)
Definition: misc_log_ex.h:74
int mdb_env_create(MDB_env **env)
Create an LMDB environment handle.
Mainly useful to represent current progress of application.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
static int compare_publickey(const MDB_val *a, const MDB_val *b)
Definition: db_lmdb.cpp:188
#define VERSION
Definition: db_lmdb.cpp:60
int mdb_env_set_maxreaders(MDB_env *env, unsigned int readers)
Set the maximum number of threads/reader slots for the environment.
mdb_size_t me_mapsize
Definition: lmdb.h:503
#define MDB_val_str(var, val)
Definition: db_lmdb.cpp:93
else if(0==res)
#define MDB_DUPSORT
Definition: lmdb.h:345
mdb_size_t ms_entries
Definition: lmdb.h:497
#define DBF_ADDR_TX_SALVAGE
int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Get items from a database.
#define MDB_NOSYNC
Definition: lmdb.h:318
#define MDB_NORDAHEAD
Definition: lmdb.h:332
int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags)
Store items into a database.
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
static int compare_string(const MDB_val *a, const MDB_val *b)
Definition: db_lmdb.cpp:165
boost::optional< bool > is_hdd(const char *file_path)
Definition: util.cpp:813

◆ pop_block()

void cryptonote::BlockchainLMDB::pop_block ( block blk,
std::vector< transaction > &  txs 
)
virtual

pops the top block off the blockchain

The subclass should remove the most recent block from the blockchain, along with all transactions, outputs, and other metadata created as a result of its addition to the blockchain. Most of this is handled by the concrete members of the base class provided the subclass correctly implements remove_* functions.

The subclass should return by reference the popped block and its associated transactions

Parameters
blkreturn-by-reference the block which was popped
txsreturn-by-reference the transactions from the popped block

Reimplemented from cryptonote::BlockchainDB.

Definition at line 4513 of file db_lmdb.cpp.

4514 {
4515  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4516  check_open();
4517 
4518  block_wtxn_start();
4519 
4520  try
4521  {
4522  BlockchainDB::pop_block(blk, txs);
4523  block_wtxn_stop();
4524  }
4525  catch (...)
4526  {
4527  block_wtxn_abort();
4528  throw;
4529  }
4530 }
virtual void block_wtxn_start()
Definition: db_lmdb.cpp:4406
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual void block_wtxn_stop()
Definition: db_lmdb.cpp:4439
virtual void block_wtxn_abort()
Definition: db_lmdb.cpp:4461
Here is the call graph for this function:

◆ prune_blockchain()

bool cryptonote::BlockchainLMDB::prune_blockchain ( uint32_t  pruning_seed = 0)
virtual

prunes the blockchain

Parameters
pruning_seedthe seed to use, 0 for default (highly recommended)
Returns
success iff true

Implements cryptonote::BlockchainDB.

Definition at line 2926 of file db_lmdb.cpp.

2927 {
2928  return prune_worker(prune_mode_prune, pruning_seed);
2929 }

◆ remove_data_file()

bool cryptonote::BlockchainLMDB::remove_data_file ( const std::string &  folder) const
virtual

remove file(s) storing the database

This function is for resetting the database (for core tests, functional tests, etc). The function reset() is not usable because it needs to open the database file first which can fail if the existing database file is in an incompatible format. As such, this function needs to be called before calling open().

Parameters
folderThe path of the folder containing the database file(s) which must not end with slash '/'.
Returns
true if the operation is succesfull

Implements cryptonote::BlockchainDB.

Definition at line 1740 of file db_lmdb.cpp.

1741 {
1742  const std::string filename = folder + "/data.mdb";
1743  try
1744  {
1745  boost::filesystem::remove(filename);
1746  }
1747  catch (const std::exception &e)
1748  {
1749  MERROR("Failed to remove " << filename << ": " << e.what());
1750  return false;
1751  }
1752  return true;
1753 }
#define MERROR(x)
Definition: misc_log_ex.h:73
::std::string string
Definition: gtest-port.h:1097

◆ remove_txpool_tx()

void cryptonote::BlockchainLMDB::remove_txpool_tx ( const crypto::hash txid)
virtual

remove a txpool transaction

Parameters
txidthe transaction id of the transation to remove

Implements cryptonote::BlockchainDB.

Definition at line 2528 of file db_lmdb.cpp.

2529 {
2530  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2531  check_open();
2532  mdb_txn_cursors *m_cursors = &m_wcursors;
2533 
2534  CURSOR(txpool_meta)
2535  CURSOR(txpool_blob)
2536 
2537  MDB_val k = {sizeof(txid), (void *)&txid};
2538  auto result = mdb_cursor_get(m_cur_txpool_meta, &k, NULL, MDB_SET);
2539  if (result != 0 && result != MDB_NOTFOUND)
2540  throw1(DB_ERROR(lmdb_error("Error finding txpool tx meta to remove: ", result).c_str()));
2541  if (!result)
2542  {
2543  result = mdb_cursor_del(m_cur_txpool_meta, 0);
2544  if (result)
2545  throw1(DB_ERROR(lmdb_error("Error adding removal of txpool tx metadata to db transaction: ", result).c_str()));
2546  }
2547  result = mdb_cursor_get(m_cur_txpool_blob, &k, NULL, MDB_SET);
2548  if (result != 0 && result != MDB_NOTFOUND)
2549  throw1(DB_ERROR(lmdb_error("Error finding txpool tx blob to remove: ", result).c_str()));
2550  if (!result)
2551  {
2552  result = mdb_cursor_del(m_cur_txpool_blob, 0);
2553  if (result)
2554  throw1(DB_ERROR(lmdb_error("Error adding removal of txpool tx blob to db transaction: ", result).c_str()));
2555  }
2556 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define m_cur_txpool_blob
Definition: db_lmdb.h:95
Definition: lmdb.h:422
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
int mdb_cursor_del(MDB_cursor *cursor, unsigned int flags)
Delete current key/data pair.
struct cryptonote::mdb_txn_cursors mdb_txn_cursors
#define CURSOR(name)
Definition: db_lmdb.cpp:285
Here is the call graph for this function:

◆ reset()

void cryptonote::BlockchainLMDB::reset ( )
virtual

Remove everything from the BlockchainDB.

This function should completely remove all data from a BlockchainDB.

Use with caution!

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Implements cryptonote::BlockchainDB.

Definition at line 1662 of file db_lmdb.cpp.

1663 {
1664  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1665  check_open();
1666 
1667  mdb_txn_safe txn;
1668  if (auto result = lmdb_txn_begin(m_env, NULL, 0, txn))
1669  throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
1670 
1671  if (auto result = mdb_drop(txn, m_blocks, 0))
1672  throw0(DB_ERROR(lmdb_error("Failed to drop m_blocks: ", result).c_str()));
1673  if (auto result = mdb_drop(txn, m_block_info, 0))
1674  throw0(DB_ERROR(lmdb_error("Failed to drop m_block_info: ", result).c_str()));
1675  if (auto result = mdb_drop(txn, m_block_heights, 0))
1676  throw0(DB_ERROR(lmdb_error("Failed to drop m_block_heights: ", result).c_str()));
1677  if (auto result = mdb_drop(txn, m_txs_pruned, 0))
1678  throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_pruned: ", result).c_str()));
1679  if (auto result = mdb_drop(txn, m_txs_prunable, 0))
1680  throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_prunable: ", result).c_str()));
1681  if (auto result = mdb_drop(txn, m_txs_prunable_hash, 0))
1682  throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_prunable_hash: ", result).c_str()));
1683  if (auto result = mdb_drop(txn, m_txs_prunable_tip, 0))
1684  throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_prunable_tip: ", result).c_str()));
1685  if (auto result = mdb_drop(txn, m_tx_indices, 0))
1686  throw0(DB_ERROR(lmdb_error("Failed to drop m_tx_indices: ", result).c_str()));
1687  if (auto result = mdb_drop(txn, m_tx_outputs, 0))
1688  throw0(DB_ERROR(lmdb_error("Failed to drop m_tx_outputs: ", result).c_str()));
1689  if (auto result = mdb_drop(txn, m_output_txs, 0))
1690  throw0(DB_ERROR(lmdb_error("Failed to drop m_output_txs: ", result).c_str()));
1691  if (auto result = mdb_drop(txn, m_output_amounts, 0))
1692  throw0(DB_ERROR(lmdb_error("Failed to drop m_output_amounts: ", result).c_str()));
1693  if (auto result = mdb_drop(txn, m_spent_keys, 0))
1694  throw0(DB_ERROR(lmdb_error("Failed to drop m_spent_keys: ", result).c_str()));
1695  (void)mdb_drop(txn, m_hf_starting_heights, 0); // this one is dropped in new code
1696  if (auto result = mdb_drop(txn, m_hf_versions, 0))
1697  throw0(DB_ERROR(lmdb_error("Failed to drop m_hf_versions: ", result).c_str()));
1698  if (auto result = mdb_drop(txn, m_validators, 0))
1699  throw0(DB_ERROR(lmdb_error("Failed to drop m_validators: ", result).c_str()));
1700  if (auto result = mdb_drop(txn, m_utxos, 0))
1701  throw0(DB_ERROR(lmdb_error("Failed to drop m_utxos: ", result).c_str()));
1702  if (auto result = mdb_drop(txn, m_addr_outputs, 0))
1703  throw0(DB_ERROR(lmdb_error("Failed to drop m_addr_outputs: ", result).c_str()));
1704  if (auto result = mdb_drop(txn, m_addr_txs, 0))
1705  throw0(DB_ERROR(lmdb_error("Failed to drop m_addr_txs: ", result).c_str()));
1706  if (auto result = mdb_drop(txn, m_addr_txs_old, 0))
1707  throw0(DB_ERROR(lmdb_error("Failed to drop m_addr_txs_old: ", result).c_str()));
1708  if (auto result = mdb_drop(txn, m_tx_inputs, 0))
1709  throw0(DB_ERROR(lmdb_error("Failed to drop m_tx_inputs: ", result).c_str()));
1710  if (auto result = mdb_drop(txn, m_properties, 0))
1711  throw0(DB_ERROR(lmdb_error("Failed to drop m_properties: ", result).c_str()));
1712 
1713  // init with current version
1714  MDB_val_str(k, "version");
1715  MDB_val_copy<uint32_t> v(VERSION);
1716  if (auto result = mdb_put(txn, m_properties, &k, &v, 0))
1717  throw0(DB_ERROR(lmdb_error("Failed to write version to database: ", result).c_str()));
1718 
1719  txn.commit();
1720  m_cum_size = 0;
1721  m_cum_count = 0;
1722 }
int lmdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: db_lmdb.cpp:527
int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
Empty or delete+close a database.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define VERSION
Definition: db_lmdb.cpp:60
#define MDB_val_str(var, val)
Definition: db_lmdb.cpp:93
int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags)
Store items into a database.
Here is the call graph for this function:

◆ safesyncmode()

void cryptonote::BlockchainLMDB::safesyncmode ( const bool  onoff)
virtual

toggle safe syncs for the DB

Used to switch DBF_SAFE on or off after starting up with DBF_FAST.

Implements cryptonote::BlockchainDB.

Definition at line 1656 of file db_lmdb.cpp.

1657 {
1658  MINFO("switching safe mode " << (onoff ? "on" : "off"));
1659  mdb_env_set_flags(m_env, MDB_NOSYNC|MDB_MAPASYNC, !onoff);
1660 }
#define MINFO(x)
Definition: misc_log_ex.h:75
#define MDB_MAPASYNC
Definition: lmdb.h:326
int mdb_env_set_flags(MDB_env *env, unsigned int flags, int onoff)
Set environment flags.
#define MDB_NOSYNC
Definition: lmdb.h:318
Here is the call graph for this function:

◆ set_batch_transactions()

void cryptonote::BlockchainLMDB::set_batch_transactions ( bool  )
virtual

sets whether or not to batch transactions

If the subclass implements batching, this function tells it to begin batching automatically.

If the subclass implements batching and has a batch in-progress, a parameter of false should disable batching and call batch_stop() to store the current batch.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Parameters
boolbatch whether or not to use batch transactions.

Implements cryptonote::BlockchainDB.

Definition at line 4343 of file db_lmdb.cpp.

4344 {
4345  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
4346  if ((batch_transactions) && (m_batch_transactions))
4347  {
4348  MINFO("batch transaction mode already enabled, but asked to enable batch mode");
4349  }
4350  m_batch_transactions = batch_transactions;
4351  MINFO("batch transactions " << (m_batch_transactions ? "enabled" : "disabled"));
4352 }
#define MINFO(x)
Definition: misc_log_ex.h:75
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102

◆ set_block_cumulative_difficulty()

void cryptonote::BlockchainLMDB::set_block_cumulative_difficulty ( uint64_t  height,
difficulty_type  diff 
)
virtual

sets a block's cumulative difficulty

The subclass should return true if the cumulative difficulty is set successfully

If the block does not exist, the subclass should throw BLOCK_DNE

Parameters
heightthe height requested
diffthe cumulative difficulty value to be set
Returns
true | false

Implements cryptonote::BlockchainDB.

Definition at line 3327 of file db_lmdb.cpp.

3328 {
3329  LOG_PRINT_L3("BlockchainLMDB::" << __func__ << " height: " << height);
3330  check_open();
3331  mdb_txn_cursors *m_cursors = &m_wcursors;
3332 
3333  int result;
3334 
3335  CURSOR(block_info)
3336 
3337  MDB_val_set(val_bi, height);
3338  result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &val_bi, MDB_GET_BOTH);
3339  if (result == MDB_NOTFOUND)
3340  {
3341  throw0(BLOCK_DNE(std::string("Attempt to set cumulative difficulty from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- difficulty not in db").c_str()));
3342  }
3343  else if (result)
3344  throw0(DB_ERROR("Error attempting to set a cumulative difficulty"));
3345 
3346  mdb_block_info *result_bi = (mdb_block_info *)val_bi.mv_data;
3347 
3348  mdb_block_info bi;
3349  bi.bi_height = result_bi->bi_height;
3350  bi.bi_timestamp = result_bi->bi_timestamp;
3351  bi.bi_coins = result_bi->bi_coins;
3352  bi.bi_weight = result_bi->bi_weight;
3353  //bi.bi_diff_lo = diff; // TODO
3354  bi.bi_hash = result_bi->bi_hash;
3355 
3356  MDB_val_set(val, bi);
3357  result = mdb_cursor_put(m_cur_block_info, (MDB_val *)&val_bi, &val, MDB_CURRENT);
3358  if (result)
3359  throw0(DB_ERROR(lmdb_error("Failed to set cumulative difficulty to db transaction: ", result).c_str()));
3360 
3361 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
::std::string string
Definition: gtest-port.h:1097
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Store by cursor.
#define MDB_CURRENT
Definition: lmdb.h:371
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
mdb_block_info_4 mdb_block_info
Definition: db_lmdb.cpp:355
#define m_cur_block_info
Definition: db_lmdb.h:83
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
struct cryptonote::mdb_txn_cursors mdb_txn_cursors
#define CURSOR(name)
Definition: db_lmdb.cpp:285
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ sync()

void cryptonote::BlockchainLMDB::sync ( )
virtual

sync the BlockchainDB with disk

This function should write any changes to whatever permanent backing store the subclass uses. Example: a BlockchainDB instance which keeps the whole blockchain in RAM won't need to regularly access a disk, but should write out its state when this is called.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Implements cryptonote::BlockchainDB.

Definition at line 1640 of file db_lmdb.cpp.

1641 {
1642  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1643  check_open();
1644 
1645  if (is_read_only())
1646  return;
1647 
1648  // Does nothing unless LMDB environment was opened with MDB_NOSYNC or in part
1649  // MDB_NOMETASYNC. Force flush to be synchronous.
1650  if (auto result = mdb_env_sync(m_env, true))
1651  {
1652  throw0(DB_ERROR(lmdb_error("Failed to sync database: ", result).c_str()));
1653  }
1654 }
int mdb_env_sync(MDB_env *env, int force)
Flush the data buffers to disk.
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
Here is the call graph for this function:
Here is the caller graph for this function:

◆ top_block_hash()

crypto::hash cryptonote::BlockchainLMDB::top_block_hash ( uint64_t block_height = NULL) const
virtual

fetch the top block's hash

The subclass should return the hash of the most recent block

Parameters
block_heightif non NULL, returns the height of that block (ie, the blockchain height minus 1)
Returns
the top block's hash

Implements cryptonote::BlockchainDB.

Definition at line 3502 of file db_lmdb.cpp.

3503 {
3504  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3505  check_open();
3506  uint64_t m_height = height();
3507  if (block_height)
3508  *block_height = m_height - 1;
3509  if (m_height != 0)
3510  {
3511  return get_block_hash_from_height(m_height - 1);
3512  }
3513 
3514  return null_hash;
3515 }
unsigned __int64 uint64_t
Definition: stdint.h:136
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
virtual crypto::hash get_block_hash_from_height(const uint64_t &height) const
fetch a block&#39;s hash
Definition: db_lmdb.cpp:3451
virtual uint64_t height() const
fetch the current blockchain height
Definition: db_lmdb.cpp:3532
Here is the call graph for this function:

◆ tx_exists() [1/2]

bool cryptonote::BlockchainLMDB::tx_exists ( const crypto::hash h) const
virtual

check if a transaction with a given hash exists

The subclass should check if a transaction is stored which has the given hash and return true if so, false otherwise.

Parameters
hthe hash to check against
tx_id(optional) returns the tx_id for the tx hash
Returns
true if the transaction exists, otherwise false

Implements cryptonote::BlockchainDB.

Definition at line 3568 of file db_lmdb.cpp.

3569 {
3570  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3571  check_open();
3572 
3574  RCURSOR(tx_indices);
3575 
3576  MDB_val_set(key, h);
3577  bool tx_found = false;
3578 
3579  TIME_MEASURE_START(time1);
3580  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
3581  if (get_result == 0)
3582  tx_found = true;
3583  else if (get_result != MDB_NOTFOUND)
3584  throw0(DB_ERROR(lmdb_error(std::string("DB error attempting to fetch transaction index from hash ") + epee::string_tools::pod_to_hex(h) + ": ", get_result).c_str()));
3585 
3586  TIME_MEASURE_FINISH(time1);
3587  time_tx_exists += time1;
3588 
3590 
3591  if (! tx_found)
3592  {
3593  LOG_PRINT_L1("transaction with hash " << epee::string_tools::pod_to_hex(h) << " not found in db");
3594  return false;
3595  }
3596 
3597  return true;
3598 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define LOG_PRINT_L1(x)
Definition: misc_log_ex.h:100
::std::string string
Definition: gtest-port.h:1097
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
const char * key
Definition: hmac_keccak.cpp:39
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
uint64_t time_tx_exists
a performance metric
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
Here is the call graph for this function:

◆ tx_exists() [2/2]

bool cryptonote::BlockchainLMDB::tx_exists ( const crypto::hash h,
uint64_t tx_index 
) const
virtual

Implements cryptonote::BlockchainDB.

Definition at line 3600 of file db_lmdb.cpp.

3601 {
3602  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
3603  check_open();
3604 
3606  RCURSOR(tx_indices);
3607 
3608  MDB_val_set(v, h);
3609 
3610  TIME_MEASURE_START(time1);
3611  auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
3612  TIME_MEASURE_FINISH(time1);
3613  time_tx_exists += time1;
3614  if (!get_result) {
3615  txindex *tip = (txindex *)v.mv_data;
3616  tx_id = tip->data.tx_id;
3617  }
3618 
3620 
3621  bool ret = false;
3622  if (get_result == MDB_NOTFOUND)
3623  {
3624  LOG_PRINT_L1("transaction with hash " << epee::string_tools::pod_to_hex(h) << " not found in db");
3625  }
3626  else if (get_result)
3627  throw0(DB_ERROR(lmdb_error("DB error attempting to fetch transaction from hash", get_result).c_str()));
3628  else
3629  ret = true;
3630 
3631  return ret;
3632 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define LOG_PRINT_L1(x)
Definition: misc_log_ex.h:100
tx_data_t data
Definition: db_lmdb.h:46
struct cryptonote::txindex txindex
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
#define MDB_val_set(var, val)
Definition: db_lmdb.cpp:89
std::string pod_to_hex(const t_pod_type &s)
Definition: string_tools.h:317
uint64_t time_tx_exists
a performance metric
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define TIME_MEASURE_START(var_name)
Definition: profile_tools.h:61
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
#define TIME_MEASURE_FINISH(var_name)
Definition: profile_tools.h:64
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
#define m_cur_tx_indices
Definition: db_lmdb.h:91
Here is the call graph for this function:

◆ txpool_has_tx()

bool cryptonote::BlockchainLMDB::txpool_has_tx ( const crypto::hash txid) const
virtual

check whether a txid is in the txpool

Implements cryptonote::BlockchainDB.

Definition at line 2512 of file db_lmdb.cpp.

2513 {
2514  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2515  check_open();
2516 
2518  RCURSOR(txpool_meta)
2519 
2520  MDB_val k = {sizeof(txid), (void *)&txid};
2521  auto result = mdb_cursor_get(m_cur_txpool_meta, &k, NULL, MDB_SET);
2522  if (result != 0 && result != MDB_NOTFOUND)
2523  throw1(DB_ERROR(lmdb_error("Error finding txpool tx meta: ", result).c_str()));
2525  return result != MDB_NOTFOUND;
2526 }
#define MDB_NOTFOUND
Definition: lmdb.h:439
#define TXN_POSTFIX_RDONLY()
Definition: db_lmdb.cpp:1795
Definition: lmdb.h:422
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define RCURSOR(name)
Definition: db_lmdb.cpp:292
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define TXN_PREFIX_RDONLY()
Definition: db_lmdb.cpp:1788
Here is the call graph for this function:

◆ unlock()

void cryptonote::BlockchainLMDB::unlock ( )
virtual

This function releases the BlockchainDB lock.

The subclass, should it have implemented lock(), will release any lock held by the calling thread. In the case of recursive locking, it should release one instance of a lock.

If any of this cannot be done, the subclass should throw the corresponding subclass of DB_EXCEPTION

Implements cryptonote::BlockchainDB.

Definition at line 1771 of file db_lmdb.cpp.

1772 {
1773  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
1774  check_open();
1775 }
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102

◆ update_pruning()

bool cryptonote::BlockchainLMDB::update_pruning ( )
virtual

prunes recent blockchain changes as needed, iff pruning is enabled

Returns
success iff true

Implements cryptonote::BlockchainDB.

Definition at line 2931 of file db_lmdb.cpp.

2932 {
2933  return prune_worker(prune_mode_update, 0);
2934 }

◆ update_txpool_tx()

void cryptonote::BlockchainLMDB::update_txpool_tx ( const crypto::hash txid,
const txpool_tx_meta_t details 
)
virtual

update a txpool transaction's metadata

Parameters
txidthe txid of the transaction to update
detailsthe details of the transaction to update

Implements cryptonote::BlockchainDB.

Definition at line 2441 of file db_lmdb.cpp.

2442 {
2443  LOG_PRINT_L3("BlockchainLMDB::" << __func__);
2444  check_open();
2445  mdb_txn_cursors *m_cursors = &m_wcursors;
2446 
2447  CURSOR(txpool_meta)
2448  CURSOR(txpool_blob)
2449 
2450  MDB_val k = {sizeof(txid), (void *)&txid};
2451  MDB_val v;
2452  auto result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, MDB_SET);
2453  if (result != 0)
2454  throw1(DB_ERROR(lmdb_error("Error finding txpool tx meta to update: ", result).c_str()));
2455  result = mdb_cursor_del(m_cur_txpool_meta, 0);
2456  if (result)
2457  throw1(DB_ERROR(lmdb_error("Error adding removal of txpool tx metadata to db transaction: ", result).c_str()));
2458  v = MDB_val({sizeof(meta), (void *)&meta});
2459  if ((result = mdb_cursor_put(m_cur_txpool_meta, &k, &v, MDB_NODUPDATA)) != 0) {
2460  if (result == MDB_KEYEXIST)
2461  throw1(DB_ERROR("Attempting to add txpool tx metadata that's already in the db"));
2462  else
2463  throw1(DB_ERROR(lmdb_error("Error adding txpool tx metadata to db transaction: ", result).c_str()));
2464  }
2465 }
#define MDB_NODUPDATA
Definition: lmdb.h:369
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Store by cursor.
struct MDB_val MDB_val
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:422
#define m_cur_txpool_meta
Definition: db_lmdb.h:94
#define LOG_PRINT_L3(x)
Definition: misc_log_ex.h:102
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define MDB_KEYEXIST
Definition: lmdb.h:437
int mdb_cursor_del(MDB_cursor *cursor, unsigned int flags)
Delete current key/data pair.
struct cryptonote::mdb_txn_cursors mdb_txn_cursors
#define CURSOR(name)
Definition: db_lmdb.cpp:285
Here is the call graph for this function:

The documentation for this class was generated from the following files: