Browse Source

add metod filterdTxsHash to MerkleBlock, that return all the txs hash in the block that match the filter (depth === 0 and flag bit is 1)

patch-2
Filippo Merli 9 years ago
parent
commit
5d5f9bacae
  1. 40
      lib/block/merkleblock.js

40
lib/block/merkleblock.js

@ -8,6 +8,7 @@ var BufferWriter = require('../encoding/bufferwriter');
var Hash = require('../crypto/hash'); var Hash = require('../crypto/hash');
var JSUtil = require('../util/js'); var JSUtil = require('../util/js');
var Transaction = require('../transaction'); var Transaction = require('../transaction');
var errors = require('../errors');
var $ = require('../util/preconditions'); var $ = require('../util/preconditions');
/** /**
@ -63,6 +64,7 @@ function MerkleBlock(arg) {
_.extend(this,info); _.extend(this,info);
this._flagBitsUsed = 0; this._flagBitsUsed = 0;
this._hashesUsed = 0; this._hashesUsed = 0;
return this; return this;
} }
@ -149,19 +151,48 @@ MerkleBlock.prototype.validMerkleTree = function validMerkleTree() {
return BufferUtil.equals(root, this.header.merkleRoot); return BufferUtil.equals(root, this.header.merkleRoot);
}; };
/**
* Return a list of all the txs hash that match the filter
* @returns {Array} - txs hash that match the filter
*/
MerkleBlock.prototype.filterdTxsHash = function validMerkleTree() {
$.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array');
$.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array');
// Can't have more hashes than numTransactions
if(this.hashes.length > this.numTransactions) {
throw new errors.MerkleBlock.InvalidMerkleTree();
}
// Can't have more flag bits than num hashes
if(this.flags.length * 8 < this.hashes.length) {
throw new errors.MerkleBlock.InvalidMerkleTree();
}
var height = this._calcTreeHeight();
var opts = { hashesUsed: 0, flagBitsUsed: 0 };
var txs = this._traverseMerkleTree(height, 0, opts, true);
if(opts.hashesUsed !== this.hashes.length) {
throw new errors.MerkleBlock.InvalidMerkleTree();
}
return txs;
};
/** /**
* Traverse a the tree in this MerkleBlock, validating it along the way * Traverse a the tree in this MerkleBlock, validating it along the way
* Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract() * Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract()
* @param {Number} - depth - Current height * @param {Number} - depth - Current height
* @param {Number} - pos - Current position in the tree * @param {Number} - pos - Current position in the tree
* @param {Object} - opts - Object with values that need to be mutated throughout the traversal * @param {Object} - opts - Object with values that need to be mutated throughout the traversal
* @param {Boolean} - checkForTxs - if true return opts.txs else return the Merkle Hash
* @param {Number} - opts.flagBitsUsed - Number of flag bits used, should start at 0 * @param {Number} - opts.flagBitsUsed - Number of flag bits used, should start at 0
* @param {Number} - opts.hashesUsed - Number of hashes used, should start at 0 * @param {Number} - opts.hashesUsed - Number of hashes used, should start at 0
* @param {Array} - opts.txs - Will finish populated by transactions found during traversal * @param {Array} - opts.txs - Will finish populated by transactions found during traversal that match the filter
* @returns {Buffer|null} - Buffer containing the Merkle Hash for that height * @returns {Buffer|null} - Buffer containing the Merkle Hash for that height
* @returns {Array} - transactions found during traversal that match the filter
* @private * @private
*/ */
MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, pos, opts) { MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, pos, opts, checkForTxs) {
/* jshint maxcomplexity: 12*/ /* jshint maxcomplexity: 12*/
/* jshint maxstatements: 20 */ /* jshint maxstatements: 20 */
@ -169,6 +200,7 @@ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, p
opts.txs = opts.txs || []; opts.txs = opts.txs || [];
opts.flagBitsUsed = opts.flagBitsUsed || 0; opts.flagBitsUsed = opts.flagBitsUsed || 0;
opts.hashesUsed = opts.hashesUsed || 0; opts.hashesUsed = opts.hashesUsed || 0;
var checkForTxs = checkForTxs || false;
if(opts.flagBitsUsed > this.flags.length * 8) { if(opts.flagBitsUsed > this.flags.length * 8) {
return null; return null;
@ -189,7 +221,11 @@ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, p
if(pos*2+1 < this._calcTreeWidth(depth-1)) { if(pos*2+1 < this._calcTreeWidth(depth-1)) {
right = this._traverseMerkleTree(depth-1, pos*2+1, opts); right = this._traverseMerkleTree(depth-1, pos*2+1, opts);
} }
if (checkForTxs){
return opts.txs;
} else {
return Hash.sha256sha256(new Buffer.concat([left, right])); return Hash.sha256sha256(new Buffer.concat([left, right]));
};
} }
}; };

Loading…
Cancel
Save