BulkSync BlockFetch implementation for Genesis
This pull request implements a BlockFetch logic to use when synchronizing peers with Genesis.
BlockFetch needs to penalize peers that are slow enough to delay syncing in order to fend from attacks targeting the synchronizing nodes.
The penalization consists in switching the serving peer when blocks are in flight long enough that the syncing node is idle while waiting for more blocks to validate.
Switching peers, in turn, requires organizing peers in a queue, where blocks are retrieved from the first peer in the queue that can serve them, and any time a peer is penalized, it is moved to the end of the queue.
Most of the implementation is in the first commit where the implementation of BulkSync mode is replaced. Probably the best file to approach the implementation is ouroboros-network/src/Ouroboros/Network/BlockFetch/Decision/BulkSync.hs. There are supporting commits to split large modules into smaller ones, and to update the tests related to the BulkSync mode.
I force-pushed a rehashing of the changes that preserves the old BulkSync mode, which the network team suggested in the last review call.