From afd6ee15c9c084a1f65565f6b45f92c63721be1a Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 24 Feb 2016 23:45:14 -0800 Subject: [PATCH] getblocks. parser/framer fixes. add profiler. --- lib/bcoin.js | 2 + lib/bcoin/pool.js | 14 +-- lib/bcoin/profiler.js | 173 +++++++++++++++++++++++++++++++++++ lib/bcoin/protocol/framer.js | 4 +- package.json | 5 +- test/block-test.js | 2 +- test/protocol-test.js | 2 +- test/tx-test.js | 2 +- 8 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 lib/bcoin/profiler.js diff --git a/lib/bcoin.js b/lib/bcoin.js index 17c0312c..35e52f98 100644 --- a/lib/bcoin.js +++ b/lib/bcoin.js @@ -14,6 +14,7 @@ bcoin.isBrowser = bcoin.prefix = process.env.BCOIN_PREFIX || process.env.HOME + '/.bcoin'; bcoin.debug = +process.env.BCOIN_DEBUG === 1; bcoin.debugFile = +process.env.BCOIN_DEBUGFILE !== 0; +bcoin.profile = +process.env.BCOIN_PROFILE === 1; bcoin.ensurePrefix = function ensurePrefix() { if (!bcoin.fs) @@ -56,6 +57,7 @@ assert(!bcoin.ecdsa.keypair); bcoin.ecdsa.keypair = require('elliptic/lib/elliptic/ec/key'); bcoin.utils = require('./bcoin/utils'); +bcoin.profiler = require('./bcoin/profiler'); bcoin.ec = require('./bcoin/ec'); bcoin.lru = require('./bcoin/lru'); bcoin.protocol = require('./bcoin/protocol'); diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 468d1991..80a26773 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -582,10 +582,12 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) { hashes.length, peer.host); - if (hashes.length > 500) { - this.setMisbehavior(peer, 100); - return; - } + // Normally this is 500, but with older + // versions locator.GetDistanceBack() is called. + // if (hashes.length > 500) { + // this.setMisbehavior(peer, 100); + // return; + // } this.emit('blocks', hashes); @@ -614,10 +616,10 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) { // from the last hash. if (i === hashes.length - 1) { // Request more hashes: - self.getBlocks(peer, hash, null); + // self.getBlocks(peer, hash, null); // Re-download the block (traditional method): - // self.getData(peer, self.block.type, hash, { force: true }); + self.getData(peer, self.block.type, hash, { force: true }); continue; } diff --git a/lib/bcoin/profiler.js b/lib/bcoin/profiler.js new file mode 100644 index 00000000..ef5a224d --- /dev/null +++ b/lib/bcoin/profiler.js @@ -0,0 +1,173 @@ +/** + * profiler.js - profiler for bcoin + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * https://github.com/indutny/bcoin + */ + +var bcoin = require('../bcoin'); +var utils = bcoin.utils; +var assert = utils.assert; +var fs = bcoin.fs; +var profiler; + +if (bcoin.profile && !bcoin.isBrowser) + profiler = require('v8-' + 'profiler'); + +/** + * Profile + */ + +function Profile(name) { + if (profiler) { + if (!name) + name = ''; + name += '-' + Profile.uid++; + this.profile = profiler.startProfiling(name, true); + this.name = name; + } +} + +Profile.uid = 0; + +Profile.prototype.stopProfiling = function stopProfiling(callback) { + if (!profiler) + return; + + assert(this.profile); + + this.profile.stopProfiling(); +}; + +Profile.prototype.del = function del(callback) { + if (!profiler) + return; + + assert(this.profile); + + this.profile['delete'](); +}; + +Profile.prototype.save = function save(callback) { + var self = this; + + callback = utils.asyncify(callback); + + if (!profiler) + return callback(); + + assert(this.profile); + + this.profile['export'](function(err, result) { + var file; + + if (err) { + self.profile['delete'](); + delete self.profile; + return callback(err); + } + + file = bcoin.prefix + '/profile-' + self.name + '.json'; + + fs.writeFile(file, result, function(err) { + self.profile['delete'](); + delete self.profile; + callback(err); + }); + }); +}; + +/** + * Snapshot + */ + +function Snapshot(name) { + if (profiler) { + if (!name) + name = ''; + name += '-' + Snapshot.uid++; + this.snapshot = profiler.takeSnapshot(name); + this.name = name; + } +} + +Snapshot.uid = 0; + +Snapshot.prototype.compare = function compare(other) { + if (!profiler) + return; + + assert(this.snapshot); + + return this.snapshot.compare(other.snapshot); +}; + +Snapshot.prototype.getHeader = function getHeader() { + if (!profiler) + return; + + assert(this.snapshot); + + return this.snapshot.getHeader(); +}; + +Snapshot.prototype.del = function del() { + if (!profiler) + return; + + assert(this.snapshot); + + return this.snapshot['delete'](); +}; + +Snapshot.prototype.save = function save(callback) { + var self = this; + + callback = utils.asyncify(callback); + + if (!profiler) + return callback(); + + assert(this.snapshot); + + this.snapshot['export'](function(err, result) { + var file; + + if (err) { + self.profile['delete'](); + delete self.profile; + return callback(err); + } + + file = bcoin.prefix + '/snapshot-' + self.name + '.json'; + + fs.writeFile(file, result, function(err) { + self.snapshot['delete'](); + delete self.snapshot; + callback(err); + }); + }); +}; + +/** + * Expose + */ + +exports.startProfiling = function startProfiling(name) { + return new Profile(name); +}; + +exports.takeSnapshot = function takeSnapshot(name) { + return new Snapshot(name); +}; + +exports.snapshot = function snapshot(name, callback) { + var snapshot; + + if (typeof name === 'function') { + callback = name; + name = null; + } + + snapshot = new Snapshot(name); + snapshot.save(callback); +}; diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 2a71eefd..ee6b4e00 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -221,8 +221,8 @@ Framer.version = function version(options) { assert.equal(off, 80); // User-agent - off += utils.writeIntv(p, agent.length, off); - off += utils.copy(agent, p, off); + off += utils.writeIntv(p, options.agent.length, off); + off += utils.copy(options.agent, p, off); // Start height off += utils.writeU32(p, options.height || 0, off); diff --git a/package.json b/package.json index 74e26378..722516cd 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "node": ">= 0.8.0" }, "dependencies": { - "bn.js": "4.6.3", + "bn.js": "4.10.3", "elliptic": "6.0.2", "leveldown": "1.4.4", "levelup": "1.3.1" @@ -42,6 +42,7 @@ "level-js": "2.2.3", "browserify": "13.0.0", "uglify-js": "2.6.1", - "mocha": "1.21.5" + "mocha": "1.21.5", + "v8-profiler": "5.6.0" } } diff --git a/test/block-test.js b/test/block-test.js index 49cbbaba..8354a413 100644 --- a/test/block-test.js +++ b/test/block-test.js @@ -3,7 +3,7 @@ var bn = require('bn.js'); var bcoin = require('../'); describe('Block', function() { - var parser = bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; var block = bcoin.merkleblock({ type: 'block', version: 2, diff --git a/test/protocol-test.js b/test/protocol-test.js index 600dd325..187291f1 100644 --- a/test/protocol-test.js +++ b/test/protocol-test.js @@ -178,7 +178,7 @@ describe('Protocol', function() { 'c9954c44b0ce168bc78efd5f1e1c7db9d6c21b3016599ffffffff01a029' + 'de5c0500000017a9141d9ca71efa36d814424ea6ca1437e67287aebe348' + '700000000', 'hex'); - var tx = parser.parseTX(rawTwoTxs); + var tx = bcoin.protocol.parser.parseTX(rawTwoTxs); assert.deepEqual(tx._raw, rawFirstTx); }); }); diff --git a/test/tx-test.js b/test/tx-test.js index 501b920e..2cc703ee 100644 --- a/test/tx-test.js +++ b/test/tx-test.js @@ -3,7 +3,7 @@ var bn = require('bn.js'); var bcoin = require('../'); describe('TX', function() { - var parser = bcoin.protocol.parser(); + var parser = bcoin.protocol.parser; var raw = '010000000125393c67cd4f581456dd0805fa8e9db3abdf90dbe1d4b53e28' + '6490f35d22b6f2010000006b483045022100f4fa5ced20d2dbd2f905809d' + '79ebe34e03496ef2a48a04d0a9a1db436a211dd202203243d086398feb4a' +