Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faster block existence check when the block type is known #1484

Merged
merged 1 commit into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 51 additions & 23 deletions rai/node/lmdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions rai/node/lmdb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class mdb_store : public block_store
std::shared_ptr<rai::block> 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;

Expand Down
6 changes: 3 additions & 3 deletions rai/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<rai::block> 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<rai::block> ledger_block (ledger.forked_block (transaction_a, *block_a));
if (ledger_block)
Expand Down Expand Up @@ -2583,13 +2583,13 @@ class confirmed_visitor : public rai::block_visitor
void rai::node::process_confirmed (std::shared_ptr<rai::block> 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)
{
Expand Down
1 change: 1 addition & 0 deletions rai/secure/blockstore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class block_store
virtual std::shared_ptr<rai::block> 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;

Expand Down
21 changes: 14 additions & 7 deletions rai/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if we can directly put types here & for other similar ledger_processor items like rai::block_type::state

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I couldn't decide on that :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'll be okay -- we can always change it if it shows up in profiling

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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -1005,7 +1012,7 @@ std::shared_ptr<rai::block> rai::ledger::successor (rai::transaction const & tra

std::shared_ptr<rai::block> 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)));
Expand Down
1 change: 1 addition & 0 deletions rai/secure/ledger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &);
Expand Down