Skip to content

Commit a8fb19f

Browse files
committed
drafted sections for all subsystems
1 parent 9d36d4e commit a8fb19f

File tree

1 file changed

+68
-44
lines changed

1 file changed

+68
-44
lines changed

bitswap/README.md

Lines changed: 68 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,67 +25,54 @@ Bitswap is the data trading module for IPFS. Its purpose is to request blocks fr
2525

2626
# Organization of this document
2727

28-
TODO
28+
- [Introduction](#introduction)
29+
- [Subsystems](#subsystems)
30+
- [Implementation Details](#implementation-details)
31+
- [API Spec](#api-spec)
32+
- [Implementations](#implementations)
2933

3034
# Introduction
3135

32-
Bitswap is IPFS's central block exchange protocol. It handles the requests made by an IPFS user, human, or application to fetch data blocks from the network. It interacts with other Bitswap agents present in other IPFS nodes, exchanging (fetching + serving) blocks as it needs.
36+
Bitswap is IPFSs central block exchange protocol. It handles the requests made by an IPFS user, human, or application to fetch data blocks from the network. It interacts with other Bitswap agents present in other IPFS nodes, exchanging (fetching + serving) blocks as it needs.
3337

34-
Bitswap is a message based protocol, as opposed to response-reply. All messages contain wantlists, or blocks. Upon receiving a wantlist, an IPFS node should consider sending out wanted blocks if it has them. Upon receiving blocks, the node should send out a notification called a 'Cancel' signifying that they no longer want the block. At the protocol level, Bitswap is very simple.
38+
Bitswap is a message based protocol, as opposed to response-reply. All messages contain wantlists, or blocks. Upon receiving a wantlist, an IPFS node should consider sending out wanted blocks if it has them. Upon receiving blocks, the node should send out a notification called a `Cancel` signifying that they no longer want the block. At the protocol level, Bitswap is very simple.
3539

3640
While Bitswap is a relatively simple protocol, a time- and memory- performant implementation requires that many details be carefully thought out. We aim to document these details here so that future implementers may build upon the knowledge gathered over the several iterations of Bitswap.
3741

38-
# Systems
42+
# Subsystems
3943

40-
![](https://cloud.githubusercontent.com/assets/1211152/21071077/4620387a-be4a-11e6-895c-aa8f2b06aa4e.png)
41-
42-
## Wantlist Manager
43-
44-
TODO
45-
46-
## Decision Engine
44+
There are two primary flows that Bitswap manages: requesting blocks from and serving blocks to peers. Block requests are primarily mediated by the want-manager, which tells our peers whenever we want a new block. Serving blocks is primarily handled by the decision engine, which decides how resources should be allocated among our peers.
4745

48-
TODO
46+
The subsystems involved in these flows are detailed in the following subsections.
4947

50-
### Strategies
48+
**TODO**: Update graphic
5149

52-
TODO: Link to strategy impl docs
53-
54-
## Message Queue
55-
56-
TODO
57-
58-
## Network
59-
60-
TODO
61-
62-
# Bitswap Flows
63-
64-
There are two primary flows that Bitswap manages: requesting blocks from and serving blocks to peers.
65-
66-
## Requesting Blocks
67-
68-
**TODO**: continue editing from here
69-
70-
Client requests for new blocks are handled by the wantlist manager. For every new block (or set of blocks) wanted, the `WantBlocks` method is invoked. The want manager then ensures that connected peers are notified of the new block that we want by sending the new entries to a message queue for each peer. The message queue will loop while there is work available and do the following:
50+
![](https://cloud.githubusercontent.com/assets/1211152/21071077/4620387a-be4a-11e6-895c-aa8f2b06aa4e.png)
7151

72-
1. Ensure it has a connection to its peer
73-
2. Grab the message to be sent
74-
3. Send it
52+
## Types
7553

76-
If new messages are added while the loop is in steps 1 or 3, the messages are combined into one to avoid having to keep an actual queue and send multiple messages. The same process occurs when the client receives a block and sends a cancel message for it.
54+
The following types are used in the descriptions of the Bitswap subsystems.
7755

78-
## Serving Blocks
56+
- `CID`: A [content-addressed identifier](https://github.com/ipld/cid) that refers to a particular `Block`.
57+
- `Peer`: Another Bitswap instance that we are connected to.
58+
- `Block`: A binary blob.
59+
- `Message`: A Bitswap message.
60+
- `Entry`: A wantlist entry that may be included in a Message when adding/removing a particular `CID` from our wantlist. Contains:
61+
- `CID` referring to a particular block.
62+
- `Priority` relative priority with which the user wants `CID` (relevant only if `Cancel` is not true.
63+
- `Cancel` is a boolean representing whether this `Entry` is meant to remove `CID` from our wantlist.
64+
- `Ledger`: A record of the aggregate data exchanged between two peers. Each peer stores one `Ledger` for each of their peers.
7965

80-
Internally, when a message with a wantlist is received, it is sent to the decision engine to be considered, and blocks that we have that are wanted are placed into the peer request queue. Any block we possess that is wanted by another peer has a task in the peer request queue created for it.
66+
### Bitswap Message
8167

82-
The peer request queue is a priority queue that sorts available tasks by some metric, currently, that metric is very simple and aims to fairly address the tasks of each other peer. More advanced decision logic will be implemented in the future.
68+
A single Bitswap message may contain any of the following content:
8369

84-
Task workers pull tasks to be done off of the queue, retreive the block to be sent, and send it off. The number of task workers is limited by a constant factor.
70+
1. The sender’s wantlist. This wantlist may either be the sender’s complete wantlist or just the changes to the sender’s wantlist that the receiver needs to know.
71+
2. Data blocks. These are meant to be blocks that the receiver has requested (i.e., blocks on that are on the receiver’s wantlist as far as the sender is aware at the time of sending).
8572

86-
# Wire Format
73+
#### Wire Format
8774

88-
Streams of [Bitswap messages, according to this protobuf](https://github.com/ipfs/go-ipfs/blob/master/exchange/bitswap/message/pb/message.proto):
75+
The wire format for Bitswap is simply a stream of Bitswap messages. The following protobuf describes the form of these messages.
8976

9077
```
9178
message Message {
@@ -105,16 +92,51 @@ message Message {
10592
}
10693
```
10794

95+
## Want-Manager
96+
97+
The want-manager handles requests for blocks. For a requested block, identified by `cid`, the `Bitswap.GetBlock(cid)` method is invoked. `Bitswap.GetBlock(cid)` requests `cid` from the network and, if the corresponding `Block` is received, returns it. More concretely, `Bitswap.GetBlock(cid)` adds `cid` to our wantlist. The want-manager then updates all peers with this addition by adding a new `Entry` to each peer’s message queue, who then may or may not respond with the desired block.
98+
99+
## Decision Engine
100+
101+
The decision engine decides how to allocate resources to peers. When a `Message` with a wantlist from a peer is received, the `Message` is sent to the decision engine. For every `CID` in the wantlist that we have the corresponding `Block` for, the block has a `Task` added to the peer’s `TaskQueue`. A `Task` is considered complete once the corresponding `Block` has been sent to the message queue for that peer.
102+
103+
The primary data structure in the decision engine is the peer request queue (`PRQ`). The `PRQ` adds peers to a weighted round-robin queue, where the weights are based on one or more peer-specific metrics. This is where Bitswap *strategies* come in. Currently, a `Strategy` is a function whose input is a peer’s `Ledger` and output is a weight for that peer. The peers are then served the `Task`s in their respective `TaskQueue`s. The amount of data each peer is served in a given round-robin round is determined by their relative weight in the queue. The in-progress Bitswap strategy implementation can be found [here](https://github.com/ipfs/research-bitswap/tree/docs/strategy_impl/strategy-impl). Further Bitswap strategy metrics and configuration interfaces are planned for the near future.
104+
105+
*Note: The Bitswap strategy implementations in the current releases of* `go-ipfs` *and* `js-ipfs` *do not conform to the description here as of the time of this writing.*
106+
107+
## Message Queue
108+
109+
Each active peer has an associated message queue. The message queue holds the next message to be sent to that peer. The message queues receive updates from two other subsystems:
110+
111+
1. Wantlist manager: When a `CID` is added or removed from our wantlist, we must update our peers – these wantlist updates are sent to all relevant peers’ message queues.
112+
2. Decision engine: When we have a block that a peer wants and the decision engine decides to send the block, we propagate the block to that peer’s message queue.
113+
114+
Task workers watch the message queues, dequeue a waiting message, and send it to the recipient.
115+
116+
## Network
117+
118+
The network is the abstraction representing all Bitswap peers that are connected to us by one or more hops. Bitswap messages flow in and out of the network. This is where a game-theoretical analysis of Bitswap becomes relevant – in an arbitrary network we must assume that all of our peers are rational and self-interested, and we act accordingly. Work along these lines can be found in the [research-bitswap respository](https://github.com/ipfs/research-bitswap), with a preliminary game-theoretical analysis currently in-progress [here](https://github.com/ipfs/research-bitswap/blob/docs/strategy_analysis/analysis/prelim_strategy_analysis.pdf).
119+
108120
# Implementation Details
109121

122+
## Coalescing Messages
123+
124+
When a message queue that already contains a Bitswap message receives another, the new message should be coalesced with the original to reduce the overhead of sending separate packets.
125+
126+
## Bitswap Sessions
127+
128+
**TODO**
129+
130+
**TODO**: Everything below must either be updated/integrated above, or removed
131+
110132
Also, make sure to read - <https://github.com/ipfs/go-ipfs/tree/master/exchange/bitswap#go-ipfs-implementation>
111133

112134
Implementation suggestions:
113135

114-
- maintain a peer set of "live partners"
136+
- maintain a peer set of live partners
115137
- protocol listener accept streams for partners to receive messages
116138
- protocol sender opens streams to partners to send messages
117-
- separate out a decision engine that selects which blocks to send to which partners, and at what time. (this is a bit tricky, but it's super easy to make as a whole if the engine is separated out)
139+
- separate out a decision engine that selects which blocks to send to which partners, and at what time. (this is a bit tricky, but its super easy to make as a whole if the engine is separated out)
118140

119141
Sender:
120142

@@ -172,6 +194,8 @@ bs.getBlock(multihash, (err, block) => {
172194

173195
# API Spec
174196

197+
**TODO**: Fill this in, may need some input from @diasdavid, @whyrusleeping
198+
175199
> **Will be written once it gets stable, by now, it still requires a ton of experimentation**
176200
177201
# Implementations

0 commit comments

Comments
 (0)