Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Watch blocks separately in work watcher #2228

Merged
107 changes: 92 additions & 15 deletions nano/core_test/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,38 +1108,115 @@ TEST (wallet, deterministic_restore)
ASSERT_TRUE (wallet->exists (pub));
}

TEST (wallet, update_work_action)
TEST (wallet, work_watcher_update)
{
nano::system system;
nano::node_config node_config (24000, system.logging);
node_config.enable_voting = false;
node_config.work_watcher_period = 1s;
auto & node = *system.add_node (node_config);
auto & wallet (*system.wallet (0));
wallet.insert_adhoc (nano::test_genesis_key.prv);
nano::keypair key;
auto const block (wallet.send_action (nano::test_genesis_key.pub, key.pub, nano::genesis_amount));
auto const block1 (wallet.send_action (nano::test_genesis_key.pub, key.pub, 100));
uint64_t difficulty1 (0);
nano::work_validate (*block, &difficulty1);
auto multiplier1 = nano::difficulty::to_multiplier (difficulty1, node.network_params.network.publish_threshold);
nano::work_validate (*block1, &difficulty1);
auto const block2 (wallet.send_action (nano::test_genesis_key.pub, key.pub, 200));
uint64_t difficulty2 (0);
nano::work_validate (*block2, &difficulty2);
auto multiplier = nano::difficulty::to_multiplier (std::max (difficulty1, difficulty2), node.network_params.network.publish_threshold);
uint64_t updated_difficulty1{ difficulty1 }, updated_difficulty2{ difficulty2 };
{
std::unique_lock<std::mutex> lock (node.active.mutex);
//fill multipliers_cb and update active difficulty;
for (auto i (0); i < node.active.multipliers_cb.size (); i++)
{
node.active.multipliers_cb.push_back (multiplier * (1 + i / 100.));
}
node.active.update_active_difficulty (lock);
}
system.deadline_set (10s);
auto updated (false);
uint64_t updated_difficulty;
while (!updated)
while (updated_difficulty1 == difficulty1 || updated_difficulty2 == difficulty2)
{
{
auto const existing (node.active.roots.find (block1->qualified_root ()));
//if existing is junk the block has been confirmed already
ASSERT_NE (existing, node.active.roots.end ());
updated_difficulty1 = existing->difficulty;
}
{
auto const existing (node.active.roots.find (block2->qualified_root ()));
//if existing is junk the block has been confirmed already
ASSERT_NE (existing, node.active.roots.end ());
updated_difficulty2 = existing->difficulty;
}
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_GT (updated_difficulty1, difficulty1);
ASSERT_GT (updated_difficulty2, difficulty2);
}

TEST (wallet, work_watcher_removed)
{
nano::system system;
nano::node_config node_config (24000, system.logging);
node_config.work_watcher_period = 1s;
auto & node = *system.add_node (node_config);
auto & wallet (*system.wallet (0));
wallet.insert_adhoc (nano::test_genesis_key.prv);
nano::keypair key;
ASSERT_EQ (0, wallet.wallets.watcher->watched.size ());
auto const block (wallet.send_action (nano::test_genesis_key.pub, key.pub, 100));
ASSERT_EQ (1, wallet.wallets.watcher->watched.size ());
auto transaction (wallet.wallets.tx_begin_write ());
system.deadline_set (3s);
while (!wallet.wallets.watcher->watched.empty ())
{
ASSERT_NO_ERROR (system.poll ());
}
}

TEST (wallet, work_watcher_cancel)
{
nano::system system;
nano::node_config node_config (24000, system.logging);
node_config.work_watcher_period = 1s;
node_config.max_work_generate_multiplier = 1e6;
auto & node = *system.add_node (node_config);
auto & wallet (*system.wallet (0));
wallet.insert_adhoc (nano::test_genesis_key.prv);
nano::keypair key;
auto const block1 (wallet.send_action (nano::test_genesis_key.pub, key.pub, 100));
uint64_t difficulty1 (0);
nano::work_validate (*block1, &difficulty1);
{
std::unique_lock<std::mutex> lock (node.active.mutex);
//fill multipliers_cb and update active difficulty;
for (auto i (0); i < node.active.multipliers_cb.size (); i++)
{
node.active.multipliers_cb.push_back (multiplier1 * (1 + i / 100.));
node.active.multipliers_cb.push_back (node_config.max_work_generate_multiplier);
}
node.active.update_active_difficulty (lock);
auto const existing (node.active.roots.find (block->qualified_root ()));
//if existing is junk the block has been confirmed already
ASSERT_NE (existing, node.active.roots.end ());
updated = existing->difficulty != difficulty1;
updated_difficulty = existing->difficulty;
lock.unlock ();
}
// Wait for work generation to start
system.deadline_set (3s);
while (node.work.pending.empty ())
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_GT (updated_difficulty, difficulty1);
// Cancel the ongoing work
node.work.cancel (block1->root ());
{
std::unique_lock<std::mutex> lock (wallet.wallets.watcher->mutex);
auto existing (wallet.wallets.watcher->watched.find (block1->qualified_root ()));
ASSERT_NE (wallet.wallets.watcher->watched.end (), existing);
auto block2 (existing->second);
// Block must be the same
ASSERT_NE (nullptr, block1);
ASSERT_NE (nullptr, block2);
ASSERT_EQ (*block1, *block2);
// but should still be under watch
lock.unlock ();
ASSERT_TRUE (wallet.wallets.watcher->is_watched (block1->qualified_root ()));
}
}
2 changes: 1 addition & 1 deletion nano/node/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ void nano::active_transactions::flush_lowest ()
if (count != 2)
{
auto election = it->election;
if (election->confirmation_request_count > high_confirmation_request_count && !election->confirmed && !election->stopped && !node.wallets.watcher.is_watched (it->root))
if (election->confirmation_request_count > high_confirmation_request_count && !election->confirmed && !election->stopped && !node.wallets.watcher->is_watched (it->root))
{
it = decltype (it){ sorted_roots.erase (std::next (it).base ()) };
election->stop ();
Expand Down
4 changes: 2 additions & 2 deletions nano/node/blockprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ void nano::block_processor::process_batch (std::unique_lock<std::mutex> & lock_a
for (auto & i : rollback_list)
{
node.votes_cache.remove (i->hash ());
node.wallets.watcher.remove (i);
node.wallets.watcher->remove (i);
node.active.erase (*i);
}
}
Expand Down Expand Up @@ -374,7 +374,7 @@ void nano::block_processor::process_live (nano::block_hash const & hash_a, std::
//add block to watcher if desired after block has been added to active
if (watch_work_a)
{
node.wallets.watcher.add (block_a);
node.wallets.watcher->add (block_a);
}
// Announce block contents to the network
node.network.flood_block (block_a, false);
Expand Down
2 changes: 1 addition & 1 deletion nano/node/testing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void nano::system::generate_rollback (nano::node & node_a, std::vector<nano::acc
assert (!error);
for (auto & i : rollback_list)
{
node_a.wallets.watcher.remove (i);
node_a.wallets.watcher->remove (i);
node_a.active.erase (*i);
}
}
Expand Down
Loading