diff --git a/integration/bitcoind.js b/integration/bitcoind.js index 61f4d12..b844181 100644 --- a/integration/bitcoind.js +++ b/integration/bitcoind.js @@ -26,6 +26,10 @@ var blockHash = { 'livenet': '000000000000000013413cf2536b491bf0988f52e90c476ffeb701c8bfdb1db9', 'testnet': '0000000058cc069d964711cd25083c0a709f4df2b34c8ff9302ce71fe5b45786' }; +var stopBlock = { + 'livenet': '000000000000000006181d9d183e2191a5e704d6ed3513f29b0970198fb34d2e', + 'testnet': '000000003d594c41db49d5a8b850344943438620acf79ce8aa88177f5b35e337' +}; var txHash = { 'livenet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b', 'testnet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b' @@ -152,4 +156,32 @@ describe('Integration with ' + network.name + ' bitcoind', function() { peer.sendMessage(message); }); }); + var from = [blockHash[network.name]]; + var stop = stopBlock[network.name]; + it('can get headers', function(cb) { + connect(function(peer) { + peer.once('headers', function(message) { + (message instanceof Messages.Headers).should.equal(true); + message.headers.length.should.equal(2); + cb(); + }); + var message = new Messages.GetHeaders(from, stop); + peer.sendMessage(message); + }); + }); + it.skip('can get blocks', function(cb) { + connect(function(peer) { + peer.on('inv', function(message) { + (message instanceof Messages.Inventory).should.equal(true); + console.log('inv' + message.inventory.length); + if (message.inventory.length === 2) { + console.log(message); + message.inventory[0].type.should.equal(Messages.Inventory.TYPE.BLOCK); + cb(); + } + }); + var message = new Messages.GetBlocks(from, stop); + peer.sendMessage(message); + }); + }); }); diff --git a/lib/messages.js b/lib/messages.js index 8ff3a94..c7d795c 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -601,7 +601,7 @@ Headers.prototype.fromBuffer = function(payload) { this.headers = []; for (var i = 0; i < count; i++) { - var header = BlockHeaderModel._fromBufferReader(parser); + var header = BlockHeaderModel.fromBufferReader(parser); this.headers.push(header); } @@ -613,7 +613,9 @@ Headers.prototype.getPayload = function() { put.varint(this.headers.length); for (var i = 0; i < this.headers.length; i++) { - var buffer = this.headers[i].toBuffer(); + var buffer = this + .headers[i] + .toBuffer(); put.put(buffer); } @@ -685,24 +687,35 @@ module.exports.Transaction = Message.COMMANDS.tx = Transaction; * hashes. * * @name P2P.Message.GetBlocks - * @param{Array} starts - array of buffers with the starting block hashes + * @param{Array} starts - array of buffers or strings with the starting block hashes * @param{Buffer} [stop] - hash of the last block */ function GetBlocks(starts, stop) { + $.checkArgument(_.isUndefined(starts) || _.isArray(starts)); this.command = 'getblocks'; /** * @type {number} */ this.version = PROTOCOL_VERSION; + + starts = starts ? starts.map(function(hash) { + return _.isString(hash) ? BufferUtil.reverse(new Buffer(hash, 'hex')) : hash; + }) : undefined; /** * @type {Array.Buffer} */ this.starts = starts || []; + + for (var i = 0; i < this.starts.length; i++) { + if (this.starts[i].length !== 32) { + throw new Error('Invalid hash ' + i + ' length: ' + this.starts[i].length); + } + } /** * @type {Array.Buffer} * @desc Hashes to limit the amount of blocks to be sent */ - this.stop = stop || BufferUtil.NULL_HASH; + this.stop = (_.isString(stop) ? BufferUtil.reverse(new Buffer(stop, 'hex')) : stop) || BufferUtil.NULL_HASH; } util.inherits(GetBlocks, Message); @@ -727,14 +740,11 @@ GetBlocks.prototype.getPayload = function() { put.varint(this.starts.length); for (var i = 0; i < this.starts.length; i++) { - if (this.starts[i].length !== 32) { - throw new Error('Invalid hash length'); - } put.put(this.starts[i]); } if (this.stop.length !== 32) { - throw new Error('Invalid hash length'); + throw new Error('Invalid hash length: ' + this.stop.length); } put.put(this.stop); @@ -751,19 +761,8 @@ module.exports.GetBlocks = Message.COMMANDS.getblocks = GetBlocks; * @param{Buffer} [stop] - hash of the last block */ function GetHeaders(starts, stop) { + GetBlocks.call(this, starts, stop); this.command = 'getheaders'; - /** - * @type {number} - */ - this.version = PROTOCOL_VERSION; - /** - * @type {Array.Buffer} - */ - this.starts = starts || []; - /** - * @type {Array.Buffer} - */ - this.stop = stop || BufferUtil.NULL_HASH; } util.inherits(GetHeaders, GetBlocks); diff --git a/test/data/messages.json b/test/data/messages.json index ea75e8d..0036144 100644 --- a/test/data/messages.json +++ b/test/data/messages.json @@ -32,8 +32,8 @@ "payload": "" }, "HEADERS": { - "message": "", - "payload": "" + "message": "f9beb4d9686561646572730000000000a1000000ffd6770b0202000000b91ddbbfc801b7fe6f470ce9528f98f01b496b53f23c411300000000000000004901c9d18d0a468b20cc62ddf75aee58cf410440ea390300bf7a5f6848be350508d4cb54c0a31a18b9f661ec0002000000a02d6472e3e6fc9a1cebeaad14a90208a715e2bd234ea00600000000000000006f596f650fbbd5478489c66d651c9e3ea56f394d1f1481f90975cf0c8dda45fd3ad4cb54c0a31a1872e262", + "payload": "0202000000b91ddbbfc801b7fe6f470ce9528f98f01b496b53f23c411300000000000000004901c9d18d0a468b20cc62ddf75aee58cf410440ea390300bf7a5f6848be350508d4cb54c0a31a18b9f661ec0002000000a02d6472e3e6fc9a1cebeaad14a90208a715e2bd234ea00600000000000000006f596f650fbbd5478489c66d651c9e3ea56f394d1f1481f90975cf0c8dda45fd3ad4cb54c0a31a1872e262" }, "TX": { "message": "", diff --git a/test/messages.js b/test/messages.js index d72e6a6..9222abe 100644 --- a/test/messages.js +++ b/test/messages.js @@ -31,7 +31,7 @@ describe('Messages', function() { NotFound: 'notfound' }; // TODO: add data for these - var noPayload = ['Alert', 'Reject', 'GetBlocks', 'GetHeaders', 'GetData', 'Headers']; + var noPayload = ['Alert', 'Reject', 'GetBlocks', 'GetHeaders', 'GetData']; var names = Object.keys(commands); describe('named', function() { names.forEach(function(name) {