bitcore-node-zcash/integration/regtest-node.js

629 lines
18 KiB
JavaScript
Raw Normal View History

2015-08-21 08:17:26 -07:00
'use strict';
// These tests require bitcore-node Bitcoin Core bindings to be compiled with
// the environment variable BITCORENODE_ENV=test. This enables the use of regtest
2015-08-21 08:17:26 -07:00
// functionality by including the wallet in the build.
2015-08-24 06:56:38 -07:00
// To run the tests: $ mocha -R spec integration/regtest-node.js
2015-08-21 08:17:26 -07:00
var index = require('..');
2015-08-24 06:56:38 -07:00
var async = require('async');
var log = index.log;
2015-08-24 06:56:38 -07:00
log.debug = function() {};
2015-08-21 08:17:26 -07:00
if (process.env.BITCORENODE_ENV !== 'test') {
log.info('Please set the environment variable BITCORENODE_ENV=test and make sure bindings are compiled for testing');
process.exit();
}
var chai = require('chai');
var bitcore = require('bitcore');
var rimraf = require('rimraf');
var node;
var should = chai.should();
var BitcoinRPC = require('bitcoind-rpc');
2015-08-31 06:00:00 -07:00
var index = require('..');
var Transaction = index.Transaction;
2015-08-31 06:00:00 -07:00
var BitcoreNode = index.Node;
2015-08-31 06:00:00 -07:00
var AddressService = index.services.Address;
var BitcoinService = index.services.Bitcoin;
var DBService = index.services.DB;
2015-08-21 08:17:26 -07:00
var testWIF = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG';
var testKey;
var client;
describe('Node Functionality', function() {
var regtest;
2015-08-21 08:17:26 -07:00
before(function(done) {
this.timeout(30000);
// Add the regtest network
bitcore.Networks.remove(bitcore.Networks.testnet);
bitcore.Networks.add({
name: 'regtest',
alias: 'regtest',
pubkeyhash: 0x6f,
privatekey: 0xef,
scripthash: 0xc4,
xpubkey: 0x043587cf,
xprivkey: 0x04358394,
networkMagic: 0xfabfb5da,
port: 18444,
dnsSeeds: [ ]
});
regtest = bitcore.Networks.get('regtest');
2015-08-21 08:17:26 -07:00
var datadir = __dirname + '/data';
testKey = bitcore.PrivateKey(testWIF);
rimraf(datadir + '/regtest', function(err) {
if (err) {
throw err;
}
var configuration = {
datadir: datadir,
2015-08-31 06:00:00 -07:00
network: 'regtest',
2015-08-31 06:00:00 -07:00
services: [
2015-08-31 06:00:00 -07:00
{
2015-08-31 06:00:00 -07:00
name: 'db',
2015-08-31 06:00:00 -07:00
module: DBService,
2015-08-31 10:38:21 -07:00
config: {}
2015-08-31 06:00:00 -07:00
},
{
2015-08-31 06:00:00 -07:00
name: 'bitcoind',
2015-08-31 06:00:00 -07:00
module: BitcoinService,
2015-08-31 10:38:21 -07:00
config: {}
2015-08-31 06:00:00 -07:00
},
{
name: 'address',
2015-08-31 06:00:00 -07:00
module: AddressService,
2015-08-31 10:38:21 -07:00
config: {}
2015-08-31 06:00:00 -07:00
}
]
2015-08-21 08:17:26 -07:00
};
node = new BitcoreNode(configuration);
node.on('error', function(err) {
log.error(err);
});
node.on('ready', function() {
client = new BitcoinRPC({
protocol: 'https',
2015-08-21 08:17:26 -07:00
host: '127.0.0.1',
port: 18332,
user: 'bitcoin',
pass: 'local321',
rejectUnauthorized: false
2015-08-21 08:17:26 -07:00
});
2015-08-24 06:56:38 -07:00
var syncedHandler = function() {
2015-08-31 06:00:00 -07:00
if (node.services.db.tip.__height === 150) {
2015-08-24 06:56:38 -07:00
node.removeListener('synced', syncedHandler);
2015-08-21 08:17:26 -07:00
done();
}
2015-08-24 06:56:38 -07:00
};
node.on('synced', syncedHandler);
2015-08-21 08:17:26 -07:00
client.generate(150, function(err, response) {
if (err) {
throw err;
}
});
});
node.start(function(err) {
if (err) {
throw err;
}
});
2015-08-21 08:17:26 -07:00
});
});
after(function(done) {
this.timeout(20000);
2015-08-31 06:00:00 -07:00
node.stop(function(err, result) {
if(err) {
throw err;
}
2015-08-21 08:17:26 -07:00
done();
});
});
2015-09-08 11:04:14 -07:00
var invalidatedBlockHash;
2015-08-24 06:56:38 -07:00
it('will handle a reorganization', function(done) {
2015-08-21 08:17:26 -07:00
2015-08-24 06:56:38 -07:00
var count;
var blockHash;
async.series([
function(next) {
client.getBlockCount(function(err, response) {
if (err) {
return next(err);
}
count = response.result;
next();
});
},
function(next) {
2015-08-21 08:17:26 -07:00
client.getBlockHash(count, function(err, response) {
if (err) {
2015-08-24 06:56:38 -07:00
return next(err);
2015-08-21 08:17:26 -07:00
}
2015-09-08 11:04:14 -07:00
invalidatedBlockHash = response.result;
2015-08-24 06:56:38 -07:00
next();
2015-08-21 08:17:26 -07:00
});
2015-08-24 06:56:38 -07:00
},
function(next) {
2015-09-08 11:04:14 -07:00
client.invalidateBlock(invalidatedBlockHash, next);
2015-08-24 06:56:38 -07:00
},
function(next) {
client.getBlockCount(function(err, response) {
if (err) {
return next(err);
}
response.result.should.equal(count - 1);
next();
});
}
], function(err) {
if (err) {
throw err;
}
var blocksRemoved = 0;
var blocksAdded = 0;
2015-08-21 08:17:26 -07:00
2015-08-24 06:56:38 -07:00
var removeBlock = function() {
blocksRemoved++;
};
2015-08-21 08:17:26 -07:00
2015-08-31 06:00:00 -07:00
node.services.db.on('removeblock', removeBlock);
2015-08-24 06:56:38 -07:00
var addBlock = function() {
blocksAdded++;
if (blocksAdded === 2 && blocksRemoved === 1) {
2015-08-31 06:00:00 -07:00
node.services.db.removeListener('addblock', addBlock);
node.services.db.removeListener('removeblock', removeBlock);
2015-08-24 06:56:38 -07:00
done();
}
};
2015-08-31 06:00:00 -07:00
node.services.db.on('addblock', addBlock);
2015-08-21 08:17:26 -07:00
// We need to add a transaction to the mempool so that the next block will
// have a different hash as the hash has been invalidated.
client.sendToAddress(testKey.toAddress().toString(), 10, function(err) {
if (err) {
throw err;
}
client.generate(2, function(err, response) {
if (err) {
throw err;
}
});
});
});
2015-08-24 06:56:38 -07:00
});
2015-09-08 11:04:14 -07:00
it('isMainChain() will return false for stale/orphan block', function(done) {
2015-09-08 14:42:33 -07:00
node.services.bitcoind.isMainChain(invalidatedBlockHash).should.equal(false);
2015-09-08 11:04:14 -07:00
setImmediate(done);
});
describe('Bus Functionality', function() {
it('subscribes and unsubscribes to an event on the bus', function(done) {
var bus = node.openBus();
var block;
bus.subscribe('db/block');
bus.on('block', function(data) {
bus.unsubscribe('db/block');
data.should.be.equal(block);
done();
});
client.generate(1, function(err, response) {
if (err) {
throw err;
}
block = response.result[0];
});
});
});
describe('Address Functionality', function() {
var address;
var unspentOutput;
before(function() {
address = testKey.toAddress().toString();
});
it('should be able to get the balance of the test address', function(done) {
node.services.address.getBalance(address, false, function(err, balance) {
if (err) {
throw err;
}
balance.should.equal(10 * 1e8);
done();
});
});
it('can get unspent outputs for address', function(done) {
node.services.address.getUnspentOutputs(address, false, function(err, results) {
if (err) {
throw err;
}
results.length.should.equal(1);
unspentOutput = results[0];
done();
});
});
it('correctly give the history for the address', function(done) {
var options = {
from: 0,
to: 10,
queryMempool: false
};
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
results.length.should.equal(1);
var info = results[0];
info.address.should.equal(address);
info.satoshis.should.equal(10 * 1e8);
info.confirmations.should.equal(3);
info.timestamp.should.be.a('number');
info.fees.should.be.within(190, 193);
info.outputIndexes.length.should.equal(1);
info.outputIndexes[0].should.be.within(0, 1);
info.inputIndexes.should.deep.equal([]);
info.tx.should.be.an.instanceof(Transaction);
done();
});
});
describe('History', function() {
this.timeout(20000);
var testKey2;
var address2;
var testKey3;
var address3;
var testKey4;
var address4;
var testKey5;
var address5;
var testKey6;
var address6;
before(function(done) {
/* jshint maxstatements: 50 */
testKey2 = bitcore.PrivateKey.fromWIF('cNfF4jXiLHQnFRsxaJyr2YSGcmtNYvxQYSakNhuDGxpkSzAwn95x');
address2 = testKey2.toAddress().toString();
testKey3 = bitcore.PrivateKey.fromWIF('cVTYQbaFNetiZcvxzXcVMin89uMLC43pEBMy2etgZHbPPxH5obYt');
address3 = testKey3.toAddress().toString();
testKey4 = bitcore.PrivateKey.fromWIF('cPNQmfE31H2oCUFqaHpfSqjDibkt7XoT2vydLJLDHNTvcddCesGw');
address4 = testKey4.toAddress().toString();
testKey5 = bitcore.PrivateKey.fromWIF('cVrzm9gCmnzwEVMGeCxY6xLVPdG3XWW97kwkFH3H3v722nb99QBF');
address5 = testKey5.toAddress().toString();
testKey6 = bitcore.PrivateKey.fromWIF('cPfMesNR2gsQEK69a6xe7qE44CZEZavgMUak5hQ74XDgsRmmGBYF');
address6 = testKey6.toAddress().toString();
var tx = new Transaction();
tx.from(unspentOutput);
tx.to(address, 1 * 1e8);
tx.to(address, 2 * 1e8);
tx.to(address, 0.5 * 1e8);
tx.to(address, 3 * 1e8);
tx.fee(10000);
tx.change(address);
tx.sign(testKey);
node.services.bitcoind.sendTransaction(tx.serialize());
function mineBlock(next) {
client.generate(1, function(err, response) {
if (err) {
throw err;
}
should.exist(response);
next();
});
}
client.generate(1, function(err, response) {
if (err) {
throw err;
}
should.exist(response);
node.once('synced', function() {
node.services.address.getUnspentOutputs(address, false, function(err, results) {
/* jshint maxstatements: 50 */
if (err) {
throw err;
}
results.length.should.equal(5);
async.series([
function(next) {
var tx2 = new Transaction();
tx2.from(results[0]);
tx2.to(address2, results[0].satoshis - 10000);
tx2.change(address);
tx2.sign(testKey);
node.services.bitcoind.sendTransaction(tx2.serialize());
mineBlock(next);
}, function(next) {
var tx3 = new Transaction();
tx3.from(results[1]);
tx3.to(address3, results[1].satoshis - 10000);
tx3.change(address);
tx3.sign(testKey);
node.services.bitcoind.sendTransaction(tx3.serialize());
mineBlock(next);
}, function(next) {
var tx4 = new Transaction();
tx4.from(results[2]);
tx4.to(address4, results[2].satoshis - 10000);
tx4.change(address);
tx4.sign(testKey);
node.services.bitcoind.sendTransaction(tx4.serialize());
mineBlock(next);
}, function(next) {
var tx5 = new Transaction();
tx5.from(results[3]);
tx5.from(results[4]);
tx5.to(address5, results[3].satoshis - 10000);
tx5.to(address6, results[4].satoshis - 10000);
tx5.change(address);
tx5.sign(testKey);
node.services.bitcoind.sendTransaction(tx5.serialize());
mineBlock(next);
}
], function(err) {
if (err) {
throw err;
}
node.once('synced', function() {
done();
});
});
});
});
});
});
it('five addresses', function(done) {
var addresses = [
address2,
address3,
address4,
address5,
address6
];
var options = {};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(5);
history[0].height.should.equal(157);
history[0].confirmations.should.equal(1);
history[1].height.should.equal(157);
history[2].height.should.equal(156);
history[2].address.should.equal(address4);
history[3].height.should.equal(155);
history[3].address.should.equal(address3);
history[4].height.should.equal(154);
history[4].address.should.equal(address2);
history[4].satoshis.should.equal(99990000);
history[4].confirmations.should.equal(4);
done();
});
});
it('five addresses (limited by height)', function(done) {
var addresses = [
address2,
address3,
address4,
address5,
address6
];
var options = {
start: 157,
end: 156
};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(3);
history[0].height.should.equal(157);
history[0].confirmations.should.equal(1);
history[1].height.should.equal(157);
history[2].height.should.equal(156);
history[2].address.should.equal(address4);
done();
});
});
it('five addresses (paginated by index)', function(done) {
var addresses = [
address2,
address3,
address4,
address5,
address6
];
var options = {
from: 0,
to: 3
};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(3);
history[0].height.should.equal(157);
history[0].confirmations.should.equal(1);
history[1].height.should.equal(157);
history[2].height.should.equal(156);
history[2].address.should.equal(address4);
done();
});
});
it('one address with sending and receiving', function(done) {
var addresses = [
address
];
var options = {};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(6);
history[0].height.should.equal(157);
history[0].inputIndexes.should.deep.equal([0, 1]);
history[0].outputIndexes.should.deep.equal([2]);
history[0].confirmations.should.equal(1);
history[1].height.should.equal(156);
history[2].height.should.equal(155);
history[3].height.should.equal(154);
history[4].height.should.equal(153);
history[4].satoshis.should.equal(-10000);
history[4].outputIndexes.should.deep.equal([0, 1, 2, 3, 4]);
history[4].inputIndexes.should.deep.equal([0]);
history[5].height.should.equal(150);
history[5].satoshis.should.equal(10 * 1e8);
done();
});
});
it('total transaction count (sending and receiving)', function(done) {
var addresses = [
address
];
var options = {};
node.services.address.getAddressHistoryCount(addresses, options, function(err, count) {
if (err) {
throw err;
}
count.should.equal(6);
done();
});
});
describe('Pagination', function() {
it('from 0 to 1', function(done) {
var options = {
from: 0,
to: 1
};
node.services.address.getAddressHistory(address, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(1);
history[0].height.should.equal(157);
done();
});
});
it('from 1 to 2', function(done) {
var options = {
from: 1,
to: 2
};
node.services.address.getAddressHistory(address, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(1);
history[0].height.should.equal(156);
done();
});
});
it('from 2 to 3', function(done) {
var options = {
from: 2,
to: 3
};
node.services.address.getAddressHistory(address, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(1);
history[0].height.should.equal(155);
done();
});
});
it('from 3 to 4', function(done) {
var options = {
from: 3,
to: 4
};
node.services.address.getAddressHistory(address, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(1);
history[0].height.should.equal(154);
done();
});
});
it('from 4 to 5', function(done) {
var options = {
from: 4,
to: 5
};
node.services.address.getAddressHistory(address, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(1);
history[0].height.should.equal(153);
history[0].satoshis.should.equal(-10000);
history[0].outputIndexes.should.deep.equal([0, 1, 2, 3, 4]);
history[0].inputIndexes.should.deep.equal([0]);
done();
});
});
it('from 5 to 6', function(done) {
var options = {
from: 5,
to: 6
};
node.services.address.getAddressHistory(address, options, function(err, history) {
if (err) {
throw err;
}
history.length.should.equal(1);
history[0].height.should.equal(150);
history[0].satoshis.should.equal(10 * 1e8);
done();
});
});
});
});
});
2015-08-21 08:17:26 -07:00
});