UNPKG

bitcore-p2p

Version:

Interface to the bitcoin P2P network for bitcore

222 lines (215 loc) 7.24 kB
'use strict'; var chai = require('chai'); /* jshint unused: false */ var should = chai.should(); var sinon = require('sinon'); var bitcore = require('bitcore-lib'); var _ = bitcore.deps._; var Random = bitcore.crypto.Random; var BN = bitcore.crypto.BN; var BufferUtil = bitcore.util.buffer; var p2p = require('../'); var Peer = p2p.Peer; var Pool = p2p.Pool; var Networks = bitcore.Networks; var Messages = p2p.Messages; var Inventory = p2p.Inventory; var Block = bitcore.Block; var Transaction = bitcore.Transaction; // config var network = process.env.NETWORK === 'testnet' ? Networks.testnet : Networks.livenet; var messages = new Messages({ network: network }); var blockHash = { 'livenet': '000000000000000013413cf2536b491bf0988f52e90c476ffeb701c8bfdb1db9', 'testnet': '0000000058cc069d964711cd25083c0a709f4df2b34c8ff9302ce71fe5b45786' }; var stopBlock = { 'livenet': '00000000000000000b539ef570128acb953af3dbcfc19dd8e6066949672311a1', 'testnet': '00000000d0bc4271bcefaa7eb25000e345910ba16b91eb375cd944b68624de9f' }; var txHash = { 'livenet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b', 'testnet': '22231e8219a0617a0ded618b5dc713fdf9b0db8ebd5bb3322d3011a703119d3b' }; // These tests require a running bitcoind instance describe('Integration with ' + network.name + ' bitcoind', function() { this.timeout(15000); var opts = { host: 'localhost', network: network.name }; it('handshakes', function(cb) { var peer = new Peer(opts); peer.once('version', function(m) { m.version.should.be.above(70000); m.services.toString().should.equal('1'); Math.abs(new Date() - m.timestamp).should.be.below(10000); // less than 10 seconds of time difference m.nonce.length.should.equal(8); m.startHeight.should.be.above(300000); cb(); }); peer.once('verack', function(m) { should.exist(m); m.command.should.equal('verack'); }); peer.connect(); }); var connect = function(cb) { var peer = new Peer(opts); peer.once('ready', function() { cb(peer); }); peer.once('error', function(err) { should.not.exist(err); }); peer.connect(); }; it('connects', function(cb) { connect(function(peer) { peer.version.should.be.above(70000); _.isString(peer.subversion).should.equal(true); _.isNumber(peer.bestHeight).should.equal(true); cb(); }); }); it('handles inv', function(cb) { // assumes there will be at least one transaction/block // in the next few seconds connect(function(peer) { peer.once('inv', function(message) { message.inventory[0].hash.length.should.equal(32); cb(); }); }); }); it('handles addr', function(cb) { connect(function(peer) { peer.once('addr', function(message) { message.addresses.forEach(function(address) { (address.time instanceof Date).should.equal(true); should.exist(address.ip); (address.services instanceof BN).should.equal(true); }); cb(); }); var message = messages.GetAddr(); peer.sendMessage(message); }); }); it('requests inv detailed info', function(cb) { connect(function(peer) { peer.once('block', function(message) { should.exist(message.block); cb(); }); peer.once('tx', function(message) { should.exist(message.transaction); cb(); }); peer.once('inv', function(message) { var get = messages.GetData(message.inventory); peer.sendMessage(get); }); }); }); it('sends tx inv and receives getdata for that tx', function(cb) { connect(function(peer) { var type = Inventory.TYPE.TX; var inv = [{ type: type, hash: new Buffer(Random.getRandomBuffer(32)) // needs to be random for repeatability }]; peer.once('getdata', function(message) { message.inventory[0].should.deep.equal(inv[0]); cb(); }); var message = messages.Inventory(inv); message.inventory[0].hash.length.should.equal(32); peer.sendMessage(message); }); }); it('requests block data', function(cb) { connect(function(peer) { peer.once('block', function(message) { (message.block instanceof Block).should.equal(true); cb(); }); var message = messages.GetData.forBlock(blockHash[network.name]); peer.sendMessage(message); }); }); var fakeHash = 'e2dfb8afe1575bfacae1a0b4afc49af7ddda69285857267bae0e22be15f74a3a'; it('handles request tx data not found', function(cb) { connect(function(peer) { var expected = messages.NotFound.forTransaction(fakeHash); peer.once('notfound', function(message) { message.command.should.equal('notfound'); message.inventory[0].type.should.equal(Inventory.TYPE.TX); var expectedHash = expected.inventory[0].hash.toString('hex'); message.inventory[0].hash.toString('hex').should.equal(expectedHash); cb(); }); var message = messages.GetData.forTransaction(fakeHash); peer.sendMessage(message); }); }); var from = [blockHash[network.name]]; var stop = stopBlock[network.name]; it('gets headers', function(cb) { connect(function(peer) { peer.once('headers', function(message) { message.command.should.equal('headers'); message.headers.length.should.equal(3); cb(); }); var message = messages.GetHeaders({ starts: from, stop: stop }); peer.sendMessage(message); }); }); it('gets blocks', function(cb) { connect(function(peer) { peer.once('inv', function(message) { message.command.should.equal('inv'); if (message.inventory.length === 2) { message.inventory[0].type.should.equal(Inventory.TYPE.BLOCK); message.inventory[1].type.should.equal(Inventory.TYPE.BLOCK); cb(); } }); var message = messages.GetBlocks({ starts: from, stop: stop }); peer.sendMessage(message); }); }); var testInvGetData = function(expected, message, cb) { connect(function(peer) { peer.once('getdata', function(message) { message.command.should.equal('getdata'); message.inventory[0].type.should.equal(expected.inventory[0].type); var expectedHash = expected.inventory[0].hash.toString('hex'); message.inventory[0].hash.toString('hex').should.equal(expectedHash); cb(); }); peer.sendMessage(message); }); }; it('sends block inv and receives getdata', function(cb) { var randomHash = new Buffer(Random.getRandomBuffer(32)); // slow buffer var expected = messages.GetData.forBlock(randomHash); var message = messages.Inventory.forBlock(randomHash); testInvGetData(expected, message, cb); }); it('sends tx inv and receives getdata', function(cb) { var randomHash = new Buffer(Random.getRandomBuffer(32)); // slow buffer var expected = messages.GetData.forTransaction(randomHash); var message = messages.Inventory.forTransaction(randomHash); testInvGetData(expected, message, cb); }); });