diff --git a/lib/block/blockheader.js b/lib/block/blockheader.js index 029fe25..2683ad1 100644 --- a/lib/block/blockheader.js +++ b/lib/block/blockheader.js @@ -9,6 +9,8 @@ var Hash = require('../crypto/hash'); var JSUtil = require('../util/js'); var $ = require('../util/preconditions'); +var GENESIS_BITS = 0x1d00ffff; + /** * Instantiate a BlockHeader from a Buffer, JSON object, or Object with * the properties of the BlockHeader @@ -199,18 +201,36 @@ BlockHeader.prototype.toBufferWriter = function toBufferWriter(bw) { }; /** - * @link https://en.bitcoin.it/wiki/Difficulty - * @returns {BN} - An instance of BN with the decoded difficulty bits + * Returns the target difficulty for this block + * @param {Number} bits + * @returns {BN} An instance of BN with the decoded difficulty bits */ -BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(info) { - var target = new BN(this.bits & 0xffffff); - var mov = 8 * ((this.bits >>> 24) - 3); +BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(bits) { + bits = bits || this.bits; + + var target = new BN(bits & 0xffffff); + var mov = 8 * ((bits >>> 24) - 3); while (mov-- > 0) { target = target.mul(new BN(2)); } return target; }; +/** + * @link https://en.bitcoin.it/wiki/Difficulty + * @return {Number} + */ +BlockHeader.prototype.getDifficulty = function getDifficulty() { + var difficulty1TargetBN = this.getTargetDifficulty(GENESIS_BITS).mul(new BN(Math.pow(10, 8))); + var currentTargetBN = this.getTargetDifficulty(); + + var difficultyString = difficulty1TargetBN.div(currentTargetBN).toString(10); + var decimalPos = difficultyString.length - 8; + difficultyString = difficultyString.slice(0, decimalPos) + '.' + difficultyString.slice(decimalPos); + + return parseFloat(difficultyString); +}; + /** * @returns {Buffer} - The little endian hash buffer of the header */ diff --git a/test/block/blockheader.js b/test/block/blockheader.js index 1a37764..4bf53ae 100644 --- a/test/block/blockheader.js +++ b/test/block/blockheader.js @@ -248,6 +248,42 @@ describe('BlockHeader', function() { }); + describe('#getDifficulty', function() { + it('should get the correct difficulty for block 86756', function() { + var x = BlockHeader.fromRawBlock(dataRawBlockBuffer); + x.bits.should.equal(0x1c3fffc0); + x.getDifficulty().should.equal(4); + }); + + it('should get the correct difficulty for testnet block 552065', function() { + var x = new BlockHeader({ + bits: 0x1b00c2a8 + }); + x.getDifficulty().should.equal(86187.62562209); + }); + + it('should get the correct difficulty for livenet block 373043', function() { + var x = new BlockHeader({ + bits: 0x18134dc1 + }); + x.getDifficulty().should.equal(56957648455.01001); + }); + + it('should get the correct difficulty for livenet block 340000', function() { + var x = new BlockHeader({ + bits: 0x1819012f + }); + x.getDifficulty().should.equal(43971662056.08958); + }); + + it('should use exponent notation if difficulty is larger than Javascript number', function() { + var x = new BlockHeader({ + bits: 0x0900c2a8 + }); + x.getDifficulty().should.equal(1.9220482782645836 * 1e48); + }); + }); + it('coverage: caches the "_id" property', function() { var blockHeader = BlockHeader.fromRawBlock(dataRawBlockBuffer); blockHeader.id.should.equal(blockHeader.id);