Skip to content

Commit beff8d1

Browse files
committed
upgrade message to support bitswap 1.0.0 and 1.1.0 simultaneously, also
start the work on network support
1 parent 32e8997 commit beff8d1

File tree

8 files changed

+214
-58
lines changed

8 files changed

+214
-58
lines changed

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
},
3636
"homepage": "https://github.com/ipfs/js-ipfs-bitswap#readme",
3737
"devDependencies": {
38-
"aegir": "9.2.1",
38+
"aegir": "9.3.0",
3939
"buffer-loader": "0.0.1",
4040
"chai": "^3.5.0",
4141
"fs-pull-blob-store": "^0.4.1",
4242
"idb-pull-blob-store": "^0.5.1",
4343
"interface-pull-blob-store": "^0.6.0",
44-
"ipfs-repo": "^0.11.1",
45-
"libp2p-ipfs-nodejs": "^0.16.4",
44+
"ipfs-repo": "^0.11.2",
45+
"libp2p-ipfs-nodejs": "^0.17.0",
4646
"lodash": "^4.17.2",
4747
"multiaddr": "^2.1.1",
4848
"ncp": "^2.0.0",
@@ -54,19 +54,20 @@
5454
},
5555
"dependencies": {
5656
"async": "^2.1.4",
57-
"cids": "^0.3.4",
58-
"debug": "^2.3.3",
57+
"cids": "^0.3.5",
58+
"debug": "^2.4.4",
5959
"heap": "^0.2.6",
60-
"ipfs-block": "^0.5.1",
60+
"ipfs-block": "^0.5.3",
6161
"lodash.debounce": "^4.0.8",
6262
"lodash.isequalwith": "^4.4.0",
63-
"multihashes": "^0.3.0",
63+
"multihashes": "^0.3.1",
6464
"protocol-buffers": "^3.2.1",
6565
"pull-defer": "^0.2.2",
6666
"pull-length-prefixed": "^1.2.0",
6767
"pull-paramap": "^1.2.1",
6868
"pull-pushable": "^2.0.1",
69-
"pull-stream": "^3.5.0"
69+
"pull-stream": "^3.5.0",
70+
"varint-decoder": "^0.1.1"
7071
},
7172
"contributors": [
7273
"David Dias <[email protected]>",

src/components/want-manager/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ module.exports = class WantManager {
135135
// resend entirew wantlist every so often
136136
const fullwantlist = new Message(true)
137137
for (let entry of this.wantlist.entries()) {
138-
fullwantlist.addEntry(entry[1].key, entry[1].priority)
138+
fullwantlist.addEntry(entry[1].cid, entry[1].priority)
139139
}
140140

141141
this.peers.forEach((p) => {

src/types/message/index.js

Lines changed: 93 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const isEqualWith = require('lodash.isequalwith')
66
const assert = require('assert')
77
const map = require('async/map')
88
const CID = require('cids')
9+
const codecName = require('multicodec/src/name-table')
10+
const vd = require('varint-decoder')
911

1012
const pbm = protobuf(require('./message.proto'))
1113
const Entry = require('./entry')
@@ -23,7 +25,7 @@ class BitswapMessage {
2325
}
2426

2527
addEntry (cid, priority, cancel) {
26-
assert(CID.isCID(cid), 'must be a valid cid')
28+
assert(cid && CID.isCID(cid), 'must be a valid cid')
2729
const cidStr = cid.toBaseEncodedString()
2830

2931
const entry = this.wantlist.get(cidStr)
@@ -80,7 +82,32 @@ class BitswapMessage {
8082
* version 1.1.0
8183
*/
8284
serializeToBitswap110 () {
83-
// TODO
85+
const msg = {
86+
wantlist: {
87+
entries: Array.from(this.wantlist.values()).map((entry) => {
88+
return {
89+
block: entry.cid.buffer, // cid
90+
priority: Number(entry.priority),
91+
cancel: Boolean(entry.cancel)
92+
}
93+
})
94+
},
95+
payload: []
96+
}
97+
98+
if (this.full) {
99+
msg.wantlist.full = true
100+
}
101+
102+
this.blocks.forEach((block, cidStr) => {
103+
const cid = new CID(cidStr)
104+
msg.payload.push({
105+
prefix: cid.prefix,
106+
data: block.data
107+
})
108+
})
109+
110+
return pbm.Message.encode(msg)
84111
}
85112

86113
equals (other) {
@@ -108,32 +135,76 @@ class BitswapMessage {
108135
}
109136

110137
BitswapMessage.deserialize = (raw, callback) => {
111-
const decoded = pbm.Message.decode(raw)
112-
const msg = new BitswapMessage(decoded.wantlist.full)
138+
let decoded
139+
try {
140+
decoded = pbm.Message.decode(raw)
141+
} catch (err) {
142+
return setImmediate(() => callback(err))
143+
}
144+
145+
const isFull = (decoded.wantlist && decoded.wantlist.full) || false
146+
const msg = new BitswapMessage(isFull)
113147

114-
decoded.wantlist.entries.forEach((entry) => {
115-
// note: entry.block is the CID here
116-
const cid = new CID(entry.block)
117-
msg.addEntry(cid, entry.priority, entry.cancel)
118-
})
148+
if (decoded.wantlist) {
149+
decoded.wantlist.entries.forEach((entry) => {
150+
// note: entry.block is the CID here
151+
const cid = new CID(entry.block)
152+
msg.addEntry(cid, entry.priority, entry.cancel)
153+
})
154+
}
119155

156+
// Bitswap 1.0.0
120157
// decoded.blocks are just the byte arrays
121-
map(decoded.blocks, (b, cb) => {
122-
const block = new Block(b)
123-
block.key((err, key) => {
158+
if (decoded.blocks.length > 0) {
159+
map(decoded.blocks, (b, cb) => {
160+
const block = new Block(b)
161+
block.key((err, key) => {
162+
if (err) {
163+
return cb(err)
164+
}
165+
const cid = new CID(key)
166+
msg.addBlock(cid, block)
167+
cb()
168+
})
169+
}, (err) => {
124170
if (err) {
125-
return cb(err)
171+
return callback(err)
126172
}
127-
const cid = new CID(key)
128-
msg.addBlock(cid, block)
129-
cb()
173+
callback(null, msg)
130174
})
131-
}, (err) => {
132-
if (err) {
133-
return callback(err)
134-
}
135-
callback(null, msg)
136-
})
175+
return
176+
}
177+
178+
// Bitswap 1.1.0
179+
if (decoded.payload.length > 0) {
180+
map(decoded.payload, (p, cb) => {
181+
if (!p.prefix || !p.data) {
182+
cb()
183+
}
184+
console.log(p)
185+
const values = vd(p.prefix)
186+
const cidVersion = values[0]
187+
const multicodec = values[1]
188+
const hashAlg = values[2]
189+
// const hashLen = values[3] // We haven't need to use this so far
190+
const block = new Block(p.data)
191+
block.key(hashAlg, (err, multihash) => {
192+
if (err) {
193+
return cb(err)
194+
}
195+
const cid = new CID(cidVersion, codecName[multicodec.toString('16')], multihash)
196+
msg.addBlock(cid, block)
197+
cb()
198+
})
199+
}, (err) => {
200+
if (err) {
201+
return callback(err)
202+
}
203+
callback(null, msg)
204+
})
205+
return
206+
}
207+
callback(null, msg)
137208
}
138209

139210
BitswapMessage.Entry = Entry

src/types/message/message.proto.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ module.exports = `
66
message Message {
77
message Wantlist {
88
message Entry {
9-
// changed from string to bytes,
10-
// because it makes a difference
11-
// in JavaScript
9+
// changed from string to bytes, it makes a difference in JavaScript
1210
optional bytes block = 1; // the block cid (cidV0 in bitswap 1.0.0, cidV1 in bitswap 1.1.0)
1311
optional int32 priority = 2; // the priority (normalized). default to 1
1412
optional bool cancel = 3; // whether this revokes an entry

test/components/network/network.node.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ describe('network', () => {
141141
})
142142
})
143143

144-
it('._receiveMessage success', (done) => {
144+
it('._receiveMessage success from Bitswap 1.0.0', (done) => {
145145
const msg = new Message(true)
146146
const b1 = blocks[0]
147147
const b2 = blocks[1]
@@ -184,6 +184,10 @@ describe('network', () => {
184184
})
185185
})
186186

187+
it.skip('._receiveMessage success from Bitswap 1.1.0', (done) => {})
188+
it.skip('._sendMessage on Bitswap 1.0.0', (done) => {})
189+
it.skip('._sendMessage on Bitswap 1.1.0', (done) => {})
190+
187191
it('.sendMessage', (done) => {
188192
const msg = new Message(true)
189193
const b1 = blocks[0]
Binary file not shown.
Binary file not shown.

test/types/message.spec.js

Lines changed: 105 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ const map = require('async/map')
88
const pbm = protobuf(require('../../src/types/message/message.proto'))
99
const CID = require('cids')
1010

11+
const loadFixture = require('aegir/fixtures')
12+
const testDataPath = '../test-data/serialized-from-go'
13+
const rawMessageFullWantlist = loadFixture(__dirname, testDataPath + '/bitswap110-message-full-wantlist')
14+
const rawMessageOneBlock = loadFixture(__dirname, testDataPath + '/bitswap110-message-one-block')
15+
1116
const BitswapMessage = require('../../src/types/message')
1217

1318
describe('BitswapMessage', () => {
@@ -39,47 +44,103 @@ describe('BitswapMessage', () => {
3944
})
4045
})
4146

42-
it('.serializeToBitswap100', (done) => {
47+
it('.serializeToBitswap100', () => {
4348
const block = blocks[1]
4449
const cid = cids[1]
45-
const m = new BitswapMessage(true)
46-
m.addBlock(cid, block)
47-
expect(pbm.Message.decode(m.serializeToBitswap100()).blocks)
48-
.to.be.eql([block.data])
49-
done()
50+
const msg = new BitswapMessage(true)
51+
msg.addBlock(cid, block)
52+
const serialized = msg.serializeToBitswap100()
53+
expect(pbm.Message.decode(serialized).blocks).to.eql([block.data])
5054
})
5155

52-
it('.deserialize', (done) => {
53-
const cid = cids[0]
56+
it('.serializeToBitswap110', () => {
57+
const block = blocks[1]
58+
const cid = cids[1]
59+
const msg = new BitswapMessage(true)
60+
msg.addBlock(cid, block)
61+
62+
const serialized = msg.serializeToBitswap110()
63+
const decoded = pbm.Message.decode(serialized)
64+
65+
expect(decoded.payload[0].data).to.eql(block.data)
66+
})
67+
68+
it('.deserialize a Bitswap100 Message', (done) => {
69+
const cid0 = cids[0]
70+
const cid1 = cids[1]
71+
const cid2 = cids[2]
72+
73+
const b1 = blocks[1]
74+
const b2 = blocks[2]
75+
5476
const raw = pbm.Message.encode({
5577
wantlist: {
5678
entries: [{
57-
block: cid.buffer,
79+
block: cid0.buffer,
5880
cancel: false
5981
}],
6082
full: true
6183
},
6284
blocks: [
63-
new Buffer('hello'),
64-
new Buffer('world')
85+
b1.data,
86+
b2.data
6587
]
6688
})
6789

68-
BitswapMessage.deserialize(raw, (err, protoMessage) => {
90+
BitswapMessage.deserialize(raw, (err, msg) => {
6991
expect(err).to.not.exist
70-
expect(protoMessage.full).to.equal(true)
71-
expect(Array.from(protoMessage.wantlist))
72-
.to.be.eql([[
73-
cid.toBaseEncodedString(),
74-
new BitswapMessage.Entry(cid, 0, false)
92+
expect(msg.full).to.equal(true)
93+
expect(Array.from(msg.wantlist))
94+
.to.eql([[
95+
cid0.toBaseEncodedString(),
96+
new BitswapMessage.Entry(cid0, 0, false)
7597
]])
7698

77-
const b1 = blocks[1]
78-
const b2 = blocks[2]
79-
const cid1 = cids[1]
80-
const cid2 = cids[2]
99+
expect(Array.from(msg.blocks).map((b) => [b[0], b[1].data]))
100+
.to.eql([
101+
[cid1.toBaseEncodedString(), b1.data],
102+
[cid2.toBaseEncodedString(), b2.data]
103+
])
81104

82-
expect(Array.from(protoMessage.blocks).map((b) => [b[0], b[1].data]))
105+
done()
106+
})
107+
})
108+
109+
it('.deserialize a Bitswap110 Message', (done) => {
110+
const cid0 = cids[0]
111+
const cid1 = cids[1]
112+
const cid2 = cids[2]
113+
114+
const b1 = blocks[1]
115+
const b2 = blocks[2]
116+
117+
const raw = pbm.Message.encode({
118+
wantlist: {
119+
entries: [{
120+
block: cid0.buffer,
121+
cancel: false
122+
}],
123+
full: true
124+
},
125+
payload: [{
126+
data: b1.data,
127+
prefix: cid1.prefix
128+
}, {
129+
data: b2.data,
130+
prefix: cid2.prefix
131+
}]
132+
})
133+
134+
BitswapMessage.deserialize(raw, (err, msg) => {
135+
expect(err).to.not.exist
136+
expect(msg.full).to.equal(true)
137+
expect(Array.from(msg.wantlist))
138+
.to.eql([[
139+
cid0.toBaseEncodedString(),
140+
new BitswapMessage.Entry(cid0, 0, false)
141+
]])
142+
143+
expect(Array.from(msg.blocks).map((b) => [b[0], b[1].data]))
83144
.to.eql([
84145
[cid1.toBaseEncodedString(), b1.data],
85146
[cid2.toBaseEncodedString(), b2.data]
@@ -193,6 +254,27 @@ describe('BitswapMessage', () => {
193254
})
194255
})
195256

196-
it.skip('bitswap 1.1.0 message', (done) => {})
257+
describe.skip('bitswap 1.1.0 message', () => {
258+
// TODO check with whyrusleeping the quality of the raw protobufs
259+
// deserialization is just failing on the first and the second has a
260+
// payload but empty
261+
it('full wantlist message', (done) => {
262+
BitswapMessage.deserialize(rawMessageFullWantlist, (err, message) => {
263+
expect(err).to.not.exist
264+
// TODO
265+
// check the deserialised message
266+
done()
267+
})
268+
})
269+
270+
it('one block message', (done) => {
271+
BitswapMessage.deserialize(rawMessageOneBlock, (err, message) => {
272+
expect(err).to.not.exist
273+
// TODO
274+
// check the deserialised message
275+
done()
276+
})
277+
})
278+
})
197279
})
198280
})

0 commit comments

Comments
 (0)