From 1d8f694c84e67990f3436086ffb3f0d7d4f0184b Mon Sep 17 00:00:00 2001 From: Kagami Hiiragi Date: Fri, 16 Jan 2015 03:08:56 +0300 Subject: [PATCH] Implement messages.error --- README.md | 7 ++--- lib/messages.js | 82 ++++++++++++++++++++++++++++++++++++++++++++----- test.js | 24 +++++++++++++++ 3 files changed, 101 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4608b52..a19974b 100644 --- a/README.md +++ b/README.md @@ -36,13 +36,13 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/ - [x] message encodings - [x] service features - [x] pubkey features -- [ ] Message types +- [x] Message types - [x] version - [x] verack - [x] addr - [x] inv - [x] getdata - - [ ] error + - [x] error - [x] object - [ ] Object types - [ ] getpubkey @@ -58,9 +58,6 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/ - [x] getRipe - [x] fromRandom - [ ] fromPassphrase - - [ ] Message - - [ ] encrypt - - [ ] decrypt - [x] UserAgent - [ ] Parse PyBitmessage configs - [ ] keys.dat diff --git a/lib/messages.js b/lib/messages.js index 3994187..d7848d4 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -1,6 +1,8 @@ /** * Working with messages. * @see {@link https://bitmessage.org/wiki/Protocol_specification#Message_types} + * @see {@link https://bitmessage.org/wiki/Protocol_specification_v3#Message_types} + * @see {@link https://bitmessage.org/Bitmessage%20Technical%20Paper.pdf} * @module bitmessage/messages */ @@ -23,8 +25,7 @@ exports.version = { /** * Decode `version` payload. * NOTE: `nonce` is copied. - * @param {Buffer} buf - Buffer that starts with encoded `version` - * payload + * @param {Buffer} buf - `version` payload * @return {Object} Decoded `version` structure. */ decode: function(buf) { @@ -107,7 +108,7 @@ exports.version = { exports.addr = { /** * Decode `addr` payload. - * @param {Buffer} buf - Buffer that starts with encoded `addr` payload + * @param {Buffer} buf - `addr` payload * @return {Object} Decoded `addr` structure. */ decode: function(buf) { @@ -150,7 +151,7 @@ exports.addr = { var inv = exports.inv = { /** * Decode `inv` payload. - * @param {Buffer} buf - Buffer that starts with encoded `inv` payload + * @param {Buffer} buf - `inv` payload * @return {Object} Decoded `inv` structure. */ decode: function(buf) { @@ -173,7 +174,7 @@ var inv = exports.inv = { /** * Encode `inv` payload. - * @param {Buffer[]} inventory - Inventory vectors (encoded) + * @param {Buffer[]} inventory - Inventory vector list (encoded) * @return {Buffer} Encoded `inv` payload. */ encode: function(inventory) { @@ -192,6 +193,74 @@ var inv = exports.inv = { */ exports.getdata = inv; +/** + * `error` message. + * @see {@link https://bitmessage.org/wiki/Protocol_specification_v3#error} + * @namespace + */ +var error = exports.error = { + /** + * Just a warning. + */ + WARNING: 0, + + /** + * It's an error, something was going wrong (e.g. an object got lost). + */ + ERROR: 1, + + /** + * It's a fatal error. The node will drop the line for that error and + * maybe ban you for some time. + */ + FATAL: 2, + + /** + * Decode `error` payload. + * @param {Buffer} buf - `error` payload + * @return {Object} Decoded `error` structure. + */ + decode: function(buf) { + assert(buf.length >= 4, "Buffer is too small"); + var decodedFatal = structs.var_int.decode(buf); + var decodedBanTime = structs.var_int.decode(decodedFatal.rest); + var decodedVector = structs.var_str.decode(decodedBanTime.rest); + var decodedErrorText = structs.var_str.decode(decodedVector.rest); + var length = ( + decodedFatal.length + + decodedBanTime.length + + decodedVector.length + + decodedErrorText.length + ); + return { + fatal: decodedFatal.value, + banTime: decodedBanTime.value, + vector: decodedVector.str, + errorText: decodedErrorText.str, + // Real data length. + length: length, + }; + }, + + /** + * Encode `error` payload. + * @param {Object} opts - Error options + * @return {Buffer} Encoded `error` payload. + */ + encode: function(opts) { + var fatal = opts.fatal || error.WARNING; + var banTime = opts.banTime || 0; + var vector = opts.vector || ""; + var errorText = opts.errorText || ""; + return Buffer.concat([ + structs.var_int.encode(fatal), + structs.var_int.encode(banTime), + structs.var_str.encode(vector), + structs.var_str.encode(errorText), + ]); + }, +}; + /** * `object` message. An `object` is a message which is shared throughout * a stream. It is the only message which propagates; all others are @@ -203,8 +272,7 @@ exports.object = { /** * Decode `object` payload. * NOTE: `nonce` and `payload` are copied. - * @param {Buffer} buf - Buffer that starts with encoded `object` - * payload + * @param {Buffer} buf - `object` payload * @return {Object} Decoded `object` structure. */ decode: function(buf) { diff --git a/test.js b/test.js index 9d17ef6..31b9d17 100644 --- a/test.js +++ b/test.js @@ -21,6 +21,7 @@ var messages = bitmessage.messages; var version = messages.version; var addr = messages.addr; var inv = messages.inv; +var error = messages.error; var object = messages.object; var WIF = bitmessage.WIF; var POW = bitmessage.POW; @@ -354,6 +355,29 @@ describe("Message types", function() { }); }); + describe("error", function() { + it("should encode and decode", function() { + var res = error.decode(error.encode({errorText: "test"})); + expect(res.fatal).to.equal(0); + expect(res.banTime).to.equal(0); + expect(res.vector).to.equal(""); + expect(res.errorText).to.equal("test"); + expect(res.length).to.equal(8); + + var res = error.decode(error.encode({ + fatal: error.FATAL, + banTime: 120, + vector: "123", + errorText: "fatal error", + })); + expect(res.fatal).to.equal(2); + expect(res.banTime).to.equal(120); + expect(res.vector).to.equal("123"); + expect(res.errorText).to.equal("fatal error"); + expect(res.length).to.equal(18); + }); + }); + describe("object", function() { it("should encode and decode", function() { var nonce = Buffer(8);