merkleblock/utils: optimize merkle root calculation.

This commit is contained in:
Christopher Jeffrey 2016-07-27 06:28:28 -07:00
parent 868512e054
commit 4e977810ce
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 47 additions and 17 deletions

View File

@ -25,8 +25,11 @@ node.open(function(err) {
if (process.argv.indexOf('--test') !== -1) {
node.pool.watchAddress('1VayNert3x1KzbpzMGt2qdqrAThiRovi8');
node.on('tx', function(tx) {
utils.log(tx);
node.pool.watch(bcoin.outpoint().toRaw());
node.on('block', function(block) {
assert(block.txs.length >= 1);
if (block.txs.length > 1)
utils.log(block.txs[1]);
});
}

View File

@ -429,17 +429,26 @@ crypto.ccmp = function ccmp(a, b) {
crypto.buildMerkleTree = function buildMerkleTree(leaves) {
var tree = leaves.slice();
var size = leaves.length;
var i, j, i2, hash;
var i, j, i2, hash, left, right, buf;
if (size > 1)
buf = new Buffer(64);
for (j = 0; size > 1; size = ((size + 1) / 2) | 0) {
for (i = 0; i < size; i += 2) {
i2 = Math.min(i + 1, size - 1);
left = tree[j + i];
right = tree[j + i2];
if (i2 === i + 1 && i2 + 1 === size
&& tree[j + i].compare(tree[j + i2]) === 0) {
&& left.compare(right) === 0) {
return;
}
hash = Buffer.concat([tree[j + i], tree[j + i2]]);
hash = crypto.hash256(hash);
left.copy(buf, 0);
right.copy(buf, 32);
hash = crypto.hash256(buf);
tree.push(hash);
}
j += size;
@ -498,19 +507,25 @@ crypto.getMerkleBranch = function getMerkleBranch(index, leaves) {
*/
crypto.checkMerkleBranch = function checkMerkleBranch(hash, branch, index) {
var otherside, i;
var i, otherside, buf;
if (index === -1)
return false;
if (branch.length === 0)
return hash;
buf = new Buffer(64);
for (i = 0; i < branch.length; i++) {
otherside = branch[i];
if (index & 1)
hash = crypto.hash256(Buffer.concat([otherside, hash]));
else
hash = crypto.hash256(Buffer.concat([hash, otherside]));
if (index & 1) {
otherside.copy(buf, 0);
hash.copy(buf, 32);
} else {
hash.copy(buf, 0);
otherside.copy(buf, 32);
}
hash = crypto.hash256(buf);
index >>>= 1;
}

View File

@ -162,7 +162,7 @@ MerkleBlock.prototype.extractTree = function extractTree() {
var flags = this.flags;
var totalTX = this.totalTX;
var height = 0;
var root, p;
var root, p, buf;
function width(height) {
return (totalTX + (1 << height) - 1) >>> height;
@ -203,7 +203,10 @@ MerkleBlock.prototype.extractTree = function extractTree() {
right = left;
}
return utils.hash256(Buffer.concat([left, right]));
left.copy(buf, 0);
right.copy(buf, 32);
return utils.hash256(buf);
}
for (p = 0; p < this.hashes.length; p++)
@ -225,6 +228,9 @@ MerkleBlock.prototype.extractTree = function extractTree() {
while (width(height) > 1)
height++;
if (height > 0)
buf = new Buffer(64);
root = traverse(height, 0);
if (failed)
@ -446,7 +452,7 @@ MerkleBlock.fromBlock = function fromBlock(block, filter) {
var leaves = [];
var bits = [];
var hashes = [];
var i, tx, totalTX, height, flags, p, merkle;
var i, tx, totalTX, height, flags, p, merkle, buf;
for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i];
@ -478,7 +484,10 @@ MerkleBlock.fromBlock = function fromBlock(block, filter) {
else
right = left;
return utils.hash256(Buffer.concat([left, right]));
left.copy(buf, 0);
right.copy(buf, 32);
return utils.hash256(buf);
}
function traverse(height, pos, leaves, matches) {
@ -505,6 +514,9 @@ MerkleBlock.fromBlock = function fromBlock(block, filter) {
while (width(height) > 1)
height++;
if (height > 0)
buf = new Buffer(64);
traverse(height, 0, leaves, matches);
flags = new Buffer((bits.length + 7) / 8 | 0);