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.
> verify blocks (yes, they need to be hashed to ensure they match the key)

Blocks received from the network are hashed when they become blocks (NB: `NewBlock` does this). The key is a _byproduct_ of this transformation. Thus, we don't make any assumptions about what key a block is supposed to satisfy. We treat the contents of the block as the source of truth. A bad block results in an unrecognized key. This is true wherever `NewBlock` is used.

> this sequence of operations should be its own function

it is*. that's `HasBlock`

\* NB: these steps are omitted in HasBlock:

- `datastore.Put` because we assume the client has already done so. I would make the argument that bitswap should not write to the datastore at all.
- `notifications.Publish` because it would be odd for the local node to call `GetBlocks(foo)` and then call `HasBlock(foo)` right after. In hindsight, since Publish has been shown to be a relatively cheap operation, I do not believe it is worthwhile to continue with this assumption. `HasBlocks` ought to call `Publish`

With these two amendments, `HasBlock` becomes the only function that needs to be called.

> hasBlock. (actually, why is this here? pls document it as at first glance it looks vestigial and I'd probably remove it in passing)

`HasBlock` is bitswap's public method that the local node calls when it wants to let the network know that it has a block. see above

**bitswap's awkward relationship with its datastore**

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.

Now:

* bitswap _doesn't_ consult the datastore before making network requests. _Why?_ because bitswap assumes the local caller has access to the datastore and the caller knows the block isn't there.
* when the local client calls `HasBlock`, bitswap _doesn't_ write to the datastore because it assumes the caller has already written the data to the datastore.

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.



Overall, it is probably better for bitswap to treat the datastore as a one-way component. To make this clear, I propose we provide bitswap with a limited interface:
``` go
type Blocksource interface {
  Get(u.Key) *blocks.Block, error
}
```

> How did bitswap end up with a datastore in the first place? 

It needs to access blocks for bartering purposes.

**action items**
To keep things moving, I propose the following action items.

- [ ] decide whether bitswap should ever write to the datastore. I will provide a change in behavior as a PR. you guys can decide whether you agree and would like to merge it into this.
- [ ] add `notifications.Publish` to `HasBlock`. I'll add this to this PR.
- [ ] rename `HasBlock`. It's up to you guys to decide on a new name.