Skip to content

Commit

Permalink
Pruning
Browse files Browse the repository at this point in the history
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.

No other data is currently pruned.
  • Loading branch information
moneromooo-monero committed Nov 14, 2018
1 parent 8534f71 commit da35d5c
Show file tree
Hide file tree
Showing 46 changed files with 2,763 additions and 334 deletions.
9 changes: 9 additions & 0 deletions contrib/epee/include/string_tools.h
Expand Up @@ -233,6 +233,15 @@ POP_WARNINGS
return boost::lexical_cast<std::string>(val);
}
//----------------------------------------------------------------------------
template<typename T> inline std::string to_string_hex(const T &val)
{
std::stringstream ss;
ss << std::hex << val;
std::string s;
ss >> s;
return s;
}
//----------------------------------------------------------------------------

inline bool compare_no_case(const std::string& str1, const std::string& str2)
{
Expand Down
27 changes: 25 additions & 2 deletions src/blockchain_db/blockchain_db.cpp
Expand Up @@ -29,6 +29,7 @@
#include <boost/range/adaptor/reversed.hpp>

#include "string_tools.h"
#include "common/pruning.h"
#include "blockchain_db.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "profile_tools.h"
Expand Down Expand Up @@ -265,9 +266,12 @@ void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs)

remove_block();

CHECK_AND_ASSERT_THROW_MES(!blk.miner_tx.vin.empty(), "Miner tx has no inputs");
const uint64_t block_height = boost::get<cryptonote::txin_gen>(blk.miner_tx.vin.front()).height;
const bool has_unpruned_block = tools::has_unpruned_block(block_height, height(), get_blockchain_pruning_seed());
for (const auto& h : boost::adaptors::reverse(blk.tx_hashes))
{
txs.push_back(get_tx(h));
txs.push_back(has_unpruned_block ? get_tx(h) : get_pruned_tx(h));
remove_transaction(h);
}
remove_transaction(get_transaction_hash(blk.miner_tx));
Expand All @@ -280,7 +284,7 @@ bool BlockchainDB::is_open() const

void BlockchainDB::remove_transaction(const crypto::hash& tx_hash)
{
transaction tx = get_tx(tx_hash);
transaction tx = get_pruned_tx(tx_hash);

for (const txin_v& tx_input : tx.vin)
{
Expand Down Expand Up @@ -325,6 +329,17 @@ bool BlockchainDB::get_tx(const crypto::hash& h, cryptonote::transaction &tx) co
return true;
}

bool BlockchainDB::get_pruned_tx(const crypto::hash& h, cryptonote::transaction &tx) const
{
blobdata bd;
if (!get_pruned_tx_blob(h, bd))
return false;
if (!parse_and_validate_tx_base_from_blob(bd, tx))
throw DB_ERROR("Failed to parse transaction base from blob retrieved from the db");

return true;
}

transaction BlockchainDB::get_tx(const crypto::hash& h) const
{
transaction tx;
Expand All @@ -333,6 +348,14 @@ transaction BlockchainDB::get_tx(const crypto::hash& h) const
return tx;
}

transaction BlockchainDB::get_pruned_tx(const crypto::hash& h) const
{
transaction tx;
if (!get_pruned_tx(h, tx))
throw TX_DNE(std::string("pruned tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str());
return tx;
}

void BlockchainDB::reset_stats()
{
num_calls = 0;
Expand Down
62 changes: 62 additions & 0 deletions src/blockchain_db/blockchain_db.h
Expand Up @@ -1126,6 +1126,17 @@ class BlockchainDB
*/
virtual transaction get_tx(const crypto::hash& h) const;

/**
* @brief fetches the transaction base with the given hash
*
* If the transaction does not exist, the subclass should throw TX_DNE.
*
* @param h the hash to look for
*
* @return the transaction with the given hash
*/
virtual transaction get_pruned_tx(const crypto::hash& h) const;

/**
* @brief fetches the transaction with the given hash
*
Expand All @@ -1137,6 +1148,17 @@ class BlockchainDB
*/
virtual bool get_tx(const crypto::hash& h, transaction &tx) const;

/**
* @brief fetches the transaction base with the given hash
*
* If the transaction does not exist, the subclass should return false.
*
* @param h the hash to look for
*
* @return true iff the transaction was found
*/
virtual bool get_pruned_tx(const crypto::hash& h, transaction &tx) const;

/**
* @brief fetches the transaction blob with the given hash
*
Expand Down Expand Up @@ -1165,6 +1187,21 @@ class BlockchainDB
*/
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0;

/**
* @brief fetches the prunable transaction blob with the given hash
*
* The subclass should return the prunable transaction stored which has the given
* hash.
*
* If the transaction does not exist, or if we do not have that prunable data,
* the subclass should return false.
*
* @param h the hash to look for
*
* @return true iff the transaction was found and we have its prunable data
*/
virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0;

/**
* @brief fetches the prunable transaction hash
*
Expand Down Expand Up @@ -1405,6 +1442,31 @@ class BlockchainDB
*/
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const = 0;

/**
* @brief get the blockchain pruning seed
* @return the blockchain pruning seed
*/
virtual uint32_t get_blockchain_pruning_seed() const = 0;

/**
* @brief prunes the blockchain
* @param pruning_seed the seed to use, 0 for default (highly recommended)
* @return success iff true
*/
virtual bool prune_blockchain(uint32_t pruning_seed = 0) = 0;

/**
* @brief prunes recent blockchain changes as needed, iff pruning is enabled
* @return success iff true
*/
virtual bool update_pruning() = 0;

/**
* @brief checks pruning was done correctly, iff enabled
* @return success iff true
*/
virtual bool check_pruning() = 0;

/**
* @brief runs a function over all txpool transactions
*
Expand Down

0 comments on commit da35d5c

Please sign in to comment.