parent
af2c6a9011
commit
86664d158f
5 changed files with 173 additions and 5 deletions
|
|
@ -1233,6 +1233,137 @@ TEST (frontier_req, time_cutoff)
|
||||||
ASSERT_TRUE (request2->frontier.is_zero ());
|
ASSERT_TRUE (request2->frontier.is_zero ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST (frontier_req, confirmed_frontier)
|
||||||
|
{
|
||||||
|
nano::system system (1);
|
||||||
|
auto node1 = system.nodes[0];
|
||||||
|
nano::genesis genesis;
|
||||||
|
nano::raw_key priv_key;
|
||||||
|
// Public key before genesis in accounts table
|
||||||
|
while (nano::pub_key (priv_key).number () >= nano::dev_genesis_key.pub.number ())
|
||||||
|
{
|
||||||
|
priv_key = nano::keypair ().prv;
|
||||||
|
}
|
||||||
|
nano::keypair key_before_genesis (priv_key.to_string ());
|
||||||
|
// Public key after genesis in accounts table
|
||||||
|
while (nano::pub_key (priv_key).number () <= nano::dev_genesis_key.pub.number ())
|
||||||
|
{
|
||||||
|
priv_key = nano::keypair ().prv;
|
||||||
|
}
|
||||||
|
nano::keypair key_after_genesis (priv_key.to_string ());
|
||||||
|
|
||||||
|
auto send1 (std::make_shared<nano::state_block> (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key_before_genesis.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
|
||||||
|
node1->work_generate_blocking (*send1);
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code);
|
||||||
|
auto send2 (std::make_shared<nano::state_block> (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key_after_genesis.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
|
||||||
|
node1->work_generate_blocking (*send2);
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code);
|
||||||
|
auto receive1 (std::make_shared<nano::state_block> (key_before_genesis.pub, 0, nano::dev_genesis_key.pub, nano::Gxrb_ratio, send1->hash (), key_before_genesis.prv, key_before_genesis.pub, 0));
|
||||||
|
node1->work_generate_blocking (*receive1);
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node1->process (*receive1).code);
|
||||||
|
auto receive2 (std::make_shared<nano::state_block> (key_after_genesis.pub, 0, nano::dev_genesis_key.pub, nano::Gxrb_ratio, send2->hash (), key_after_genesis.prv, key_after_genesis.pub, 0));
|
||||||
|
node1->work_generate_blocking (*receive2);
|
||||||
|
ASSERT_EQ (nano::process_result::progress, node1->process (*receive2).code);
|
||||||
|
|
||||||
|
// Request for all accounts (confirmed only)
|
||||||
|
auto connection (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req = std::make_unique<nano::frontier_req> ();
|
||||||
|
req->start.clear ();
|
||||||
|
req->age = std::numeric_limits<decltype (req->age)>::max ();
|
||||||
|
req->count = std::numeric_limits<decltype (req->count)>::max ();
|
||||||
|
ASSERT_FALSE (req->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
req->header.flag_set (nano::message_header::frontier_req_only_confirmed);
|
||||||
|
ASSERT_TRUE (req->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request (std::make_shared<nano::frontier_req_server> (connection, std::move (req)));
|
||||||
|
ASSERT_EQ (nano::dev_genesis_key.pub, request->current);
|
||||||
|
ASSERT_EQ (genesis.hash (), request->frontier);
|
||||||
|
|
||||||
|
// Request starting with account before genesis (confirmed only)
|
||||||
|
auto connection2 (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req2 = std::make_unique<nano::frontier_req> ();
|
||||||
|
req2->start = key_before_genesis.pub;
|
||||||
|
req2->age = std::numeric_limits<decltype (req2->age)>::max ();
|
||||||
|
req2->count = std::numeric_limits<decltype (req2->count)>::max ();
|
||||||
|
ASSERT_FALSE (req2->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
req2->header.flag_set (nano::message_header::frontier_req_only_confirmed);
|
||||||
|
ASSERT_TRUE (req2->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection2->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request2 (std::make_shared<nano::frontier_req_server> (connection2, std::move (req2)));
|
||||||
|
ASSERT_EQ (nano::dev_genesis_key.pub, request2->current);
|
||||||
|
ASSERT_EQ (genesis.hash (), request2->frontier);
|
||||||
|
|
||||||
|
// Request starting with account after genesis (confirmed only)
|
||||||
|
auto connection3 (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req3 = std::make_unique<nano::frontier_req> ();
|
||||||
|
req3->start = key_after_genesis.pub;
|
||||||
|
req3->age = std::numeric_limits<decltype (req3->age)>::max ();
|
||||||
|
req3->count = std::numeric_limits<decltype (req3->count)>::max ();
|
||||||
|
ASSERT_FALSE (req3->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
req3->header.flag_set (nano::message_header::frontier_req_only_confirmed);
|
||||||
|
ASSERT_TRUE (req3->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection3->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request3 (std::make_shared<nano::frontier_req_server> (connection3, std::move (req3)));
|
||||||
|
ASSERT_TRUE (request3->current.is_zero ());
|
||||||
|
ASSERT_TRUE (request3->frontier.is_zero ());
|
||||||
|
|
||||||
|
// Request for all accounts (unconfirmed blocks)
|
||||||
|
auto connection4 (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req4 = std::make_unique<nano::frontier_req> ();
|
||||||
|
req4->start.clear ();
|
||||||
|
req4->age = std::numeric_limits<decltype (req4->age)>::max ();
|
||||||
|
req4->count = std::numeric_limits<decltype (req4->count)>::max ();
|
||||||
|
ASSERT_FALSE (req4->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection4->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request4 (std::make_shared<nano::frontier_req_server> (connection4, std::move (req4)));
|
||||||
|
ASSERT_EQ (key_before_genesis.pub, request4->current);
|
||||||
|
ASSERT_EQ (receive1->hash (), request4->frontier);
|
||||||
|
|
||||||
|
// Request starting with account after genesis (unconfirmed blocks)
|
||||||
|
auto connection5 (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req5 = std::make_unique<nano::frontier_req> ();
|
||||||
|
req5->start = key_after_genesis.pub;
|
||||||
|
req5->age = std::numeric_limits<decltype (req5->age)>::max ();
|
||||||
|
req5->count = std::numeric_limits<decltype (req5->count)>::max ();
|
||||||
|
ASSERT_FALSE (req5->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection5->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request5 (std::make_shared<nano::frontier_req_server> (connection5, std::move (req5)));
|
||||||
|
ASSERT_EQ (key_after_genesis.pub, request5->current);
|
||||||
|
ASSERT_EQ (receive2->hash (), request5->frontier);
|
||||||
|
|
||||||
|
// Confirm account before genesis (confirmed only)
|
||||||
|
nano::blocks_confirm (*node1, { send1, receive1 }, true);
|
||||||
|
ASSERT_TIMELY (5s, node1->block_confirmed (send1->hash ()) && node1->block_confirmed (receive1->hash ()));
|
||||||
|
auto connection6 (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req6 = std::make_unique<nano::frontier_req> ();
|
||||||
|
req6->start = key_before_genesis.pub;
|
||||||
|
req6->age = std::numeric_limits<decltype (req6->age)>::max ();
|
||||||
|
req6->count = std::numeric_limits<decltype (req6->count)>::max ();
|
||||||
|
ASSERT_FALSE (req6->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
req6->header.flag_set (nano::message_header::frontier_req_only_confirmed);
|
||||||
|
ASSERT_TRUE (req6->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection6->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request6 (std::make_shared<nano::frontier_req_server> (connection6, std::move (req6)));
|
||||||
|
ASSERT_EQ (key_before_genesis.pub, request6->current);
|
||||||
|
ASSERT_EQ (receive1->hash (), request6->frontier);
|
||||||
|
|
||||||
|
// Confirm account after genesis (confirmed only)
|
||||||
|
nano::blocks_confirm (*node1, { send2, receive2 }, true);
|
||||||
|
ASSERT_TIMELY (5s, node1->block_confirmed (send2->hash ()) && node1->block_confirmed (receive2->hash ()));
|
||||||
|
auto connection7 (std::make_shared<nano::bootstrap_server> (nullptr, node1));
|
||||||
|
auto req7 = std::make_unique<nano::frontier_req> ();
|
||||||
|
req7->start = key_after_genesis.pub;
|
||||||
|
req7->age = std::numeric_limits<decltype (req7->age)>::max ();
|
||||||
|
req7->count = std::numeric_limits<decltype (req7->count)>::max ();
|
||||||
|
ASSERT_FALSE (req7->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
req7->header.flag_set (nano::message_header::frontier_req_only_confirmed);
|
||||||
|
ASSERT_TRUE (req7->header.frontier_req_is_only_confirmed_present ());
|
||||||
|
connection7->requests.push (std::unique_ptr<nano::message>{});
|
||||||
|
auto request7 (std::make_shared<nano::frontier_req_server> (connection7, std::move (req7)));
|
||||||
|
ASSERT_EQ (key_after_genesis.pub, request7->current);
|
||||||
|
ASSERT_EQ (receive2->hash (), request7->frontier);
|
||||||
|
}
|
||||||
|
|
||||||
TEST (bulk, genesis)
|
TEST (bulk, genesis)
|
||||||
{
|
{
|
||||||
nano::system system;
|
nano::system system;
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,8 @@ void nano::frontier_req_server::next ()
|
||||||
bool disable_age_filter (request->age == std::numeric_limits<decltype (request->age)>::max ());
|
bool disable_age_filter (request->age == std::numeric_limits<decltype (request->age)>::max ());
|
||||||
size_t max_size (128);
|
size_t max_size (128);
|
||||||
auto transaction (connection->node->store.tx_begin_read ());
|
auto transaction (connection->node->store.tx_begin_read ());
|
||||||
|
if (!send_confirmed ())
|
||||||
|
{
|
||||||
for (auto i (connection->node->store.accounts_begin (transaction, current.number () + 1)), n (connection->node->store.accounts_end ()); i != n && accounts.size () != max_size; ++i)
|
for (auto i (connection->node->store.accounts_begin (transaction, current.number () + 1)), n (connection->node->store.accounts_end ()); i != n && accounts.size () != max_size; ++i)
|
||||||
{
|
{
|
||||||
nano::account_info const & info (i->second);
|
nano::account_info const & info (i->second);
|
||||||
|
|
@ -328,6 +330,20 @@ void nano::frontier_req_server::next ()
|
||||||
accounts.emplace_back (account, info.head);
|
accounts.emplace_back (account, info.head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto i (connection->node->store.confirmation_height_begin (transaction, current.number () + 1)), n (connection->node->store.confirmation_height_end ()); i != n && accounts.size () != max_size; ++i)
|
||||||
|
{
|
||||||
|
nano::confirmation_height_info const & info (i->second);
|
||||||
|
nano::block_hash const & confirmed_frontier (info.frontier);
|
||||||
|
if (!confirmed_frontier.is_zero ())
|
||||||
|
{
|
||||||
|
nano::account const & account (i->first);
|
||||||
|
accounts.emplace_back (account, confirmed_frontier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* If loop breaks before max_size, then accounts_end () is reached
|
/* If loop breaks before max_size, then accounts_end () is reached
|
||||||
Add empty record to finish frontier_req_server */
|
Add empty record to finish frontier_req_server */
|
||||||
if (accounts.size () != max_size)
|
if (accounts.size () != max_size)
|
||||||
|
|
@ -341,3 +357,8 @@ void nano::frontier_req_server::next ()
|
||||||
frontier = account_pair.second;
|
frontier = account_pair.second;
|
||||||
accounts.pop_front ();
|
accounts.pop_front ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nano::frontier_req_server::send_confirmed ()
|
||||||
|
{
|
||||||
|
return request->header.frontier_req_is_only_confirmed_present ();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ public:
|
||||||
void send_finished ();
|
void send_finished ();
|
||||||
void no_block_sent (boost::system::error_code const &, size_t);
|
void no_block_sent (boost::system::error_code const &, size_t);
|
||||||
void next ();
|
void next ();
|
||||||
|
bool send_confirmed ();
|
||||||
std::shared_ptr<nano::bootstrap_server> connection;
|
std::shared_ptr<nano::bootstrap_server> connection;
|
||||||
nano::account current;
|
nano::account current;
|
||||||
nano::block_hash frontier;
|
nano::block_hash frontier;
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,19 @@ bool nano::message_header::bulk_pull_is_count_present () const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nano::message_header::frontier_req_is_only_confirmed_present () const
|
||||||
|
{
|
||||||
|
auto result (false);
|
||||||
|
if (type == nano::message_type::frontier_req)
|
||||||
|
{
|
||||||
|
if (extensions.test (frontier_req_only_confirmed))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool nano::message_header::node_id_handshake_is_query () const
|
bool nano::message_header::node_id_handshake_is_query () const
|
||||||
{
|
{
|
||||||
auto result (false);
|
auto result (false);
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,8 @@ public:
|
||||||
void flag_set (uint8_t);
|
void flag_set (uint8_t);
|
||||||
static uint8_t constexpr bulk_pull_count_present_flag = 0;
|
static uint8_t constexpr bulk_pull_count_present_flag = 0;
|
||||||
bool bulk_pull_is_count_present () const;
|
bool bulk_pull_is_count_present () const;
|
||||||
|
static uint8_t constexpr frontier_req_only_confirmed = 1;
|
||||||
|
bool frontier_req_is_only_confirmed_present () const;
|
||||||
static uint8_t constexpr node_id_handshake_query_flag = 0;
|
static uint8_t constexpr node_id_handshake_query_flag = 0;
|
||||||
static uint8_t constexpr node_id_handshake_response_flag = 1;
|
static uint8_t constexpr node_id_handshake_response_flag = 1;
|
||||||
bool node_id_handshake_is_query () const;
|
bool node_id_handshake_is_query () const;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue