From 07a67888318233c6704833fb1a4d97483a12c074 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 17 Dec 2015 14:28:13 -0800 Subject: [PATCH] optimize block and tx rendering. script maxes. sync. --- lib/bcoin/block.js | 5 +++++ lib/bcoin/peer.js | 26 ++++++++++++++++++---- lib/bcoin/pool.js | 39 +++++++++++++++++++++++++++++++++ lib/bcoin/protocol/constants.js | 7 ++++++ lib/bcoin/protocol/parser.js | 6 +++-- lib/bcoin/script.js | 6 +++-- lib/bcoin/tx.js | 3 +++ 7 files changed, 84 insertions(+), 8 deletions(-) diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 446e19c5..f2466ada 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -19,6 +19,8 @@ function Block(data, subtype) { return utils.toHex(hash); }); this.flags = data.flags || []; + this._network = data._network || false; + this._raw = data._raw || null; // List of matched TXs this.tx = []; @@ -55,6 +57,9 @@ Block.prototype.hash = function hash(enc) { }; Block.prototype.abbr = function abbr() { + if (this._network) + return this._raw.slice(); + var res = new Array(80); utils.writeU32(res, this.version, 0); utils.copy(utils.toArray(this.prevBlock, 'hex'), res, 4); diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index af5e7aa5..d1e69259 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -95,8 +95,8 @@ Peer.prototype._init = function init() { self.pool.emit('debug', 'Sent version (%s): height=%s', ip, this.pool.chain.getStartHeight()); - self.pool.emit('debug', 'version (%s): sending locator hashes', ip); - self.loadBlocks(self.chain.locatorHashes(), 0); + // self.pool.emit('debug', 'version (%s): sending locator hashes', ip); + // self.loadBlocks(self.chain.locatorHashes(), 0); }); } @@ -122,6 +122,17 @@ Peer.prototype._init = function init() { }); }; +Peer.prototype.startSync = function startSync() { + if (!this.pool.options.fullNode) + return; + + var ip = this.socket && this.socket.remoteAddress || '0.0.0.0'; + + this.pool.emit('debug', 'version (%s): sending locator hashes', ip); + + this.loadBlocks(this.chain.locatorHashes(), 0); +}; + Peer.prototype.broadcast = function broadcast(items) { if (this.destroyed) return; @@ -305,9 +316,11 @@ Peer.prototype._onPacket = function onPacket(packet) { return this._handleGetAddr(); if (cmd === 'merkleblock' || cmd === 'block') { + payload._network = true; payload = bcoin.block(payload, cmd); this.lastBlock = payload; } else if (cmd === 'tx') { + payload._network = true; payload = bcoin.tx(payload, this.lastBlock); } if (this._res(cmd, payload)) @@ -443,14 +456,17 @@ Peer.prototype._handleInv = function handleInv(items) { this.emit('blocks', blocks); if (this.pool.options.fullNode) { + var req = []; for (var i = 0; i < blocks.length; i++) { - var hash = utils.toHex(blocks[i]); + var block = blocks[i]; + var hash = utils.toHex(block); if (this.chain.orphan.bmap[hash]) { this.loadBlocks(this.chain.locatorHashes(), this.chain.getOrphanRoot(hash)); continue; } if (!this.chain.hasBlock(hash)) { - this.getData([{ type: 'block', hash: hash }]); + // this.getData({ type: 'block', hash: hash }); + req.push({ type: 'block', hash: block }); continue; } if (i === blocks.length - 1) { @@ -458,6 +474,8 @@ Peer.prototype._handleInv = function handleInv(items) { continue; } } + if (req.length) + this.getData(req); } if (txs.length === 0) diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index c23a4b6a..bc4a4a03 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -54,6 +54,9 @@ function Pool(options) { this.bloom = new bcoin.bloom(8 * 1024, 10, (Math.random() * 0xffffffff) | 0); + + this.bestHeight = 0; + this.peers = { // Peers that are loading blocks themselves block: [], @@ -399,14 +402,50 @@ Pool.prototype._addPeer = function _addPeer(backoff) { }); peer.on('version', function(version) { + if (version.height > self.bestHeight) + self.bestHeight = version.height; self.emit('version', version, peer); }); + peer.on('ack', function() { + if (self.options.fullNode) { + if (self.peers.block.length >= self.size) + self.startSync(); + } + }); + utils.nextTick(function() { self.emit('peer', peer); }); }; +Pool.prototype.bestPeer = function bestPeer() { + var best = null; + + this.peers.block.forEach(function(peer) { + if (!peer.version || !peer.socket) + return; + if (!best || peer.version.height > best.version.height) + best = peer; + }); + + if (best) + this.emit('debug', 'Best peer: %s', best.socket.remoteAddress); + + return best; +}; + +Pool.prototype.startSync = function startSync(peer) { + if (!this.options.fullNode) + return; + + peer = peer || this.bestPeer(); + if (!peer) + return; + + peer.startSync(); +}; + Pool.prototype._removePeer = function _removePeer(peer) { var i = this.peers.pending.indexOf(peer); if (i !== -1) diff --git a/lib/bcoin/protocol/constants.js b/lib/bcoin/protocol/constants.js index cbd579d0..90af855d 100644 --- a/lib/bcoin/protocol/constants.js +++ b/lib/bcoin/protocol/constants.js @@ -149,6 +149,13 @@ exports.block = { maxOrphanTx: 1000000 / 100 }; +exports.script = { + maxSize: 10000, + maxStack: 1000, + maxPush: 520, + maxOps: 201 +}; + exports.locktimeThreshold = 500000000; // Tue Nov 5 00:53:20 1985 UTC exports.oneHash = utils.toArray( diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index c13bcbd9..f201d3cf 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -221,7 +221,8 @@ Parser.prototype.parseMerkleBlock = function parseMerkleBlock(p) { nonce: readU32(p, 76), totalTX: readU32(p, 80), hashes: hashes, - flags: flags + flags: flags, + _raw: p.slice(0, 80) }; }; @@ -287,7 +288,8 @@ Parser.prototype.parseBlock = function parseBlock(p) { bits: readU32(p, 72), nonce: readU32(p, 76), totalTX: totalTX, - txs: txs + txs: txs, + _raw: p.slice(0, 80) }; }; diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index f0a73188..732356be 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -200,7 +200,7 @@ script._next = function(to, s, pc) { script.execute = function execute(s, stack, tx, index) { s = s.slice(); - if (s.length > 10000) + if (s.length > constants.script.maxOps) return false; var lastSep = -1; @@ -211,6 +211,8 @@ script.execute = function execute(s, stack, tx, index) { var o = s[pc]; if (Array.isArray(o)) { + if (o.length > constants.script.maxPush) + return false; stack.push(o); continue; } @@ -754,7 +756,7 @@ script.execute = function execute(s, stack, tx, index) { } } - if (stack.length + stack.alt.length > 1000) + if (stack.length + stack.alt.length > constants.script.maxStack) return false; return true; diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index bfae68a7..49bb3e27 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -22,6 +22,7 @@ function TX(data, block) { this._hash = null; this._raw = data._raw || null; + this._network = data._network || false; if (data.inputs) { data.inputs.forEach(function(input) { @@ -59,6 +60,8 @@ TX.prototype.hash = function hash(enc) { }; TX.prototype.render = function render() { + if (this._network) + return this._raw.slice(); return bcoin.protocol.framer.tx(this); };