Include block to fork confirm_req response (#2994)

* Include block to fork confirm_req response
* Formatting
This commit is contained in:
Sergey Kroshnin 2020-11-02 18:57:33 +03:00 committed by GitHub
commit 882a28761c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 14 deletions

View file

@ -2747,6 +2747,55 @@ TEST (node, local_votes_cache_generate_new_vote)
ASSERT_TIMELY (3s, 3 == node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out));
}
TEST (node, local_votes_cache_fork)
{
nano::system system;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_bootstrap_bulk_pull_server = true;
node_flags.disable_bootstrap_listener = true;
node_flags.disable_lazy_bootstrap = true;
node_flags.disable_legacy_bootstrap = true;
node_flags.disable_wallet_bootstrap = true;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 (*system.add_node (node_config, node_flags));
nano::genesis genesis;
system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv);
auto send1 = nano::state_block_builder ()
.account (nano::dev_genesis_key.pub)
.previous (genesis.hash ())
.representative (nano::dev_genesis_key.pub)
.balance (nano::genesis_amount - nano::Gxrb_ratio)
.link (nano::dev_genesis_key.pub)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*node1.work_generate_blocking (genesis.hash ()))
.build_shared ();
auto send1_fork = nano::state_block_builder ()
.account (nano::dev_genesis_key.pub)
.previous (genesis.hash ())
.representative (nano::dev_genesis_key.pub)
.balance (nano::genesis_amount - 2 * nano::Gxrb_ratio)
.link (nano::dev_genesis_key.pub)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*node1.work_generate_blocking (genesis.hash ()))
.build_shared ();
ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code);
// Cache vote
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, std::vector<nano::block_hash> (1, send1->hash ())));
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
node1.history.add (send1->root (), send1->hash (), vote);
auto votes2 (node1.history.votes (send1->root (), send1->hash ()));
ASSERT_EQ (1, votes2.size ());
ASSERT_EQ (1, votes2[0]->blocks.size ());
// Start election for forked block
node_config.peering_port = nano::get_available_port ();
auto & node2 (*system.add_node (node_config, node_flags));
node2.process_active (send1_fork);
node2.block_processor.flush ();
ASSERT_TIMELY (5s, node2.ledger.block_exists (send1->hash ()));
}
TEST (node, vote_republish)
{
nano::system system (2);

View file

@ -162,10 +162,10 @@ std::vector<std::shared_ptr<nano::block>> nano::request_aggregator::aggregate (s
size_t cached_hashes = 0;
std::vector<std::shared_ptr<nano::block>> to_generate;
std::vector<std::shared_ptr<nano::vote>> cached_votes;
for (auto const & hash_root : requests_a)
for (auto const & [hash, root] : requests_a)
{
// 1. Votes in cache
auto find_votes (local_votes.votes (hash_root.second, hash_root.first));
auto find_votes (local_votes.votes (root, hash));
if (!find_votes.empty ())
{
++cached_hashes;
@ -173,26 +173,27 @@ std::vector<std::shared_ptr<nano::block>> nano::request_aggregator::aggregate (s
}
else
{
bool generate_vote (true);
// 2. Election winner by hash
auto block = active.winner (hash_root.first);
auto block = active.winner (hash);
// 3. Ledger by hash
if (block == nullptr)
{
block = ledger.store.block_get (transaction, hash_root.first);
block = ledger.store.block_get (transaction, hash);
}
// 4. Ledger by root
if (block == nullptr && !hash_root.second.is_zero ())
if (block == nullptr && !root.is_zero ())
{
// Search for block root
auto successor (ledger.store.block_successor (transaction, hash_root.second.as_block_hash ()));
auto successor (ledger.store.block_successor (transaction, root.as_block_hash ()));
// Search for account root
if (successor.is_zero ())
{
nano::account_info info;
auto error (ledger.store.account_get (transaction, hash_root.second.as_account (), info));
auto error (ledger.store.account_get (transaction, root.as_account (), info));
if (!error)
{
successor = info.open_block;
@ -202,25 +203,27 @@ std::vector<std::shared_ptr<nano::block>> nano::request_aggregator::aggregate (s
{
auto successor_block = ledger.store.block_get (transaction, successor);
debug_assert (successor_block != nullptr);
block = std::move (successor_block);
// 5. Votes in cache for successor
auto find_successor_votes (local_votes.votes (hash_root.second, successor));
auto find_successor_votes (local_votes.votes (root, successor));
if (!find_successor_votes.empty ())
{
cached_votes.insert (cached_votes.end (), find_successor_votes.begin (), find_successor_votes.end ());
}
else
{
block = std::move (successor_block);
generate_vote = false;
}
}
}
if (block)
{
to_generate.push_back (block);
// Generate new vote
if (generate_vote)
{
to_generate.push_back (block);
}
// Let the node know about the alternative block
if (block->hash () != hash_root.first)
if (block->hash () != hash)
{
nano::publish publish (block);
channel_a->send (publish);