Implement messages.object
This commit is contained in:
parent
52dce062c4
commit
1f5ae113b0
|
@ -43,7 +43,7 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/
|
|||
- [x] inv
|
||||
- [x] getdata
|
||||
- [ ] error
|
||||
- [ ] object
|
||||
- [x] object
|
||||
- [ ] Object types
|
||||
- [ ] getpubkey
|
||||
- [ ] pubkey
|
||||
|
|
|
@ -68,6 +68,7 @@ exports.version = {
|
|||
var services = opts.services || [structs.serviceFeatures.NODE_NETWORK];
|
||||
var time = opts.time || new Date();
|
||||
var nonce = opts.nonce || exports.version.NONCE;
|
||||
assert(nonce.length === 8, "Bad nonce");
|
||||
var software = opts.software || UserAgent.SELF;
|
||||
var streamNumbers = opts.streamNumbers || [1];
|
||||
// Start encoding.
|
||||
|
@ -190,3 +191,66 @@ var inv = exports.inv = {
|
|||
* @namespace
|
||||
*/
|
||||
exports.getdata = inv;
|
||||
|
||||
/**
|
||||
* `object` message. An `object` is a message which is shared throughout
|
||||
* a stream. It is the only message which propagates; all others are
|
||||
* only between two nodes.
|
||||
* @see {@link https://bitmessage.org/wiki/Protocol_specification#object}
|
||||
* @namespace
|
||||
*/
|
||||
exports.object = {
|
||||
/**
|
||||
* Decode `object` payload.
|
||||
* NOTE: `nonce` and `payload` are copied.
|
||||
* @param {Buffer} buf - Buffer that starts with encoded `object`
|
||||
* payload
|
||||
* @return {Object} Decoded `object` structure.
|
||||
*/
|
||||
decode: function(buf) {
|
||||
// 8 + 8 + 4 + (1+) + (1+)
|
||||
assert(buf.length >= 22, "Buffer is too small");
|
||||
var nonce = new Buffer(8);
|
||||
buf.copy(nonce, 0, 0, 8);
|
||||
var expiresTime = util.readTimestamp64BE(buf.slice(8, 16));
|
||||
var ttl = expiresTime - util.tnow();
|
||||
assert(ttl >= -3600, "Object expired more than a hour ago");
|
||||
assert(ttl <= 2430000, "expiresTime is too far in the future");
|
||||
var type = buf.readUInt32BE(16);
|
||||
var decodedVersion = structs.var_int.decode(buf.slice(20));
|
||||
var decodedStream = structs.var_int.decode(decodedVersion.rest);
|
||||
var payload = new Buffer(decodedStream.rest.length);
|
||||
decodedStream.rest.copy(payload);
|
||||
return {
|
||||
nonce: nonce,
|
||||
ttl: ttl,
|
||||
type: type,
|
||||
version: decodedVersion.value,
|
||||
stream: decodedStream.value,
|
||||
payload: payload,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Encode `object` payload.
|
||||
* @param {Object} opts - Object options
|
||||
* @return {Buffer} Encoded `object` payload.
|
||||
*/
|
||||
encode: function(opts) {
|
||||
assert(opts.nonce.length === 8, "Bad nonce");
|
||||
assert(opts.ttl > 0, "Bad TTL");
|
||||
assert(opts.ttl <= 2430000, "TTL may not be larger than 28 days + 3 hours");
|
||||
var expiresTime = util.tnow() + opts.ttl;
|
||||
var type = new Buffer(4);
|
||||
type.writeUInt32BE(opts.type, 0);
|
||||
var stream = opts.stream || 1;
|
||||
return Buffer.concat([
|
||||
opts.nonce,
|
||||
util.writeUInt64BE(null, expiresTime),
|
||||
type,
|
||||
structs.var_int.encode(opts.version),
|
||||
structs.var_int.encode(stream),
|
||||
opts.payload,
|
||||
]);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -56,3 +56,8 @@ exports.writeTime64BE = function(buf, time, offset, noAssert) {
|
|||
var timestamp = Math.floor(time.getTime() / 1000);
|
||||
return writeUInt64BE(buf, timestamp, offset, noAssert);
|
||||
};
|
||||
|
||||
exports.tnow = function() {
|
||||
var time = new Date();
|
||||
return Math.floor(time.getTime() / 1000);
|
||||
};
|
||||
|
|
33
test.js
33
test.js
|
@ -21,6 +21,7 @@ var messages = bitmessage.messages;
|
|||
var version = messages.version;
|
||||
var addr = messages.addr;
|
||||
var inv = messages.inv;
|
||||
var object = messages.object;
|
||||
var WIF = bitmessage.WIF;
|
||||
var POW = bitmessage.POW;
|
||||
var Address = bitmessage.Address;
|
||||
|
@ -347,11 +348,41 @@ describe("Message types", function() {
|
|||
expect(res.length).to.equal(65);
|
||||
});
|
||||
|
||||
it("shouldn't encode/decode more than 1000 entires", function() {
|
||||
it("shouldn't encode/decode more than 50000 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("object", function() {
|
||||
it("should encode and decode", function() {
|
||||
var nonce = Buffer(8);
|
||||
var res = object.decode(object.encode({
|
||||
nonce: nonce,
|
||||
ttl: 100,
|
||||
type: 2,
|
||||
version: 1,
|
||||
payload: Buffer("test"),
|
||||
}));
|
||||
|
||||
expect(bufferEqual(nonce, res.nonce)).to.be.true;
|
||||
expect(res.ttl).to.be.at.least(100);
|
||||
expect(res.type).to.equal(2);
|
||||
expect(res.version).to.equal(1);
|
||||
expect(res.stream).to.equal(1);
|
||||
expect(res.payload.toString()).to.equal("test");
|
||||
});
|
||||
|
||||
it("shouldn't encode too big TTL", function() {
|
||||
expect(object.encode.bind(null, {
|
||||
nonce: Buffer(8),
|
||||
ttl: 10000000,
|
||||
type: 2,
|
||||
version: 1,
|
||||
payload: Buffer("test"),
|
||||
})).to.throw(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("WIF", function() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user