From 1a5c3fa729bb3cda63e3962e8b8bdcb42159a6c0 Mon Sep 17 00:00:00 2001 From: warptangent Date: Thu, 28 Jan 2016 17:44:56 -0800 Subject: [PATCH] BlockchainBDB: Remove tx outputs in reverse order Data should be removed in the reverse order it was added. This matches the order of removal in blockchain_storage::pop_transaction_from_global_index. See f11def012f38106b0ffeb7010a2f749de1e5b640 --- src/blockchain_db/berkeleydb/db_bdb.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index 02fdaba2..86d1900a 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -419,16 +419,26 @@ void BlockchainBDB::remove_tx_outputs(const crypto::hash& tx_hash, const transac } else { + result = cur->get(&k, &v, DB_NEXT_NODUP); + if (result != 0 && result != DB_NOTFOUND) + throw0(DB_ERROR("DB error attempting to get next non-duplicate tx hash")); + + if (result == 0) + result = cur->get(&k, &v, DB_PREV); + else if (result == DB_NOTFOUND) + result = cur->get(&k, &v, DB_LAST); + db_recno_t num_elems = 0; cur->count(&num_elems, 0); - for (uint64_t i = 0; i < num_elems; ++i) + // remove in order: from newest to oldest + for (uint64_t i = num_elems; i > 0; --i) { - const tx_out tx_output = tx.vout[i]; + const tx_out tx_output = tx.vout[i-1]; remove_output(v, tx_output.amount); - if (i < num_elems - 1) + if (i > 1) { - cur->get(&k, &v, DB_NEXT_DUP); + cur->get(&k, &v, DB_PREV_DUP); } } }