Implement inv_vect, inv
This commit is contained in:
parent
ec616a0151
commit
73d2ad393a
|
@ -14,7 +14,7 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/
|
||||||
|
|
||||||
## Feature matrix (both Browser and Node)
|
## Feature matrix (both Browser and Node)
|
||||||
|
|
||||||
- [x] crypto
|
- [x] Crypto
|
||||||
- [x] SHA-512
|
- [x] SHA-512
|
||||||
- [x] SHA-256
|
- [x] SHA-256
|
||||||
- [x] RIPEMD-160
|
- [x] RIPEMD-160
|
||||||
|
@ -31,6 +31,7 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/
|
||||||
- [x] var_str
|
- [x] var_str
|
||||||
- [x] var_int_list
|
- [x] var_int_list
|
||||||
- [x] net_addr
|
- [x] net_addr
|
||||||
|
- [x] inv_vect
|
||||||
- [x] encrypted
|
- [x] encrypted
|
||||||
- [x] message encodings
|
- [x] message encodings
|
||||||
- [x] service features
|
- [x] service features
|
||||||
|
@ -39,7 +40,7 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/
|
||||||
- [x] version
|
- [x] version
|
||||||
- [x] verack
|
- [x] verack
|
||||||
- [x] addr
|
- [x] addr
|
||||||
- [ ] inv
|
- [x] inv
|
||||||
- [ ] getdata
|
- [ ] getdata
|
||||||
- [ ] error
|
- [ ] error
|
||||||
- [ ] object
|
- [ ] object
|
||||||
|
|
|
@ -12,7 +12,7 @@ var UserAgent = require("./user-agent");
|
||||||
var util = require("./util");
|
var util = require("./util");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version message.
|
* `version` message.
|
||||||
* @see {@link https://bitmessage.org/wiki/Protocol_specification#version}
|
* @see {@link https://bitmessage.org/wiki/Protocol_specification#version}
|
||||||
* @namespace
|
* @namespace
|
||||||
*/
|
*/
|
||||||
|
@ -99,7 +99,7 @@ exports.version = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Addresses message. Provide information on known nodes of the network.
|
* `addr` message. Provide information on known nodes of the network.
|
||||||
* @see {@link https://bitmessage.org/wiki/Protocol_specification#addr}
|
* @see {@link https://bitmessage.org/wiki/Protocol_specification#addr}
|
||||||
* @namespace
|
* @namespace
|
||||||
*/
|
*/
|
||||||
|
@ -138,3 +138,45 @@ exports.addr = {
|
||||||
return Buffer.concat([structs.var_int.encode(addrs.length), addrsBuf]);
|
return Buffer.concat([structs.var_int.encode(addrs.length), addrsBuf]);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `inv` message. Allows a node to advertise its knowledge of one or
|
||||||
|
* more objects.
|
||||||
|
* @see {@link https://bitmessage.org/wiki/Protocol_specification#inv}
|
||||||
|
* @namespace
|
||||||
|
*/
|
||||||
|
exports.inv = {
|
||||||
|
/**
|
||||||
|
* Decode `inv` payload.
|
||||||
|
* @param {Buffer} buf - Buffer that starts with encoded `inv` payload
|
||||||
|
* @return {Object} Decoded `inv` structure.
|
||||||
|
*/
|
||||||
|
decode: function(buf) {
|
||||||
|
var decoded = structs.var_int.decode(buf);
|
||||||
|
var listLength = decoded.value;
|
||||||
|
assert(listLength <= 50000, "Too many inventory entires");
|
||||||
|
var length = decoded.length + listLength * 32;
|
||||||
|
assert(buf.length >= length, "Buffer is too small");
|
||||||
|
var rest = decoded.rest;
|
||||||
|
var inventory = new Array(listLength);
|
||||||
|
for (var i = 0; i < listLength; i++) {
|
||||||
|
inventory[i] = rest.slice(i*32, (i+1)*32);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
inventory: inventory,
|
||||||
|
// Real data length.
|
||||||
|
length: length,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode `inv` payload.
|
||||||
|
* @param {Buffer[]} inventory - Inventory vectors (encoded)
|
||||||
|
* @return {Buffer} Encoded `inv` payload.
|
||||||
|
*/
|
||||||
|
encode: function(inventory) {
|
||||||
|
assert(inventory.length <= 50000, "Too many inventory entires");
|
||||||
|
var invBuf = Buffer.concat(inventory);
|
||||||
|
return Buffer.concat([structs.var_int.encode(inventory.length), invBuf]);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -417,6 +417,23 @@ exports.net_addr = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inventory vector.
|
||||||
|
* @see {@link https://bitmessage.org/wiki/Protocol_specification#Inventory_Vectors}
|
||||||
|
* @namespace
|
||||||
|
*/
|
||||||
|
// Only encode operation is defined because decode is impossible.
|
||||||
|
exports.inv_vect = {
|
||||||
|
/**
|
||||||
|
* Encode inventory vector.
|
||||||
|
* @param {Buffer} buf - Payload to calculate inventory vector for
|
||||||
|
* @return {Buffer} Encoded `inv_vect`.
|
||||||
|
*/
|
||||||
|
encode: function(buf) {
|
||||||
|
return bmcrypto.sha512(bmcrypto.sha512(buf)).slice(0, 32);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
var SECP256K1_TYPE = 714;
|
var SECP256K1_TYPE = 714;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
36
test.js
36
test.js
|
@ -12,6 +12,7 @@ var var_int = structs.var_int;
|
||||||
var var_str = structs.var_str;
|
var var_str = structs.var_str;
|
||||||
var var_int_list = structs.var_int_list;
|
var var_int_list = structs.var_int_list;
|
||||||
var net_addr = structs.net_addr;
|
var net_addr = structs.net_addr;
|
||||||
|
var inv_vect = structs.inv_vect;
|
||||||
var encrypted = structs.encrypted;
|
var encrypted = structs.encrypted;
|
||||||
var messageEncodings = structs.messageEncodings;
|
var messageEncodings = structs.messageEncodings;
|
||||||
var serviceFeatures = structs.serviceFeatures;
|
var serviceFeatures = structs.serviceFeatures;
|
||||||
|
@ -19,6 +20,7 @@ var pubkeyFeatures = structs.pubkeyFeatures;
|
||||||
var messages = bitmessage.messages;
|
var messages = bitmessage.messages;
|
||||||
var version = messages.version;
|
var version = messages.version;
|
||||||
var addr = messages.addr;
|
var addr = messages.addr;
|
||||||
|
var inv = messages.inv;
|
||||||
var WIF = bitmessage.WIF;
|
var WIF = bitmessage.WIF;
|
||||||
var POW = bitmessage.POW;
|
var POW = bitmessage.POW;
|
||||||
var Address = bitmessage.Address;
|
var Address = bitmessage.Address;
|
||||||
|
@ -225,7 +227,13 @@ describe("Common structures", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Encrypted", function() {
|
describe("inv_vect", function() {
|
||||||
|
it("should encode", function() {
|
||||||
|
expect(inv_vect.encode("test").toString("hex")).to.equal("faadcaf60afd35dfcdb5e9ea0d0a0531f6338c62187cff37a1efe11f1d41a348");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("encrypted", function() {
|
||||||
it("should encode and decode", function() {
|
it("should encode and decode", function() {
|
||||||
var iv = Buffer(16);
|
var iv = Buffer(16);
|
||||||
var ephemPublicKey = Buffer(65);
|
var ephemPublicKey = Buffer(65);
|
||||||
|
@ -249,7 +257,7 @@ describe("Common structures", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Message encodings", function() {
|
describe("message encodings", function() {
|
||||||
it("should decode", function() {
|
it("should decode", function() {
|
||||||
expect(messageEncodings.decode(Buffer([2])).value).to.equal(messageEncodings.SIMPLE);
|
expect(messageEncodings.decode(Buffer([2])).value).to.equal(messageEncodings.SIMPLE);
|
||||||
});
|
});
|
||||||
|
@ -259,7 +267,7 @@ describe("Common structures", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Service features", function() {
|
describe("service features", function() {
|
||||||
it("should decode", function() {
|
it("should decode", function() {
|
||||||
expect(serviceFeatures.decode(Buffer("0000000000000001", "hex"))).to.have.members([serviceFeatures.NODE_NETWORK]);
|
expect(serviceFeatures.decode(Buffer("0000000000000001", "hex"))).to.have.members([serviceFeatures.NODE_NETWORK]);
|
||||||
});
|
});
|
||||||
|
@ -270,7 +278,7 @@ describe("Common structures", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Pubkey features", function() {
|
describe("pubkey features", function() {
|
||||||
it("should decode", function() {
|
it("should decode", function() {
|
||||||
expect(pubkeyFeatures.decode(Buffer("c0000000", "hex"))).to.have.members([pubkeyFeatures.DOES_ACK, pubkeyFeatures.INCLUDE_DESTINATION]);
|
expect(pubkeyFeatures.decode(Buffer("c0000000", "hex"))).to.have.members([pubkeyFeatures.DOES_ACK, pubkeyFeatures.INCLUDE_DESTINATION]);
|
||||||
});
|
});
|
||||||
|
@ -326,6 +334,24 @@ describe("Message types", function() {
|
||||||
expect(addr.decode.bind(null, var_int.encode(2000))).to.throw(/too many/i);
|
expect(addr.decode.bind(null, var_int.encode(2000))).to.throw(/too many/i);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("inv", function() {
|
||||||
|
it("should encode and decode", function() {
|
||||||
|
var vect1 = inv_vect.encode(Buffer("test"));
|
||||||
|
var vect2 = inv_vect.encode(Buffer("test2"));
|
||||||
|
var inventory = [vect1, vect2];
|
||||||
|
var res = inv.decode(inv.encode(inventory));
|
||||||
|
expect(res.inventory.length).to.equal(2);
|
||||||
|
expect(bufferEqual(res.inventory[0], vect1)).to.be.true;
|
||||||
|
expect(bufferEqual(res.inventory[1], vect2)).to.be.true;
|
||||||
|
expect(res.length).to.equal(65);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't encode/decode more than 1000 entires", function() {
|
||||||
|
expect(inv.encode.bind(null, Array(60000))).to.throw(/too many/i);
|
||||||
|
expect(inv.decode.bind(null, var_int.encode(60000))).to.throw(/too many/i);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("WIF", function() {
|
describe("WIF", function() {
|
||||||
|
@ -447,7 +473,7 @@ describe("High-level classes", function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("User Agent", function() {
|
describe("UserAgent", function() {
|
||||||
var pybm = {name: "PyBitmessage", version: "0.4.4"};
|
var pybm = {name: "PyBitmessage", version: "0.4.4"};
|
||||||
var bnode = {name: "bitchan-node", version: "0.0.1"};
|
var bnode = {name: "bitchan-node", version: "0.0.1"};
|
||||||
var bweb = {name: "bitchan-web"};
|
var bweb = {name: "bitchan-web"};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user