diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index fc6d7da9..469e7d63 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -32,8 +32,8 @@ function Pool(options) { network.set(this.options.network); this.options.fullNode = !!this.options.fullNode; - this.options.headers = !!this.options.headers; - this.options.multiplePeers = !!this.options.multiplePeers; + this.options.headers = this.options.headers; + this.options.multiplePeers = this.options.multiplePeers; this.options.relay = this.options.relay == null ? (this.options.fullNode ? true : false) : this.options.relay; @@ -45,8 +45,15 @@ function Pool(options) { this.redundancy = options.redundancy || 2; if (!this.options.fullNode) { - this.options.headers = true; - this.options.multiplePeers = true; + if (this.options.headers == null) + this.options.headers = true; + if (this.options.multiplePeers == null) + this.options.multiplePeers = true; + } else { + if (this.options.headers == null) + this.options.headers = true; + if (this.options.multiplePeers == null) + this.options.multiplePeers = false; } this.backoff = { @@ -266,6 +273,10 @@ Pool.prototype._addLoader = function _addLoader() { }); peer.once('ack', function() { + if (!peer.socket) { + peer.destroy(); + return; + } peer.updateWatch(); if (!self._load()) self._stopTimer(); @@ -308,14 +319,19 @@ Pool.prototype._handleHeaders = function _handleHeaders(headers, peer) { assert(this.options.headers); - if (headers.length === 0) - return; - this.emit('debug', 'Recieved %s headers from %s', headers.length, peer.address); + if (headers.length === 0) + return; + + if (headers.length > 2000) { + peer.destroy(); + return; + } + this.emit('headers', headers); for (i = 0; i < headers.length; i++) { @@ -337,8 +353,12 @@ Pool.prototype._handleHeaders = function _handleHeaders(headers, peer) { } // Restart the getheaders process - if (last && headers.length >= 1999) - peer.loadHeaders(this.chain.locatorHashes(last), null); + if (last && headers.length === 2000) { + // Ideally we should use chain.locatorHashes here, but we can't since we + // didn't add the headers to the chain (in non-headers-first mode) + // peer.loadHeaders(this.chain.locatorHashes(last), null); + peer.loadHeaders([last.hash('hex')], null); + } // Push our getdata packet this._scheduleRequests(); @@ -351,7 +371,7 @@ Pool.prototype._handleHeaders = function _handleHeaders(headers, peer) { this.emit('debug', 'Requesting %s block packets from %s with getdata', - this.request.active, + this.request.queue.length, peer.address ); }; @@ -361,16 +381,21 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) { assert(!this.options.headers); - if (hashes.length === 0) - return; - - this.emit('blocks', hashes); - this.emit('debug', 'Recieved %s block hashes from %s', hashes.length, peer.address); + if (hashes.length === 0) + return; + + if (hashes.length > 500) { + peer.destroy(); + return; + } + + this.emit('blocks', hashes); + for (i = 0; i < hashes.length; i++) { hash = hashes[i]; @@ -402,7 +427,7 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) { this.emit('debug', 'Requesting %s block packets from %s with getdata', - this.request.active, + this.request.queue.length, peer.address ); }; @@ -582,6 +607,11 @@ Pool.prototype._addPeer = function _addPeer(backoff) { peer.once('ack', function() { var i; + if (!peer.socket) { + peer.destroy(); + return; + } + if (self.destroyed) return; diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 82187d38..ed470489 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -256,28 +256,29 @@ Parser.prototype.parseHeaders = function parseHeaders(p) { off = result.off; count = result.r; - if (p.length >= off + 81) { - for (i = 0; i < count && off + 81 < p.length; i++) { - header = {}; - start = off; - header.version = readU32(p, off); - off += 4; - header.prevBlock = p.slice(off, off + 32); - off += 32; - header.merkleRoot = p.slice(off, off + 32); - off += 32; - header.ts = readU32(p, off); - off += 4; - header.bits = readU32(p, off); - off += 4; - header.nonce = readU32(p, off); - off += 4; - r = utils.readIntv(p, off); - header.totalTX = r.r; - off = r.off; - header._raw = p.slice(start, start + 80); - headers.push(header); - } + if (p.length < count * 80) + return this._error('Invalid headers size'); + + for (i = 0; i < count; i++) { + header = {}; + start = off; + header.version = readU32(p, off); + off += 4; + header.prevBlock = p.slice(off, off + 32); + off += 32; + header.merkleRoot = p.slice(off, off + 32); + off += 32; + header.ts = readU32(p, off); + off += 4; + header.bits = readU32(p, off); + off += 4; + header.nonce = readU32(p, off); + off += 4; + r = utils.readIntv(p, off); + header.totalTX = r.r; + off = r.off; + header._raw = p.slice(start, start + 80); + headers.push(header); } return headers;