Faster block existence check when the block type is known (#1484)
This commit is contained in:
parent
3749ac2d99
commit
dc11556491
6 changed files with 71 additions and 33 deletions
|
|
@ -1369,46 +1369,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;
|
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);
|
switch (type)
|
||||||
exists = status == 0;
|
|
||||||
if (!exists)
|
|
||||||
{
|
{
|
||||||
auto status (mdb_get (env.tx (transaction_a), receive_blocks, rai::mdb_val (hash_a), junk));
|
case rai::block_type::send:
|
||||||
release_assert (status == 0 || status == MDB_NOTFOUND);
|
{
|
||||||
exists = status == 0;
|
auto status (mdb_get (env.tx (transaction_a), send_blocks, rai::mdb_val (hash_a), junk));
|
||||||
if (!exists)
|
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));
|
auto status (mdb_get (env.tx (transaction_a), open_blocks, rai::mdb_val (hash_a), junk));
|
||||||
release_assert (status == 0 || status == MDB_NOTFOUND);
|
release_assert (status == 0 || status == MDB_NOTFOUND);
|
||||||
exists = status == 0;
|
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)
|
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);
|
release_assert (status == 0 || status == MDB_NOTFOUND);
|
||||||
exists = status == 0;
|
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;
|
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 rai::mdb_store::block_count (rai::transaction const & transaction_a)
|
||||||
{
|
{
|
||||||
rai::block_counts result;
|
rai::block_counts result;
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ public:
|
||||||
std::shared_ptr<rai::block> block_random (rai::transaction const &) override;
|
std::shared_ptr<rai::block> block_random (rai::transaction const &) override;
|
||||||
void block_del (rai::transaction const &, rai::block_hash 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_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;
|
rai::block_counts block_count (rai::transaction const &) override;
|
||||||
bool root_exists (rai::transaction const &, rai::uint256_union const &) override;
|
bool root_exists (rai::transaction const &, rai::uint256_union const &) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1866,7 +1866,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)
|
void rai::node::process_fork (rai::transaction const & transaction_a, std::shared_ptr<rai::block> block_a)
|
||||||
{
|
{
|
||||||
auto root (block_a->root ());
|
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));
|
std::shared_ptr<rai::block> ledger_block (ledger.forked_block (transaction_a, *block_a));
|
||||||
if (ledger_block)
|
if (ledger_block)
|
||||||
|
|
@ -2645,13 +2645,13 @@ public:
|
||||||
void rai::node::process_confirmed (std::shared_ptr<rai::block> block_a)
|
void rai::node::process_confirmed (std::shared_ptr<rai::block> block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a->hash ());
|
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
|
// Attempt to process confirmed block if it's not in ledger yet
|
||||||
if (!exists)
|
if (!exists)
|
||||||
{
|
{
|
||||||
auto transaction (store.tx_begin_write ());
|
auto transaction (store.tx_begin_write ());
|
||||||
block_processor.process_receive_one (transaction, block_a);
|
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)
|
if (exists)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,7 @@ public:
|
||||||
virtual std::shared_ptr<rai::block> block_random (rai::transaction const &) = 0;
|
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 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_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 rai::block_counts block_count (rai::transaction const &) = 0;
|
||||||
virtual bool root_exists (rai::transaction const &, rai::uint256_union const &) = 0;
|
virtual bool root_exists (rai::transaction const &, rai::uint256_union const &) = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
void ledger_processor::state_block_impl (rai::state_block const & block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a.hash ());
|
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)
|
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)
|
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)
|
void ledger_processor::epoch_block_impl (rai::state_block const & block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a.hash ());
|
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)
|
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)
|
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)
|
void ledger_processor::change_block (rai::change_block const & block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a.hash ());
|
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)
|
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)
|
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)
|
void ledger_processor::send_block (rai::send_block const & block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a.hash ());
|
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)
|
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)
|
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)
|
void ledger_processor::receive_block (rai::receive_block const & block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a.hash ());
|
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)
|
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)
|
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)
|
void ledger_processor::open_block (rai::open_block const & block_a)
|
||||||
{
|
{
|
||||||
auto hash (block_a.hash ());
|
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)
|
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)
|
if (result.code == rai::process_result::progress)
|
||||||
{
|
{
|
||||||
|
|
@ -685,6 +685,13 @@ bool rai::ledger::block_exists (rai::block_hash const & hash_a)
|
||||||
return result;
|
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)
|
std::string rai::ledger::block_text (char const * hash_a)
|
||||||
{
|
{
|
||||||
return block_text (rai::block_hash (hash_a));
|
return block_text (rai::block_hash (hash_a));
|
||||||
|
|
@ -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)
|
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 ());
|
auto root (block_a.root ());
|
||||||
assert (store.block_exists (transaction_a, root) || store.account_exists (transaction_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)));
|
auto result (store.block_get (transaction_a, store.block_successor (transaction_a, root)));
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ public:
|
||||||
rai::block_hash representative (rai::transaction const &, rai::block_hash const &);
|
rai::block_hash representative (rai::transaction const &, rai::block_hash const &);
|
||||||
rai::block_hash representative_calculated (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_hash const &);
|
||||||
|
bool block_exists (rai::block_type, rai::block_hash const &);
|
||||||
std::string block_text (char const *);
|
std::string block_text (char const *);
|
||||||
std::string block_text (rai::block_hash const &);
|
std::string block_text (rai::block_hash const &);
|
||||||
bool is_send (rai::transaction const &, rai::state_block const &);
|
bool is_send (rai::transaction const &, rai::state_block const &);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue