Specify whether bootstrap pull should start at block hash or account (#4018)

* Specify whether pull should start at block hash or account

* Specify account info request target type
This commit is contained in:
Piotr Wójcik 2022-12-08 15:22:59 +01:00 committed by GitHub
commit 7965c512b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 17 deletions

View file

@ -171,6 +171,7 @@ TEST (bootstrap_server, serve_account_blocks)
nano::asc_pull_req::blocks_payload request_payload; nano::asc_pull_req::blocks_payload request_payload;
request_payload.start = first_account; request_payload.start = first_account;
request_payload.count = nano::bootstrap_server::max_blocks; request_payload.count = nano::bootstrap_server::max_blocks;
request_payload.start_type = nano::asc_pull_req::hash_type::account;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -217,6 +218,7 @@ TEST (bootstrap_server, serve_hash)
nano::asc_pull_req::blocks_payload request_payload; nano::asc_pull_req::blocks_payload request_payload;
request_payload.start = blocks.front ()->hash (); request_payload.start = blocks.front ()->hash ();
request_payload.count = nano::bootstrap_server::max_blocks; request_payload.count = nano::bootstrap_server::max_blocks;
request_payload.start_type = nano::asc_pull_req::hash_type::block;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -263,6 +265,7 @@ TEST (bootstrap_server, serve_hash_one)
nano::asc_pull_req::blocks_payload request_payload; nano::asc_pull_req::blocks_payload request_payload;
request_payload.start = blocks.front ()->hash (); request_payload.start = blocks.front ()->hash ();
request_payload.count = 1; request_payload.count = 1;
request_payload.start_type = nano::asc_pull_req::hash_type::block;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -303,6 +306,7 @@ TEST (bootstrap_server, serve_end_of_chain)
nano::asc_pull_req::blocks_payload request_payload; nano::asc_pull_req::blocks_payload request_payload;
request_payload.start = blocks.back ()->hash (); request_payload.start = blocks.back ()->hash ();
request_payload.count = nano::bootstrap_server::max_blocks; request_payload.count = nano::bootstrap_server::max_blocks;
request_payload.start_type = nano::asc_pull_req::hash_type::block;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -343,6 +347,7 @@ TEST (bootstrap_server, serve_missing)
nano::asc_pull_req::blocks_payload request_payload; nano::asc_pull_req::blocks_payload request_payload;
request_payload.start = nano::test::random_hash (); request_payload.start = nano::test::random_hash ();
request_payload.count = nano::bootstrap_server::max_blocks; request_payload.count = nano::bootstrap_server::max_blocks;
request_payload.start_type = nano::asc_pull_req::hash_type::block;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -387,6 +392,7 @@ TEST (bootstrap_server, serve_multiple)
nano::asc_pull_req::blocks_payload request_payload; nano::asc_pull_req::blocks_payload request_payload;
request_payload.start = account; request_payload.start = account;
request_payload.count = nano::bootstrap_server::max_blocks; request_payload.count = nano::bootstrap_server::max_blocks;
request_payload.start_type = nano::asc_pull_req::hash_type::account;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -444,6 +450,7 @@ TEST (bootstrap_server, serve_account_info)
nano::asc_pull_req::account_info_payload request_payload; nano::asc_pull_req::account_info_payload request_payload;
request_payload.target = account; request_payload.target = account;
request_payload.target_type = nano::asc_pull_req::hash_type::account;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();
@ -491,6 +498,7 @@ TEST (bootstrap_server, serve_account_info_missing)
nano::asc_pull_req::account_info_payload request_payload; nano::asc_pull_req::account_info_payload request_payload;
request_payload.target = nano::test::random_account (); request_payload.target = nano::test::random_account ();
request_payload.target_type = nano::asc_pull_req::hash_type::account;
request.payload = request_payload; request.payload = request_payload;
request.update_header (); request.update_header ();

View file

@ -174,23 +174,26 @@ nano::asc_pull_ack nano::bootstrap_server::process (nano::transaction const & tr
{ {
const std::size_t count = std::min (static_cast<std::size_t> (request.count), max_blocks); const std::size_t count = std::min (static_cast<std::size_t> (request.count), max_blocks);
// `start` can represent either account or block hash switch (request.start_type)
if (store.block.exists (transaction, request.start.as_block_hash ()))
{ {
return prepare_response (transaction, id, request.start.as_block_hash (), count); case asc_pull_req::hash_type::block:
}
if (store.account.exists (transaction, request.start.as_account ()))
{
auto info = store.account.get (transaction, request.start.as_account ());
if (info)
{ {
// Start from open block if pulling by account if (store.block.exists (transaction, request.start.as_block_hash ()))
return prepare_response (transaction, id, info->open_block, count); {
return prepare_response (transaction, id, request.start.as_block_hash (), count);
}
} }
else break;
case asc_pull_req::hash_type::account:
{ {
debug_assert (false, "account exists but cannot be retrieved"); auto info = store.account.get (transaction, request.start.as_account ());
if (info)
{
// Start from open block if pulling by account
return prepare_response (transaction, id, info->open_block, count);
}
} }
break;
} }
// Neither block nor account found, send empty response to indicate that // Neither block nor account found, send empty response to indicate that
@ -258,13 +261,21 @@ nano::asc_pull_ack nano::bootstrap_server::process (const nano::transaction & tr
response.id = id; response.id = id;
response.type = nano::asc_pull_type::account_info; response.type = nano::asc_pull_type::account_info;
auto target = request.target.as_account (); nano::account target{ 0 };
// Try to lookup account assuming target is block hash switch (request.target_type)
if (auto account_from_hash = ledger.account_safe (transaction, request.target.as_block_hash ()); !account_from_hash.is_zero ())
{ {
target = account_from_hash; case asc_pull_req::hash_type::account:
{
target = request.target.as_account ();
}
break;
case asc_pull_req::hash_type::block:
{
// Try to lookup account assuming target is block hash
target = ledger.account_safe (transaction, request.target.as_block_hash ());
}
break;
} }
// Otherwise assume target is an actual account
nano::asc_pull_ack::account_info_payload response_payload{}; nano::asc_pull_ack::account_info_payload response_payload{};
response_payload.account = target; response_payload.account = target;

View file

@ -1747,12 +1747,14 @@ void nano::asc_pull_req::blocks_payload::serialize (nano::stream & stream) const
{ {
nano::write (stream, start); nano::write (stream, start);
nano::write (stream, count); nano::write (stream, count);
nano::write (stream, start_type);
} }
void nano::asc_pull_req::blocks_payload::deserialize (nano::stream & stream) void nano::asc_pull_req::blocks_payload::deserialize (nano::stream & stream)
{ {
nano::read (stream, start); nano::read (stream, start);
nano::read (stream, count); nano::read (stream, count);
nano::read (stream, start_type);
} }
/* /*
@ -1762,11 +1764,13 @@ void nano::asc_pull_req::blocks_payload::deserialize (nano::stream & stream)
void nano::asc_pull_req::account_info_payload::serialize (stream & stream) const void nano::asc_pull_req::account_info_payload::serialize (stream & stream) const
{ {
nano::write (stream, target); nano::write (stream, target);
nano::write (stream, target_type);
} }
void nano::asc_pull_req::account_info_payload::deserialize (stream & stream) void nano::asc_pull_req::account_info_payload::deserialize (stream & stream)
{ {
nano::read (stream, target); nano::read (stream, target);
nano::read (stream, target_type);
} }
/* /*

View file

@ -414,6 +414,12 @@ private: // Debug
bool verify_consistency () const; bool verify_consistency () const;
public: // Payload definitions public: // Payload definitions
enum class hash_type : uint8_t
{
account = 0,
block = 1,
};
class blocks_payload class blocks_payload
{ {
public: public:
@ -423,6 +429,7 @@ public: // Payload definitions
public: public:
nano::hash_or_account start{ 0 }; nano::hash_or_account start{ 0 };
uint8_t count{ 0 }; uint8_t count{ 0 };
asc_pull_req::hash_type start_type{ 0 };
}; };
class account_info_payload class account_info_payload
@ -433,6 +440,7 @@ public: // Payload definitions
public: public:
nano::hash_or_account target{ 0 }; nano::hash_or_account target{ 0 };
asc_pull_req::hash_type target_type{ 0 };
}; };
public: // Payload public: // Payload