Fix error messages generated when peer is syncing with empty blockchain
This commit is contained in:
parent
1141d1ce89
commit
0046cc0698
3 changed files with 42 additions and 11 deletions
|
|
@ -382,6 +382,10 @@ namespace detail {
|
||||||
ilog("Got block #${n} from network", ("n", blk_msg.block.block_num()));
|
ilog("Got block #${n} from network", ("n", blk_msg.block.block_num()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
|
||||||
|
// you can help the network code out by throwing a block_older_than_undo_history exception.
|
||||||
|
// when the net code sees that, it will stop trying to push blocks from that chain, but
|
||||||
|
// leave that peer connected so that they can get sync blocks from us
|
||||||
bool result = _chain_db->push_block(blk_msg.block, _is_block_producer ? database::skip_nothing : database::skip_transaction_signatures);
|
bool result = _chain_db->push_block(blk_msg.block, _is_block_producer ? database::skip_nothing : database::skip_transaction_signatures);
|
||||||
|
|
||||||
// the block was accepted, so we now know all of the transactions contained in the block
|
// the block was accepted, so we now know all of the transactions contained in the block
|
||||||
|
|
@ -444,7 +448,7 @@ namespace detail {
|
||||||
uint32_t& remaining_item_count,
|
uint32_t& remaining_item_count,
|
||||||
uint32_t limit) override
|
uint32_t limit) override
|
||||||
{ try {
|
{ try {
|
||||||
vector<block_id_type> result;
|
vector<block_id_type> result;
|
||||||
remaining_item_count = 0;
|
remaining_item_count = 0;
|
||||||
if( _chain_db->head_block_num() == 0 )
|
if( _chain_db->head_block_num() == 0 )
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -452,14 +456,29 @@ namespace detail {
|
||||||
result.reserve(limit);
|
result.reserve(limit);
|
||||||
block_id_type last_known_block_id;
|
block_id_type last_known_block_id;
|
||||||
|
|
||||||
for (const item_hash_t& block_id_in_synopsis : boost::adaptors::reverse(blockchain_synopsis))
|
if (blockchain_synopsis.empty() ||
|
||||||
if (block_id_in_synopsis == block_id_type() ||
|
(blockchain_synopsis.size() == 1 && blockchain_synopsis[0] == block_id_type()))
|
||||||
(_chain_db->is_known_block(block_id_in_synopsis) && is_included_block(block_id_in_synopsis)))
|
{
|
||||||
{
|
// peer has sent us an empty synopsis meaning they have no blocks.
|
||||||
last_known_block_id = block_id_in_synopsis;
|
// A bug in old versions would cause them to send a synopsis containing block 000000000
|
||||||
break;
|
// when they had an empty blockchain, so pretend they sent the right thing here.
|
||||||
}
|
|
||||||
|
|
||||||
|
// do nothing, leave last_known_block_id set to zero
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool found_a_block_in_synopsis = false;
|
||||||
|
for (const item_hash_t& block_id_in_synopsis : boost::adaptors::reverse(blockchain_synopsis))
|
||||||
|
if (block_id_in_synopsis == block_id_type() ||
|
||||||
|
(_chain_db->is_known_block(block_id_in_synopsis) && is_included_block(block_id_in_synopsis)))
|
||||||
|
{
|
||||||
|
last_known_block_id = block_id_in_synopsis;
|
||||||
|
found_a_block_in_synopsis = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found_a_block_in_synopsis)
|
||||||
|
FC_THROW_EXCEPTION(graphene::net::peer_is_on_an_unreachable_fork, "Unable to provide a list of blocks starting at any of the blocks in peer's synopsis");
|
||||||
|
}
|
||||||
for( uint32_t num = block_header::num_from_id(last_known_block_id);
|
for( uint32_t num = block_header::num_from_id(last_known_block_id);
|
||||||
num <= _chain_db->head_block_num() && result.size() < limit;
|
num <= _chain_db->head_block_num() && result.size() < limit;
|
||||||
++num )
|
++num )
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,6 @@ namespace graphene { namespace net {
|
||||||
FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::net::net_exception, 90002, "insufficient relay fee" );
|
FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::net::net_exception, 90002, "insufficient relay fee" );
|
||||||
FC_DECLARE_DERIVED_EXCEPTION( already_connected_to_requested_peer, graphene::net::net_exception, 90003, "already connected to requested peer" );
|
FC_DECLARE_DERIVED_EXCEPTION( already_connected_to_requested_peer, graphene::net::net_exception, 90003, "already connected to requested peer" );
|
||||||
FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::net::net_exception, 90004, "block is older than our undo history allows us to process" );
|
FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::net::net_exception, 90004, "block is older than our undo history allows us to process" );
|
||||||
|
FC_DECLARE_DERIVED_EXCEPTION( peer_is_on_an_unreachable_fork, graphene::net::net_exception, 90005, "peer is on another fork" );
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
||||||
|
|
@ -2162,9 +2162,20 @@ namespace graphene { namespace net { namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
blockchain_item_ids_inventory_message reply_message;
|
blockchain_item_ids_inventory_message reply_message;
|
||||||
reply_message.item_hashes_available = _delegate->get_block_ids(fetch_blockchain_item_ids_message_received.blockchain_synopsis,
|
|
||||||
reply_message.total_remaining_item_count );
|
|
||||||
reply_message.item_type = fetch_blockchain_item_ids_message_received.item_type;
|
reply_message.item_type = fetch_blockchain_item_ids_message_received.item_type;
|
||||||
|
reply_message.total_remaining_item_count = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reply_message.item_hashes_available = _delegate->get_block_ids(fetch_blockchain_item_ids_message_received.blockchain_synopsis,
|
||||||
|
reply_message.total_remaining_item_count);
|
||||||
|
}
|
||||||
|
catch (const peer_is_on_an_unreachable_fork&)
|
||||||
|
{
|
||||||
|
dlog("Peer is on a fork and there's no set of blocks we can provide to switch them to our fork");
|
||||||
|
// we reply with an empty list as if we had an empty blockchain;
|
||||||
|
// we don't want to disconnect because they may be able to provide
|
||||||
|
// us with blocks on their chain
|
||||||
|
}
|
||||||
|
|
||||||
bool disconnect_from_inhibited_peer = false;
|
bool disconnect_from_inhibited_peer = false;
|
||||||
// if our client doesn't have any items after the item the peer requested, it will send back
|
// if our client doesn't have any items after the item the peer requested, it will send back
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue