From ed08f36e0729420c31fa2baf0e489116e153e196 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 23 May 2016 03:11:31 -0700 Subject: [PATCH] fix block sync. improve announce vs. sendInv. --- lib/bcoin/peer.js | 91 +++++++++++++++++++++++++++++++++++++++-------- lib/bcoin/pool.js | 4 +-- 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index 35f7530a..a1a2ddd3 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -41,7 +41,7 @@ var constants = bcoin.protocol.constants; * @property {Boolean} ack - Whether verack has been received. * @property {Boolean} connected * @property {Number} ts - * @property {Boolean} sendHeaders - Whether the peer has + * @property {Boolean} preferHeaders - Whether the peer has * requested getheaders. * @property {Boolean} haveWitness - Whether the peer supports segwit, * either notified via service bits or deprecated `havewitness` packet. @@ -90,7 +90,7 @@ function Peer(pool, options) { this.ack = false; this.connected = false; this.ts = this.options.ts || 0; - this.sendHeaders = false; + this.preferHeaders = false; this.haveWitness = false; this.hashContinue = null; this.spvFilter = null; @@ -229,7 +229,7 @@ Peer.prototype._init = function init() { self.updateWatch(); // Announce our currently broadcasted items. - self.sendInv(self.pool.inv.items); + self.announce(self.pool.inv.items); // Set a fee rate filter. if (self.pool.feeRate !== -1) @@ -295,20 +295,15 @@ Peer.prototype.createSocket = function createSocket(port, host) { * @param {Block[]|TX[]|InvItem[]|BroadcastEntry[]} items */ -Peer.prototype.sendInv = function sendInv(items) { +Peer.prototype.announce = function announce(items) { var self = this; var inv = []; - var i, item, chunk; + var headers = []; + var i, item; if (this.destroyed) return; - if (!this.relay) - return; - - if (!items) - return; - if (!Array.isArray(items)) items = [items]; @@ -318,21 +313,89 @@ Peer.prototype.sendInv = function sendInv(items) { if (!this.isWatched(item)) continue; + if (this.preferHeaders) { + if (item instanceof bcoin.abstractblock) { + headers.push(item); + continue; + } + } + if (item.toInv) item = item.toInv(); - if (!this.invFilter.added(item.hash, 'hex')) + if (!this.relay) { + if (item.type === constants.inv.TX) + continue; + } + + if (this.invFilter.test(item.hash, 'hex')) continue; inv.push(item); } + this.sendInv(inv); + + if (headers.length > 0) + this.sendHeaders(headers); +}; + +/** + * Send inv to a peer. + * @param {InvItem[]} items + */ + +Peer.prototype.sendInv = function sendInv(items) { + var self = this; + var inv = []; + var i, item, chunk; + + if (this.destroyed) + return; + + if (!Array.isArray(items)) + items = [items]; + + for (i = 0; i < items.length; i++) { + item = items[i]; + this.invFilter.add(item.hash, 'hex'); + inv.push(item); + } + for (i = 0; i < inv.length; i += 50000) { chunk = inv.slice(i, i + 50000); this.write(this.framer.inv(chunk)); } }; +/** + * Send headers to a peer. + * @param {Headers[]} items + */ + +Peer.prototype.sendHeaders = function sendHeaders(items) { + var self = this; + var headers = []; + var i, item, chunk; + + if (this.destroyed) + return; + + if (!Array.isArray(items)) + items = [items]; + + for (i = 0; i < items.length; i++) { + item = items[i]; + this.invFilter.add(item.hash()); + headers.push(item); + } + + for (i = 0; i < headers.length; i += 2000) { + chunk = headers.slice(i, i + 2000); + this.write(this.framer.headers(chunk)); + } +}; + /** * Send a `ping` packet. */ @@ -615,7 +678,7 @@ Peer.prototype._onPacket = function onPacket(packet) { this.fire(cmd, payload); break; case 'sendheaders': - this.sendHeaders = true; + this.preferHeaders = true; this.fire(cmd, payload); break; case 'havewitness': @@ -903,7 +966,7 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) { if (err) return self.emit('error', err); - self.write(self.framer.headers(headers)); + self.sendHeaders(headers); } if (!payload.locator) diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index d5d6378c..641999e2 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -1735,10 +1735,10 @@ Pool.prototype.announce = function announce(msg) { var i; if (this.peers.load) - this.peers.load.sendInv(msg); + this.peers.load.announce(msg); for (i = 0; i < this.peers.regular.length; i++) - this.peers.regular[i].sendInv(msg); + this.peers.regular[i].announce(msg); }; /**