diff --git a/benchmark/script.js b/benchmark/script.js new file mode 100644 index 0000000..76a6320 --- /dev/null +++ b/benchmark/script.js @@ -0,0 +1,79 @@ +'use strict'; + +var benchmark = require('benchmark'); +var bitcore = require('..'); +var async = require('async'); +var blockData = require('./block-357238.json'); + +var maxTime = 10; + +console.log('Benchmarking Script'); +console.log('---------------------------------------'); + +async.series([ + function(next) { + + var c = 0; + var scripts = []; + var block = bitcore.Block.fromString(blockData); + for (var i = 0; i < block.transactions.length; i++) { + var tx = block.transactions[i]; + for (var j = 0; j < tx.inputs.length; j++) { + var input = tx.inputs[j]; + if (input.script) { + scripts.push(input.script); + } + } + } + + function isPublicKeyHashIn() { + if (c >= scripts.length) { + c = 0; + } + scripts[c].isPublicKeyHashIn(true); + c++; + } + + function isPublicKeyHashInAccurate() { + if (c >= scripts.length) { + c = 0; + } + scripts[c].isPublicKeyHashIn(); + c++; + } + + function toAddress() { + if (c >= scripts.length) { + c = 0; + } + scripts[c].toAddress(); + c++; + } + + function getAddressInfo() { + if (c >= scripts.length) { + c = 0; + } + scripts[c].getAddressInfo(); + c++; + } + + var suite = new benchmark.Suite(); + suite.add('isPublicKeyHashIn', isPublicKeyHashIn, {maxTime: maxTime}); + suite.add('isPublicKeyHashIn (accurate)', isPublicKeyHashInAccurate, {maxTime: maxTime}); + suite.add('toAddress', toAddress, {maxTime: maxTime}); + suite.add('getAddressInfo', getAddressInfo, {maxTime: maxTime}); + suite + .on('cycle', function(event) { + console.log(String(event.target)); + }) + .on('complete', function() { + console.log('Done'); + console.log('----------------------------------------------------------------------'); + next(); + }) + .run(); + } +], function(err) { + console.log('Finished'); +}); diff --git a/lib/script/script.js b/lib/script/script.js index f93ace2..3f25faa 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -245,13 +245,33 @@ Script.prototype.isPublicKeyHashOut = function() { }; /** + * @param {boolean} inaccurate - option to disable full (slow) public key validation * @returns {boolean} if this is a pay to public key hash input script */ -Script.prototype.isPublicKeyHashIn = function() { - return this.chunks.length === 2 && - this.chunks[0].buf && - this.chunks[0].buf.length <= 0x49 && - PublicKey.isValid(this.chunks[1].buf); +Script.prototype.isPublicKeyHashIn = function(inaccurate) { + if (this.chunks.length === 2) { + var signatureBuf = this.chunks[0].buf; + var pubkeyBuf = this.chunks[1].buf; + if (signatureBuf && + signatureBuf.length && + signatureBuf[0] === 0x30 && + pubkeyBuf.length + ) { + var version = pubkeyBuf[0]; + var isVersion = false; + if (version === 0x04 && pubkeyBuf.length === 65) { + isVersion = true; + } else if ((version === 0x03 || version === 0x02) && pubkeyBuf.length === 33) { + isVersion = true; + } + if (inaccurate) { + return isVersion; + } else { + return PublicKey.isValid(pubkeyBuf); + } + } + } + return false; }; Script.prototype.getPublicKeyHash = function() { @@ -753,7 +773,7 @@ Script.prototype.getAddressInfo = function() { } else if (this.isPublicKeyHashOut()) { info.hashBuffer = this.getData(); info.type = Address.PayToPublicKeyHash; - } else if (this.isPublicKeyHashIn()) { + } else if (this.isPublicKeyHashIn(true)) { // hash the publickey found in the scriptSig info.hashBuffer = Hash.sha256ripemd160(this.chunks[1].buf); info.type = Address.PayToPublicKeyHash;