aboutsummaryrefslogtreecommitdiff
path: root/src/blockchain_db
diff options
context:
space:
mode:
Diffstat (limited to 'src/blockchain_db')
-rw-r--r--src/blockchain_db/blockchain_db.h2
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp82
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h2
3 files changed, 53 insertions, 33 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 71c46d76b..7118b0881 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -1349,7 +1349,7 @@ public:
*
* @param details the details of the transaction to add
*/
- virtual void add_txpool_tx(const transaction &tx, const txpool_tx_meta_t& details) = 0;
+ virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t& details) = 0;
/**
* @brief update a txpool transaction's metadata
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index bd91f308a..ea3638a85 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -85,6 +85,10 @@ inline void throw1(const T &e)
#define MDB_val_set(var, val) MDB_val var = {sizeof(val), (void *)&val}
+#define MDB_val_sized(var, val) MDB_val var = {val.size(), (void *)val.data()}
+
+#define MDB_val_str(var, val) MDB_val var = {strlen(val) + 1, (void *)val}
+
template<typename T>
struct MDB_val_copy: public MDB_val
{
@@ -714,7 +718,8 @@ void BlockchainLMDB::add_block(const block& blk, size_t block_weight, const diff
CURSOR(block_info)
// this call to mdb_cursor_put will change height()
- MDB_val_copy<blobdata> blob(block_to_blob(blk));
+ cryptonote::blobdata block_blob(block_to_blob(blk));
+ MDB_val_sized(blob, block_blob);
result = mdb_cursor_put(m_cur_blocks, &key, &blob, MDB_APPEND);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to add block blob to db transaction: ", result).c_str()));
@@ -828,7 +833,7 @@ 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()));
cryptonote::blobdata blob = tx_to_blob(tx);
- MDB_val_copy<blobdata> blobval(blob);
+ MDB_val_sized(blobval, blob);
std::stringstream ss;
binary_archive<true> ba(ss);
@@ -836,7 +841,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
if (!r)
throw0(DB_ERROR("Failed to serialize pruned tx"));
std::string pruned = ss.str();
- MDB_val_copy<blobdata> pruned_blob(pruned);
+ MDB_val_sized(pruned_blob, pruned);
result = mdb_cursor_put(m_cur_txs_pruned, &val_tx_id, &pruned_blob, MDB_APPEND);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to add pruned tx blob to db transaction: ", result).c_str()));
@@ -844,7 +849,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
if (pruned.size() > blob.size())
throw0(DB_ERROR("pruned tx size is larger than tx size"));
cryptonote::blobdata prunable(blob.data() + pruned.size(), blob.size() - pruned.size());
- MDB_val_copy<blobdata> prunable_blob(prunable);
+ MDB_val_sized(prunable_blob, prunable);
result = mdb_cursor_put(m_cur_txs_prunable, &val_tx_id, &prunable_blob, MDB_APPEND);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to add prunable tx blob to db transaction: ", result).c_str()));
@@ -1208,7 +1213,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
if (is_hdd_result)
{
if (is_hdd_result.value())
- MCLOG_RED(el::Level::Warning, "global", "The blockchain is on a rotating drive: this will be very slow, use a SSD if possible");
+ MCLOG_RED(el::Level::Warning, "global", "The blockchain is on a rotating drive: this will be very slow, use an SSD if possible");
}
m_folder = filename;
@@ -1331,7 +1336,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
bool compatible = true;
- MDB_val_copy<const char*> k("version");
+ MDB_val_str(k, "version");
MDB_val v;
auto get_result = mdb_get(txn, m_properties, &k, &v);
if(get_result == MDB_SUCCESS)
@@ -1379,7 +1384,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
// only write version on an empty DB
if (m_height == 0)
{
- MDB_val_copy<const char*> k("version");
+ MDB_val_str(k, "version");
MDB_val_copy<uint32_t> v(VERSION);
auto put_result = mdb_put(txn, m_properties, &k, &v, 0);
if (put_result != MDB_SUCCESS)
@@ -1476,7 +1481,7 @@ void BlockchainLMDB::reset()
throw0(DB_ERROR(lmdb_error("Failed to drop m_properties: ", result).c_str()));
// init with current version
- MDB_val_copy<const char*> k("version");
+ MDB_val_str(k, "version");
MDB_val_copy<uint32_t> v(VERSION);
if (auto result = mdb_put(txn, m_properties, &k, &v, 0))
throw0(DB_ERROR(lmdb_error("Failed to write version to database: ", result).c_str()));
@@ -1591,7 +1596,7 @@ void BlockchainLMDB::unlock()
auto_txn.commit(); \
} while(0)
-void BlockchainLMDB::add_txpool_tx(const transaction &tx, const txpool_tx_meta_t &meta)
+void BlockchainLMDB::add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@@ -1600,8 +1605,6 @@ void BlockchainLMDB::add_txpool_tx(const transaction &tx, const txpool_tx_meta_t
CURSOR(txpool_meta)
CURSOR(txpool_blob)
- const crypto::hash txid = get_transaction_hash(tx);
-
MDB_val k = {sizeof(txid), (void *)&txid};
MDB_val v = {sizeof(meta), (void *)&meta};
if (auto result = mdb_cursor_put(m_cur_txpool_meta, &k, &v, MDB_NODUPDATA)) {
@@ -1610,7 +1613,7 @@ void BlockchainLMDB::add_txpool_tx(const transaction &tx, const txpool_tx_meta_t
else
throw1(DB_ERROR(lmdb_error("Error adding txpool tx metadata to db transaction: ", result).c_str()));
}
- MDB_val_copy<cryptonote::blobdata> blob_val(tx_to_blob(tx));
+ MDB_val_sized(blob_val, blob);
if (auto result = mdb_cursor_put(m_cur_txpool_blob, &k, &blob_val, MDB_NODUPDATA)) {
if (result == MDB_KEYEXIST)
throw1(DB_ERROR("Attempting to add txpool tx blob that's already in the db"));
@@ -1980,22 +1983,36 @@ std::vector<uint64_t> BlockchainLMDB::get_block_cumulative_rct_outputs(const std
MDB_val v;
uint64_t prev_height = heights[0];
+ uint64_t range_begin = 0, range_end = 0;
for (uint64_t height: heights)
{
- if (height == prev_height + 1)
+ if (height >= range_begin && height < range_end)
{
- MDB_val k2;
- result = mdb_cursor_get(m_cur_block_info, &k2, &v, MDB_NEXT);
+ // nohting to do
}
else
{
- v.mv_size = sizeof(uint64_t);
- v.mv_data = (void*)&height;
- result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
+ if (height == prev_height + 1)
+ {
+ MDB_val k2;
+ result = mdb_cursor_get(m_cur_block_info, &k2, &v, MDB_NEXT_MULTIPLE);
+ range_begin = ((const mdb_block_info*)v.mv_data)->bi_height;
+ range_end = range_begin + v.mv_size / sizeof(mdb_block_info); // whole records please
+ if (height < range_begin || height >= range_end)
+ 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()));
+ }
+ else
+ {
+ v.mv_size = sizeof(uint64_t);
+ v.mv_data = (void*)&height;
+ result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
+ range_begin = height;
+ range_end = range_begin + 1;
+ }
+ if (result)
+ throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct distribution from the db: ", result).c_str()));
}
- if (result)
- throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct distribution from the db: ", result).c_str()));
- const mdb_block_info *bi = (const mdb_block_info *)v.mv_data;
+ const mdb_block_info *bi = ((const mdb_block_info *)v.mv_data) + (height - range_begin);
res.push_back(bi->bi_cum_rct);
prev_height = height;
}
@@ -2485,7 +2502,8 @@ output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint6
MDB_val_set(v, index);
auto get_result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_GET_BOTH);
if (get_result == MDB_NOTFOUND)
- throw1(OUTPUT_DNE("Attempting to get output pubkey by index, but key does not exist"));
+ throw1(OUTPUT_DNE(std::string("Attempting to get output pubkey by index, but key does not exist: amount " +
+ std::to_string(amount) + ", index " + std::to_string(index)).c_str()));
else if (get_result)
throw0(DB_ERROR("Error attempting to retrieve an output pubkey from the db"));
@@ -3157,6 +3175,7 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
tx_out_indices.clear();
+ tx_out_indices.reserve(global_indices.size());
TXN_PREFIX_RDONLY();
RCURSOR(output_txs);
@@ -3171,9 +3190,8 @@ void BlockchainLMDB::get_output_tx_and_index_from_global(const std::vector<uint6
else if (get_result)
throw0(DB_ERROR("DB error attempting to fetch output tx hash"));
- outtx *ot = (outtx *)v.mv_data;
- auto result = tx_out_index(ot->tx_hash, ot->local_index);
- tx_out_indices.push_back(result);
+ const outtx *ot = (const outtx *)v.mv_data;
+ tx_out_indices.push_back(tx_out_index(ot->tx_hash, ot->local_index));
}
TXN_POSTFIX_RDONLY();
@@ -3185,6 +3203,7 @@ void BlockchainLMDB::get_output_key(const uint64_t &amount, const std::vector<ui
TIME_MEASURE_START(db3);
check_open();
outputs.clear();
+ outputs.reserve(offsets.size());
TXN_PREFIX_RDONLY();
@@ -3208,19 +3227,19 @@ void BlockchainLMDB::get_output_key(const uint64_t &amount, const std::vector<ui
else if (get_result)
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output pubkey from the db", get_result).c_str()));
- output_data_t data;
if (amount == 0)
{
const outkey *okp = (const outkey *)v.mv_data;
- data = okp->data;
+ outputs.push_back(okp->data);
}
else
{
const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data;
+ outputs.resize(outputs.size() + 1);
+ output_data_t &data = outputs.back();
memcpy(&data, &okp->data, sizeof(pre_rct_output_data_t));
data.commitment = rct::zeroCommit(amount);
}
- outputs.push_back(data);
}
TXN_POSTFIX_RDONLY();
@@ -3236,6 +3255,7 @@ void BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, const std::
indices.clear();
std::vector <uint64_t> tx_indices;
+ tx_indices.reserve(offsets.size());
TXN_PREFIX_RDONLY();
RCURSOR(output_amounts);
@@ -4049,7 +4069,7 @@ void BlockchainLMDB::migrate_0_1()
uint32_t version = 1;
v.mv_data = (void *)&version;
v.mv_size = sizeof(version);
- MDB_val_copy<const char *> vk("version");
+ MDB_val_str(vk, "version");
result = mdb_txn_begin(m_env, NULL, 0, txn);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
@@ -4191,7 +4211,7 @@ void BlockchainLMDB::migrate_1_2()
uint32_t version = 2;
v.mv_data = (void *)&version;
v.mv_size = sizeof(version);
- MDB_val_copy<const char *> vk("version");
+ MDB_val_str(vk, "version");
result = mdb_txn_begin(m_env, NULL, 0, txn);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
@@ -4326,7 +4346,7 @@ void BlockchainLMDB::migrate_2_3()
uint32_t version = 3;
v.mv_data = (void *)&version;
v.mv_size = sizeof(version);
- MDB_val_copy<const char *> vk("version");
+ MDB_val_str(vk, "version");
result = mdb_txn_begin(m_env, NULL, 0, txn);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index e1f748ed8..7e76236a5 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -256,7 +256,7 @@ public:
virtual bool has_key_image(const crypto::key_image& img) const;
- virtual void add_txpool_tx(const transaction &tx, const txpool_tx_meta_t& meta);
+ virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t& meta);
virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& meta);
virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const;
virtual bool txpool_has_tx(const crypto::hash &txid) const;