From 6f63e36eca2ba593fe0fa187989539cbf79c6482 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Fri, 20 Feb 2015 13:23:22 -0800 Subject: [PATCH 1/4] add forFilteredBlock() on Inventory, GetData, NotFound --- lib/messages.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/messages.js b/lib/messages.js index fe1ff85..7afc9b0 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -941,5 +941,6 @@ Buffers.prototype.skip = function(i) { [Inventory, GetData, NotFound].forEach(function(clazz) { clazz.forBlock = creatorForItem(clazz, Inventory.TYPE.BLOCK); + clazz.forFilteredBlock = creatorForItem(clazz, Inventory.TYPE.FILTERED_BLOCK); clazz.forTransaction = creatorForItem(clazz, Inventory.TYPE.TX); }); From 641dfe579d727c51d77e7dc260dc680f82f31df9 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Fri, 20 Feb 2015 13:25:45 -0800 Subject: [PATCH 2/4] Add MerkleBlock() Message --- lib/messages.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/messages.js b/lib/messages.js index 7afc9b0..5a5d04e 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -14,6 +14,7 @@ var _ = bitcore.deps._; var BlockHeaderModel = bitcore.BlockHeader; var BlockModel = bitcore.Block; +var MerkleBlockModel = bitcore.MerkleBlock; var BufferReader = bitcore.encoding.BufferReader; var BufferWriter = bitcore.encoding.BufferWriter; var BufferUtil = bitcore.util.buffer; @@ -720,6 +721,37 @@ Block.prototype.getPayload = function() { module.exports.Block = Message.COMMANDS.block = Block; +/** + * Contains information about a MerkleBlock + * + * @name P2P.Message.MerkleBlock + * @param {MerkleBlock} block + */ +function MerkleBlock(block) { + $.checkArgument(_.isUndefined(block) || block instanceof MerkleBlockModel); + this.command = 'merkleblock'; + + /** + * @type {Block} + * @desc The block received + */ + this.merkleBlock = block; +} +util.inherits(MerkleBlock, Message); + +MerkleBlock.prototype.fromBuffer = function(payload) { + $.checkArgument(BufferUtil.isBuffer(payload)); + var block = MerkleBlockModel(payload); + return new MerkleBlock(block); +}; + +MerkleBlock.prototype.getPayload = function() { + return this.merkleBlock ? this.merkleBlock.toBuffer() : new Buffer(0); +}; + +module.exports.MerkleBlock = Message.COMMANDS.merkleblock = MerkleBlock; + + /** * Contains information about a transaction * From b7473e708045d54fcfed46d5f9d49118d9795230 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Fri, 20 Feb 2015 13:33:52 -0800 Subject: [PATCH 3/4] Have pool propagate merkleblock events --- lib/messages.js | 1 + lib/pool.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/messages.js b/lib/messages.js index 5a5d04e..ccab1a4 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -974,5 +974,6 @@ Buffers.prototype.skip = function(i) { [Inventory, GetData, NotFound].forEach(function(clazz) { clazz.forBlock = creatorForItem(clazz, Inventory.TYPE.BLOCK); clazz.forFilteredBlock = creatorForItem(clazz, Inventory.TYPE.FILTERED_BLOCK); + clazz.forMerkleBlock = creatorForItem(clazz, Inventory.TYPE.FILTERED_BLOCK); clazz.forTransaction = creatorForItem(clazz, Inventory.TYPE.TX); }); diff --git a/lib/pool.js b/lib/pool.js index 98f20ee..47d6596 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -105,7 +105,7 @@ util.inherits(Pool, EventEmitter); Pool.MaxConnectedPeers = 8; Pool.RetrySeconds = 30; Pool.PeerEvents = ['version', 'inv', 'getdata', 'ping', 'pong', 'addr', - 'getaddr', 'verack', 'reject', 'alert', 'headers', 'block', + 'getaddr', 'verack', 'reject', 'alert', 'headers', 'block', 'merkleblock', 'tx', 'getblocks', 'getheaders', 'error', 'filterload', 'filteradd', 'filterclear' ]; From d6b89176f279452c4e5c97e1efc2f86e7e5f50f6 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Thu, 26 Feb 2015 00:30:20 -0800 Subject: [PATCH 4/4] MerkleBlock Tests --- lib/messages.js | 6 +++--- package.json | 2 +- test/data/messages.json | 4 ++++ test/messages.js | 10 ++++++++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/messages.js b/lib/messages.js index ccab1a4..74917d9 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -316,7 +316,7 @@ function Inventory(inventory) { } util.inherits(Inventory, Message); -// https://en.bitcoin.it/wiki/Protocol_specification#Inventory_Vectors +// https://en.bitcoin.it/wiki/Protocol_specification#Inventory_Vectors Inventory.TYPE = {}; Inventory.TYPE.ERROR = 0; Inventory.TYPE.TX = 1; @@ -973,7 +973,7 @@ Buffers.prototype.skip = function(i) { [Inventory, GetData, NotFound].forEach(function(clazz) { clazz.forBlock = creatorForItem(clazz, Inventory.TYPE.BLOCK); - clazz.forFilteredBlock = creatorForItem(clazz, Inventory.TYPE.FILTERED_BLOCK); - clazz.forMerkleBlock = creatorForItem(clazz, Inventory.TYPE.FILTERED_BLOCK); + clazz.forFilteredBlock = clazz.forMerkleBlock = + creatorForItem(clazz, Inventory.TYPE.FILTERED_BLOCK); clazz.forTransaction = creatorForItem(clazz, Inventory.TYPE.TX); }); diff --git a/package.json b/package.json index a344506..4f252c5 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "url": "https://github.com/bitpay/bitcore-p2p.git" }, "dependencies": { - "bitcore": "^0.10.2", + "bitcore": "^0.11.0", "bloom-filter": "^0.1.1", "bufferput": "^0.1.2", "buffers": "^0.1.1", diff --git a/test/data/messages.json b/test/data/messages.json index 551b578..8cd3f61 100644 --- a/test/data/messages.json +++ b/test/data/messages.json @@ -77,5 +77,9 @@ "FILTERCLEAR": { "message": "f9beb4d966696c7465726c6365617200000000005df6e0e2", "payload": "" + }, + "MERKLEBLOCK": { + "message": "f9beb4d96d65726b6c65626c6f636b00d7000000365913480100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b852907000000043612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2019f5b01d4195ecbc9398fbf3c3b1fa9bb3183301d7a1fb3bd174fcfa40a2b6541ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d06820d2a7bc994987302e5b1ac80fc425fe25f8b63169ea78e68fbaaefa59379bbf011d", + "payload": "0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b852907000000043612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2019f5b01d4195ecbc9398fbf3c3b1fa9bb3183301d7a1fb3bd174fcfa40a2b6541ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d06820d2a7bc994987302e5b1ac80fc425fe25f8b63169ea78e68fbaaefa59379bbf011d" } } diff --git a/test/messages.js b/test/messages.js index 6cd29d6..b393713 100644 --- a/test/messages.js +++ b/test/messages.js @@ -27,6 +27,7 @@ describe('Messages', function() { Alert: 'alert', Reject: 'reject', Block: 'block', + MerkleBlock: 'merkleblock', FilterLoad: 'filterload', FilterAdd: 'filteradd', FilterClear: 'filterclear', @@ -111,10 +112,13 @@ describe('Messages', function() { var hash = 'eb951630aba498b9a0d10f72b5ea9e39d5ff04b03dc2231e662f52057f948aa1'; [Messages.Inventory, Messages.GetData, Messages.NotFound].forEach(function(clazz) { var b = clazz.forBlock(hash); + var mb = clazz.forMerkleBlock(hash); (b instanceof clazz).should.equal(true); var t = clazz.forTransaction(hash); (t instanceof clazz).should.equal(true); clazz.forBlock(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(b); + clazz.forMerkleBlock(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(mb); + clazz.forFilteredBlock(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(mb); clazz.forTransaction(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(t); }); }); @@ -141,4 +145,10 @@ describe('Messages', function() { msg.getPayload().toString('hex').should.equal(testPayload); }); + it('MerkleBlock#fromBuffer method works', function() { + var testPayload = Data.MERKLEBLOCK.payload; + var msg = new Messages.MerkleBlock().fromBuffer(new Buffer(testPayload, 'hex')); + msg.getPayload().toString('hex').should.equal(testPayload); + }); + });