diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 1e3b38b6..87b81aac 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -5,6 +5,7 @@ */ var bcoin = require('../bcoin'); +var bn = require('bn.js'); var utils = bcoin.utils; var constants = bcoin.protocol.constants; var network = bcoin.protocol.network; @@ -253,18 +254,6 @@ Block.prototype._checkBlock = function checkBlock() { return true; }; -Block.prototype.__defineSetter__('height', function(height) { - return this._height = height; -}); - -Block.prototype.__defineGetter__('height', function() { - return this.getHeight(bcoin.chain.global); -}); - -Block.prototype.__defineGetter__('nextBlock', function() { - return this.getNextBlock(bcoin.chain.global); -}); - Block.prototype.getHeight = function getHeight(chain) { if (this._height >= 0) return this._height; @@ -296,19 +285,15 @@ Block.prototype.getNextBlock = function getNextBlock(chain) { return this._nextBlock = next; }; -Block.prototype.__defineGetter__('rhash', function() { - return utils.revHex(this.hash('hex')); -}); - Block.reward = function reward(height) { var halvings = height / network.halvingInterval | 0; var reward; if (height < 0) - return utils.satoshi('0.0'); + return new bn(0); if (halvings >= 64) - return utils.satoshi('0.0'); + return new bn(0); reward = utils.satoshi('50.0'); reward.iushrn(halvings); @@ -316,8 +301,64 @@ Block.reward = function reward(height) { return reward; }; +Block.prototype.getReward = function getReward() { + var reward, base, fee, height; + + if (this._reward) + return this._reward; + + if (this.txs.length === 0 || !this.txs[0].isCoinbase()) { + return this._reward = { + fee: new bn(0), + reward: Block.reward(this.height) + }; + } + + reward = this.txs[0].outputs.reduce(function(total, output) { + total.iadd(output.value); + return total; + }, new bn(0)); + + base = Block.reward(this.height); + + // If height is not accurate, artificially increase + // the reward era until base is smaller than the reward. + height = 0; + while (base.cmp(reward) > 0) { + base = Block.reward(height); + height += constants.halvingInterval; + } + + fee = reward.sub(base); + + return this._reward = { + fee: fee, + reward: reward + }; +}; + +Block.prototype.__defineSetter__('height', function(height) { + return this._height = height; +}); + +Block.prototype.__defineGetter__('height', function() { + return this.getHeight(bcoin.chain.global); +}); + +Block.prototype.__defineGetter__('nextBlock', function() { + return this.getNextBlock(bcoin.chain.global); +}); + +Block.prototype.__defineGetter__('rhash', function() { + return utils.revHex(this.hash('hex')); +}); + Block.prototype.__defineGetter__('reward', function() { - return Block.reward(this.height); + return this.getReward().reward; +}); + +Block.prototype.__defineGetter__('fee', function() { + return this.getReward().fee; }); Block.prototype.inspect = function inspect() { @@ -328,6 +369,8 @@ Block.prototype.inspect = function inspect() { copy.rhash = this.rhash; copy.height = this.height; copy.nextBlock = this.nextBlock; + copy.reward = utils.btc(this.reward); + copy.fee = utils.btc(this.fee); return copy; };