Tally votes on conflicting block with no inactive votes (#2744)
Mostly applicable to tests, but consider this sequence of events: - An election gets created for a processed block - A vote arrives for a conflicting block; gets added to election, not inactive - The conflicting block gets processed Currently, `election::publish` calls `insert_inactive_votes_cache` but votes are not tallied since there was no inactive vote. This fixes the above situation by calling `confirm_if_quorum` if no votes were cached when a new conflicting block is inserted.
This commit is contained in:
parent
7966efd652
commit
e31cdebc87
3 changed files with 38 additions and 5 deletions
|
|
@ -1088,4 +1088,32 @@ TEST (active_transactions, restart_dropped)
|
|||
ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::election_restart));
|
||||
// Wait for the election to complete
|
||||
ASSERT_TIMELY (5s, node.ledger.cache.cemented_count == 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures votes are tallied on election::publish even if no vote is inserted through inactive_votes_cache
|
||||
TEST (active_transactions, conflicting_block_vote_existing_election)
|
||||
{
|
||||
nano::system system;
|
||||
nano::node_flags node_flags;
|
||||
node_flags.disable_request_loop = true;
|
||||
auto & node = *system.add_node (node_flags);
|
||||
nano::genesis genesis;
|
||||
nano::keypair key;
|
||||
auto send (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - 100, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
auto fork (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - 200, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
|
||||
auto vote_fork (std::make_shared<nano::vote> (nano::test_genesis_key.pub, nano::test_genesis_key.prv, 0, fork));
|
||||
|
||||
ASSERT_EQ (nano::process_result::progress, node.process_local (send).code);
|
||||
ASSERT_EQ (1, node.active.size ());
|
||||
|
||||
// Vote for conflicting block, but the block does not yet exist in the ledger
|
||||
node.active.vote (vote_fork);
|
||||
|
||||
// Block now gets processed
|
||||
ASSERT_EQ (nano::process_result::fork, node.process_local (fork).code);
|
||||
|
||||
// Election must be confirmed
|
||||
auto election (node.active.election (fork->qualified_root ()));
|
||||
ASSERT_NE (nullptr, election);
|
||||
ASSERT_TRUE (election->confirmed ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,7 +481,11 @@ bool nano::election::publish (std::shared_ptr<nano::block> block_a)
|
|||
if (existing == blocks.end ())
|
||||
{
|
||||
blocks.emplace (std::make_pair (block_a->hash (), block_a));
|
||||
insert_inactive_votes_cache (block_a->hash ());
|
||||
if (!insert_inactive_votes_cache (block_a->hash ()))
|
||||
{
|
||||
// Even if no votes were in cache, they could be in the election
|
||||
confirm_if_quorum ();
|
||||
}
|
||||
node.network.flood_block (block_a, nano::buffer_drop_policy::no_limiter_drop);
|
||||
}
|
||||
else
|
||||
|
|
@ -576,10 +580,10 @@ void nano::election::cleanup ()
|
|||
}
|
||||
}
|
||||
|
||||
void nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_a)
|
||||
size_t nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_a)
|
||||
{
|
||||
auto cache (node.active.find_inactive_votes_cache (hash_a));
|
||||
for (auto & rep : cache.voters)
|
||||
for (auto const & rep : cache.voters)
|
||||
{
|
||||
auto inserted (last_votes.emplace (rep, nano::vote_info{ std::chrono::steady_clock::time_point::min (), 0, hash_a }));
|
||||
if (inserted.second)
|
||||
|
|
@ -597,6 +601,7 @@ void nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_
|
|||
}
|
||||
confirm_if_quorum ();
|
||||
}
|
||||
return cache.voters.size ();
|
||||
}
|
||||
|
||||
bool nano::election::prioritized () const
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public:
|
|||
size_t last_votes_size ();
|
||||
void update_dependent ();
|
||||
void adjust_dependent_difficulty ();
|
||||
void insert_inactive_votes_cache (nano::block_hash const &);
|
||||
size_t insert_inactive_votes_cache (nano::block_hash const &);
|
||||
bool prioritized () const;
|
||||
void prioritize_election (nano::vote_generator_session &);
|
||||
// Erase all blocks from active and, if not confirmed, clear digests from network filters
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue