Cleanup and clarify
Try to rationalize the variable names, document usage.
This commit is contained in:
parent
b2f1c58805
commit
591e421875
|
@ -82,21 +82,17 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t tx_index = add_transaction_data(blk_hash, tx, tx_hash);
|
uint64_t tx_id = add_transaction_data(blk_hash, tx, tx_hash);
|
||||||
|
|
||||||
std::vector<uint64_t> amount_output_indices;
|
std::vector<uint64_t> amount_output_indices;
|
||||||
std::vector<uint64_t> global_output_indices;
|
|
||||||
|
|
||||||
// iterate tx.vout using indices instead of C++11 foreach syntax because
|
// iterate tx.vout using indices instead of C++11 foreach syntax because
|
||||||
// we need the index
|
// we need the index
|
||||||
for (uint64_t i = 0; i < tx.vout.size(); ++i)
|
for (uint64_t i = 0; i < tx.vout.size(); ++i)
|
||||||
{
|
{
|
||||||
uint64_t amount_output_index, global_output_index;
|
amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time));
|
||||||
add_output(tx_hash, tx.vout[i], i, tx.unlock_time, amount_output_index, global_output_index);
|
|
||||||
amount_output_indices.push_back(amount_output_index);
|
|
||||||
global_output_indices.push_back(global_output_index);
|
|
||||||
}
|
}
|
||||||
add_amount_and_global_output_indices(tx_index, amount_output_indices, global_output_indices);
|
add_tx_amount_output_indices(tx_id, amount_output_indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t BlockchainDB::add_block( const block& blk
|
uint64_t BlockchainDB::add_block( const block& blk
|
||||||
|
|
|
@ -63,6 +63,26 @@
|
||||||
* of this interface call to private members of the interface to be added
|
* of this interface call to private members of the interface to be added
|
||||||
* later that will then populate as needed.
|
* later that will then populate as needed.
|
||||||
*
|
*
|
||||||
|
* Indices and Identifiers:
|
||||||
|
* The word "index" is used ambiguously throughout this code. It is
|
||||||
|
* particularly confusing when talking about the output or transaction
|
||||||
|
* tables since their indexing can refer to themselves or each other.
|
||||||
|
* I have attempted to clarify these usages here:
|
||||||
|
*
|
||||||
|
* Blocks, transactions, and outputs are all identified by a hash.
|
||||||
|
* For storage efficiency, a 64-bit integer ID is used instead of the hash
|
||||||
|
* inside the DB. Tables exist to map between hash and ID. A block ID is
|
||||||
|
* also referred to as its "height". Transactions and outputs generally are
|
||||||
|
* not referred to by ID outside of this module, but the tx ID is returned
|
||||||
|
* by tx_exists() and used by get_tx_amount_output_indices(). Like their
|
||||||
|
* corresponding hashes, IDs are globally unique.
|
||||||
|
*
|
||||||
|
* The remaining uses of the word "index" refer to local offsets, and are
|
||||||
|
* not globally unique. An "amount output index" N refers to the Nth output
|
||||||
|
* of a specific amount. An "output local index" N refers to the Nth output
|
||||||
|
* of a specific tx.
|
||||||
|
*
|
||||||
|
*
|
||||||
* General:
|
* General:
|
||||||
* open()
|
* open()
|
||||||
* is_open()
|
* is_open()
|
||||||
|
@ -99,7 +119,7 @@
|
||||||
* void pop_block(block&, tx_list&)
|
* void pop_block(block&, tx_list&)
|
||||||
*
|
*
|
||||||
* Transactions:
|
* Transactions:
|
||||||
* bool tx_exists(hash)
|
* bool tx_exists(hash, tx_id)
|
||||||
* uint64_t get_tx_unlock_time(hash)
|
* uint64_t get_tx_unlock_time(hash)
|
||||||
* tx get_tx(hash)
|
* tx get_tx(hash)
|
||||||
* uint64_t get_tx_count()
|
* uint64_t get_tx_count()
|
||||||
|
@ -111,7 +131,7 @@
|
||||||
* pub_key get_output_key(amount, index)
|
* pub_key get_output_key(amount, index)
|
||||||
* hash,index get_output_tx_and_index_from_global(index)
|
* hash,index get_output_tx_and_index_from_global(index)
|
||||||
* hash,index get_output_tx_and_index(amount, index)
|
* hash,index get_output_tx_and_index(amount, index)
|
||||||
* vec<uint64> get_tx_output_indices(tx_hash)
|
* vec<uint64> get_tx_amount_output_indices(tx_id)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Spent Output Key Images:
|
* Spent Output Key Images:
|
||||||
|
@ -151,9 +171,9 @@ struct output_data_t
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct tx_data_t
|
struct tx_data_t
|
||||||
{
|
{
|
||||||
uint64_t tx_index;
|
uint64_t tx_id;
|
||||||
uint64_t unlock_time;
|
uint64_t unlock_time;
|
||||||
uint64_t height;
|
uint64_t block_id;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
@ -299,25 +319,22 @@ private:
|
||||||
// tells the subclass to remove data about the top block
|
// tells the subclass to remove data about the top block
|
||||||
virtual void remove_block() = 0;
|
virtual void remove_block() = 0;
|
||||||
|
|
||||||
// tells the subclass to store the transaction and its metadata
|
// tells the subclass to store the transaction and its metadata, returns tx ID
|
||||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash& tx_hash) = 0;
|
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash& tx_hash) = 0;
|
||||||
|
|
||||||
// tells the subclass to remove data about a transaction
|
// tells the subclass to remove data about a transaction
|
||||||
virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx) = 0;
|
virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx) = 0;
|
||||||
|
|
||||||
// tells the subclass to store an output
|
// tells the subclass to store an output, returns amount output index
|
||||||
virtual void add_output(const crypto::hash& tx_hash,
|
virtual uint64_t add_output(const crypto::hash& tx_hash,
|
||||||
const tx_out& tx_output,
|
const tx_out& tx_output,
|
||||||
const uint64_t& local_index,
|
const uint64_t& local_index,
|
||||||
const uint64_t unlock_time,
|
const uint64_t unlock_time
|
||||||
uint64_t& amount_output_index,
|
|
||||||
uint64_t& global_output_index
|
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
// tells the subclass to store indices for a tx's outputs, both amount output indices and global output indices
|
// tells the subclass to store amount output indices for a tx's outputs
|
||||||
virtual void add_amount_and_global_output_indices(const uint64_t tx_index,
|
virtual void add_tx_amount_output_indices(const uint64_t tx_id,
|
||||||
const std::vector<uint64_t>& amount_output_indices,
|
const std::vector<uint64_t>& amount_output_indices
|
||||||
const std::vector<uint64_t>& global_output_indices
|
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
// tells the subclass to remove an output
|
// tells the subclass to remove an output
|
||||||
|
@ -482,7 +499,7 @@ public:
|
||||||
|
|
||||||
// return true if a transaction with hash <h> exists
|
// return true if a transaction with hash <h> exists
|
||||||
virtual bool tx_exists(const crypto::hash& h) const = 0;
|
virtual bool tx_exists(const crypto::hash& h) const = 0;
|
||||||
virtual bool tx_exists(const crypto::hash& h, uint64_t& tx_index) const = 0;
|
virtual bool tx_exists(const crypto::hash& h, uint64_t& tx_id) const = 0;
|
||||||
|
|
||||||
// return unlock time of tx with hash <h>
|
// return unlock time of tx with hash <h>
|
||||||
virtual uint64_t get_tx_unlock_time(const crypto::hash& h) const = 0;
|
virtual uint64_t get_tx_unlock_time(const crypto::hash& h) const = 0;
|
||||||
|
@ -523,16 +540,9 @@ public:
|
||||||
|
|
||||||
virtual bool can_thread_bulk_indices() const = 0;
|
virtual bool can_thread_bulk_indices() const = 0;
|
||||||
|
|
||||||
// return two vectors of indices: vector of amount output indices and global
|
|
||||||
// output indices, corresponding to each output in the transaction with hash
|
|
||||||
// <h>
|
|
||||||
virtual void get_amount_and_global_output_indices(const uint64_t tx_index,
|
|
||||||
std::vector<uint64_t>& amount_output_indices,
|
|
||||||
std::vector<uint64_t>& global_output_indices) const = 0;
|
|
||||||
|
|
||||||
// return a vector of indices corresponding to the amount output index for
|
// return a vector of indices corresponding to the amount output index for
|
||||||
// each output in the transaction with hash <h>
|
// each output in the transaction with ID <tx_id>
|
||||||
virtual std::vector<uint64_t> get_tx_amount_output_indices(const uint64_t tx_index) const = 0;
|
virtual std::vector<uint64_t> get_tx_amount_output_indices(const uint64_t tx_id) const = 0;
|
||||||
|
|
||||||
// returns true if key image <img> is present in spent key images storage
|
// returns true if key image <img> is present in spent key images storage
|
||||||
virtual bool has_key_image(const crypto::key_image& img) const = 0;
|
virtual bool has_key_image(const crypto::key_image& img) const = 0;
|
||||||
|
|
|
@ -145,9 +145,34 @@ int compare_string(const MDB_val *a, const MDB_val *b)
|
||||||
return strcmp(va, vb);
|
return strcmp(va, vb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DB schema:
|
||||||
|
*
|
||||||
|
* Table Key Data
|
||||||
|
* ----- --- ----
|
||||||
|
* blocks block ID block blob
|
||||||
|
* block_heights block hash block height
|
||||||
|
* block_info block ID {block metadata}
|
||||||
|
*
|
||||||
|
* txs txn ID txn blob
|
||||||
|
* tx_indices txn hash {txn ID, metadata}
|
||||||
|
* tx_outputs txn ID [txn amount output indices]
|
||||||
|
*
|
||||||
|
* output_txs output ID {txn hash, local index}
|
||||||
|
* output_amounts amount [{amount output index, metadata}...]
|
||||||
|
*
|
||||||
|
* spent_keys output hash -
|
||||||
|
*
|
||||||
|
* Note: where the data items are of uniform size, DUPFIXED tables have
|
||||||
|
* been used to save space. In most of these cases, a dummy "zerokval"
|
||||||
|
* key is used when accessing the table; the Key listed above will be
|
||||||
|
* attached as a prefix on the Data to serve as the DUPSORT key.
|
||||||
|
* (DUPFIXED saves 8 bytes per record.)
|
||||||
|
*
|
||||||
|
* The output_amounts table doesn't use a dummy key, but uses DUPSORT.
|
||||||
|
*/
|
||||||
const char* const LMDB_BLOCKS = "blocks";
|
const char* const LMDB_BLOCKS = "blocks";
|
||||||
const char* const LMDB_BLOCK_INFO = "block_info";
|
|
||||||
const char* const LMDB_BLOCK_HEIGHTS = "block_heights";
|
const char* const LMDB_BLOCK_HEIGHTS = "block_heights";
|
||||||
|
const char* const LMDB_BLOCK_INFO = "block_info";
|
||||||
|
|
||||||
const char* const LMDB_TXS = "txs";
|
const char* const LMDB_TXS = "txs";
|
||||||
const char* const LMDB_TX_INDICES = "tx_indices";
|
const char* const LMDB_TX_INDICES = "tx_indices";
|
||||||
|
@ -215,8 +240,8 @@ typedef struct mdb_block_info
|
||||||
} mdb_block_info;
|
} mdb_block_info;
|
||||||
|
|
||||||
typedef struct blk_height {
|
typedef struct blk_height {
|
||||||
crypto::hash key;
|
crypto::hash bh_hash;
|
||||||
uint64_t height;
|
uint64_t bh_height;
|
||||||
} blk_height;
|
} blk_height;
|
||||||
|
|
||||||
typedef struct txindex {
|
typedef struct txindex {
|
||||||
|
@ -226,12 +251,12 @@ typedef struct txindex {
|
||||||
|
|
||||||
typedef struct outkey {
|
typedef struct outkey {
|
||||||
uint64_t amount_index;
|
uint64_t amount_index;
|
||||||
uint64_t tx_index;
|
uint64_t output_id;
|
||||||
output_data_t data;
|
output_data_t data;
|
||||||
} outkey;
|
} outkey;
|
||||||
|
|
||||||
typedef struct outtx {
|
typedef struct outtx {
|
||||||
uint64_t txnum;
|
uint64_t output_id;
|
||||||
crypto::hash tx_hash;
|
crypto::hash tx_hash;
|
||||||
uint64_t local_index;
|
uint64_t local_index;
|
||||||
} outtx;
|
} outtx;
|
||||||
|
@ -560,14 +585,13 @@ void BlockchainLMDB::add_block(const block& blk, const size_t& block_size, const
|
||||||
|
|
||||||
CURSOR(block_heights)
|
CURSOR(block_heights)
|
||||||
blk_height bh = {blk_hash, m_height};
|
blk_height bh = {blk_hash, m_height};
|
||||||
MDB_val val_h = {sizeof(bh), (void *)&bh};
|
MDB_val_set(val_h, bh);
|
||||||
if (mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH) == 0)
|
if (mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH) == 0)
|
||||||
throw1(BLOCK_EXISTS("Attempting to add block that's already in the db"));
|
throw1(BLOCK_EXISTS("Attempting to add block that's already in the db"));
|
||||||
|
|
||||||
if (m_height > 0)
|
if (m_height > 0)
|
||||||
{
|
{
|
||||||
blk_height ph = {blk.prev_id, 0};
|
MDB_val_set(parent_key, blk.prev_id);
|
||||||
MDB_val parent_key = {sizeof(ph), (void *)&ph};
|
|
||||||
int result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &parent_key, MDB_GET_BOTH);
|
int result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &parent_key, MDB_GET_BOTH);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
@ -576,13 +600,13 @@ void BlockchainLMDB::add_block(const block& blk, const size_t& block_size, const
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to get top block hash to check for new block's parent: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to get top block hash to check for new block's parent: ", result).c_str()));
|
||||||
}
|
}
|
||||||
blk_height *prev = (blk_height *)parent_key.mv_data;
|
blk_height *prev = (blk_height *)parent_key.mv_data;
|
||||||
if (prev->height != m_height - 1)
|
if (prev->bh_height != m_height - 1)
|
||||||
throw0(BLOCK_PARENT_DNE("Top block is not new block's parent"));
|
throw0(BLOCK_PARENT_DNE("Top block is not new block's parent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
MDB_val_copy<uint64_t> key(m_height);
|
MDB_val_set(key, m_height);
|
||||||
|
|
||||||
CURSOR(blocks)
|
CURSOR(blocks)
|
||||||
CURSOR(block_info)
|
CURSOR(block_info)
|
||||||
|
@ -600,7 +624,7 @@ void BlockchainLMDB::add_block(const block& blk, const size_t& block_size, const
|
||||||
bi.bi_diff = cumulative_difficulty;
|
bi.bi_diff = cumulative_difficulty;
|
||||||
bi.bi_hash = blk_hash;
|
bi.bi_hash = blk_hash;
|
||||||
|
|
||||||
MDB_val val = {sizeof(bi), (void *)&bi};
|
MDB_val_set(val, bi);
|
||||||
result = mdb_cursor_put(m_cur_block_info, (MDB_val *)&zerokval, &val, MDB_APPENDDUP);
|
result = mdb_cursor_put(m_cur_block_info, (MDB_val *)&zerokval, &val, MDB_APPENDDUP);
|
||||||
if (result)
|
if (result)
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to add block info to db transaction: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to add block info to db transaction: ", result).c_str()));
|
||||||
|
@ -657,26 +681,27 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
|
||||||
check_open();
|
check_open();
|
||||||
mdb_txn_cursors *m_cursors = &m_wcursors;
|
mdb_txn_cursors *m_cursors = &m_wcursors;
|
||||||
|
|
||||||
int result = 0;
|
int result;
|
||||||
uint64_t tx_index = m_num_txs;
|
uint64_t tx_id = m_num_txs;
|
||||||
|
|
||||||
CURSOR(txs)
|
CURSOR(txs)
|
||||||
CURSOR(tx_indices)
|
CURSOR(tx_indices)
|
||||||
|
|
||||||
txindex ti = {tx_hash};
|
MDB_val_set(val_tx_id, tx_id);
|
||||||
MDB_val_copy<uint64_t> val_tx_index(tx_index);
|
MDB_val_set(val_h, tx_hash);
|
||||||
MDB_val val_h = {sizeof(ti), (void *)&ti};
|
|
||||||
result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH);
|
result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
txindex *tip = (txindex *)val_h.mv_data;
|
txindex *tip = (txindex *)val_h.mv_data;
|
||||||
throw1(TX_EXISTS(std::string("Attempting to add transaction that's already in the db (tx index ").append(boost::lexical_cast<std::string>(tip->data.tx_index)).append(")").c_str()));
|
throw1(TX_EXISTS(std::string("Attempting to add transaction that's already in the db (tx id ").append(boost::lexical_cast<std::string>(tip->data.tx_id)).append(")").c_str()));
|
||||||
} else if (result != MDB_NOTFOUND) {
|
} else if (result != MDB_NOTFOUND) {
|
||||||
throw1(DB_ERROR(lmdb_error(std::string("Error checking if tx index exists for tx hash ") + epee::string_tools::pod_to_hex(tx_hash) + ": ", result).c_str()));
|
throw1(DB_ERROR(lmdb_error(std::string("Error checking if tx index exists for tx hash ") + epee::string_tools::pod_to_hex(tx_hash) + ": ", result).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ti.data.tx_index = tx_index;
|
txindex ti;
|
||||||
|
ti.key = tx_hash;
|
||||||
|
ti.data.tx_id = tx_id;
|
||||||
ti.data.unlock_time = tx.unlock_time;
|
ti.data.unlock_time = tx.unlock_time;
|
||||||
ti.data.height = m_height;
|
ti.data.block_id = m_height; // we don't need blk_hash since we know m_height
|
||||||
|
|
||||||
val_h.mv_size = sizeof(ti);
|
val_h.mv_size = sizeof(ti);
|
||||||
val_h.mv_data = (void *)&ti;
|
val_h.mv_data = (void *)&ti;
|
||||||
|
@ -686,12 +711,12 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to add tx data to db transaction: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to add tx data to db transaction: ", result).c_str()));
|
||||||
|
|
||||||
MDB_val_copy<blobdata> blob(tx_to_blob(tx));
|
MDB_val_copy<blobdata> blob(tx_to_blob(tx));
|
||||||
result = mdb_cursor_put(m_cur_txs, &val_tx_index, &blob, MDB_APPEND);
|
result = mdb_cursor_put(m_cur_txs, &val_tx_id, &blob, MDB_APPEND);
|
||||||
if (result)
|
if (result)
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to add tx blob to db transaction: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to add tx blob to db transaction: ", result).c_str()));
|
||||||
|
|
||||||
m_num_txs++;
|
m_num_txs++;
|
||||||
return tx_index;
|
return tx_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: compare pros and cons of looking up the tx hash's tx index once and
|
// TODO: compare pros and cons of looking up the tx hash's tx index once and
|
||||||
|
@ -708,24 +733,22 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const
|
||||||
CURSOR(txs)
|
CURSOR(txs)
|
||||||
CURSOR(tx_outputs)
|
CURSOR(tx_outputs)
|
||||||
|
|
||||||
txindex ti = {tx_hash};
|
MDB_val_set(val_h, tx_hash);
|
||||||
MDB_val val_h = {sizeof(ti), (void *)&ti};
|
|
||||||
|
|
||||||
if (mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH))
|
if (mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH))
|
||||||
throw1(TX_DNE("Attempting to remove transaction that isn't in the db"));
|
throw1(TX_DNE("Attempting to remove transaction that isn't in the db"));
|
||||||
txindex *tip = (txindex *)val_h.mv_data;
|
txindex *tip = (txindex *)val_h.mv_data;
|
||||||
uint64_t tx_index = tip->data.tx_index;
|
MDB_val_set(val_tx_id, tip->data.tx_id);
|
||||||
MDB_val_copy<uint64_t> val_tx_index(tx_index);
|
|
||||||
|
|
||||||
if ((result = mdb_cursor_get(m_cur_txs, &val_tx_index, NULL, MDB_SET)))
|
if ((result = mdb_cursor_get(m_cur_txs, &val_tx_id, NULL, MDB_SET)))
|
||||||
throw1(DB_ERROR(lmdb_error("Failed to locate tx for removal: ", result).c_str()));
|
throw1(DB_ERROR(lmdb_error("Failed to locate tx for removal: ", result).c_str()));
|
||||||
result = mdb_cursor_del(m_cur_txs, 0);
|
result = mdb_cursor_del(m_cur_txs, 0);
|
||||||
if (result)
|
if (result)
|
||||||
throw1(DB_ERROR(lmdb_error("Failed to add removal of tx to db transaction: ", result).c_str()));
|
throw1(DB_ERROR(lmdb_error("Failed to add removal of tx to db transaction: ", result).c_str()));
|
||||||
|
|
||||||
remove_tx_outputs(tx_index, tx);
|
remove_tx_outputs(tip->data.tx_id, tx);
|
||||||
|
|
||||||
result = mdb_cursor_get(m_cur_tx_outputs, &val_tx_index, NULL, MDB_SET);
|
result = mdb_cursor_get(m_cur_tx_outputs, &val_tx_id, NULL, MDB_SET);
|
||||||
if (result == MDB_NOTFOUND)
|
if (result == MDB_NOTFOUND)
|
||||||
LOG_PRINT_L1("tx has no outputs to remove: " << tx_hash);
|
LOG_PRINT_L1("tx has no outputs to remove: " << tx_hash);
|
||||||
else if (result)
|
else if (result)
|
||||||
|
@ -737,24 +760,17 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const
|
||||||
throw1(DB_ERROR(lmdb_error("Failed to add removal of tx outputs to db transaction: ", result).c_str()));
|
throw1(DB_ERROR(lmdb_error("Failed to add removal of tx outputs to db transaction: ", result).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Though other things could change, so long as earlier functions (like
|
// Don't delete the tx_indices entry until the end, after we're done with val_tx_id
|
||||||
// remove_tx_outputs) need to do the lookup of tx hash -> tx index, don't
|
|
||||||
// delete the tx_indices entry until the end.
|
|
||||||
if (mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH))
|
|
||||||
throw1(TX_DNE("Attempting to remove transaction that isn't in the db"));
|
|
||||||
if (mdb_cursor_del(m_cur_tx_indices, 0))
|
if (mdb_cursor_del(m_cur_tx_indices, 0))
|
||||||
throw1(DB_ERROR("Failed to add removal of tx index to db transaction"));
|
throw1(DB_ERROR("Failed to add removal of tx index to db transaction"));
|
||||||
|
|
||||||
m_num_txs--;
|
m_num_txs--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// global_output_index is no longer used for locating outputs
|
uint64_t BlockchainLMDB::add_output(const crypto::hash& tx_hash,
|
||||||
void BlockchainLMDB::add_output(const crypto::hash& tx_hash,
|
|
||||||
const tx_out& tx_output,
|
const tx_out& tx_output,
|
||||||
const uint64_t& local_index,
|
const uint64_t& local_index,
|
||||||
const uint64_t unlock_time,
|
const uint64_t unlock_time)
|
||||||
uint64_t& amount_output_index,
|
|
||||||
uint64_t& global_output_index)
|
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
check_open();
|
check_open();
|
||||||
|
@ -791,7 +807,7 @@ void BlockchainLMDB::add_output(const crypto::hash& tx_hash,
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to get output amount in db transaction: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to get output amount in db transaction: ", result).c_str()));
|
||||||
else
|
else
|
||||||
ok.amount_index = 0;
|
ok.amount_index = 0;
|
||||||
ok.tx_index = m_num_outputs;
|
ok.output_id = m_num_outputs;
|
||||||
ok.data.pubkey = boost::get < txout_to_key > (tx_output.target).key;
|
ok.data.pubkey = boost::get < txout_to_key > (tx_output.target).key;
|
||||||
ok.data.unlock_time = unlock_time;
|
ok.data.unlock_time = unlock_time;
|
||||||
ok.data.height = m_height;
|
ok.data.height = m_height;
|
||||||
|
@ -801,16 +817,12 @@ void BlockchainLMDB::add_output(const crypto::hash& tx_hash,
|
||||||
if ((result = mdb_cursor_put(m_cur_output_amounts, &val_amount, &data, MDB_APPENDDUP)))
|
if ((result = mdb_cursor_put(m_cur_output_amounts, &val_amount, &data, MDB_APPENDDUP)))
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to add output pubkey to db transaction: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to add output pubkey to db transaction: ", result).c_str()));
|
||||||
|
|
||||||
amount_output_index = ok.amount_index;
|
|
||||||
global_output_index = m_num_outputs;
|
|
||||||
|
|
||||||
m_num_outputs++;
|
m_num_outputs++;
|
||||||
|
return ok.amount_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// global_output_indices is now ignored
|
void BlockchainLMDB::add_tx_amount_output_indices(const uint64_t tx_id,
|
||||||
void BlockchainLMDB::add_amount_and_global_output_indices(const uint64_t tx_index,
|
const std::vector<uint64_t>& amount_output_indices)
|
||||||
const std::vector<uint64_t>& amount_output_indices,
|
|
||||||
const std::vector<uint64_t>& global_output_indices)
|
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
check_open();
|
check_open();
|
||||||
|
@ -821,24 +833,22 @@ void BlockchainLMDB::add_amount_and_global_output_indices(const uint64_t tx_inde
|
||||||
|
|
||||||
int num_outputs = amount_output_indices.size();
|
int num_outputs = amount_output_indices.size();
|
||||||
|
|
||||||
MDB_val_copy<uint64_t> k_tx_index(tx_index);
|
MDB_val_set(k_tx_id, tx_id);
|
||||||
MDB_val v;
|
MDB_val v;
|
||||||
v.mv_data = (void *)amount_output_indices.data();
|
v.mv_data = (void *)amount_output_indices.data();
|
||||||
v.mv_size = sizeof(uint64_t) * num_outputs;
|
v.mv_size = sizeof(uint64_t) * num_outputs;
|
||||||
// LOG_PRINT_L1("tx_outputs[tx_hash] size: " << v.mv_size);
|
// LOG_PRINT_L1("tx_outputs[tx_hash] size: " << v.mv_size);
|
||||||
|
|
||||||
result = mdb_cursor_put(m_cur_tx_outputs, &k_tx_index, &v, MDB_APPEND);
|
result = mdb_cursor_put(m_cur_tx_outputs, &k_tx_id, &v, MDB_APPEND);
|
||||||
if (result)
|
if (result)
|
||||||
throw0(DB_ERROR(std::string("Failed to add <tx hash, amount output index array> to db transaction: ").append(mdb_strerror(result)).c_str()));
|
throw0(DB_ERROR(std::string("Failed to add <tx hash, amount output index array> to db transaction: ").append(mdb_strerror(result)).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockchainLMDB::remove_tx_outputs(const uint64_t tx_index, const transaction& tx)
|
void BlockchainLMDB::remove_tx_outputs(const uint64_t tx_id, const transaction& tx)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
|
||||||
// only need amount_output_indices
|
std::vector<uint64_t> amount_output_indices = get_tx_amount_output_indices(tx_id);
|
||||||
std::vector<uint64_t> amount_output_indices, global_output_indices;
|
|
||||||
get_amount_and_global_output_indices(tx_index, amount_output_indices, global_output_indices);
|
|
||||||
|
|
||||||
if (amount_output_indices.empty())
|
if (amount_output_indices.empty())
|
||||||
{
|
{
|
||||||
|
@ -880,7 +890,7 @@ void BlockchainLMDB::remove_output(const uint64_t& out_index, const uint64_t amo
|
||||||
throw0(DB_ERROR(lmdb_error("DB error attempting to get an output", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("DB error attempting to get an output", result).c_str()));
|
||||||
|
|
||||||
outkey *ok = (outkey *)v.mv_data;
|
outkey *ok = (outkey *)v.mv_data;
|
||||||
MDB_val_set(otxk, ok->tx_index);
|
MDB_val_set(otxk, ok->output_id);
|
||||||
result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &otxk, MDB_GET_BOTH);
|
result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &otxk, MDB_GET_BOTH);
|
||||||
if (result == MDB_NOTFOUND)
|
if (result == MDB_NOTFOUND)
|
||||||
{
|
{
|
||||||
|
@ -1333,8 +1343,7 @@ bool BlockchainLMDB::block_exists(const crypto::hash& h) const
|
||||||
RCURSOR(block_heights);
|
RCURSOR(block_heights);
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
blk_height bh = {h, 0};
|
MDB_val_set(key, h);
|
||||||
MDB_val key = {sizeof(bh), (void *)&bh};
|
|
||||||
auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
{
|
{
|
||||||
|
@ -1365,8 +1374,7 @@ uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) const
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(block_heights);
|
RCURSOR(block_heights);
|
||||||
|
|
||||||
blk_height bh = {h, 0};
|
MDB_val_set(key, h);
|
||||||
MDB_val key = {sizeof(bh), (void *)&bh};
|
|
||||||
auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
throw1(BLOCK_DNE("Attempted to retrieve non-existent block height"));
|
throw1(BLOCK_DNE("Attempted to retrieve non-existent block height"));
|
||||||
|
@ -1374,7 +1382,7 @@ uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) const
|
||||||
throw0(DB_ERROR("Error attempting to retrieve a block height from the db"));
|
throw0(DB_ERROR("Error attempting to retrieve a block height from the db"));
|
||||||
|
|
||||||
blk_height *bhp = (blk_height *)key.mv_data;
|
blk_height *bhp = (blk_height *)key.mv_data;
|
||||||
uint64_t ret = bhp->height;
|
uint64_t ret = bhp->bh_height;
|
||||||
TXN_POSTFIX_RDONLY();
|
TXN_POSTFIX_RDONLY();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1635,7 +1643,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) const
|
||||||
RCURSOR(tx_indices);
|
RCURSOR(tx_indices);
|
||||||
RCURSOR(txs);
|
RCURSOR(txs);
|
||||||
|
|
||||||
MDB_val_copy<crypto::hash> key(h);
|
MDB_val_set(key, h);
|
||||||
bool tx_found = false;
|
bool tx_found = false;
|
||||||
|
|
||||||
TIME_MEASURE_START(time1);
|
TIME_MEASURE_START(time1);
|
||||||
|
@ -1666,7 +1674,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockchainLMDB::tx_exists(const crypto::hash& h, uint64_t& tx_index) const
|
bool BlockchainLMDB::tx_exists(const crypto::hash& h, uint64_t& tx_id) const
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
check_open();
|
check_open();
|
||||||
|
@ -1674,8 +1682,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h, uint64_t& tx_index) const
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(tx_indices);
|
RCURSOR(tx_indices);
|
||||||
|
|
||||||
txindex ti = {h};
|
MDB_val_set(v, h);
|
||||||
MDB_val v = {sizeof(ti), (void *)&ti};
|
|
||||||
|
|
||||||
TIME_MEASURE_START(time1);
|
TIME_MEASURE_START(time1);
|
||||||
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||||
|
@ -1683,7 +1690,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h, uint64_t& tx_index) const
|
||||||
time_tx_exists += time1;
|
time_tx_exists += time1;
|
||||||
if (!get_result) {
|
if (!get_result) {
|
||||||
txindex *tip = (txindex *)v.mv_data;
|
txindex *tip = (txindex *)v.mv_data;
|
||||||
tx_index = tip->data.tx_index;
|
tx_id = tip->data.tx_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
TXN_POSTFIX_RDONLY();
|
TXN_POSTFIX_RDONLY();
|
||||||
|
@ -1709,8 +1716,7 @@ uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) const
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(tx_indices);
|
RCURSOR(tx_indices);
|
||||||
|
|
||||||
txindex ti = {h};
|
MDB_val_set(v, h);
|
||||||
MDB_val v = {sizeof(ti), (void *)&ti};
|
|
||||||
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
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()));
|
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()));
|
||||||
|
@ -1732,16 +1738,14 @@ transaction BlockchainLMDB::get_tx(const crypto::hash& h) const
|
||||||
RCURSOR(tx_indices);
|
RCURSOR(tx_indices);
|
||||||
RCURSOR(txs);
|
RCURSOR(txs);
|
||||||
|
|
||||||
txindex ti = {h};
|
MDB_val_set(v, h);
|
||||||
MDB_val v = {sizeof(ti), (void *)&ti};
|
|
||||||
MDB_val result;
|
MDB_val result;
|
||||||
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||||
if (get_result == 0)
|
if (get_result == 0)
|
||||||
{
|
{
|
||||||
txindex *tip = (txindex *)v.mv_data;
|
txindex *tip = (txindex *)v.mv_data;
|
||||||
uint64_t tx_index = tip->data.tx_index;
|
MDB_val_set(val_tx_id, tip->data.tx_id);
|
||||||
MDB_val_copy<uint64_t> val_tx_index(tx_index);
|
get_result = mdb_cursor_get(m_cur_txs, &val_tx_id, &result, MDB_SET);
|
||||||
get_result = mdb_cursor_get(m_cur_txs, &val_tx_index, &result, MDB_SET);
|
|
||||||
}
|
}
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
throw1(TX_DNE(std::string("tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()));
|
throw1(TX_DNE(std::string("tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()));
|
||||||
|
@ -1798,8 +1802,7 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(tx_indices);
|
RCURSOR(tx_indices);
|
||||||
|
|
||||||
txindex ti = {h};
|
MDB_val_set(v, h);
|
||||||
MDB_val v = {sizeof(ti), (void *)&ti};
|
|
||||||
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
{
|
{
|
||||||
|
@ -1809,7 +1812,7 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const
|
||||||
throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx height from hash", get_result).c_str()));
|
throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx height from hash", get_result).c_str()));
|
||||||
|
|
||||||
txindex *tip = (txindex *)v.mv_data;
|
txindex *tip = (txindex *)v.mv_data;
|
||||||
uint64_t ret = tip->data.height;
|
uint64_t ret = tip->data.block_id;
|
||||||
TXN_POSTFIX_RDONLY();
|
TXN_POSTFIX_RDONLY();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1867,7 +1870,7 @@ output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint6
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t& index) const
|
tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t& output_id) const
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
check_open();
|
check_open();
|
||||||
|
@ -1875,7 +1878,7 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t&
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(output_txs);
|
RCURSOR(output_txs);
|
||||||
|
|
||||||
MDB_val_set(v, index);
|
MDB_val_set(v, output_id);
|
||||||
|
|
||||||
auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
|
@ -1903,29 +1906,21 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con
|
||||||
return indices[0];
|
return indices[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't have global_output_indices
|
std::vector<uint64_t> BlockchainLMDB::get_tx_amount_output_indices(const uint64_t tx_id) const
|
||||||
void BlockchainLMDB::get_amount_and_global_output_indices(const uint64_t tx_index,
|
|
||||||
std::vector<uint64_t>& amount_output_indices,
|
|
||||||
std::vector<uint64_t>& global_output_indices) const
|
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
|
||||||
check_open();
|
check_open();
|
||||||
|
|
||||||
// If a new txn is created, it only needs to read.
|
|
||||||
//
|
|
||||||
// This must existence of m_write_txn too (not only m_batch_active), as
|
|
||||||
// that's what remove_tx_outputs() expected to use instead of creating a new
|
|
||||||
// txn, regardless of batch mode. Otherwise, remove_tx_outputs() would now
|
|
||||||
// create a new read-only txn here, which is incorrect.
|
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(tx_outputs);
|
RCURSOR(tx_outputs);
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
MDB_val_copy<uint64_t> k_tx_index(tx_index);
|
MDB_val_set(k_tx_id, tx_id);
|
||||||
MDB_val v;
|
MDB_val v;
|
||||||
|
std::vector<uint64_t> amount_output_indices;
|
||||||
|
|
||||||
result = mdb_cursor_get(m_cur_tx_outputs, &k_tx_index, &v, MDB_SET);
|
result = mdb_cursor_get(m_cur_tx_outputs, &k_tx_id, &v, MDB_SET);
|
||||||
if (result == MDB_NOTFOUND)
|
if (result == MDB_NOTFOUND)
|
||||||
LOG_PRINT_L0("WARNING: Unexpected: tx has no amount indices stored in "
|
LOG_PRINT_L0("WARNING: Unexpected: tx has no amount indices stored in "
|
||||||
"tx_outputs, but it should have an empty entry even if it's a tx without "
|
"tx_outputs, but it should have an empty entry even if it's a tx without "
|
||||||
|
@ -1944,21 +1939,10 @@ void BlockchainLMDB::get_amount_and_global_output_indices(const uint64_t tx_inde
|
||||||
indices = nullptr;
|
indices = nullptr;
|
||||||
|
|
||||||
TXN_POSTFIX_RDONLY();
|
TXN_POSTFIX_RDONLY();
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint64_t> BlockchainLMDB::get_tx_amount_output_indices(const uint64_t tx_index) const
|
|
||||||
{
|
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
|
||||||
|
|
||||||
std::vector<uint64_t> amount_output_indices, global_output_indices;
|
|
||||||
// only need amount_output_indices
|
|
||||||
get_amount_and_global_output_indices(tx_index, amount_output_indices, global_output_indices);
|
|
||||||
|
|
||||||
return amount_output_indices;
|
return amount_output_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool BlockchainLMDB::has_key_image(const crypto::key_image& img) const
|
bool BlockchainLMDB::has_key_image(const crypto::key_image& img) const
|
||||||
{
|
{
|
||||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
@ -2110,7 +2094,7 @@ bool BlockchainLMDB::for_all_outputs(std::function<bool(uint64_t amount, const c
|
||||||
throw0(DB_ERROR("Failed to enumerate outputs"));
|
throw0(DB_ERROR("Failed to enumerate outputs"));
|
||||||
uint64_t amount = *(const uint64_t*)k.mv_data;
|
uint64_t amount = *(const uint64_t*)k.mv_data;
|
||||||
outkey *ok = (outkey *)v.mv_data;
|
outkey *ok = (outkey *)v.mv_data;
|
||||||
tx_out_index toi = get_output_tx_and_index_from_global(ok->tx_index);
|
tx_out_index toi = get_output_tx_and_index_from_global(ok->output_id);
|
||||||
if (!f(amount, toi.first, toi.second)) {
|
if (!f(amount, toi.first, toi.second)) {
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
break;
|
||||||
|
@ -2453,9 +2437,9 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
|
||||||
TXN_PREFIX_RDONLY();
|
TXN_PREFIX_RDONLY();
|
||||||
RCURSOR(output_txs);
|
RCURSOR(output_txs);
|
||||||
|
|
||||||
for (const uint64_t &index : global_indices)
|
for (const uint64_t &output_id : global_indices)
|
||||||
{
|
{
|
||||||
MDB_val_set(v, index);
|
MDB_val_set(v, output_id);
|
||||||
|
|
||||||
auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
|
||||||
if (get_result == MDB_NOTFOUND)
|
if (get_result == MDB_NOTFOUND)
|
||||||
|
@ -2527,7 +2511,7 @@ void BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, const std::
|
||||||
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output from the db", get_result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output from the db", get_result).c_str()));
|
||||||
|
|
||||||
outkey *okp = (outkey *)v.mv_data;
|
outkey *okp = (outkey *)v.mv_data;
|
||||||
tx_indices.push_back(okp->tx_index);
|
tx_indices.push_back(okp->output_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
TIME_MEASURE_START(db3);
|
TIME_MEASURE_START(db3);
|
||||||
|
|
|
@ -227,11 +227,7 @@ public:
|
||||||
virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index);
|
virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index);
|
||||||
virtual void get_output_tx_and_index(const uint64_t& amount, const std::vector<uint64_t> &offsets, std::vector<tx_out_index> &indices);
|
virtual void get_output_tx_and_index(const uint64_t& amount, const std::vector<uint64_t> &offsets, std::vector<tx_out_index> &indices);
|
||||||
|
|
||||||
virtual void get_amount_and_global_output_indices(const uint64_t tx_index,
|
virtual std::vector<uint64_t> get_tx_amount_output_indices(const uint64_t tx_id) const;
|
||||||
std::vector<uint64_t>& amount_output_indices,
|
|
||||||
std::vector<uint64_t>& global_output_indices) const;
|
|
||||||
|
|
||||||
virtual std::vector<uint64_t> get_tx_amount_output_indices(const uint64_t tx_index) const;
|
|
||||||
|
|
||||||
virtual bool has_key_image(const crypto::key_image& img) const;
|
virtual bool has_key_image(const crypto::key_image& img) const;
|
||||||
|
|
||||||
|
@ -282,22 +278,19 @@ private:
|
||||||
|
|
||||||
virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx);
|
virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx);
|
||||||
|
|
||||||
virtual void add_output(const crypto::hash& tx_hash,
|
virtual uint64_t add_output(const crypto::hash& tx_hash,
|
||||||
const tx_out& tx_output,
|
const tx_out& tx_output,
|
||||||
const uint64_t& local_index,
|
const uint64_t& local_index,
|
||||||
const uint64_t unlock_time,
|
const uint64_t unlock_time
|
||||||
uint64_t& amount_output_index,
|
|
||||||
uint64_t& global_output_index
|
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual void add_amount_and_global_output_indices(const uint64_t tx_index,
|
virtual void add_tx_amount_output_indices(const uint64_t tx_id,
|
||||||
const std::vector<uint64_t>& amount_output_indices,
|
const std::vector<uint64_t>& amount_output_indices
|
||||||
const std::vector<uint64_t>& global_output_indices
|
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual void remove_output(const tx_out& tx_output);
|
virtual void remove_output(const tx_out& tx_output);
|
||||||
|
|
||||||
void remove_tx_outputs(const uint64_t tx_index, const transaction& tx);
|
void remove_tx_outputs(const uint64_t tx_id, const transaction& tx);
|
||||||
|
|
||||||
void remove_output(const uint64_t& out_index, const uint64_t amount);
|
void remove_output(const uint64_t& out_index, const uint64_t amount);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue