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._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();
};

View File

@ -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;
};