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.h3
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp82
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h4
3 files changed, 65 insertions, 24 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 99b520d8b..93527b484 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -337,9 +337,6 @@ private:
const std::vector<uint64_t>& amount_output_indices
) = 0;
- // tells the subclass to remove an output
- virtual void remove_output(const tx_out& tx_output) = 0;
-
// tells the subclass to store a spent key
virtual void add_spent_key(const crypto::key_image& k_image) = 0;
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index a9645a95e..f9deca0b4 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -861,18 +861,11 @@ void BlockchainLMDB::remove_tx_outputs(const uint64_t tx_id, const transaction&
for (uint64_t i = tx.vout.size(); i > 0; --i)
{
const tx_out tx_output = tx.vout[i-1];
- remove_output(amount_output_indices[i-1], tx_output.amount);
+ remove_output(tx_output.amount, amount_output_indices[i-1]);
}
}
-// TODO: probably remove this function
-void BlockchainLMDB::remove_output(const tx_out& tx_output)
-{
- LOG_PRINT_L3("BlockchainLMDB::" << __func__ << " (unused version - does nothing)");
- return;
-}
-
-void BlockchainLMDB::remove_output(const uint64_t& out_index, const uint64_t amount)
+void BlockchainLMDB::remove_output(const uint64_t amount, const uint64_t& out_index)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@@ -1841,12 +1834,54 @@ uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) const
return num_elems;
}
-// TODO: probably remove this function
+// This is a lot harder now that we've removed the output_keys index
output_data_t BlockchainLMDB::get_output_key(const uint64_t &global_index) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__ << " (unused version - does nothing)");
- outkey ok = {0};
- return ok.data;
+ check_open();
+ TXN_PREFIX_RDONLY();
+ RCURSOR(output_txs);
+ RCURSOR(tx_indices);
+ RCURSOR(txs);
+
+ output_data_t od;
+ MDB_val_set(v, global_index);
+ auto get_result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
+ if (get_result == MDB_NOTFOUND)
+ throw1(OUTPUT_DNE("output with given index not in db"));
+ else if (get_result)
+ throw0(DB_ERROR("DB error attempting to fetch output tx hash"));
+
+ outtx *ot = (outtx *)v.mv_data;
+
+ MDB_val_set(val_h, ot->tx_hash);
+ get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH);
+ if (get_result)
+ throw0(DB_ERROR(lmdb_error(std::string("DB error attempting to fetch transaction index from hash ") + epee::string_tools::pod_to_hex(ot->tx_hash) + ": ", get_result).c_str()));
+
+ txindex *tip = (txindex *)val_h.mv_data;
+ MDB_val_set(val_tx_id, tip->data.tx_id);
+ MDB_val result;
+ get_result = mdb_cursor_get(m_cur_txs, &val_tx_id, &result, MDB_SET);
+ if (get_result == MDB_NOTFOUND)
+ throw1(TX_DNE(std::string("tx with hash ").append(epee::string_tools::pod_to_hex(ot->tx_hash)).append(" not found in db").c_str()));
+ else if (get_result)
+ throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", get_result).c_str()));
+
+ blobdata bd;
+ bd.assign(reinterpret_cast<char*>(result.mv_data), result.mv_size);
+
+ transaction tx;
+ if (!parse_and_validate_tx_from_blob(bd, tx))
+ throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
+
+ const tx_out tx_output = tx.vout[ot->local_index];
+ od.unlock_time = tip->data.unlock_time;
+ od.height = tip->data.block_id;
+ od.pubkey = boost::get<txout_to_key>(tx_output.target).key;
+
+ TXN_POSTFIX_RDONLY();
+ return od;
}
output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint64_t& index)
@@ -1968,19 +2003,20 @@ bool BlockchainLMDB::for_all_key_images(std::function<bool(const crypto::key_ima
TXN_PREFIX_RDONLY();
RCURSOR(spent_keys);
- MDB_val k;
+ MDB_val k, v;
bool ret = true;
+ k = zerokval;
MDB_cursor_op op = MDB_FIRST;
while (1)
{
- int ret = mdb_cursor_get(m_cur_spent_keys, (MDB_val *)&zerokval, &k, op);
+ int ret = mdb_cursor_get(m_cur_spent_keys, &k, &v, op);
op = MDB_NEXT;
if (ret == MDB_NOTFOUND)
break;
if (ret < 0)
throw0(DB_ERROR("Failed to enumerate key images"));
- const crypto::key_image k_image = *(const crypto::key_image*)k.mv_data;
+ const crypto::key_image k_image = *(const crypto::key_image*)v.mv_data;
if (!f(k_image)) {
ret = false;
break;
@@ -2040,6 +2076,7 @@ bool BlockchainLMDB::for_all_transactions(std::function<bool(const crypto::hash&
TXN_PREFIX_RDONLY();
RCURSOR(txs);
+ RCURSOR(tx_indices);
MDB_val k;
MDB_val v;
@@ -2048,13 +2085,22 @@ bool BlockchainLMDB::for_all_transactions(std::function<bool(const crypto::hash&
MDB_cursor_op op = MDB_FIRST;
while (1)
{
- int ret = mdb_cursor_get(m_cur_txs, &k, &v, op);
+ int ret = mdb_cursor_get(m_cur_tx_indices, &k, &v, op);
op = MDB_NEXT;
if (ret == MDB_NOTFOUND)
break;
if (ret)
- throw0(DB_ERROR("Failed to enumerate transactions"));
- const crypto::hash hash = *(const crypto::hash*)k.mv_data;
+ throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str()));
+
+ txindex *ti = (txindex *)v.mv_data;
+ const crypto::hash hash = ti->key;
+ k.mv_data = (void *)&ti->data.tx_id;
+ k.mv_size = sizeof(ti->data.tx_id);
+ ret = mdb_cursor_get(m_cur_txs, &k, &v, MDB_SET);
+ if (ret == MDB_NOTFOUND)
+ break;
+ if (ret)
+ throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str()));
blobdata bd;
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
transaction tx;
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index 534f5575f..1f8c3bbef 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -288,11 +288,9 @@ private:
const std::vector<uint64_t>& amount_output_indices
);
- virtual void remove_output(const tx_out& tx_output);
-
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 amount, const uint64_t& out_index);
virtual void add_spent_key(const crypto::key_image& k_image);