Tests
This commit is contained in:
parent
8bec4ee12a
commit
ed4c175f94
3 changed files with 303 additions and 0 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include <nano/node/make_store.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
#include <nano/secure/ledger_set_any.hpp>
|
||||
#include <nano/test_common/chains.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/testutil.hpp>
|
||||
|
||||
|
|
@ -266,3 +267,291 @@ TEST (bootstrap_ascending, trace_base)
|
|||
// std::cerr << "node1: " << node1.network.endpoint () << std::endl;
|
||||
ASSERT_TIMELY (10s, node1.block (receive1->hash ()) != nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests that bootstrap will prioritize existing accounts with outdated frontiers
|
||||
*/
|
||||
TEST (bootstrap_ascending, frontier_scan)
|
||||
{
|
||||
nano::test::system system;
|
||||
|
||||
nano::node_flags flags;
|
||||
flags.disable_legacy_bootstrap = true;
|
||||
nano::node_config config;
|
||||
// Disable other bootstrap strategies
|
||||
config.bootstrap_ascending.enable_scan = false;
|
||||
config.bootstrap_ascending.enable_dependency_walker = false;
|
||||
// Disable election activation
|
||||
config.backlog_population.enable = false;
|
||||
config.priority_scheduler.enable = false;
|
||||
config.optimistic_scheduler.enable = false;
|
||||
config.hinted_scheduler.enable = false;
|
||||
|
||||
// Prepare blocks for frontier scan (genesis 10 sends -> 10 opens -> 10 updates)
|
||||
std::vector<std::shared_ptr<nano::block>> sends;
|
||||
std::vector<std::shared_ptr<nano::block>> opens;
|
||||
std::vector<std::shared_ptr<nano::block>> updates;
|
||||
{
|
||||
auto source = nano::dev::genesis_key;
|
||||
auto latest = nano::dev::genesis->hash ();
|
||||
auto balance = nano::dev::genesis->balance ().number ();
|
||||
|
||||
size_t const count = 10;
|
||||
|
||||
for (int n = 0; n < count; ++n)
|
||||
{
|
||||
nano::keypair key;
|
||||
nano::block_builder builder;
|
||||
|
||||
balance -= 1;
|
||||
auto send = builder
|
||||
.state ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.balance (balance)
|
||||
.link (key.pub)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*system.work.generate (latest))
|
||||
.build ();
|
||||
|
||||
latest = send->hash ();
|
||||
|
||||
auto open = builder
|
||||
.state ()
|
||||
.account (key.pub)
|
||||
.previous (0)
|
||||
.representative (key.pub)
|
||||
.balance (1)
|
||||
.link (send->hash ())
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*system.work.generate (key.pub))
|
||||
.build ();
|
||||
|
||||
auto update = builder
|
||||
.state ()
|
||||
.account (key.pub)
|
||||
.previous (open->hash ())
|
||||
.representative (0)
|
||||
.balance (1)
|
||||
.link (0)
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*system.work.generate (open->hash ()))
|
||||
.build ();
|
||||
|
||||
sends.push_back (send);
|
||||
opens.push_back (open);
|
||||
updates.push_back (update);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize nodes with blocks without the `updates` frontiers
|
||||
std::vector<std::shared_ptr<nano::block>> blocks;
|
||||
blocks.insert (blocks.end (), sends.begin (), sends.end ());
|
||||
blocks.insert (blocks.end (), opens.begin (), opens.end ());
|
||||
system.set_initialization_blocks ({ blocks.begin (), blocks.end () });
|
||||
|
||||
auto & node0 = *system.add_node (config, flags);
|
||||
ASSERT_TRUE (nano::test::process (node0, updates));
|
||||
|
||||
// No blocks should be broadcast to the other node
|
||||
auto & node1 = *system.add_node (config, flags);
|
||||
ASSERT_ALWAYS_EQ (100ms, node1.ledger.block_count (), blocks.size () + 1);
|
||||
|
||||
// Frontier scan should detect all the accounts with missing blocks
|
||||
ASSERT_TIMELY (10s, std::all_of (updates.begin (), updates.end (), [&node1] (auto const & block) {
|
||||
return node1.ascendboot.prioritized (block->account ());
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests that bootstrap will prioritize not yet existing accounts with pending blocks
|
||||
*/
|
||||
TEST (bootstrap_ascending, frontier_scan_pending)
|
||||
{
|
||||
nano::test::system system;
|
||||
|
||||
nano::node_flags flags;
|
||||
flags.disable_legacy_bootstrap = true;
|
||||
nano::node_config config;
|
||||
// Disable other bootstrap strategies
|
||||
config.bootstrap_ascending.enable_scan = false;
|
||||
config.bootstrap_ascending.enable_dependency_walker = false;
|
||||
// Disable election activation
|
||||
config.backlog_population.enable = false;
|
||||
config.priority_scheduler.enable = false;
|
||||
config.optimistic_scheduler.enable = false;
|
||||
config.hinted_scheduler.enable = false;
|
||||
|
||||
// Prepare blocks for frontier scan (genesis 10 sends -> 10 opens)
|
||||
std::vector<std::shared_ptr<nano::block>> sends;
|
||||
std::vector<std::shared_ptr<nano::block>> opens;
|
||||
{
|
||||
auto source = nano::dev::genesis_key;
|
||||
auto latest = nano::dev::genesis->hash ();
|
||||
auto balance = nano::dev::genesis->balance ().number ();
|
||||
|
||||
size_t const count = 10;
|
||||
|
||||
for (int n = 0; n < count; ++n)
|
||||
{
|
||||
nano::keypair key;
|
||||
nano::block_builder builder;
|
||||
|
||||
balance -= 1;
|
||||
auto send = builder
|
||||
.state ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.balance (balance)
|
||||
.link (key.pub)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*system.work.generate (latest))
|
||||
.build ();
|
||||
|
||||
latest = send->hash ();
|
||||
|
||||
auto open = builder
|
||||
.state ()
|
||||
.account (key.pub)
|
||||
.previous (0)
|
||||
.representative (key.pub)
|
||||
.balance (1)
|
||||
.link (send->hash ())
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*system.work.generate (key.pub))
|
||||
.build ();
|
||||
|
||||
sends.push_back (send);
|
||||
opens.push_back (open);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize nodes with blocks without the `updates` frontiers
|
||||
std::vector<std::shared_ptr<nano::block>> blocks;
|
||||
blocks.insert (blocks.end (), sends.begin (), sends.end ());
|
||||
system.set_initialization_blocks ({ blocks.begin (), blocks.end () });
|
||||
|
||||
auto & node0 = *system.add_node (config, flags);
|
||||
ASSERT_TRUE (nano::test::process (node0, opens));
|
||||
|
||||
// No blocks should be broadcast to the other node
|
||||
auto & node1 = *system.add_node (config, flags);
|
||||
ASSERT_ALWAYS_EQ (100ms, node1.ledger.block_count (), blocks.size () + 1);
|
||||
|
||||
// Frontier scan should detect all the accounts with missing blocks
|
||||
ASSERT_TIMELY (10s, std::all_of (opens.begin (), opens.end (), [&node1] (auto const & block) {
|
||||
return node1.ascendboot.prioritized (block->account ());
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
* Bootstrap should not attempt to prioritize accounts that can't be immediately connected to the ledger (no pending blocks, no existing frontier)
|
||||
*/
|
||||
TEST (bootstrap_ascending, frontier_scan_cannot_prioritize)
|
||||
{
|
||||
nano::test::system system;
|
||||
|
||||
nano::node_flags flags;
|
||||
flags.disable_legacy_bootstrap = true;
|
||||
nano::node_config config;
|
||||
// Disable other bootstrap strategies
|
||||
config.bootstrap_ascending.enable_scan = false;
|
||||
config.bootstrap_ascending.enable_dependency_walker = false;
|
||||
// Disable election activation
|
||||
config.backlog_population.enable = false;
|
||||
config.priority_scheduler.enable = false;
|
||||
config.optimistic_scheduler.enable = false;
|
||||
config.hinted_scheduler.enable = false;
|
||||
|
||||
// Prepare blocks for frontier scan (genesis 10 sends -> 10 opens -> 10 sends -> 10 opens)
|
||||
std::vector<std::shared_ptr<nano::block>> sends;
|
||||
std::vector<std::shared_ptr<nano::block>> opens;
|
||||
std::vector<std::shared_ptr<nano::block>> sends2;
|
||||
std::vector<std::shared_ptr<nano::block>> opens2;
|
||||
{
|
||||
auto source = nano::dev::genesis_key;
|
||||
auto latest = nano::dev::genesis->hash ();
|
||||
auto balance = nano::dev::genesis->balance ().number ();
|
||||
|
||||
size_t const count = 10;
|
||||
|
||||
for (int n = 0; n < count; ++n)
|
||||
{
|
||||
nano::keypair key, key2;
|
||||
nano::block_builder builder;
|
||||
|
||||
balance -= 1;
|
||||
auto send = builder
|
||||
.state ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.balance (balance)
|
||||
.link (key.pub)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*system.work.generate (latest))
|
||||
.build ();
|
||||
|
||||
latest = send->hash ();
|
||||
|
||||
auto open = builder
|
||||
.state ()
|
||||
.account (key.pub)
|
||||
.previous (0)
|
||||
.representative (key.pub)
|
||||
.balance (1)
|
||||
.link (send->hash ())
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*system.work.generate (key.pub))
|
||||
.build ();
|
||||
|
||||
auto send2 = builder
|
||||
.state ()
|
||||
.account (key.pub)
|
||||
.previous (open->hash ())
|
||||
.representative (key.pub)
|
||||
.balance (0)
|
||||
.link (key2.pub)
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*system.work.generate (open->hash ()))
|
||||
.build ();
|
||||
|
||||
auto open2 = builder
|
||||
.state ()
|
||||
.account (key2.pub)
|
||||
.previous (0)
|
||||
.representative (key2.pub)
|
||||
.balance (1)
|
||||
.link (send2->hash ())
|
||||
.sign (key2.prv, key2.pub)
|
||||
.work (*system.work.generate (key2.pub))
|
||||
.build ();
|
||||
|
||||
sends.push_back (send);
|
||||
opens.push_back (open);
|
||||
sends2.push_back (send2);
|
||||
opens2.push_back (open2);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize nodes with blocks without the `updates` frontiers
|
||||
std::vector<std::shared_ptr<nano::block>> blocks;
|
||||
blocks.insert (blocks.end (), sends.begin (), sends.end ());
|
||||
blocks.insert (blocks.end (), opens.begin (), opens.end ());
|
||||
system.set_initialization_blocks ({ blocks.begin (), blocks.end () });
|
||||
|
||||
auto & node0 = *system.add_node (config, flags);
|
||||
ASSERT_TRUE (nano::test::process (node0, sends2));
|
||||
ASSERT_TRUE (nano::test::process (node0, opens2));
|
||||
|
||||
// No blocks should be broadcast to the other node
|
||||
auto & node1 = *system.add_node (config, flags);
|
||||
ASSERT_ALWAYS_EQ (100ms, node1.ledger.block_count (), blocks.size () + 1);
|
||||
|
||||
// Frontier scan should not detect the accounts
|
||||
ASSERT_ALWAYS (1s, std::none_of (opens2.begin (), opens2.end (), [&node1] (auto const & block) {
|
||||
return node1.ascendboot.prioritized (block->account ());
|
||||
}));
|
||||
}
|
||||
|
|
@ -217,6 +217,18 @@ std::size_t nano::bootstrap_ascending::service::score_size () const
|
|||
return scoring.size ();
|
||||
}
|
||||
|
||||
bool nano::bootstrap_ascending::service::prioritized (nano::account const & account) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> lock{ mutex };
|
||||
return accounts.prioritized (account);
|
||||
}
|
||||
|
||||
bool nano::bootstrap_ascending::service::blocked (nano::account const & account) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> lock{ mutex };
|
||||
return accounts.blocked (account);
|
||||
}
|
||||
|
||||
/** Inspects a block that has been processed by the block processor
|
||||
- Marks an account as blocked if the result code is gap source as there is no reason request additional blocks for this account until the dependency is resolved
|
||||
- Marks an account as forwarded if it has been recently referenced by a block that has been inserted.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ namespace bootstrap_ascending
|
|||
std::size_t blocked_size () const;
|
||||
std::size_t priority_size () const;
|
||||
std::size_t score_size () const;
|
||||
bool prioritized (nano::account const &) const;
|
||||
bool blocked (nano::account const &) const;
|
||||
nano::bootstrap_ascending::account_sets::info_t info () const;
|
||||
|
||||
private: // Dependencies
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue