Outputs where all amounts are known spent can now be pruned
Only for pre rct for obvious reasons. Note: DO NOT use a known spent list which includes outputs which are not known spent. If the list includes any output that's just strongly thought to be spent, but not provably so, you risk finding yourself unable to sync past the point where that output is spent. I estimate only 200 MB saved on current mainnet though, unless the new blackballing rule unearths a good amount of large-amount-set extra spent outs.
This commit is contained in:
@@ -1405,6 +1405,13 @@ public:
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
||||
@@ -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__);
|
||||
@@ -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
|
||||
|
||||
@@ -345,6 +345,8 @@ private:
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user