diff --git a/lib/messages.js b/lib/messages.js index 72f715b..4cf3e3b 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -17,6 +17,7 @@ var BufferUtil = bitcore.util.buffer; var Hash = bitcore.crypto.Hash; var Random = bitcore.crypto.Random; var TransactionModel = bitcore.Transaction; +var errors = bitcore.Errors; var CONNECTION_NONCE = Random.getPseudoRandomBuffer(8); var PROTOCOL_VERSION = 70000; @@ -88,7 +89,7 @@ function discardUntilNextMessage(network, dataBuffer) { /** * Abstract Message that knows how to parse and serialize itself. - * Concret subclases should implement {fromBuffer} and {getPayload} methods. + * Concrete subclasses should implement {fromBuffer} and {getPayload} methods. * @name P2P.Message */ function Message() {} @@ -106,7 +107,7 @@ Message.COMMANDS = {}; Message.buildMessage = function(command, payload) { try { var CommandClass = Message.COMMANDS[command]; - return new CommandClass().fromBuffer(payload); + return new CommandClass.fromBuffer(payload); } catch (err) { console.log('Error while parsing message', err); } @@ -118,9 +119,9 @@ Message.buildMessage = function(command, payload) { * @param{Buffer} payload - the buffer to read from * @returns{Message} The same message instance */ -Message.prototype.fromBuffer = function(payload) { +Message.fromBuffer = function(payload) { /* jshint unused: false */ - return this; + throw new errors.NotImplemented(); }; /** @@ -180,51 +181,52 @@ function Version(subversion, nonce) { } util.inherits(Version, Message); -Version.prototype.fromBuffer = function(payload) { +Version.fromBuffer = function(payload) { + var that = new Version(); var parser = new BufferReader(payload); /** * @type {number} * @desc The version of the bitcoin protocol */ - this.version = parser.readUInt32LE(); + that.version = parser.readUInt32LE(); /** * @type {BN} * @desc A mapbit with service bits: what features are supported by the peer */ - this.services = parser.readUInt64LEBN(); + that.services = parser.readUInt64LEBN(); /** * @type {BN} * @desc The time this message was sent */ - this.timestamp = parser.readUInt64LEBN(); + that.timestamp = parser.readUInt64LEBN(); /** * @type {Buffer} * @desc IPv4/6 address of the interface used to connect to this peer */ - this.addr_me = parser.read(26); + that.addr_me = parser.read(26); /** * @type {Buffer} * @desc IPv4/6 address of the peer */ - this.addr_you = parser.read(26); + that.addr_you = parser.read(26); /** * @type {Buffer} * @desc A random number */ - this.nonce = parser.read(8); + that.nonce = parser.read(8); /** * @desc A random number * @type {string} */ - this.subversion = parser.readVarintBuf().toString(); + that.subversion = parser.readVarintBuf().toString(); /** * @desc The height of the last block accepted in the blockchain by this peer * @type {number} */ - this.start_height = parser.readUInt32LE(); + that.start_height = parser.readUInt32LE(); - return this; + return that; }; Version.prototype.getPayload = function() { @@ -263,17 +265,18 @@ function Inventory(inventory) { } util.inherits(Inventory, Message); -Inventory.prototype.fromBuffer = function(payload) { +Inventory.fromBuffer = function(payload) { + var that = new Inventory(); var parser = new BufferReader(payload); var count = parser.readVarintNum(); for (var i = 0; i < count; i++) { - this.inventory.push({ + that.inventory.push({ type: parser.readUInt32LE(), hash: parser.read(32) }); } - return this; + return that; }; Inventory.prototype.getPayload = function() { @@ -327,9 +330,10 @@ function Ping(nonce) { } util.inherits(Ping, Message); -Ping.prototype.fromBuffer = function(payload) { - this.nonce = new BufferReader(payload).read(8); - return this; +Ping.fromBuffer = function(payload) { + var that = new Ping(); + that.nonce = new BufferReader(payload).read(8); + return that; }; Ping.prototype.getPayload = function() { @@ -354,6 +358,9 @@ function Pong(nonce) { } util.inherits(Pong, Ping); +Pong.fromBuffer = function() { + return new Pong(); +}; module.exports.Pong = Message.COMMANDS.pong = Pong; /** @@ -372,11 +379,12 @@ function Addresses(addresses) { } util.inherits(Addresses, Message); -Addresses.prototype.fromBuffer = function(payload) { +Addresses.fromBuffer = function(payload) { + var that = new Addresses(); var parser = new BufferReader(payload); var addrCount = Math.min(parser.readVarintNum(), 1000); - this.addresses = []; + that.addresses = []; for (var i = 0; i < addrCount; i++) { // TODO: Time actually depends on the version of the other peer (>=31402) @@ -399,7 +407,7 @@ Addresses.prototype.fromBuffer = function(payload) { var port = parser.readUInt16BE(); - this.addresses.push({ + that.addresses.push({ time: time, services: services, ip: { v6: ipv6, v4: ipv4 }, @@ -407,7 +415,7 @@ Addresses.prototype.fromBuffer = function(payload) { }); } - return this; + return that; }; Addresses.prototype.getPayload = function() { @@ -436,6 +444,9 @@ function GetAddresses() { } util.inherits(GetAddresses, Message); +GetAddresses.fromBuffer = function() { + return new GetAddresses(); +}; module.exports.GetAddresses = Message.COMMANDS.getaddr = GetAddresses; /** @@ -448,6 +459,9 @@ function VerAck() { } util.inherits(VerAck, Message); +VerAck.fromBuffer = function() { + return new VerAck(); +}; module.exports.VerAck = Message.COMMANDS.verack = VerAck; /** @@ -477,11 +491,12 @@ function Alert(payload, signature) { } util.inherits(Alert, Message); -Alert.prototype.fromBuffer = function(payload) { +Alert.fromBuffer = function(payload) { + var that = new Alert(); var parser = new BufferReader(payload); - this.payload = parser.readVarintBuf(); // TODO: Use current format - this.signature = parser.readVarintBuf(); - return this; + that.payload = parser.readVarintBuf(); // TODO: Use current format + that.signature = parser.readVarintBuf(); + return that; }; Alert.prototype.getPayload = function() { @@ -514,17 +529,18 @@ function Headers(blockheaders) { } util.inherits(Headers, Message); -Headers.prototype.fromBuffer = function(payload) { +Headers.fromBuffer = function(payload) { + var that = new Headers(); var parser = new BufferReader(payload); var count = parser.readVarintNum(); - this.headers = []; + that.headers = []; for (var i = 0; i < count; i++) { var header = BlockHeaderModel._fromBufferReader(parser); - this.headers.push(header); + that.headers.push(header); } - return this; + return that; }; Headers.prototype.getPayload = function() { @@ -558,9 +574,10 @@ function Block(block) { } util.inherits(Block, Message); -Block.prototype.fromBuffer = function(payload) { - this.block = BlockModel(payload); - return this; +Block.fromBuffer = function(payload) { + var that = new Block(); + that.block = BlockModel(payload); + return that; }; Block.prototype.getPayload = function() { @@ -584,9 +601,10 @@ function Transaction(transaction) { } util.inherits(Transaction, Message); -Transaction.prototype.fromBuffer = function(payload) { - this.transaction = TransactionModel(payload); - return this; +Transaction.fromBuffer = function(payload) { + var that = new Transaction(); + that.transaction = TransactionModel(payload); + return that; }; Transaction.prototype.getPayload = function() { @@ -622,18 +640,19 @@ function GetBlocks(starts, stop) { } util.inherits(GetBlocks, Message); -GetBlocks.prototype.fromBuffer = function(payload) { +GetBlocks.fromBuffer = function(payload) { + var that = new GetBlocks(); var parser = new BufferReader(payload); - this.version = parser.readUInt32LE(); + that.version = parser.readUInt32LE(); var startCount = Math.min(parser.readVarintNum(), 500); - this.starts = []; + that.starts = []; for (var i = 0; i < startCount; i++) { - this.starts.push(parser.read(32)); + that.starts.push(parser.read(32)); } - this.stop = parser.read(32); + that.stop = parser.read(32); - return this; + return that; }; GetBlocks.prototype.getPayload = function() { diff --git a/test/messages.js b/test/messages.js index 0935cf6..3b5de1e 100644 --- a/test/messages.js +++ b/test/messages.js @@ -36,31 +36,32 @@ describe('Messages', function() { it('should be able to parse payload', function() { var payload = new Buffer(Data.VERSION.payload, 'hex'); - new Messages.Version().fromBuffer(payload); + var m = Messages.Version.fromBuffer(payload); + should.exist(m); }); }); - describe('VerAck', function() { + var name = 'VerAck'; + describe(name, function() { + var message = new Messages[name](); it('should be able to create instance', function() { - var message = new Messages.VerAck(); - message.command.should.equal('verack'); + message.command.should.equal(name.toLowerCase()); }); it('should be able to serialize the payload', function() { - var message = new Messages.VerAck(); var payload = message.getPayload(); should.exist(payload); }); it('should be able to serialize the message', function() { - var message = new Messages.VerAck(); var buffer = message.serialize(Networks.livenet); should.exist(buffer); }); it('should be able to parse payload', function() { - var payload = new Buffer(Data.VERACK.payload, 'hex'); - new Messages.VerAck().fromBuffer(payload); + var payload = new Buffer(Data[name.toUpperCase()].payload, 'hex'); + var m = Messages[name].fromBuffer(payload); + should.exist(m); }); }); @@ -84,7 +85,8 @@ describe('Messages', function() { it('should be able to parse payload', function() { var payload = new Buffer(Data.INV.payload, 'hex'); - new Messages.Inventory().fromBuffer(payload); + var m = Messages.Inventory.fromBuffer(payload); + should.exist(m); }); }); @@ -108,10 +110,17 @@ describe('Messages', function() { it('should be able to parse payload', function() { var payload = new Buffer(Data.ADDR.payload, 'hex'); - new Messages.Addresses().fromBuffer(payload); + var m = Messages.Addresses.fromBuffer(payload); + should.exist(m); }); }); + /* + Data.forEach(function(x) { + console.log(x); + }); + */ + describe('Ping', function() { it('should be able to create instance', function() { var message = new Messages.Ping(); @@ -132,7 +141,8 @@ describe('Messages', function() { it('should be able to parse payload', function() { var payload = new Buffer(Data.PING.payload, 'hex'); - new Messages.Ping().fromBuffer(payload); + var m = Messages.Ping.fromBuffer(payload); + should.exist(m); }); }); @@ -156,7 +166,8 @@ describe('Messages', function() { it('should be able to parse payload', function() { var payload = new Buffer(Data.PING.payload, 'hex'); - new Messages.Pong().fromBuffer(payload); + var m = Messages.Pong.fromBuffer(payload); + should.exist(m); }); }); diff --git a/test/pool.js b/test/pool.js index fb5e13b..eac97f0 100644 --- a/test/pool.js +++ b/test/pool.js @@ -66,7 +66,7 @@ describe('Pool', function() { // mock a addr peer event var peerMessageStub = sinon.stub(Peer.prototype, '_readMessage', function() { var payload = new Buffer(MessagesData.ADDR.payload, 'hex'); - var message = new Messages.Addresses().fromBuffer(payload); + var message = Messages.Addresses.fromBuffer(payload); this.emit(message.command, message); });