diff --git a/bin/node b/bin/node index 8d0c3e8f..4917aff5 100755 --- a/bin/node +++ b/bin/node @@ -11,9 +11,3 @@ var node = bcoin.fullnode({ node.on('error', function(err) { utils.print(err.message); }); - -node.pool.on('full', function() { - setInterval(function() { - console.log(node.wallet.getAll()); - }, 1000); -}); diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 0b8d2362..9f216e33 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -411,7 +411,10 @@ Pool.prototype._addLoader = function _addLoader() { peer = this._createPeer({ seed: this.getSeed(true), - priority: true + priority: true, + network: true, + spv: this.options.spv, + witness: this.options.witness }); assert(peer); @@ -826,10 +829,36 @@ Pool.prototype._createPeer = function _createPeer(options) { peer.on('version', function(version) { if (version.height > self.block.versionHeight) self.block.versionHeight = version.height; - self.emit('version', version, peer); + + if (options.network) { + if (!version.network) { + utils.debug('Peer does not support network services. Killing.'); + self.setMisbehavior(peer, 100); + return; + } + } + + if (options.spv) { + if (!version.bloom || version.v < 70011) { + utils.debug('Peer does not support bip37. Killing.'); + self.setMisbehavior(peer, 100); + return; + } + } + + if (options.witness) { + if (!version.witness) { + utils.debug('Peer does not support segregated witness. Killing.'); + self.setMisbehavior(peer, 100); + return; + } + } + utils.debug( 'Received version from %s: version=%d height=%d agent=%s', peer.host, version.v, version.height, version.agent); + + self.emit('version', version, peer); }); return peer; @@ -881,7 +910,10 @@ Pool.prototype._addLeech = function _addLeech(socket) { peer = this._createPeer({ socket: socket, - priority: false + priority: false, + network: false, + spv: false, + witness: false }); assert(peer); @@ -958,7 +990,10 @@ Pool.prototype._addPeer = function _addPeer() { peer = this._createPeer({ seed: seed, - priority: false + priority: false, + network: true, + spv: this.options.spv, + witness: this.options.witness }); this.peers.pending.push(peer); diff --git a/lib/bcoin/protocol/constants.js b/lib/bcoin/protocol/constants.js index 98a182d7..06692234 100644 --- a/lib/bcoin/protocol/constants.js +++ b/lib/bcoin/protocol/constants.js @@ -8,13 +8,17 @@ var bcoin = require('../../bcoin'); var bn = require('bn.js'); var utils = bcoin.utils; -var i; - exports.minVersion = 70001; exports.version = 70002; +// exports.maxMessage = 2 * 1024 * 1024; // main +exports.maxMessage = 4 * 1000 * 1000; // segwit +exports.bcoinServices = 0; exports.services = { - network: 1 + network: (1 << 0), + getutxo: (1 << 1), + bloom: (1 << 2), + witness: (1 << 3) }; exports.inv = { diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 6f059a92..2eddb154 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -157,7 +157,7 @@ Framer.address = function addr(data, full) { data.ts = utils.now() - (process.uptime() | 0); if (!data.services) - data.services = constants.services.network; + data.services = 0; if (!data.ipv4) data.ipv4 = new Buffer([]); @@ -206,21 +206,30 @@ Framer.version = function version(options) { if (!options) options = {}; + if (!options.remote) + options.remote = {}; + + if (!options.local) + options.local = {}; + + if (options.local.services == null) + options.local.services = constants.bcoinServices; + // Version off += utils.writeU32(p, constants.version, off); // Services - off += utils.writeU64(p, constants.services.network, off); + off += utils.writeU64(p, constants.bcoinServices, off); // Timestamp off += utils.write64(p, utils.now(), off); // Their address (recv) - remote = Framer.address(options.remote || {}); + remote = Framer.address(options.remote); off += utils.copy(remote, p, off); // Our address (from) - local = Framer.address(options.local || {}); + local = Framer.address(options.local); off += utils.copy(local, p, off); // Nonce, very dramatic diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 7979384f..514f0744 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -67,6 +67,9 @@ Parser.prototype.feed = function feed(data) { }; Parser.prototype.parse = function parse(chunk) { + if (chunk.length > constants.maxMessage) + return this._error('Packet too large: %dmb.', utils.mb(chunk.length)); + if (this.packet === null) { this.packet = this.parseHeader(chunk) || {}; return; @@ -95,9 +98,8 @@ Parser.prototype.parseHeader = function parseHeader(h) { magic = utils.readU32(h, 0); - if (magic !== network.magic) { + if (magic !== network.magic) return this._error('Invalid magic value: ' + magic.toString(16)); - } // Count length of the cmd for (i = 0; h[i + 4] !== 0 && i < 12; i++); @@ -108,6 +110,9 @@ Parser.prototype.parseHeader = function parseHeader(h) { cmd = h.slice(4, 4 + i).toString('ascii'); this.waiting = utils.readU32(h, 16); + if (this.waiting > constants.maxMessage) + return this._error('Packet length too large: %dmb', utils.mb(this.waiting)); + return { cmd: cmd, length: this.waiting, @@ -216,6 +221,10 @@ Parser.parseVersion = function parseVersion(p) { return { v: v, services: services, + network: (services & constants.services.network) !== 0, + getutxo: (services & constants.services.getutxo) !== 0, + bloom: (services & constants.services.bloom) !== 0, + witness: (services & constants.services.witness) !== 0, ts: ts, local: recv, remote: from, @@ -800,6 +809,10 @@ Parser.parseAddress = function parseAddress(p, off, full) { return { ts: ts, services: services, + network: (services & constants.services.network) !== 0, + getutxo: (services & constants.services.getutxo) !== 0, + bloom: (services & constants.services.bloom) !== 0, + witness: (services & constants.services.witness) !== 0, ipv6: utils.array2ip(ip, 6), ipv4: utils.array2ip(ip, 4), port: port