From e9eb258ab0ebd18df6c0879659127229ee2fec60 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sat, 9 Apr 2022 13:34:11 +0100 Subject: [PATCH] Remove db templates (#3783) * Removing templates from frontier_store and using simple polymorphism. * Remove account_store_partial and replace with simply concrete implementations for mdb and rocksdb. * Removing pending_store_partial and separating in to mdb/rocksdb implementations. * De-templatizing unchecked_store. * De-template online_weight_store. * De-templating pruned_store_partial. * De-templating peer_store. * De-templating confirmation_height_store. * De-templating final_vote_store. * De-templating version_store. * De-templating block_store. * Removing static downcast in make_iterator. * Formatting. --- nano/node/CMakeLists.txt | 44 +++ nano/node/lmdb/account_store.cpp | 71 ++++ nano/node/lmdb/account_store.hpp | 26 ++ nano/node/lmdb/block_store.cpp | 296 +++++++++++++++++ nano/node/lmdb/block_store.hpp | 44 +++ nano/node/lmdb/confirmation_height_store.cpp | 83 +++++ nano/node/lmdb/confirmation_height_store.hpp | 26 ++ nano/node/lmdb/final_vote_store.cpp | 88 +++++ nano/node/lmdb/final_vote_store.hpp | 26 ++ nano/node/lmdb/frontier_store.cpp | 56 ++++ nano/node/lmdb/frontier_store.hpp | 24 ++ nano/node/lmdb/lmdb.cpp | 73 ++-- nano/node/lmdb/lmdb.hpp | 72 ++-- nano/node/lmdb/online_weight_store.cpp | 45 +++ nano/node/lmdb/online_weight_store.hpp | 23 ++ nano/node/lmdb/peer_store.cpp | 43 +++ nano/node/lmdb/peer_store.hpp | 23 ++ nano/node/lmdb/pending_store.cpp | 71 ++++ nano/node/lmdb/pending_store.hpp | 25 ++ nano/node/lmdb/pruned_store.cpp | 69 ++++ nano/node/lmdb/pruned_store.hpp | 26 ++ nano/node/lmdb/unchecked_store.cpp | 62 ++++ nano/node/lmdb/unchecked_store.hpp | 26 ++ nano/node/lmdb/version_store.cpp | 28 ++ nano/node/lmdb/version_store.hpp | 18 + nano/node/rocksdb/account_store.cpp | 71 ++++ nano/node/rocksdb/account_store.hpp | 26 ++ nano/node/rocksdb/block_store.cpp | 296 +++++++++++++++++ nano/node/rocksdb/block_store.hpp | 46 +++ .../rocksdb/confirmation_height_store.cpp | 83 +++++ .../rocksdb/confirmation_height_store.hpp | 26 ++ nano/node/rocksdb/final_vote_store.cpp | 88 +++++ nano/node/rocksdb/final_vote_store.hpp | 26 ++ nano/node/rocksdb/frontier_store.cpp | 56 ++++ nano/node/rocksdb/frontier_store.hpp | 24 ++ nano/node/rocksdb/online_weight_store.cpp | 45 +++ nano/node/rocksdb/online_weight_store.hpp | 23 ++ nano/node/rocksdb/peer_store.cpp | 43 +++ nano/node/rocksdb/peer_store.hpp | 23 ++ nano/node/rocksdb/pending_store.cpp | 71 ++++ nano/node/rocksdb/pending_store.hpp | 25 ++ nano/node/rocksdb/pruned_store.cpp | 69 ++++ nano/node/rocksdb/pruned_store.hpp | 26 ++ nano/node/rocksdb/rocksdb.cpp | 61 ++-- nano/node/rocksdb/rocksdb.hpp | 77 ++--- nano/node/rocksdb/unchecked_store.cpp | 62 ++++ nano/node/rocksdb/unchecked_store.hpp | 26 ++ nano/node/rocksdb/version_store.cpp | 28 ++ nano/node/rocksdb/version_store.hpp | 18 + nano/secure/CMakeLists.txt | 13 +- nano/secure/store/account_store_partial.hpp | 101 ------ nano/secure/store/block_store_partial.hpp | 313 ------------------ .../confirmation_height_store_partial.hpp | 109 ------ .../secure/store/final_vote_store_partial.hpp | 115 ------- nano/secure/store/frontier_store_partial.hpp | 82 ----- nano/secure/store/online_weight_partial.hpp | 65 ---- nano/secure/store/peer_store_partial.hpp | 70 ---- nano/secure/store/pending_store_partial.hpp | 100 ------ nano/secure/store/pruned_store_partial.hpp | 97 ------ nano/secure/store/unchecked_store_partial.hpp | 90 ----- nano/secure/store/version_store_partial.hpp | 47 --- nano/secure/store_partial.hpp | 106 +++--- 62 files changed, 2617 insertions(+), 1418 deletions(-) create mode 100644 nano/node/lmdb/account_store.cpp create mode 100644 nano/node/lmdb/account_store.hpp create mode 100644 nano/node/lmdb/block_store.cpp create mode 100644 nano/node/lmdb/block_store.hpp create mode 100644 nano/node/lmdb/confirmation_height_store.cpp create mode 100644 nano/node/lmdb/confirmation_height_store.hpp create mode 100644 nano/node/lmdb/final_vote_store.cpp create mode 100644 nano/node/lmdb/final_vote_store.hpp create mode 100644 nano/node/lmdb/frontier_store.cpp create mode 100644 nano/node/lmdb/frontier_store.hpp create mode 100644 nano/node/lmdb/online_weight_store.cpp create mode 100644 nano/node/lmdb/online_weight_store.hpp create mode 100644 nano/node/lmdb/peer_store.cpp create mode 100644 nano/node/lmdb/peer_store.hpp create mode 100644 nano/node/lmdb/pending_store.cpp create mode 100644 nano/node/lmdb/pending_store.hpp create mode 100644 nano/node/lmdb/pruned_store.cpp create mode 100644 nano/node/lmdb/pruned_store.hpp create mode 100644 nano/node/lmdb/unchecked_store.cpp create mode 100644 nano/node/lmdb/unchecked_store.hpp create mode 100644 nano/node/lmdb/version_store.cpp create mode 100644 nano/node/lmdb/version_store.hpp create mode 100644 nano/node/rocksdb/account_store.cpp create mode 100644 nano/node/rocksdb/account_store.hpp create mode 100644 nano/node/rocksdb/block_store.cpp create mode 100644 nano/node/rocksdb/block_store.hpp create mode 100644 nano/node/rocksdb/confirmation_height_store.cpp create mode 100644 nano/node/rocksdb/confirmation_height_store.hpp create mode 100644 nano/node/rocksdb/final_vote_store.cpp create mode 100644 nano/node/rocksdb/final_vote_store.hpp create mode 100644 nano/node/rocksdb/frontier_store.cpp create mode 100644 nano/node/rocksdb/frontier_store.hpp create mode 100644 nano/node/rocksdb/online_weight_store.cpp create mode 100644 nano/node/rocksdb/online_weight_store.hpp create mode 100644 nano/node/rocksdb/peer_store.cpp create mode 100644 nano/node/rocksdb/peer_store.hpp create mode 100644 nano/node/rocksdb/pending_store.cpp create mode 100644 nano/node/rocksdb/pending_store.hpp create mode 100644 nano/node/rocksdb/pruned_store.cpp create mode 100644 nano/node/rocksdb/pruned_store.hpp create mode 100644 nano/node/rocksdb/unchecked_store.cpp create mode 100644 nano/node/rocksdb/unchecked_store.hpp create mode 100644 nano/node/rocksdb/version_store.cpp create mode 100644 nano/node/rocksdb/version_store.hpp delete mode 100644 nano/secure/store/account_store_partial.hpp delete mode 100644 nano/secure/store/block_store_partial.hpp delete mode 100644 nano/secure/store/confirmation_height_store_partial.hpp delete mode 100644 nano/secure/store/final_vote_store_partial.hpp delete mode 100644 nano/secure/store/frontier_store_partial.hpp delete mode 100644 nano/secure/store/online_weight_partial.hpp delete mode 100644 nano/secure/store/peer_store_partial.hpp delete mode 100644 nano/secure/store/pending_store_partial.hpp delete mode 100644 nano/secure/store/pruned_store_partial.hpp delete mode 100644 nano/secure/store/unchecked_store_partial.hpp delete mode 100644 nano/secure/store/version_store_partial.hpp diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index 0a737a55..ca7645df 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -82,6 +82,28 @@ add_library( json_handler.cpp ledger_walker.hpp ledger_walker.cpp + lmdb/account_store.hpp + lmdb/account_store.cpp + lmdb/block_store.hpp + lmdb/block_store.cpp + lmdb/confirmation_height_store.hpp + lmdb/confirmation_height_store.cpp + lmdb/final_vote_store.hpp + lmdb/final_vote_store.cpp + lmdb/frontier_store.hpp + lmdb/frontier_store.cpp + lmdb/online_weight_store.hpp + lmdb/online_weight_store.cpp + lmdb/peer_store.hpp + lmdb/peer_store.cpp + lmdb/pending_store.hpp + lmdb/pending_store.cpp + lmdb/pruned_store.hpp + lmdb/pruned_store.cpp + lmdb/version_store.hpp + lmdb/version_store.cpp + lmdb/unchecked_store.hpp + lmdb/unchecked_store.cpp lmdb/lmdb.hpp lmdb/lmdb.cpp lmdb/lmdb_env.hpp @@ -121,6 +143,28 @@ add_library( repcrawler.cpp request_aggregator.hpp request_aggregator.cpp + rocksdb/account_store.hpp + rocksdb/account_store.cpp + rocksdb/block_store.hpp + rocksdb/block_store.cpp + rocksdb/confirmation_height_store.hpp + rocksdb/confirmation_height_store.cpp + rocksdb/final_vote_store.hpp + rocksdb/final_vote_store.cpp + rocksdb/frontier_store.hpp + rocksdb/frontier_store.cpp + rocksdb/online_weight_store.hpp + rocksdb/online_weight_store.cpp + rocksdb/peer_store.hpp + rocksdb/peer_store.cpp + rocksdb/pending_store.hpp + rocksdb/pending_store.cpp + rocksdb/pruned_store.hpp + rocksdb/pruned_store.cpp + rocksdb/unchecked_store.hpp + rocksdb/unchecked_store.cpp + rocksdb/version_store.hpp + rocksdb/version_store.cpp rocksdb/rocksdb.hpp rocksdb/rocksdb.cpp rocksdb/rocksdb_iterator.hpp diff --git a/nano/node/lmdb/account_store.cpp b/nano/node/lmdb/account_store.cpp new file mode 100644 index 00000000..c7dfb72c --- /dev/null +++ b/nano/node/lmdb/account_store.cpp @@ -0,0 +1,71 @@ +#include +#include + +nano::account_store_mdb::account_store_mdb (nano::mdb_store & store_a) : + store (store_a){}; + +void nano::account_store_mdb::put (nano::write_transaction const & transaction, nano::account const & account, nano::account_info const & info) +{ + auto status = store.put (transaction, tables::accounts, account, info); + store.release_assert_success (status); +} + +bool nano::account_store_mdb::get (nano::transaction const & transaction, nano::account const & account, nano::account_info & info) +{ + nano::mdb_val value; + auto status1 (store.get (transaction, tables::accounts, account, value)); + release_assert (store.success (status1) || store.not_found (status1)); + bool result (true); + if (store.success (status1)) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = info.deserialize (stream); + } + return result; +} + +void nano::account_store_mdb::del (nano::write_transaction const & transaction_a, nano::account const & account_a) +{ + auto status = store.del (transaction_a, tables::accounts, account_a); + release_assert_success (store, status); +} + +bool nano::account_store_mdb::exists (nano::transaction const & transaction_a, nano::account const & account_a) +{ + auto iterator (begin (transaction_a, account_a)); + return iterator != end () && nano::account (iterator->first) == account_a; +} + +size_t nano::account_store_mdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::accounts); +} + +nano::store_iterator nano::account_store_mdb::begin (nano::transaction const & transaction, nano::account const & account) const +{ + return store.make_iterator (transaction, tables::accounts, account); +} + +nano::store_iterator nano::account_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::accounts); +} + +nano::store_iterator nano::account_store_mdb::rbegin (nano::transaction const & transaction_a) const +{ + return store.make_iterator (transaction_a, tables::accounts, false); +} + +nano::store_iterator nano::account_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::account_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/account_store.hpp b/nano/node/lmdb/account_store.hpp new file mode 100644 index 00000000..f4443607 --- /dev/null +++ b/nano/node/lmdb/account_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class account_store_mdb : public account_store +{ +private: + nano::mdb_store & store; + +public: + explicit account_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction, nano::account const & account, nano::account_info const & info) override; + bool get (nano::transaction const & transaction_a, nano::account const & account_a, nano::account_info & info_a) override; + void del (nano::write_transaction const & transaction_a, nano::account const & account_a) override; + bool exists (nano::transaction const & transaction_a, nano::account const & account_a) override; + size_t count (nano::transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::account const & account_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator rbegin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/lmdb/block_store.cpp b/nano/node/lmdb/block_store.cpp new file mode 100644 index 00000000..8caff65d --- /dev/null +++ b/nano/node/lmdb/block_store.cpp @@ -0,0 +1,296 @@ +#include +#include + +namespace nano +{ +/** + * Fill in our predecessors + */ +class block_predecessor_mdb_set : public nano::block_visitor +{ +public: + block_predecessor_mdb_set (nano::write_transaction const & transaction_a, nano::block_store_mdb & block_store_a); + virtual ~block_predecessor_mdb_set () = default; + void fill_value (nano::block const & block_a); + void send_block (nano::send_block const & block_a) override; + void receive_block (nano::receive_block const & block_a) override; + void open_block (nano::open_block const & block_a) override; + void change_block (nano::change_block const & block_a) override; + void state_block (nano::state_block const & block_a) override; + nano::write_transaction const & transaction; + nano::block_store_mdb & block_store; +}; +} + +nano::block_store_mdb::block_store_mdb (nano::mdb_store & store_a) : + store{ store_a } {}; + +void nano::block_store_mdb::put (nano::write_transaction const & transaction, nano::block_hash const & hash, nano::block const & block) +{ + debug_assert (block.sideband ().successor.is_zero () || exists (transaction, block.sideband ().successor)); + std::vector vector; + { + nano::vectorstream stream (vector); + nano::serialize_block (stream, block); + block.sideband ().serialize (stream, block.type ()); + } + raw_put (transaction, vector, hash); + block_predecessor_mdb_set predecessor (transaction, *this); + block.visit (predecessor); + debug_assert (block.previous ().is_zero () || successor (transaction, block.previous ()) == hash); +} + +void nano::block_store_mdb::raw_put (nano::write_transaction const & transaction_a, std::vector const & data, nano::block_hash const & hash_a) +{ + nano::mdb_val value{ data.size (), (void *)data.data () }; + auto status = store.put (transaction_a, tables::blocks, hash_a, value); + release_assert_success (store, status); +} + +nano::block_hash nano::block_store_mdb::successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + nano::mdb_val value; + block_raw_get (transaction_a, hash_a, value); + nano::block_hash result; + if (value.size () != 0) + { + debug_assert (value.size () >= result.bytes.size ()); + auto type = block_type_from_raw (value.data ()); + nano::bufferstream stream (reinterpret_cast (value.data ()) + block_successor_offset (transaction_a, value.size (), type), result.bytes.size ()); + auto error (nano::try_read (stream, result.bytes)); + (void)error; + debug_assert (!error); + } + else + { + result.clear (); + } + return result; +} + +void nano::block_store_mdb::successor_clear (nano::write_transaction const & transaction, nano::block_hash const & hash) +{ + nano::mdb_val value; + block_raw_get (transaction, hash, value); + debug_assert (value.size () != 0); + auto type = block_type_from_raw (value.data ()); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::fill_n (data.begin () + block_successor_offset (transaction, value.size (), type), sizeof (nano::block_hash), uint8_t{ 0 }); + raw_put (transaction, data, hash); +} + +std::shared_ptr nano::block_store_mdb::get (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + nano::mdb_val value; + block_raw_get (transaction, hash, value); + std::shared_ptr result; + if (value.size () != 0) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + nano::block_type type; + auto error (try_read (stream, type)); + release_assert (!error); + result = nano::deserialize_block (stream, type); + release_assert (result != nullptr); + nano::block_sideband sideband; + error = (sideband.deserialize (stream, type)); + release_assert (!error); + result->sideband_set (sideband); + } + return result; +} + +std::shared_ptr nano::block_store_mdb::get_no_sideband (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + nano::mdb_val value; + block_raw_get (transaction, hash, value); + std::shared_ptr result; + if (value.size () != 0) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = nano::deserialize_block (stream); + debug_assert (result != nullptr); + } + return result; +} + +std::shared_ptr nano::block_store_mdb::random (nano::transaction const & transaction) +{ + nano::block_hash hash; + nano::random_pool::generate_block (hash.bytes.data (), hash.bytes.size ()); + auto existing = begin (transaction, hash); + if (existing == end ()) + { + existing = begin (transaction); + } + debug_assert (existing != end ()); + return existing->second.block; +} + +void nano::block_store_mdb::del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto status = store.del (transaction_a, tables::blocks, hash_a); + release_assert_success (store, status); +} + +bool nano::block_store_mdb::exists (nano::transaction const & transaction, nano::block_hash const & hash) +{ + nano::mdb_val junk; + block_raw_get (transaction, hash, junk); + return junk.size () != 0; +} + +uint64_t nano::block_store_mdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::blocks); +} + +nano::account nano::block_store_mdb::account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + auto block (get (transaction_a, hash_a)); + debug_assert (block != nullptr); + return account_calculated (*block); +} + +nano::account nano::block_store_mdb::account_calculated (nano::block const & block_a) const +{ + debug_assert (block_a.has_sideband ()); + nano::account result (block_a.account ()); + if (result.is_zero ()) + { + result = block_a.sideband ().account; + } + debug_assert (!result.is_zero ()); + return result; +} + +nano::store_iterator nano::block_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::blocks); +} + +nano::store_iterator nano::block_store_mdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + return store.make_iterator (transaction, tables::blocks, hash); +} + +nano::store_iterator nano::block_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +nano::uint128_t nano::block_store_mdb::balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto block (get (transaction_a, hash_a)); + release_assert (block); + nano::uint128_t result (balance_calculated (block)); + return result; +} + +nano::uint128_t nano::block_store_mdb::balance_calculated (std::shared_ptr const & block_a) const +{ + nano::uint128_t result; + switch (block_a->type ()) + { + case nano::block_type::open: + case nano::block_type::receive: + case nano::block_type::change: + result = block_a->sideband ().balance.number (); + break; + case nano::block_type::send: + result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); + break; + case nano::block_type::state: + result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); + break; + case nano::block_type::invalid: + case nano::block_type::not_a_block: + release_assert (false); + break; + } + return result; +} + +nano::epoch nano::block_store_mdb::version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto block = get (transaction_a, hash_a); + if (block && block->type () == nano::block_type::state) + { + return block->sideband ().details.epoch; + } + + return nano::epoch::epoch_0; +} + +void nano::block_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} + +// Converts a block hash to a block height +uint64_t nano::block_store_mdb::account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + auto block = get (transaction_a, hash_a); + return block->sideband ().height; +} + +void nano::block_store_mdb::block_raw_get (nano::transaction const & transaction, nano::block_hash const & hash, nano::mdb_val & value) const +{ + auto status = store.get (transaction, tables::blocks, hash, value); + release_assert (store.success (status) || store.not_found (status)); +} + +size_t nano::block_store_mdb::block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const +{ + return entry_size_a - nano::block_sideband::size (type_a); +} + +nano::block_type nano::block_store_mdb::block_type_from_raw (void * data_a) +{ + // The block type is the first byte + return static_cast ((reinterpret_cast (data_a))[0]); +} + +nano::block_predecessor_mdb_set::block_predecessor_mdb_set (nano::write_transaction const & transaction_a, nano::block_store_mdb & block_store_a) : + transaction{ transaction_a }, + block_store{ block_store_a } +{ +} +void nano::block_predecessor_mdb_set::fill_value (nano::block const & block_a) +{ + auto hash = block_a.hash (); + nano::mdb_val value; + block_store.block_raw_get (transaction, block_a.previous (), value); + debug_assert (value.size () != 0); + auto type = block_store.block_type_from_raw (value.data ()); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::copy (hash.bytes.begin (), hash.bytes.end (), data.begin () + block_store.block_successor_offset (transaction, value.size (), type)); + block_store.raw_put (transaction, data, block_a.previous ()); +} +void nano::block_predecessor_mdb_set::send_block (nano::send_block const & block_a) +{ + fill_value (block_a); +} +void nano::block_predecessor_mdb_set::receive_block (nano::receive_block const & block_a) +{ + fill_value (block_a); +} +void nano::block_predecessor_mdb_set::open_block (nano::open_block const & block_a) +{ + // Open blocks don't have a predecessor +} +void nano::block_predecessor_mdb_set::change_block (nano::change_block const & block_a) +{ + fill_value (block_a); +} +void nano::block_predecessor_mdb_set::state_block (nano::state_block const & block_a) +{ + if (!block_a.previous ().is_zero ()) + { + fill_value (block_a); + } +} diff --git a/nano/node/lmdb/block_store.hpp b/nano/node/lmdb/block_store.hpp new file mode 100644 index 00000000..874b9356 --- /dev/null +++ b/nano/node/lmdb/block_store.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +using mdb_val = db_val; +class block_predecessor_mdb_set; +class block_store_mdb : public block_store +{ + friend class block_predecessor_mdb_set; + nano::mdb_store & store; + +public: + explicit block_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a) override; + void raw_put (nano::write_transaction const & transaction_a, std::vector const & data, nano::block_hash const & hash_a) override; + nano::block_hash successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + void successor_clear (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + std::shared_ptr get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + std::shared_ptr get_no_sideband (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + std::shared_ptr random (nano::transaction const & transaction_a) override; + void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override; + uint64_t count (nano::transaction const & transaction_a) override; + nano::account account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::account account_calculated (nano::block const & block_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::store_iterator end () const override; + nano::uint128_t balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override; + nano::uint128_t balance_calculated (std::shared_ptr const & block_a) const override; + nano::epoch version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; + // Converts a block hash to a block height + uint64_t account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + +protected: + void block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::mdb_val & value) const; + size_t block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const; + static nano::block_type block_type_from_raw (void * data_a); +}; +} diff --git a/nano/node/lmdb/confirmation_height_store.cpp b/nano/node/lmdb/confirmation_height_store.cpp new file mode 100644 index 00000000..c127bd34 --- /dev/null +++ b/nano/node/lmdb/confirmation_height_store.cpp @@ -0,0 +1,83 @@ +#include +#include + +nano::confirmation_height_store_mdb::confirmation_height_store_mdb (nano::mdb_store & store) : + store{ store } +{ +} + +void nano::confirmation_height_store_mdb::put (nano::write_transaction const & transaction, nano::account const & account, nano::confirmation_height_info const & confirmation_height_info) +{ + auto status = store.put (transaction, tables::confirmation_height, account, confirmation_height_info); + release_assert_success (store, status); +} + +bool nano::confirmation_height_store_mdb::get (nano::transaction const & transaction, nano::account const & account, nano::confirmation_height_info & confirmation_height_info) +{ + nano::mdb_val value; + auto status = store.get (transaction, tables::confirmation_height, account, value); + release_assert (store.success (status) || store.not_found (status)); + bool result (true); + if (store.success (status)) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = confirmation_height_info.deserialize (stream); + } + if (result) + { + confirmation_height_info.height = 0; + confirmation_height_info.frontier = 0; + } + + return result; +} + +bool nano::confirmation_height_store_mdb::exists (nano::transaction const & transaction, nano::account const & account) const +{ + return store.exists (transaction, tables::confirmation_height, account); +} + +void nano::confirmation_height_store_mdb::del (nano::write_transaction const & transaction, nano::account const & account) +{ + auto status = store.del (transaction, tables::confirmation_height, account); + release_assert_success (store, status); +} + +uint64_t nano::confirmation_height_store_mdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::confirmation_height); +} + +void nano::confirmation_height_store_mdb::clear (nano::write_transaction const & transaction_a, nano::account const & account_a) +{ + del (transaction_a, account_a); +} + +void nano::confirmation_height_store_mdb::clear (nano::write_transaction const & transaction_a) +{ + store.drop (transaction_a, nano::tables::confirmation_height); +} + +nano::store_iterator nano::confirmation_height_store_mdb::begin (nano::transaction const & transaction, nano::account const & account) const +{ + return store.make_iterator (transaction, tables::confirmation_height, account); +} + +nano::store_iterator nano::confirmation_height_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::confirmation_height); +} + +nano::store_iterator nano::confirmation_height_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::confirmation_height_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/confirmation_height_store.hpp b/nano/node/lmdb/confirmation_height_store.hpp new file mode 100644 index 00000000..9d8d8791 --- /dev/null +++ b/nano/node/lmdb/confirmation_height_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class confirmation_height_store_mdb : public confirmation_height_store +{ + nano::mdb_store & store; + +public: + explicit confirmation_height_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info const & confirmation_height_info_a) override; + bool get (nano::transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info & confirmation_height_info_a) override; + bool exists (nano::transaction const & transaction_a, nano::account const & account_a) const override; + void del (nano::write_transaction const & transaction_a, nano::account const & account_a) override; + uint64_t count (nano::transaction const & transaction_a) override; + void clear (nano::write_transaction const & transaction_a, nano::account const & account_a) override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::account const & account_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/lmdb/final_vote_store.cpp b/nano/node/lmdb/final_vote_store.cpp new file mode 100644 index 00000000..e594d429 --- /dev/null +++ b/nano/node/lmdb/final_vote_store.cpp @@ -0,0 +1,88 @@ +#include +#include + +nano::final_vote_store_mdb::final_vote_store_mdb (nano::mdb_store & store) : + store{ store } {}; + +bool nano::final_vote_store_mdb::put (nano::write_transaction const & transaction, nano::qualified_root const & root, nano::block_hash const & hash) +{ + nano::mdb_val value; + auto status = store.get (transaction, tables::final_votes, root, value); + release_assert (store.success (status) || store.not_found (status)); + bool result (true); + if (store.success (status)) + { + result = static_cast (value) == hash; + } + else + { + status = store.put (transaction, tables::final_votes, root, hash); + release_assert_success (store, status); + } + return result; +} + +std::vector nano::final_vote_store_mdb::get (nano::transaction const & transaction, nano::root const & root_a) +{ + std::vector result; + nano::qualified_root key_start{ root_a.raw, 0 }; + for (auto i = begin (transaction, key_start), n = end (); i != n && nano::qualified_root{ i->first }.root () == root_a; ++i) + { + result.push_back (i->second); + } + return result; +} + +void nano::final_vote_store_mdb::del (nano::write_transaction const & transaction, nano::root const & root) +{ + std::vector final_vote_qualified_roots; + for (auto i = begin (transaction, nano::qualified_root{ root.raw, 0 }), n = end (); i != n && nano::qualified_root{ i->first }.root () == root; ++i) + { + final_vote_qualified_roots.push_back (i->first); + } + + for (auto & final_vote_qualified_root : final_vote_qualified_roots) + { + auto status = store.del (transaction, tables::final_votes, final_vote_qualified_root); + release_assert_success (store, status); + } +} + +size_t nano::final_vote_store_mdb::count (nano::transaction const & transaction_a) const +{ + return store.count (transaction_a, tables::final_votes); +} + +void nano::final_vote_store_mdb::clear (nano::write_transaction const & transaction_a, nano::root const & root_a) +{ + del (transaction_a, root_a); +} + +void nano::final_vote_store_mdb::clear (nano::write_transaction const & transaction_a) +{ + store.drop (transaction_a, nano::tables::final_votes); +} + +nano::store_iterator nano::final_vote_store_mdb::begin (nano::transaction const & transaction, nano::qualified_root const & root) const +{ + return store.make_iterator (transaction, tables::final_votes, root); +} + +nano::store_iterator nano::final_vote_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::final_votes); +} + +nano::store_iterator nano::final_vote_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::final_vote_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/final_vote_store.hpp b/nano/node/lmdb/final_vote_store.hpp new file mode 100644 index 00000000..fd8d4e5d --- /dev/null +++ b/nano/node/lmdb/final_vote_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class final_vote_store_mdb : public final_vote_store +{ +private: + nano::mdb_store & store; + +public: + explicit final_vote_store_mdb (nano::mdb_store & store); + bool put (nano::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) override; + std::vector get (nano::transaction const & transaction_a, nano::root const & root_a) override; + void del (nano::write_transaction const & transaction_a, nano::root const & root_a) override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a, nano::root const & root_a) override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::qualified_root const & root_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/lmdb/frontier_store.cpp b/nano/node/lmdb/frontier_store.cpp new file mode 100644 index 00000000..3f26d3b0 --- /dev/null +++ b/nano/node/lmdb/frontier_store.cpp @@ -0,0 +1,56 @@ +#include +#include + +nano::frontier_store_mdb::frontier_store_mdb (nano::mdb_store & store) : + store{ store } +{ +} + +void nano::frontier_store_mdb::put (nano::write_transaction const & transaction, nano::block_hash const & hash, nano::account const & account) +{ + auto status = store.put (transaction, tables::frontiers, hash, account); + release_assert_success (store, status); +} + +nano::account nano::frontier_store_mdb::get (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + nano::db_val value; + auto status = store.get (transaction, tables::frontiers, hash, value); + release_assert (store.success (status) || store.not_found (status)); + nano::account result{}; + if (store.success (status)) + { + result = static_cast (value); + } + return result; +} + +void nano::frontier_store_mdb::del (nano::write_transaction const & transaction, nano::block_hash const & hash) +{ + auto status = store.del (transaction, tables::frontiers, hash); + release_assert_success (store, status); +} + +nano::store_iterator nano::frontier_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::frontiers); +} + +nano::store_iterator nano::frontier_store_mdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + return store.make_iterator (transaction, tables::frontiers, nano::db_val (hash)); +} + +nano::store_iterator nano::frontier_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::frontier_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/frontier_store.hpp b/nano/node/lmdb/frontier_store.hpp new file mode 100644 index 00000000..1d2f9020 --- /dev/null +++ b/nano/node/lmdb/frontier_store.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class frontier_store_mdb : public frontier_store +{ +public: + frontier_store_mdb (nano::mdb_store & store); + void put (nano::write_transaction const &, nano::block_hash const &, nano::account const &) override; + nano::account get (nano::transaction const &, nano::block_hash const &) const override; + void del (nano::write_transaction const &, nano::block_hash const &) override; + nano::store_iterator begin (nano::transaction const &) const override; + nano::store_iterator begin (nano::transaction const &, nano::block_hash const &) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; + +private: + nano::mdb_store & store; +}; + +} diff --git a/nano/node/lmdb/lmdb.cpp b/nano/node/lmdb/lmdb.cpp index 5681d77c..6df9b935 100644 --- a/nano/node/lmdb/lmdb.cpp +++ b/nano/node/lmdb/lmdb.cpp @@ -44,30 +44,30 @@ nano::mdb_store::mdb_store (nano::logger_mt & logger_a, boost::filesystem::path // clang-format off store_partial{ constants, - block_store_partial, - frontier_store_partial, - account_store_partial, - pending_store_partial, - unchecked_mdb_store, - online_weight_store_partial, - pruned_store_partial, - peer_store_partial, - confirmation_height_store_partial, - final_vote_store_partial, - version_store_partial + block_store, + frontier_store, + account_store, + pending_store, + unchecked_store, + online_weight_store, + pruned_store, + peer_store, + confirmation_height_store, + final_vote_store, + version_store }, // clang-format on - block_store_partial{ *this }, - frontier_store_partial{ *this }, - account_store_partial{ *this }, - pending_store_partial{ *this }, - online_weight_store_partial{ *this }, - pruned_store_partial{ *this }, - peer_store_partial{ *this }, - confirmation_height_store_partial{ *this }, - final_vote_store_partial{ *this }, - unchecked_mdb_store{ *this }, - version_store_partial{ *this }, + block_store{ *this }, + frontier_store{ *this }, + account_store{ *this }, + pending_store{ *this }, + online_weight_store{ *this }, + pruned_store{ *this }, + peer_store{ *this }, + confirmation_height_store{ *this }, + final_vote_store{ *this }, + unchecked_store{ *this }, + version_store{ *this }, logger (logger_a), env (error, path_a, nano::mdb_env::options::make ().set_config (lmdb_config_a).set_use_no_mem_init (true)), mdb_txn_tracker (logger_a, txn_tracking_config_a, block_processor_batch_max_time_a), @@ -384,7 +384,7 @@ void nano::mdb_store::upgrade_v14_to_v15 (nano::write_transaction & transaction_ nano::mdb_val value{ data.size (), (void *)data.data () }; auto s = mdb_put (env.tx (transaction_a), state_blocks_new, nano::mdb_val (hash), value, MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); // Every so often output to the log to indicate progress constexpr auto output_cutoff = 1000000; @@ -515,7 +515,7 @@ void nano::mdb_store::upgrade_v16_to_v17 (nano::write_transaction const & transa // Clear it then append auto status (mdb_drop (env.tx (transaction_a), confirmation_height_handle, 0)); - release_assert_success (*this, status); + release_assert_success (status); for (auto const & confirmation_height_info_pair : confirmation_height_infos) { @@ -571,7 +571,7 @@ void nano::mdb_store::upgrade_v17_to_v18 (nano::write_transaction const & transa } nano::mdb_val value{ data.size (), (void *)data.data () }; auto s = mdb_cursor_put (state_i.cursor, state_i->first, value, MDB_CURRENT); - release_assert_success (*this, s); + release_assert_success (s); // Every so often output to the log to indicate progress constexpr auto output_cutoff = 1000000; @@ -641,7 +641,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa nano::mdb_val value{ data.size (), (void *)data.data () }; auto s = mdb_put (env.tx (transaction_a), temp_legacy_open_receive_change_blocks, nano::mdb_val (legacy_block.first), value, MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } } @@ -665,7 +665,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa nano::mdb_val value{ data.size (), (void *)data.data () }; auto s = mdb_put (env.tx (transaction_a), temp_legacy_send_blocks, nano::mdb_val (i->first), value, MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } } @@ -683,7 +683,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa for (; i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), temp_legacy_send_open_receive_change_blocks, nano::mdb_val (i->first), nano::mdb_val (i->second), MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } // Delete tables @@ -730,7 +730,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa nano::mdb_val value{ data.size (), (void *)data.data () }; auto s = mdb_put (env.tx (transaction_a), temp_state_blocks, nano::mdb_val (i->first), value, MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } } @@ -746,7 +746,7 @@ void nano::mdb_store::upgrade_v18_to_v19 (nano::write_transaction const & transa for (; i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), blocks_handle, nano::mdb_val (i->first), nano::mdb_val (i->second), MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } // Delete tables @@ -811,9 +811,6 @@ void nano::mdb_store::create_backup_file (nano::mdb_env & env_a, boost::filesyst } } -nano::unchecked_mdb_store::unchecked_mdb_store (nano::mdb_store & mdb_store_a) : - unchecked_store_partial (mdb_store_a){}; - bool nano::mdb_store::exists (nano::transaction const & transaction_a, tables table_a, nano::mdb_val const & key_a) const { nano::mdb_val junk; @@ -856,7 +853,7 @@ uint64_t nano::mdb_store::count (nano::transaction const & transaction_a, MDB_db { MDB_stat stats; auto status (mdb_stat (env.tx (transaction_a), db_a, &stats)); - release_assert_success (*this, status); + release_assert_success (status); return (stats.ms_entries); } @@ -929,7 +926,7 @@ void nano::mdb_store::rebuild_db (nano::write_transaction const & transaction_a) for (auto i (nano::store_iterator (std::make_unique> (transaction_a, table))), n (nano::store_iterator (nullptr)); i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), temp, nano::mdb_val (i->first), i->second, MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } release_assert (count (transaction_a, table) == count (transaction_a, temp)); // Clear existing table @@ -938,7 +935,7 @@ void nano::mdb_store::rebuild_db (nano::write_transaction const & transaction_a) for (auto i (nano::store_iterator (std::make_unique> (transaction_a, temp))), n (nano::store_iterator (nullptr)); i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), table, nano::mdb_val (i->first), i->second, MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } release_assert (count (transaction_a, table) == count (transaction_a, temp)); // Remove temporary table @@ -952,7 +949,7 @@ void nano::mdb_store::rebuild_db (nano::write_transaction const & transaction_a) for (auto i (nano::store_iterator (std::make_unique> (transaction_a, pending_handle))), n (nano::store_iterator (nullptr)); i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), temp, nano::mdb_val (i->first), nano::mdb_val (i->second), MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } release_assert (count (transaction_a, pending_handle) == count (transaction_a, temp)); mdb_drop (env.tx (transaction_a), pending_handle, 0); @@ -960,7 +957,7 @@ void nano::mdb_store::rebuild_db (nano::write_transaction const & transaction_a) for (auto i (nano::store_iterator (std::make_unique> (transaction_a, temp))), n (nano::store_iterator (nullptr)); i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), pending_handle, nano::mdb_val (i->first), nano::mdb_val (i->second), MDB_APPEND); - release_assert_success (*this, s); + release_assert_success (s); } release_assert (count (transaction_a, pending_handle) == count (transaction_a, temp)); mdb_drop (env.tx (transaction_a), temp, 1); diff --git a/nano/node/lmdb/lmdb.hpp b/nano/node/lmdb/lmdb.hpp index 8364e5a0..612d32f7 100644 --- a/nano/node/lmdb/lmdb.hpp +++ b/nano/node/lmdb/lmdb.hpp @@ -4,21 +4,21 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -40,12 +40,7 @@ using mdb_val = db_val; class logging_mt; class mdb_store; - -class unchecked_mdb_store : public unchecked_store_partial -{ -public: - explicit unchecked_mdb_store (nano::mdb_store &); -}; +class transaction; /** * mdb implementation of the block store @@ -53,19 +48,29 @@ public: class mdb_store : public store_partial { private: - nano::block_store_partial block_store_partial; - nano::frontier_store_partial frontier_store_partial; - nano::account_store_partial account_store_partial; - nano::pending_store_partial pending_store_partial; - nano::unchecked_mdb_store unchecked_mdb_store; - nano::online_weight_store_partial online_weight_store_partial; - nano::pruned_store_partial pruned_store_partial; - nano::peer_store_partial peer_store_partial; - nano::confirmation_height_store_partial confirmation_height_store_partial; - nano::final_vote_store_partial final_vote_store_partial; - nano::version_store_partial version_store_partial; + nano::block_store_mdb block_store; + nano::frontier_store_mdb frontier_store; + nano::account_store_mdb account_store; + nano::pending_store_mdb pending_store; + nano::unchecked_store_mdb unchecked_store; + nano::online_weight_store_mdb online_weight_store; + nano::pruned_store_mdb pruned_store; + nano::peer_store_mdb peer_store; + nano::confirmation_height_store_mdb confirmation_height_store; + nano::final_vote_store_mdb final_vote_store; + nano::version_store_mdb version_store; - friend class nano::unchecked_mdb_store; + friend class nano::account_store_mdb; + friend class nano::block_store_mdb; + friend class nano::confirmation_height_store_mdb; + friend class nano::final_vote_store_mdb; + friend class nano::frontier_store_mdb; + friend class nano::online_weight_store_mdb; + friend class nano::peer_store_mdb; + friend class nano::pending_store_mdb; + friend class nano::pruned_store_mdb; + friend class nano::unchecked_store_mdb; + friend class nano::version_store_mdb; public: mdb_store (nano::logger_mt &, boost::filesystem::path const &, nano::ledger_constants & constants, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); @@ -237,7 +242,7 @@ public: void rebuild_db (nano::write_transaction const & transaction_a) override; template - nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc) const + nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const { return nano::store_iterator (std::make_unique> (transaction_a, table_to_dbi (table_a), nano::mdb_val{}, direction_asc)); } @@ -282,6 +287,13 @@ private: bool not_found (int status) const override; bool success (int status) const override; + void release_assert_success (int const status) const + { + if (!success (status)) + { + release_assert (false, error_string (status)); + } + } int status_code_not_found () const override; MDB_dbi table_to_dbi (tables table_a) const; diff --git a/nano/node/lmdb/online_weight_store.cpp b/nano/node/lmdb/online_weight_store.cpp new file mode 100644 index 00000000..f11720ee --- /dev/null +++ b/nano/node/lmdb/online_weight_store.cpp @@ -0,0 +1,45 @@ +#include +#include + +nano::online_weight_store_mdb::online_weight_store_mdb (nano::mdb_store & store_a) : + store{ store_a } +{ +} + +void nano::online_weight_store_mdb::put (nano::write_transaction const & transaction, uint64_t time, nano::amount const & amount) +{ + auto status = store.put (transaction, tables::online_weight, time, amount); + release_assert_success (store, status); +} + +void nano::online_weight_store_mdb::del (nano::write_transaction const & transaction, uint64_t time) +{ + auto status = store.del (transaction, tables::online_weight, time); + release_assert_success (store, status); +} + +nano::store_iterator nano::online_weight_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::online_weight); +} + +nano::store_iterator nano::online_weight_store_mdb::rbegin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::online_weight, false); +} + +nano::store_iterator nano::online_weight_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +size_t nano::online_weight_store_mdb::count (nano::transaction const & transaction) const +{ + return store.count (transaction, tables::online_weight); +} + +void nano::online_weight_store_mdb::clear (nano::write_transaction const & transaction) +{ + auto status = store.drop (transaction, tables::online_weight); + release_assert_success (store, status); +} diff --git a/nano/node/lmdb/online_weight_store.hpp b/nano/node/lmdb/online_weight_store.hpp new file mode 100644 index 00000000..eb9215d6 --- /dev/null +++ b/nano/node/lmdb/online_weight_store.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class online_weight_store_mdb : public online_weight_store +{ +private: + nano::mdb_store & store; + +public: + explicit online_weight_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override; + void del (nano::write_transaction const & transaction_a, uint64_t time_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator rbegin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a) override; +}; +} diff --git a/nano/node/lmdb/peer_store.cpp b/nano/node/lmdb/peer_store.cpp new file mode 100644 index 00000000..bd2ef407 --- /dev/null +++ b/nano/node/lmdb/peer_store.cpp @@ -0,0 +1,43 @@ +#include +#include + +nano::peer_store_mdb::peer_store_mdb (nano::mdb_store & store) : + store{ store } {}; + +void nano::peer_store_mdb::put (nano::write_transaction const & transaction, nano::endpoint_key const & endpoint) +{ + auto status = store.put_key (transaction, tables::peers, endpoint); + release_assert_success (store, status); +} + +void nano::peer_store_mdb::del (nano::write_transaction const & transaction, nano::endpoint_key const & endpoint) +{ + auto status = store.del (transaction, tables::peers, endpoint); + release_assert_success (store, status); +} + +bool nano::peer_store_mdb::exists (nano::transaction const & transaction, nano::endpoint_key const & endpoint) const +{ + return store.exists (transaction, tables::peers, endpoint); +} + +size_t nano::peer_store_mdb::count (nano::transaction const & transaction) const +{ + return store.count (transaction, tables::peers); +} + +void nano::peer_store_mdb::clear (nano::write_transaction const & transaction) +{ + auto status = store.drop (transaction, tables::peers); + release_assert_success (store, status); +} + +nano::store_iterator nano::peer_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::peers); +} + +nano::store_iterator nano::peer_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} diff --git a/nano/node/lmdb/peer_store.hpp b/nano/node/lmdb/peer_store.hpp new file mode 100644 index 00000000..4bae1925 --- /dev/null +++ b/nano/node/lmdb/peer_store.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class peer_store_mdb : public peer_store +{ +private: + nano::mdb_store & store; + +public: + explicit peer_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override; + void del (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override; + bool exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; +}; +} diff --git a/nano/node/lmdb/pending_store.cpp b/nano/node/lmdb/pending_store.cpp new file mode 100644 index 00000000..73826a88 --- /dev/null +++ b/nano/node/lmdb/pending_store.cpp @@ -0,0 +1,71 @@ +#include +#include + +nano::pending_store_mdb::pending_store_mdb (nano::mdb_store & store) : + store{ store } {}; + +void nano::pending_store_mdb::put (nano::write_transaction const & transaction, nano::pending_key const & key, nano::pending_info const & pending) +{ + auto status = store.put (transaction, tables::pending, key, pending); + release_assert_success (store, status); +} + +void nano::pending_store_mdb::del (nano::write_transaction const & transaction, nano::pending_key const & key) +{ + auto status = store.del (transaction, tables::pending, key); + release_assert_success (store, status); +} + +bool nano::pending_store_mdb::get (nano::transaction const & transaction, nano::pending_key const & key, nano::pending_info & pending_a) +{ + nano::mdb_val value; + auto status1 = store.get (transaction, tables::pending, key, value); + release_assert (store.success (status1) || store.not_found (status1)); + bool result (true); + if (store.success (status1)) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = pending_a.deserialize (stream); + } + return result; +} + +bool nano::pending_store_mdb::exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) +{ + auto iterator (begin (transaction_a, key_a)); + return iterator != end () && nano::pending_key (iterator->first) == key_a; +} + +bool nano::pending_store_mdb::any (nano::transaction const & transaction_a, nano::account const & account_a) +{ + auto iterator (begin (transaction_a, nano::pending_key (account_a, 0))); + return iterator != end () && nano::pending_key (iterator->first).account == account_a; +} + +nano::store_iterator nano::pending_store_mdb::begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const +{ + return store.make_iterator (transaction_a, tables::pending, key_a); +} + +nano::store_iterator nano::pending_store_mdb::begin (nano::transaction const & transaction_a) const +{ + return store.make_iterator (transaction_a, tables::pending); +} + +nano::store_iterator nano::pending_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::pending_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { + nano::uint512_union union_start (start); + nano::uint512_union union_end (end); + nano::pending_key key_start (union_start.uint256s[0].number (), union_start.uint256s[1].number ()); + nano::pending_key key_end (union_end.uint256s[0].number (), union_end.uint256s[1].number ()); + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/pending_store.hpp b/nano/node/lmdb/pending_store.hpp new file mode 100644 index 00000000..26afe357 --- /dev/null +++ b/nano/node/lmdb/pending_store.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class pending_store_mdb : public pending_store +{ +private: + nano::mdb_store & store; + +public: + explicit pending_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info const & pending_info_a) override; + void del (nano::write_transaction const & transaction_a, nano::pending_key const & key_a) override; + bool get (nano::transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info & pending_a) override; + bool exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) override; + bool any (nano::transaction const & transaction_a, nano::account const & account_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/lmdb/pruned_store.cpp b/nano/node/lmdb/pruned_store.cpp new file mode 100644 index 00000000..419c3e5e --- /dev/null +++ b/nano/node/lmdb/pruned_store.cpp @@ -0,0 +1,69 @@ +#include +#include + +nano::pruned_store_mdb::pruned_store_mdb (nano::mdb_store & store_a) : + store{ store_a } {}; + +void nano::pruned_store_mdb::put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto status = store.put_key (transaction_a, tables::pruned, hash_a); + release_assert_success (store, status); +} + +void nano::pruned_store_mdb::del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto status = store.del (transaction_a, tables::pruned, hash_a); + release_assert_success (store, status); +} + +bool nano::pruned_store_mdb::exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + return store.exists (transaction_a, tables::pruned, hash_a); +} + +nano::block_hash nano::pruned_store_mdb::random (nano::transaction const & transaction) +{ + nano::block_hash random_hash; + nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ()); + auto existing = begin (transaction, random_hash); + if (existing == end ()) + { + existing = begin (transaction); + } + return existing != end () ? existing->first : 0; +} + +size_t nano::pruned_store_mdb::count (nano::transaction const & transaction_a) const +{ + return store.count (transaction_a, tables::pruned); +} + +void nano::pruned_store_mdb::clear (nano::write_transaction const & transaction_a) +{ + auto status = store.drop (transaction_a, tables::pruned); + release_assert_success (store, status); +} + +nano::store_iterator nano::pruned_store_mdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + return store.make_iterator (transaction, tables::pruned, hash); +} + +nano::store_iterator nano::pruned_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::pruned); +} + +nano::store_iterator nano::pruned_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::pruned_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/pruned_store.hpp b/nano/node/lmdb/pruned_store.hpp new file mode 100644 index 00000000..896b4364 --- /dev/null +++ b/nano/node/lmdb/pruned_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class pruned_store_mdb : public pruned_store +{ +private: + nano::mdb_store & store; + +public: + explicit pruned_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::block_hash random (nano::transaction const & transaction_a) override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/lmdb/unchecked_store.cpp b/nano/node/lmdb/unchecked_store.cpp new file mode 100644 index 00000000..f69d208d --- /dev/null +++ b/nano/node/lmdb/unchecked_store.cpp @@ -0,0 +1,62 @@ +#include +#include + +nano::unchecked_store_mdb::unchecked_store_mdb (nano::mdb_store & store_a) : + store (store_a){}; + +void nano::unchecked_store_mdb::clear (nano::write_transaction const & transaction_a) +{ + auto status = store.drop (transaction_a, tables::unchecked); + release_assert_success (store, status); +} + +void nano::unchecked_store_mdb::put (nano::write_transaction const & transaction_a, nano::hash_or_account const & dependency, nano::unchecked_info const & info) +{ + auto status = store.put (transaction_a, tables::unchecked, nano::unchecked_key{ dependency, info.block->hash () }, info); + release_assert_success (store, status); +} + +bool nano::unchecked_store_mdb::exists (nano::transaction const & transaction_a, nano::unchecked_key const & key) +{ + nano::mdb_val value; + auto status = store.get (transaction_a, tables::unchecked, key, value); + release_assert (store.success (status) || store.not_found (status)); + return store.success (status); +} + +void nano::unchecked_store_mdb::del (nano::write_transaction const & transaction_a, nano::unchecked_key const & key_a) +{ + auto status (store.del (transaction_a, tables::unchecked, key_a)); + release_assert_success (store, status); +} + +nano::store_iterator nano::unchecked_store_mdb::end () const +{ + return nano::store_iterator (nullptr); +} + +nano::store_iterator nano::unchecked_store_mdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::unchecked); +} + +nano::store_iterator nano::unchecked_store_mdb::lower_bound (nano::transaction const & transaction, nano::unchecked_key const & key) const +{ + return store.make_iterator (transaction, tables::unchecked, key); +} + +size_t nano::unchecked_store_mdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::unchecked); +} + +void nano::unchecked_store_mdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { + nano::unchecked_key key_start (start); + nano::unchecked_key key_end (end); + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->lower_bound (transaction, key_start), !is_last ? this->lower_bound (transaction, key_end) : this->end ()); + }); +} diff --git a/nano/node/lmdb/unchecked_store.hpp b/nano/node/lmdb/unchecked_store.hpp new file mode 100644 index 00000000..0ae16fe6 --- /dev/null +++ b/nano/node/lmdb/unchecked_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class unchecked_store_mdb : public unchecked_store +{ +private: + nano::mdb_store & store; + +public: + unchecked_store_mdb (nano::mdb_store & store_a); + + void clear (nano::write_transaction const & transaction_a) override; + void put (nano::write_transaction const & transaction_a, nano::hash_or_account const & dependency, nano::unchecked_info const & info_a) override; + bool exists (nano::transaction const & transaction_a, nano::unchecked_key const & unchecked_key_a) override; + void del (nano::write_transaction const & transaction_a, nano::unchecked_key const & key_a) override; + nano::store_iterator end () const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator lower_bound (nano::transaction const & transaction_a, nano::unchecked_key const & key_a) const override; + size_t count (nano::transaction const & transaction_a) override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/lmdb/version_store.cpp b/nano/node/lmdb/version_store.cpp new file mode 100644 index 00000000..f9d1490e --- /dev/null +++ b/nano/node/lmdb/version_store.cpp @@ -0,0 +1,28 @@ +#include +#include + +nano::version_store_mdb::version_store_mdb (nano::mdb_store & store_a) : + store{ store_a } {}; + +void nano::version_store_mdb::put (nano::write_transaction const & transaction_a, int version) +{ + nano::uint256_union version_key{ 1 }; + nano::uint256_union version_value (version); + auto status = store.put (transaction_a, tables::meta, version_key, version_value); + release_assert_success (store, status); +} + +int nano::version_store_mdb::get (nano::transaction const & transaction_a) const +{ + nano::uint256_union version_key{ 1 }; + nano::mdb_val data; + auto status = store.get (transaction_a, tables::meta, version_key, data); + int result = store.minimum_version; + if (store.success (status)) + { + nano::uint256_union version_value{ data }; + debug_assert (version_value.qwords[2] == 0 && version_value.qwords[1] == 0 && version_value.qwords[0] == 0); + result = version_value.number ().convert_to (); + } + return result; +} diff --git a/nano/node/lmdb/version_store.hpp b/nano/node/lmdb/version_store.hpp new file mode 100644 index 00000000..45edb23c --- /dev/null +++ b/nano/node/lmdb/version_store.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class version_store_mdb : public version_store +{ +protected: + nano::mdb_store & store; + +public: + explicit version_store_mdb (nano::mdb_store & store_a); + void put (nano::write_transaction const & transaction_a, int version_a) override; + int get (nano::transaction const & transaction_a) const override; +}; +} diff --git a/nano/node/rocksdb/account_store.cpp b/nano/node/rocksdb/account_store.cpp new file mode 100644 index 00000000..296874fe --- /dev/null +++ b/nano/node/rocksdb/account_store.cpp @@ -0,0 +1,71 @@ +#include +#include + +nano::account_store_rocksdb::account_store_rocksdb (nano::rocksdb_store & store_a) : + store (store_a){}; + +void nano::account_store_rocksdb::put (nano::write_transaction const & transaction, nano::account const & account, nano::account_info const & info) +{ + auto status = store.put (transaction, tables::accounts, account, info); + release_assert_success (store, status); +} + +bool nano::account_store_rocksdb::get (nano::transaction const & transaction, nano::account const & account, nano::account_info & info) +{ + nano::rocksdb_val value; + auto status1 (store.get (transaction, tables::accounts, account, value)); + release_assert (store.success (status1) || store.not_found (status1)); + bool result (true); + if (store.success (status1)) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = info.deserialize (stream); + } + return result; +} + +void nano::account_store_rocksdb::del (nano::write_transaction const & transaction_a, nano::account const & account_a) +{ + auto status = store.del (transaction_a, tables::accounts, account_a); + release_assert_success (store, status); +} + +bool nano::account_store_rocksdb::exists (nano::transaction const & transaction_a, nano::account const & account_a) +{ + auto iterator (begin (transaction_a, account_a)); + return iterator != end () && nano::account (iterator->first) == account_a; +} + +size_t nano::account_store_rocksdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::accounts); +} + +nano::store_iterator nano::account_store_rocksdb::begin (nano::transaction const & transaction, nano::account const & account) const +{ + return store.make_iterator (transaction, tables::accounts, account); +} + +nano::store_iterator nano::account_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::accounts); +} + +nano::store_iterator nano::account_store_rocksdb::rbegin (nano::transaction const & transaction_a) const +{ + return store.make_iterator (transaction_a, tables::accounts, false); +} + +nano::store_iterator nano::account_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::account_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/account_store.hpp b/nano/node/rocksdb/account_store.hpp new file mode 100644 index 00000000..33eac4e1 --- /dev/null +++ b/nano/node/rocksdb/account_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class account_store_rocksdb : public account_store +{ +private: + nano::rocksdb_store & store; + +public: + explicit account_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction, nano::account const & account, nano::account_info const & info) override; + bool get (nano::transaction const & transaction_a, nano::account const & account_a, nano::account_info & info_a) override; + void del (nano::write_transaction const & transaction_a, nano::account const & account_a) override; + bool exists (nano::transaction const & transaction_a, nano::account const & account_a) override; + size_t count (nano::transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::account const & account_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator rbegin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/rocksdb/block_store.cpp b/nano/node/rocksdb/block_store.cpp new file mode 100644 index 00000000..6c4c9667 --- /dev/null +++ b/nano/node/rocksdb/block_store.cpp @@ -0,0 +1,296 @@ +#include +#include + +namespace nano +{ +/** + * Fill in our predecessors + */ +class block_predecessor_rocksdb_set : public nano::block_visitor +{ +public: + block_predecessor_rocksdb_set (nano::write_transaction const & transaction_a, nano::block_store_rocksdb & block_store_a); + virtual ~block_predecessor_rocksdb_set () = default; + void fill_value (nano::block const & block_a); + void send_block (nano::send_block const & block_a) override; + void receive_block (nano::receive_block const & block_a) override; + void open_block (nano::open_block const & block_a) override; + void change_block (nano::change_block const & block_a) override; + void state_block (nano::state_block const & block_a) override; + nano::write_transaction const & transaction; + nano::block_store_rocksdb & block_store; +}; +} + +nano::block_store_rocksdb::block_store_rocksdb (nano::rocksdb_store & store_a) : + store{ store_a } {}; + +void nano::block_store_rocksdb::put (nano::write_transaction const & transaction, nano::block_hash const & hash, nano::block const & block) +{ + debug_assert (block.sideband ().successor.is_zero () || exists (transaction, block.sideband ().successor)); + std::vector vector; + { + nano::vectorstream stream (vector); + nano::serialize_block (stream, block); + block.sideband ().serialize (stream, block.type ()); + } + raw_put (transaction, vector, hash); + block_predecessor_rocksdb_set predecessor (transaction, *this); + block.visit (predecessor); + debug_assert (block.previous ().is_zero () || successor (transaction, block.previous ()) == hash); +} + +void nano::block_store_rocksdb::raw_put (nano::write_transaction const & transaction_a, std::vector const & data, nano::block_hash const & hash_a) +{ + nano::rocksdb_val value{ data.size (), (void *)data.data () }; + auto status = store.put (transaction_a, tables::blocks, hash_a, value); + release_assert_success (store, status); +} + +nano::block_hash nano::block_store_rocksdb::successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + nano::rocksdb_val value; + block_raw_get (transaction_a, hash_a, value); + nano::block_hash result; + if (value.size () != 0) + { + debug_assert (value.size () >= result.bytes.size ()); + auto type = block_type_from_raw (value.data ()); + nano::bufferstream stream (reinterpret_cast (value.data ()) + block_successor_offset (transaction_a, value.size (), type), result.bytes.size ()); + auto error (nano::try_read (stream, result.bytes)); + (void)error; + debug_assert (!error); + } + else + { + result.clear (); + } + return result; +} + +void nano::block_store_rocksdb::successor_clear (nano::write_transaction const & transaction, nano::block_hash const & hash) +{ + nano::rocksdb_val value; + block_raw_get (transaction, hash, value); + debug_assert (value.size () != 0); + auto type = block_type_from_raw (value.data ()); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::fill_n (data.begin () + block_successor_offset (transaction, value.size (), type), sizeof (nano::block_hash), uint8_t{ 0 }); + raw_put (transaction, data, hash); +} + +std::shared_ptr nano::block_store_rocksdb::get (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + nano::rocksdb_val value; + block_raw_get (transaction, hash, value); + std::shared_ptr result; + if (value.size () != 0) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + nano::block_type type; + auto error (try_read (stream, type)); + release_assert (!error); + result = nano::deserialize_block (stream, type); + release_assert (result != nullptr); + nano::block_sideband sideband; + error = (sideband.deserialize (stream, type)); + release_assert (!error); + result->sideband_set (sideband); + } + return result; +} + +std::shared_ptr nano::block_store_rocksdb::get_no_sideband (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + nano::rocksdb_val value; + block_raw_get (transaction, hash, value); + std::shared_ptr result; + if (value.size () != 0) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = nano::deserialize_block (stream); + debug_assert (result != nullptr); + } + return result; +} + +std::shared_ptr nano::block_store_rocksdb::random (nano::transaction const & transaction) +{ + nano::block_hash hash; + nano::random_pool::generate_block (hash.bytes.data (), hash.bytes.size ()); + auto existing = begin (transaction, hash); + if (existing == end ()) + { + existing = begin (transaction); + } + debug_assert (existing != end ()); + return existing->second.block; +} + +void nano::block_store_rocksdb::del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto status = store.del (transaction_a, tables::blocks, hash_a); + release_assert_success (store, status); +} + +bool nano::block_store_rocksdb::exists (nano::transaction const & transaction, nano::block_hash const & hash) +{ + nano::rocksdb_val junk; + block_raw_get (transaction, hash, junk); + return junk.size () != 0; +} + +uint64_t nano::block_store_rocksdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::blocks); +} + +nano::account nano::block_store_rocksdb::account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + auto block (get (transaction_a, hash_a)); + debug_assert (block != nullptr); + return account_calculated (*block); +} + +nano::account nano::block_store_rocksdb::account_calculated (nano::block const & block_a) const +{ + debug_assert (block_a.has_sideband ()); + nano::account result (block_a.account ()); + if (result.is_zero ()) + { + result = block_a.sideband ().account; + } + debug_assert (!result.is_zero ()); + return result; +} + +nano::store_iterator nano::block_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::blocks); +} + +nano::store_iterator nano::block_store_rocksdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + return store.make_iterator (transaction, tables::blocks, hash); +} + +nano::store_iterator nano::block_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +nano::uint128_t nano::block_store_rocksdb::balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto block (get (transaction_a, hash_a)); + release_assert (block); + nano::uint128_t result (balance_calculated (block)); + return result; +} + +nano::uint128_t nano::block_store_rocksdb::balance_calculated (std::shared_ptr const & block_a) const +{ + nano::uint128_t result; + switch (block_a->type ()) + { + case nano::block_type::open: + case nano::block_type::receive: + case nano::block_type::change: + result = block_a->sideband ().balance.number (); + break; + case nano::block_type::send: + result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); + break; + case nano::block_type::state: + result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); + break; + case nano::block_type::invalid: + case nano::block_type::not_a_block: + release_assert (false); + break; + } + return result; +} + +nano::epoch nano::block_store_rocksdb::version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto block = get (transaction_a, hash_a); + if (block && block->type () == nano::block_type::state) + { + return block->sideband ().details.epoch; + } + + return nano::epoch::epoch_0; +} + +void nano::block_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} + +// Converts a block hash to a block height +uint64_t nano::block_store_rocksdb::account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + auto block = get (transaction_a, hash_a); + return block->sideband ().height; +} + +void nano::block_store_rocksdb::block_raw_get (nano::transaction const & transaction, nano::block_hash const & hash, nano::rocksdb_val & value) const +{ + auto status = store.get (transaction, tables::blocks, hash, value); + release_assert (store.success (status) || store.not_found (status)); +} + +size_t nano::block_store_rocksdb::block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const +{ + return entry_size_a - nano::block_sideband::size (type_a); +} + +nano::block_type nano::block_store_rocksdb::block_type_from_raw (void * data_a) +{ + // The block type is the first byte + return static_cast ((reinterpret_cast (data_a))[0]); +} + +nano::block_predecessor_rocksdb_set::block_predecessor_rocksdb_set (nano::write_transaction const & transaction_a, nano::block_store_rocksdb & block_store_a) : + transaction{ transaction_a }, + block_store{ block_store_a } +{ +} +void nano::block_predecessor_rocksdb_set::fill_value (nano::block const & block_a) +{ + auto hash = block_a.hash (); + nano::rocksdb_val value; + block_store.block_raw_get (transaction, block_a.previous (), value); + debug_assert (value.size () != 0); + auto type = block_store.block_type_from_raw (value.data ()); + std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); + std::copy (hash.bytes.begin (), hash.bytes.end (), data.begin () + block_store.block_successor_offset (transaction, value.size (), type)); + block_store.raw_put (transaction, data, block_a.previous ()); +} +void nano::block_predecessor_rocksdb_set::send_block (nano::send_block const & block_a) +{ + fill_value (block_a); +} +void nano::block_predecessor_rocksdb_set::receive_block (nano::receive_block const & block_a) +{ + fill_value (block_a); +} +void nano::block_predecessor_rocksdb_set::open_block (nano::open_block const & block_a) +{ + // Open blocks don't have a predecessor +} +void nano::block_predecessor_rocksdb_set::change_block (nano::change_block const & block_a) +{ + fill_value (block_a); +} +void nano::block_predecessor_rocksdb_set::state_block (nano::state_block const & block_a) +{ + if (!block_a.previous ().is_zero ()) + { + fill_value (block_a); + } +} diff --git a/nano/node/rocksdb/block_store.hpp b/nano/node/rocksdb/block_store.hpp new file mode 100644 index 00000000..6df4a9fd --- /dev/null +++ b/nano/node/rocksdb/block_store.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include + +namespace nano +{ +class rocksdb_store; +using rocksdb_val = db_val; +class block_predecessor_rocksdb_set; +class block_store_rocksdb : public block_store +{ + friend class block_predecessor_rocksdb_set; + nano::rocksdb_store & store; + +public: + explicit block_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a) override; + void raw_put (nano::write_transaction const & transaction_a, std::vector const & data, nano::block_hash const & hash_a) override; + nano::block_hash successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + void successor_clear (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + std::shared_ptr get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + std::shared_ptr get_no_sideband (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + std::shared_ptr random (nano::transaction const & transaction_a) override; + void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override; + uint64_t count (nano::transaction const & transaction_a) override; + nano::account account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::account account_calculated (nano::block const & block_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::store_iterator end () const override; + nano::uint128_t balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override; + nano::uint128_t balance_calculated (std::shared_ptr const & block_a) const override; + nano::epoch version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; + // Converts a block hash to a block height + uint64_t account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + +protected: + void block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a, nano::rocksdb_val & value) const; + size_t block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const; + static nano::block_type block_type_from_raw (void * data_a); +}; +} diff --git a/nano/node/rocksdb/confirmation_height_store.cpp b/nano/node/rocksdb/confirmation_height_store.cpp new file mode 100644 index 00000000..a61ee12d --- /dev/null +++ b/nano/node/rocksdb/confirmation_height_store.cpp @@ -0,0 +1,83 @@ +#include +#include + +nano::confirmation_height_store_rocksdb::confirmation_height_store_rocksdb (nano::rocksdb_store & store) : + store{ store } +{ +} + +void nano::confirmation_height_store_rocksdb::put (nano::write_transaction const & transaction, nano::account const & account, nano::confirmation_height_info const & confirmation_height_info) +{ + auto status = store.put (transaction, tables::confirmation_height, account, confirmation_height_info); + release_assert_success (store, status); +} + +bool nano::confirmation_height_store_rocksdb::get (nano::transaction const & transaction, nano::account const & account, nano::confirmation_height_info & confirmation_height_info) +{ + nano::rocksdb_val value; + auto status = store.get (transaction, tables::confirmation_height, account, value); + release_assert (store.success (status) || store.not_found (status)); + bool result (true); + if (store.success (status)) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = confirmation_height_info.deserialize (stream); + } + if (result) + { + confirmation_height_info.height = 0; + confirmation_height_info.frontier = 0; + } + + return result; +} + +bool nano::confirmation_height_store_rocksdb::exists (nano::transaction const & transaction, nano::account const & account) const +{ + return store.exists (transaction, tables::confirmation_height, account); +} + +void nano::confirmation_height_store_rocksdb::del (nano::write_transaction const & transaction, nano::account const & account) +{ + auto status = store.del (transaction, tables::confirmation_height, account); + release_assert_success (store, status); +} + +uint64_t nano::confirmation_height_store_rocksdb::count (nano::transaction const & transaction) +{ + return store.count (transaction, tables::confirmation_height); +} + +void nano::confirmation_height_store_rocksdb::clear (nano::write_transaction const & transaction, nano::account const & account) +{ + del (transaction, account); +} + +void nano::confirmation_height_store_rocksdb::clear (nano::write_transaction const & transaction) +{ + store.drop (transaction, nano::tables::confirmation_height); +} + +nano::store_iterator nano::confirmation_height_store_rocksdb::begin (nano::transaction const & transaction, nano::account const & account) const +{ + return store.make_iterator (transaction, tables::confirmation_height, account); +} + +nano::store_iterator nano::confirmation_height_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::confirmation_height); +} + +nano::store_iterator nano::confirmation_height_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::confirmation_height_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/confirmation_height_store.hpp b/nano/node/rocksdb/confirmation_height_store.hpp new file mode 100644 index 00000000..f8c2d78e --- /dev/null +++ b/nano/node/rocksdb/confirmation_height_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class confirmation_height_store_rocksdb : public confirmation_height_store +{ + nano::rocksdb_store & store; + +public: + explicit confirmation_height_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info const & confirmation_height_info_a) override; + bool get (nano::transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info & confirmation_height_info_a) override; + bool exists (nano::transaction const & transaction_a, nano::account const & account_a) const override; + void del (nano::write_transaction const & transaction_a, nano::account const & account_a) override; + uint64_t count (nano::transaction const & transaction_a) override; + void clear (nano::write_transaction const & transaction_a, nano::account const & account_a) override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::account const & account_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/rocksdb/final_vote_store.cpp b/nano/node/rocksdb/final_vote_store.cpp new file mode 100644 index 00000000..717bb1ab --- /dev/null +++ b/nano/node/rocksdb/final_vote_store.cpp @@ -0,0 +1,88 @@ +#include +#include + +nano::final_vote_store_rocksdb::final_vote_store_rocksdb (nano::rocksdb_store & store) : + store{ store } {}; + +bool nano::final_vote_store_rocksdb::put (nano::write_transaction const & transaction, nano::qualified_root const & root, nano::block_hash const & hash) +{ + nano::rocksdb_val value; + auto status = store.get (transaction, tables::final_votes, root, value); + release_assert (store.success (status) || store.not_found (status)); + bool result (true); + if (store.success (status)) + { + result = static_cast (value) == hash; + } + else + { + status = store.put (transaction, tables::final_votes, root, hash); + release_assert_success (store, status); + } + return result; +} + +std::vector nano::final_vote_store_rocksdb::get (nano::transaction const & transaction, nano::root const & root_a) +{ + std::vector result; + nano::qualified_root key_start{ root_a.raw, 0 }; + for (auto i = begin (transaction, key_start), n = end (); i != n && nano::qualified_root{ i->first }.root () == root_a; ++i) + { + result.push_back (i->second); + } + return result; +} + +void nano::final_vote_store_rocksdb::del (nano::write_transaction const & transaction, nano::root const & root) +{ + std::vector final_vote_qualified_roots; + for (auto i = begin (transaction, nano::qualified_root{ root.raw, 0 }), n = end (); i != n && nano::qualified_root{ i->first }.root () == root; ++i) + { + final_vote_qualified_roots.push_back (i->first); + } + + for (auto & final_vote_qualified_root : final_vote_qualified_roots) + { + auto status = store.del (transaction, tables::final_votes, final_vote_qualified_root); + release_assert_success (store, status); + } +} + +size_t nano::final_vote_store_rocksdb::count (nano::transaction const & transaction_a) const +{ + return store.count (transaction_a, tables::final_votes); +} + +void nano::final_vote_store_rocksdb::clear (nano::write_transaction const & transaction_a, nano::root const & root_a) +{ + del (transaction_a, root_a); +} + +void nano::final_vote_store_rocksdb::clear (nano::write_transaction const & transaction_a) +{ + store.drop (transaction_a, nano::tables::final_votes); +} + +nano::store_iterator nano::final_vote_store_rocksdb::begin (nano::transaction const & transaction, nano::qualified_root const & root) const +{ + return store.make_iterator (transaction, tables::final_votes, root); +} + +nano::store_iterator nano::final_vote_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::final_votes); +} + +nano::store_iterator nano::final_vote_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::final_vote_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/final_vote_store.hpp b/nano/node/rocksdb/final_vote_store.hpp new file mode 100644 index 00000000..9473dc2a --- /dev/null +++ b/nano/node/rocksdb/final_vote_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class final_vote_store_rocksdb : public final_vote_store +{ +private: + nano::rocksdb_store & store; + +public: + explicit final_vote_store_rocksdb (nano::rocksdb_store & store); + bool put (nano::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) override; + std::vector get (nano::transaction const & transaction_a, nano::root const & root_a) override; + void del (nano::write_transaction const & transaction_a, nano::root const & root_a) override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a, nano::root const & root_a) override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::qualified_root const & root_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/rocksdb/frontier_store.cpp b/nano/node/rocksdb/frontier_store.cpp new file mode 100644 index 00000000..3002c7f4 --- /dev/null +++ b/nano/node/rocksdb/frontier_store.cpp @@ -0,0 +1,56 @@ +#include +#include + +nano::frontier_store_rocksdb::frontier_store_rocksdb (nano::rocksdb_store & store) : + store{ store } +{ +} + +void nano::frontier_store_rocksdb::put (nano::write_transaction const & transaction, nano::block_hash const & block, nano::account const & account) +{ + auto status = store.put (transaction, tables::frontiers, block, account); + release_assert_success (store, status); +} + +nano::account nano::frontier_store_rocksdb::get (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + nano::db_val value; + auto status = store.get (transaction, tables::frontiers, hash, value); + release_assert (store.success (status) || store.not_found (status)); + nano::account result{}; + if (store.success (status)) + { + result = static_cast (value); + } + return result; +} + +void nano::frontier_store_rocksdb::del (nano::write_transaction const & transaction, nano::block_hash const & hash) +{ + auto status = store.del (transaction, tables::frontiers, hash); + release_assert_success (store, status); +} + +nano::store_iterator nano::frontier_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::frontiers); +} + +nano::store_iterator nano::frontier_store_rocksdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const +{ + return store.make_iterator (transaction, tables::frontiers, hash); +} + +nano::store_iterator nano::frontier_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::frontier_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/frontier_store.hpp b/nano/node/rocksdb/frontier_store.hpp new file mode 100644 index 00000000..832b6699 --- /dev/null +++ b/nano/node/rocksdb/frontier_store.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class frontier_store_rocksdb : public frontier_store +{ +public: + frontier_store_rocksdb (nano::rocksdb_store & store); + void put (nano::write_transaction const &, nano::block_hash const &, nano::account const &) override; + nano::account get (nano::transaction const &, nano::block_hash const &) const override; + void del (nano::write_transaction const &, nano::block_hash const &) override; + nano::store_iterator begin (nano::transaction const &) const override; + nano::store_iterator begin (nano::transaction const &, nano::block_hash const &) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; + +private: + nano::rocksdb_store & store; +}; + +} diff --git a/nano/node/rocksdb/online_weight_store.cpp b/nano/node/rocksdb/online_weight_store.cpp new file mode 100644 index 00000000..257070a0 --- /dev/null +++ b/nano/node/rocksdb/online_weight_store.cpp @@ -0,0 +1,45 @@ +#include +#include + +nano::online_weight_store_rocksdb::online_weight_store_rocksdb (nano::rocksdb_store & store_a) : + store{ store_a } +{ +} + +void nano::online_weight_store_rocksdb::put (nano::write_transaction const & transaction, uint64_t time, nano::amount const & amount) +{ + auto status = store.put (transaction, tables::online_weight, time, amount); + release_assert_success (store, status); +} + +void nano::online_weight_store_rocksdb::del (nano::write_transaction const & transaction, uint64_t time) +{ + auto status = store.del (transaction, tables::online_weight, time); + release_assert_success (store, status); +} + +nano::store_iterator nano::online_weight_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::online_weight); +} + +nano::store_iterator nano::online_weight_store_rocksdb::rbegin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::online_weight, false); +} + +nano::store_iterator nano::online_weight_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +size_t nano::online_weight_store_rocksdb::count (nano::transaction const & transaction) const +{ + return store.count (transaction, tables::online_weight); +} + +void nano::online_weight_store_rocksdb::clear (nano::write_transaction const & transaction) +{ + auto status = store.drop (transaction, tables::online_weight); + release_assert_success (store, status); +} diff --git a/nano/node/rocksdb/online_weight_store.hpp b/nano/node/rocksdb/online_weight_store.hpp new file mode 100644 index 00000000..49305a01 --- /dev/null +++ b/nano/node/rocksdb/online_weight_store.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class online_weight_store_rocksdb : public online_weight_store +{ +private: + nano::rocksdb_store & store; + +public: + explicit online_weight_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override; + void del (nano::write_transaction const & transaction_a, uint64_t time_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator rbegin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a) override; +}; +} diff --git a/nano/node/rocksdb/peer_store.cpp b/nano/node/rocksdb/peer_store.cpp new file mode 100644 index 00000000..0318097d --- /dev/null +++ b/nano/node/rocksdb/peer_store.cpp @@ -0,0 +1,43 @@ +#include +#include + +nano::peer_store_rocksdb::peer_store_rocksdb (nano::rocksdb_store & store) : + store{ store } {}; + +void nano::peer_store_rocksdb::put (nano::write_transaction const & transaction, nano::endpoint_key const & endpoint) +{ + auto status = store.put_key (transaction, tables::peers, endpoint); + release_assert_success (store, status); +} + +void nano::peer_store_rocksdb::del (nano::write_transaction const & transaction, nano::endpoint_key const & endpoint) +{ + auto status = store.del (transaction, tables::peers, endpoint); + release_assert_success (store, status); +} + +bool nano::peer_store_rocksdb::exists (nano::transaction const & transaction, nano::endpoint_key const & endpoint) const +{ + return store.exists (transaction, tables::peers, endpoint); +} + +size_t nano::peer_store_rocksdb::count (nano::transaction const & transaction) const +{ + return store.count (transaction, tables::peers); +} + +void nano::peer_store_rocksdb::clear (nano::write_transaction const & transaction) +{ + auto status = store.drop (transaction, tables::peers); + release_assert_success (store, status); +} + +nano::store_iterator nano::peer_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::peers); +} + +nano::store_iterator nano::peer_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} diff --git a/nano/node/rocksdb/peer_store.hpp b/nano/node/rocksdb/peer_store.hpp new file mode 100644 index 00000000..5827f532 --- /dev/null +++ b/nano/node/rocksdb/peer_store.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class peer_store_rocksdb : public peer_store +{ +private: + nano::rocksdb_store & store; + +public: + explicit peer_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override; + void del (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override; + bool exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; +}; +} diff --git a/nano/node/rocksdb/pending_store.cpp b/nano/node/rocksdb/pending_store.cpp new file mode 100644 index 00000000..fdb2b61d --- /dev/null +++ b/nano/node/rocksdb/pending_store.cpp @@ -0,0 +1,71 @@ +#include +#include + +nano::pending_store_rocksdb::pending_store_rocksdb (nano::rocksdb_store & store) : + store{ store } {}; + +void nano::pending_store_rocksdb::put (nano::write_transaction const & transaction, nano::pending_key const & key, nano::pending_info const & pending) +{ + auto status = store.put (transaction, tables::pending, key, pending); + release_assert_success (store, status); +} + +void nano::pending_store_rocksdb::del (nano::write_transaction const & transaction, nano::pending_key const & key) +{ + auto status = store.del (transaction, tables::pending, key); + release_assert_success (store, status); +} + +bool nano::pending_store_rocksdb::get (nano::transaction const & transaction, nano::pending_key const & key, nano::pending_info & pending) +{ + nano::rocksdb_val value; + auto status1 = store.get (transaction, tables::pending, key, value); + release_assert (store.success (status1) || store.not_found (status1)); + bool result (true); + if (store.success (status1)) + { + nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); + result = pending.deserialize (stream); + } + return result; +} + +bool nano::pending_store_rocksdb::exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) +{ + auto iterator (begin (transaction_a, key_a)); + return iterator != end () && nano::pending_key (iterator->first) == key_a; +} + +bool nano::pending_store_rocksdb::any (nano::transaction const & transaction_a, nano::account const & account_a) +{ + auto iterator (begin (transaction_a, nano::pending_key (account_a, 0))); + return iterator != end () && nano::pending_key (iterator->first).account == account_a; +} + +nano::store_iterator nano::pending_store_rocksdb::begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const +{ + return store.template make_iterator (transaction_a, tables::pending, key_a); +} + +nano::store_iterator nano::pending_store_rocksdb::begin (nano::transaction const & transaction_a) const +{ + return store.template make_iterator (transaction_a, tables::pending); +} + +nano::store_iterator nano::pending_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::pending_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { + nano::uint512_union union_start (start); + nano::uint512_union union_end (end); + nano::pending_key key_start (union_start.uint256s[0].number (), union_start.uint256s[1].number ()); + nano::pending_key key_end (union_end.uint256s[0].number (), union_end.uint256s[1].number ()); + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/pending_store.hpp b/nano/node/rocksdb/pending_store.hpp new file mode 100644 index 00000000..831a2d94 --- /dev/null +++ b/nano/node/rocksdb/pending_store.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class pending_store_rocksdb : public pending_store +{ +private: + nano::rocksdb_store & store; + +public: + explicit pending_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info const & pending_info_a) override; + void del (nano::write_transaction const & transaction_a, nano::pending_key const & key_a) override; + bool get (nano::transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info & pending_a) override; + bool exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) override; + bool any (nano::transaction const & transaction_a, nano::account const & account_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/rocksdb/pruned_store.cpp b/nano/node/rocksdb/pruned_store.cpp new file mode 100644 index 00000000..57b097a9 --- /dev/null +++ b/nano/node/rocksdb/pruned_store.cpp @@ -0,0 +1,69 @@ +#include +#include + +nano::pruned_store_rocksdb::pruned_store_rocksdb (nano::rocksdb_store & store_a) : + store{ store_a } {}; + +void nano::pruned_store_rocksdb::put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto status = store.put_key (transaction_a, tables::pruned, hash_a); + release_assert_success (store, status); +} + +void nano::pruned_store_rocksdb::del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) +{ + auto status = store.del (transaction_a, tables::pruned, hash_a); + release_assert_success (store, status); +} + +bool nano::pruned_store_rocksdb::exists (nano::transaction const & transaction, nano::block_hash const & hash_a) const +{ + return store.exists (transaction, tables::pruned, hash_a); +} + +nano::block_hash nano::pruned_store_rocksdb::random (nano::transaction const & transaction) +{ + nano::block_hash random_hash; + nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ()); + auto existing = begin (transaction, random_hash); + if (existing == end ()) + { + existing = begin (transaction); + } + return existing != end () ? existing->first : 0; +} + +size_t nano::pruned_store_rocksdb::count (nano::transaction const & transaction_a) const +{ + return store.count (transaction_a, tables::pruned); +} + +void nano::pruned_store_rocksdb::clear (nano::write_transaction const & transaction_a) +{ + auto status = store.drop (transaction_a, tables::pruned); + release_assert_success (store, status); +} + +nano::store_iterator nano::pruned_store_rocksdb::begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + return store.make_iterator (transaction_a, tables::pruned, hash_a); +} + +nano::store_iterator nano::pruned_store_rocksdb::begin (nano::transaction const & transaction_a) const +{ + return store.make_iterator (transaction_a, tables::pruned); +} + +nano::store_iterator nano::pruned_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +void nano::pruned_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/pruned_store.hpp b/nano/node/rocksdb/pruned_store.hpp new file mode 100644 index 00000000..b6110b2a --- /dev/null +++ b/nano/node/rocksdb/pruned_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class pruned_store_rocksdb : public pruned_store +{ +private: + nano::rocksdb_store & store; + +public: + explicit pruned_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; + bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::block_hash random (nano::transaction const & transaction_a) override; + size_t count (nano::transaction const & transaction_a) const override; + void clear (nano::write_transaction const & transaction_a) override; + nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator end () const override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/rocksdb/rocksdb.cpp b/nano/node/rocksdb/rocksdb.cpp index 5b3843d2..f0a3777d 100644 --- a/nano/node/rocksdb/rocksdb.cpp +++ b/nano/node/rocksdb/rocksdb.cpp @@ -67,30 +67,30 @@ nano::rocksdb_store::rocksdb_store (nano::logger_mt & logger_a, boost::filesyste // clang-format off store_partial{ constants, - block_store_partial, - frontier_store_partial, - account_store_partial, - pending_store_partial, - unchecked_rocksdb_store, - online_weight_store_partial, - pruned_store_partial, - peer_store_partial, - confirmation_height_store_partial, - final_vote_store_partial, - version_rocksdb_store + block_store, + frontier_store, + account_store, + pending_store, + unchecked_store, + online_weight_store, + pruned_store, + peer_store, + confirmation_height_store, + final_vote_store, + version_store }, // clang-format on - block_store_partial{ *this }, - frontier_store_partial{ *this }, - account_store_partial{ *this }, - pending_store_partial{ *this }, - unchecked_rocksdb_store{ *this }, - online_weight_store_partial{ *this }, - pruned_store_partial{ *this }, - peer_store_partial{ *this }, - confirmation_height_store_partial{ *this }, - final_vote_store_partial{ *this }, - version_rocksdb_store{ *this }, + block_store{ *this }, + frontier_store{ *this }, + account_store{ *this }, + pending_store{ *this }, + unchecked_store{ *this }, + online_weight_store{ *this }, + pruned_store{ *this }, + peer_store{ *this }, + confirmation_height_store{ *this }, + final_vote_store{ *this }, + version_store{ *this }, logger{ logger_a }, constants{ constants }, rocksdb_config{ rocksdb_config_a }, @@ -442,15 +442,6 @@ void nano::rocksdb_store::flush_table (nano::tables table_a) db->Flush (rocksdb::FlushOptions{}, table_to_column_family (table_a)); } -void nano::version_rocksdb_store::version_put (nano::write_transaction const & transaction_a, int version_a) -{ - debug_assert (transaction_a.contains (tables::meta)); - nano::uint256_union version_key (1); - nano::uint256_union version_value (version_a); - auto status (rocksdb_store.put (transaction_a, tables::meta, version_key, nano::rocksdb_val (version_value))); - release_assert (rocksdb_store.success (status)); -} - rocksdb::Transaction * nano::rocksdb_store::tx (nano::transaction const & transaction_a) const { debug_assert (!is_read (transaction_a)); @@ -614,14 +605,6 @@ int nano::rocksdb_store::clear (rocksdb::ColumnFamilyHandle * column_family) return status.code (); } -nano::unchecked_rocksdb_store::unchecked_rocksdb_store (nano::rocksdb_store & rocksdb_store_a) : - nano::unchecked_store_partial (rocksdb_store_a), - rocksdb_store{ rocksdb_store_a } {}; - -nano::version_rocksdb_store::version_rocksdb_store (nano::rocksdb_store & rocksdb_store_a) : - nano::version_store_partial (rocksdb_store_a), - rocksdb_store{ rocksdb_store_a } {}; - void nano::rocksdb_store::construct_column_family_mutexes () { for (auto table : all_tables ()) diff --git a/nano/node/rocksdb/rocksdb.hpp b/nano/node/rocksdb/rocksdb.hpp index 599a72c0..e398ac4e 100644 --- a/nano/node/rocksdb/rocksdb.hpp +++ b/nano/node/rocksdb/rocksdb.hpp @@ -3,18 +3,19 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -31,46 +32,36 @@ class logging_mt; class rocksdb_config; class rocksdb_store; -class unchecked_rocksdb_store : public unchecked_store_partial -{ -public: - explicit unchecked_rocksdb_store (nano::rocksdb_store &); - -private: - nano::rocksdb_store & rocksdb_store; -}; - -class version_rocksdb_store : public version_store_partial -{ -public: - explicit version_rocksdb_store (nano::rocksdb_store &); - void version_put (nano::write_transaction const &, int); - -private: - nano::rocksdb_store & rocksdb_store; -}; - /** * rocksdb implementation of the block store */ class rocksdb_store : public store_partial { private: - nano::block_store_partial block_store_partial; - nano::frontier_store_partial frontier_store_partial; - nano::account_store_partial account_store_partial; - nano::pending_store_partial pending_store_partial; - nano::unchecked_rocksdb_store unchecked_rocksdb_store; - nano::online_weight_store_partial online_weight_store_partial; - nano::pruned_store_partial pruned_store_partial; - nano::peer_store_partial peer_store_partial; - nano::confirmation_height_store_partial confirmation_height_store_partial; - nano::final_vote_store_partial final_vote_store_partial; - nano::version_rocksdb_store version_rocksdb_store; + nano::block_store_rocksdb block_store; + nano::frontier_store_rocksdb frontier_store; + nano::account_store_rocksdb account_store; + nano::confirmation_height_store_rocksdb confirmation_height_store; + nano::pending_store_rocksdb pending_store; + nano::unchecked_store_rocksdb unchecked_store; + nano::online_weight_store_rocksdb online_weight_store; + nano::pruned_store_rocksdb pruned_store; + nano::peer_store_rocksdb peer_store; + nano::final_vote_store_rocksdb final_vote_store; + nano::version_store_rocksdb version_store; public: - friend class nano::unchecked_rocksdb_store; - friend class nano::version_rocksdb_store; + friend class nano::account_store_rocksdb; + friend class nano::block_store_rocksdb; + friend class nano::confirmation_height_store_rocksdb; + friend class nano::frontier_store_rocksdb; + friend class nano::final_vote_store_rocksdb; + friend class nano::online_weight_store_rocksdb; + friend class nano::peer_store_rocksdb; + friend class nano::pending_store_rocksdb; + friend class nano::pruned_store_rocksdb; + friend class nano::unchecked_store_rocksdb; + friend class nano::version_store_rocksdb; explicit rocksdb_store (nano::logger_mt &, boost::filesystem::path const &, nano::ledger_constants & constants, nano::rocksdb_config const & = nano::rocksdb_config{}, bool open_read_only = false); @@ -94,7 +85,7 @@ public: unsigned max_block_write_batch_num () const override; template - nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc) const + nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const { return nano::store_iterator (std::make_unique> (db.get (), transaction_a, table_to_column_family (table_a), nullptr, direction_asc)); } diff --git a/nano/node/rocksdb/unchecked_store.cpp b/nano/node/rocksdb/unchecked_store.cpp new file mode 100644 index 00000000..f8cf3252 --- /dev/null +++ b/nano/node/rocksdb/unchecked_store.cpp @@ -0,0 +1,62 @@ +#include +#include + +nano::unchecked_store_rocksdb::unchecked_store_rocksdb (nano::rocksdb_store & store_a) : + store (store_a){}; + +void nano::unchecked_store_rocksdb::clear (nano::write_transaction const & transaction_a) +{ + auto status = store.drop (transaction_a, tables::unchecked); + release_assert_success (store, status); +} + +void nano::unchecked_store_rocksdb::put (nano::write_transaction const & transaction_a, nano::hash_or_account const & dependency, nano::unchecked_info const & info) +{ + auto status = store.put (transaction_a, tables::unchecked, nano::unchecked_key{ dependency, info.block->hash () }, info); + release_assert_success (store, status); +} + +bool nano::unchecked_store_rocksdb::exists (nano::transaction const & transaction_a, nano::unchecked_key const & key) +{ + nano::rocksdb_val value; + auto status = store.get (transaction_a, tables::unchecked, key, value); + release_assert (store.success (status) || store.not_found (status)); + return store.success (status); +} + +void nano::unchecked_store_rocksdb::del (nano::write_transaction const & transaction_a, nano::unchecked_key const & key_a) +{ + auto status (store.del (transaction_a, tables::unchecked, key_a)); + release_assert_success (store, status); +} + +nano::store_iterator nano::unchecked_store_rocksdb::end () const +{ + return nano::store_iterator (nullptr); +} + +nano::store_iterator nano::unchecked_store_rocksdb::begin (nano::transaction const & transaction) const +{ + return store.make_iterator (transaction, tables::unchecked); +} + +nano::store_iterator nano::unchecked_store_rocksdb::lower_bound (nano::transaction const & transaction, nano::unchecked_key const & key) const +{ + return store.make_iterator (transaction, tables::unchecked, key); +} + +size_t nano::unchecked_store_rocksdb::count (nano::transaction const & transaction_a) +{ + return store.count (transaction_a, tables::unchecked); +} + +void nano::unchecked_store_rocksdb::for_each_par (std::function, nano::store_iterator)> const & action_a) const +{ + parallel_traversal ( + [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { + nano::unchecked_key key_start (start); + nano::unchecked_key key_end (end); + auto transaction (this->store.tx_begin_read ()); + action_a (transaction, this->lower_bound (transaction, key_start), !is_last ? this->lower_bound (transaction, key_end) : this->end ()); + }); +} diff --git a/nano/node/rocksdb/unchecked_store.hpp b/nano/node/rocksdb/unchecked_store.hpp new file mode 100644 index 00000000..1d673972 --- /dev/null +++ b/nano/node/rocksdb/unchecked_store.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace nano +{ +class mdb_store; +class unchecked_store_rocksdb : public unchecked_store +{ +private: + nano::rocksdb_store & store; + +public: + unchecked_store_rocksdb (nano::rocksdb_store & store_a); + + void clear (nano::write_transaction const & transaction_a) override; + void put (nano::write_transaction const & transaction_a, nano::hash_or_account const & dependency, nano::unchecked_info const & info_a) override; + bool exists (nano::transaction const & transaction_a, nano::unchecked_key const & unchecked_key_a) override; + void del (nano::write_transaction const & transaction_a, nano::unchecked_key const & key_a) override; + nano::store_iterator end () const override; + nano::store_iterator begin (nano::transaction const & transaction_a) const override; + nano::store_iterator lower_bound (nano::transaction const & transaction_a, nano::unchecked_key const & key_a) const override; + size_t count (nano::transaction const & transaction_a) override; + void for_each_par (std::function, nano::store_iterator)> const & action_a) const override; +}; +} diff --git a/nano/node/rocksdb/version_store.cpp b/nano/node/rocksdb/version_store.cpp new file mode 100644 index 00000000..caf459e8 --- /dev/null +++ b/nano/node/rocksdb/version_store.cpp @@ -0,0 +1,28 @@ +#include +#include + +nano::version_store_rocksdb::version_store_rocksdb (nano::rocksdb_store & store_a) : + store{ store_a } {}; + +void nano::version_store_rocksdb::put (nano::write_transaction const & transaction_a, int version) +{ + nano::uint256_union version_key{ 1 }; + nano::uint256_union version_value (version); + auto status = store.put (transaction_a, tables::meta, version_key, version_value); + release_assert_success (store, status); +} + +int nano::version_store_rocksdb::get (nano::transaction const & transaction_a) const +{ + nano::uint256_union version_key{ 1 }; + nano::rocksdb_val data; + auto status = store.get (transaction_a, tables::meta, version_key, data); + int result = store.minimum_version; + if (store.success (status)) + { + nano::uint256_union version_value{ data }; + debug_assert (version_value.qwords[2] == 0 && version_value.qwords[1] == 0 && version_value.qwords[0] == 0); + result = version_value.number ().convert_to (); + } + return result; +} diff --git a/nano/node/rocksdb/version_store.hpp b/nano/node/rocksdb/version_store.hpp new file mode 100644 index 00000000..e81057e8 --- /dev/null +++ b/nano/node/rocksdb/version_store.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace nano +{ +class rocksdb_store; +class version_store_rocksdb : public version_store +{ +protected: + nano::rocksdb_store & store; + +public: + explicit version_store_rocksdb (nano::rocksdb_store & store_a); + void put (nano::write_transaction const & transaction_a, int version_a) override; + int get (nano::transaction const & transaction_a) const override; +}; +} diff --git a/nano/secure/CMakeLists.txt b/nano/secure/CMakeLists.txt index e55d8982..bd6f02f6 100644 --- a/nano/secure/CMakeLists.txt +++ b/nano/secure/CMakeLists.txt @@ -53,18 +53,7 @@ add_library( utility.cpp versioning.hpp versioning.cpp - working.hpp - store/block_store_partial.hpp - store/frontier_store_partial.hpp - store/account_store_partial.hpp - store/pending_store_partial.hpp - store/online_weight_partial.hpp - store/pruned_store_partial.hpp - store/peer_store_partial.hpp - store/confirmation_height_store_partial.hpp - store/unchecked_store_partial.hpp - store/final_vote_store_partial.hpp - store/version_store_partial.hpp) + working.hpp) target_link_libraries( secure diff --git a/nano/secure/store/account_store_partial.hpp b/nano/secure/store/account_store_partial.hpp deleted file mode 100644 index 727ba5d7..00000000 --- a/nano/secure/store/account_store_partial.hpp +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class account_store_partial : public account_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit account_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::account const & account_a, nano::account_info const & info_a) override - { - // Check we are still in sync with other tables - nano::db_val info (info_a); - auto status = store.put (transaction_a, tables::accounts, account_a, info); - release_assert_success (store, status); - } - - bool get (nano::transaction const & transaction_a, nano::account const & account_a, nano::account_info & info_a) override - { - nano::db_val value; - nano::db_val account (account_a); - auto status1 (store.get (transaction_a, tables::accounts, account, value)); - release_assert (store.success (status1) || store.not_found (status1)); - bool result (true); - if (store.success (status1)) - { - nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); - result = info_a.deserialize (stream); - } - return result; - } - - void del (nano::write_transaction const & transaction_a, nano::account const & account_a) override - { - auto status = store.del (transaction_a, tables::accounts, account_a); - release_assert_success (store, status); - } - - bool exists (nano::transaction const & transaction_a, nano::account const & account_a) override - { - auto iterator (begin (transaction_a, account_a)); - return iterator != end () && nano::account (iterator->first) == account_a; - } - - size_t count (nano::transaction const & transaction_a) override - { - return store.count (transaction_a, tables::accounts); - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::account const & account_a) const override - { - return store.template make_iterator (transaction_a, tables::accounts, nano::db_val (account_a)); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::accounts); - } - - nano::store_iterator rbegin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::accounts, false); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/block_store_partial.hpp b/nano/secure/store/block_store_partial.hpp deleted file mode 100644 index a8461af5..00000000 --- a/nano/secure/store/block_store_partial.hpp +++ /dev/null @@ -1,313 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -class block_predecessor_set; - -template -void release_assert_success (store_partial const &, int const); - -template -class block_store_partial : public block_store -{ -protected: - nano::store_partial & store; - - friend class nano::block_predecessor_set; - -public: - explicit block_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a, nano::block const & block_a) override - { - debug_assert (block_a.sideband ().successor.is_zero () || exists (transaction_a, block_a.sideband ().successor)); - std::vector vector; - { - nano::vectorstream stream (vector); - nano::serialize_block (stream, block_a); - block_a.sideband ().serialize (stream, block_a.type ()); - } - raw_put (transaction_a, vector, hash_a); - nano::block_predecessor_set predecessor (transaction_a, *this); - block_a.visit (predecessor); - debug_assert (block_a.previous ().is_zero () || successor (transaction_a, block_a.previous ()) == hash_a); - } - - void raw_put (nano::write_transaction const & transaction_a, std::vector const & data, nano::block_hash const & hash_a) override - { - nano::db_val value{ data.size (), (void *)data.data () }; - auto status = store.put (transaction_a, tables::blocks, hash_a, value); - release_assert_success (store, status); - } - - nano::block_hash successor (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - auto value (block_raw_get (transaction_a, hash_a)); - nano::block_hash result; - if (value.size () != 0) - { - debug_assert (value.size () >= result.bytes.size ()); - auto type = block_type_from_raw (value.data ()); - nano::bufferstream stream (reinterpret_cast (value.data ()) + block_successor_offset (transaction_a, value.size (), type), result.bytes.size ()); - auto error (nano::try_read (stream, result.bytes)); - (void)error; - debug_assert (!error); - } - else - { - result.clear (); - } - return result; - } - - void successor_clear (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto value (block_raw_get (transaction_a, hash_a)); - debug_assert (value.size () != 0); - auto type = block_type_from_raw (value.data ()); - std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); - std::fill_n (data.begin () + block_successor_offset (transaction_a, value.size (), type), sizeof (nano::block_hash), uint8_t{ 0 }); - raw_put (transaction_a, data, hash_a); - } - - std::shared_ptr get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - auto value (block_raw_get (transaction_a, hash_a)); - std::shared_ptr result; - if (value.size () != 0) - { - nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); - nano::block_type type; - auto error (try_read (stream, type)); - release_assert (!error); - result = nano::deserialize_block (stream, type); - release_assert (result != nullptr); - nano::block_sideband sideband; - error = (sideband.deserialize (stream, type)); - release_assert (!error); - result->sideband_set (sideband); - } - return result; - } - - std::shared_ptr get_no_sideband (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - auto value (block_raw_get (transaction_a, hash_a)); - std::shared_ptr result; - if (value.size () != 0) - { - nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); - result = nano::deserialize_block (stream); - debug_assert (result != nullptr); - } - return result; - } - - std::shared_ptr random (nano::transaction const & transaction_a) override - { - nano::block_hash hash; - nano::random_pool::generate_block (hash.bytes.data (), hash.bytes.size ()); - auto existing = store.template make_iterator> (transaction_a, tables::blocks, nano::db_val (hash)); - auto end (nano::store_iterator> (nullptr)); - if (existing == end) - { - existing = store.template make_iterator> (transaction_a, tables::blocks); - } - debug_assert (existing != end); - return existing->second; - } - - void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto status = store.del (transaction_a, tables::blocks, hash_a); - release_assert_success (store, status); - } - - bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto junk = block_raw_get (transaction_a, hash_a); - return junk.size () != 0; - } - - uint64_t count (nano::transaction const & transaction_a) override - { - return store.count (transaction_a, tables::blocks); - } - - nano::account account (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - auto block (get (transaction_a, hash_a)); - debug_assert (block != nullptr); - return account_calculated (*block); - } - - nano::account account_calculated (nano::block const & block_a) const override - { - debug_assert (block_a.has_sideband ()); - nano::account result (block_a.account ()); - if (result.is_zero ()) - { - result = block_a.sideband ().account; - } - debug_assert (!result.is_zero ()); - return result; - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::blocks); - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - return store.template make_iterator (transaction_a, tables::blocks, nano::db_val (hash_a)); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - nano::uint128_t balance (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto block (get (transaction_a, hash_a)); - release_assert (block); - nano::uint128_t result (balance_calculated (block)); - return result; - } - - nano::uint128_t balance_calculated (std::shared_ptr const & block_a) const override - { - nano::uint128_t result; - switch (block_a->type ()) - { - case nano::block_type::open: - case nano::block_type::receive: - case nano::block_type::change: - result = block_a->sideband ().balance.number (); - break; - case nano::block_type::send: - result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); - break; - case nano::block_type::state: - result = boost::polymorphic_downcast (block_a.get ())->hashables.balance.number (); - break; - case nano::block_type::invalid: - case nano::block_type::not_a_block: - release_assert (false); - break; - } - return result; - } - - nano::epoch version (nano::transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto block = get (transaction_a, hash_a); - if (block && block->type () == nano::block_type::state) - { - return block->sideband ().details.epoch; - } - - return nano::epoch::epoch_0; - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); - }); - } - - // Converts a block hash to a block height - uint64_t account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - auto block = get (transaction_a, hash_a); - return block->sideband ().height; - } - -protected: - nano::db_val block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const - { - nano::db_val result; - auto status = store.get (transaction_a, tables::blocks, hash_a, result); - release_assert (store.success (status) || store.not_found (status)); - return result; - } - - size_t block_successor_offset (nano::transaction const & transaction_a, size_t entry_size_a, nano::block_type type_a) const - { - return entry_size_a - nano::block_sideband::size (type_a); - } - - static nano::block_type block_type_from_raw (void * data_a) - { - // The block type is the first byte - return static_cast ((reinterpret_cast (data_a))[0]); - } -}; - -/** - * Fill in our predecessors - */ -template -class block_predecessor_set : public nano::block_visitor -{ -public: - block_predecessor_set (nano::write_transaction const & transaction_a, nano::block_store_partial & block_store_a) : - transaction (transaction_a), - block_store (block_store_a) - { - } - virtual ~block_predecessor_set () = default; - void fill_value (nano::block const & block_a) - { - auto hash (block_a.hash ()); - auto value (block_store.block_raw_get (transaction, block_a.previous ())); - debug_assert (value.size () != 0); - auto type = block_store.block_type_from_raw (value.data ()); - std::vector data (static_cast (value.data ()), static_cast (value.data ()) + value.size ()); - std::copy (hash.bytes.begin (), hash.bytes.end (), data.begin () + block_store.block_successor_offset (transaction, value.size (), type)); - block_store.raw_put (transaction, data, block_a.previous ()); - } - void send_block (nano::send_block const & block_a) override - { - fill_value (block_a); - } - void receive_block (nano::receive_block const & block_a) override - { - fill_value (block_a); - } - void open_block (nano::open_block const & block_a) override - { - // Open blocks don't have a predecessor - } - void change_block (nano::change_block const & block_a) override - { - fill_value (block_a); - } - void state_block (nano::state_block const & block_a) override - { - if (!block_a.previous ().is_zero ()) - { - fill_value (block_a); - } - } - nano::write_transaction const & transaction; - nano::block_store_partial & block_store; -}; -} diff --git a/nano/secure/store/confirmation_height_store_partial.hpp b/nano/secure/store/confirmation_height_store_partial.hpp deleted file mode 100644 index 3eb4fd60..00000000 --- a/nano/secure/store/confirmation_height_store_partial.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class confirmation_height_store_partial : public confirmation_height_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit confirmation_height_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info const & confirmation_height_info_a) override - { - nano::db_val confirmation_height_info (confirmation_height_info_a); - auto status = store.put (transaction_a, tables::confirmation_height, account_a, confirmation_height_info); - release_assert_success (store, status); - } - - bool get (nano::transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info & confirmation_height_info_a) override - { - nano::db_val value; - auto status = store.get (transaction_a, tables::confirmation_height, nano::db_val (account_a), value); - release_assert (store.success (status) || store.not_found (status)); - bool result (true); - if (store.success (status)) - { - nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); - result = confirmation_height_info_a.deserialize (stream); - } - if (result) - { - confirmation_height_info_a.height = 0; - confirmation_height_info_a.frontier = 0; - } - - return result; - } - - bool exists (nano::transaction const & transaction_a, nano::account const & account_a) const override - { - return store.exists (transaction_a, tables::confirmation_height, nano::db_val (account_a)); - } - - void del (nano::write_transaction const & transaction_a, nano::account const & account_a) override - { - auto status (store.del (transaction_a, tables::confirmation_height, nano::db_val (account_a))); - release_assert_success (store, status); - } - - uint64_t count (nano::transaction const & transaction_a) override - { - return store.count (transaction_a, tables::confirmation_height); - } - - void clear (nano::write_transaction const & transaction_a, nano::account const & account_a) override - { - del (transaction_a, account_a); - } - - void clear (nano::write_transaction const & transaction_a) override - { - store.drop (transaction_a, nano::tables::confirmation_height); - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::account const & account_a) const override - { - return store.template make_iterator (transaction_a, tables::confirmation_height, nano::db_val (account_a)); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::confirmation_height); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/final_vote_store_partial.hpp b/nano/secure/store/final_vote_store_partial.hpp deleted file mode 100644 index b0f450c9..00000000 --- a/nano/secure/store/final_vote_store_partial.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const & store, int const status); - -template -class final_vote_store_partial : public final_vote_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit final_vote_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - bool put (nano::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) override - { - nano::db_val value; - auto status = store.get (transaction_a, tables::final_votes, nano::db_val (root_a), value); - release_assert (store.success (status) || store.not_found (status)); - bool result (true); - if (store.success (status)) - { - result = static_cast (value) == hash_a; - } - else - { - status = store.put (transaction_a, tables::final_votes, root_a, hash_a); - release_assert_success (store, status); - } - return result; - } - - std::vector get (nano::transaction const & transaction_a, nano::root const & root_a) override - { - std::vector result; - nano::qualified_root key_start (root_a.raw, 0); - for (auto i (begin (transaction_a, key_start)), n (end ()); i != n && nano::qualified_root (i->first).root () == root_a; ++i) - { - result.push_back (i->second); - } - return result; - } - - void del (nano::write_transaction const & transaction_a, nano::root const & root_a) override - { - std::vector final_vote_qualified_roots; - for (auto i (begin (transaction_a, nano::qualified_root (root_a.raw, 0))), n (end ()); i != n && nano::qualified_root (i->first).root () == root_a; ++i) - { - final_vote_qualified_roots.push_back (i->first); - } - - for (auto & final_vote_qualified_root : final_vote_qualified_roots) - { - auto status (store.del (transaction_a, tables::final_votes, nano::db_val (final_vote_qualified_root))); - release_assert_success (store, status); - } - } - - size_t count (nano::transaction const & transaction_a) const override - { - return store.count (transaction_a, tables::final_votes); - } - - void clear (nano::write_transaction const & transaction_a, nano::root const & root_a) override - { - del (transaction_a, root_a); - } - - void clear (nano::write_transaction const & transaction_a) override - { - store.drop (transaction_a, nano::tables::final_votes); - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::qualified_root const & root_a) const override - { - return store.template make_iterator (transaction_a, tables::final_votes, nano::db_val (root_a)); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::final_votes); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/frontier_store_partial.hpp b/nano/secure/store/frontier_store_partial.hpp deleted file mode 100644 index 78d44a31..00000000 --- a/nano/secure/store/frontier_store_partial.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const & store, int const status); - -template -class frontier_store_partial : public frontier_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit frontier_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::block_hash const & block_a, nano::account const & account_a) override - { - nano::db_val account (account_a); - auto status (store.put (transaction_a, tables::frontiers, block_a, account)); - release_assert_success (store, status); - } - - nano::account get (nano::transaction const & transaction_a, nano::block_hash const & block_a) const override - { - nano::db_val value; - auto status (store.get (transaction_a, tables::frontiers, nano::db_val (block_a), value)); - release_assert (store.success (status) || store.not_found (status)); - nano::account result{}; - if (store.success (status)) - { - result = static_cast (value); - } - return result; - } - - void del (nano::write_transaction const & transaction_a, nano::block_hash const & block_a) override - { - auto status (store.del (transaction_a, tables::frontiers, block_a)); - release_assert_success (store, status); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::frontiers); - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - return store.template make_iterator (transaction_a, tables::frontiers, nano::db_val (hash_a)); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/online_weight_partial.hpp b/nano/secure/store/online_weight_partial.hpp deleted file mode 100644 index 0e1bbefd..00000000 --- a/nano/secure/store/online_weight_partial.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class online_weight_store_partial : public online_weight_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit online_weight_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override - { - nano::db_val value (amount_a); - auto status (store.put (transaction_a, tables::online_weight, time_a, value)); - release_assert_success (store, status); - } - - void del (nano::write_transaction const & transaction_a, uint64_t time_a) override - { - auto status (store.del (transaction_a, tables::online_weight, time_a)); - release_assert_success (store, status); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::online_weight); - } - - nano::store_iterator rbegin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::online_weight, false); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - size_t count (nano::transaction const & transaction_a) const override - { - return store.count (transaction_a, tables::online_weight); - } - - void clear (nano::write_transaction const & transaction_a) override - { - auto status (store.drop (transaction_a, tables::online_weight)); - release_assert_success (store, status); - } -}; - -} diff --git a/nano/secure/store/peer_store_partial.hpp b/nano/secure/store/peer_store_partial.hpp deleted file mode 100644 index 913e17a6..00000000 --- a/nano/secure/store/peer_store_partial.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class peer_store_partial : public peer_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit peer_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override - { - auto status = store.put_key (transaction_a, tables::peers, endpoint_a); - release_assert_success (store, status); - } - - void del (nano::write_transaction const & transaction_a, nano::endpoint_key const & endpoint_a) override - { - auto status (store.del (transaction_a, tables::peers, endpoint_a)); - release_assert_success (store, status); - } - - bool exists (nano::transaction const & transaction_a, nano::endpoint_key const & endpoint_a) const override - { - return store.exists (transaction_a, tables::peers, nano::db_val (endpoint_a)); - } - - size_t count (nano::transaction const & transaction_a) const override - { - return store.count (transaction_a, tables::peers); - } - - void clear (nano::write_transaction const & transaction_a) override - { - auto status = store.drop (transaction_a, tables::peers); - release_assert_success (store, status); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::peers); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } -}; - -} diff --git a/nano/secure/store/pending_store_partial.hpp b/nano/secure/store/pending_store_partial.hpp deleted file mode 100644 index 25d6ba54..00000000 --- a/nano/secure/store/pending_store_partial.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class pending_store_partial : public pending_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit pending_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info const & pending_info_a) override - { - nano::db_val pending (pending_info_a); - auto status = store.put (transaction_a, tables::pending, key_a, pending); - release_assert_success (store, status); - } - - void del (nano::write_transaction const & transaction_a, nano::pending_key const & key_a) override - { - auto status = store.del (transaction_a, tables::pending, key_a); - release_assert_success (store, status); - } - - bool get (nano::transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info & pending_a) override - { - nano::db_val value; - nano::db_val key (key_a); - auto status1 = store.get (transaction_a, tables::pending, key, value); - release_assert (store.success (status1) || store.not_found (status1)); - bool result (true); - if (store.success (status1)) - { - nano::bufferstream stream (reinterpret_cast (value.data ()), value.size ()); - result = pending_a.deserialize (stream); - } - return result; - } - - bool exists (nano::transaction const & transaction_a, nano::pending_key const & key_a) override - { - auto iterator (begin (transaction_a, key_a)); - return iterator != end () && nano::pending_key (iterator->first) == key_a; - } - - bool any (nano::transaction const & transaction_a, nano::account const & account_a) override - { - auto iterator (begin (transaction_a, nano::pending_key (account_a, 0))); - return iterator != end () && nano::pending_key (iterator->first).account == account_a; - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const override - { - return store.template make_iterator (transaction_a, tables::pending, nano::db_val (key_a)); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::pending); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { - nano::uint512_union union_start (start); - nano::uint512_union union_end (end); - nano::pending_key key_start (union_start.uint256s[0].number (), union_start.uint256s[1].number ()); - nano::pending_key key_end (union_end.uint256s[0].number (), union_end.uint256s[1].number ()); - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/pruned_store_partial.hpp b/nano/secure/store/pruned_store_partial.hpp deleted file mode 100644 index 93b9e1a0..00000000 --- a/nano/secure/store/pruned_store_partial.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class pruned_store_partial : public pruned_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - explicit pruned_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto status = store.put_key (transaction_a, tables::pruned, hash_a); - release_assert_success (store, status); - } - - void del (nano::write_transaction const & transaction_a, nano::block_hash const & hash_a) override - { - auto status = store.del (transaction_a, tables::pruned, hash_a); - release_assert_success (store, status); - } - - bool exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - return store.exists (transaction_a, tables::pruned, nano::db_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 = store.template make_iterator> (transaction_a, tables::pruned, nano::db_val (random_hash)); - auto end (nano::store_iterator> (nullptr)); - if (existing == end) - { - existing = store.template make_iterator> (transaction_a, tables::pruned); - } - return existing != end ? existing->first : 0; - } - - size_t count (nano::transaction const & transaction_a) const override - { - return store.count (transaction_a, tables::pruned); - } - - void clear (nano::write_transaction const & transaction_a) override - { - auto status = store.drop (transaction_a, tables::pruned); - release_assert_success (store, status); - } - - nano::store_iterator begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override - { - return store.template make_iterator (transaction_a, tables::pruned, nano::db_val (hash_a)); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::pruned); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/unchecked_store_partial.hpp b/nano/secure/store/unchecked_store_partial.hpp deleted file mode 100644 index 30da7f61..00000000 --- a/nano/secure/store/unchecked_store_partial.hpp +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include - -namespace -{ -template -void parallel_traversal (std::function const & action); -} - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class unchecked_store_partial : public unchecked_store -{ -private: - nano::store_partial & store; - - friend void release_assert_success (store_partial const &, int const); - -public: - unchecked_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void clear (nano::write_transaction const & transaction_a) override - { - auto status = store.drop (transaction_a, tables::unchecked); - release_assert_success (store, status); - } - - void put (nano::write_transaction const & transaction_a, nano::hash_or_account const & dependency, nano::unchecked_info const & info_a) override - { - nano::db_val info (info_a); - auto status (store.put (transaction_a, tables::unchecked, nano::unchecked_key{ dependency, info_a.block->hash () }, info)); - release_assert_success (store, status); - } - - bool exists (nano::transaction const & transaction_a, nano::unchecked_key const & unchecked_key_a) override - { - nano::db_val value; - auto status (store.get (transaction_a, tables::unchecked, nano::db_val (unchecked_key_a), value)); - release_assert (store.success (status) || store.not_found (status)); - return (store.success (status)); - } - - void del (nano::write_transaction const & transaction_a, nano::unchecked_key const & key_a) override - { - auto status (store.del (transaction_a, tables::unchecked, key_a)); - release_assert_success (store, status); - } - - nano::store_iterator end () const override - { - return nano::store_iterator (nullptr); - } - - nano::store_iterator begin (nano::transaction const & transaction_a) const override - { - return store.template make_iterator (transaction_a, tables::unchecked); - } - - nano::store_iterator lower_bound (nano::transaction const & transaction_a, nano::unchecked_key const & key_a) const override - { - return store.template make_iterator (transaction_a, tables::unchecked, nano::db_val (key_a)); - } - - size_t count (nano::transaction const & transaction_a) override - { - return store.count (transaction_a, tables::unchecked); - } - - void for_each_par (std::function, nano::store_iterator)> const & action_a) const override - { - parallel_traversal ( - [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { - nano::unchecked_key key_start (start); - nano::unchecked_key key_end (end); - auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->lower_bound (transaction, key_start), !is_last ? this->lower_bound (transaction, key_end) : this->end ()); - }); - } -}; - -} diff --git a/nano/secure/store/version_store_partial.hpp b/nano/secure/store/version_store_partial.hpp deleted file mode 100644 index 9966c20d..00000000 --- a/nano/secure/store/version_store_partial.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include - -namespace nano -{ -template -class store_partial; - -template -void release_assert_success (store_partial const &, int const); - -template -class version_store_partial : public version_store -{ -protected: - nano::store_partial & store; - -public: - explicit version_store_partial (nano::store_partial & store_a) : - store (store_a){}; - - void put (nano::write_transaction const & transaction_a, int version_a) override - { - nano::uint256_union version_key (1); - nano::uint256_union version_value (version_a); - auto status (store.put (transaction_a, tables::meta, nano::db_val (version_key), nano::db_val (version_value))); - release_assert_success (store, status); - } - - int get (nano::transaction const & transaction_a) const override - { - nano::uint256_union version_key (1); - nano::db_val data; - auto status = store.get (transaction_a, tables::meta, nano::db_val (version_key), data); - int result (store.minimum_version); - if (store.success (status)) - { - nano::uint256_union version_value (data); - debug_assert (version_value.qwords[2] == 0 && version_value.qwords[1] == 0 && version_value.qwords[0] == 0); - result = version_value.number ().convert_to (); - } - return result; - } -}; - -} diff --git a/nano/secure/store_partial.hpp b/nano/secure/store_partial.hpp index 31103cee..d8f72582 100644 --- a/nano/secure/store_partial.hpp +++ b/nano/secure/store_partial.hpp @@ -6,17 +6,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include @@ -32,71 +21,45 @@ void parallel_traversal (std::function namespace nano { template -class block_predecessor_set; +class store_partial; template -void release_assert_success (store_partial const & store, int const status) -{ - if (!store.success (status)) - { - release_assert (false, store.error_string (status)); - } -} - -template -class account_store_partial; - -template -class unchecked_store_partial; - -template -class block_store_partial; +void release_assert_success (store_partial const & store, int const status); /** This base class implements the store interface functions which have DB agnostic functionality. It also maps all the store classes. */ template class store_partial : public store { friend void release_assert_success (store_partial const &, int const); - friend class nano::block_store_partial; - friend class nano::frontier_store_partial; - friend class nano::account_store_partial; - friend class nano::pending_store_partial; - friend class nano::unchecked_store_partial; - friend class nano::online_weight_store_partial; - friend class nano::pruned_store_partial; - friend class nano::peer_store_partial; - friend class nano::confirmation_height_store_partial; - friend class nano::final_vote_store_partial; - friend class nano::version_store_partial; public: // clang-format off store_partial ( nano::ledger_constants & constants, - nano::block_store_partial & block_store_partial_a, - nano::frontier_store_partial & frontier_store_partial_a, - nano::account_store_partial & account_store_partial_a, - nano::pending_store_partial & pending_store_partial_a, - nano::unchecked_store_partial & unchecked_store_partial_a, - nano::online_weight_store_partial & online_weight_store_partial_a, - nano::pruned_store_partial & pruned_store_partial_a, - nano::peer_store_partial & peer_store_partial_a, - nano::confirmation_height_store_partial & confirmation_height_store_partial_a, - nano::final_vote_store_partial & final_vote_store_partial_a, - nano::version_store_partial & version_store_partial_a) : + nano::block_store & block_store_a, + nano::frontier_store & frontier_store_a, + nano::account_store & account_store_a, + nano::pending_store & pending_store_a, + nano::unchecked_store & unchecked_store_a, + nano::online_weight_store & online_weight_store_a, + nano::pruned_store & pruned_store_a, + nano::peer_store & peer_store_a, + nano::confirmation_height_store & confirmation_height_store_a, + nano::final_vote_store & final_vote_store_a, + nano::version_store & version_store_a) : constants{ constants }, store{ - block_store_partial_a, - frontier_store_partial_a, - account_store_partial_a, - pending_store_partial_a, - unchecked_store_partial_a, - online_weight_store_partial_a, - pruned_store_partial_a, - peer_store_partial_a, - confirmation_height_store_partial_a, - final_vote_store_partial_a, - version_store_partial_a + block_store_a, + frontier_store_a, + account_store_a, + pending_store_a, + unchecked_store_a, + online_weight_store_a, + pruned_store_a, + peer_store_a, + confirmation_height_store_a, + final_vote_store_a, + version_store_a } {} // clang-format on @@ -131,12 +94,6 @@ public: return static_cast (*this).exists (transaction_a, table_a, key_a); } - int const minimum_version{ 14 }; - -protected: - nano::ledger_constants & constants; - int const version_number{ 21 }; - template nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const { @@ -149,6 +106,12 @@ protected: return static_cast (*this).template make_iterator (transaction_a, table_a, key); } + int const minimum_version{ 14 }; + +protected: + nano::ledger_constants & constants; + int const version_number{ 21 }; + uint64_t count (nano::transaction const & transaction_a, std::initializer_list dbs_a) const { uint64_t total_count = 0; @@ -187,6 +150,15 @@ protected: virtual int status_code_not_found () const = 0; virtual std::string error_string (int status) const = 0; }; + +template +void release_assert_success (store_partial const & store, int const status) +{ + if (!store.success (status)) + { + release_assert (false, store.error_string (status)); + } +} } namespace