From e66f2f50bf3246d858147ac2e59e2b3c9b8a8490 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 23 May 2014 23:08:59 -0500 Subject: [PATCH] block: build merkleTree to verify merkleRoot on regular blocks. --- lib/bcoin/block.js | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 330259ea..40435029 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -1,4 +1,5 @@ var bcoin = require('../bcoin'); +var hash = require('hash.js'); var utils = bcoin.utils; function Block(data, subtype) { @@ -36,6 +37,7 @@ function Block(data, subtype) { return tx.hash('hex'); }); this.tx = this.hashes.slice(); + this.invalid = !this._checkBlock(); } this._hash = null; @@ -80,7 +82,6 @@ Block.prototype._verifyMerkle = function verifyMerkle() { var height = 0; if (this.subtype === 'block') { - this.invalid = !utils.testTarget(this.bits, this.hash()); return; } @@ -158,3 +159,38 @@ Block.fromJSON = function fromJSON(json) { return block; }; + +Block.prototype._phash = function phash(p1begin, p1end, p2begin, p2end) { + var pblank = ''; + var hash1 = hash.sha256(); + hash1.update(p1begin === p1end ? pblank : p1begin, 'hex'); + hash1.update(p2begin === p2end ? pblank : p2begin, 'hex'); + hash1 = hash1.digest('hex'); + var hash2 = hash.sha256(); + hash2.update(hash1, 'hex'); + hash2 = hash2.digest('hex'); + return hash2; +}; + +Block.prototype._buildMerkle = function buildMerkle() { + var merkleTree = []; + for (var i = 0; i < this.txs.length; i++) { + merkleTree.push(this.txs[i].hash('hex')); + } + var j = 0; + for (var size = this.txs.length; size > 1; size = ((size + 1) / 2) | 0) { + for (var i = 0; i < size; i += 2) { + var i2 = Math.min(i + 1, size - 1); + merkleTree.push( + this._phash(merkleTree[j+i], merkleTree[j+i+1], + merkleTree[j+i2], merkleTree[j+i2+1])); + } + j += size; + } + return merkleTree; +}; + +Block.prototype._checkBlock = function checkBlock() { + this.merkleTree = this._buildMerkle(); + return this.merkleTree[this.merkleTree.length-1] === this.merkleRoot; +};