bitcore/test/block/block.js

269 lines
338 KiB
JavaScript
Raw Normal View History

2014-11-20 13:19:48 -08:00
'use strict';
2015-05-20 11:02:03 -07:00
var bitcore = require('../..');
var BN = require('../../lib/crypto/bn');
2014-11-21 08:26:30 -08:00
var BufferReader = bitcore.encoding.BufferReader;
var BufferWriter = bitcore.encoding.BufferWriter;
var BlockHeader = bitcore.BlockHeader;
2014-11-20 13:19:48 -08:00
var Block = bitcore.Block;
var chai = require('chai');
var fs = require('fs');
var should = chai.should();
2014-11-20 13:19:48 -08:00
var Transaction = bitcore.Transaction;
// https://test-insight.bitpay.com/block/000000000b99b16390660d79fcc138d2ad0c89a0d044c4201a02bdf1f61ffa11
var dataRawBlockBuffer = fs.readFileSync('test/data/blk86756-testnet.dat');
var dataRawBlockBinary = fs.readFileSync('test/data/blk86756-testnet.dat', 'binary');
var dataJson = fs.readFileSync('test/data/blk86756-testnet.json').toString();
2015-05-20 11:02:03 -07:00
var data = require('../data/blk86756-testnet');
var dataBlocks = require('../data/bitcoind/blocks');
2014-09-16 18:42:11 -07:00
describe('Block', function() {
var blockhex = data.blockhex;
2014-09-16 18:42:11 -07:00
var blockbuf = new Buffer(blockhex, 'hex');
var bh = BlockHeader.fromBuffer(new Buffer(data.blockheaderhex, 'hex'));
var txs = [];
2015-04-28 11:17:41 -07:00
JSON.parse(dataJson).transactions.forEach(function(tx) {
txs.push(new Transaction().fromObject(tx));
});
var json = dataJson;
2014-09-16 18:42:11 -07:00
var genesishex = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000';
var genesisbuf = new Buffer(genesishex, 'hex');
var genesisidhex = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f';
2015-04-28 11:17:41 -07:00
var blockOneHex = '010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e362990101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000';
var blockOneBuf = new Buffer(blockOneHex, 'hex');
var blockOneId = '00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048';
it('should make a new block', function() {
var b = Block(blockbuf);
b.toBuffer().toString('hex').should.equal(blockhex);
});
it('should not make an empty block', function() {
(function() {
return new Block();
}).should.throw('Unrecognized argument for Block');
});
describe('#constructor', function() {
2014-09-16 18:42:11 -07:00
it('should set these known values', function() {
var b = new Block({
header: bh,
transactions: txs
2014-09-16 18:42:11 -07:00
});
should.exist(b.header);
should.exist(b.transactions);
});
it('should properly deserialize blocks', function() {
2015-04-28 11:17:41 -07:00
dataBlocks.forEach(function(block) {
var b = Block.fromBuffer(new Buffer(block.data, 'hex'));
b.transactions.length.should.equal(block.transactions);
});
});
});
describe('#fromRawBlock', function() {
it('should instantiate from a raw block binary', function() {
var x = Block.fromRawBlock(dataRawBlockBinary);
x.header.version.should.equal(2);
new BN(x.header.bits).toString('hex').should.equal('1c3fffc0');
});
it('should instantiate from raw block buffer', function() {
var x = Block.fromRawBlock(dataRawBlockBuffer);
x.header.version.should.equal(2);
new BN(x.header.bits).toString('hex').should.equal('1c3fffc0');
});
});
describe('#fromJSON', function() {
it('should set these known values', function() {
var block = Block.fromObject(JSON.parse(json));
should.exist(block.header);
should.exist(block.transactions);
});
it('should set these known values', function() {
var block = new Block(JSON.parse(json));
should.exist(block.header);
should.exist(block.transactions);
});
});
describe('#toJSON', function() {
it('should recover these known values', function() {
var block = Block.fromObject(JSON.parse(json));
var b = block.toJSON();
should.exist(b.header);
should.exist(b.transactions);
});
2014-09-16 18:42:11 -07:00
});
describe('#fromString/#toString', function() {
it('should output/input a block hex string', function() {
var b = Block.fromString(blockhex);
b.toString().should.equal(blockhex);
});
});
2015-04-29 11:54:41 -07:00
describe('#fromBuffer', function() {
2014-09-16 18:42:11 -07:00
it('should make a block from this known buffer', function() {
var block = Block.fromBuffer(blockbuf);
2014-09-16 18:42:11 -07:00
block.toBuffer().toString('hex').should.equal(blockhex);
});
2015-04-29 11:31:46 -07:00
it('should instantiate from block buffer from the network', function() {
var networkBlock = '02000000e74122c23a90d7bb207fad2cfd07fbdc33de36352b5561120000000000000000d6097b7aded2327c8ca979ff85367f664879a7a7f42e1914ab880e63276b8dd1b12eff54c02e171831fb8d1ea201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5b03984b05e4b883e5bda9e7a59ee4bb99e9b1bcfabe6d6d5cb348c1c7d580627835202f5ad93c2f3db10bb850a1a513979f8328d9f35aff1000000000000000006189dd01cf00004d696e6564206279207975313333353131373131ffffffff0111622195000000001976a914c825a1ecf2a6830c4401620c3a16f1995057c2ab88ac000000000100000001a9f062bdd6bf76f3059169ce8f30905e23b08b25e30570b2baca08ff2878b0e3000000008a473044022037da4b94dfbfe08e425b4b72476047bb45850fe9af109926dabebb8c7f0b93da022014de78058989b54d1a7ae19644c83ca4e26efd4000a4fe8e45659209468cd4cf014104861822906143d90a413c28c5aec29985ac36783d2c157fd0f87c55a5663aef51e74b0181740f3247aa1e7ab78b07379e1b1a94384c9442cfa5eeca8898769537ffffffff02e8030000000000001976a914b28ae06f3050160e775c806a42e7d1d127ab5dd388acb8820100000000001976a914017c96cc0f3a81c2604d9820dbb1b490127d2bca88ac000000000100000001b36da34608b43f5af519bff8f4ed4a30969963de3a7b7cd27ef897d14a0732f5000000006a47304402206ab21b1f1aa900eedfc4dbba741f972644647eb19627d1a664d1756d65e029820220070caebd37d1393e4e4af176f64d718bd860d6af08355a42cedeba6f509c240501210386b0396cf4aece2bf608adfd0e8d95414f6bdcd61b217241ec980d2f5f76eee6ffffffff01e882d000000000001976a914539c3e80f41382631d2d03c4778ed0fdf81b7d2588ac00000000010000000133f61c96b620149bdd45808dc8f2795bd8d9874a1d91fae44dad627445adc09a010000006a473044022035f04cdb8048e0a4995ae9bc8e59373f99b2751d5a920f7847d572090ea1265d022052e5eac0fd3e556171b4fe4bc15e4d5fd2a5f801d1707ce84dd9d74b1975abb0012102b9913536286170a0f6adcc2988cc2552bf1f97ec30d75d1ca6bd20b6b5394e62ffffffff0118fd6700000000001976a914539c3e80f41382631d2d03c4778ed0fdf81b7d2588ac00000000010000000151148eeeb3612d11bdd073f98f964c9431bd5ca67aa0ede8004e98f6d627f5dd000000006a473044022016838fbd4c9684407e771d2a99fc2a230ab655f315f1b5086949f286f71bff3102204ab02bf9e188619bc9b79bc9b01788f98900373a639b0888463fae7b3a4c66b20121029ac24d1abfa92582156ab553cc1562d56f48bcebadeadf1904fdff2dab74da62ffffffff0110ca4d00000000001976a914539c3e80f41382631d2d03c4778ed0fdf81b7d2588ac0000000001000000019c05873dc500ba9ae3616d92282c6a8723a8703be8c85fb880a4330b2995a56e000000006a473044022038ae1c068b089a73df1d369de616ce3bac0110fdb824523922934a6fb0e3f01102201fdb5edd8d77f2e97c4f898ac022be1e0c41d90550aa410d12471af305e520000121030c07ddac3638f0f9309d9e344fc9653aaf6430b4b38d703570763acb8246132fffffffff01d0aa4d00000000001976a914539c3e80f41382631d2d03c4778ed0fdf81b7d2588ac000000000100000001649072082c6150572663065f26554692502cbb8006f6ecac39e8cb421f5de070000000006a473044022004428233b5b46e36e244669d1370663c594d487b525cefb8d693e38286ba861202200f54176b57e8ec2a8e6ae4df41cf0cdc556fd7d6a58adef23e32bf6e744e1cf5012102820ebfafe39f5f4bf0b7e25ae9915cb7de8ceff88c0d01cac19bdb50a4b1e051ffffffff02c61b2107000000001976a914c225ab6924b62a12e85aa53f366eaee38609ed6d88ac3a986013000000001976a914c0fbecd8b2f85c31c5ac86630de53c7ae7ce464c88ac0000000001000000015a5c351916611a4b995dc75c482dd8afc6a813a5ce678cc7c5fb9e95b6e69bd3000000008b48304502201fe6c1b80f37c5e452c2ca4d1bee0fbc87e8fc17a13967d1cc9f685a29cc3e77022100f1a1fdbf297f50c46a2fe179170233181075260134fe3a8d8cf14490d72d10e9014104ec8286c3e7d962cd687cb9f3860c3e73866d4f79e57fe4df692680b6488c37b7009c4a963a5649323721ae3f20d6f393d7865f85b829a27f0b541bbdd7f15838ffffffff024e38c404000000001976a91484e16c064a30f69c78f9b3b42002fd89d8c900f988ac808d5b00000000001976a914a6e86762140b6d7f661b251cb7c3cf1afb2d870588ac000000000100000002507c35d72b8ebb55a43b5cf450f17f5f13cd3da4b263609cfc6e4508132a4ed1000000006a4730440220772619770d94488234ea4f47430f05cd5c78697a2e7791b12c6819602ad9004902204b2bc4aa967d0709a4c99d5f36f2317c44794489084cb593726c4062ad911cc3012102094d1fc9488b1ce68d021c6623b6d12ce2dfc0d6f527e6f2096765c245158624feffffffa216eab2a659f25ca6bc7bee9cc4a5e54772118f0a50d98f0656edfecdd849ad000000006a473044022009bb9bec4494389220e3188b37551b1dcabd035a7114a309c2ea62d1b7228d95022034beac693b005a9b5312b5c48c41f31da0665e1359be81dce8930c4c47de67f7012103fd5c201fed02e586282d4
var x = Block.fromBuffer(networkBlock);
x.toBuffer().toString('hex').should.equal(networkBlock);
});
2014-09-16 18:42:11 -07:00
});
describe('#fromBufferReader', function() {
2014-09-16 18:42:11 -07:00
it('should make a block from this known buffer', function() {
var block = Block.fromBufferReader(BufferReader(blockbuf));
2014-09-16 18:42:11 -07:00
block.toBuffer().toString('hex').should.equal(blockhex);
});
});
describe('#toBuffer', function() {
2014-09-16 18:42:11 -07:00
it('should recover a block from this known buffer', function() {
var block = Block.fromBuffer(blockbuf);
2014-09-16 18:42:11 -07:00
block.toBuffer().toString('hex').should.equal(blockhex);
});
});
describe('#toBufferWriter', function() {
2014-09-16 18:42:11 -07:00
it('should recover a block from this known buffer', function() {
var block = Block.fromBuffer(blockbuf);
2014-09-16 18:42:11 -07:00
block.toBufferWriter().concat().toString('hex').should.equal(blockhex);
});
it('doesn\'t create a bufferWriter if one provided', function() {
var writer = new BufferWriter();
var block = Block.fromBuffer(blockbuf);
block.toBufferWriter(writer).should.equal(writer);
});
2014-09-16 18:42:11 -07:00
});
2015-04-28 12:42:56 -07:00
describe('#toObject', function() {
2015-04-28 11:17:41 -07:00
it('should recover a block from genesis block buffer', function() {
var block = Block.fromBuffer(blockOneBuf);
block.id.should.equal(blockOneId);
block.toObject().should.deep.equal({
header: {
hash: '00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048',
2015-04-28 11:17:41 -07:00
version: 1,
prevHash: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
merkleRoot: '0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098',
time: 1231469665,
bits: 486604799,
nonce: 2573394689
},
transactions: [{
hash: '0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098',
2015-04-28 11:17:41 -07:00
version: 1,
inputs: [{
prevTxId: '0000000000000000000000000000000000000000000000000000000000000000',
outputIndex: 4294967295,
sequenceNumber: 4294967295,
2015-04-29 13:29:33 -07:00
script: '04ffff001d0104'
2015-04-28 11:17:41 -07:00
}],
outputs: [{
satoshis: 5000000000,
script: '410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c' +
'52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac'
2015-04-28 11:17:41 -07:00
}],
nLockTime: 0
}]
});
});
2015-04-28 12:42:56 -07:00
it('roundtrips correctly', function() {
var block = Block.fromBuffer(blockOneBuf);
var obj = block.toObject();
var block2 = Block.fromObject(obj);
block2.toObject().should.deep.equal(block.toObject());
});
2015-04-28 11:17:41 -07:00
});
describe('#_getHash', function() {
it('should return the correct hash of the genesis block', function() {
var block = Block.fromBuffer(genesisbuf);
var blockhash = new Buffer(Array.apply([], new Buffer(genesisidhex, 'hex')).reverse());
block._getHash().toString('hex').should.equal(blockhash.toString('hex'));
});
});
describe('#id', function() {
it('should return the correct id of the genesis block', function() {
var block = Block.fromBuffer(genesisbuf);
block.id.should.equal(genesisidhex);
});
it('"hash" should be the same as "id"', function() {
var block = Block.fromBuffer(genesisbuf);
block.id.should.equal(block.hash);
});
});
describe('#inspect', function() {
it('should return the correct inspect of the genesis block', function() {
var block = Block.fromBuffer(genesisbuf);
2015-04-28 11:17:41 -07:00
block.inspect().should.equal('<Block ' + genesisidhex + '>');
});
});
describe('#merkleRoot', function() {
it('should describe as valid merkle root', function() {
var x = Block.fromRawBlock(dataRawBlockBinary);
var valid = x.validMerkleRoot();
valid.should.equal(true);
});
it('should describe as invalid merkle root', function() {
var x = Block.fromRawBlock(dataRawBlockBinary);
x.transactions.push(new Transaction());
var valid = x.validMerkleRoot();
valid.should.equal(false);
});
it('should get a null hash merkle root', function() {
var x = Block.fromRawBlock(dataRawBlockBinary);
x.transactions = []; // empty the txs
var mr = x.getMerkleRoot();
mr.should.deep.equal(Block.Values.NULL_HASH);
});
});
2014-09-16 18:42:11 -07:00
});