diff --git a/lib/primitives/block.js b/lib/primitives/block.js index c4370bf9..22514404 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -37,8 +37,6 @@ function Block(options) { this.txs = []; - this._cbHeight = null; - this._raw = null; this._size = -1; this._witness = -1; @@ -253,7 +251,7 @@ Block.prototype.addTX = function addTX(tx) { /** * Test the block's transaction vector against a hash. - * @param {Hash|TX} hash + * @param {Hash} hash * @returns {Boolean} */ @@ -263,7 +261,7 @@ Block.prototype.hasTX = function hasTX(hash) { /** * Find the index of a transaction in the block. - * @param {Hash|TX} hash + * @param {Hash} hash * @returns {Number} index (-1 if not present). */ @@ -506,20 +504,15 @@ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() { if (this.version < 2) return -1; - if (this._cbHeight != null) - return this._cbHeight; + if (this.txs.length === 0) + return -1; coinbase = this.txs[0]; - if (!coinbase || coinbase.inputs.length === 0) + if (coinbase.inputs.length === 0) return -1; - height = coinbase.inputs[0].script.getCoinbaseHeight(); - - if (!this.mutable) - this._cbHeight = height; - - return height; + return coinbase.inputs[0].script.getCoinbaseHeight(); }; /** @@ -528,7 +521,7 @@ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() { */ Block.prototype.getClaimed = function getClaimed() { - assert(this.txs[0]); + assert(this.txs.length > 0); assert(this.txs[0].isCoinbase()); return this.txs[0].getOutputValue(); }; diff --git a/lib/primitives/memblock.js b/lib/primitives/memblock.js index 6c685f2e..9b589197 100644 --- a/lib/primitives/memblock.js +++ b/lib/primitives/memblock.js @@ -13,6 +13,7 @@ var Block = require('./block'); var Script = require('../script/script'); var Headers = require('./headers'); var BufferReader = require('../utils/reader'); +var DUMMY = new Buffer(0); /** * A block object which is essentially a "placeholder" @@ -39,8 +40,7 @@ function MemBlock() { if (!(this instanceof MemBlock)) return new MemBlock(); - this._cbHeight = -1; - this._raw = null; + this._raw = DUMMY; } util.inherits(MemBlock, AbstractBlock); @@ -84,13 +84,57 @@ MemBlock.prototype.verifyBody = function verifyBody(ret) { }; /** - * Retrieve the coinbase height from the coinbase input script (already - * extracted in actuality). + * Retrieve the coinbase height + * from the coinbase input script. * @returns {Number} height (-1 if not present). */ MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() { - return this._cbHeight; + if (this.version < 2) + return -1; + + try { + return this.parseCoinbaseHeight(); + } catch (e) { + return -1; + } +}; + +/** + * Parse the coinbase height + * from the coinbase input script. + * @private + * @returns {Number} height (-1 if not present). + */ + +MemBlock.prototype.parseCoinbaseHeight = function parseCoinbaseHeight() { + var br = new BufferReader(this._raw, true); + var count, script; + + br.seek(80); + + count = br.readVarint(); + + if (count === 0) + return -1; + + br.seek(4); + + count = br.readVarint(); + + if (count === 0) { + if (br.readU8() !== 0) + count = br.readVarint(); + } + + if (count === 0) + return -1; + + br.seek(36); + + script = br.readVarBytes(); + + return Script.getCoinbaseHeight(script); }; /** @@ -101,30 +145,9 @@ MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() { MemBlock.prototype.fromRaw = function fromRaw(data) { var br = new BufferReader(data, true); - var height = -1; - var count, script; this.parseAbbr(br); - count = br.readVarint(); - - if (this.version > 1 && count > 0) { - br.seek(4); - count = br.readVarint(); - - if (count === 0) { - if (br.readU8() !== 0) - count = br.readVarint(); - } - - if (count > 0) { - br.seek(36); - script = br.readVarBytes(); - height = Script.getCoinbaseHeight(script); - } - } - - this._cbHeight = height; this._raw = br.data; return this; @@ -167,10 +190,10 @@ MemBlock.prototype.toNormal = function toNormal() { MemBlock.prototype.toBlock = function toBlock() { var block = Block.fromRaw(this._raw); + block._hash = this._hash; block._hhash = this._hhash; - block._cbHeight = this._cbHeight; - this._raw = null; + return block; };