Some bitfields refactoring

This commit is contained in:
Kagami Hiiragi 2015-01-19 01:09:17 +03:00
parent 5d812eba47
commit dd7d4315c2
4 changed files with 30 additions and 27 deletions

View File

@ -11,6 +11,7 @@ var bufferEqual = require("buffer-equal");
var bs58 = require("bs58"); var bs58 = require("bs58");
var assert = require("./util").assert; var assert = require("./util").assert;
var var_int = require("./structs").var_int; var var_int = require("./structs").var_int;
var pubkeyBitfield = require("./structs").pubkeyBitfield;
var bmcrypto = require("./crypto"); var bmcrypto = require("./crypto");
/** /**
@ -28,9 +29,13 @@ function Address(opts) {
this.version = popkey(opts, "version") || 4; this.version = popkey(opts, "version") || 4;
assert(this.version <= 4, "Version too high"); assert(this.version <= 4, "Version too high");
assert(this.version >= 1, "Version too low"); assert(this.version >= 1, "Version too low");
this.stream = popkey(opts, "stream") || 1;
// Merge remained values. // Merge remained values.
objectAssign(this, opts); objectAssign(this, opts);
this.stream = this.stream || 1;
if (!this.pubkeyFeatures) {
// Fill up default features.
this.pubkeyFeatures = pubkeyBitfield.encode([pubkeyBitfield.DOES_ACK]);
}
} }
/** /**

View File

@ -33,7 +33,7 @@ exports.version = {
// 4 + 8 + 8 + 26 + 26 + 8 + (1+) + (1+) // 4 + 8 + 8 + 26 + 26 + 8 + (1+) + (1+)
assert(buf.length >= 82, "Buffer is too small"); assert(buf.length >= 82, "Buffer is too small");
var protoVersion = buf.readUInt32BE(0, true); var protoVersion = buf.readUInt32BE(0, true);
var services = structs.serviceFeatures.decode(buf.slice(4, 12)); var services = structs.servicesBitfield.decode(buf.slice(4, 12));
var time = util.readTime64BE(buf, 12); var time = util.readTime64BE(buf, 12);
var short = {short: true}; var short = {short: true};
var addrRecv = structs.net_addr.decode(buf.slice(20, 46), short); var addrRecv = structs.net_addr.decode(buf.slice(20, 46), short);
@ -67,7 +67,7 @@ exports.version = {
*/ */
encode: function(opts) { encode: function(opts) {
// Deal with default options. // Deal with default options.
var services = opts.services || [structs.serviceFeatures.NODE_NETWORK]; var services = opts.services || [structs.servicesBitfield.NODE_NETWORK];
var time = opts.time || new Date(); var time = opts.time || new Date();
var nonce = opts.nonce || exports.version.NONCE; var nonce = opts.nonce || exports.version.NONCE;
assert(nonce.length === 8, "Bad nonce"); assert(nonce.length === 8, "Bad nonce");
@ -90,7 +90,7 @@ exports.version = {
}); });
return Buffer.concat([ return Buffer.concat([
protoVersion, protoVersion,
structs.serviceFeatures.encode(services), structs.servicesBitfield.encode(services),
util.writeTime64BE(null, time), util.writeTime64BE(null, time),
addrRecv, addrRecv,
addrFrom, addrFrom,

View File

@ -379,7 +379,7 @@ exports.net_addr = {
res.stream = buf.readUInt32BE(8, true); res.stream = buf.readUInt32BE(8, true);
buf = buf.slice(12); buf = buf.slice(12);
} }
res.services = serviceFeatures.decode(buf.slice(0, 8)); res.services = servicesBitfield.decode(buf.slice(0, 8));
res.host = inet_ntop(buf.slice(8, 24)); res.host = inet_ntop(buf.slice(8, 24));
res.port = buf.readUInt16BE(24, true); res.port = buf.readUInt16BE(24, true);
return res; return res;
@ -409,8 +409,8 @@ exports.net_addr = {
buf.writeUInt32BE(stream, 8); buf.writeUInt32BE(stream, 8);
shift = 12; shift = 12;
} }
var services = opts.services || [serviceFeatures.NODE_NETWORK]; var services = opts.services || [servicesBitfield.NODE_NETWORK];
serviceFeatures.encode(services).copy(buf, shift); servicesBitfield.encode(services).copy(buf, shift);
inet_pton(opts.host).copy(buf, shift + 8); inet_pton(opts.host).copy(buf, shift + 8);
buf.writeUInt16BE(opts.port, shift + 24); buf.writeUInt16BE(opts.port, shift + 24);
return buf; return buf;
@ -531,21 +531,19 @@ var bitfield = function(size) {
}; };
/** /**
* Service bitfield features. Implements encoding/decoding for a 8-byte * Services bitfield features.
* buffer object.
* @see {@link https://bitmessage.org/wiki/Protocol_specification#version} * @see {@link https://bitmessage.org/wiki/Protocol_specification#version}
* @namespace * @namespace
* @static * @static
*/ */
// TODO(Kagami): Document methods. // TODO(Kagami): Document methods.
var serviceFeatures = exports.serviceFeatures = objectAssign(bitfield(64), { var servicesBitfield = exports.servicesBitfield = objectAssign(bitfield(64), {
/** This is a normal network node. */ /** This is a normal network node. */
NODE_NETWORK: 0, NODE_NETWORK: 0,
}); });
/** /**
* Pubkey bitfield features. Implements encoding/decoding for a 4-byte * Pubkey bitfield features.
* buffer object.
* @see {@link https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features} * @see {@link https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features}
* @namespace * @namespace
*/ */
@ -553,7 +551,7 @@ var serviceFeatures = exports.serviceFeatures = objectAssign(bitfield(64), {
// XXX(Kagami): PyBitmessage uses MSB 0 scheme for this bitfield so we // XXX(Kagami): PyBitmessage uses MSB 0 scheme for this bitfield so we
// invert the numberes. See // invert the numberes. See
// <https://github.com/Bitmessage/PyBitmessage/issues/769> for details. // <https://github.com/Bitmessage/PyBitmessage/issues/769> for details.
exports.pubkeyFeatures = objectAssign(bitfield(32), { exports.pubkeyBitfield = objectAssign(bitfield(32), {
/** /**
* Receiving node expects that the RIPE hash encoded in their address * Receiving node expects that the RIPE hash encoded in their address
* preceedes the encrypted message data of msg messages bound for * preceedes the encrypted message data of msg messages bound for

28
test.js
View File

@ -14,8 +14,8 @@ 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 inv_vect = structs.inv_vect;
var encrypted = structs.encrypted; var encrypted = structs.encrypted;
var serviceFeatures = structs.serviceFeatures; var servicesBitfield = structs.servicesBitfield;
var pubkeyFeatures = structs.pubkeyFeatures; var pubkeyBitfield = structs.pubkeyBitfield;
var messages = bitmessage.messages; var messages = bitmessage.messages;
var version = messages.version; var version = messages.version;
var addr = messages.addr; var addr = messages.addr;
@ -209,27 +209,27 @@ describe("Common structures", function() {
res = net_addr.decode(Buffer("0000000054aaf6c000000001000000000000000100000000000000000000ffff7f00000120fc", "hex")); res = net_addr.decode(Buffer("0000000054aaf6c000000001000000000000000100000000000000000000ffff7f00000120fc", "hex"));
expect(res.time.getTime()).to.equal(1420490432000); expect(res.time.getTime()).to.equal(1420490432000);
expect(res.stream).to.equal(1); expect(res.stream).to.equal(1);
expect(res.services).to.have.members([serviceFeatures.NODE_NETWORK]); expect(res.services).to.have.members([servicesBitfield.NODE_NETWORK]);
expect(res.host).to.equal("127.0.0.1"); expect(res.host).to.equal("127.0.0.1");
expect(res.port).to.equal(8444); expect(res.port).to.equal(8444);
expect(net_addr.decode.bind(null, Buffer("000000000000000100000000000000000000ffff7f00000120fc", "hex"))).to.throw(Error);; expect(net_addr.decode.bind(null, Buffer("000000000000000100000000000000000000ffff7f00000120fc", "hex"))).to.throw(Error);;
res = net_addr.decode(Buffer("000000000000000100000000000000000000ffff7f00000120fc", "hex"), {short: true}); res = net_addr.decode(Buffer("000000000000000100000000000000000000ffff7f00000120fc", "hex"), {short: true});
expect(res.services).to.have.members([serviceFeatures.NODE_NETWORK]); expect(res.services).to.have.members([servicesBitfield.NODE_NETWORK]);
expect(res.host).to.equal("127.0.0.1"); expect(res.host).to.equal("127.0.0.1");
expect(res.port).to.equal(8444); expect(res.port).to.equal(8444);
res = net_addr.decode(Buffer("000000000000000100000000000000000000000000000001fde8", "hex"), {short: true}); res = net_addr.decode(Buffer("000000000000000100000000000000000000000000000001fde8", "hex"), {short: true});
expect(res.services).to.have.members([serviceFeatures.NODE_NETWORK]); expect(res.services).to.have.members([servicesBitfield.NODE_NETWORK]);
expect(res.host).to.equal("0:0:0:0:0:0:0:1"); expect(res.host).to.equal("0:0:0:0:0:0:0:1");
expect(res.port).to.equal(65000); expect(res.port).to.equal(65000);
}); });
it("should encode", function() { it("should encode", function() {
var time = new Date(1420490432000); var time = new Date(1420490432000);
expect(net_addr.encode({time: time, stream: 1, services: [serviceFeatures.NODE_NETWORK], host: "127.0.0.1", port: 8444}).toString("hex")).to.equal("0000000054aaf6c000000001000000000000000100000000000000000000ffff7f00000120fc"); expect(net_addr.encode({time: time, stream: 1, services: [servicesBitfield.NODE_NETWORK], host: "127.0.0.1", port: 8444}).toString("hex")).to.equal("0000000054aaf6c000000001000000000000000100000000000000000000ffff7f00000120fc");
expect(net_addr.encode({short: true, services: [serviceFeatures.NODE_NETWORK], host: "127.0.0.1", port: 8444}).toString("hex")).to.equal("000000000000000100000000000000000000ffff7f00000120fc"); expect(net_addr.encode({short: true, services: [servicesBitfield.NODE_NETWORK], host: "127.0.0.1", port: 8444}).toString("hex")).to.equal("000000000000000100000000000000000000ffff7f00000120fc");
expect(net_addr.encode({short: true, host: "::1", port: 65000}).toString("hex")).to.equal("000000000000000100000000000000000000000000000001fde8"); expect(net_addr.encode({short: true, host: "::1", port: 65000}).toString("hex")).to.equal("000000000000000100000000000000000000000000000001fde8");
}); });
}); });
@ -266,23 +266,23 @@ 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(servicesBitfield.decode(Buffer("0000000000000001", "hex"))).to.have.members([servicesBitfield.NODE_NETWORK]);
}); });
it("should encode", function() { it("should encode", function() {
expect(serviceFeatures.encode([serviceFeatures.NODE_NETWORK]).toString("hex")).to.equal("0000000000000001"); expect(servicesBitfield.encode([servicesBitfield.NODE_NETWORK]).toString("hex")).to.equal("0000000000000001");
expect(serviceFeatures.encode(serviceFeatures.NODE_NETWORK).toString("hex")).to.equal("0000000000000001"); expect(servicesBitfield.encode(servicesBitfield.NODE_NETWORK).toString("hex")).to.equal("0000000000000001");
}); });
}); });
describe("pubkey features", function() { describe("pubkey features", function() {
it("should decode", function() { it("should decode", function() {
expect(pubkeyFeatures.decode(Buffer("00000003", "hex"))).to.have.members([pubkeyFeatures.DOES_ACK, pubkeyFeatures.INCLUDE_DESTINATION]); expect(pubkeyBitfield.decode(Buffer("00000003", "hex"))).to.have.members([pubkeyBitfield.DOES_ACK, pubkeyBitfield.INCLUDE_DESTINATION]);
}); });
it("should encode", function() { it("should encode", function() {
expect(pubkeyFeatures.encode([pubkeyFeatures.INCLUDE_DESTINATION, pubkeyFeatures.DOES_ACK]).toString("hex")).to.equal("00000003"); expect(pubkeyBitfield.encode([pubkeyBitfield.INCLUDE_DESTINATION, pubkeyBitfield.DOES_ACK]).toString("hex")).to.equal("00000003");
expect(pubkeyFeatures.encode(pubkeyFeatures.DOES_ACK).toString("hex")).to.equal("00000001"); expect(pubkeyBitfield.encode(pubkeyBitfield.DOES_ACK).toString("hex")).to.equal("00000001");
}); });
}); });
}); });
@ -296,7 +296,7 @@ describe("Message types", function() {
port: 8444, port: 8444,
})); }));
expect(res.version).to.equal(3); expect(res.version).to.equal(3);
expect(res.services).to.deep.equal([serviceFeatures.NODE_NETWORK]); expect(res.services).to.deep.equal([servicesBitfield.NODE_NETWORK]);
expect(res.time).to.be.instanceof(Date); expect(res.time).to.be.instanceof(Date);
expect(res.remoteHost).to.equal("1.2.3.4"); expect(res.remoteHost).to.equal("1.2.3.4");
expect(res.remotePort).to.equal(48444); expect(res.remotePort).to.equal(48444);