Merge branch 'master' into fix/isCoinbaseHash
This commit is contained in:
commit
79ac51dbbd
3 changed files with 82 additions and 0 deletions
30
src/block.js
30
src/block.js
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
14
test/fixtures/block.json
vendored
14
test/fixtures/block.json
vendored
|
@ -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": [
|
||||||
|
|
Loading…
Reference in a new issue