merkleblock/utils: optimize merkle root calculation.
This commit is contained in:
parent
868512e054
commit
4e977810ce
@ -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]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user