From c50cd956743838dc256a1fe81722c80898cd2ec9 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Sun, 14 Dec 2014 15:20:41 -0500 Subject: [PATCH] Fixes a bug with getting output metadata from BlockchainDB Thanks to moneromooo-monero for spotting the bug. --- .../BlockchainDB_impl/db_lmdb.cpp | 46 ++++++++++++------- .../BlockchainDB_impl/db_lmdb.h | 2 + src/cryptonote_core/blockchain.cpp | 2 +- src/cryptonote_core/blockchain_db.h | 4 ++ 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp index 9d0728f6c..e96b9f90f 100644 --- a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp +++ b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp @@ -1208,6 +1208,35 @@ tx_out BlockchainLMDB::get_output(const uint64_t& index) const return output_from_blob(b); } +tx_out_index BlockchainLMDB::get_output_tx_and_index_from_global(const uint64_t& index) const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + txn_safe txn; + if (mdb_txn_begin(m_env, NULL, MDB_RDONLY, txn)) + throw0(DB_ERROR("Failed to create a transaction for the db")); + + MDB_val_copy k(index); + MDB_val v; + + auto get_result = mdb_get(txn, m_output_txs, &k, &v); + 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")); + + crypto::hash tx_hash = *(crypto::hash*)v.mv_data; + + get_result = mdb_get(txn, m_output_indices, &k, &v); + 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 index")); + + return tx_out_index(tx_hash, *(const uint64_t *)v.mv_data); +} + tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -1249,24 +1278,9 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con cur.close(); - k = MDB_val_copy(glob_index); - auto get_result = mdb_get(txn, m_output_txs, &k, &v); - 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")); - - crypto::hash tx_hash = *(crypto::hash*)v.mv_data; - - get_result = mdb_get(txn, m_output_indices, &k, &v); - 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 index")); - txn.commit(); - return tx_out_index(tx_hash, *(const uint64_t *)v.mv_data); + return get_output_tx_and_index_from_global(glob_index); } std::vector BlockchainLMDB::get_tx_output_indices(const crypto::hash& h) const diff --git a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h index 3bac5d740..6696ef492 100644 --- a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h +++ b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h @@ -161,6 +161,8 @@ public: */ tx_out get_output(const uint64_t& index) const; + virtual tx_out_index get_output_tx_and_index_from_global(const uint64_t& index) const; + virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const; virtual std::vector get_tx_output_indices(const crypto::hash& h) const; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 87be9d566..c4767765d 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -170,7 +170,7 @@ bool Blockchain::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, vi try { // get tx hash and output index for output - auto output_index = m_db->get_output_tx_and_index(tx_in_to_key.amount, i); + auto output_index = m_db->get_output_tx_and_index_from_global(i); // get tx that output is from auto tx = m_db->get_tx(output_index.first); diff --git a/src/cryptonote_core/blockchain_db.h b/src/cryptonote_core/blockchain_db.h index aa82672f2..a3c7bc26b 100644 --- a/src/cryptonote_core/blockchain_db.h +++ b/src/cryptonote_core/blockchain_db.h @@ -107,6 +107,7 @@ * uint64_t get_num_outputs(amount) * pub_key get_output_key(amount, index) * tx_out get_output(tx_hash, index) + * hash,index get_output_tx_and_index_from_global(index) * hash,index get_output_tx_and_index(amount, index) * vec get_tx_output_indices(tx_hash) * @@ -441,6 +442,9 @@ public: // returns the output indexed by in the transaction with hash virtual tx_out get_output(const crypto::hash& h, const uint64_t& index) const = 0; + // returns the tx hash associated with an output, referenced by global output index + virtual tx_out_index get_output_tx_and_index_from_global(const uint64_t& index) const = 0; + // returns the transaction-local reference for the output with at // return type is pair of tx hash and index virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const = 0;