{"action":"closed","issue":{"url":"https://api.github.com/repos/jbenet/go-ipfs/issues/417","labels_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/417/labels{/name}","comments_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/417/comments","events_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/417/events","html_url":"https://github.com/jbenet/go-ipfs/issues/417","id":51267698,"number":417,"title":"Bitswap Rounds","user":{"login":"jbenet","id":138401,"avatar_url":"https://avatars.githubusercontent.com/u/138401?v=3","gravatar_id":"","url":"https://api.github.com/users/jbenet","html_url":"https://github.com/jbenet","followers_url":"https://api.github.com/users/jbenet/followers","following_url":"https://api.github.com/users/jbenet/following{/other_user}","gists_url":"https://api.github.com/users/jbenet/gists{/gist_id}","starred_url":"https://api.github.com/users/jbenet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbenet/subscriptions","organizations_url":"https://api.github.com/users/jbenet/orgs","repos_url":"https://api.github.com/users/jbenet/repos","events_url":"https://api.github.com/users/jbenet/events{/privacy}","received_events_url":"https://api.github.com/users/jbenet/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/jbenet/go-ipfs/labels/in+progress","name":"in progress","color":"ededed"}],"state":"closed","locked":false,"assignee":{"login":"whyrusleeping","id":1243164,"avatar_url":"https://avatars.githubusercontent.com/u/1243164?v=3","gravatar_id":"","url":"https://api.github.com/users/whyrusleeping","html_url":"https://github.com/whyrusleeping","followers_url":"https://api.github.com/users/whyrusleeping/followers","following_url":"https://api.github.com/users/whyrusleeping/following{/other_user}","gists_url":"https://api.github.com/users/whyrusleeping/gists{/gist_id}","starred_url":"https://api.github.com/users/whyrusleeping/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/whyrusleeping/subscriptions","organizations_url":"https://api.github.com/users/whyrusleeping/orgs","repos_url":"https://api.github.com/users/whyrusleeping/repos","events_url":"https://api.github.com/users/whyrusleeping/events{/privacy}","received_events_url":"https://api.github.com/users/whyrusleeping/received_events","type":"User","site_admin":false},"milestone":null,"comments":27,"created_at":"2014-12-08T08:13:48Z","updated_at":"2015-01-05T17:09:21Z","closed_at":"2015-01-05T17:09:21Z","body":"This doc describes how the Bitswap Protocol v1 should work.\r\n\r\nFor now, we assume an understanding of the goals and high level description. In time, this document will hopefully be self-contained. \r\n\r\nI describe here the _desired_ state. Not necessarily what we'll implement right away\r\n\r\n## Elements\r\n\r\nBitswap Concepts\r\n- `Peer` - other hosts we exchange data with\r\n- `Ledger` - containing peer-to-peer accounting\r\n- `Wantlist` - list of desired blocks\r\n- `Strategy` - pluggable decision making unit\r\n\r\nImplementation Details\r\n- `Client` - the client of bitswap (e.g. ipfs node)\r\n- `Message` - a bitswap message, outgoing or incoming\r\n- `Blockstore` - local block storage\r\n- `Available Bandwidth` - defined by `Client`\r\n- `Round` - an iteration of the protocol, within one host\r\n- `Allocation` - what to send to whom. decided on by Strategy, per Round. \r\n\r\ngo-ipfs specifics\r\n- `net.Service` - registered service, which sends + receives messages\r\n- `net.Handler` - request handler\r\n\r\nMessage looks like this:\r\n```proto\r\nmessage Message {\r\n\r\n  message Wantlist {\r\n\r\n    message Entry {\r\n      optional string block = 1; // the block key\r\n      optional int priority = 2; // the priority (normalized). default to 1\r\n      optional bool cancel = 3;  // whether this revokes an entry\r\n    }\r\n\r\n    repeated Entry entries = 1; // a list of wantlist entries\r\n    optional bool full = 2;     // whether this is the full wantlist. default to false\r\n  }\r\n\r\n  optional Wantlist wantlist = 1;\r\n  repeated bytes blocks = 2;\r\n}\r\n```\r\n\r\nHigh Level:\r\n- the core bitswap service employs two async workers:\r\n- the `RoundWorker` which handles rounds, allocations, and sending\r\n- the `ClientWorker` (need better name) which handles requests from `Client`\r\n- all incoming requests from `Peers` and `Client` pass information to the workers through channels. workers modify state, may issue outgoing requests, and send back responses.\r\n\r\nThe RoundWorker:\r\n- maintains a peer's Wantlist\r\n- iteratively performs rounds: \r\n  - call `(s *Strategy) GetAllocation(Ledgers, Wantlist, Available Bandwidth, Blockstore) *Allocation`\r\n  - send out blocks according to `Allocation`\r\n- (select on Wantlist update channel, and on round time interval?)\r\n\r\nNormally, we would let the data sending define the rounds (this makes it easier to use available bandwidth correctly), but our net system may buffer the msgs out and return before actually sending them (can see about removing this). So we may have to use timed intervals (0.25, 0.5, 1s ?) instead.\r\n\r\nExample of the RoundWorker\r\n\r\n![](https://www.evernote.com/shard/s198/sh/aa245160-2040-4570-b64e-4a5db02584b4/f3440bdd6c8f2d7d8df09b1f7745e608/deep/0/Pasted-Image-2014-12-07,-08-18.png)\r\n\r\nThe ClientWorker:\r\n- maintains local Wantlist\r\n- periodically rebroadcasts Wantlist (5-15s?)\r\n- sends out single Wantlist updates to other nodes\r\n- (select on local request channel, and on periodic rebroadcast)\r\n\r\nNote that `Message.Wantlist.Entry` has int priority. These are normalized, meaning that a priority is really: `p_i / sum(p_j for all p)`. We need it because sending a single WantlistEntry as an update is not able to convey where the priority is. Also, sorting is not able to express priority differences. Hence this change.\r\n\r\nAs Peer messages come in:\r\n- send peer wantlist updates to RoundWorker (over channel)\r\n- call HasBlock on blocks\r\n\r\nAs Client requests come in:\r\n- send local wantlist updates to ClientWorker (over channel)\r\n- return blocks promise (subscribe, send out requests etc)\r\n\r\n(WIP)"}}