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.
This commit is contained in:
clemahieu 2022-04-09 13:34:11 +01:00 committed by GitHub
commit e9eb258ab0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 2617 additions and 1418 deletions

View file

@ -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

View file

@ -0,0 +1,71 @@
#include <nano/node/lmdb/account_store.hpp>
#include <nano/node/lmdb/lmdb.hpp>
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<uint8_t const *> (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, nano::account_info> nano::account_store_mdb::begin (nano::transaction const & transaction, nano::account const & account) const
{
return store.make_iterator<nano::account, nano::account_info> (transaction, tables::accounts, account);
}
nano::store_iterator<nano::account, nano::account_info> nano::account_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::account, nano::account_info> (transaction, tables::accounts);
}
nano::store_iterator<nano::account, nano::account_info> nano::account_store_mdb::rbegin (nano::transaction const & transaction_a) const
{
return store.make_iterator<nano::account, nano::account_info> (transaction_a, tables::accounts, false);
}
nano::store_iterator<nano::account, nano::account_info> nano::account_store_mdb::end () const
{
return nano::store_iterator<nano::account, nano::account_info> (nullptr);
}
void nano::account_store_mdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::account_info>, nano::store_iterator<nano::account, nano::account_info>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::account, nano::account_info> begin (nano::transaction const & transaction_a, nano::account const & account_a) const override;
nano::store_iterator<nano::account, nano::account_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::account, nano::account_info> rbegin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::account, nano::account_info> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::account_info>, nano::store_iterator<nano::account, nano::account_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,296 @@
#include <nano/node/lmdb/block_store.hpp>
#include <nano/node/lmdb/lmdb.hpp>
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<uint8_t> 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<uint8_t> 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<uint8_t const *> (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<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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> 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<nano::block> result;
if (value.size () != 0)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (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> 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<nano::block> result;
if (value.size () != 0)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
result = nano::deserialize_block (stream);
debug_assert (result != nullptr);
}
return result;
}
std::shared_ptr<nano::block> 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_hash, nano::block_w_sideband> nano::block_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::block_hash, nano::block_w_sideband> (transaction, tables::blocks);
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> nano::block_store_mdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const
{
return store.make_iterator<nano::block_hash, nano::block_w_sideband> (transaction, tables::blocks, hash);
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> nano::block_store_mdb::end () const
{
return nano::store_iterator<nano::block_hash, nano::block_w_sideband> (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<nano::block> 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<nano::send_block *> (block_a.get ())->hashables.balance.number ();
break;
case nano::block_type::state:
result = boost::polymorphic_downcast<nano::state_block *> (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<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, block_w_sideband>, nano::store_iterator<nano::block_hash, block_w_sideband>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->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<nano::block_type> ((reinterpret_cast<uint8_t const *> (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<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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);
}
}

View file

@ -0,0 +1,44 @@
#pragma once
#include <nano/secure/store.hpp>
namespace nano
{
class mdb_store;
using mdb_val = db_val<MDB_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<uint8_t> 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<nano::block> get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
std::shared_ptr<nano::block> get_no_sideband (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
std::shared_ptr<nano::block> 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<nano::block_hash, nano::block_w_sideband> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::block_hash, nano::block_w_sideband> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
nano::store_iterator<nano::block_hash, nano::block_w_sideband> 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<nano::block> 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<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, block_w_sideband>, nano::store_iterator<nano::block_hash, block_w_sideband>)> const & action_a) const 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);
};
}

View file

@ -0,0 +1,83 @@
#include <nano/node/lmdb/confirmation_height_store.hpp>
#include <nano/node/lmdb/lmdb.hpp>
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<uint8_t const *> (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::account, nano::confirmation_height_info> nano::confirmation_height_store_mdb::begin (nano::transaction const & transaction, nano::account const & account) const
{
return store.make_iterator<nano::account, nano::confirmation_height_info> (transaction, tables::confirmation_height, account);
}
nano::store_iterator<nano::account, nano::confirmation_height_info> nano::confirmation_height_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::account, nano::confirmation_height_info> (transaction, tables::confirmation_height);
}
nano::store_iterator<nano::account, nano::confirmation_height_info> nano::confirmation_height_store_mdb::end () const
{
return nano::store_iterator<nano::account, nano::confirmation_height_info> (nullptr);
}
void nano::confirmation_height_store_mdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::confirmation_height_info>, nano::store_iterator<nano::account, nano::confirmation_height_info>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::account, nano::confirmation_height_info> begin (nano::transaction const & transaction_a, nano::account const & account_a) const override;
nano::store_iterator<nano::account, nano::confirmation_height_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::account, nano::confirmation_height_info> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::confirmation_height_info>, nano::store_iterator<nano::account, nano::confirmation_height_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,88 @@
#include <nano/node/lmdb/final_vote_store.hpp>
#include <nano/node/lmdb/lmdb.hpp>
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<nano::block_hash> (value) == hash;
}
else
{
status = store.put (transaction, tables::final_votes, root, hash);
release_assert_success (store, status);
}
return result;
}
std::vector<nano::block_hash> nano::final_vote_store_mdb::get (nano::transaction const & transaction, nano::root const & root_a)
{
std::vector<nano::block_hash> 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<nano::qualified_root> 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::qualified_root, nano::block_hash> nano::final_vote_store_mdb::begin (nano::transaction const & transaction, nano::qualified_root const & root) const
{
return store.make_iterator<nano::qualified_root, nano::block_hash> (transaction, tables::final_votes, root);
}
nano::store_iterator<nano::qualified_root, nano::block_hash> nano::final_vote_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::qualified_root, nano::block_hash> (transaction, tables::final_votes);
}
nano::store_iterator<nano::qualified_root, nano::block_hash> nano::final_vote_store_mdb::end () const
{
return nano::store_iterator<nano::qualified_root, nano::block_hash> (nullptr);
}
void nano::final_vote_store_mdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::qualified_root, nano::block_hash>, nano::store_iterator<nano::qualified_root, nano::block_hash>)> const & action_a) const
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::block_hash> 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<nano::qualified_root, nano::block_hash> begin (nano::transaction const & transaction_a, nano::qualified_root const & root_a) const override;
nano::store_iterator<nano::qualified_root, nano::block_hash> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::qualified_root, nano::block_hash> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::qualified_root, nano::block_hash>, nano::store_iterator<nano::qualified_root, nano::block_hash>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,56 @@
#include <nano/node/lmdb/frontier_store.hpp>
#include <nano/node/lmdb/lmdb.hpp>
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<MDB_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<nano::account> (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::block_hash, nano::account> nano::frontier_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::block_hash, nano::account> (transaction, tables::frontiers);
}
nano::store_iterator<nano::block_hash, nano::account> nano::frontier_store_mdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const
{
return store.make_iterator<nano::block_hash, nano::account> (transaction, tables::frontiers, nano::db_val<MDB_val> (hash));
}
nano::store_iterator<nano::block_hash, nano::account> nano::frontier_store_mdb::end () const
{
return nano::store_iterator<nano::block_hash, nano::account> (nullptr);
}
void nano::frontier_store_mdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, nano::account>, nano::store_iterator<nano::block_hash, nano::account>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::block_hash, nano::account> begin (nano::transaction const &) const override;
nano::store_iterator<nano::block_hash, nano::account> begin (nano::transaction const &, nano::block_hash const &) const override;
nano::store_iterator<nano::block_hash, nano::account> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, nano::account>, nano::store_iterator<nano::block_hash, nano::account>)> const & action_a) const override;
private:
nano::mdb_store & store;
};
}

View file

@ -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_val, mdb_store> (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<nano::uint256_union, nano::mdb_val> (std::make_unique<nano::mdb_iterator<nano::uint256_union, nano::mdb_val>> (transaction_a, table))), n (nano::store_iterator<nano::uint256_union, nano::mdb_val> (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<nano::uint256_union, nano::mdb_val> (std::make_unique<nano::mdb_iterator<nano::uint256_union, nano::mdb_val>> (transaction_a, temp))), n (nano::store_iterator<nano::uint256_union, nano::mdb_val> (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<nano::pending_key, nano::pending_info> (std::make_unique<nano::mdb_iterator<nano::pending_key, nano::pending_info>> (transaction_a, pending_handle))), n (nano::store_iterator<nano::pending_key, nano::pending_info> (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<nano::pending_key, nano::pending_info> (std::make_unique<nano::mdb_iterator<nano::pending_key, nano::pending_info>> (transaction_a, temp))), n (nano::store_iterator<nano::pending_key, nano::pending_info> (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);

View file

@ -4,21 +4,21 @@
#include <nano/lib/lmdbconfig.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/node/lmdb/account_store.hpp>
#include <nano/node/lmdb/block_store.hpp>
#include <nano/node/lmdb/confirmation_height_store.hpp>
#include <nano/node/lmdb/final_vote_store.hpp>
#include <nano/node/lmdb/frontier_store.hpp>
#include <nano/node/lmdb/lmdb_env.hpp>
#include <nano/node/lmdb/lmdb_iterator.hpp>
#include <nano/node/lmdb/lmdb_txn.hpp>
#include <nano/node/lmdb/online_weight_store.hpp>
#include <nano/node/lmdb/peer_store.hpp>
#include <nano/node/lmdb/pending_store.hpp>
#include <nano/node/lmdb/pruned_store.hpp>
#include <nano/node/lmdb/unchecked_store.hpp>
#include <nano/node/lmdb/version_store.hpp>
#include <nano/secure/common.hpp>
#include <nano/secure/store/account_store_partial.hpp>
#include <nano/secure/store/block_store_partial.hpp>
#include <nano/secure/store/confirmation_height_store_partial.hpp>
#include <nano/secure/store/final_vote_store_partial.hpp>
#include <nano/secure/store/frontier_store_partial.hpp>
#include <nano/secure/store/online_weight_partial.hpp>
#include <nano/secure/store/peer_store_partial.hpp>
#include <nano/secure/store/pending_store_partial.hpp>
#include <nano/secure/store/pruned_store_partial.hpp>
#include <nano/secure/store/unchecked_store_partial.hpp>
#include <nano/secure/store/version_store_partial.hpp>
#include <nano/secure/store_partial.hpp>
#include <nano/secure/versioning.hpp>
@ -40,12 +40,7 @@ using mdb_val = db_val<MDB_val>;
class logging_mt;
class mdb_store;
class unchecked_mdb_store : public unchecked_store_partial<MDB_val, mdb_store>
{
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<MDB_val, mdb_store>
{
private:
nano::block_store_partial<MDB_val, mdb_store> block_store_partial;
nano::frontier_store_partial<MDB_val, mdb_store> frontier_store_partial;
nano::account_store_partial<MDB_val, mdb_store> account_store_partial;
nano::pending_store_partial<MDB_val, mdb_store> pending_store_partial;
nano::unchecked_mdb_store unchecked_mdb_store;
nano::online_weight_store_partial<MDB_val, mdb_store> online_weight_store_partial;
nano::pruned_store_partial<MDB_val, mdb_store> pruned_store_partial;
nano::peer_store_partial<MDB_val, mdb_store> peer_store_partial;
nano::confirmation_height_store_partial<MDB_val, mdb_store> confirmation_height_store_partial;
nano::final_vote_store_partial<MDB_val, mdb_store> final_vote_store_partial;
nano::version_store_partial<MDB_val, mdb_store> 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 <typename Key, typename Value>
nano::store_iterator<Key, Value> make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc) const
nano::store_iterator<Key, Value> make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const
{
return nano::store_iterator<Key, Value> (std::make_unique<nano::mdb_iterator<Key, Value>> (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;

View file

@ -0,0 +1,45 @@
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/node/lmdb/online_weight_store.hpp>
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<uint64_t, nano::amount> nano::online_weight_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<uint64_t, nano::amount> (transaction, tables::online_weight);
}
nano::store_iterator<uint64_t, nano::amount> nano::online_weight_store_mdb::rbegin (nano::transaction const & transaction) const
{
return store.make_iterator<uint64_t, nano::amount> (transaction, tables::online_weight, false);
}
nano::store_iterator<uint64_t, nano::amount> nano::online_weight_store_mdb::end () const
{
return nano::store_iterator<uint64_t, nano::amount> (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);
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <nano/secure/store.hpp>
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<uint64_t, nano::amount> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<uint64_t, nano::amount> rbegin (nano::transaction const & transaction_a) const override;
nano::store_iterator<uint64_t, nano::amount> end () const override;
size_t count (nano::transaction const & transaction_a) const override;
void clear (nano::write_transaction const & transaction_a) override;
};
}

View file

@ -0,0 +1,43 @@
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/node/lmdb/peer_store.hpp>
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::endpoint_key, nano::no_value> nano::peer_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::endpoint_key, nano::no_value> (transaction, tables::peers);
}
nano::store_iterator<nano::endpoint_key, nano::no_value> nano::peer_store_mdb::end () const
{
return nano::store_iterator<nano::endpoint_key, nano::no_value> (nullptr);
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::endpoint_key, nano::no_value> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::endpoint_key, nano::no_value> end () const override;
};
}

View file

@ -0,0 +1,71 @@
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/node/lmdb/pending_store.hpp>
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<uint8_t const *> (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_key, nano::pending_info> nano::pending_store_mdb::begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const
{
return store.make_iterator<nano::pending_key, nano::pending_info> (transaction_a, tables::pending, key_a);
}
nano::store_iterator<nano::pending_key, nano::pending_info> nano::pending_store_mdb::begin (nano::transaction const & transaction_a) const
{
return store.make_iterator<nano::pending_key, nano::pending_info> (transaction_a, tables::pending);
}
nano::store_iterator<nano::pending_key, nano::pending_info> nano::pending_store_mdb::end () const
{
return nano::store_iterator<nano::pending_key, nano::pending_info> (nullptr);
}
void nano::pending_store_mdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::pending_key, nano::pending_info>, nano::store_iterator<nano::pending_key, nano::pending_info>)> const & action_a) const
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}

View file

@ -0,0 +1,25 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::pending_key, nano::pending_info> begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const override;
nano::store_iterator<nano::pending_key, nano::pending_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::pending_key, nano::pending_info> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::pending_key, nano::pending_info>, nano::store_iterator<nano::pending_key, nano::pending_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,69 @@
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/node/lmdb/pruned_store.hpp>
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::block_hash, std::nullptr_t> nano::pruned_store_mdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const
{
return store.make_iterator<nano::block_hash, std::nullptr_t> (transaction, tables::pruned, hash);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> nano::pruned_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::block_hash, std::nullptr_t> (transaction, tables::pruned);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> nano::pruned_store_mdb::end () const
{
return nano::store_iterator<nano::block_hash, std::nullptr_t> (nullptr);
}
void nano::pruned_store_mdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::block_hash, std::nullptr_t> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,62 @@
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/node/lmdb/unchecked_store.hpp>
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_key, nano::unchecked_info> nano::unchecked_store_mdb::end () const
{
return nano::store_iterator<nano::unchecked_key, nano::unchecked_info> (nullptr);
}
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> nano::unchecked_store_mdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::unchecked_key, nano::unchecked_info> (transaction, tables::unchecked);
}
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> nano::unchecked_store_mdb::lower_bound (nano::transaction const & transaction, nano::unchecked_key const & key) const
{
return store.make_iterator<nano::unchecked_key, nano::unchecked_info> (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<void (nano::read_transaction const &, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>)> const & action_a) const
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::unchecked_key, nano::unchecked_info> end () const override;
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> 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<void (nano::read_transaction const &, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,28 @@
#include <nano/node/lmdb/lmdb.hpp>
#include <nano/node/lmdb/version_store.hpp>
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<int> ();
}
return result;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include <nano/secure/store.hpp>
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;
};
}

View file

@ -0,0 +1,71 @@
#include <nano/node/rocksdb/account_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<uint8_t const *> (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, nano::account_info> nano::account_store_rocksdb::begin (nano::transaction const & transaction, nano::account const & account) const
{
return store.make_iterator<nano::account, nano::account_info> (transaction, tables::accounts, account);
}
nano::store_iterator<nano::account, nano::account_info> nano::account_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::account, nano::account_info> (transaction, tables::accounts);
}
nano::store_iterator<nano::account, nano::account_info> nano::account_store_rocksdb::rbegin (nano::transaction const & transaction_a) const
{
return store.make_iterator<nano::account, nano::account_info> (transaction_a, tables::accounts, false);
}
nano::store_iterator<nano::account, nano::account_info> nano::account_store_rocksdb::end () const
{
return nano::store_iterator<nano::account, nano::account_info> (nullptr);
}
void nano::account_store_rocksdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::account_info>, nano::store_iterator<nano::account, nano::account_info>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::account, nano::account_info> begin (nano::transaction const & transaction_a, nano::account const & account_a) const override;
nano::store_iterator<nano::account, nano::account_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::account, nano::account_info> rbegin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::account, nano::account_info> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::account_info>, nano::store_iterator<nano::account, nano::account_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,296 @@
#include <nano/node/rocksdb/block_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<uint8_t> 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<uint8_t> 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<uint8_t const *> (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<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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> 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<nano::block> result;
if (value.size () != 0)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (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> 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<nano::block> result;
if (value.size () != 0)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
result = nano::deserialize_block (stream);
debug_assert (result != nullptr);
}
return result;
}
std::shared_ptr<nano::block> 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_hash, nano::block_w_sideband> nano::block_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::block_hash, nano::block_w_sideband> (transaction, tables::blocks);
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> nano::block_store_rocksdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const
{
return store.make_iterator<nano::block_hash, nano::block_w_sideband> (transaction, tables::blocks, hash);
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> nano::block_store_rocksdb::end () const
{
return nano::store_iterator<nano::block_hash, nano::block_w_sideband> (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<nano::block> 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<nano::send_block *> (block_a.get ())->hashables.balance.number ();
break;
case nano::block_type::state:
result = boost::polymorphic_downcast<nano::state_block *> (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<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, block_w_sideband>, nano::store_iterator<nano::block_hash, block_w_sideband>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->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<nano::block_type> ((reinterpret_cast<uint8_t const *> (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<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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);
}
}

View file

@ -0,0 +1,46 @@
#pragma once
#include <nano/secure/store.hpp>
#include <rocksdb/slice.h>
namespace nano
{
class rocksdb_store;
using rocksdb_val = db_val<rocksdb::Slice>;
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<uint8_t> 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<nano::block> get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
std::shared_ptr<nano::block> get_no_sideband (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
std::shared_ptr<nano::block> 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<nano::block_hash, nano::block_w_sideband> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::block_hash, nano::block_w_sideband> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
nano::store_iterator<nano::block_hash, nano::block_w_sideband> 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<nano::block> 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<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, block_w_sideband>, nano::store_iterator<nano::block_hash, block_w_sideband>)> const & action_a) const 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);
};
}

View file

@ -0,0 +1,83 @@
#include <nano/node/rocksdb/confirmation_height_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<uint8_t const *> (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::account, nano::confirmation_height_info> nano::confirmation_height_store_rocksdb::begin (nano::transaction const & transaction, nano::account const & account) const
{
return store.make_iterator<nano::account, nano::confirmation_height_info> (transaction, tables::confirmation_height, account);
}
nano::store_iterator<nano::account, nano::confirmation_height_info> nano::confirmation_height_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::account, nano::confirmation_height_info> (transaction, tables::confirmation_height);
}
nano::store_iterator<nano::account, nano::confirmation_height_info> nano::confirmation_height_store_rocksdb::end () const
{
return nano::store_iterator<nano::account, nano::confirmation_height_info> (nullptr);
}
void nano::confirmation_height_store_rocksdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::confirmation_height_info>, nano::store_iterator<nano::account, nano::confirmation_height_info>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::account, nano::confirmation_height_info> begin (nano::transaction const & transaction_a, nano::account const & account_a) const override;
nano::store_iterator<nano::account, nano::confirmation_height_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::account, nano::confirmation_height_info> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::confirmation_height_info>, nano::store_iterator<nano::account, nano::confirmation_height_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,88 @@
#include <nano/node/rocksdb/final_vote_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<nano::block_hash> (value) == hash;
}
else
{
status = store.put (transaction, tables::final_votes, root, hash);
release_assert_success (store, status);
}
return result;
}
std::vector<nano::block_hash> nano::final_vote_store_rocksdb::get (nano::transaction const & transaction, nano::root const & root_a)
{
std::vector<nano::block_hash> 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<nano::qualified_root> 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::qualified_root, nano::block_hash> nano::final_vote_store_rocksdb::begin (nano::transaction const & transaction, nano::qualified_root const & root) const
{
return store.make_iterator<nano::qualified_root, nano::block_hash> (transaction, tables::final_votes, root);
}
nano::store_iterator<nano::qualified_root, nano::block_hash> nano::final_vote_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::qualified_root, nano::block_hash> (transaction, tables::final_votes);
}
nano::store_iterator<nano::qualified_root, nano::block_hash> nano::final_vote_store_rocksdb::end () const
{
return nano::store_iterator<nano::qualified_root, nano::block_hash> (nullptr);
}
void nano::final_vote_store_rocksdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::qualified_root, nano::block_hash>, nano::store_iterator<nano::qualified_root, nano::block_hash>)> const & action_a) const
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::block_hash> 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<nano::qualified_root, nano::block_hash> begin (nano::transaction const & transaction_a, nano::qualified_root const & root_a) const override;
nano::store_iterator<nano::qualified_root, nano::block_hash> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::qualified_root, nano::block_hash> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::qualified_root, nano::block_hash>, nano::store_iterator<nano::qualified_root, nano::block_hash>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,56 @@
#include <nano/node/rocksdb/frontier_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<rocksdb::Slice> 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<nano::account> (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::block_hash, nano::account> nano::frontier_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::block_hash, nano::account> (transaction, tables::frontiers);
}
nano::store_iterator<nano::block_hash, nano::account> nano::frontier_store_rocksdb::begin (nano::transaction const & transaction, nano::block_hash const & hash) const
{
return store.make_iterator<nano::block_hash, nano::account> (transaction, tables::frontiers, hash);
}
nano::store_iterator<nano::block_hash, nano::account> nano::frontier_store_rocksdb::end () const
{
return nano::store_iterator<nano::block_hash, nano::account> (nullptr);
}
void nano::frontier_store_rocksdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, nano::account>, nano::store_iterator<nano::block_hash, nano::account>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::block_hash, nano::account> begin (nano::transaction const &) const override;
nano::store_iterator<nano::block_hash, nano::account> begin (nano::transaction const &, nano::block_hash const &) const override;
nano::store_iterator<nano::block_hash, nano::account> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, nano::account>, nano::store_iterator<nano::block_hash, nano::account>)> const & action_a) const override;
private:
nano::rocksdb_store & store;
};
}

View file

@ -0,0 +1,45 @@
#include <nano/node/rocksdb/online_weight_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<uint64_t, nano::amount> nano::online_weight_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<uint64_t, nano::amount> (transaction, tables::online_weight);
}
nano::store_iterator<uint64_t, nano::amount> nano::online_weight_store_rocksdb::rbegin (nano::transaction const & transaction) const
{
return store.make_iterator<uint64_t, nano::amount> (transaction, tables::online_weight, false);
}
nano::store_iterator<uint64_t, nano::amount> nano::online_weight_store_rocksdb::end () const
{
return nano::store_iterator<uint64_t, nano::amount> (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);
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <nano/secure/store.hpp>
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<uint64_t, nano::amount> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<uint64_t, nano::amount> rbegin (nano::transaction const & transaction_a) const override;
nano::store_iterator<uint64_t, nano::amount> end () const override;
size_t count (nano::transaction const & transaction_a) const override;
void clear (nano::write_transaction const & transaction_a) override;
};
}

View file

@ -0,0 +1,43 @@
#include <nano/node/rocksdb/peer_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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::endpoint_key, nano::no_value> nano::peer_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::endpoint_key, nano::no_value> (transaction, tables::peers);
}
nano::store_iterator<nano::endpoint_key, nano::no_value> nano::peer_store_rocksdb::end () const
{
return nano::store_iterator<nano::endpoint_key, nano::no_value> (nullptr);
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::endpoint_key, nano::no_value> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::endpoint_key, nano::no_value> end () const override;
};
}

View file

@ -0,0 +1,71 @@
#include <nano/node/lmdb/pending_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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<uint8_t const *> (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_key, nano::pending_info> nano::pending_store_rocksdb::begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const
{
return store.template make_iterator<nano::pending_key, nano::pending_info> (transaction_a, tables::pending, key_a);
}
nano::store_iterator<nano::pending_key, nano::pending_info> nano::pending_store_rocksdb::begin (nano::transaction const & transaction_a) const
{
return store.template make_iterator<nano::pending_key, nano::pending_info> (transaction_a, tables::pending);
}
nano::store_iterator<nano::pending_key, nano::pending_info> nano::pending_store_rocksdb::end () const
{
return nano::store_iterator<nano::pending_key, nano::pending_info> (nullptr);
}
void nano::pending_store_rocksdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::pending_key, nano::pending_info>, nano::store_iterator<nano::pending_key, nano::pending_info>)> const & action_a) const
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}

View file

@ -0,0 +1,25 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::pending_key, nano::pending_info> begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const override;
nano::store_iterator<nano::pending_key, nano::pending_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::pending_key, nano::pending_info> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::pending_key, nano::pending_info>, nano::store_iterator<nano::pending_key, nano::pending_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,69 @@
#include <nano/node/rocksdb/pruned_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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::block_hash, std::nullptr_t> nano::pruned_store_rocksdb::begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
return store.make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned, hash_a);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> nano::pruned_store_rocksdb::begin (nano::transaction const & transaction_a) const
{
return store.make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> nano::pruned_store_rocksdb::end () const
{
return nano::store_iterator<nano::block_hash, std::nullptr_t> (nullptr);
}
void nano::pruned_store_rocksdb::for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override;
nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::block_hash, std::nullptr_t> end () const override;
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const override;
};
}

View file

@ -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::Slice, nano::rocksdb_store> (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::Slice, nano::rocksdb_store> (rocksdb_store_a),
rocksdb_store{ rocksdb_store_a } {};
void nano::rocksdb_store::construct_column_family_mutexes ()
{
for (auto table : all_tables ())

View file

@ -3,18 +3,19 @@
#include <nano/lib/config.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/node/rocksdb/account_store.hpp>
#include <nano/node/rocksdb/block_store.hpp>
#include <nano/node/rocksdb/confirmation_height_store.hpp>
#include <nano/node/rocksdb/final_vote_store.hpp>
#include <nano/node/rocksdb/frontier_store.hpp>
#include <nano/node/rocksdb/online_weight_store.hpp>
#include <nano/node/rocksdb/peer_store.hpp>
#include <nano/node/rocksdb/pending_store.hpp>
#include <nano/node/rocksdb/pruned_store.hpp>
#include <nano/node/rocksdb/rocksdb_iterator.hpp>
#include <nano/node/rocksdb/unchecked_store.hpp>
#include <nano/node/rocksdb/version_store.hpp>
#include <nano/secure/common.hpp>
#include <nano/secure/store/account_store_partial.hpp>
#include <nano/secure/store/confirmation_height_store_partial.hpp>
#include <nano/secure/store/final_vote_store_partial.hpp>
#include <nano/secure/store/frontier_store_partial.hpp>
#include <nano/secure/store/online_weight_partial.hpp>
#include <nano/secure/store/peer_store_partial.hpp>
#include <nano/secure/store/pending_store_partial.hpp>
#include <nano/secure/store/pruned_store_partial.hpp>
#include <nano/secure/store/unchecked_store_partial.hpp>
#include <nano/secure/store/version_store_partial.hpp>
#include <nano/secure/store_partial.hpp>
#include <rocksdb/db.h>
@ -31,46 +32,36 @@ class logging_mt;
class rocksdb_config;
class rocksdb_store;
class unchecked_rocksdb_store : public unchecked_store_partial<rocksdb::Slice, nano::rocksdb_store>
{
public:
explicit unchecked_rocksdb_store (nano::rocksdb_store &);
private:
nano::rocksdb_store & rocksdb_store;
};
class version_rocksdb_store : public version_store_partial<rocksdb::Slice, nano::rocksdb_store>
{
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<rocksdb::Slice, rocksdb_store>
{
private:
nano::block_store_partial<rocksdb::Slice, rocksdb_store> block_store_partial;
nano::frontier_store_partial<rocksdb::Slice, rocksdb_store> frontier_store_partial;
nano::account_store_partial<rocksdb::Slice, rocksdb_store> account_store_partial;
nano::pending_store_partial<rocksdb::Slice, rocksdb_store> pending_store_partial;
nano::unchecked_rocksdb_store unchecked_rocksdb_store;
nano::online_weight_store_partial<rocksdb::Slice, rocksdb_store> online_weight_store_partial;
nano::pruned_store_partial<rocksdb::Slice, rocksdb_store> pruned_store_partial;
nano::peer_store_partial<rocksdb::Slice, rocksdb_store> peer_store_partial;
nano::confirmation_height_store_partial<rocksdb::Slice, rocksdb_store> confirmation_height_store_partial;
nano::final_vote_store_partial<rocksdb::Slice, rocksdb_store> 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 <typename Key, typename Value>
nano::store_iterator<Key, Value> make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc) const
nano::store_iterator<Key, Value> make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const
{
return nano::store_iterator<Key, Value> (std::make_unique<nano::rocksdb_iterator<Key, Value>> (db.get (), transaction_a, table_to_column_family (table_a), nullptr, direction_asc));
}

View file

@ -0,0 +1,62 @@
#include <nano/node/lmdb/unchecked_store.hpp>
#include <nano/node/rocksdb/rocksdb.hpp>
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_key, nano::unchecked_info> nano::unchecked_store_rocksdb::end () const
{
return nano::store_iterator<nano::unchecked_key, nano::unchecked_info> (nullptr);
}
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> nano::unchecked_store_rocksdb::begin (nano::transaction const & transaction) const
{
return store.make_iterator<nano::unchecked_key, nano::unchecked_info> (transaction, tables::unchecked);
}
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> nano::unchecked_store_rocksdb::lower_bound (nano::transaction const & transaction, nano::unchecked_key const & key) const
{
return store.make_iterator<nano::unchecked_key, nano::unchecked_info> (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<void (nano::read_transaction const &, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>)> const & action_a) const
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <nano/secure/store.hpp>
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<nano::unchecked_key, nano::unchecked_info> end () const override;
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> begin (nano::transaction const & transaction_a) const override;
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> 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<void (nano::read_transaction const &, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>)> const & action_a) const override;
};
}

View file

@ -0,0 +1,28 @@
#include <nano/node/rocksdb/rocksdb.hpp>
#include <nano/node/rocksdb/version_store.hpp>
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<int> ();
}
return result;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include <nano/secure/store.hpp>
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;
};
}

View file

@ -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

View file

@ -1,101 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class account_store_partial : public account_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit account_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<Val> value;
nano::db_val<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<uint8_t const *> (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<nano::account, nano::account_info> begin (nano::transaction const & transaction_a, nano::account const & account_a) const override
{
return store.template make_iterator<nano::account, nano::account_info> (transaction_a, tables::accounts, nano::db_val<Val> (account_a));
}
nano::store_iterator<nano::account, nano::account_info> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::account, nano::account_info> (transaction_a, tables::accounts);
}
nano::store_iterator<nano::account, nano::account_info> rbegin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::account, nano::account_info> (transaction_a, tables::accounts, false);
}
nano::store_iterator<nano::account, nano::account_info> end () const override
{
return nano::store_iterator<nano::account, nano::account_info> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::account_info>, nano::store_iterator<nano::account, nano::account_info>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}
};
}

View file

@ -1,313 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
class block_predecessor_set;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class block_store_partial : public block_store
{
protected:
nano::store_partial<Val, Derived_Store> & store;
friend class nano::block_predecessor_set<Val, Derived_Store>;
public:
explicit block_store_partial (nano::store_partial<Val, Derived_Store> & 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<uint8_t> 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<Val, Derived_Store> 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<uint8_t> const & data, nano::block_hash const & hash_a) override
{
nano::db_val<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<uint8_t const *> (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<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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<nano::block> 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<nano::block> result;
if (value.size () != 0)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (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> 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<nano::block> result;
if (value.size () != 0)
{
nano::bufferstream stream (reinterpret_cast<uint8_t const *> (value.data ()), value.size ());
result = nano::deserialize_block (stream);
debug_assert (result != nullptr);
}
return result;
}
std::shared_ptr<nano::block> 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<nano::block_hash, std::shared_ptr<nano::block>> (transaction_a, tables::blocks, nano::db_val<Val> (hash));
auto end (nano::store_iterator<nano::block_hash, std::shared_ptr<nano::block>> (nullptr));
if (existing == end)
{
existing = store.template make_iterator<nano::block_hash, std::shared_ptr<nano::block>> (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<nano::block_hash, nano::block_w_sideband> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::block_hash, nano::block_w_sideband> (transaction_a, tables::blocks);
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return store.template make_iterator<nano::block_hash, nano::block_w_sideband> (transaction_a, tables::blocks, nano::db_val<Val> (hash_a));
}
nano::store_iterator<nano::block_hash, nano::block_w_sideband> end () const override
{
return nano::store_iterator<nano::block_hash, nano::block_w_sideband> (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<nano::block> 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<nano::send_block *> (block_a.get ())->hashables.balance.number ();
break;
case nano::block_type::state:
result = boost::polymorphic_downcast<nano::state_block *> (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<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, block_w_sideband>, nano::store_iterator<nano::block_hash, block_w_sideband>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->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<Val> block_raw_get (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const
{
nano::db_val<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<nano::block_type> ((reinterpret_cast<uint8_t const *> (data_a))[0]);
}
};
/**
* Fill in our predecessors
*/
template <typename Val, typename Derived_Store>
class block_predecessor_set : public nano::block_visitor
{
public:
block_predecessor_set (nano::write_transaction const & transaction_a, nano::block_store_partial<Val, Derived_Store> & 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<uint8_t> data (static_cast<uint8_t *> (value.data ()), static_cast<uint8_t *> (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<Val, Derived_Store> & block_store;
};
}

View file

@ -1,109 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class confirmation_height_store_partial : public confirmation_height_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit confirmation_height_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<Val> value;
auto status = store.get (transaction_a, tables::confirmation_height, nano::db_val<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<uint8_t const *> (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<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<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<nano::account, nano::confirmation_height_info> begin (nano::transaction const & transaction_a, nano::account const & account_a) const override
{
return store.template make_iterator<nano::account, nano::confirmation_height_info> (transaction_a, tables::confirmation_height, nano::db_val<Val> (account_a));
}
nano::store_iterator<nano::account, nano::confirmation_height_info> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::account, nano::confirmation_height_info> (transaction_a, tables::confirmation_height);
}
nano::store_iterator<nano::account, nano::confirmation_height_info> end () const override
{
return nano::store_iterator<nano::account, nano::confirmation_height_info> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::account, nano::confirmation_height_info>, nano::store_iterator<nano::account, nano::confirmation_height_info>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}
};
}

View file

@ -1,115 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const & store, int const status);
template <typename Val, typename Derived_Store>
class final_vote_store_partial : public final_vote_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit final_vote_store_partial (nano::store_partial<Val, Derived_Store> & 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<Val> value;
auto status = store.get (transaction_a, tables::final_votes, nano::db_val<Val> (root_a), value);
release_assert (store.success (status) || store.not_found (status));
bool result (true);
if (store.success (status))
{
result = static_cast<nano::block_hash> (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<nano::block_hash> get (nano::transaction const & transaction_a, nano::root const & root_a) override
{
std::vector<nano::block_hash> 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<nano::qualified_root> 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<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<nano::qualified_root, nano::block_hash> begin (nano::transaction const & transaction_a, nano::qualified_root const & root_a) const override
{
return store.template make_iterator<nano::qualified_root, nano::block_hash> (transaction_a, tables::final_votes, nano::db_val<Val> (root_a));
}
nano::store_iterator<nano::qualified_root, nano::block_hash> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::qualified_root, nano::block_hash> (transaction_a, tables::final_votes);
}
nano::store_iterator<nano::qualified_root, nano::block_hash> end () const override
{
return nano::store_iterator<nano::qualified_root, nano::block_hash> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::qualified_root, nano::block_hash>, nano::store_iterator<nano::qualified_root, nano::block_hash>)> const & action_a) const override
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}
};
}

View file

@ -1,82 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const & store, int const status);
template <typename Val, typename Derived_Store>
class frontier_store_partial : public frontier_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit frontier_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<Val> value;
auto status (store.get (transaction_a, tables::frontiers, nano::db_val<Val> (block_a), value));
release_assert (store.success (status) || store.not_found (status));
nano::account result{};
if (store.success (status))
{
result = static_cast<nano::account> (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<nano::block_hash, nano::account> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::block_hash, nano::account> (transaction_a, tables::frontiers);
}
nano::store_iterator<nano::block_hash, nano::account> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return store.template make_iterator<nano::block_hash, nano::account> (transaction_a, tables::frontiers, nano::db_val<Val> (hash_a));
}
nano::store_iterator<nano::block_hash, nano::account> end () const override
{
return nano::store_iterator<nano::block_hash, nano::account> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, nano::account>, nano::store_iterator<nano::block_hash, nano::account>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}
};
}

View file

@ -1,65 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class online_weight_store_partial : public online_weight_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit online_weight_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<uint64_t, nano::amount> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<uint64_t, nano::amount> (transaction_a, tables::online_weight);
}
nano::store_iterator<uint64_t, nano::amount> rbegin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<uint64_t, nano::amount> (transaction_a, tables::online_weight, false);
}
nano::store_iterator<uint64_t, nano::amount> end () const override
{
return nano::store_iterator<uint64_t, nano::amount> (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);
}
};
}

View file

@ -1,70 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class peer_store_partial : public peer_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit peer_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<nano::endpoint_key, nano::no_value> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::endpoint_key, nano::no_value> (transaction_a, tables::peers);
}
nano::store_iterator<nano::endpoint_key, nano::no_value> end () const override
{
return nano::store_iterator<nano::endpoint_key, nano::no_value> (nullptr);
}
};
}

View file

@ -1,100 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class pending_store_partial : public pending_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit pending_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<Val> value;
nano::db_val<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<uint8_t const *> (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<nano::pending_key, nano::pending_info> begin (nano::transaction const & transaction_a, nano::pending_key const & key_a) const override
{
return store.template make_iterator<nano::pending_key, nano::pending_info> (transaction_a, tables::pending, nano::db_val<Val> (key_a));
}
nano::store_iterator<nano::pending_key, nano::pending_info> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::pending_key, nano::pending_info> (transaction_a, tables::pending);
}
nano::store_iterator<nano::pending_key, nano::pending_info> end () const override
{
return nano::store_iterator<nano::pending_key, nano::pending_info> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::pending_key, nano::pending_info>, nano::store_iterator<nano::pending_key, nano::pending_info>)> const & action_a) const override
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}
};
}

View file

@ -1,97 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class pruned_store_partial : public pruned_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
explicit pruned_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<nano::block_hash, nano::db_val<Val>> (transaction_a, tables::pruned, nano::db_val<Val> (random_hash));
auto end (nano::store_iterator<nano::block_hash, nano::db_val<Val>> (nullptr));
if (existing == end)
{
existing = store.template make_iterator<nano::block_hash, nano::db_val<Val>> (transaction_a, tables::pruned);
}
return existing != end ? existing->first : 0;
}
size_t count (nano::transaction const & transaction_a) const override
{
return 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<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const override
{
return store.template make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned, nano::db_val<Val> (hash_a));
}
nano::store_iterator<nano::block_hash, std::nullptr_t> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::block_hash, std::nullptr_t> (transaction_a, tables::pruned);
}
nano::store_iterator<nano::block_hash, std::nullptr_t> end () const override
{
return nano::store_iterator<nano::block_hash, std::nullptr_t> (nullptr);
}
void for_each_par (std::function<void (nano::read_transaction const &, nano::store_iterator<nano::block_hash, std::nullptr_t>, nano::store_iterator<nano::block_hash, std::nullptr_t>)> const & action_a) const override
{
parallel_traversal<nano::uint256_t> (
[&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) {
auto transaction (this->store.tx_begin_read ());
action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ());
});
}
};
}

View file

@ -1,90 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace
{
template <typename T>
void parallel_traversal (std::function<void (T const &, T const &, bool const)> const & action);
}
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class unchecked_store_partial : public unchecked_store
{
private:
nano::store_partial<Val, Derived_Store> & store;
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
public:
unchecked_store_partial (nano::store_partial<Val, Derived_Store> & 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<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<Val> value;
auto status (store.get (transaction_a, tables::unchecked, nano::db_val<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<nano::unchecked_key, nano::unchecked_info> end () const override
{
return nano::store_iterator<nano::unchecked_key, nano::unchecked_info> (nullptr);
}
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> begin (nano::transaction const & transaction_a) const override
{
return store.template make_iterator<nano::unchecked_key, nano::unchecked_info> (transaction_a, tables::unchecked);
}
nano::store_iterator<nano::unchecked_key, nano::unchecked_info> lower_bound (nano::transaction const & transaction_a, nano::unchecked_key const & key_a) const override
{
return store.template make_iterator<nano::unchecked_key, nano::unchecked_info> (transaction_a, tables::unchecked, nano::db_val<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<void (nano::read_transaction const &, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>, nano::store_iterator<nano::unchecked_key, nano::unchecked_info>)> const & action_a) const override
{
parallel_traversal<nano::uint512_t> (
[&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 ());
});
}
};
}

View file

@ -1,47 +0,0 @@
#pragma once
#include <nano/secure/store_partial.hpp>
namespace nano
{
template <typename Val, typename Derived_Store>
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const &, int const);
template <typename Val, typename Derived_Store>
class version_store_partial : public version_store
{
protected:
nano::store_partial<Val, Derived_Store> & store;
public:
explicit version_store_partial (nano::store_partial<Val, Derived_Store> & 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<Val> (version_key), nano::db_val<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<Val> data;
auto status = store.get (transaction_a, tables::meta, nano::db_val<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<int> ();
}
return result;
}
};
}

View file

@ -6,17 +6,6 @@
#include <nano/lib/timer.hpp>
#include <nano/secure/buffer.hpp>
#include <nano/secure/store.hpp>
#include <nano/secure/store/account_store_partial.hpp>
#include <nano/secure/store/block_store_partial.hpp>
#include <nano/secure/store/confirmation_height_store_partial.hpp>
#include <nano/secure/store/final_vote_store_partial.hpp>
#include <nano/secure/store/frontier_store_partial.hpp>
#include <nano/secure/store/online_weight_partial.hpp>
#include <nano/secure/store/peer_store_partial.hpp>
#include <nano/secure/store/pending_store_partial.hpp>
#include <nano/secure/store/pruned_store_partial.hpp>
#include <nano/secure/store/unchecked_store_partial.hpp>
#include <nano/secure/store/version_store_partial.hpp>
#include <crypto/cryptopp/words.h>
@ -32,71 +21,45 @@ void parallel_traversal (std::function<void (T const &, T const &, bool const)>
namespace nano
{
template <typename Val, typename Derived_Store>
class block_predecessor_set;
class store_partial;
template <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const & store, int const status)
{
if (!store.success (status))
{
release_assert (false, store.error_string (status));
}
}
template <typename Val, typename Derived_Store>
class account_store_partial;
template <typename Val, typename Derived_Store>
class unchecked_store_partial;
template <typename Val, typename Derived_Store>
class block_store_partial;
void release_assert_success (store_partial<Val, Derived_Store> 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 <typename Val, typename Derived_Store>
class store_partial : public store
{
friend void release_assert_success<Val, Derived_Store> (store_partial<Val, Derived_Store> const &, int const);
friend class nano::block_store_partial<Val, Derived_Store>;
friend class nano::frontier_store_partial<Val, Derived_Store>;
friend class nano::account_store_partial<Val, Derived_Store>;
friend class nano::pending_store_partial<Val, Derived_Store>;
friend class nano::unchecked_store_partial<Val, Derived_Store>;
friend class nano::online_weight_store_partial<Val, Derived_Store>;
friend class nano::pruned_store_partial<Val, Derived_Store>;
friend class nano::peer_store_partial<Val, Derived_Store>;
friend class nano::confirmation_height_store_partial<Val, Derived_Store>;
friend class nano::final_vote_store_partial<Val, Derived_Store>;
friend class nano::version_store_partial<Val, Derived_Store>;
public:
// clang-format off
store_partial (
nano::ledger_constants & constants,
nano::block_store_partial<Val, Derived_Store> & block_store_partial_a,
nano::frontier_store_partial<Val, Derived_Store> & frontier_store_partial_a,
nano::account_store_partial<Val, Derived_Store> & account_store_partial_a,
nano::pending_store_partial<Val, Derived_Store> & pending_store_partial_a,
nano::unchecked_store_partial<Val, Derived_Store> & unchecked_store_partial_a,
nano::online_weight_store_partial<Val, Derived_Store> & online_weight_store_partial_a,
nano::pruned_store_partial<Val, Derived_Store> & pruned_store_partial_a,
nano::peer_store_partial<Val, Derived_Store> & peer_store_partial_a,
nano::confirmation_height_store_partial<Val, Derived_Store> & confirmation_height_store_partial_a,
nano::final_vote_store_partial<Val, Derived_Store> & final_vote_store_partial_a,
nano::version_store_partial<Val, Derived_Store> & 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<const Derived_Store &> (*this).exists (transaction_a, table_a, key_a);
}
int const minimum_version{ 14 };
protected:
nano::ledger_constants & constants;
int const version_number{ 21 };
template <typename Key, typename Value>
nano::store_iterator<Key, Value> make_iterator (nano::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const
{
@ -149,6 +106,12 @@ protected:
return static_cast<Derived_Store const &> (*this).template make_iterator<Key, Value> (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<tables> 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 <typename Val, typename Derived_Store>
void release_assert_success (store_partial<Val, Derived_Store> const & store, int const status)
{
if (!store.success (status))
{
release_assert (false, store.error_string (status));
}
}
}
namespace