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.
> HasBlock right now is our way of announcing that we are providing a block, and also for sending that block to other peers that want it. It probably deserves a better name

Agreed. I think i named it. It's a bad name now, given `Has*` is a datastore method meaning something different. Perhaps `AddBlock`, `AddedBlock`, `ProcessBlock` ...

> Blocks received from the network are hashed when they become blocks (NB: NewBlock does this). The key is a byproduct of this transformation. 

Great! there was talk a while back of trusting what you get from the network, so just making sure we do hash.

> Datastore operations are expensive. After hashing, most of IPFS' time is spent in the datastore. So, it's worthwhile to consider optimizations to reduce datastore accesses.

I think by far the biggest optimizations may be an in-memory cache (not sure how leveldb works under the hood), and an index of what blocks are stored locally (blocks are immutable, so can avoid puting twice).

> Despite these facts, bitswap has been saddled with an awkward responsibility of adding blocks received from the network to the datastore. We're making an assumption that callers want this behavior, but is it really true? Blockservice is responsible for mediating client requests. It optimizes performance by consulting the datastore before consulting bitswap. blockservice should add received blocks to the datastore.

Dividing the responsibility is awkward. do note though that bitswap in the future may retrieve + store blocks for the sake of trading. (blocks not requested by the client). So it will need access to a blockstore. Maybe the correct thing to do is sink the full responsibilities into bitswap ("consult the datastore before making network requests," and "write to the datastore when the local client calls HasBlock").