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.
By strategy I mean the strategy object that can be implemented by a third
party to change the behavior of bitswap.

On Wed, Nov 26, 2014, 6:06 PM Brian Tiger Chow <notifications@github.com>
wrote:

> In exchange/bitswap/strategy/interface.go:
>
> > @@ -29,4 +31,8 @@ type Strategy interface {
> >  	NumBytesSentTo(peer.Peer) uint64
> >
> >  	NumBytesReceivedFrom(peer.Peer) uint64
> > +
> > +	// Values determining bitswap behavioural patterns
> > +	GetBatchSize() int
> > +	GetRebroadcastDelay() time.Duration
>
> Strategy is becoming an overloaded term. That much is clear.
>
> @jbenet <https://github.com/jbenet>, I believe you mean to distinguish
> between the decision engine and implementation-specific configuration
> variables. Framed this way, the rebroadcast delays and batch sizes belong
> with maxProviders and bs.requestchan's channel buffer.
>
> @whyrusleeping <https://github.com/whyrusleeping>, if you believe these
> should be configurable at runtime, sure. I agree. We can definitely do
> that. Bitswap can expose configuration methods in its API as appropriate.
>
> However, remember the way we formulated a plan for persisting ledgers? The
> incidental configuration variables like rebroadcast delay don't really have
> a place in that plan. This is the what strategy, as formulated, is meant to
> capture:
>
> message Ledger {
>     enum Strategy {
>         NICE = 0;
>         STANDARD = 1; // as described in IPFS Draft 3 (name DRAFT_3?)
>     }
>     optional uint64 bytes_sent = 1 [default = 0];
>     optional uint64 bytes_received = 2 [default = 0];
>     optional uint64 first_exchange_unix_time = 3; // default?
>     optional uint64 last_exchange_unix_time = 4; // default?
>     optional uint64 exchange_count = 5 [default = 0];
>     optional Strategy strategy = 6 [default = STANDARD];
> }
>
> If I have misidentified the source of confusion, let me know.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/jbenet/go-ipfs/pull/386/files#r20976085>.
>