pool: better peer options handling.

This commit is contained in:
Christopher Jeffrey 2016-07-25 01:22:31 -07:00
parent 8bd52cff0a
commit 20d52ca110
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 50 additions and 54 deletions

View File

@ -77,11 +77,12 @@ function Peer(pool, options) {
this.options = options; this.options = options;
this.pool = pool; this.pool = pool;
this.logger = pool.logger; this.logger = pool.logger;
this.type = options.type;
this.socket = null; this.socket = null;
this.host = null; this.host = null;
this.port = 0; this.port = 0;
this.hostname = null; this.hostname = null;
this._createSocket = this.options.createSocket; this._createSocket = this.pool.options.createSocket;
this.chain = this.pool.chain; this.chain = this.pool.chain;
this.mempool = this.pool.mempool; this.mempool = this.pool.mempool;
this.network = this.chain.network; this.network = this.chain.network;
@ -92,7 +93,7 @@ function Peer(pool, options) {
this.destroyed = false; this.destroyed = false;
this.ack = false; this.ack = false;
this.connected = false; this.connected = false;
this.ts = this.options.ts || 0; this.ts = options.ts || 0;
this.preferHeaders = false; this.preferHeaders = false;
this.haveWitness = false; this.haveWitness = false;
this.hashContinue = null; this.hashContinue = null;
@ -104,7 +105,6 @@ function Peer(pool, options) {
this.lastBlock = null; this.lastBlock = null;
this.waiting = 0; this.waiting = 0;
this.syncSent = false; this.syncSent = false;
this.loader = options.loader || false;
this._connectTimeout = null; this._connectTimeout = null;
this.compactMode = null; this.compactMode = null;
this.compactBlocks = {}; this.compactBlocks = {};
@ -117,6 +117,8 @@ function Peer(pool, options) {
this.banScore = 0; this.banScore = 0;
assert(typeof this.type === 'number', 'Peer must have a type.');
if (options.socket) { if (options.socket) {
this.socket = options.socket; this.socket = options.socket;
this.host = IP.normalize(this.socket.remoteAddress); this.host = IP.normalize(this.socket.remoteAddress);
@ -137,14 +139,14 @@ function Peer(pool, options) {
this.hostname = IP.hostname(this.host, this.port); this.hostname = IP.hostname(this.host, this.port);
this.requests = { this.requests = {
timeout: this.options.requestTimeout || 10000, timeout: options.requestTimeout || 10000,
skip: {}, skip: {},
map: {} map: {}
}; };
this.ping = { this.ping = {
timer: null, timer: null,
interval: this.options.pingInterval || 120000 interval: options.pingInterval || 120000
}; };
this.queue = { this.queue = {
@ -170,6 +172,18 @@ utils.inherits(Peer, EventEmitter);
Peer.uid = 0; Peer.uid = 0;
/**
* Peer types.
* @enum {Number}
* @default
*/
Peer.types = {
LOADER: 0,
REGULAR: 1,
LEECH: 2
};
/** /**
* Begin peer initialization. * Begin peer initialization.
* @private * @private
@ -278,7 +292,7 @@ Peer.prototype._onAck = function _onAck(err) {
}, this.ping.interval); }, this.ping.interval);
// Ask for headers-only. // Ask for headers-only.
if (this.options.headers) { if (this.pool.options.headers) {
if (this.version.version >= 70012) if (this.version.version >= 70012)
this.write(this.framer.sendHeaders()); this.write(this.framer.sendHeaders());
} }
@ -286,13 +300,13 @@ Peer.prototype._onAck = function _onAck(err) {
// Let them know we support segwit (old // Let them know we support segwit (old
// segwit3 nodes require this instead // segwit3 nodes require this instead
// of service bits). // of service bits).
if (this.options.witness) { if (this.pool.options.witness) {
if (this.version.version >= 70012) if (this.version.version >= 70012)
this.write(this.framer.haveWitness()); this.write(this.framer.haveWitness());
} }
// We want compact blocks! // We want compact blocks!
if (this.options.compact) { if (this.pool.options.compact) {
if (this.version.version >= 70014) if (this.version.version >= 70014)
this.sendCompact(); this.sendCompact();
} }
@ -315,7 +329,7 @@ Peer.prototype._onAck = function _onAck(err) {
// Ask for the mempool if we're synced. // Ask for the mempool if we're synced.
if (this.network.requestMempool) { if (this.network.requestMempool) {
if (this.loader && this.pool.synced) if (this.type === Peer.types.LOADER && this.pool.synced)
this.sendMempool(); this.sendMempool();
} }
@ -486,7 +500,7 @@ Peer.prototype.sendVersion = function sendVersion() {
nonce: this.pool.localNonce, nonce: this.pool.localNonce,
agent: constants.USER_AGENT, agent: constants.USER_AGENT,
height: this.chain.height, height: this.chain.height,
relay: this.options.relay relay: this.pool.options.relay
}); });
this.write(this.framer.version(packet)); this.write(this.framer.version(packet));
@ -721,7 +735,7 @@ Peer.prototype.getData = function getData(items) {
if (item.toInv) if (item.toInv)
item = item.toInv(); item = item.toInv();
if (this.options.compact if (this.pool.options.compact
&& this.compactMode && this.compactMode
&& item.isBlock() && item.isBlock()
&& !item.hasWitness()) { && !item.hasWitness()) {
@ -1289,15 +1303,7 @@ Peer.prototype._handleVersion = function _handleVersion(version) {
return; return;
} }
if (this.options.headers) { if (this.type !== Peer.types.LEECH) {
if (!version.hasHeaders()) {
this._error('Peer doesn\'t support getheaders.');
this.setMisbehavior(100);
return;
}
}
if (this.options.network) {
if (!version.hasNetwork()) { if (!version.hasNetwork()) {
this._error('Peer does not support network services.'); this._error('Peer does not support network services.');
this.setMisbehavior(100); 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()) { if (!version.hasBloom()) {
this._error('Peer does not support bip37.'); this._error('Peer does not support bip37.');
this.setMisbehavior(100); 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 (!version.hasWitness()) {
if (!this.network.oldWitness) { if (!this.network.oldWitness) {
this._error('Peer does not support segregated witness.'); this._error('Peer does not support segregated witness.');
@ -1849,7 +1863,7 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(block) {
self.fire('cmpctblock', block); self.fire('cmpctblock', block);
} }
if (!this.options.compact) { if (!this.pool.options.compact) {
this.logger.info('Peer sent unsolicited cmpctblock (%s).', this.hostname); this.logger.info('Peer sent unsolicited cmpctblock (%s).', this.hostname);
return; return;
} }
@ -2220,14 +2234,14 @@ Peer.prototype.sync = function sync(callback) {
if (this.syncSent) if (this.syncSent)
return; return;
if (!this.loader) { if (this.type !== Peer.types.LOADER) {
if (!this.chain.isFull()) if (!this.chain.isFull())
return; return;
} }
this.syncSent = true; this.syncSent = true;
if (this.options.headers) { if (this.pool.options.headers) {
if (!this.chain.tip.isGenesis()) if (!this.chain.tip.isGenesis())
tip = this.chain.tip.prevBlock; tip = this.chain.tip.prevBlock;

View File

@ -202,6 +202,10 @@ function Pool(options) {
if (this.options.witness) { if (this.options.witness) {
this.block.type |= constants.WITNESS_MASK; this.block.type |= constants.WITNESS_MASK;
this.tx.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 = { this.request = {
@ -574,11 +578,7 @@ Pool.prototype._addLoader = function _addLoader() {
peer = this._createPeer({ peer = this._createPeer({
host: this.getLoaderHost(), host: this.getLoaderHost(),
loader: true, type: bcoin.peer.types.LOADER
network: true,
spv: this.options.spv,
witness: this.options.witness,
compact: this.options.compact
}); });
this.logger.info('Added loader peer (%s).', peer.hostname); 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) { Pool.prototype._createPeer = function _createPeer(options) {
var self = this; var self = this;
var peer = new bcoin.peer(this, options);
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
});
peer.once('close', function() { peer.once('close', function() {
self._removePeer(peer); self._removePeer(peer);
@ -988,7 +976,7 @@ Pool.prototype._createPeer = function _createPeer(options) {
if (!self.loaded) if (!self.loaded)
return; return;
if (!peer.loader) if (peer.type !== bcoin.peer.types.LOADER)
return; return;
self._stopInterval(); self._stopInterval();
@ -1021,7 +1009,7 @@ Pool.prototype._createPeer = function _createPeer(options) {
if (err) if (err)
return self.emit('error', err); return self.emit('error', err);
if (peer.loader) { if (peer.type === bcoin.peer.types.LOADER) {
self._startInterval(); self._startInterval();
self._startTimer(); self._startTimer();
} }
@ -1041,7 +1029,7 @@ Pool.prototype._createPeer = function _createPeer(options) {
if (err) if (err)
return self.emit('error', err); return self.emit('error', err);
if (peer.loader) { if (peer.type === bcoin.peer.types.LOADER) {
self._startInterval(); self._startInterval();
self._startTimer(); self._startTimer();
} }
@ -1279,10 +1267,7 @@ Pool.prototype._addLeech = function _addLeech(socket) {
peer = this._createPeer({ peer = this._createPeer({
socket: socket, socket: socket,
network: false, type: bcoin.peer.types.LEECH
spv: false,
witness: false,
compact: false
}); });
this.logger.info('Added leech peer (%s).', peer.hostname); this.logger.info('Added leech peer (%s).', peer.hostname);
@ -1321,10 +1306,7 @@ Pool.prototype._addPeer = function _addPeer() {
peer = this._createPeer({ peer = this._createPeer({
host: host, host: host,
network: true, type: bcoin.peer.types.REGULAR
spv: this.options.spv,
witness: this.options.witness,
compact: this.options.compact
}); });
this.peers.pending.push(peer); this.peers.pending.push(peer);