pool: refactor and add compact block mode 1 support.

This commit is contained in:
Christopher Jeffrey 2017-01-20 09:03:24 -08:00
parent 7543049180
commit 18c4a83ed3
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 180 additions and 163 deletions

View File

@ -1678,10 +1678,10 @@ RejectPacket.fromRaw = function fromRaw(data, enc) {
* @private
* @param {Number} code
* @param {String} reason
* @param {(TX|Block)?} obj
* @param {(TX|Block)?} msg
*/
RejectPacket.prototype.fromReason = function fromReason(code, reason, obj) {
RejectPacket.prototype.fromReason = function fromReason(code, reason, msg) {
if (typeof code === 'string')
code = RejectPacket.codes[code.toUpperCase()];
@ -1695,9 +1695,9 @@ RejectPacket.prototype.fromReason = function fromReason(code, reason, obj) {
this.code = code;
this.reason = reason;
if (obj) {
this.message = (obj instanceof TX) ? 'tx' : 'block';
this.hash = obj.hash('hex');
if (msg) {
this.message = (msg instanceof TX) ? 'tx' : 'block';
this.hash = msg.hash('hex');
}
return this;

View File

@ -26,7 +26,6 @@ var BIP152 = require('./bip152');
var Block = require('../primitives/block');
var TX = require('../primitives/tx');
var encoding = require('../utils/encoding');
var errors = require('../protocol/errors');
var NetAddress = require('../primitives/netaddress');
var services = common.services;
var invTypes = InvItem.types;
@ -115,8 +114,9 @@ function Peer(pool) {
this.bip150 = null;
this.compactMode = -1;
this.compactWitness = false;
this.lastMerkle = null;
this.waitingTX = 0;
this.merkleBlock = null;
this.merkleTime = -1;
this.merkleMatches = 0;
this.syncSent = false;
this.sentAddr = false;
this.sentGetAddr = false;
@ -270,13 +270,14 @@ Peer.prototype._init = function init() {
this.parser.on('error', function(err) {
self.error(err);
self.reject(null, 'malformed', 'error parsing message', 10);
self.sendReject('malformed', 'error parsing message');
self.increaseBan(10);
});
if (this.bip151) {
this.bip151.on('error', function(err) {
self.error(err);
self.reject(null, 'malformed', 'error parsing message', 10);
self.destroy();
});
this.bip151.on('rekey', function() {
self.logger.debug('Rekeying with peer (%s).', self.hostname);
@ -649,7 +650,7 @@ Peer.prototype.announceBlock = function announceBlock(blocks) {
// they're using compact block mode 1.
if (this.compactMode === 1) {
this.invFilter.add(block.hash());
this.sendCompactBlock(block, this.compactWitness);
this.sendCompactBlock(block);
continue;
}
@ -824,11 +825,12 @@ Peer.prototype.sendHeaders = function sendHeaders(items) {
* Send a compact block.
* @private
* @param {Block} block
* @param {Boolean} witness
* @returns {Boolean}
*/
Peer.prototype.sendCompactBlock = function sendCompactBlock(block, witness) {
Peer.prototype.sendCompactBlock = function sendCompactBlock(block) {
var witness = this.compactWitness;
// Try again with a new nonce
// if we get a siphash collision.
for (;;) {
@ -1122,6 +1124,15 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
}
}
if (this.merkleBlock) {
assert(this.merkleTime !== -1);
if (now > this.merkleTime + 60000) {
this.error('Peer is stalling (merkleblock).');
this.destroy();
return;
}
}
if (!this.pool.syncing || this.chain.synced)
return;
@ -1509,26 +1520,10 @@ Peer.prototype.handlePacket = co(function* handlePacket(packet) {
this.emit(packet.cmd, packet);
});
/**
* Flush merkle block once all matched
* txs have been received.
* @private
* @returns {Promise}
*/
Peer.prototype.flushMerkle = co(function* flushMerkle() {
assert(this.lastMerkle);
yield this.pool.addBlock(this, this.lastMerkle);
this.lastMerkle = null;
this.waitingTX = 0;
});
/**
* Handle `filterload` packet.
* @private
* @param {FilterLoadPacket}
* @param {FilterLoadPacket} packet
*/
Peer.prototype.handleFilterLoad = co(function* handleFilterLoad(packet) {
@ -1546,7 +1541,7 @@ Peer.prototype.handleFilterLoad = co(function* handleFilterLoad(packet) {
/**
* Handle `filteradd` packet.
* @private
* @param {FilterAddPacket}
* @param {FilterAddPacket} packet
*/
Peer.prototype.handleFilterAdd = co(function* handleFilterAdd(packet) {
@ -2025,7 +2020,7 @@ Peer.prototype.handleGetBlockTxn = co(function* handleGetBlockTxn(packet) {
*/
Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(packet) {
yield this.pool.handleGetBlockTxn(this, packet);
yield this.pool.handleBlockTxn(this, packet);
});
/**
@ -2037,24 +2032,22 @@ Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(packet) {
Peer.prototype.sendGetHeaders = function sendGetHeaders(locator, stop) {
var packet = new packets.GetHeadersPacket(locator, stop);
var height = -1;
var hash = null;
var end = null;
if (packet.locator.length > 0)
hash = util.revHex(packet.locator[0]);
if (stop)
end = util.revHex(stop);
this.logger.debug(
'Requesting headers packet from peer with getheaders (%s).',
this.hostname);
if (packet.locator.length > 0) {
height = this.chain.checkHeight(packet.locator[0]);
hash = util.revHex(packet.locator[0]);
}
if (stop)
stop = util.revHex(stop);
this.logger.debug(
'Height: %d, Hash: %s, Stop: %s',
height, hash, stop || null);
'Sending getheaders (hash=%s, stop=%s).',
hash, end);
this.send(packet);
};
@ -2069,10 +2062,7 @@ Peer.prototype.sendGetBlocks = function getBlocks(locator, stop) {
var packet = new packets.GetBlocksPacket(locator, stop);
var height = -1;
var hash = null;
this.logger.debug(
'Requesting inv packet from peer with getblocks (%s).',
this.hostname);
var end = null;
if (packet.locator.length > 0) {
height = this.chain.checkHeight(packet.locator[0]);
@ -2080,11 +2070,15 @@ Peer.prototype.sendGetBlocks = function getBlocks(locator, stop) {
}
if (stop)
stop = util.revHex(stop);
end = util.revHex(stop);
this.logger.debug(
'Height: %d, Hash: %s, Stop: %s',
height, hash, stop || null);
'Requesting inv packet from peer with getblocks (%s).',
this.hostname);
this.logger.debug(
'Sending getblocks (height=%d, hash=%s, stop=%s).',
height, hash, end);
this.send(packet);
};
@ -2115,15 +2109,15 @@ Peer.prototype.sendMempool = function sendMempool() {
* Send `reject` to peer.
* @param {Number} code
* @param {String} reason
* @param {TX|Block} obj
* @param {TX|Block} msg
*/
Peer.prototype.sendReject = function sendReject(code, reason, obj) {
var reject = packets.RejectPacket.fromReason(code, reason, obj);
Peer.prototype.sendReject = function sendReject(code, reason, msg) {
var reject = packets.RejectPacket.fromReason(code, reason, msg);
if (obj) {
if (msg) {
this.logger.debug('Rejecting %s %s (%s): ccode=%s reason=%s.',
reject.message, obj.rhash(), this.hostname, code, reason);
reject.message, msg.rhash(), this.hostname, code, reason);
} else {
this.logger.debug('Rejecting packet from %s: ccode=%s reason=%s.',
this.hostname, code, reason);
@ -2138,12 +2132,13 @@ Peer.prototype.sendReject = function sendReject(code, reason, obj) {
/**
* Send a `sendcmpct` packet.
* @param {Number} mode
*/
Peer.prototype.sendCompact = function sendCompact() {
Peer.prototype.sendCompact = function sendCompact(mode) {
var version = this.options.witness ? 2 : 1;
this.logger.info('Initializing compact blocks (%s).', this.hostname);
this.send(new packets.SendCmpctPacket(0, version));
this.send(new packets.SendCmpctPacket(mode, version));
};
/**
@ -2174,14 +2169,14 @@ Peer.prototype.ban = function ban() {
/**
* Send a `reject` packet to peer.
* @see Framer.reject
* @param {(TX|Block)?} obj
* @param {String} code - cccode.
* @param {(TX|Block)?} msg
* @param {String} code
* @param {String} reason
* @param {Number} score
*/
Peer.prototype.reject = function reject(obj, code, reason, score) {
this.sendReject(code, reason, obj);
Peer.prototype.reject = function reject(msg, code, reason, score) {
this.sendReject(code, reason, msg);
this.increaseBan(score);
};

View File

@ -34,7 +34,6 @@ var Map = require('../utils/map');
var packets = require('./packets');
var invTypes = InvItem.types;
var VerifyError = errors.VerifyError;
var VerifyResult = errors.VerifyResult;
/**
* A pool of peers for handling all network activity.
@ -104,7 +103,6 @@ function Pool(options) {
this.connected = false;
this.syncing = false;
this.feeRate = this.options.feeRate;
this.nonce = util.nonce();
this.spvFilter = null;
this.txFilter = null;
@ -180,26 +178,6 @@ Pool.prototype._init = function _init() {
self.emit('block', block, entry);
});
this.chain.on('competitor', function(block, entry) {
self.emit('competitor', block, entry);
});
this.chain.on('fork', function(block, height, expected) {
self.emit('fork', block, height, expected);
});
this.chain.on('invalid', function(block, height) {
self.emit('invalid', block, height);
});
this.chain.on('exists', function(block, height) {
self.emit('exists', block, height);
});
this.chain.on('orphan', function(block, height) {
self.emit('orphan', block, height);
});
this.chain.on('reset', function() {
self.resetChain();
self.forceSync();
@ -896,7 +874,7 @@ Pool.prototype.handleOpen = function handleOpen(peer) {
// We want compact blocks!
if (this.options.compact) {
if (peer.version >= common.COMPACT_VERSION)
peer.sendCompact();
peer.sendCompact(this.options.blockMode);
}
// Find some more peers.
@ -911,8 +889,8 @@ Pool.prototype.handleOpen = function handleOpen(peer) {
this.announceList(peer);
// Set a fee rate filter.
if (this.feeRate !== -1)
peer.sendFeeRate(this.feeRate);
if (this.options.feeRate !== -1)
peer.sendFeeRate(this.options.feeRate);
// Start syncing the chain.
peer.sync();
@ -982,7 +960,7 @@ Pool.prototype.handleVersion = co(function* handleVersion(peer, packet) {
*/
Pool.prototype.handleVerack = co(function* handleVerack(peer, packet) {
;
this.emit('verack', packet, peer);
});
/**
@ -993,7 +971,7 @@ Pool.prototype.handleVerack = co(function* handleVerack(peer, packet) {
*/
Pool.prototype.handlePing = co(function* handlePing(peer, packet) {
;
this.emit('ping', packet, peer);
});
/**
@ -1004,7 +982,7 @@ Pool.prototype.handlePing = co(function* handlePing(peer, packet) {
*/
Pool.prototype.handlePong = co(function* handlePong(peer, packet) {
;
this.emit('pong', packet, peer);
});
/**
@ -1051,6 +1029,8 @@ Pool.prototype.handleGetAddr = co(function* handleGetAddr(peer, packet) {
peer.hostname);
peer.send(new packets.AddrPacket(items));
this.emit('getaddr', packet, peer);
});
/**
@ -1066,8 +1046,6 @@ Pool.prototype.handleAddr = co(function* handleAddr(peer, packet) {
var services = this.options.requiredServices;
var i, addr;
this.emit('addr', addrs, peer);
for (i = 0; i < addrs.length; i++) {
addr = addrs[i];
@ -1096,6 +1074,8 @@ Pool.prototype.handleAddr = co(function* handleAddr(peer, packet) {
peer.hostname);
this.fillOutbound();
this.emit('addr', packet, peer);
});
/**
@ -1159,13 +1139,13 @@ Pool.prototype._handleInv = co(function* handleInv(peer, packet) {
unknown, peer.hostname);
}
this.emit('inv', items, peer);
if (blocks.length > 0)
yield this.handleBlockInv(peer, blocks);
if (txs.length > 0)
yield this.handleTXInv(peer, txs);
this.emit('inv', packet, peer);
});
/**
@ -1361,7 +1341,7 @@ Pool.prototype.handleGetData = co(function* handleGetData(peer, packet) {
continue;
}
peer.sendCompactBlock(block, peer.compactWitness);
peer.sendCompactBlock(block);
blocks++;
@ -1399,7 +1379,7 @@ Pool.prototype.handleGetData = co(function* handleGetData(peer, packet) {
unknown, peer.hostname);
}
this.emit('getdata', items, peer);
this.emit('getdata', packet, peer);
});
/**
@ -1417,6 +1397,8 @@ Pool.prototype.handleNotFound = co(function* handleNotFound(peer, packet) {
item = items[i];
this.fulfill(peer, item.hash);
}
this.emit('notfound', packet, peer);
});
/**
@ -1462,6 +1444,8 @@ Pool.prototype.handleGetBlocks = co(function* handleGetBlocks(peer, packet) {
}
peer.sendInv(blocks);
this.emit('getblocks', packet, peer);
});
/**
@ -1511,6 +1495,8 @@ Pool.prototype.handleGetHeaders = co(function* handleGetHeaders(peer, packet) {
}
peer.sendHeaders(headers);
this.emit('getheaders', packet, peer);
});
/**
@ -1595,13 +1581,13 @@ Pool.prototype._handleHeaders = co(function* handleHeaders(peer, packet) {
this.headerChain.push(node);
}
this.emit('headers', headers, peer);
this.logger.debug(
'Received %s headers from peer (%s).',
headers.length,
peer.hostname);
this.emit('headers', packet, peer);
// Request the hashes we just added.
if (isCheckpoint) {
this.headerChain.shift();
@ -1622,7 +1608,7 @@ Pool.prototype._handleHeaders = co(function* handleHeaders(peer, packet) {
*/
Pool.prototype.handleSendHeaders = co(function* handleSendHeaders(peer, packet) {
this.emit('sendheader', packet, peer);
this.emit('sendheaders', packet, peer);
});
/**
@ -1645,7 +1631,7 @@ Pool.prototype.handleBlock = co(function* handleBlock(peer, packet) {
});
/**
* Handle `block` packet. Attempt to add to chain.
* Attempt to add block to chain.
* @private
* @param {Peer} peer
* @param {Block} block
@ -1663,7 +1649,7 @@ Pool.prototype.addBlock = co(function* addBlock(peer, block) {
});
/**
* Handle `block` packet. Attempt to add to chain (without a lock).
* Attempt to add block to chain (without a lock).
* @private
* @param {Peer} peer
* @param {Block} block
@ -1673,16 +1659,12 @@ Pool.prototype.addBlock = co(function* addBlock(peer, block) {
Pool.prototype._addBlock = co(function* addBlock(peer, block) {
var hash = block.hash('hex');
var isCheckpoint = false;
var requested, node, checkpoint;
var node, checkpoint;
if (!this.syncing)
return;
requested = this.fulfill(peer, hash);
// Someone is sending us blocks without
// us requesting them.
if (!requested) {
if (!this.fulfill(peer, hash)) {
peer.invFilter.add(block.hash());
this.logger.warning(
'Received unrequested block: %s (%s).',
@ -1817,23 +1799,28 @@ Pool.prototype.handleTX = co(function* handleTX(peer, packet) {
Pool.prototype._handleTX = co(function* handleTX(peer, packet) {
var tx = packet.tx;
var hash = tx.hash('hex');
var requested, missing;
if (peer.lastMerkle) {
assert(peer.waitingTX > 0);
if (peer.lastMerkle.hasTX(tx)) {
peer.lastMerkle.addTX(tx);
if (--peer.waitingTX === 0)
yield peer.flushMerkle();
if (peer.merkleBlock) {
assert(peer.merkleMatches > 0);
if (peer.merkleBlock.hasTX(tx)) {
peer.merkleBlock.addTX(tx);
if (--peer.merkleMatches === 0) {
yield this.addBlock(peer, peer.merkleBlock);
peer.merkleTime = -1;
peer.merkleBlock = null;
peer.merkleMatches = 0;
}
return;
}
}
var hash = tx.hash('hex');
var requested = this.fulfill(peer, hash);
var missing;
requested = this.fulfill(peer, hash);
if (!requested) {
this.logger.warning('Peer sent unrequested tx: %s (%s).',
this.logger.warning(
'Peer sent unrequested tx: %s (%s).',
tx.txid(), peer.hostname);
peer.invFilter.add(tx.hash());
@ -1917,7 +1904,7 @@ Pool.prototype.handleReject = co(function* handleReject(peer, packet) {
Pool.prototype.handleMempool = co(function* handleMempool(peer, packet) {
var items = [];
var i, hashes;
var i, hash, hashes;
if (!this.mempool)
return;
@ -1930,14 +1917,16 @@ Pool.prototype.handleMempool = co(function* handleMempool(peer, packet) {
hashes = this.mempool.getSnapshot();
for (i = 0; i < hashes.length; i++)
items.push(new InvItem(invTypes.TX, hashes[i]));
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
items.push(new InvItem(invTypes.TX, hash));
}
this.logger.debug('Sending mempool snapshot (%s).', peer.hostname);
this.emit('mempool', peer);
peer.sendInv(items);
this.emit('mempool', packet, peer);
});
/**
@ -1970,7 +1959,7 @@ Pool.prototype.handleFilterAdd = co(function* handleFilterAdd(peer, packet) {
*/
Pool.prototype.handleFilterClear = co(function* handleFilterClear(peer, packet) {
this.emit('filterclear', peer, packet);
this.emit('filterclear', packet, peer);
});
/**
@ -1982,7 +1971,10 @@ Pool.prototype.handleFilterClear = co(function* handleFilterClear(peer, packet)
Pool.prototype.handleMerkleBlock = co(function* handleMerkleBlock(peer, packet) {
var block = packet.block;
var ret = new VerifyResult();
var hash = block.hash('hex');
if (!this.syncing)
return;
// Potential DoS.
if (!this.options.spv) {
@ -1993,7 +1985,15 @@ Pool.prototype.handleMerkleBlock = co(function* handleMerkleBlock(peer, packet)
return;
}
if (peer.lastMerkle) {
if (!peer.requestMap.has(hash)) {
this.logger.warning(
'Peer sent an unrequested merkleblock (%s).',
peer.hostname);
peer.destroy();
return;
}
if (peer.merkleBlock) {
this.logger.warning(
'Peer sent a merkleblock prematurely (%s).',
peer.hostname);
@ -2001,19 +2001,24 @@ Pool.prototype.handleMerkleBlock = co(function* handleMerkleBlock(peer, packet)
return;
}
if (!block.verify(ret)) {
if (!block.verify()) {
this.logger.warning(
'Peer sent an invalid merkleblock (%s).',
peer.hostname);
peer.reject(block, 'invalid', ret.reason, ret.score);
peer.increaseBan(100);
return;
}
peer.lastMerkle = block;
peer.waitingTX = block.matches.length;
if (block.matches.length === 0) {
yield this.addBlock(peer, block);
return;
}
if (peer.waitingTX === 0)
yield peer.flushMerkle();
peer.merkleTime = util.ms();
peer.merkleBlock = block;
peer.merkleMatches = block.matches.length;
this.emit('merkleblock', packet, peer);
});
/**
@ -2051,6 +2056,9 @@ Pool.prototype.handleCmpctBlock = co(function* handleCmpctBlock(peer, packet) {
var witness = this.options.witness;
var result;
if (!this.syncing)
return;
if (!this.options.compact) {
this.logger.info('Peer sent unsolicited cmpctblock (%s).', peer.hostname);
return;
@ -2061,13 +2069,33 @@ Pool.prototype.handleCmpctBlock = co(function* handleCmpctBlock(peer, packet) {
return;
}
if (this.compactBlocks.has(hash)) {
if (peer.compactBlocks.has(hash)) {
this.logger.debug(
'Peer sent us a duplicate compact block (%s).',
peer.hostname);
return;
}
if (this.compactBlocks.has(hash)) {
this.logger.debug(
'Already waiting for compact block %s (%s).',
hash, peer.hostname);
return;
}
if (!peer.requestMap.has(hash)) {
if (this.options.blockMode !== 1) {
this.logger.warning(
'Peer sent us an unrequested compact block (%s).',
peer.hostname);
peer.destroy();
return;
}
peer.requestMap.insert(hash);
assert(!this.requestMap.has(hash));
this.requestMap.insert(hash);
}
if (!block.verify()) {
this.logger.debug(
'Peer sent an invalid compact block (%s).',
@ -2086,10 +2114,12 @@ Pool.prototype.handleCmpctBlock = co(function* handleCmpctBlock(peer, packet) {
return;
}
if (peer.compactBlocks.size >= 10) {
this.logger.warning('Compact block DoS attempt (%s).', peer.hostname);
peer.destroy();
return;
if (this.options.blockMode === 1) {
if (peer.compactBlocks.size >= 10) {
this.logger.warning('Compact block DoS attempt (%s).', peer.hostname);
peer.destroy();
return;
}
}
assert(!peer.compactBlocks.has(hash));
@ -2101,9 +2131,9 @@ Pool.prototype.handleCmpctBlock = co(function* handleCmpctBlock(peer, packet) {
'Received semi-full compact block %s (%s).',
block.rhash(), peer.hostname);
this.emit('cmpctblock', block, peer);
peer.send(new packets.GetBlockTxnPacket(block.toRequest()));
this.emit('cmpctblock', packet, peer);
});
/**
@ -2147,11 +2177,11 @@ Pool.prototype.handleGetBlockTxn = co(function* handleGetBlockTxn(peer, packet)
return;
}
this.emit('getblocktxn', req, peer);
res = BIP152.TXResponse.fromBlock(block, req);
peer.send(new packets.BlockTxnPacket(res, peer.compactWitness));
this.emit('getblocktxn', packet, peer);
});
/**
@ -2161,7 +2191,7 @@ Pool.prototype.handleGetBlockTxn = co(function* handleGetBlockTxn(peer, packet)
* @param {BlockTxnPacket} packet
*/
Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(peer, packet) {
Pool.prototype.handleBlockTxn = co(function* handleBlockTxn(peer, packet) {
var res = packet.response;
var block = peer.compactBlocks.get(res.hash);
@ -2185,9 +2215,9 @@ Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(peer, packet) {
'Filled compact block %s (%s).',
block.rhash(), peer.hostname);
this.emit('blocktxn', res, peer);
yield this.addBlock(peer, block.toBlock());
this.emit('blocktxn', packet, peer);
});
/**
@ -2197,7 +2227,7 @@ Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(peer, packet) {
* @param {EncinitPacket} packet
*/
Peer.prototype.handleEncinit = co(function* handleEncinit(peer, packet) {
Pool.prototype.handleEncinit = co(function* handleEncinit(peer, packet) {
this.emit('encinit', packet, peer);
});
@ -2208,7 +2238,7 @@ Peer.prototype.handleEncinit = co(function* handleEncinit(peer, packet) {
* @param {EncackPacket} packet
*/
Peer.prototype.handleEncack = co(function* handleEncack(peer, packet) {
Pool.prototype.handleEncack = co(function* handleEncack(peer, packet) {
this.emit('encack', packet, peer);
});
@ -2219,7 +2249,7 @@ Peer.prototype.handleEncack = co(function* handleEncack(peer, packet) {
* @param {AuthChallengePacket} packet
*/
Peer.prototype.handleAuthChallenge = co(function* handleAuthChallenge(peer, packet) {
Pool.prototype.handleAuthChallenge = co(function* handleAuthChallenge(peer, packet) {
this.emit('authchallenge', packet, peer);
});
@ -2230,7 +2260,7 @@ Peer.prototype.handleAuthChallenge = co(function* handleAuthChallenge(peer, pack
* @param {AuthReplyPacket} packet
*/
Peer.prototype.handleAuthReply = co(function* handleAuthReply(peer, packet) {
Pool.prototype.handleAuthReply = co(function* handleAuthReply(peer, packet) {
this.emit('authreply', packet, peer);
});
@ -2241,7 +2271,7 @@ Peer.prototype.handleAuthReply = co(function* handleAuthReply(peer, packet) {
* @param {AuthProposePacket} packet
*/
Peer.prototype.handleAuthPropose = co(function* handleAuthPropose(peer, packet) {
Pool.prototype.handleAuthPropose = co(function* handleAuthPropose(peer, packet) {
this.emit('authpropose', packet, peer);
});
@ -2252,8 +2282,8 @@ Peer.prototype.handleAuthPropose = co(function* handleAuthPropose(peer, packet)
* @param {UnknownPacket} packet
*/
Peer.prototype.handleUnknown = co(function* handleUnknown(peer, packet) {
this.logger.warning('Unknown packet: %s.', packet.cmd);
Pool.prototype.handleUnknown = co(function* handleUnknown(peer, packet) {
this.logger.warning('Unknown packet: %s (%s).', packet.cmd, peer.hostname);
this.emit('unknown', packet, peer);
});
@ -2780,20 +2810,6 @@ Pool.prototype.announceTX = function announceTX(msg) {
peer.announceTX(msg);
};
/**
* Set a fee rate filter for all peers.
* @param {Rate} rate
*/
Pool.prototype.setFeeRate = function setFeeRate(rate) {
var peer;
this.feeRate = rate;
for (peer = this.peers.head(); peer; peer = peer.next)
peer.sendFeeRate(rate);
};
/**
* Attempt to retrieve external IP from icanhazip.com.
* @returns {Promise}
@ -2898,6 +2914,7 @@ function PoolOptions(options) {
this.seeds = this.network.seeds;
this.nodes = [];
this.invTimeout = 60000;
this.blockMode = 0;
this.services = common.LOCAL_SERVICES;
this.requiredServices = common.REQUIRED_SERVICES;
@ -3091,6 +3108,11 @@ PoolOptions.prototype.fromOptions = function fromOptions(options) {
this.invTimeout = options.invTimeout;
}
if (options.blockMode != null) {
assert(typeof options.blockMode === 'number');
this.blockMode = options.blockMode;
}
if (!this.witness) {
this.services &= ~common.services.WITNESS;
this.requiredServices &= ~common.services.WITNESS;