Merge branch 'master' into fix/isCoinbaseHash

This commit is contained in:
Daniel Cousens 2016-05-06 14:18:06 +10:00
commit 79ac51dbbd
3 changed files with 82 additions and 0 deletions

View file

@ -1,3 +1,4 @@
var createHash = require('create-hash')
var bufferutils = require('./bufferutils') var bufferutils = require('./bufferutils')
var bcrypto = require('./crypto') var bcrypto = require('./crypto')
var bufferCompare = require('buffer-compare') var bufferCompare = require('buffer-compare')
@ -133,6 +134,35 @@ Block.calculateTarget = function (bits) {
return target return target
} }
Block.calculateMerkleRoot = function (transactions) {
var length = transactions.length
if (length === 0) throw TypeError('Cannot compute merkle root for zero transactions')
var hashes = transactions.map(function (transaction) { return transaction.getHash() })
while (length > 1) {
var j = 0
for (var i = 0; i < length; i += 2, ++j) {
var hasher = createHash('sha256')
hasher.update(hashes[i])
hasher.update(i + 1 !== length ? hashes[i + 1] : hashes[i])
hashes[j] = bcrypto.sha256(hasher.digest())
}
length = j
}
return hashes[0]
}
Block.prototype.checkMerkleRoot = function () {
if (!this.transactions) return false
var actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
return bufferCompare(this.merkleRoot, actualMerkleRoot) === 0
}
Block.prototype.checkProofOfWork = function () { Block.prototype.checkProofOfWork = function () {
var hash = bufferReverse(this.getHash()) var hash = bufferReverse(this.getHash())
var target = Block.calculateTarget(this.bits) var target = Block.calculateTarget(this.bits)

View file

@ -97,6 +97,44 @@ describe('Block', function () {
}) })
}) })
describe('calculateMerkleRoot', function () {
it('should throw on zero-length transaction array', function () {
assert.throws(function () {
Block.calculateMerkleRoot([])
}, /Cannot compute merkle root for zero transactions/)
})
fixtures.valid.forEach(function (f) {
if (f.hex.length === 160) return
var block
beforeEach(function () {
block = Block.fromHex(f.hex)
})
it('returns ' + f.merkleRoot + ' for ' + f.id, function () {
assert.strictEqual(Block.calculateMerkleRoot(block.transactions).toString('hex'), f.merkleRoot)
})
})
})
describe('checkMerkleRoot', function () {
fixtures.valid.forEach(function (f) {
if (f.hex.length === 160) return
var block
beforeEach(function () {
block = Block.fromHex(f.hex)
})
it('returns ' + f.valid + ' for ' + f.id, function () {
assert.strictEqual(block.checkMerkleRoot(), true)
})
})
})
describe('checkProofOfWork', function () { describe('checkProofOfWork', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
var block var block

View file

@ -101,6 +101,20 @@
"timestamp": 1439710609, "timestamp": 1439710609,
"valid": false, "valid": false,
"version": 3 "version": 3
},
{
"description": "Genesis Block",
"bits": 486604799,
"hash": "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000",
"height": 0,
"hex": "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"id": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
"merkleRoot": "3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a",
"nonce": 2083236893,
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": 1231006505,
"valid": true,
"version": 1
} }
], ],
"invalid": [ "invalid": [