From 20d52ca110da3bb10dd73b8eadd682ab18ebc45e Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 25 Jul 2016 01:22:31 -0700 Subject: [PATCH] pool: better peer options handling. --- lib/bcoin/peer.js | 64 +++++++++++++++++++++++++++++------------------ lib/bcoin/pool.js | 40 ++++++++--------------------- 2 files changed, 50 insertions(+), 54 deletions(-) diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index 17924907..791c83df 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -77,11 +77,12 @@ function Peer(pool, options) { this.options = options; this.pool = pool; this.logger = pool.logger; + this.type = options.type; this.socket = null; this.host = null; this.port = 0; this.hostname = null; - this._createSocket = this.options.createSocket; + this._createSocket = this.pool.options.createSocket; this.chain = this.pool.chain; this.mempool = this.pool.mempool; this.network = this.chain.network; @@ -92,7 +93,7 @@ function Peer(pool, options) { this.destroyed = false; this.ack = false; this.connected = false; - this.ts = this.options.ts || 0; + this.ts = options.ts || 0; this.preferHeaders = false; this.haveWitness = false; this.hashContinue = null; @@ -104,7 +105,6 @@ function Peer(pool, options) { this.lastBlock = null; this.waiting = 0; this.syncSent = false; - this.loader = options.loader || false; this._connectTimeout = null; this.compactMode = null; this.compactBlocks = {}; @@ -117,6 +117,8 @@ function Peer(pool, options) { this.banScore = 0; + assert(typeof this.type === 'number', 'Peer must have a type.'); + if (options.socket) { this.socket = options.socket; this.host = IP.normalize(this.socket.remoteAddress); @@ -137,14 +139,14 @@ function Peer(pool, options) { this.hostname = IP.hostname(this.host, this.port); this.requests = { - timeout: this.options.requestTimeout || 10000, + timeout: options.requestTimeout || 10000, skip: {}, map: {} }; this.ping = { timer: null, - interval: this.options.pingInterval || 120000 + interval: options.pingInterval || 120000 }; this.queue = { @@ -170,6 +172,18 @@ utils.inherits(Peer, EventEmitter); Peer.uid = 0; +/** + * Peer types. + * @enum {Number} + * @default + */ + +Peer.types = { + LOADER: 0, + REGULAR: 1, + LEECH: 2 +}; + /** * Begin peer initialization. * @private @@ -278,7 +292,7 @@ Peer.prototype._onAck = function _onAck(err) { }, this.ping.interval); // Ask for headers-only. - if (this.options.headers) { + if (this.pool.options.headers) { if (this.version.version >= 70012) this.write(this.framer.sendHeaders()); } @@ -286,13 +300,13 @@ Peer.prototype._onAck = function _onAck(err) { // Let them know we support segwit (old // segwit3 nodes require this instead // of service bits). - if (this.options.witness) { + if (this.pool.options.witness) { if (this.version.version >= 70012) this.write(this.framer.haveWitness()); } // We want compact blocks! - if (this.options.compact) { + if (this.pool.options.compact) { if (this.version.version >= 70014) this.sendCompact(); } @@ -315,7 +329,7 @@ Peer.prototype._onAck = function _onAck(err) { // Ask for the mempool if we're synced. if (this.network.requestMempool) { - if (this.loader && this.pool.synced) + if (this.type === Peer.types.LOADER && this.pool.synced) this.sendMempool(); } @@ -486,7 +500,7 @@ Peer.prototype.sendVersion = function sendVersion() { nonce: this.pool.localNonce, agent: constants.USER_AGENT, height: this.chain.height, - relay: this.options.relay + relay: this.pool.options.relay }); this.write(this.framer.version(packet)); @@ -721,7 +735,7 @@ Peer.prototype.getData = function getData(items) { if (item.toInv) item = item.toInv(); - if (this.options.compact + if (this.pool.options.compact && this.compactMode && item.isBlock() && !item.hasWitness()) { @@ -1289,15 +1303,7 @@ Peer.prototype._handleVersion = function _handleVersion(version) { return; } - if (this.options.headers) { - if (!version.hasHeaders()) { - this._error('Peer doesn\'t support getheaders.'); - this.setMisbehavior(100); - return; - } - } - - if (this.options.network) { + if (this.type !== Peer.types.LEECH) { if (!version.hasNetwork()) { this._error('Peer does not support network services.'); this.setMisbehavior(100); @@ -1305,7 +1311,15 @@ Peer.prototype._handleVersion = function _handleVersion(version) { } } - if (this.options.spv) { + if (this.pool.options.headers) { + if (!version.hasHeaders()) { + this._error('Peer doesn\'t support getheaders.'); + this.setMisbehavior(100); + return; + } + } + + if (this.pool.options.spv) { if (!version.hasBloom()) { this._error('Peer does not support bip37.'); this.setMisbehavior(100); @@ -1313,7 +1327,7 @@ Peer.prototype._handleVersion = function _handleVersion(version) { } } - if (this.options.witness) { + if (this.pool.options.witness) { if (!version.hasWitness()) { if (!this.network.oldWitness) { this._error('Peer does not support segregated witness.'); @@ -1849,7 +1863,7 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(block) { self.fire('cmpctblock', block); } - if (!this.options.compact) { + if (!this.pool.options.compact) { this.logger.info('Peer sent unsolicited cmpctblock (%s).', this.hostname); return; } @@ -2220,14 +2234,14 @@ Peer.prototype.sync = function sync(callback) { if (this.syncSent) return; - if (!this.loader) { + if (this.type !== Peer.types.LOADER) { if (!this.chain.isFull()) return; } this.syncSent = true; - if (this.options.headers) { + if (this.pool.options.headers) { if (!this.chain.tip.isGenesis()) tip = this.chain.tip.prevBlock; diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 86bc006d..ef9f4e38 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -202,6 +202,10 @@ function Pool(options) { if (this.options.witness) { this.block.type |= constants.WITNESS_MASK; this.tx.type |= constants.WITNESS_MASK; + if (this.options.compact) { + this.logger.warning('Disabling compact blocks due to segwit.'); + this.options.compact = false; + } } this.request = { @@ -574,11 +578,7 @@ Pool.prototype._addLoader = function _addLoader() { peer = this._createPeer({ host: this.getLoaderHost(), - loader: true, - network: true, - spv: this.options.spv, - witness: this.options.witness, - compact: this.options.compact + type: bcoin.peer.types.LOADER }); this.logger.info('Added loader peer (%s).', peer.hostname); @@ -968,19 +968,7 @@ Pool.prototype.sendAlert = function sendAlert(alert) { Pool.prototype._createPeer = function _createPeer(options) { var self = this; - - var peer = new bcoin.peer(this, { - host: options.host, - createSocket: this.options.createSocket, - loader: options.loader, - relay: this.options.relay, - socket: options.socket, - network: options.network, - spv: options.spv, - witness: options.witness, - headers: this.options.headers, - compact: this.options.compact - }); + var peer = new bcoin.peer(this, options); peer.once('close', function() { self._removePeer(peer); @@ -988,7 +976,7 @@ Pool.prototype._createPeer = function _createPeer(options) { if (!self.loaded) return; - if (!peer.loader) + if (peer.type !== bcoin.peer.types.LOADER) return; self._stopInterval(); @@ -1021,7 +1009,7 @@ Pool.prototype._createPeer = function _createPeer(options) { if (err) return self.emit('error', err); - if (peer.loader) { + if (peer.type === bcoin.peer.types.LOADER) { self._startInterval(); self._startTimer(); } @@ -1041,7 +1029,7 @@ Pool.prototype._createPeer = function _createPeer(options) { if (err) return self.emit('error', err); - if (peer.loader) { + if (peer.type === bcoin.peer.types.LOADER) { self._startInterval(); self._startTimer(); } @@ -1279,10 +1267,7 @@ Pool.prototype._addLeech = function _addLeech(socket) { peer = this._createPeer({ socket: socket, - network: false, - spv: false, - witness: false, - compact: false + type: bcoin.peer.types.LEECH }); this.logger.info('Added leech peer (%s).', peer.hostname); @@ -1321,10 +1306,7 @@ Pool.prototype._addPeer = function _addPeer() { peer = this._createPeer({ host: host, - network: true, - spv: this.options.spv, - witness: this.options.witness, - compact: this.options.compact + type: bcoin.peer.types.REGULAR }); this.peers.pending.push(peer);