| 3311 | } |
| 3312 | |
| 3313 | void node_impl::process_block_during_normal_operation( peer_connection* originating_peer, |
| 3314 | const graphene::net::block_message& block_message_to_process, |
| 3315 | const message_hash_type& message_hash ) |
| 3316 | { |
| 3317 | fc::time_point message_receive_time = fc::time_point::now(); |
| 3318 | |
| 3319 | dlog( "received a block from peer ${endpoint}, passing it to client", ("endpoint", originating_peer->get_remote_endpoint() ) ); |
| 3320 | std::set<peer_connection_ptr> peers_to_disconnect; |
| 3321 | std::string disconnect_reason; |
| 3322 | fc::oexception disconnect_exception; |
| 3323 | fc::oexception restart_sync_exception; |
| 3324 | try |
| 3325 | { |
| 3326 | // we can get into an intersting situation near the end of synchronization. We can be in |
| 3327 | // sync with one peer who is sending us the last block on the chain via a regular inventory |
| 3328 | // message, while at the same time still be synchronizing with a peer who is sending us the |
| 3329 | // block through the sync mechanism. Further, we must request both blocks because |
| 3330 | // we don't know they're the same (for the peer in normal operation, it has only told us the |
| 3331 | // message id, for the peer in the sync case we only known the block_id). |
| 3332 | fc::time_point message_validated_time; |
| 3333 | if (std::find(_most_recent_blocks_accepted.begin(), _most_recent_blocks_accepted.end(), |
| 3334 | block_message_to_process.block_id) == _most_recent_blocks_accepted.end()) |
| 3335 | { |
| 3336 | std::vector<fc::uint160_t> contained_transaction_message_ids; |
| 3337 | _delegate->handle_block(block_message_to_process, false, contained_transaction_message_ids); |
| 3338 | message_validated_time = fc::time_point::now(); |
| 3339 | ilog("Successfully pushed block ${num} (id:${id})", |
| 3340 | ("num", block_message_to_process.block.block_num()) |
| 3341 | ("id", block_message_to_process.block_id)); |
| 3342 | _most_recent_blocks_accepted.push_back(block_message_to_process.block_id); |
| 3343 | |
| 3344 | bool new_transaction_discovered = false; |
| 3345 | for (const item_hash_t& transaction_message_hash : contained_transaction_message_ids) |
| 3346 | { |
| 3347 | size_t items_erased = _items_to_fetch.get<item_id_index>().erase(item_id(trx_message_type, transaction_message_hash)); |
| 3348 | // there are two ways we could behave here: we could either act as if we received |
| 3349 | // the transaction outside the block and offer it to our peers, or we could just |
| 3350 | // forget about it (we would still advertise this block to our peers so they should |
| 3351 | // get the transaction through that mechanism). |
| 3352 | // We take the second approach, bring in the next if block to try the first approach |
| 3353 | //if (items_erased) |
| 3354 | //{ |
| 3355 | // new_transaction_discovered = true; |
| 3356 | // _new_inventory.insert(item_id(trx_message_type, transaction_message_hash)); |
| 3357 | //} |
| 3358 | } |
| 3359 | if (new_transaction_discovered) |
| 3360 | trigger_advertise_inventory_loop(); |
| 3361 | } |
| 3362 | else |
| 3363 | dlog( "Already received and accepted this block (presumably through sync mechanism), treating it as accepted" ); |
| 3364 | |
| 3365 | dlog( "client validated the block, advertising it to other peers" ); |
| 3366 | |
| 3367 | item_id block_message_item_id(core_message_type_enum::block_message_type, message_hash); |
| 3368 | uint32_t block_number = block_message_to_process.block.block_num(); |
| 3369 | fc::time_point_sec block_time = block_message_to_process.block.timestamp; |
| 3370 |
nothing calls this directly
no test coverage detected