From 87fd0cdd39e542a344b3d855cc7926cd7d3676a4 Mon Sep 17 00:00:00 2001 From: cryptocode Date: Tue, 18 Dec 2018 21:17:47 +0100 Subject: [PATCH] Faster block existance check when the block type is known --- rai/node/lmdb.cpp | 74 +++++++++++++++++++++++++++------------ rai/node/lmdb.hpp | 1 + rai/node/node.cpp | 6 ++-- rai/secure/blockstore.hpp | 1 + rai/secure/ledger.cpp | 21 +++++++---- rai/secure/ledger.hpp | 1 + 6 files changed, 71 insertions(+), 33 deletions(-) diff --git a/rai/node/lmdb.cpp b/rai/node/lmdb.cpp index 4e1f576ebc..cc3eeba8d4 100644 --- a/rai/node/lmdb.cpp +++ b/rai/node/lmdb.cpp @@ -1360,46 +1360,74 @@ void rai::mdb_store::block_del (rai::transaction const & transaction_a, rai::blo } } -bool rai::mdb_store::block_exists (rai::transaction const & transaction_a, rai::block_hash const & hash_a) +bool rai::mdb_store::block_exists (rai::transaction const & transaction_a, rai::block_type type, rai::block_hash const & hash_a) { - auto exists (true); + auto exists (false); rai::mdb_val junk; - auto status (mdb_get (env.tx (transaction_a), send_blocks, rai::mdb_val (hash_a), junk)); - assert (status == 0 || status == MDB_NOTFOUND); - exists = status == 0; - if (!exists) + + switch (type) { - auto status (mdb_get (env.tx (transaction_a), receive_blocks, rai::mdb_val (hash_a), junk)); - release_assert (status == 0 || status == MDB_NOTFOUND); - exists = status == 0; - if (!exists) + case rai::block_type::send: + { + auto status (mdb_get (env.tx (transaction_a), send_blocks, rai::mdb_val (hash_a), junk)); + assert (status == 0 || status == MDB_NOTFOUND); + exists = status == 0; + break; + } + case rai::block_type::receive: + { + auto status (mdb_get (env.tx (transaction_a), receive_blocks, rai::mdb_val (hash_a), junk)); + release_assert (status == 0 || status == MDB_NOTFOUND); + exists = status == 0; + break; + } + case rai::block_type::open: { auto status (mdb_get (env.tx (transaction_a), open_blocks, rai::mdb_val (hash_a), junk)); release_assert (status == 0 || status == MDB_NOTFOUND); exists = status == 0; + break; + } + case rai::block_type::change: + { + auto status (mdb_get (env.tx (transaction_a), change_blocks, rai::mdb_val (hash_a), junk)); + release_assert (status == 0 || status == MDB_NOTFOUND); + exists = status == 0; + break; + } + case rai::block_type::state: + { + auto status (mdb_get (env.tx (transaction_a), state_blocks_v0, rai::mdb_val (hash_a), junk)); + release_assert (status == 0 || status == MDB_NOTFOUND); + exists = status == 0; if (!exists) { - auto status (mdb_get (env.tx (transaction_a), change_blocks, rai::mdb_val (hash_a), junk)); + auto status (mdb_get (env.tx (transaction_a), state_blocks_v1, rai::mdb_val (hash_a), junk)); release_assert (status == 0 || status == MDB_NOTFOUND); exists = status == 0; - if (!exists) - { - auto status (mdb_get (env.tx (transaction_a), state_blocks_v0, rai::mdb_val (hash_a), junk)); - release_assert (status == 0 || status == MDB_NOTFOUND); - exists = status == 0; - if (!exists) - { - auto status (mdb_get (env.tx (transaction_a), state_blocks_v1, rai::mdb_val (hash_a), junk)); - release_assert (status == 0 || status == MDB_NOTFOUND); - exists = status == 0; - } - } } + break; } + case rai::block_type::invalid: + case rai::block_type::not_a_block: + break; } + return exists; } +bool rai::mdb_store::block_exists (rai::transaction const & tx_a, rai::block_hash const & hash_a) +{ + // clang-format off + return + block_exists (tx_a, rai::block_type::send, hash_a) || + block_exists (tx_a, rai::block_type::receive, hash_a) || + block_exists (tx_a, rai::block_type::open, hash_a) || + block_exists (tx_a, rai::block_type::change, hash_a) || + block_exists (tx_a, rai::block_type::state, hash_a); + // clang-format on +} + rai::block_counts rai::mdb_store::block_count (rai::transaction const & transaction_a) { rai::block_counts result; diff --git a/rai/node/lmdb.hpp b/rai/node/lmdb.hpp index fe9ce36571..b6b471d855 100644 --- a/rai/node/lmdb.hpp +++ b/rai/node/lmdb.hpp @@ -159,6 +159,7 @@ class mdb_store : public block_store std::shared_ptr block_random (rai::transaction const &) override; void block_del (rai::transaction const &, rai::block_hash const &) override; bool block_exists (rai::transaction const &, rai::block_hash const &) override; + bool block_exists (rai::transaction const &, rai::block_type, rai::block_hash const &) override; rai::block_counts block_count (rai::transaction const &) override; bool root_exists (rai::transaction const &, rai::uint256_union const &) override; diff --git a/rai/node/node.cpp b/rai/node/node.cpp index 9ef40225ce..5a3d11ef4a 100644 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -1804,7 +1804,7 @@ void rai::node::send_keepalive (rai::endpoint const & endpoint_a) void rai::node::process_fork (rai::transaction const & transaction_a, std::shared_ptr block_a) { auto root (block_a->root ()); - if (!store.block_exists (transaction_a, block_a->hash ()) && store.root_exists (transaction_a, block_a->root ())) + if (!store.block_exists (transaction_a, block_a->type (), block_a->hash ()) && store.root_exists (transaction_a, block_a->root ())) { std::shared_ptr ledger_block (ledger.forked_block (transaction_a, *block_a)); if (ledger_block) @@ -2583,13 +2583,13 @@ class confirmed_visitor : public rai::block_visitor void rai::node::process_confirmed (std::shared_ptr block_a) { auto hash (block_a->hash ()); - bool exists (ledger.block_exists (hash)); + bool exists (ledger.block_exists (block_a->type (), hash)); // Attempt to process confirmed block if it's not in ledger yet if (!exists) { auto transaction (store.tx_begin_write ()); block_processor.process_receive_one (transaction, block_a); - exists = store.block_exists (transaction, hash); + exists = store.block_exists (transaction, block_a->type (), hash); } if (exists) { diff --git a/rai/secure/blockstore.hpp b/rai/secure/blockstore.hpp index 9fb8796655..90b612dc00 100644 --- a/rai/secure/blockstore.hpp +++ b/rai/secure/blockstore.hpp @@ -200,6 +200,7 @@ class block_store virtual std::shared_ptr block_random (rai::transaction const &) = 0; virtual void block_del (rai::transaction const &, rai::block_hash const &) = 0; virtual bool block_exists (rai::transaction const &, rai::block_hash const &) = 0; + virtual bool block_exists (rai::transaction const &, rai::block_type, rai::block_hash const &) = 0; virtual rai::block_counts block_count (rai::transaction const &) = 0; virtual bool root_exists (rai::transaction const &, rai::uint256_union const &) = 0; diff --git a/rai/secure/ledger.cpp b/rai/secure/ledger.cpp index 68e8ebd8cf..7dd6518d88 100644 --- a/rai/secure/ledger.cpp +++ b/rai/secure/ledger.cpp @@ -217,7 +217,7 @@ void ledger_processor::state_block (rai::state_block const & block_a) void ledger_processor::state_block_impl (rai::state_block const & block_a) { auto hash (block_a.hash ()); - auto existing (ledger.store.block_exists (transaction, hash)); + auto existing (ledger.store.block_exists (transaction, block_a.type (), hash)); result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block before? (Unambiguous) if (result.code == rai::process_result::progress) { @@ -328,7 +328,7 @@ void ledger_processor::state_block_impl (rai::state_block const & block_a) void ledger_processor::epoch_block_impl (rai::state_block const & block_a) { auto hash (block_a.hash ()); - auto existing (ledger.store.block_exists (transaction, hash)); + auto existing (ledger.store.block_exists (transaction, block_a.type (), hash)); result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block before? (Unambiguous) if (result.code == rai::process_result::progress) { @@ -391,7 +391,7 @@ void ledger_processor::epoch_block_impl (rai::state_block const & block_a) void ledger_processor::change_block (rai::change_block const & block_a) { auto hash (block_a.hash ()); - auto existing (ledger.store.block_exists (transaction, hash)); + auto existing (ledger.store.block_exists (transaction, block_a.type (), hash)); result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block before? (Harmless) if (result.code == rai::process_result::progress) { @@ -433,7 +433,7 @@ void ledger_processor::change_block (rai::change_block const & block_a) void ledger_processor::send_block (rai::send_block const & block_a) { auto hash (block_a.hash ()); - auto existing (ledger.store.block_exists (transaction, hash)); + auto existing (ledger.store.block_exists (transaction, block_a.type (), hash)); result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block before? (Harmless) if (result.code == rai::process_result::progress) { @@ -480,7 +480,7 @@ void ledger_processor::send_block (rai::send_block const & block_a) void ledger_processor::receive_block (rai::receive_block const & block_a) { auto hash (block_a.hash ()); - auto existing (ledger.store.block_exists (transaction, hash)); + auto existing (ledger.store.block_exists (transaction, block_a.type (), hash)); result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block already? (Harmless) if (result.code == rai::process_result::progress) { @@ -545,7 +545,7 @@ void ledger_processor::receive_block (rai::receive_block const & block_a) void ledger_processor::open_block (rai::open_block const & block_a) { auto hash (block_a.hash ()); - auto existing (ledger.store.block_exists (transaction, hash)); + auto existing (ledger.store.block_exists (transaction, block_a.type (), hash)); result.code = existing ? rai::process_result::old : rai::process_result::progress; // Have we seen this block already? (Harmless) if (result.code == rai::process_result::progress) { @@ -685,6 +685,13 @@ bool rai::ledger::block_exists (rai::block_hash const & hash_a) return result; } +bool rai::ledger::block_exists (rai::block_type type, rai::block_hash const & hash_a) +{ + auto transaction (store.tx_begin_read ()); + auto result (store.block_exists (transaction, type, hash_a)); + return result; +} + std::string rai::ledger::block_text (char const * hash_a) { return block_text (rai::block_hash (hash_a)); @@ -1005,7 +1012,7 @@ std::shared_ptr rai::ledger::successor (rai::transaction const & tra std::shared_ptr rai::ledger::forked_block (rai::transaction const & transaction_a, rai::block const & block_a) { - assert (!store.block_exists (transaction_a, block_a.hash ())); + assert (!store.block_exists (transaction_a, block_a.type (), block_a.hash ())); auto root (block_a.root ()); assert (store.block_exists (transaction_a, root) || store.account_exists (transaction_a, root)); auto result (store.block_get (transaction_a, store.block_successor (transaction_a, root))); diff --git a/rai/secure/ledger.hpp b/rai/secure/ledger.hpp index 6ae3b4e798..a22dce435d 100644 --- a/rai/secure/ledger.hpp +++ b/rai/secure/ledger.hpp @@ -31,6 +31,7 @@ class ledger rai::block_hash representative (rai::transaction const &, rai::block_hash const &); rai::block_hash representative_calculated (rai::transaction const &, rai::block_hash const &); bool block_exists (rai::block_hash const &); + bool block_exists (rai::block_type, rai::block_hash const &); std::string block_text (char const *); std::string block_text (rai::block_hash const &); bool is_send (rai::transaction const &, rai::state_block const &);