Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outputs where all amounts are known spent can now be pruned #4901

Merged
merged 2 commits into from
Dec 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/blockchain_db/blockchain_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,13 @@ class BlockchainDB
*/
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const = 0;

/**
* @brief prune output data for the given amount
*
* @param amount the amount for which to prune data
*/
virtual void prune_outputs(uint64_t amount) = 0;

/**
* @brief runs a function over all txpool transactions
*
Expand Down
70 changes: 66 additions & 4 deletions src/blockchain_db/lmdb/db_lmdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,60 @@ void BlockchainLMDB::remove_output(const uint64_t amount, const uint64_t& out_in
throw0(DB_ERROR(lmdb_error(std::string("Error deleting amount for output index ").append(boost::lexical_cast<std::string>(out_index).append(": ")).c_str(), result).c_str()));
}

void BlockchainLMDB::prune_outputs(uint64_t amount)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
mdb_txn_cursors *m_cursors = &m_wcursors;
CURSOR(output_amounts);
CURSOR(output_txs);

MINFO("Pruning outputs for amount " << amount);

MDB_val v;
MDB_val_set(k, amount);
int result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_SET);
if (result == MDB_NOTFOUND)
return;
if (result)
throw0(DB_ERROR(lmdb_error("Error looking up outputs: ", result).c_str()));

// gather output ids
mdb_size_t num_elems;
mdb_cursor_count(m_cur_output_amounts, &num_elems);
MINFO(num_elems << " outputs found");
std::vector<uint64_t> output_ids;
output_ids.reserve(num_elems);
while (1)
{
const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data;
output_ids.push_back(okp->output_id);
MDEBUG("output id " << okp->output_id);
result = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_NEXT_DUP);
if (result == MDB_NOTFOUND)
break;
if (result)
throw0(DB_ERROR(lmdb_error("Error counting outputs: ", result).c_str()));
}
if (output_ids.size() != num_elems)
throw0(DB_ERROR("Unexpected number of outputs"));

result = mdb_cursor_del(m_cur_output_amounts, MDB_NODUPDATA);
if (result)
throw0(DB_ERROR(lmdb_error("Error deleting outputs: ", result).c_str()));

for (uint64_t output_id: output_ids)
{
MDB_val_set(v, output_id);
result = mdb_cursor_get(m_cur_output_txs, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
if (result)
throw0(DB_ERROR(lmdb_error("Error looking up output: ", result).c_str()));
result = mdb_cursor_del(m_cur_output_txs, 0);
if (result)
throw0(DB_ERROR(lmdb_error("Error deleting output: ", result).c_str()));
}
}

void BlockchainLMDB::add_spent_key(const crypto::key_image& k_image)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
Expand Down Expand Up @@ -2231,11 +2285,19 @@ uint64_t BlockchainLMDB::num_outputs() const
TXN_PREFIX_RDONLY();
int result;

// get current height
MDB_stat db_stats;
if ((result = mdb_stat(m_txn, m_output_txs, &db_stats)))
RCURSOR(output_txs)

uint64_t num = 0;
MDB_val k, v;
result = mdb_cursor_get(m_cur_output_txs, &k, &v, MDB_LAST);
if (result == MDB_NOTFOUND)
num = 0;
else if (result == 0)
num = 1 + ((const outtx*)v.mv_data)->output_id;
else
throw0(DB_ERROR(lmdb_error("Failed to query m_output_txs: ", result).c_str()));
return db_stats.ms_entries;

return num;
}

bool BlockchainLMDB::tx_exists(const crypto::hash& h) const
Expand Down
2 changes: 2 additions & 0 deletions src/blockchain_db/lmdb/db_lmdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ class BlockchainLMDB : public BlockchainDB

void remove_output(const uint64_t amount, const uint64_t& out_index);

virtual void prune_outputs(uint64_t amount);

virtual void add_spent_key(const crypto::key_image& k_image);

virtual void remove_spent_key(const crypto::key_image& k_image);
Expand Down
33 changes: 33 additions & 0 deletions src/blockchain_utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ monero_private_headers(blockchain_usage



set(blockchain_prune_known_spent_data_sources
blockchain_prune_known_spent_data.cpp
)

set(blockchain_prune_known_spent_data_private_headers)

monero_private_headers(blockchain_prune_known_spent_data
${blockchain_prune_known_spent_data_private_headers})



set(blockchain_ancestry_sources
blockchain_ancestry.cpp
)
Expand Down Expand Up @@ -265,3 +276,25 @@ set_property(TARGET blockchain_stats
PROPERTY
OUTPUT_NAME "monero-blockchain-stats")
install(TARGETS blockchain_stats DESTINATION bin)

monero_add_executable(blockchain_prune_known_spent_data
${blockchain_prune_known_spent_data_sources}
${blockchain_prune_known_spent_data_private_headers})

target_link_libraries(blockchain_prune_known_spent_data
PRIVATE
cryptonote_core
blockchain_db
p2p
version
epee
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${EXTRA_LIBRARIES})

set_property(TARGET blockchain_prune_known_spent_data
PROPERTY
OUTPUT_NAME "monero-blockchain-prune-known-spent-data")
install(TARGETS blockchain_prune_known_spent_data DESTINATION bin)
Loading