parent
2a155b7dca
commit
1f1c8abc21
2 changed files with 219 additions and 1 deletions
|
@ -2,10 +2,12 @@
|
|||
#include <nano/lib/logging.hpp>
|
||||
#include <nano/lib/stats.hpp>
|
||||
#include <nano/lib/tomlconfig.hpp>
|
||||
#include <nano/node/bootstrap_ascending/database_scan.hpp>
|
||||
#include <nano/node/bootstrap_ascending/service.hpp>
|
||||
#include <nano/node/make_store.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
#include <nano/secure/ledger_set_any.hpp>
|
||||
#include <nano/test_common/ledger_context.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/testutil.hpp>
|
||||
|
||||
|
@ -266,3 +268,219 @@ TEST (bootstrap_ascending, trace_base)
|
|||
// std::cerr << "node1: " << node1.network.endpoint () << std::endl;
|
||||
ASSERT_TIMELY (10s, node1.block (receive1->hash ()) != nullptr);
|
||||
}
|
||||
|
||||
TEST (bootstrap_ascending, pending_database_scanner)
|
||||
{
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
|
||||
// Prepare pending sends from genesis
|
||||
// 1 account with 1 pending
|
||||
// 1 account with 21 pendings
|
||||
// 2 accounts with 1 pending each
|
||||
std::deque<std::shared_ptr<nano::block>> blocks;
|
||||
nano::keypair key1, key2, key3, key4;
|
||||
{
|
||||
nano::state_block_builder builder;
|
||||
|
||||
auto source = nano::dev::genesis_key;
|
||||
auto latest = nano::dev::genesis->hash ();
|
||||
auto balance = nano::dev::genesis->balance ().number ();
|
||||
|
||||
// 1 account with 1 pending
|
||||
{
|
||||
auto send = builder.make_block ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.link (key1.pub)
|
||||
.balance (balance - 1)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*pool.generate (latest))
|
||||
.build ();
|
||||
latest = send->hash ();
|
||||
balance = send->balance_field ().value ().number ();
|
||||
blocks.push_back (send);
|
||||
}
|
||||
// 1 account with 21 pendings
|
||||
for (int i = 0; i < 21; ++i)
|
||||
{
|
||||
auto send = builder.make_block ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.link (key2.pub)
|
||||
.balance (balance - 1)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*pool.generate (latest))
|
||||
.build ();
|
||||
latest = send->hash ();
|
||||
balance = send->balance_field ().value ().number ();
|
||||
blocks.push_back (send);
|
||||
}
|
||||
// 2 accounts with 1 pending each
|
||||
{
|
||||
auto send = builder.make_block ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.link (key3.pub)
|
||||
.balance (balance - 1)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*pool.generate (latest))
|
||||
.build ();
|
||||
latest = send->hash ();
|
||||
balance = send->balance_field ().value ().number ();
|
||||
blocks.push_back (send);
|
||||
}
|
||||
{
|
||||
auto send = builder.make_block ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.link (key4.pub)
|
||||
.balance (balance - 1)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*pool.generate (latest))
|
||||
.build ();
|
||||
latest = send->hash ();
|
||||
balance = send->balance_field ().value ().number ();
|
||||
blocks.push_back (send);
|
||||
}
|
||||
}
|
||||
|
||||
nano::test::ledger_context ctx{ std::move (blocks) };
|
||||
|
||||
// Single batch
|
||||
{
|
||||
nano::bootstrap_ascending::pending_database_iterator scanner{ ctx.ledger () };
|
||||
auto transaction = ctx.store ().tx_begin_read ();
|
||||
auto accounts = scanner.next_batch (transaction, 256);
|
||||
|
||||
// Check that account set contains all keys
|
||||
ASSERT_EQ (accounts.size (), 4);
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key1.pub) != accounts.end ());
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key2.pub) != accounts.end ());
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key3.pub) != accounts.end ());
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key4.pub) != accounts.end ());
|
||||
|
||||
ASSERT_EQ (scanner.completed, 1);
|
||||
}
|
||||
// Multi batch
|
||||
{
|
||||
nano::bootstrap_ascending::pending_database_iterator scanner{ ctx.ledger () };
|
||||
auto transaction = ctx.store ().tx_begin_read ();
|
||||
|
||||
// Request accounts in multiple batches
|
||||
auto accounts1 = scanner.next_batch (transaction, 2);
|
||||
auto accounts2 = scanner.next_batch (transaction, 1);
|
||||
auto accounts3 = scanner.next_batch (transaction, 1);
|
||||
|
||||
ASSERT_EQ (accounts1.size (), 2);
|
||||
ASSERT_EQ (accounts2.size (), 1);
|
||||
ASSERT_EQ (accounts3.size (), 1);
|
||||
|
||||
std::deque<nano::account> accounts;
|
||||
accounts.insert (accounts.end (), accounts1.begin (), accounts1.end ());
|
||||
accounts.insert (accounts.end (), accounts2.begin (), accounts2.end ());
|
||||
accounts.insert (accounts.end (), accounts3.begin (), accounts3.end ());
|
||||
|
||||
// Check that account set contains all keys
|
||||
ASSERT_EQ (accounts.size (), 4);
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key1.pub) != accounts.end ());
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key2.pub) != accounts.end ());
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key3.pub) != accounts.end ());
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key4.pub) != accounts.end ());
|
||||
|
||||
ASSERT_EQ (scanner.completed, 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST (bootstrap_ascending, account_database_scanner)
|
||||
{
|
||||
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
|
||||
|
||||
size_t const count = 4;
|
||||
|
||||
// Prepare some accounts
|
||||
std::deque<std::shared_ptr<nano::block>> blocks;
|
||||
std::deque<nano::keypair> keys;
|
||||
{
|
||||
nano::state_block_builder builder;
|
||||
|
||||
auto source = nano::dev::genesis_key;
|
||||
auto latest = nano::dev::genesis->hash ();
|
||||
auto balance = nano::dev::genesis->balance ().number ();
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
nano::keypair key;
|
||||
auto send = builder.make_block ()
|
||||
.account (source.pub)
|
||||
.previous (latest)
|
||||
.representative (source.pub)
|
||||
.link (key.pub)
|
||||
.balance (balance - 1)
|
||||
.sign (source.prv, source.pub)
|
||||
.work (*pool.generate (latest))
|
||||
.build ();
|
||||
auto open = builder.make_block ()
|
||||
.account (key.pub)
|
||||
.previous (0)
|
||||
.representative (key.pub)
|
||||
.link (send->hash ())
|
||||
.balance (1)
|
||||
.sign (key.prv, key.pub)
|
||||
.work (*pool.generate (key.pub))
|
||||
.build ();
|
||||
latest = send->hash ();
|
||||
balance = send->balance_field ().value ().number ();
|
||||
blocks.push_back (send);
|
||||
blocks.push_back (open);
|
||||
keys.push_back (key);
|
||||
}
|
||||
}
|
||||
|
||||
nano::test::ledger_context ctx{ std::move (blocks) };
|
||||
|
||||
// Single batch
|
||||
{
|
||||
nano::bootstrap_ascending::account_database_iterator scanner{ ctx.ledger () };
|
||||
auto transaction = ctx.store ().tx_begin_read ();
|
||||
auto accounts = scanner.next_batch (transaction, 256);
|
||||
|
||||
// Check that account set contains all keys
|
||||
ASSERT_EQ (accounts.size (), keys.size () + 1); // +1 for genesis
|
||||
for (auto const & key : keys)
|
||||
{
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key.pub) != accounts.end ());
|
||||
}
|
||||
ASSERT_EQ (scanner.completed, 1);
|
||||
}
|
||||
// Multi batch
|
||||
{
|
||||
nano::bootstrap_ascending::account_database_iterator scanner{ ctx.ledger () };
|
||||
auto transaction = ctx.store ().tx_begin_read ();
|
||||
|
||||
// Request accounts in multiple batches
|
||||
auto accounts1 = scanner.next_batch (transaction, 2);
|
||||
auto accounts2 = scanner.next_batch (transaction, 2);
|
||||
auto accounts3 = scanner.next_batch (transaction, 1);
|
||||
|
||||
ASSERT_EQ (accounts1.size (), 2);
|
||||
ASSERT_EQ (accounts2.size (), 2);
|
||||
ASSERT_EQ (accounts3.size (), 1);
|
||||
|
||||
std::deque<nano::account> accounts;
|
||||
accounts.insert (accounts.end (), accounts1.begin (), accounts1.end ());
|
||||
accounts.insert (accounts.end (), accounts2.begin (), accounts2.end ());
|
||||
accounts.insert (accounts.end (), accounts3.begin (), accounts3.end ());
|
||||
|
||||
// Check that account set contains all keys
|
||||
ASSERT_EQ (accounts.size (), keys.size () + 1); // +1 for genesis
|
||||
for (auto const & key : keys)
|
||||
{
|
||||
ASSERT_TRUE (std::find (accounts.begin (), accounts.end (), key.pub) != accounts.end ());
|
||||
}
|
||||
ASSERT_EQ (scanner.completed, 1);
|
||||
}
|
||||
}
|
|
@ -136,7 +136,7 @@ std::deque<nano::account> nano::bootstrap_ascending::pending_database_iterator::
|
|||
}
|
||||
|
||||
// If we didn't advance to the next account, perform a fresh lookup
|
||||
if (it != end && it->first.account != starting_account)
|
||||
if (it != end && it->first.account == starting_account)
|
||||
{
|
||||
it = ledger.store.pending.begin (transaction, { starting_account.number () + 1, 0 });
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue