Rework request_aggregator::aggregate logic

This commit is contained in:
Piotr Wójcik 2024-11-03 19:45:50 +01:00
commit 4189bdfe2d
6 changed files with 52 additions and 47 deletions

View file

@ -12,6 +12,7 @@
#include <nano/node/wallet.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/ledger_set_any.hpp>
#include <nano/secure/ledger_set_confirmed.hpp>
#include <nano/store/component.hpp>
nano::request_aggregator::request_aggregator (request_aggregator_config const & config_a, nano::node & node_a, nano::stats & stats_a, nano::vote_generator & generator_a, nano::vote_generator & final_generator_a, nano::local_vote_history & history_a, nano::ledger & ledger_a, nano::wallets & wallets_a, nano::vote_router & vote_router_a) :
@ -208,68 +209,45 @@ void nano::request_aggregator::erase_duplicates (std::vector<std::pair<nano::blo
requests_a.end ());
}
// This filters candidates for vote generation, the final decision and necessary checks are also performed by the vote generator
auto nano::request_aggregator::aggregate (nano::secure::transaction const & transaction, request_type const & requests_a, std::shared_ptr<nano::transport::channel> const & channel_a) const -> aggregate_result
{
std::vector<std::shared_ptr<nano::block>> to_generate;
std::vector<std::shared_ptr<nano::block>> to_generate_final;
for (auto const & [hash, root] : requests_a)
{
bool generate_final_vote (false);
std::shared_ptr<nano::block> block;
// Ledger by hash
std::shared_ptr<nano::block> block = ledger.any.block_get (transaction, hash);
// 2. Final votes
auto final_vote_hashes (ledger.store.final_vote.get (transaction, root));
if (!final_vote_hashes.empty ())
{
generate_final_vote = true;
block = ledger.any.block_get (transaction, final_vote_hashes[0]);
// Allow same root vote
if (block != nullptr && final_vote_hashes.size () > 1)
{
// WTF? This shouldn't be done like this
to_generate_final.push_back (block);
block = ledger.any.block_get (transaction, final_vote_hashes[1]);
debug_assert (final_vote_hashes.size () == 2);
}
}
// 4. Ledger by hash
if (block == nullptr)
{
block = ledger.any.block_get (transaction, hash);
// Confirmation status. Generate final votes for confirmed
if (block != nullptr)
{
nano::confirmation_height_info confirmation_height_info;
ledger.store.confirmation_height.get (transaction, block->account (), confirmation_height_info);
generate_final_vote = (confirmation_height_info.height >= block->sideband ().height);
}
}
// 5. Ledger by root
if (block == nullptr && !root.is_zero ())
// Ledger by root
if (!block && !root.is_zero ())
{
// Search for block root
auto successor = ledger.any.block_successor (transaction, root.as_block_hash ());
if (successor)
if (auto successor = ledger.any.block_successor (transaction, root.as_block_hash ()))
{
auto successor_block = ledger.any.block_get (transaction, successor.value ());
release_assert (successor_block != nullptr);
block = std::move (successor_block);
block = ledger.any.block_get (transaction, successor.value ());
release_assert (block);
}
}
// Confirmation status. Generate final votes for confirmed successor
if (block != nullptr)
auto should_generate_final_vote = [&] (auto const & block) {
release_assert (block);
// Check if final vote is set for this block
if (auto final_hash = ledger.store.final_vote.get (transaction, block->qualified_root ()))
{
nano::confirmation_height_info confirmation_height_info;
ledger.store.confirmation_height.get (transaction, block->account (), confirmation_height_info);
generate_final_vote = (confirmation_height_info.height >= block->sideband ().height);
}
return final_hash == block->hash ();
}
// If the final vote is not set, generate vote if the block is confirmed
else
{
return ledger.confirmed.block_exists (transaction, block->hash ());
}
};
if (block)
{
if (generate_final_vote)
if (should_generate_final_vote (block))
{
to_generate_final.push_back (block);
stats.inc (nano::stat::type::requests, nano::stat::detail::requests_final);

View file

@ -23,6 +23,7 @@ public:
public:
virtual bool put (store::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) = 0;
virtual std::vector<nano::block_hash> get (store::transaction const & transaction_a, nano::root const & root_a) = 0;
virtual std::optional<nano::block_hash> get (store::transaction const & transaction_a, nano::qualified_root const & qualified_root_a) = 0;
virtual void del (store::write_transaction const & transaction_a, nano::root const & root_a) = 0;
virtual size_t count (store::transaction const & transaction_a) const = 0;
virtual void clear (store::write_transaction const &, nano::root const &) = 0;

View file

@ -34,6 +34,18 @@ std::vector<nano::block_hash> nano::store::lmdb::final_vote::get (store::transac
return result;
}
std::optional<nano::block_hash> nano::store::lmdb::final_vote::get (store::transaction const & transaction, nano::qualified_root const & qualified_root_a)
{
nano::store::lmdb::db_val result;
auto status = store.get (transaction, tables::final_votes, qualified_root_a, result);
std::optional<nano::block_hash> final_vote_hash;
if (store.success (status))
{
final_vote_hash = static_cast<nano::block_hash> (result);
}
return final_vote_hash;
}
void nano::store::lmdb::final_vote::del (store::write_transaction const & transaction, nano::root const & root)
{
std::vector<nano::qualified_root> final_vote_qualified_roots;

View file

@ -19,6 +19,7 @@ public:
explicit final_vote (nano::store::lmdb::component & store);
bool put (store::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) override;
std::vector<nano::block_hash> get (store::transaction const & transaction_a, nano::root const & root_a) override;
std::optional<nano::block_hash> get (store::transaction const & transaction_a, nano::qualified_root const & qualified_root_a) override;
void del (store::write_transaction const & transaction_a, nano::root const & root_a) override;
size_t count (store::transaction const & transaction_a) const override;
void clear (store::write_transaction const & transaction_a, nano::root const & root_a) override;

View file

@ -35,6 +35,18 @@ std::vector<nano::block_hash> nano::store::rocksdb::final_vote::get (store::tran
return result;
}
std::optional<nano::block_hash> nano::store::rocksdb::final_vote::get (store::transaction const & transaction, nano::qualified_root const & qualified_root_a)
{
nano::store::rocksdb::db_val result;
auto status = store.get (transaction, tables::final_votes, qualified_root_a, result);
std::optional<nano::block_hash> final_vote_hash;
if (store.success (status))
{
final_vote_hash = static_cast<nano::block_hash> (result);
}
return final_vote_hash;
}
void nano::store::rocksdb::final_vote::del (store::write_transaction const & transaction, nano::root const & root)
{
std::vector<nano::qualified_root> final_vote_qualified_roots;

View file

@ -17,6 +17,7 @@ public:
explicit final_vote (nano::store::rocksdb::component & store);
bool put (store::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) override;
std::vector<nano::block_hash> get (store::transaction const & transaction_a, nano::root const & root_a) override;
std::optional<nano::block_hash> get (store::transaction const & transaction_a, nano::qualified_root const & qualified_root_a) override;
void del (store::write_transaction const & transaction_a, nano::root const & root_a) override;
size_t count (store::transaction const & transaction_a) const override;
void clear (store::write_transaction const & transaction_a, nano::root const & root_a) override;