wip on changing subsciption endpoints.
This commit is contained in:
parent
5a8e1d0980
commit
15fe096a07
@ -76,7 +76,7 @@ BlockController.prototype.block = function(req, res, next) {
|
||||
}
|
||||
|
||||
if (!block) {
|
||||
return self.common.handleErrors(null, res);
|
||||
return self.common.handleErrors(new Error('block not in index'), res);
|
||||
}
|
||||
|
||||
self._header.getBlockHeader(hash, function(err, info) {
|
||||
|
||||
@ -100,11 +100,11 @@ InsightAPI.prototype.start = function(callback) {
|
||||
this._bus = this.node.openBus({remoteAddress: 'localhost-insight-api'});
|
||||
}
|
||||
|
||||
this._bus.on('p2p/transaction', this.transactionEventHandler.bind(this));
|
||||
this._bus.subscribe('p2p/transaction');
|
||||
this._bus.on('mempool/transaction', this.transactionEventHandler.bind(this));
|
||||
this._bus.subscribe('mempool/transaction');
|
||||
|
||||
this._bus.on('p2p/block', this.blockEventHandler.bind(this));
|
||||
this._bus.subscribe('p2p/block');
|
||||
this._bus.on('block/block', this.blockEventHandler.bind(this));
|
||||
this._bus.subscribe('block/block');
|
||||
|
||||
callback();
|
||||
|
||||
|
||||
586
regtest/block.js
586
regtest/block.js
@ -8,12 +8,12 @@ var fs = require('fs');
|
||||
var async = require('async');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var http = require('http');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var exec = require('child_process').exec;
|
||||
var bitcore = require('bitcore-lib');
|
||||
var Block = bitcore.Block;
|
||||
|
||||
var rpc1Address;
|
||||
var rpc2Address;
|
||||
var tx1;
|
||||
var tx2;
|
||||
var block;
|
||||
var blocksGenerated = 0;
|
||||
|
||||
var rpcConfig = {
|
||||
protocol: 'http',
|
||||
@ -24,12 +24,12 @@ var rpcConfig = {
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var rpc1 = new RPC(rpcConfig);
|
||||
rpcConfig.port++;
|
||||
var rpc2 = new RPC(rpcConfig);
|
||||
var rpc = new RPC(rpcConfig);
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDataDirs = ['/tmp/bitcoin1', '/tmp/bitcoin2'];
|
||||
var bitcoinDir = '/tmp/bitcoin';
|
||||
var bitcoinDataDirs = [ bitcoinDir ];
|
||||
var blocks= [];
|
||||
|
||||
var bitcoin = {
|
||||
args: {
|
||||
@ -39,7 +39,7 @@ var bitcoin = {
|
||||
server: 1,
|
||||
rpcuser: 'local',
|
||||
rpcpassword: 'localtest',
|
||||
//printtoconsole: 1
|
||||
//printtoconsole: 1,
|
||||
rpcport: 58332,
|
||||
},
|
||||
datadir: null,
|
||||
@ -75,6 +75,9 @@ var bitcore = {
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
},
|
||||
'block': {
|
||||
'readAheadBlockCount': 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,88 +89,186 @@ var bitcore = {
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcored
|
||||
exec: 'bitcored', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcored
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
var startBitcoind = function(count, callback) {
|
||||
var request = function(httpOpts, callback) {
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
return callback('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
|
||||
if (resError) {
|
||||
return callback(resError);
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
callback(null, data);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.on('error', function(err) {
|
||||
callback(err);
|
||||
});
|
||||
|
||||
if (httpOpts.body) {
|
||||
request.write(httpOpts.body);
|
||||
} else {
|
||||
request.write('');
|
||||
}
|
||||
request.end();
|
||||
};
|
||||
|
||||
var waitForBlocksGenerated = function(callback) {
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/status',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
async.retry({ interval: 1000, times: 100 }, function(next) {
|
||||
|
||||
request(httpOpts, function(err, data) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (data.info.blocks !== blocksGenerated) {
|
||||
return next(data);
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
}, callback);
|
||||
};
|
||||
|
||||
var resetDirs = function(dirs, callback) {
|
||||
|
||||
async.each(dirs, function(dir, next) {
|
||||
|
||||
rimraf(dir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(dir, next);
|
||||
|
||||
});
|
||||
|
||||
}, callback);
|
||||
|
||||
};
|
||||
|
||||
var startBitcoind = function(callback) {
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
var reportBitcoindsStarted = function() {
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(pids.length + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
};
|
||||
|
||||
var startBitcoinds = function(datadirs, callback) {
|
||||
|
||||
var listenCount = 0;
|
||||
async.timesSeries(count, function(n, next) {
|
||||
|
||||
var datadir = bitcoinDataDirs.shift();
|
||||
async.eachSeries(datadirs, function(datadir, next) {
|
||||
|
||||
bitcoin.datadir = datadir;
|
||||
bitcoin.args.datadir = datadir;
|
||||
|
||||
if (listenCount++ > 0) {
|
||||
bitcoin.args.listen = 0;
|
||||
bitcoin.args.rpcport++;
|
||||
bitcoin.args.rpcport = bitcoin.args.rpcport + 1;
|
||||
bitcoin.args.connect = '127.0.0.1';
|
||||
}
|
||||
|
||||
rimraf(datadir, function(err) {
|
||||
startBitcoind(next);
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(datadir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(count + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
callback();
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
reportBitcoindsStarted();
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
var waitForBitcoinReady = function(rpc, callback) {
|
||||
async.retry({ interval: 1000, times: 1000 }, function(next) {
|
||||
rpc.getInfo(function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
setTimeout(callback, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
var shutdownBitcoind = function(callback) {
|
||||
bitcoin.processes.forEach(function(process) {
|
||||
process.kill();
|
||||
});
|
||||
var process;
|
||||
do {
|
||||
process = bitcoin.processes.shift();
|
||||
if (process) {
|
||||
process.kill();
|
||||
}
|
||||
} while(process);
|
||||
setTimeout(callback, 3000);
|
||||
};
|
||||
|
||||
@ -178,98 +279,25 @@ var shutdownBitcore = function(callback) {
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
var buildInitialChain = function(callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
console.log('checking to see if bitcoind\'s are connected to each other.');
|
||||
rpc1.getinfo(function(err, res) {
|
||||
if (err || res.result.connections !== 1) {
|
||||
next(err || new Error('bitcoind\'s not connected to each other.'));
|
||||
}
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('generating 101 blocks');
|
||||
rpc1.generate(101, next);
|
||||
},
|
||||
function(res, next) {
|
||||
console.log('getting new address from rpc2');
|
||||
rpc2.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc2Address = res.result;
|
||||
console.log(rpc2Address);
|
||||
next(null, rpc2Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc1.sendToAddress(rpc2Address, 25, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx1 = res.result;
|
||||
console.log('TXID: ' + res.result);
|
||||
console.log('generating 7 blocks');
|
||||
rpc1.generate(7, next);
|
||||
},
|
||||
function(res, next) {
|
||||
block = res.result[res.result.length - 1];
|
||||
rpc2.getBalance(function(err, res) {
|
||||
console.log(res);
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('getting new address from rpc1');
|
||||
rpc1.getNewAddress(function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
rpc1Address = res.result;
|
||||
next(null, rpc1Address);
|
||||
});
|
||||
},
|
||||
function(addr, next) {
|
||||
rpc2.sendToAddress(rpc1Address, 20, next);
|
||||
},
|
||||
function(res, next) {
|
||||
tx2 = res.result;
|
||||
console.log('sending from rpc2Address TXID: ', res);
|
||||
console.log('generating 6 blocks');
|
||||
rpc2.generate(6, next);
|
||||
}
|
||||
], function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
rpc1.getInfo(function(err, res) {
|
||||
console.log(res);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
var writeBitcoreConf = function() {
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
rimraf(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
mkdirp(bitcoreDataDir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
|
||||
var args = bitcore.args;
|
||||
var args = bitcore.args;
|
||||
console.log('Using bitcored from: ');
|
||||
async.series([
|
||||
function(next) {
|
||||
exec('which bitcored', function(err, stdout, stderr) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
console.log(stdout.toString('hex'), stderr.toString('hex'));
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
@ -287,11 +315,9 @@ var startBitcore = function(callback) {
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
waitForBlocksGenerated(next);
|
||||
}
|
||||
], callback);
|
||||
|
||||
};
|
||||
|
||||
@ -303,24 +329,40 @@ describe('Block', function() {
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
startBitcoind(2, next);
|
||||
console.log('step 0: setting up directories.');
|
||||
var dirs = bitcoinDataDirs.concat([bitcoreDataDir]);
|
||||
resetDirs(dirs, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
writeBitcoreConf();
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
buildInitialChain(next);
|
||||
}, 8000);
|
||||
startBitcoinds(bitcoinDataDirs, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
waitForBitcoinReady(rpc, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
blocksGenerated += 10;
|
||||
rpc.generate(10, function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
blocks = res.result;
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
setTimeout(function() {
|
||||
startBitcore(next);
|
||||
}, 6000);
|
||||
startBitcore(next);
|
||||
}
|
||||
], function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
], done);
|
||||
|
||||
});
|
||||
|
||||
@ -332,169 +374,99 @@ describe('Block', function() {
|
||||
|
||||
it('should get blocks: /blocks', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/blocks', function(res) {
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: 'http://localhost:53001/api/blocks',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
request(httpOpts, function(err, data) {
|
||||
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.length).to.equal(114);
|
||||
done();
|
||||
});
|
||||
|
||||
expect(data.length).to.equal(10);
|
||||
expect(data.blocks.length).to.equal(10);
|
||||
done();
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
|
||||
});
|
||||
|
||||
it('should get a block: /block/:hash', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/block/' + block, function(res) {
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: 'http://localhost:53001/api/block/' + blocks[0],
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
request(httpOpts, function(err, data) {
|
||||
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
expect(data.hash).to.equal(block);
|
||||
done();
|
||||
});
|
||||
|
||||
expect(data.hash).to.equal(blocks[0]);
|
||||
expect(data.height).to.equal(1);
|
||||
done();
|
||||
});
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a block-index: /block-index/:height', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/block-index/' + '108', function(res) {
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: 'http://localhost:53001/api/block-index/7',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
request(httpOpts, function(err, data) {
|
||||
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.blockHash).to.equal(block);
|
||||
done();
|
||||
});
|
||||
|
||||
expect(data.blockHash).to.equal(blocks[6]);
|
||||
done();
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
it('should get a raw block: /rawblock/:hash', function(done) {
|
||||
|
||||
var request = http.request('http://localhost:53001/api/rawblock/' + block, function(res) {
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: 'http://localhost:53001/api/rawblock/' + blocks[4],
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
var error;
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
return done('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
request(httpOpts, function(err, data) {
|
||||
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
console.log(resData);
|
||||
expect(data.rawblock).to.not.be.null;
|
||||
done();
|
||||
});
|
||||
|
||||
var block = new Block(new Buffer(data.rawblock, 'hex'));
|
||||
expect(block.hash).to.equal(blocks[4]);
|
||||
done();
|
||||
});
|
||||
|
||||
request.write('');
|
||||
request.end();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
498
regtest/subscriptions.js
Normal file
498
regtest/subscriptions.js
Normal file
@ -0,0 +1,498 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var http = require('http');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var exec = require('child_process').exec;
|
||||
var bitcore = require('bitcore-lib');
|
||||
var Block = bitcore.Block;
|
||||
var PrivateKey = bitcore.PrivateKey;
|
||||
var Transaction = bitcore.Transaction;
|
||||
var io = require('socket.io-client');
|
||||
|
||||
/*
|
||||
|
||||
Theory behind this test.
|
||||
|
||||
We want to connect a web socket and subscribe to both new txs and blocks.
|
||||
|
||||
When a new tx or block comes in, we want to immediately call the api for that resource.
|
||||
|
||||
|
||||
*/
|
||||
var blocksGenerated = 0;
|
||||
|
||||
var rpcConfig = {
|
||||
protocol: 'http',
|
||||
user: 'local',
|
||||
pass: 'localtest',
|
||||
host: '127.0.0.1',
|
||||
port: 58332,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var rpc = new RPC(rpcConfig);
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDir = '/tmp/bitcoin';
|
||||
var bitcoinDataDirs = [ bitcoinDir ];
|
||||
var blocks= [];
|
||||
var pks = [];
|
||||
var initialTx;
|
||||
var startingPk;
|
||||
|
||||
var bitcoin = {
|
||||
args: {
|
||||
datadir: null,
|
||||
listen: 1,
|
||||
regtest: 1,
|
||||
server: 1,
|
||||
rpcuser: 'local',
|
||||
rpcpassword: 'localtest',
|
||||
//printtoconsole: 1,
|
||||
rpcport: 58332,
|
||||
},
|
||||
datadir: null,
|
||||
exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind
|
||||
processes: []
|
||||
};
|
||||
|
||||
var bitcore = {
|
||||
configFile: {
|
||||
file: bitcoreDataDir + '/bitcore-node.json',
|
||||
conf: {
|
||||
network: 'regtest',
|
||||
port: 53001,
|
||||
datadir: bitcoreDataDir,
|
||||
services: [
|
||||
'p2p',
|
||||
'db',
|
||||
'header',
|
||||
'block',
|
||||
'address',
|
||||
'transaction',
|
||||
'mempool',
|
||||
'web',
|
||||
'insight-api',
|
||||
'fee',
|
||||
'timestamp'
|
||||
],
|
||||
servicesConfig: {
|
||||
'p2p': {
|
||||
'peers': [
|
||||
{ 'ip': { 'v4': '127.0.0.1' }, port: 18444 }
|
||||
]
|
||||
},
|
||||
'insight-api': {
|
||||
'routePrefix': 'api'
|
||||
},
|
||||
'block': {
|
||||
'readAheadBlockCount': 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
httpOpts: {
|
||||
protocol: 'http:',
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
},
|
||||
opts: { cwd: bitcoreDataDir },
|
||||
datadir: bitcoreDataDir,
|
||||
exec: 'bitcored', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcored
|
||||
args: ['start'],
|
||||
process: null
|
||||
};
|
||||
|
||||
var request = function(httpOpts, callback) {
|
||||
|
||||
var request = http.request(httpOpts, function(res) {
|
||||
|
||||
if (res.statusCode !== 200 && res.statusCode !== 201) {
|
||||
return callback('Error from bitcore-node webserver: ' + res.statusCode);
|
||||
}
|
||||
|
||||
var resError;
|
||||
var resData = '';
|
||||
|
||||
res.on('error', function(e) {
|
||||
resError = e;
|
||||
});
|
||||
|
||||
res.on('data', function(data) {
|
||||
resData += data;
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
|
||||
if (resError) {
|
||||
return callback(resError);
|
||||
}
|
||||
var data = JSON.parse(resData);
|
||||
callback(null, data);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
request.on('error', function(err) {
|
||||
callback(err);
|
||||
});
|
||||
|
||||
if (httpOpts.body) {
|
||||
request.write(httpOpts.body);
|
||||
} else {
|
||||
request.write('');
|
||||
}
|
||||
request.end();
|
||||
};
|
||||
|
||||
var waitForBlocksGenerated = function(callback) {
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: '/api/status',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
async.retry({ interval: 1000, times: 100 }, function(next) {
|
||||
|
||||
request(httpOpts, function(err, data) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (data.info.blocks !== blocksGenerated) {
|
||||
return next(data);
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
}, callback);
|
||||
};
|
||||
|
||||
var resetDirs = function(dirs, callback) {
|
||||
|
||||
async.each(dirs, function(dir, next) {
|
||||
|
||||
rimraf(dir, function(err) {
|
||||
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
mkdirp(dir, next);
|
||||
|
||||
});
|
||||
|
||||
}, callback);
|
||||
|
||||
};
|
||||
|
||||
var startBitcoind = function(callback) {
|
||||
|
||||
var args = bitcoin.args;
|
||||
var argList = Object.keys(args).map(function(key) {
|
||||
return '-' + key + '=' + args[key];
|
||||
});
|
||||
|
||||
var bitcoinProcess = spawn(bitcoin.exec, argList, bitcoin.opts);
|
||||
bitcoin.processes.push(bitcoinProcess);
|
||||
|
||||
bitcoinProcess.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bitcoinProcess.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
|
||||
var reportBitcoindsStarted = function() {
|
||||
var pids = bitcoin.processes.map(function(process) {
|
||||
return process.pid;
|
||||
});
|
||||
|
||||
console.log(pids.length + ' bitcoind\'s started at pid(s): ' + pids);
|
||||
};
|
||||
|
||||
var startBitcoinds = function(datadirs, callback) {
|
||||
|
||||
var listenCount = 0;
|
||||
async.eachSeries(datadirs, function(datadir, next) {
|
||||
|
||||
bitcoin.datadir = datadir;
|
||||
bitcoin.args.datadir = datadir;
|
||||
|
||||
if (listenCount++ > 0) {
|
||||
bitcoin.args.listen = 0;
|
||||
bitcoin.args.rpcport = bitcoin.args.rpcport + 1;
|
||||
bitcoin.args.connect = '127.0.0.1';
|
||||
}
|
||||
|
||||
startBitcoind(next);
|
||||
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
reportBitcoindsStarted();
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
var waitForBitcoinReady = function(rpc, callback) {
|
||||
async.retry({ interval: 1000, times: 1000 }, function(next) {
|
||||
rpc.getInfo(function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
setTimeout(callback, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
var shutdownBitcoind = function(callback) {
|
||||
var process;
|
||||
do {
|
||||
process = bitcoin.processes.shift();
|
||||
if (process) {
|
||||
process.kill();
|
||||
}
|
||||
} while(process);
|
||||
setTimeout(callback, 3000);
|
||||
};
|
||||
|
||||
var shutdownBitcore = function(callback) {
|
||||
if (bitcore.process) {
|
||||
bitcore.process.kill();
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
var writeBitcoreConf = function() {
|
||||
fs.writeFileSync(bitcore.configFile.file, JSON.stringify(bitcore.configFile.conf));
|
||||
};
|
||||
|
||||
var startBitcore = function(callback) {
|
||||
|
||||
var args = bitcore.args;
|
||||
console.log('Using bitcored from: ');
|
||||
async.series([
|
||||
function(next) {
|
||||
exec('which bitcored', function(err, stdout, stderr) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
console.log(stdout.toString('hex'), stderr.toString('hex'));
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
bitcore.process = spawn(bitcore.exec, args, bitcore.opts);
|
||||
|
||||
bitcore.process.stdout.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stdout.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
bitcore.process.stderr.on('data', function(data) {
|
||||
|
||||
if (debug) {
|
||||
process.stderr.write(data.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
waitForBlocksGenerated(next);
|
||||
}
|
||||
], callback);
|
||||
|
||||
};
|
||||
|
||||
var makeLocalPrivateKeys = function(num) {
|
||||
if (!num) {
|
||||
num = 20;
|
||||
}
|
||||
for(var i = 0; i < num; i++) {
|
||||
pks.push(new PrivateKey('testnet'));
|
||||
}
|
||||
};
|
||||
|
||||
var getFirstIncomingFunds = function(callback) {
|
||||
initialTx = new Transaction();
|
||||
rpc.listUnspent(function(err, res) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
var unspent = res.result[0];
|
||||
rpc.dumpPrivKey(unspent.address, function(err, res) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
startingPk = new PrivateKey(res.result);
|
||||
var utxo = {
|
||||
txId: unspent.txid,
|
||||
outputIndex: unspent.vout,
|
||||
script: unspent.scriptPubKey,
|
||||
satoshis: unspent.amount * 1e8,
|
||||
address: unspent.address
|
||||
};
|
||||
initialTx.from(utxo).to(pks[0].toAddress(), 20*1e8).change(startingPk.toAddress()).fee(50000).sign(startingPk);
|
||||
rpc.sendRawTransaction(initialTx.serialize(), callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var sendTx = function(callback) {
|
||||
var index;
|
||||
for(var i = 0; i < initialTx.outputs.length; i++) {
|
||||
if (initialTx.outputs[i].script.toAddress().toString() === pks[0].toAddress().toString()) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var utxo = {
|
||||
address: pks[0].toAddress().toString(),
|
||||
script: initialTx.outputs[index].script.toHex(),
|
||||
satoshis: initialTx.outputs[index].satoshis,
|
||||
outputIndex: index,
|
||||
txid: initialTx.hash
|
||||
};
|
||||
|
||||
txs.push(new Transaction()
|
||||
.from(utxo)
|
||||
.to(pks[1].toAddress(), 1e8)
|
||||
.change(startingPk.toAddress()).fee(50000).sign(pks[0]));
|
||||
|
||||
var body = '{"rawtx":"' + txs[0].serialize() + '"}';
|
||||
|
||||
var httpOpts = {
|
||||
hostname: 'localhost',
|
||||
port: 53001,
|
||||
path: 'http://localhost:53001/api/tx/send',
|
||||
method: 'POST',
|
||||
body: body,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': body.length
|
||||
},
|
||||
};
|
||||
|
||||
request(httpOpts, function(err, data) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
txids.push(data.txid);
|
||||
callback();
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
describe('Subscriptions', function() {
|
||||
|
||||
this.timeout(60000);
|
||||
|
||||
before(function(done) {
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
console.log('step 0: setting up directories.');
|
||||
var dirs = bitcoinDataDirs.concat([bitcoreDataDir]);
|
||||
resetDirs(dirs, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
writeBitcoreConf();
|
||||
next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('step 1: start bitcoind');
|
||||
startBitcoinds(bitcoinDataDirs, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
waitForBitcoinReady(rpc, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
blocksGenerated += 10;
|
||||
rpc.generate(10, function(err, res) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
blocks = res.result;
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
console.log('step 2: start bitcore');
|
||||
startBitcore(next);
|
||||
},
|
||||
function(next) {
|
||||
console.log('step 3: make local private keys.');
|
||||
makeLocalPrivateKeys();
|
||||
},
|
||||
function(next) {
|
||||
console.log('step 4: setup initial tx.');
|
||||
getFirstIncomingFunds(next);
|
||||
}
|
||||
], done);
|
||||
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
shutdownBitcore(function() {
|
||||
shutdownBitcoind(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should get transaction after websocket reception of transaction', function(done) {
|
||||
var socket = io('ws://localhost:53001', {
|
||||
transports: [ 'websocket' ]
|
||||
});
|
||||
socket.emit('subscribe', 'mempool/transaction');
|
||||
// send a transaction
|
||||
socket.on('message', function(msg) {
|
||||
console.log(msg);
|
||||
done();
|
||||
});
|
||||
sendTx();
|
||||
});
|
||||
|
||||
it('should get block after websocket reception of block', function(done) {
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user