From 18c4a83ed371c1f1ee748e34f01313a20f3516f3 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 20 Jan 2017 09:03:24 -0800 Subject: [PATCH] pool: refactor and add compact block mode 1 support. --- lib/net/packets.js | 10 +- lib/net/peer.js | 107 ++++++++++----------- lib/net/pool.js | 226 +++++++++++++++++++++++++-------------------- 3 files changed, 180 insertions(+), 163 deletions(-) diff --git a/lib/net/packets.js b/lib/net/packets.js index 20992a34..ac2c0447 100644 --- a/lib/net/packets.js +++ b/lib/net/packets.js @@ -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; diff --git a/lib/net/peer.js b/lib/net/peer.js index 3b5b963f..9ba17936 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -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); }; diff --git a/lib/net/pool.js b/lib/net/pool.js index d4534e0e..09386371 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -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;