Moves out pruned methods from block store class (#3317)

This commit is contained in:
Thiago Silva 2021-06-02 17:17:32 -03:00 committed by GitHub
commit cb4906c2be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 197 additions and 150 deletions

View file

@ -916,10 +916,10 @@ TEST (block_store, pruned_random)
nano::ledger_cache ledger_cache;
auto transaction (store->tx_begin_write ());
store->initialize (transaction, genesis, ledger_cache);
store->pruned_put (transaction, hash1);
store->pruned.put (transaction, hash1);
}
auto transaction (store->tx_begin_read ());
auto random_hash (store->pruned_random (transaction));
auto random_hash (store->pruned.random (transaction));
ASSERT_EQ (hash1, random_hash);
}
@ -1212,16 +1212,16 @@ TEST (block_store, pruned_blocks)
auto transaction (store->tx_begin_write ());
// Confirm that the store is empty
ASSERT_FALSE (store->pruned_exists (transaction, hash1));
ASSERT_EQ (store->pruned_count (transaction), 0);
ASSERT_FALSE (store->pruned.exists (transaction, hash1));
ASSERT_EQ (store->pruned.count (transaction), 0);
// Add one
store->pruned_put (transaction, hash1);
ASSERT_TRUE (store->pruned_exists (transaction, hash1));
store->pruned.put (transaction, hash1);
ASSERT_TRUE (store->pruned.exists (transaction, hash1));
}
// Confirm that it can be found
ASSERT_EQ (store->pruned_count (store->tx_begin_read ()), 1);
ASSERT_EQ (store->pruned.count (store->tx_begin_read ()), 1);
// Add another one and check that it (and the existing one) can be found
nano::open_block block2 (1, 2, key1.pub, key1.prv, key1.pub, 0);
@ -1229,37 +1229,37 @@ TEST (block_store, pruned_blocks)
auto hash2 (block2.hash ());
{
auto transaction (store->tx_begin_write ());
store->pruned_put (transaction, hash2);
ASSERT_TRUE (store->pruned_exists (transaction, hash2)); // Check new pruned hash is here
store->pruned.put (transaction, hash2);
ASSERT_TRUE (store->pruned.exists (transaction, hash2)); // Check new pruned hash is here
ASSERT_FALSE (store->block_exists (transaction, hash2));
ASSERT_TRUE (store->pruned_exists (transaction, hash1)); // Check first pruned hash is still here
ASSERT_TRUE (store->pruned.exists (transaction, hash1)); // Check first pruned hash is still here
ASSERT_FALSE (store->block_exists (transaction, hash1));
}
ASSERT_EQ (store->pruned_count (store->tx_begin_read ()), 2);
ASSERT_EQ (store->pruned.count (store->tx_begin_read ()), 2);
// Delete the first one
{
auto transaction (store->tx_begin_write ());
store->pruned_del (transaction, hash2);
ASSERT_FALSE (store->pruned_exists (transaction, hash2)); // Confirm it no longer exists
store->pruned.del (transaction, hash2);
ASSERT_FALSE (store->pruned.exists (transaction, hash2)); // Confirm it no longer exists
ASSERT_FALSE (store->block_exists (transaction, hash2)); // true for block_exists
store->block_put (transaction, hash2, block2); // Add corresponding block
ASSERT_TRUE (store->block_exists (transaction, hash2));
ASSERT_TRUE (store->pruned_exists (transaction, hash1)); // Check first pruned hash is still here
ASSERT_TRUE (store->pruned.exists (transaction, hash1)); // Check first pruned hash is still here
ASSERT_FALSE (store->block_exists (transaction, hash1));
}
ASSERT_EQ (store->pruned_count (store->tx_begin_read ()), 1);
ASSERT_EQ (store->pruned.count (store->tx_begin_read ()), 1);
// Delete original one
{
auto transaction (store->tx_begin_write ());
store->pruned_del (transaction, hash1);
ASSERT_FALSE (store->pruned_exists (transaction, hash1));
store->pruned.del (transaction, hash1);
ASSERT_FALSE (store->pruned.exists (transaction, hash1));
}
ASSERT_EQ (store->pruned_count (store->tx_begin_read ()), 0);
ASSERT_EQ (store->pruned.count (store->tx_begin_read ()), 0);
}
TEST (mdb_block_store, upgrade_v14_v15)
@ -1799,13 +1799,13 @@ TEST (mdb_block_store, upgrade_v19_v20)
auto transaction (store.tx_begin_write ());
store.initialize (transaction, genesis, ledger.cache);
// Delete pruned table
ASSERT_FALSE (mdb_drop (store.env.tx (transaction), store.pruned, 1));
ASSERT_FALSE (mdb_drop (store.env.tx (transaction), store.pruned_handle, 1));
store.version_put (transaction, 19);
}
// Upgrading should create the table
nano::mdb_store store (logger, path);
ASSERT_FALSE (store.init_error ());
ASSERT_NE (store.pruned, 0);
ASSERT_NE (store.pruned_handle, 0);
// Version should be correct
auto transaction (store.tx_begin_read ());

View file

@ -443,9 +443,9 @@ TEST (bootstrap_processor, push_diamond_pruning)
ASSERT_EQ (1, node1->ledger.pruning_action (transaction, open->hash (), 1));
ASSERT_TRUE (node1->store.block_exists (transaction, latest));
ASSERT_FALSE (node1->store.block_exists (transaction, send1->hash ()));
ASSERT_TRUE (node1->store.pruned_exists (transaction, send1->hash ()));
ASSERT_TRUE (node1->store.pruned.exists (transaction, send1->hash ()));
ASSERT_FALSE (node1->store.block_exists (transaction, open->hash ()));
ASSERT_TRUE (node1->store.pruned_exists (transaction, open->hash ()));
ASSERT_TRUE (node1->store.pruned.exists (transaction, open->hash ()));
ASSERT_TRUE (node1->store.block_exists (transaction, send2->hash ()));
ASSERT_TRUE (node1->store.block_exists (transaction, receive->hash ()));
ASSERT_EQ (2, node1->ledger.cache.pruned_count);

View file

@ -3433,7 +3433,7 @@ TEST (ledger, cache)
{
auto transaction (store->tx_begin_write ());
ledger.store.pruned_put (transaction, open->hash ());
ledger.store.pruned.put (transaction, open->hash ());
++ledger.cache.pruned_count;
}
++pruned_count;
@ -3474,7 +3474,7 @@ TEST (ledger, pruning_action)
ledger.pruning = false;
ASSERT_TRUE (ledger.block_or_pruned_exists (transaction, send1.hash ()));
ledger.pruning = true;
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
ASSERT_TRUE (store->block_exists (transaction, send2.hash ()));
// Receiving pruned block
@ -3492,10 +3492,10 @@ TEST (ledger, pruning_action)
// Middle block pruning
ASSERT_TRUE (store->block_exists (transaction, send2.hash ()));
ASSERT_EQ (1, ledger.pruning_action (transaction, send2.hash (), 1));
ASSERT_TRUE (store->pruned_exists (transaction, send2.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send2.hash ()));
ASSERT_FALSE (store->block_exists (transaction, send2.hash ()));
ASSERT_EQ (store->account.count (transaction), ledger.cache.account_count);
ASSERT_EQ (store->pruned_count (transaction), ledger.cache.pruned_count);
ASSERT_EQ (store->pruned.count (transaction), ledger.cache.pruned_count);
ASSERT_EQ (store->block_count (transaction), ledger.cache.block_count - ledger.cache.pruned_count);
}
@ -3523,16 +3523,16 @@ TEST (ledger, pruning_large_chain)
ASSERT_TRUE (store->block_exists (transaction, receive.hash ()));
last_hash = receive.hash ();
}
ASSERT_EQ (0, store->pruned_count (transaction));
ASSERT_EQ (0, store->pruned.count (transaction));
ASSERT_EQ (send_receive_pairs * 2 + 1, store->block_count (transaction));
// Pruning action
ASSERT_EQ (send_receive_pairs * 2, ledger.pruning_action (transaction, last_hash, 5));
ASSERT_TRUE (store->pruned_exists (transaction, last_hash));
ASSERT_TRUE (store->pruned.exists (transaction, last_hash));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
ASSERT_FALSE (store->block_exists (transaction, last_hash));
ASSERT_EQ (store->pruned_count (transaction), ledger.cache.pruned_count);
ASSERT_EQ (store->pruned.count (transaction), ledger.cache.pruned_count);
ASSERT_EQ (store->block_count (transaction), ledger.cache.block_count - ledger.cache.pruned_count);
ASSERT_EQ (send_receive_pairs * 2, store->pruned_count (transaction));
ASSERT_EQ (send_receive_pairs * 2, store->pruned.count (transaction));
ASSERT_EQ (1, store->block_count (transaction)); // Genesis
}
@ -3559,9 +3559,9 @@ TEST (ledger, pruning_source_rollback)
// Pruning action
ASSERT_EQ (2, ledger.pruning_action (transaction, send1.hash (), 1));
ASSERT_FALSE (store->block_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
ASSERT_FALSE (store->block_exists (transaction, epoch1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, epoch1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, epoch1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
nano::pending_info info;
ASSERT_FALSE (store->pending.get (transaction, nano::pending_key (nano::genesis_account, send1.hash ()), info));
@ -3615,9 +3615,9 @@ TEST (ledger, pruning_source_rollback_legacy)
// Pruning action
ASSERT_EQ (2, ledger.pruning_action (transaction, send2.hash (), 1));
ASSERT_FALSE (store->block_exists (transaction, send2.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, send2.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send2.hash ()));
ASSERT_FALSE (store->block_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
nano::pending_info info1;
ASSERT_FALSE (store->pending.get (transaction, nano::pending_key (nano::genesis_account, send1.hash ()), info1));
@ -3686,7 +3686,7 @@ TEST (ledger, pruning_process_error)
// Pruning action for latest block (not valid action)
ASSERT_EQ (1, ledger.pruning_action (transaction, send1.hash (), 1));
ASSERT_FALSE (store->block_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
// Attempt to process pruned block again
ASSERT_EQ (nano::process_result::old, ledger.process (transaction, send1).code);
// Attept to process new block after pruned
@ -3727,18 +3727,18 @@ TEST (ledger, pruning_legacy_blocks)
ASSERT_EQ (1, ledger.pruning_action (transaction, open1.hash (), 1));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
ASSERT_FALSE (store->block_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
ASSERT_FALSE (store->block_exists (transaction, receive1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, receive1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, receive1.hash ()));
ASSERT_FALSE (store->block_exists (transaction, change1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, change1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, change1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, send2.hash ()));
ASSERT_FALSE (store->block_exists (transaction, open1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, open1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, open1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, send3.hash ()));
ASSERT_EQ (4, ledger.cache.pruned_count);
ASSERT_EQ (7, ledger.cache.block_count);
ASSERT_EQ (store->pruned_count (transaction), ledger.cache.pruned_count);
ASSERT_EQ (store->pruned.count (transaction), ledger.cache.pruned_count);
ASSERT_EQ (store->block_count (transaction), ledger.cache.block_count - ledger.cache.pruned_count);
}
@ -3764,7 +3764,7 @@ TEST (ledger, pruning_safe_functions)
ASSERT_EQ (1, ledger.pruning_action (transaction, send1.hash (), 1));
ASSERT_FALSE (store->block_exists (transaction, send1.hash ()));
ASSERT_TRUE (ledger.block_or_pruned_exists (transaction, send1.hash ())); // true for pruned
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
ASSERT_TRUE (store->block_exists (transaction, send2.hash ()));
// Safe ledger actions
@ -3806,7 +3806,7 @@ TEST (ledger, hash_root_random)
// Pruning action
ASSERT_EQ (1, ledger.pruning_action (transaction, send1.hash (), 1));
ASSERT_FALSE (store->block_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned_exists (transaction, send1.hash ()));
ASSERT_TRUE (store->pruned.exists (transaction, send1.hash ()));
ASSERT_TRUE (store->block_exists (transaction, genesis.hash ()));
ASSERT_TRUE (store->block_exists (transaction, send2.hash ()));
// Test random block including pruned
@ -3867,7 +3867,7 @@ TEST (ledger, migrate_lmdb_to_rocksdb)
store.peer_put (transaction, endpoint_key);
store.pending.put (transaction, nano::pending_key (nano::genesis_account, send->hash ()), nano::pending_info (nano::genesis_account, 100, nano::epoch::epoch_0));
store.pruned_put (transaction, send->hash ());
store.pruned.put (transaction, send->hash ());
store.unchecked_put (transaction, nano::genesis_hash, send);
store.version_put (transaction, version);
send->sideband_set ({});

View file

@ -4742,7 +4742,7 @@ TEST (node, pruning_automatic)
ASSERT_TIMELY (2s, node1.active.empty () && node1.block_confirmed (send2->hash ()));
// Check pruning result
ASSERT_TIMELY (3s, node1.ledger.cache.pruned_count == 1);
ASSERT_TIMELY (2s, node1.store.pruned_count (node1.store.tx_begin_read ()) == 1); // Transaction commit
ASSERT_TIMELY (2s, node1.store.pruned.count (node1.store.tx_begin_read ()) == 1); // Transaction commit
ASSERT_EQ (1, node1.ledger.cache.pruned_count);
ASSERT_EQ (3, node1.ledger.cache.block_count);
ASSERT_TRUE (node1.ledger.block_or_pruned_exists (genesis.hash ()));

View file

@ -1437,7 +1437,7 @@ int main (int argc, char * const * argv)
else
{
pruned_block = true;
if (!node->store.pruned_exists (transaction, block->previous ()))
if (!node->store.pruned.exists (transaction, block->previous ()))
{
print_error_message (boost::str (boost::format ("Pruned previous block does not exist %1%\n") % block->previous ().to_string ()));
}
@ -1554,7 +1554,7 @@ int main (int argc, char * const * argv)
}
}
}
else if (!node->store.pruned_exists (transaction, block->previous ()))
else if (!node->store.pruned.exists (transaction, block->previous ()))
{
print_error_message (boost::str (boost::format ("Previous pruned block does not exist %1%\n") % block->previous ().to_string ()));
}
@ -1564,7 +1564,7 @@ int main (int argc, char * const * argv)
print_error_message (boost::str (boost::format ("Incorrect sideband block details for block %1%\n") % hash.to_string ()));
}
// Check link epoch version
if (sideband.details.is_receive && (!node->ledger.pruning || !node->store.pruned_exists (transaction, block->link ().as_block_hash ())))
if (sideband.details.is_receive && (!node->ledger.pruning || !node->store.pruned.exists (transaction, block->link ().as_block_hash ())))
{
if (sideband.source_epoch != node->store.block_version (transaction, block->link ().as_block_hash ()))
{
@ -1687,7 +1687,7 @@ int main (int argc, char * const * argv)
bool pruned (false);
if (block == nullptr)
{
pruned = node->ledger.pruning && node->store.pruned_exists (transaction, key.hash);
pruned = node->ledger.pruning && node->store.pruned.exists (transaction, key.hash);
if (!pruned)
{
print_error_message (boost::str (boost::format ("Pending block does not exist %1%\n") % key.hash.to_string ()));
@ -1697,7 +1697,7 @@ int main (int argc, char * const * argv)
{
// Check if pending destination is correct
nano::account destination (0);
bool previous_pruned = node->ledger.pruning && node->store.pruned_exists (transaction, block->previous ());
bool previous_pruned = node->ledger.pruning && node->store.pruned.exists (transaction, block->previous ());
if (previous_pruned)
{
block = node->store.block_get (transaction, key.hash);

View file

@ -1310,7 +1310,7 @@ nano::inactive_cache_status nano::active_transactions::inactive_votes_bootstrap_
lock_a.lock ();
insert_impl (lock_a, block);
}
else if (!block && status.bootstrap_started && !previously_a.bootstrap_started && (!node.ledger.pruning || !node.store.pruned_exists (transaction, hash_a)))
else if (!block && status.bootstrap_started && !previously_a.bootstrap_started && (!node.ledger.pruning || !node.store.pruned.exists (transaction, hash_a)))
{
node.gap_cache.bootstrap_start (hash_a);
}

View file

@ -89,7 +89,7 @@ void nano::confirmation_height_bounded::process (std::shared_ptr<nano::block> or
if (!block)
{
if (ledger.pruning && ledger.store.pruned_exists (transaction, current))
if (ledger.pruning && ledger.store.pruned.exists (transaction, current))
{
if (!receive_source_pairs.empty ())
{

View file

@ -386,7 +386,7 @@ void nano::confirmation_height_unbounded::cement_blocks (nano::write_guard & sco
if (!block)
{
if (ledger.pruning && ledger.store.pruned_exists (transaction, pending.hash))
if (ledger.pruning && ledger.store.pruned.exists (transaction, pending.hash))
{
pending_writes.erase (pending_writes.begin ());
--pending_writes_size;

View file

@ -3173,7 +3173,7 @@ void nano::json_handler::pruned_exists ()
auto transaction (node.store.tx_begin_read ());
if (node.ledger.pruning)
{
auto exists (node.store.pruned_exists (transaction, hash));
auto exists (node.store.pruned.exists (transaction, hash));
response_l.put ("exists", exists ? "1" : "0");
}
else

View file

@ -193,7 +193,7 @@ void nano::mdb_store::open_databases (bool & error_a, nano::transaction const &
error_a |= mdb_dbi_open (env.tx (transaction_a), "online_weight", flags, &online_weight_handle) != 0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "meta", flags, &meta) != 0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "peers", flags, &peers) != 0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "pruned", flags, &pruned) != 0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "pruned", flags, &pruned_handle) != 0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "confirmation_height", flags, &confirmation_height_handle) != 0;
error_a |= mdb_dbi_open (env.tx (transaction_a), "accounts", flags, &accounts_v0) != 0;
accounts = accounts_v0;
@ -744,7 +744,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa
void nano::mdb_store::upgrade_v19_to_v20 (nano::write_transaction const & transaction_a)
{
logger.always_log ("Preparing v19 to v20 database upgrade...");
mdb_dbi_open (env.tx (transaction_a), "pruned", MDB_CREATE, &pruned);
mdb_dbi_open (env.tx (transaction_a), "pruned", MDB_CREATE, &pruned_handle);
version_put (transaction_a, 20);
logger.always_log ("Finished creating new pruned table");
}
@ -874,7 +874,7 @@ MDB_dbi nano::mdb_store::table_to_dbi (tables table_a) const
case tables::peers:
return peers;
case tables::pruned:
return pruned;
return pruned_handle;
case tables::confirmation_height:
return confirmation_height_handle;
case tables::final_votes:
@ -913,7 +913,7 @@ bool nano::mdb_store::copy_db (boost::filesystem::path const & destination_file)
void nano::mdb_store::rebuild_db (nano::write_transaction const & transaction_a)
{
// Tables with uint256_union key
std::vector<MDB_dbi> tables = { accounts, blocks, pruned, confirmation_height_handle };
std::vector<MDB_dbi> tables = { accounts, blocks, pruned_handle, confirmation_height_handle };
for (auto const & table : tables)
{
MDB_dbi temp;

View file

@ -172,7 +172,7 @@ public:
* Pruned blocks hashes
* nano::block_hash -> none
*/
MDB_dbi pruned{ 0 };
MDB_dbi pruned_handle{ 0 };
/*
* Endpoints for peers

View file

@ -411,7 +411,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, boost::filesystem::path co
}
}
ledger.pruning = flags.enable_pruning || store.pruned_count (store.tx_begin_read ()) > 0;
ledger.pruning = flags.enable_pruning || store.pruned.count (store.tx_begin_read ()) > 0;
if (ledger.pruning)
{

View file

@ -58,6 +58,7 @@ add_library(
store/account_store_partial.hpp
store/pending_store_partial.hpp
store/online_weight_partial.hpp
store/pruned_store_partial.hpp
store/confirmation_height_store_partial.hpp
store/final_vote_store_partial.hpp)

View file

@ -105,11 +105,12 @@ bool nano::write_transaction::contains (nano::tables table_a) const
return impl->contains (table_a);
}
nano::block_store::block_store (nano::frontier_store & frontier_store_a, nano::account_store & account_store_a, nano::pending_store & pending_store_a, nano::online_weight_store & online_weight_store_a, nano::confirmation_height_store & confirmation_height_store_a, nano::final_vote_store & final_vote_store_a) :
nano::block_store::block_store (nano::frontier_store & frontier_store_a, nano::account_store & account_store_a, nano::pending_store & pending_store_a, nano::online_weight_store & online_weight_store_a, nano::pruned_store & pruned_store_a, nano::confirmation_height_store & confirmation_height_store_a, nano::final_vote_store & final_vote_store_a) :
frontier (frontier_store_a),
account (account_store_a),
pending (pending_store_a),
online_weight (online_weight_store_a),
pruned (pruned_store_a),
confirmation_height (confirmation_height_store_a),
final_vote (final_vote_store_a)
{

View file

@ -685,6 +685,24 @@ public:
virtual void clear (nano::write_transaction const &) = 0;
};
/**
* Manages pruned storage and iteration
*/
class pruned_store
{
public:
virtual void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0;
virtual void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0;
virtual bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0;
virtual nano::block_hash random (nano::transaction const & transaction_a) = 0;
virtual size_t count (nano::transaction const & transaction_a) const = 0;
virtual void clear (nano::write_transaction const &) = 0;
virtual nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0;
virtual nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a) const = 0;
virtual nano::store_iterator<nano::block_hash, std::nullptr_t> end () const = 0;
virtual void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const = 0;
};
/**
* Manages confirmation height storage and iteration
*/
@ -728,7 +746,7 @@ public:
class block_store
{
public:
explicit block_store (nano::frontier_store &, nano::account_store &, nano::pending_store &, nano::online_weight_store &, nano::confirmation_height_store &, nano::final_vote_store &);
explicit block_store (nano::frontier_store &, nano::account_store &, nano::pending_store &, nano::online_weight_store &, nano::pruned_store &, nano::confirmation_height_store &, nano::final_vote_store &);
virtual ~block_store () = default;
virtual void initialize (nano::write_transaction const &, nano::genesis const &, nano::ledger_cache &) = 0;
virtual void block_put (nano::write_transaction const &, nano::block_hash const &, nano::block const &) = 0;
@ -772,15 +790,7 @@ public:
virtual void version_put (nano::write_transaction const &, int) = 0;
virtual int version_get (nano::transaction const &) const = 0;
virtual void pruned_put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0;
virtual void pruned_del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0;
virtual bool pruned_exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0;
virtual nano::block_hash pruned_random (nano::transaction const & transaction_a) = 0;
virtual size_t pruned_count (nano::transaction const & transaction_a) const = 0;
virtual void pruned_clear (nano::write_transaction const &) = 0;
virtual nano::store_iterator<nano::block_hash, std::nullptr_t> pruned_begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0;
virtual nano::store_iterator<nano::block_hash, std::nullptr_t> pruned_begin (nano::transaction const & transaction_a) const = 0;
virtual nano::store_iterator<nano::block_hash, std::nullptr_t> pruned_end () const = 0;
pruned_store & pruned;
virtual void peer_put (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) = 0;
virtual void peer_del (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) = 0;
@ -793,7 +803,6 @@ public:
confirmation_height_store & confirmation_height;
virtual void unchecked_for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>)> const & action_a) const = 0;
virtual void pruned_for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const = 0;
virtual void blocks_for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, block_w_sideband>, nano::store_iterator<nano::block_hash, block_w_sideband>)> const & action_a) const = 0;
virtual uint64_t block_account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0;

View file

@ -12,6 +12,7 @@
#include <nano/secure/store/frontier_store_partial.hpp>
#include <nano/secure/store/online_weight_partial.hpp>
#include <nano/secure/store/pending_store_partial.hpp>
#include <nano/secure/store/pruned_store_partial.hpp>
#include <crypto/cryptopp/words.h>
@ -45,6 +46,7 @@ class block_store_partial : public block_store
nano::account_store_partial<Val, Derived_Store> account_store_partial;
nano::pending_store_partial<Val, Derived_Store> pending_store_partial;
nano::online_weight_store_partial<Val, Derived_Store> online_weight_store_partial;
nano::pruned_store_partial<Val, Derived_Store> pruned_store_partial;
nano::confirmation_height_store_partial<Val, Derived_Store> confirmation_height_store_partial;
nano::final_vote_store_partial<Val, Derived_Store> final_vote_store_partial;
@ -59,15 +61,17 @@ public:
friend class nano::account_store_partial<Val, Derived_Store>;
friend class nano::pending_store_partial<Val, Derived_Store>;
friend class nano::online_weight_store_partial<Val, Derived_Store>;
friend class nano::pruned_store_partial<Val, Derived_Store>;
friend class nano::confirmation_height_store_partial<Val, Derived_Store>;
friend class nano::final_vote_store_partial<Val, Derived_Store>;
block_store_partial () :
block_store{ frontier_store_partial, account_store_partial, pending_store_partial, online_weight_store_partial, confirmation_height_store_partial, final_vote_store_partial },
block_store{ frontier_store_partial, account_store_partial, pending_store_partial, online_weight_store_partial, pruned_store_partial, confirmation_height_store_partial, final_vote_store_partial },
frontier_store_partial{ *this },
account_store_partial{ *this },
pending_store_partial{ *this },
online_weight_store_partial{ *this },
pruned_store_partial{ *this },
confirmation_height_store_partial{ *this },
final_vote_store_partial{ *this }
{
@ -255,11 +259,6 @@ public:
return nano::store_iterator<nano::block_hash, nano::block_w_sideband> (nullptr);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> pruned_end () const override
{
return nano::store_iterator<nano::block_hash, std::nullptr_t> (nullptr);
}
int version_get (nano::transaction const & transaction_a) const override
{
nano::uint256_union version_key (1);
@ -333,34 +332,6 @@ public:
release_assert_success (*this, status);
}
void pruned_put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override
{
auto status = put_key (transaction_a, tables::pruned, hash_a);
release_assert_success (*this, status);
}
void pruned_del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override
{
auto status = del (transaction_a, tables::pruned, hash_a);
release_assert_success (*this, status);
}
bool pruned_exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return exists (transaction_a, tables::pruned, nano::db_val<Val> (hash_a));
}
size_t pruned_count (nano::transaction const & transaction_a) const override
{
return count (transaction_a, tables::pruned);
}
void pruned_clear (nano::write_transaction const & transaction_a) override
{
auto status = drop (transaction_a, tables::pruned);
release_assert_success (*this, status);
}
void peer_put (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override
{
auto status = put_key (transaction_a, tables::peers, endpoint_a);
@ -413,19 +384,6 @@ public:
return existing->second;
}
nano::block_hash pruned_random (nano::transaction const & transaction_a) override
{
nano::block_hash random_hash;
nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ());
auto existing = make_iterator<nano::block_hash, nano::db_val<Val>> (transaction_a, tables::pruned, nano::db_val<Val> (random_hash));
auto end (nano::store_iterator<nano::block_hash, nano::db_val<Val>> (nullptr));
if (existing == end)
{
existing = make_iterator<nano::block_hash, nano::db_val<Val>> (transaction_a, tables::pruned);
}
return existing != end ? existing->first : 0;
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> blocks_begin (nano::transaction const & transaction_a) const override
{
return make_iterator<nano::block_hash, nano::block_w_sideband> (transaction_a, tables::blocks);
@ -451,16 +409,6 @@ public:
return make_iterator<nano::endpoint_key, nano::no_value> (transaction_a, tables::peers);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> pruned_begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned, nano::db_val<Val> (hash_a));
}
nano::store_iterator<nano::block_hash, std::nullptr_t> pruned_begin (nano::transaction const & transaction_a) const override
{
return make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned);
}
size_t unchecked_count (nano::transaction const & transaction_a) override
{
return count (transaction_a, tables::unchecked);
@ -486,15 +434,6 @@ public:
});
}
void pruned_for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->tx_begin_read ());
action_a (transaction, this->pruned_begin (transaction, start), !is_last ? this->pruned_begin (transaction, end) : this->pruned_end ());
});
}
int const minimum_version{ 14 };
protected:

View file

@ -783,7 +783,7 @@ void nano::ledger::initialize (nano::generate_cache const & generate_cache_a)
}
auto transaction (store.tx_begin_read ());
cache.pruned_count = store.pruned_count (transaction);
cache.pruned_count = store.pruned.count (transaction);
// Final votes requirement for confirmation canary block
nano::confirmation_height_info confirmation_height_info;
@ -893,7 +893,7 @@ bool nano::ledger::block_or_pruned_exists (nano::block_hash const & hash_a) cons
bool nano::ledger::block_or_pruned_exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
if (store.pruned_exists (transaction_a, hash_a))
if (store.pruned.exists (transaction_a, hash_a))
{
return true;
}
@ -999,7 +999,7 @@ std::pair<nano::block_hash, nano::block_hash> nano::ledger::hash_root_random (na
// Pruned cache cannot guarantee that pruned blocks are already commited
if (region < cache.pruned_count)
{
hash = store.pruned_random (transaction_a);
hash = store.pruned.random (transaction_a);
}
if (hash.is_zero ())
{
@ -1323,7 +1323,7 @@ std::shared_ptr<nano::block> nano::ledger::forked_block (nano::transaction const
bool nano::ledger::block_confirmed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
if (store.pruned_exists (transaction_a, hash_a))
if (store.pruned.exists (transaction_a, hash_a))
{
return true;
}
@ -1348,7 +1348,7 @@ uint64_t nano::ledger::pruning_action (nano::write_transaction & transaction_a,
if (block != nullptr)
{
store.block_del (transaction_a, hash);
store.pruned_put (transaction_a, hash);
store.pruned.put (transaction_a, hash);
hash = block->previous ();
++pruned_count;
++cache.pruned_count;
@ -1358,7 +1358,7 @@ uint64_t nano::ledger::pruning_action (nano::write_transaction & transaction_a,
transaction_a.renew ();
}
}
else if (store.pruned_exists (transaction_a, hash))
else if (store.pruned.exists (transaction_a, hash))
{
hash = 0;
}
@ -1481,12 +1481,12 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data
}
});
store.pruned_for_each_par (
store.pruned.for_each_par (
[&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) {
for (; i != n; ++i)
{
auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::pruned }));
rocksdb_store->pruned_put (rocksdb_transaction, i->first);
rocksdb_store->pruned.put (rocksdb_transaction, i->first);
}
});
@ -1517,7 +1517,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data
// Compare counts
error |= store.unchecked_count (lmdb_transaction) != rocksdb_store->unchecked_count (rocksdb_transaction);
error |= store.peer_count (lmdb_transaction) != rocksdb_store->peer_count (rocksdb_transaction);
error |= store.pruned_count (lmdb_transaction) != rocksdb_store->pruned_count (rocksdb_transaction);
error |= store.pruned.count (lmdb_transaction) != rocksdb_store->pruned.count (rocksdb_transaction);
error |= store.final_vote.count (lmdb_transaction) != rocksdb_store->final_vote.count (rocksdb_transaction);
error |= store.online_weight.count (lmdb_transaction) != rocksdb_store->online_weight.count (rocksdb_transaction);
error |= store.version_get (lmdb_transaction) != rocksdb_store->version_get (rocksdb_transaction);

View file

@ -0,0 +1,97 @@
#pragma once
#include <nano/secure/blockstore_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class block_store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (block_store_partial<Val, Derived_Store> const & block_store, const int status);
template <typename Val, typename Derived_Store>
class pruned_store_partial : public pruned_store
{
private:
nano::block_store_partial<Val, Derived_Store> & block_store;
friend void release_assert_success<Val, Derived_Store> (block_store_partial<Val, Derived_Store> const & block_store, const int status);
public:
explicit pruned_store_partial (nano::block_store_partial<Val, Derived_Store> & block_store_a) :
block_store (block_store_a){};
void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override
{
auto status = block_store.put_key (transaction_a, tables::pruned, hash_a);
release_assert_success (block_store, status);
}
void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override
{
auto status = block_store.del (transaction_a, tables::pruned, hash_a);
release_assert_success (block_store, status);
}
bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return block_store.exists (transaction_a, tables::pruned, nano::db_val<Val> (hash_a));
}
nano::block_hash random (nano::transaction const & transaction_a) override
{
nano::block_hash random_hash;
nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ());
auto existing = block_store.template make_iterator<nano::block_hash, nano::db_val<Val>> (transaction_a, tables::pruned, nano::db_val<Val> (random_hash));
auto end (nano::store_iterator<nano::block_hash, nano::db_val<Val>> (nullptr));
if (existing == end)
{
existing = block_store.template make_iterator<nano::block_hash, nano::db_val<Val>> (transaction_a, tables::pruned);
}
return existing != end ? existing->first : 0;
}
size_t count (nano::transaction const & transaction_a) const override
{
return block_store.count (transaction_a, tables::pruned);
}
void clear (nano::write_transaction const & transaction_a) override
{
auto status = block_store.drop (transaction_a, tables::pruned);
release_assert_success (block_store, status);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return block_store.template make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned, nano::db_val<Val> (hash_a));
}
nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a) const override
{
return block_store.template make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> end () const override
{
return nano::store_iterator<nano::block_hash, std::nullptr_t> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->block_store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}
};
}

View file

@ -435,7 +435,7 @@ TEST (store, pruned_load)
{
nano::block_hash random_hash;
nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ());
store->pruned_put (transaction, random_hash);
store->pruned.put (transaction, random_hash);
}
}
if (!nano::using_rocksdb_in_tests ())
@ -444,20 +444,20 @@ TEST (store, pruned_load)
for (auto k (0); k < batch_size / 2; ++k)
{
auto hash (hashes.begin ());
store->pruned_del (transaction, *hash);
store->pruned.del (transaction, *hash);
hashes.erase (hash);
}
}
}
auto transaction (store->tx_begin_read ());
ASSERT_EQ (expected_result, store->pruned_count (transaction));
ASSERT_EQ (expected_result, store->pruned.count (transaction));
}
// Reinitialize store
{
auto store = nano::make_store (logger, path);
ASSERT_FALSE (store->init_error ());
auto transaction (store->tx_begin_read ());
ASSERT_EQ (expected_result, store->pruned_count (transaction));
ASSERT_EQ (expected_result, store->pruned.count (transaction));
}
}