profiler. refactoring.
This commit is contained in:
parent
afd6ee15c9
commit
a9c116c98c
@ -47,38 +47,6 @@ function AbstractBlock(data) {
|
|||||||
this.lowVersion = this.version & 7;
|
this.lowVersion = this.version & 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractBlock.prototype.getMerkleBranch = function getMerkleBranch(index) {
|
|
||||||
var tree = utils.buildMerkleTree(this.merkleRoot);
|
|
||||||
var branch = [];
|
|
||||||
var j = 0;
|
|
||||||
for (var size = this.totalTX; size > 1; size = (size + 1) / 2 | 0) {
|
|
||||||
var i = Math.min(index ^ 1, size - 1);
|
|
||||||
branch.push(tree[j + i]);
|
|
||||||
index >>= 1;
|
|
||||||
j += size;
|
|
||||||
}
|
|
||||||
return branch;
|
|
||||||
};
|
|
||||||
|
|
||||||
AbstractBlock.prototype.hasMerkleItem = function hasMerkleItem(hash, branch, index) {
|
|
||||||
if (index === -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (typeof hash === 'string')
|
|
||||||
hash = new Buffer(hash, 'hex');
|
|
||||||
|
|
||||||
for (var i = 0; i < branch.length; i++) {
|
|
||||||
var otherside = branch[i];
|
|
||||||
if (index & 1)
|
|
||||||
hash = utils.dsha256(Buffer.concat([otherside, hash]));
|
|
||||||
else
|
|
||||||
hash = utils.dsha256(Buffer.concat([hash, otherside]));
|
|
||||||
index >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.toHex(hash) === this.merkleRoot;
|
|
||||||
};
|
|
||||||
|
|
||||||
AbstractBlock.prototype.hash = function hash(enc) {
|
AbstractBlock.prototype.hash = function hash(enc) {
|
||||||
if (!this._hash)
|
if (!this._hash)
|
||||||
this._hash = utils.dsha256(this.abbr());
|
this._hash = utils.dsha256(this.abbr());
|
||||||
|
|||||||
@ -1172,9 +1172,14 @@ Chain.prototype.add = function add(initial, peer, callback, force) {
|
|||||||
// validated, and emitted. Hopefully the deserialized
|
// validated, and emitted. Hopefully the deserialized
|
||||||
// blocks get cleaned up by the GC quickly.
|
// blocks get cleaned up by the GC quickly.
|
||||||
if (block.type === 'compactblock') {
|
if (block.type === 'compactblock') {
|
||||||
block = block.toBlock(peer);
|
try {
|
||||||
if (!block)
|
block = block.toBlock();
|
||||||
return done(new Error('Failed to parse block.'));
|
} catch (e) {
|
||||||
|
// Ugly hack to handle
|
||||||
|
// the error properly.
|
||||||
|
peer.parser.emit('error', e);
|
||||||
|
return done(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do "contextual" verification on our block
|
// Do "contextual" verification on our block
|
||||||
@ -1326,6 +1331,10 @@ Chain.prototype.add = function add(initial, peer, callback, force) {
|
|||||||
// Keep track of total blocks handled.
|
// Keep track of total blocks handled.
|
||||||
self.total += total;
|
self.total += total;
|
||||||
|
|
||||||
|
// Take heap snapshot for debugging.
|
||||||
|
if (self.total % 10 === 0)
|
||||||
|
bcoin.profiler.snapshot();
|
||||||
|
|
||||||
// We intentionally did not asyncify the
|
// We intentionally did not asyncify the
|
||||||
// callback so if it calls chain.add, it
|
// callback so if it calls chain.add, it
|
||||||
// still gets added to the queue. The
|
// still gets added to the queue. The
|
||||||
|
|||||||
@ -38,17 +38,7 @@ CompactBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CompactBlock.prototype.toBlock = function toBlock(peer) {
|
CompactBlock.prototype.toBlock = function toBlock(peer) {
|
||||||
var block;
|
return new bcoin.block(bcoin.protocol.parser.parseBlock(this._raw));
|
||||||
|
|
||||||
// XXX Hack
|
|
||||||
try {
|
|
||||||
block = bcoin.protocol.parser.parseBlock(this._raw);
|
|
||||||
} catch (e) {
|
|
||||||
peer.parser.emit('error', e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new bcoin.block(block);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -13,38 +13,43 @@ var profiler;
|
|||||||
if (bcoin.profile && !bcoin.isBrowser)
|
if (bcoin.profile && !bcoin.isBrowser)
|
||||||
profiler = require('v8-' + 'profiler');
|
profiler = require('v8-' + 'profiler');
|
||||||
|
|
||||||
|
if (profiler) {
|
||||||
|
utils.nextTick(function() {
|
||||||
|
utils.debug('Starting node with profiler enabled.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Profile
|
* Profile
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Profile(name) {
|
function Profile(name) {
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
if (!name)
|
name = 'profile-' + (name ? name + '-' : '') + Profile.uid++;
|
||||||
name = '';
|
|
||||||
name += '-' + Profile.uid++;
|
|
||||||
this.profile = profiler.startProfiling(name, true);
|
this.profile = profiler.startProfiling(name, true);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
utils.debug('Starting CPU profile: %s', this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Profile.uid = 0;
|
Profile.uid = 0;
|
||||||
|
|
||||||
Profile.prototype.stopProfiling = function stopProfiling(callback) {
|
Profile.prototype.stopProfiling = function stopProfiling() {
|
||||||
if (!profiler)
|
if (!profiler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(this.profile);
|
assert(this.profile);
|
||||||
|
|
||||||
this.profile.stopProfiling();
|
return this.profile.stopProfiling();
|
||||||
};
|
};
|
||||||
|
|
||||||
Profile.prototype.del = function del(callback) {
|
Profile.prototype.del = function del() {
|
||||||
if (!profiler)
|
if (!profiler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(this.profile);
|
assert(this.profile);
|
||||||
|
|
||||||
this.profile['delete']();
|
return this.profile['delete']();
|
||||||
};
|
};
|
||||||
|
|
||||||
Profile.prototype.save = function save(callback) {
|
Profile.prototype.save = function save(callback) {
|
||||||
@ -57,22 +62,20 @@ Profile.prototype.save = function save(callback) {
|
|||||||
|
|
||||||
assert(this.profile);
|
assert(this.profile);
|
||||||
|
|
||||||
this.profile['export'](function(err, result) {
|
utils.debug('Saving CPU profile: %s', this.name);
|
||||||
|
|
||||||
|
return this.profile['export'](function(err, result) {
|
||||||
var file;
|
var file;
|
||||||
|
|
||||||
if (err) {
|
self.profile['delete']();
|
||||||
self.profile['delete']();
|
delete self.profile;
|
||||||
delete self.profile;
|
|
||||||
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
|
||||||
|
|
||||||
file = bcoin.prefix + '/profile-' + self.name + '.json';
|
file = bcoin.prefix + '/' + self.name + '.cpuprofile';
|
||||||
|
|
||||||
fs.writeFile(file, result, function(err) {
|
fs.writeFile(file, result, callback);
|
||||||
self.profile['delete']();
|
|
||||||
delete self.profile;
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,11 +85,10 @@ Profile.prototype.save = function save(callback) {
|
|||||||
|
|
||||||
function Snapshot(name) {
|
function Snapshot(name) {
|
||||||
if (profiler) {
|
if (profiler) {
|
||||||
if (!name)
|
name = 'snapshot-' + (name ? name + '-' : '') + Snapshot.uid++;
|
||||||
name = '';
|
|
||||||
name += '-' + Snapshot.uid++;
|
|
||||||
this.snapshot = profiler.takeSnapshot(name);
|
this.snapshot = profiler.takeSnapshot(name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
utils.debug('Taking heap snapshot: %s', this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,22 +131,20 @@ Snapshot.prototype.save = function save(callback) {
|
|||||||
|
|
||||||
assert(this.snapshot);
|
assert(this.snapshot);
|
||||||
|
|
||||||
this.snapshot['export'](function(err, result) {
|
utils.debug('Saving heap snapshot: %s', this.name);
|
||||||
|
|
||||||
|
return this.snapshot['export'](function(err, result) {
|
||||||
var file;
|
var file;
|
||||||
|
|
||||||
if (err) {
|
self.snapshot['delete']();
|
||||||
self.profile['delete']();
|
delete self.snapshot;
|
||||||
delete self.profile;
|
|
||||||
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
|
||||||
|
|
||||||
file = bcoin.prefix + '/snapshot-' + self.name + '.json';
|
file = bcoin.prefix + '/' + self.name + '.heapsnapshot';
|
||||||
|
|
||||||
fs.writeFile(file, result, function(err) {
|
fs.writeFile(file, result, callback);
|
||||||
self.snapshot['delete']();
|
|
||||||
delete self.snapshot;
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -168,6 +168,9 @@ exports.snapshot = function snapshot(name, callback) {
|
|||||||
name = null;
|
name = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!profiler)
|
||||||
|
return callback ? utils.nextTick(callback) : null;
|
||||||
|
|
||||||
snapshot = new Snapshot(name);
|
snapshot = new Snapshot(name);
|
||||||
snapshot.save(callback);
|
snapshot.save(callback);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1628,7 +1628,42 @@ utils.getMerkleRoot = function getMerkleRoot(items) {
|
|||||||
return tree[tree.length - 1];
|
return tree[tree.length - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hook into bn here to ensure we get a toBuffer() method.
|
utils.getMerkleBranch = function getMerkleBranch(index, hashes) {
|
||||||
bn.prototype.toBuffer = function toBuffer(order, size) {
|
var tree = utils.buildMerkleTree(hashes);
|
||||||
return new Buffer(this.toArray(order, size));
|
var branch = [];
|
||||||
|
var size = this.totalTX;
|
||||||
|
var j = 0;
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (; size > 1; size = (size + 1) / 2 | 0) {
|
||||||
|
i = Math.min(index ^ 1, size - 1);
|
||||||
|
branch.push(tree[j + i]);
|
||||||
|
index >>= 1;
|
||||||
|
j += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return branch;
|
||||||
|
};
|
||||||
|
|
||||||
|
utils.checkMerkleBranch = function checkMerkleBranch(hash, branch, index) {
|
||||||
|
var otherside, i;
|
||||||
|
|
||||||
|
if (index === -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (typeof hash === 'string')
|
||||||
|
hash = new Buffer(hash, 'hex');
|
||||||
|
|
||||||
|
for (i = 0; i < branch.length; i++) {
|
||||||
|
otherside = branch[i];
|
||||||
|
|
||||||
|
if (index & 1)
|
||||||
|
hash = utils.dsha256(Buffer.concat([otherside, hash]));
|
||||||
|
else
|
||||||
|
hash = utils.dsha256(Buffer.concat([hash, otherside]));
|
||||||
|
|
||||||
|
index >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user