test: add regtest for multiple bitcoind connections

This commit is contained in:
Braydon Fuller 2016-04-08 22:17:45 -04:00
parent dbcb70f839
commit d7f49cc192
7 changed files with 257 additions and 4 deletions

5
.gitignore vendored
View File

@ -22,4 +22,7 @@ coverage/*
**/*.creator
*.log
.DS_Store
bin/bitcoin*
bin/bitcoin*
regtest/data/node1/regtest
regtest/data/node2/regtest
regtest/data/node3/regtest

View File

@ -16,6 +16,7 @@ node_js:
script:
- _mocha -R spec regtest/p2p.js
- _mocha -R spec regtest/bitcoind.js
- _mocha -R spec regtest/cluster.js
- _mocha -R spec regtest/node.js
- _mocha -R spec --recursive

View File

@ -111,7 +111,8 @@ Bitcoin.prototype.getAPIMethods = function() {
['getAddressBalance', this, this.getAddressBalance, 2],
['getAddressUnspentOutputs', this, this.getAddressUnspentOutputs, 2],
['getAddressHistory', this, this.getAddressHistory, 2],
['getAddressSummary', this, this.getAddressSummary, 1]
['getAddressSummary', this, this.getAddressSummary, 1],
['generateBlock', this, this.generateBlock, 1]
];
return methods;
};
@ -372,6 +373,18 @@ Bitcoin.prototype._initZmqSubSocket = function(node, zmqUrl) {
var self = this;
node.zmqSubSocket = zmq.socket('sub');
node.zmqSubSocket.on('connect', function(fd, endPoint) {
log.info('ZMQ connected to:', endPoint);
});
node.zmqSubSocket.on('connect_delay', function(fd, endPoint) {
log.warn('ZMQ connection delay:', endPoint);
});
node.zmqSubSocket.on('disconnect', function(fd, endPoint) {
log.warn('ZMQ disconnect:', endPoint);
});
node.zmqSubSocket.on('monitor_error', function(err) {
log.error('Error in monitoring: %s, will restart monitoring in 5 seconds', err);
setTimeout(function() {
@ -394,7 +407,6 @@ Bitcoin.prototype._checkReindex = function(node, callback) {
log.info('Bitcoin Core Daemon Reindex Percentage: ' + percentSynced.toFixed(2));
if (Math.round(percentSynced) >= 100) {
node._reindex = false;
self._subscribeZmqEvents(node);
callback();
clearInterval(interval);
}
@ -402,7 +414,6 @@ Bitcoin.prototype._checkReindex = function(node, callback) {
}, self._reindexWait);
} else {
self._subscribeZmqEvents(node);
callback();
}
};
@ -481,6 +492,7 @@ Bitcoin.prototype._spawnChildProcess = function(callback) {
if (err) {
return callback(err);
}
self._subscribeZmqEvents(node);
callback(null, node);
});
@ -512,6 +524,7 @@ Bitcoin.prototype._connectProcess = function(config, callback) {
}
self._initZmqSubSocket(node, config.zmqpubrawtx);
self._subscribeZmqEvents(node);
callback(null, node);
});
@ -1297,6 +1310,16 @@ Bitcoin.prototype.getInfo = function(callback) {
});
};
Bitcoin.prototype.generateBlock = function(num, callback) {
var self = this;
this.client.generate(num, function(err, response) {
if (err) {
return callback(self._wrapRPCError(err));
}
callback(null, response.result);
});
};
/**
* Called by Node to stop the service.
* @param {Function} callback

184
regtest/cluster.js Normal file
View File

@ -0,0 +1,184 @@
'use strict';
var path = require('path');
var async = require('async');
var spawn = require('child_process').spawn;
var BitcoinRPC = require('bitcoind-rpc');
var rimraf = require('rimraf');
var bitcore = require('bitcore-lib');
var chai = require('chai');
var should = chai.should();
var index = require('..');
var log = index.log;
log.debug = function() {};
var BitcoreNode = index.Node;
var BitcoinService = index.services.Bitcoin;
describe('Bitcoin Cluster', function() {
var node;
var daemons = [];
var execPath = path.resolve(__dirname, '../bin/bitcoind');
var nodesConf = [
{
datadir: path.resolve(__dirname, './data/node1'),
conf: path.resolve(__dirname, './data/node1/bitcoin.conf'),
rpcuser: 'bitcoin',
rpcpassword: 'local321',
rpcport: 30521,
zmqpubrawtx: 'tcp://127.0.0.1:30611',
zmqpubhashblock: 'tcp://127.0.0.1:30611'
},
{
datadir: path.resolve(__dirname, './data/node2'),
conf: path.resolve(__dirname, './data/node2/bitcoin.conf'),
rpcuser: 'bitcoin',
rpcpassword: 'local321',
rpcport: 30522,
zmqpubrawtx: 'tcp://127.0.0.1:30622',
zmqpubhashblock: 'tcp://127.0.0.1:30622'
},
{
datadir: path.resolve(__dirname, './data/node3'),
conf: path.resolve(__dirname, './data/node3/bitcoin.conf'),
rpcuser: 'bitcoin',
rpcpassword: 'local321',
rpcport: 30523,
zmqpubrawtx: 'tcp://127.0.0.1:30633',
zmqpubhashblock: 'tcp://127.0.0.1:30633'
}
];
before(function(done) {
log.info('Starting 3 bitcoind daemons');
this.timeout(20000);
async.each(nodesConf, function(nodeConf, next) {
var opts = [
'--regtest',
'--datadir=' + nodeConf.datadir,
'--conf=' + nodeConf.conf
];
rimraf(path.resolve(nodeConf.datadir, './regtest'), function(err) {
if (err) {
return done(err);
}
var process = spawn(execPath, opts, {stdio: 'inherit'});
var client = new BitcoinRPC({
protocol: 'http',
host: '127.0.0.1',
port: nodeConf.rpcport,
user: nodeConf.rpcuser,
pass: nodeConf.rpcpassword
});
daemons.push(process);
async.retry({times: 10, interval: 5000}, function(ready) {
client.getInfo(ready);
}, next);
});
}, done);
});
after(function(done) {
this.timeout(10000);
setTimeout(function() {
async.each(daemons, function(process, next) {
process.once('exit', next);
process.kill('SIGINT');
}, done);
}, 1000);
});
it('step 1: will connect to three bitcoind daemons', function(done) {
this.timeout(20000);
var configuration = {
network: 'regtest',
services: [
{
name: 'bitcoind',
module: BitcoinService,
config: {
connect: [
{
rpchost: '127.0.0.1',
rpcport: 30521,
rpcuser: 'bitcoin',
rpcpassword: 'local321',
zmqpubrawtx: 'tcp://127.0.0.1:30611'
},
{
rpchost: '127.0.0.1',
rpcport: 30522,
rpcuser: 'bitcoin',
rpcpassword: 'local321',
zmqpubrawtx: 'tcp://127.0.0.1:30622'
},
{
rpchost: '127.0.0.1',
rpcport: 30523,
rpcuser: 'bitcoin',
rpcpassword: 'local321',
zmqpubrawtx: 'tcp://127.0.0.1:30633'
}
]
}
}
]
};
var regtest = bitcore.Networks.get('regtest');
should.exist(regtest);
node = new BitcoreNode(configuration);
node.on('error', function(err) {
log.error(err);
});
node.on('ready', function() {
done();
});
node.start(function(err) {
if (err) {
return done(err);
}
});
});
it('step 2: receive block events', function(done) {
this.timeout(10000);
node.services.bitcoind.once('tip', function() {
setTimeout(function() {
done();
}, 1000);
});
node.generateBlock(1, function(err, hashes) {
if (err) {
return done(err);
}
should.exist(hashes);
});
});
it('step 3: get blocks', function(done) {
async.times(3, function(n, next) {
node.getBlock(1, function(err, block) {
if (err) {
return next(err);
}
should.exist(block);
next();
});
}, done);
});
});

View File

@ -0,0 +1,14 @@
server=1
whitelist=127.0.0.1
txindex=1
addressindex=1
timestampindex=1
addnode=127.0.0.1:30432
addnode=127.0.0.1:30433
port=30431
rpcport=30521
zmqpubrawtx=tcp://127.0.0.1:30611
zmqpubhashblock=tcp://127.0.0.1:30611
rpcallowip=127.0.0.1
rpcuser=bitcoin
rpcpassword=local321

View File

@ -0,0 +1,14 @@
server=1
whitelist=127.0.0.1
txindex=1
addressindex=1
timestampindex=1
addnode=127.0.0.1:30431
addnode=127.0.0.1:30433
port=30432
rpcport=30522
zmqpubrawtx=tcp://127.0.0.1:30622
zmqpubhashblock=tcp://127.0.0.1:30622
rpcallowip=127.0.0.1
rpcuser=bitcoin
rpcpassword=local321

View File

@ -0,0 +1,14 @@
server=1
whitelist=127.0.0.1
txindex=1
addressindex=1
timestampindex=1
addnode=127.0.0.1:30431
addnode=127.0.0.1:30432
port=30433
rpcport=30523
zmqpubrawtx=tcp://127.0.0.1:30633
zmqpubhashblock=tcp://127.0.0.1:30633
rpcallowip=127.0.0.1
rpcuser=bitcoin
rpcpassword=local321