blockchain_db: add functions for adding/removing/getting rct commitments
This commit is contained in:
parent
82072e701a
commit
eb56d0f994
|
@ -1199,6 +1199,39 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool has_key_image(const crypto::key_image& img) const = 0;
|
virtual bool has_key_image(const crypto::key_image& img) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns the number of ringct outputs in the database
|
||||||
|
*
|
||||||
|
* @return the number of ringct outputs in the database
|
||||||
|
*/
|
||||||
|
virtual uint64_t get_num_rct_outputs() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns the commitment for a given ringct output
|
||||||
|
*
|
||||||
|
* Throws OUTPUT_DNE if the index is out of range
|
||||||
|
* Throws DB_ERROR on other error
|
||||||
|
*
|
||||||
|
* @return the commitment for the given index
|
||||||
|
*/
|
||||||
|
virtual rct::key get_rct_commitment(uint64_t idx) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a new ringct output with the given commitment
|
||||||
|
*
|
||||||
|
* Throws DB_ERROR if the addition fails
|
||||||
|
*
|
||||||
|
* @return the index of the newly added record
|
||||||
|
*/
|
||||||
|
virtual uint64_t add_rct_commitment(const rct::key &commitment) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a ringct output with the given index
|
||||||
|
*
|
||||||
|
* Throws DB_ERROR if the removal fails
|
||||||
|
*/
|
||||||
|
virtual void remove_rct_commitment(uint64_t idx) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief runs a function over all key images stored
|
* @brief runs a function over all key images stored
|
||||||
*
|
*
|
||||||
|
|
|
@ -155,6 +155,8 @@ int compare_string(const MDB_val *a, const MDB_val *b)
|
||||||
*
|
*
|
||||||
* spent_keys input hash -
|
* spent_keys input hash -
|
||||||
*
|
*
|
||||||
|
* rct_commitments input ID {commitment key}
|
||||||
|
*
|
||||||
* Note: where the data items are of uniform size, DUPFIXED tables have
|
* 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"
|
* 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
|
* key is used when accessing the table; the Key listed above will be
|
||||||
|
@ -175,6 +177,8 @@ const char* const LMDB_OUTPUT_TXS = "output_txs";
|
||||||
const char* const LMDB_OUTPUT_AMOUNTS = "output_amounts";
|
const char* const LMDB_OUTPUT_AMOUNTS = "output_amounts";
|
||||||
const char* const LMDB_SPENT_KEYS = "spent_keys";
|
const char* const LMDB_SPENT_KEYS = "spent_keys";
|
||||||
|
|
||||||
|
const char* const LMDB_RCT_COMMITMENTS = "rct_commitments";
|
||||||
|
|
||||||
const char* const LMDB_HF_STARTING_HEIGHTS = "hf_starting_heights";
|
const char* const LMDB_HF_STARTING_HEIGHTS = "hf_starting_heights";
|
||||||
const char* const LMDB_HF_VERSIONS = "hf_versions";
|
const char* const LMDB_HF_VERSIONS = "hf_versions";
|
||||||
|
|
||||||
|
@ -1084,6 +1088,8 @@ void BlockchainLMDB::open(const std::string& filename, const int mdb_flags)
|
||||||
|
|
||||||
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");
|
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");
|
||||||
|
|
||||||
|
lmdb_db_open(txn, LMDB_RCT_COMMITMENTS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_rct_commitments, "Failed to open db handle for m_rct_commitments");
|
||||||
|
|
||||||
// this subdb is dropped on sight, so it may not be present when we open the DB.
|
// this subdb is dropped on sight, so it may not be present when we open the DB.
|
||||||
// Since we use MDB_CREATE, we'll get an exception if we open read-only and it does not exist.
|
// Since we use MDB_CREATE, we'll get an exception if we open read-only and it does not exist.
|
||||||
// So we don't open for read-only, and also not drop below. It is not used elsewhere.
|
// So we don't open for read-only, and also not drop below. It is not used elsewhere.
|
||||||
|
@ -1250,6 +1256,8 @@ void BlockchainLMDB::reset()
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to drop m_output_amounts: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to drop m_output_amounts: ", result).c_str()));
|
||||||
if (auto result = mdb_drop(txn, m_spent_keys, 0))
|
if (auto result = mdb_drop(txn, m_spent_keys, 0))
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to drop m_spent_keys: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to drop m_spent_keys: ", result).c_str()));
|
||||||
|
if (auto result = mdb_drop(txn, m_rct_commitments, 0))
|
||||||
|
throw0(DB_ERROR(lmdb_error("Failed to drop m_rct_commitments: ", result).c_str()));
|
||||||
(void)mdb_drop(txn, m_hf_starting_heights, 0); // this one is dropped in new code
|
(void)mdb_drop(txn, m_hf_starting_heights, 0); // this one is dropped in new code
|
||||||
if (auto result = mdb_drop(txn, m_hf_versions, 0))
|
if (auto result = mdb_drop(txn, m_hf_versions, 0))
|
||||||
throw0(DB_ERROR(lmdb_error("Failed to drop m_hf_versions: ", result).c_str()));
|
throw0(DB_ERROR(lmdb_error("Failed to drop m_hf_versions: ", result).c_str()));
|
||||||
|
@ -2722,6 +2730,106 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t BlockchainLMDB::get_num_rct_outputs() const
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
check_open();
|
||||||
|
|
||||||
|
TXN_PREFIX_RDONLY();
|
||||||
|
RCURSOR(rct_commitments);
|
||||||
|
|
||||||
|
mdb_size_t num_outputs = 0;
|
||||||
|
MDB_stat ms;
|
||||||
|
auto result = mdb_stat(m_txn, m_rct_commitments, &ms);
|
||||||
|
if (result == MDB_SUCCESS)
|
||||||
|
{
|
||||||
|
num_outputs = ms.ms_entries;
|
||||||
|
}
|
||||||
|
else if (result == MDB_NOTFOUND)
|
||||||
|
{
|
||||||
|
num_outputs = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw0(DB_ERROR("DB error attempting to get number of ringct outputs"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TXN_POSTFIX_RDONLY();
|
||||||
|
|
||||||
|
return num_outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
rct::key BlockchainLMDB::get_rct_commitment(uint64_t idx) const
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
check_open();
|
||||||
|
|
||||||
|
TXN_PREFIX_RDONLY();
|
||||||
|
RCURSOR(rct_commitments);
|
||||||
|
|
||||||
|
MDB_val_set(val_key, idx);
|
||||||
|
MDB_val val_ret;
|
||||||
|
auto result = mdb_cursor_get(m_cur_rct_commitments, &val_key, &val_ret, MDB_SET);
|
||||||
|
if (result == MDB_NOTFOUND)
|
||||||
|
throw0(OUTPUT_DNE(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast<std::string>(idx) + " from the db: ", result).c_str()));
|
||||||
|
else if (result)
|
||||||
|
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast<std::string>(idx) + " from the db: ", result).c_str()));
|
||||||
|
|
||||||
|
rct::key commitment = *(const rct::key*)val_ret.mv_data;
|
||||||
|
TXN_POSTFIX_RDONLY();
|
||||||
|
return commitment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockchainLMDB::remove_rct_commitment(uint64_t idx)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
check_open();
|
||||||
|
|
||||||
|
mdb_txn_cursors *m_cursors = &m_wcursors;
|
||||||
|
CURSOR(rct_commitments);
|
||||||
|
|
||||||
|
MDB_val_set(val_key, idx);
|
||||||
|
MDB_val val_ret;
|
||||||
|
auto result = mdb_cursor_get(m_cur_rct_commitments, &val_key, &val_ret, MDB_SET);
|
||||||
|
if (result == MDB_NOTFOUND)
|
||||||
|
throw0(OUTPUT_DNE(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast<std::string>(idx) + " from the db: ", result).c_str()));
|
||||||
|
else if (result)
|
||||||
|
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast<std::string>(idx) + " from the db: ", result).c_str()));
|
||||||
|
result = mdb_cursor_del(m_cur_rct_commitments, 0);
|
||||||
|
if (result)
|
||||||
|
throw0(DB_ERROR(lmdb_error("Error attempting to remove rct commitment for " + boost::lexical_cast<std::string>(idx) + " from the db: ", result).c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t BlockchainLMDB::add_rct_commitment(const rct::key &commitment)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||||
|
check_open();
|
||||||
|
|
||||||
|
mdb_txn_cursors *m_cursors = &m_wcursors;
|
||||||
|
|
||||||
|
CURSOR(rct_commitments);
|
||||||
|
|
||||||
|
uint64_t num_outputs = 0;
|
||||||
|
MDB_stat ms;
|
||||||
|
auto result = mdb_stat(*m_write_txn, m_rct_commitments, &ms);
|
||||||
|
if (result == MDB_SUCCESS)
|
||||||
|
num_outputs = ms.ms_entries;
|
||||||
|
else if (result == MDB_NOTFOUND)
|
||||||
|
num_outputs = 0;
|
||||||
|
else
|
||||||
|
throw0(DB_ERROR("DB error attempting to get number of ringct outputs"));
|
||||||
|
|
||||||
|
MDB_val_set(val_key, num_outputs);
|
||||||
|
MDB_val val_value;
|
||||||
|
val_value.mv_size = sizeof(rct::key);
|
||||||
|
val_value.mv_data = (void*)&commitment;
|
||||||
|
result = mdb_cursor_put(m_cur_rct_commitments, (MDB_val *)&val_key, &val_value, 0);
|
||||||
|
if (result)
|
||||||
|
throw0(DB_ERROR(lmdb_error("Failed to add rct output to db transaction: ", result).c_str()));
|
||||||
|
|
||||||
|
return num_outputs;
|
||||||
|
}
|
||||||
|
|
||||||
bool BlockchainLMDB::is_read_only() const
|
bool BlockchainLMDB::is_read_only() const
|
||||||
{
|
{
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "blockchain_db/blockchain_db.h"
|
#include "blockchain_db/blockchain_db.h"
|
||||||
#include "cryptonote_protocol/blobdatatype.h" // for type blobdata
|
#include "cryptonote_protocol/blobdatatype.h" // for type blobdata
|
||||||
|
#include "ringct/rctTypes.h"
|
||||||
#include <boost/thread/tss.hpp>
|
#include <boost/thread/tss.hpp>
|
||||||
|
|
||||||
#include <lmdb.h>
|
#include <lmdb.h>
|
||||||
|
@ -54,6 +55,8 @@ typedef struct mdb_txn_cursors
|
||||||
|
|
||||||
MDB_cursor *m_txc_spent_keys;
|
MDB_cursor *m_txc_spent_keys;
|
||||||
|
|
||||||
|
MDB_cursor *m_txc_rct_commitments;
|
||||||
|
|
||||||
MDB_cursor *m_txc_hf_versions;
|
MDB_cursor *m_txc_hf_versions;
|
||||||
} mdb_txn_cursors;
|
} mdb_txn_cursors;
|
||||||
|
|
||||||
|
@ -66,6 +69,7 @@ typedef struct mdb_txn_cursors
|
||||||
#define m_cur_tx_indices m_cursors->m_txc_tx_indices
|
#define m_cur_tx_indices m_cursors->m_txc_tx_indices
|
||||||
#define m_cur_tx_outputs m_cursors->m_txc_tx_outputs
|
#define m_cur_tx_outputs m_cursors->m_txc_tx_outputs
|
||||||
#define m_cur_spent_keys m_cursors->m_txc_spent_keys
|
#define m_cur_spent_keys m_cursors->m_txc_spent_keys
|
||||||
|
#define m_cur_rct_commitments m_cursors->m_txc_rct_commitments
|
||||||
#define m_cur_hf_versions m_cursors->m_txc_hf_versions
|
#define m_cur_hf_versions m_cursors->m_txc_hf_versions
|
||||||
|
|
||||||
typedef struct mdb_rflags
|
typedef struct mdb_rflags
|
||||||
|
@ -80,6 +84,7 @@ typedef struct mdb_rflags
|
||||||
bool m_rf_tx_indices;
|
bool m_rf_tx_indices;
|
||||||
bool m_rf_tx_outputs;
|
bool m_rf_tx_outputs;
|
||||||
bool m_rf_spent_keys;
|
bool m_rf_spent_keys;
|
||||||
|
bool m_rf_rct_commitments;
|
||||||
bool m_rf_hf_versions;
|
bool m_rf_hf_versions;
|
||||||
} mdb_rflags;
|
} mdb_rflags;
|
||||||
|
|
||||||
|
@ -231,6 +236,11 @@ public:
|
||||||
|
|
||||||
virtual bool has_key_image(const crypto::key_image& img) const;
|
virtual bool has_key_image(const crypto::key_image& img) const;
|
||||||
|
|
||||||
|
virtual uint64_t get_num_rct_outputs() const;
|
||||||
|
virtual rct::key get_rct_commitment(uint64_t idx) const;
|
||||||
|
virtual uint64_t add_rct_commitment(const rct::key &commitment);
|
||||||
|
virtual void remove_rct_commitment(uint64_t idx);
|
||||||
|
|
||||||
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
|
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
|
||||||
virtual bool for_all_blocks(std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const;
|
virtual bool for_all_blocks(std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const;
|
||||||
virtual bool for_all_transactions(std::function<bool(const crypto::hash&, const cryptonote::transaction&)>) const;
|
virtual bool for_all_transactions(std::function<bool(const crypto::hash&, const cryptonote::transaction&)>) const;
|
||||||
|
@ -359,6 +369,8 @@ private:
|
||||||
|
|
||||||
MDB_dbi m_spent_keys;
|
MDB_dbi m_spent_keys;
|
||||||
|
|
||||||
|
MDB_dbi m_rct_commitments;
|
||||||
|
|
||||||
MDB_dbi m_hf_starting_heights;
|
MDB_dbi m_hf_starting_heights;
|
||||||
MDB_dbi m_hf_versions;
|
MDB_dbi m_hf_versions;
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,10 @@ public:
|
||||||
virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector<uint64_t>& amount_output_indices) {}
|
virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector<uint64_t>& amount_output_indices) {}
|
||||||
virtual void add_spent_key(const crypto::key_image& k_image) {}
|
virtual void add_spent_key(const crypto::key_image& k_image) {}
|
||||||
virtual void remove_spent_key(const crypto::key_image& k_image) {}
|
virtual void remove_spent_key(const crypto::key_image& k_image) {}
|
||||||
|
virtual uint64_t get_num_rct_outputs() const { return 0; }
|
||||||
|
virtual rct::key get_rct_commitment(uint64_t idx) const { return rct::key(); }
|
||||||
|
virtual uint64_t add_rct_commitment(const rct::key &commitment) { return 0; }
|
||||||
|
virtual void remove_rct_commitment(uint64_t idx) {}
|
||||||
|
|
||||||
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const { return true; }
|
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const { return true; }
|
||||||
virtual bool for_all_blocks(std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const { return true; }
|
virtual bool for_all_blocks(std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const { return true; }
|
||||||
|
|
Loading…
Reference in New Issue