block: do not cache height parsing.

This commit is contained in:
Christopher Jeffrey 2017-02-23 20:54:41 -08:00
parent a535d7d414
commit 914b66b94f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 58 additions and 42 deletions

View File

@ -37,8 +37,6 @@ function Block(options) {
this.txs = []; this.txs = [];
this._cbHeight = null;
this._raw = null; this._raw = null;
this._size = -1; this._size = -1;
this._witness = -1; this._witness = -1;
@ -253,7 +251,7 @@ Block.prototype.addTX = function addTX(tx) {
/** /**
* Test the block's transaction vector against a hash. * Test the block's transaction vector against a hash.
* @param {Hash|TX} hash * @param {Hash} hash
* @returns {Boolean} * @returns {Boolean}
*/ */
@ -263,7 +261,7 @@ Block.prototype.hasTX = function hasTX(hash) {
/** /**
* Find the index of a transaction in the block. * Find the index of a transaction in the block.
* @param {Hash|TX} hash * @param {Hash} hash
* @returns {Number} index (-1 if not present). * @returns {Number} index (-1 if not present).
*/ */
@ -506,20 +504,15 @@ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
if (this.version < 2) if (this.version < 2)
return -1; return -1;
if (this._cbHeight != null) if (this.txs.length === 0)
return this._cbHeight; return -1;
coinbase = this.txs[0]; coinbase = this.txs[0];
if (!coinbase || coinbase.inputs.length === 0) if (coinbase.inputs.length === 0)
return -1; return -1;
height = coinbase.inputs[0].script.getCoinbaseHeight(); return coinbase.inputs[0].script.getCoinbaseHeight();
if (!this.mutable)
this._cbHeight = height;
return height;
}; };
/** /**
@ -528,7 +521,7 @@ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
*/ */
Block.prototype.getClaimed = function getClaimed() { Block.prototype.getClaimed = function getClaimed() {
assert(this.txs[0]); assert(this.txs.length > 0);
assert(this.txs[0].isCoinbase()); assert(this.txs[0].isCoinbase());
return this.txs[0].getOutputValue(); return this.txs[0].getOutputValue();
}; };

View File

@ -13,6 +13,7 @@ var Block = require('./block');
var Script = require('../script/script'); var Script = require('../script/script');
var Headers = require('./headers'); var Headers = require('./headers');
var BufferReader = require('../utils/reader'); var BufferReader = require('../utils/reader');
var DUMMY = new Buffer(0);
/** /**
* A block object which is essentially a "placeholder" * A block object which is essentially a "placeholder"
@ -39,8 +40,7 @@ function MemBlock() {
if (!(this instanceof MemBlock)) if (!(this instanceof MemBlock))
return new MemBlock(); return new MemBlock();
this._cbHeight = -1; this._raw = DUMMY;
this._raw = null;
} }
util.inherits(MemBlock, AbstractBlock); util.inherits(MemBlock, AbstractBlock);
@ -84,13 +84,57 @@ MemBlock.prototype.verifyBody = function verifyBody(ret) {
}; };
/** /**
* Retrieve the coinbase height from the coinbase input script (already * Retrieve the coinbase height
* extracted in actuality). * from the coinbase input script.
* @returns {Number} height (-1 if not present). * @returns {Number} height (-1 if not present).
*/ */
MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() { 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) { MemBlock.prototype.fromRaw = function fromRaw(data) {
var br = new BufferReader(data, true); var br = new BufferReader(data, true);
var height = -1;
var count, script;
this.parseAbbr(br); 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; this._raw = br.data;
return this; return this;
@ -167,10 +190,10 @@ MemBlock.prototype.toNormal = function toNormal() {
MemBlock.prototype.toBlock = function toBlock() { MemBlock.prototype.toBlock = function toBlock() {
var block = Block.fromRaw(this._raw); var block = Block.fromRaw(this._raw);
block._hash = this._hash; block._hash = this._hash;
block._hhash = this._hhash; block._hhash = this._hhash;
block._cbHeight = this._cbHeight;
this._raw = null;
return block; return block;
}; };