diff --git a/nano/node/request_aggregator.cpp b/nano/node/request_aggregator.cpp index 75faab069..3311978d2 100644 --- a/nano/node/request_aggregator.cpp +++ b/nano/node/request_aggregator.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include 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 const & channel_a) const -> aggregate_result { std::vector> to_generate; std::vector> to_generate_final; for (auto const & [hash, root] : requests_a) { - bool generate_final_vote (false); - std::shared_ptr block; + // Ledger by hash + std::shared_ptr 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); - - // Confirmation status. Generate final votes for confirmed successor - 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); - } + block = ledger.any.block_get (transaction, successor.value ()); + release_assert (block); } } + 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 ())) + { + 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); diff --git a/nano/store/final_vote.hpp b/nano/store/final_vote.hpp index f6f96f979..12d7d2f3e 100644 --- a/nano/store/final_vote.hpp +++ b/nano/store/final_vote.hpp @@ -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 get (store::transaction const & transaction_a, nano::root const & root_a) = 0; + virtual std::optional 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; diff --git a/nano/store/lmdb/final_vote.cpp b/nano/store/lmdb/final_vote.cpp index c7fdf7aca..677bdb5cb 100644 --- a/nano/store/lmdb/final_vote.cpp +++ b/nano/store/lmdb/final_vote.cpp @@ -34,6 +34,18 @@ std::vector nano::store::lmdb::final_vote::get (store::transac return result; } +std::optional 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 final_vote_hash; + if (store.success (status)) + { + final_vote_hash = static_cast (result); + } + return final_vote_hash; +} + void nano::store::lmdb::final_vote::del (store::write_transaction const & transaction, nano::root const & root) { std::vector final_vote_qualified_roots; diff --git a/nano/store/lmdb/final_vote.hpp b/nano/store/lmdb/final_vote.hpp index c905edc9d..d59cd562e 100644 --- a/nano/store/lmdb/final_vote.hpp +++ b/nano/store/lmdb/final_vote.hpp @@ -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 get (store::transaction const & transaction_a, nano::root const & root_a) override; + std::optional 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; diff --git a/nano/store/rocksdb/final_vote.cpp b/nano/store/rocksdb/final_vote.cpp index 52afdfe34..dad6a4a2e 100644 --- a/nano/store/rocksdb/final_vote.cpp +++ b/nano/store/rocksdb/final_vote.cpp @@ -35,6 +35,18 @@ std::vector nano::store::rocksdb::final_vote::get (store::tran return result; } +std::optional 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 final_vote_hash; + if (store.success (status)) + { + final_vote_hash = static_cast (result); + } + return final_vote_hash; +} + void nano::store::rocksdb::final_vote::del (store::write_transaction const & transaction, nano::root const & root) { std::vector final_vote_qualified_roots; diff --git a/nano/store/rocksdb/final_vote.hpp b/nano/store/rocksdb/final_vote.hpp index 67a1e0d52..9c0484713 100644 --- a/nano/store/rocksdb/final_vote.hpp +++ b/nano/store/rocksdb/final_vote.hpp @@ -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 get (store::transaction const & transaction_a, nano::root const & root_a) override; + std::optional 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;