@@ -8,6 +8,7 @@ var BufferWriter = require('../encoding/bufferwriter');
88var Hash = require ( '../crypto/hash' ) ;
99var JSUtil = require ( '../util/js' ) ;
1010var Transaction = require ( '../transaction' ) ;
11+ var errors = require ( '../errors' ) ;
1112var $ = require ( '../util/preconditions' ) ;
1213
1314/**
@@ -63,6 +64,7 @@ function MerkleBlock(arg) {
6364 _ . extend ( this , info ) ;
6465 this . _flagBitsUsed = 0 ;
6566 this . _hashesUsed = 0 ;
67+
6668 return this ;
6769}
6870
@@ -149,26 +151,61 @@ MerkleBlock.prototype.validMerkleTree = function validMerkleTree() {
149151 return BufferUtil . equals ( root , this . header . merkleRoot ) ;
150152} ;
151153
154+ /**
155+ * Return a list of all the txs hash that match the filter
156+ * @returns {Array } - txs hash that match the filter
157+ */
158+ MerkleBlock . prototype . filterdTxsHash = function filterdTxsHash ( ) {
159+ $ . checkState ( _ . isArray ( this . flags ) , 'MerkleBlock flags is not an array' ) ;
160+ $ . checkState ( _ . isArray ( this . hashes ) , 'MerkleBlock hashes is not an array' ) ;
161+
162+ // Can't have more hashes than numTransactions
163+ if ( this . hashes . length > this . numTransactions ) {
164+ throw new errors . MerkleBlock . InvalidMerkleTree ( ) ;
165+ }
166+
167+ // Can't have more flag bits than num hashes
168+ if ( this . flags . length * 8 < this . hashes . length ) {
169+ throw new errors . MerkleBlock . InvalidMerkleTree ( ) ;
170+ }
171+
172+ // If there is only one hash the filter do not match any txs in the block
173+ if ( this . hashes . length === 1 ) {
174+ return [ ] ;
175+ } ;
176+
177+ var height = this . _calcTreeHeight ( ) ;
178+ var opts = { hashesUsed : 0 , flagBitsUsed : 0 } ;
179+ var txs = this . _traverseMerkleTree ( height , 0 , opts , true ) ;
180+ if ( opts . hashesUsed !== this . hashes . length ) {
181+ throw new errors . MerkleBlock . InvalidMerkleTree ( ) ;
182+ }
183+ return txs ;
184+ } ;
185+
152186/**
153187 * Traverse a the tree in this MerkleBlock, validating it along the way
154188 * Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract()
155189 * @param {Number } - depth - Current height
156190 * @param {Number } - pos - Current position in the tree
157191 * @param {Object } - opts - Object with values that need to be mutated throughout the traversal
192+ * @param {Boolean } - checkForTxs - if true return opts.txs else return the Merkle Hash
158193 * @param {Number } - opts.flagBitsUsed - Number of flag bits used, should start at 0
159194 * @param {Number } - opts.hashesUsed - Number of hashes used, should start at 0
160- * @param {Array } - opts.txs - Will finish populated by transactions found during traversal
195+ * @param {Array } - opts.txs - Will finish populated by transactions found during traversal that match the filter
161196 * @returns {Buffer|null } - Buffer containing the Merkle Hash for that height
197+ * @returns {Array } - transactions found during traversal that match the filter
162198 * @private
163199 */
164- MerkleBlock . prototype . _traverseMerkleTree = function traverseMerkleTree ( depth , pos , opts ) {
200+ MerkleBlock . prototype . _traverseMerkleTree = function traverseMerkleTree ( depth , pos , opts , checkForTxs ) {
165201 /* jshint maxcomplexity: 12*/
166202 /* jshint maxstatements: 20 */
167203
168204 opts = opts || { } ;
169205 opts . txs = opts . txs || [ ] ;
170206 opts . flagBitsUsed = opts . flagBitsUsed || 0 ;
171207 opts . hashesUsed = opts . hashesUsed || 0 ;
208+ var checkForTxs = checkForTxs || false ;
172209
173210 if ( opts . flagBitsUsed > this . flags . length * 8 ) {
174211 return null ;
@@ -189,7 +226,11 @@ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, p
189226 if ( pos * 2 + 1 < this . _calcTreeWidth ( depth - 1 ) ) {
190227 right = this . _traverseMerkleTree ( depth - 1 , pos * 2 + 1 , opts ) ;
191228 }
192- return Hash . sha256sha256 ( new Buffer . concat ( [ left , right ] ) ) ;
229+ if ( checkForTxs ) {
230+ return opts . txs ;
231+ } else {
232+ return Hash . sha256sha256 ( new Buffer . concat ( [ left , right ] ) ) ;
233+ } ;
193234 }
194235} ;
195236
0 commit comments