Bithack

*BitHack* makes a few changes to the way our BitSwap implementation work. From an API standpoint, the biggest change is the addition of `GetBlocks`.  `GetBlock` has been changed to be a special case call of `GetBlocks`. When `GetBlocks` is called, the keys that are requested are sent to another goroutine through a channel, where the actual requests are handled.

When a set of keys are requested, BitSwap will add them all to the wantlist, and the find providers for the first key in the list. It will then send the wantlist to those found providers.
The main bitswap loop now contains a 'timeout ticker', when it ticks, bitswap will find providers for every single key left on the wantlist and send the wantlist out to them, this is the 'plan B' as we hope that our initial request succeeds, saving us the bandwidth. This operation could be optimized to ensure only sending wantlist to a peer once per tick.

`ReceiveMessage` also was changed. Previously it would *always* return a message, which looked to me like it would cause an infinite loop of messaging between a set of peers. Im surprised we never experienced anything bad because of it.

To take advantage of this new behaviour, I modified the DAGReader to use GetBlocks to retrieve blocks for reading.
Precisely.

Sequence numbers don't help because they can be faked. so can straight up acknowledgements. This problem goes all the way to Fair Exchange (a class of protocols for exchanging data without trusted third parties). An honest network failure is indistinguishable from an adversary exploit. In a non-secure setting, (which bitswap currently aims for) interaction is best effort. Adding sequence numbers complicates the protocol and doesn't improve security. Bitswap right now is intentionally underspecified in this regard to leave it up to the strategy to decide what to do. 

Perhaps the current bitswap spec should defer this decision to the strategy (i.e. present the two ledgers and the strategy decides.) An optimistic strategy could ignore ledger differences under some epsilon bandwidth, and zero out ledgers (or completely ignore a peer) when the disparity is significant.

there's also something to be said for never zeroing out ledgers and allowing different perspectives on the ledger. i.e. peers send each other the ledger they are operating with, but this is only informational and peers may opt to keep their own version, even if they disagree. (this better approaches the p2p exchange / market bitswap tries to model. reaching agreement on a shared account is itself a consensus problem.)