Optimizations for address module blockhandler

- _scriptBuffer instead of reserializing the script
This commit is contained in:
Braydon Fuller 2015-08-04 14:50:15 -04:00
parent 0e57d6f89d
commit dd59d5f64b
6 changed files with 97 additions and 26 deletions

View File

@ -0,0 +1,69 @@
'use strict';
var benchmark = require('benchmark');
var async = require('async');
var memdown = require('memdown');
var Block = require('../lib/block');
var AddressModule = require('../lib/modules/address');
var DB = require('../lib/db');
var maxTime = 20;
var blockData1 = require('./data/block-367238.json');
var blockData2 = require('./data/block-367239.json');
var blockData3 = require('./data/block-367240.json');
console.log('Benchmarking Address Block Handler');
console.log('----------------------------------');
async.series([
function(next) {
var c = 0;
var blocks = [
Block.fromBuffer(new Buffer(blockData1, 'hex')),
Block.fromBuffer(new Buffer(blockData2, 'hex')),
Block.fromBuffer(new Buffer(blockData3, 'hex'))
];
var blocksLength = 3;
var db = new DB({store: memdown});
var addressModule = new AddressModule({db: db});
function blockHandler(deffered) {
if (c >= blocksLength) {
c = 0;
}
var block = blocks[c];
addressModule.blockHandler(block, true, function(err, operations) {
if (err) {
throw err;
}
deffered.resolve();
});
c++;
}
var suite = new benchmark.Suite();
suite.add('blockHandler', blockHandler, {
defer: true,
maxTime: maxTime
});
suite
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
console.log('----------------------------------------------------------------------');
next();
})
.run();
}
], function(err) {
if (err) {
throw err;
}
console.log('Finished');
process.exit();
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -58,8 +58,6 @@ AddressModule.prototype.getPublishEvents = function() {
AddressModule.prototype.blockHandler = function(block, addOutput, callback) {
var txs = this.db.getTransactionsFromBlock(block);
log.debug('Updating output index');
var action = 'put';
if (!addOutput) {
action = 'del';
@ -67,46 +65,47 @@ AddressModule.prototype.blockHandler = function(block, addOutput, callback) {
var operations = [];
for (var i = 0; i < txs.length; i++) {
var transactionLength = txs.length;
for (var i = 0; i < transactionLength; i++) {
var tx = txs[i];
var txid = tx.id;
var inputs = tx.inputs;
var outputs = tx.outputs;
for (var j = 0; j < outputs.length; j++) {
var outputLength = outputs.length;
for (var j = 0; j < outputLength; j++) {
var output = outputs[j];
var script = output.script;
if(!script) {
log.debug('Invalid script');
continue;
}
if (!script.isPublicKeyHashOut() && !script.isScriptHashOut() && !script.isPublicKeyOut()) {
// ignore for now
log.debug('script was not pubkeyhashout, scripthashout, or pubkeyout');
var address = script.toAddress(this.db.network);
if (!address && script.isPublicKeyOut()) {
var pubkey = script.chunks[0].buf;
address = Address.fromPublicKey(new PublicKey(pubkey), this.db.network);
} else if (!address){
continue;
}
var address;
if(script.isPublicKeyOut()) {
var pubkey = script.chunks[0].buf;
address = Address.fromPublicKey(new PublicKey(pubkey), this.db.network);
} else {
address = output.script.toAddress(this.db.network);
}
var outputIndex = j;
var timestamp = block.timestamp.getTime();
var height = block.__height;
var addressStr = address.toString();
var scriptHex = output._scriptBuffer.toString('hex');
var key = [AddressModule.PREFIXES.OUTPUTS, addressStr, timestamp, txid, outputIndex].join('-');
var value = [output.satoshis, scriptHex, height].join(':');
operations.push({
type: action,
key: [AddressModule.PREFIXES.OUTPUTS, address, timestamp, txid, outputIndex].join('-'),
value: [output.satoshis, script, height].join(':')
key: key,
value: value
});
// publish events to any subscribers
@ -203,11 +202,11 @@ AddressModule.prototype.getBalance = function(address, queryMempool, callback) {
});
};
AddressModule.prototype.getOutputs = function(address, queryMempool, callback) {
AddressModule.prototype.getOutputs = function(addressStr, queryMempool, callback) {
var self = this;
var outputs = [];
var key = [AddressModule.PREFIXES.OUTPUTS, address].join('-');
var key = [AddressModule.PREFIXES.OUTPUTS, addressStr].join('-');
var stream = this.db.store.createReadStream({
start: key,
@ -220,7 +219,7 @@ AddressModule.prototype.getOutputs = function(address, queryMempool, callback) {
var value = data.value.split(':');
var output = {
address: key[1],
address: addressStr,
txid: key[3],
outputIndex: Number(key[4]),
satoshis: Number(value[0]),
@ -246,7 +245,7 @@ AddressModule.prototype.getOutputs = function(address, queryMempool, callback) {
}
if(queryMempool) {
outputs = outputs.concat(self.db.bitcoind.getMempoolOutputs(address));
outputs = outputs.concat(self.db.bitcoind.getMempoolOutputs(addressStr));
}
callback(null, outputs);
@ -403,4 +402,4 @@ AddressModule.prototype.getAddressHistory = function(address, queryMempool, call
});
};
module.exports = AddressModule;
module.exports = AddressModule;

View File

@ -74,7 +74,7 @@ describe('AddressModule', function() {
},
value: {
satoshis: 2502227470,
script: 'OP_DUP OP_HASH160 20 0x02a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b OP_EQUALVERIFY OP_CHECKSIG',
script: '76a91402a61d2066d19e9e2fd348a8320b7ebd4dd3ca2b88ac',
blockHeight: 345003
}
},
@ -98,7 +98,7 @@ describe('AddressModule', function() {
},
value: {
satoshis: 3100000,
script: 'OP_DUP OP_HASH160 20 0x9780ccd5356e2acc0ee439ee04e0fe69426c7528 OP_EQUALVERIFY OP_CHECKSIG',
script: '76a9149780ccd5356e2acc0ee439ee04e0fe69426c752888ac',
blockHeight: 345003
}
}