Fix reorg integration test after rebase.

This commit is contained in:
Braydon Fuller 2015-08-24 16:33:44 -04:00
parent f1642388af
commit 49cf3a9ca3
8 changed files with 83 additions and 146 deletions

View File

@ -66,21 +66,14 @@ describe('Daemon Binding Functionality', function() {
network: 'regtest'
});
bitcoind.start(function() {
log.info('Bitcoind started');
});
bitcoind.on('error', function(err) {
log.error('error="%s"', err.message);
});
bitcoind.on('open', function(status) {
log.info('status="%s"', status);
});
log.info('Waiting for Bitcoin Core to initialize...');
bitcoind.on('ready', function() {
bitcoind.start(function() {
log.info('Bitcoind started');
client = new BitcoinRPC({
protocol: 'http',
@ -96,6 +89,7 @@ describe('Daemon Binding Functionality', function() {
// can be spent.
client.generate(150, function(err, response) {
if (err) {
throw err;
}
@ -139,7 +133,9 @@ describe('Daemon Binding Functionality', function() {
});
});
});
});
});
});

View File

@ -45,12 +45,15 @@ function Chain(options) {
this.targetTimespan = options.targetTimespan || Chain.DEFAULTS.TARGET_TIMESPAN;
this.targetSpacing = options.targetSpacing || Chain.DEFAULTS.TARGET_SPACING;
this.node = options.node;
return this;
}
util.inherits(Chain, BaseChain);
Chain.prototype.start = function(callback) {
this.genesis = Block.fromBuffer(this.node.bitcoind.genesisBuffer);
this.on('initialized', callback);
this.initialize();
};

View File

@ -27,6 +27,8 @@ function Daemon(options) {
this.options.datadir = this.options.datadir.replace(/^~/, process.env.HOME);
this.datadir = this.options.datadir;
this.node = options.node;
this.config = this.datadir + '/bitcoin.conf';
Object.keys(exports).forEach(function(key) {
@ -68,6 +70,7 @@ Daemon.prototype.start = function(callback) {
function onTipUpdateListener(result) {
if (result) {
// Emit and event that the tip was updated
self.height = result;
self.emit('tip', result);
// Recursively wait until the next update
bitcoind.onTipUpdate(onTipUpdateListener);
@ -82,10 +85,17 @@ Daemon.prototype.start = function(callback) {
}
});
setImmediate(function() {
// Set the current chain height
var info = self.getInfo();
self.height = info.blocks;
// Get the genesis block
self.getBlock(0, function(err, block) {
self.genesisBuffer = block;
self.emit('ready', result);
callback();
setImmediate(callback);
});
});
});
};

View File

@ -26,6 +26,8 @@ function DB(options) {
this.network = bitcore.Networks.get(options.network) || bitcore.Networks.testnet;
this.node = options.node;
// Modules to be loaded when ready
this._modules = options.modules || [];
this._modules.push(AddressModule);
@ -49,7 +51,7 @@ DB.prototype.start = function(callback) {
}
this.bitcoind.on('tx', this.transactionHandler.bind(this));
this.emit('ready');
callback();
setImmediate(callback);
};
DB.prototype.stop = function(callback) {
@ -132,7 +134,7 @@ DB.prototype.estimateFee = function(blocks, callback) {
setImmediate(function() {
callback(null, self.bitcoind.estimateFee(blocks));
});
}
};
DB.prototype.validateBlockData = function(block, callback) {
// bitcoind does the validation

View File

@ -1,4 +0,0 @@
{
"livenet": "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"testnet": "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"
}

View File

@ -14,7 +14,6 @@ var bitcore = require('bitcore');
var Networks = bitcore.Networks;
var _ = bitcore.deps._;
var $ = bitcore.util.preconditions;
var genesis = require('./genesis.json');
var daemon = require('./daemon');
var Bus = require('./bus');
@ -25,12 +24,6 @@ function Node(config) {
util.inherits(Node, BaseNode);
var defaultServices = {
'bitcoind': [],
'db': ['bitcoind'],
'chain': ['db'],
};
Node.prototype.openBus = function() {
return new Bus({db: this.db});
};
@ -101,6 +94,7 @@ Node.prototype._loadBitcoind = function(config) {
var bitcoindConfig = {};
bitcoindConfig.datadir = config.datadir;
bitcoindConfig.network = config.network;
bitcoindConfig.node = this;
// start the bitcoind daemon
this.bitcoind = daemon(bitcoindConfig);
@ -228,7 +222,7 @@ Node.prototype._syncBitcoind = function() {
async.whilst(function() {
height = self.chain.tip.__height;
return height < self.bitcoindHeight && !self.stopping;
return height < self.bitcoind.height && !self.stopping;
}, function(done) {
self.bitcoind.getBlock(height + 1, function(err, blockBuffer) {
if (err) {
@ -323,15 +317,13 @@ Node.prototype._loadNetwork = function(config) {
};
Node.prototype._loadDB = function(config) {
var options = _.clone(config.db || {});
if (config.DB) {
// Other modules can inherit from our DB and replace it with their own
DB = config.DB;
}
if(!config.db) {
config.db = {};
}
// Store the additional indexes in a new directory
// based on the network configuration and the datadir
$.checkArgument(config.datadir, 'Please specify "datadir" in configuration options');
@ -339,50 +331,35 @@ Node.prototype._loadDB = function(config) {
var regtest = Networks.get('regtest');
var datadir = config.datadir.replace(/^~/, process.env.HOME);
if (this.network === Networks.livenet) {
config.db.path = datadir + '/bitcore-node.db';
options.path = datadir + '/bitcore-node.db';
} else if (this.network === Networks.testnet) {
config.db.path = datadir + '/testnet3/bitcore-node.db';
options.path = datadir + '/testnet3/bitcore-node.db';
} else if (this.network === regtest) {
config.db.path = datadir + '/regtest/bitcore-node.db';
options.path = datadir + '/regtest/bitcore-node.db';
} else {
throw new Error('Unknown network: ' + this.network);
}
config.db.network = this.network;
options.network = this.network;
if (!fs.existsSync(config.db.path)) {
mkdirp.sync(config.db.path);
if (!fs.existsSync(options.path)) {
mkdirp.sync(options.path);
}
this.db = new DB(config.db);
options.node = this;
this.db = new DB(options);
};
Node.prototype._loadConsensus = function(config) {
if (!config.consensus) {
config.consensus = {};
}
this.Block = Block;
var genesisBlock;
if (config.genesis) {
genesisBlock = config.genesis;
} else if (config.network === 'testnet') {
genesisBlock = genesis.testnet;
} else if (config.network === 'regtest') {
// initializeBitcoind will set the genesis block later in the chain
// todo: we should be able to refactor since the genesis is set later
genesisBlock = null;
var options;
if (!config) {
options = {};
} else {
genesisBlock = genesis.livenet;
options = _.clone(config.consensus || {});
}
if (_.isString(genesisBlock)) {
genesisBlock = this.Block.fromBuffer(new Buffer(genesisBlock, 'hex'));
}
// pass genesis to chain
config.consensus.genesis = genesisBlock;
this.chain = new Chain(config.consensus);
options.node = this;
this.Block = Block;
this.chain = new Chain(options);
};
Node.prototype._initialize = function() {
@ -396,10 +373,9 @@ Node.prototype._initialize = function() {
// Chain References
this.chain.db = this.db;
// Initialize the event listeners
this._initializeBitcoind();
this._initializeChain();
this._initializeDatabase();
this._initializeChain();
this.start(function(err) {
if(err) {
@ -412,22 +388,9 @@ Node.prototype._initialize = function() {
Node.prototype._initializeBitcoind = function() {
var self = this;
// Bitcoind
this.bitcoind.on('ready', function(status) {
// Notify that there is a new tip
this.bitcoind.on('ready', function() {
log.info('Bitcoin Daemon Ready');
// Set the current chain height
var info = self.bitcoind.getInfo();
self.bitcoindHeight = info.blocks;
// Get the genesis block
self.bitcoind.getBlock(0, function(err, block) {
self.chain.genesis = self.Block.fromBuffer(block);
});
});
this.bitcoind.on('open', function(status) {
log.info('Bitcoin Core Daemon Status:', status);
});
// Notify that there is a new tip
@ -435,7 +398,6 @@ Node.prototype._initializeBitcoind = function() {
if(!self.stopping) {
var percentage = self.bitcoind.syncPercentage();
log.info('Bitcoin Core Daemon New Height:', height, 'Percentage:', percentage);
self.bitcoindHeight = height;
self._syncBitcoind();
}
});
@ -465,17 +427,24 @@ Node.prototype._initializeChain = function() {
log.info('Bitcoin Chain Ready');
self._syncBitcoind();
});
this.chain.on('error', function(err) {
Error.captureStackTrace(err);
self.emit('error', err);
});
};
Node.prototype.getServiceOrder = function(services, keys, stack) {
if(!services) {
services = defaultServices;
}
Node.prototype.getServices = function() {
var defaultServices = {
'bitcoind': [],
'db': ['bitcoind'],
'chain': ['db']
};
return defaultServices;
};
Node.prototype.getServiceOrder = function(keys, stack) {
var services = this.getServices();
if(!keys) {
keys = Object.keys(services);
@ -486,21 +455,20 @@ Node.prototype.getServiceOrder = function(services, keys, stack) {
}
for(var i = 0; i < keys.length; i++) {
this.getServiceOrder(services, services[keys[i]], stack);
this.getServiceOrder(services[keys[i]], stack);
if(stack.indexOf(keys[i]) === -1) {
stack.push(keys[i]);
}
}
return stack;
};
Node.prototype.start = function(callback) {
var self = this;
var services = this.getServiceOrder();
var servicesOrder = this.getServiceOrder();
async.eachSeries(
services,
servicesOrder,
function(service, next) {
log.info('Starting ' + service);
self[service].start(next);

View File

@ -28,6 +28,8 @@ describe('Bitcoin Chain', function() {
describe('#start', function() {
it('should call the callback when base chain is initialized', function(done) {
var chain = new Chain();
chain.bitcoind = {};
chain.bitcoind.genesisBuffer = new Buffer('0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000', 'hex');
chain.initialize = function() {
chain.emit('initialized');
};

View File

@ -227,12 +227,12 @@ describe('Bitcoind Node', function() {
it('will get and add block up to the tip height', function(done) {
var node = new Node({});
node.Block = Block;
node.bitcoindHeight = 1;
var blockBuffer = new Buffer(blockData);
var block = Block.fromBuffer(blockBuffer);
node.bitcoind = {
getBlock: sinon.stub().callsArgWith(1, null, blockBuffer),
isSynced: sinon.stub().returns(true)
isSynced: sinon.stub().returns(true),
height: 1
};
node.chain = {
tip: {
@ -259,9 +259,9 @@ describe('Bitcoind Node', function() {
});
it('will exit and emit error with error from bitcoind.getBlock', function(done) {
var node = new Node({});
node.bitcoindHeight = 1;
node.bitcoind = {
getBlock: sinon.stub().callsArgWith(1, new Error('test error'))
getBlock: sinon.stub().callsArgWith(1, new Error('test error')),
height: 1
};
node.chain = {
tip: {
@ -277,12 +277,12 @@ describe('Bitcoind Node', function() {
it('will stop syncing when the node is stopping', function(done) {
var node = new Node({});
node.Block = Block;
node.bitcoindHeight = 1;
var blockBuffer = new Buffer(blockData);
var block = Block.fromBuffer(blockBuffer);
node.bitcoind = {
getBlock: sinon.stub().callsArgWith(1, null, blockBuffer),
isSynced: sinon.stub().returns(true)
isSynced: sinon.stub().returns(true),
height: 1
};
node.chain = {
tip: {
@ -434,28 +434,12 @@ describe('Bitcoind Node', function() {
describe('#_loadConsensus', function() {
var node = new Node({});
it('should use the genesis specified in the config', function() {
var config = {
genesis: '0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000'
};
node._loadConsensus(config);
it('will set properties', function() {
node._loadConsensus();
should.exist(node.Block);
should.exist(node.chain);
node.chain.genesis.hash.should.equal('00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206');
});
it('should use the testnet genesis if testnet is specified', function() {
var config = {
network: 'testnet'
};
node._loadConsensus(config);
should.exist(node.chain);
node.chain.genesis.hash.should.equal('000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943');
});
it('should use the livenet genesis if nothing is specified', function() {
var config = {};
node._loadConsensus(config);
should.exist(node.chain);
node.chain.genesis.hash.should.equal('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
});
});
describe('#_initialize', function() {
@ -516,29 +500,6 @@ describe('Bitcoind Node', function() {
describe('#_initalizeBitcoind', function() {
it('set the genesis block when ready and set height', function(done) {
var genesisBuffer = new Buffer('0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000', 'hex');
var node = new Node({});
node.Block = Block;
node.chain = {};
node.bitcoind = new EventEmitter();
node.bitcoind.getInfo = sinon.stub().returns({blocks: 10});
node.bitcoind.getBlock = sinon.stub().callsArgWith(1, null, genesisBuffer);
node.db = {
initialize: sinon.spy()
};
sinon.stub(chainlib.log, 'info');
node.bitcoind.on('ready', function() {
setImmediate(function() {
chainlib.log.info.callCount.should.equal(1);
chainlib.log.info.restore();
node.bitcoindHeight.should.equal(10);
done();
});
});
node._initializeBitcoind();
node.bitcoind.emit('ready');
});
it('will call emit an error from libbitcoind', function(done) {
var node = new Node({});
node.bitcoind = new EventEmitter();
@ -556,7 +517,6 @@ describe('Bitcoind Node', function() {
node.bitcoind.syncPercentage = sinon.spy();
node._syncBitcoind = function() {
node.bitcoind.syncPercentage.callCount.should.equal(1);
node.bitcoindHeight.should.equal(10);
done();
};
node._initializeBitcoind();
@ -636,17 +596,17 @@ describe('Bitcoind Node', function() {
});
describe('#getServiceOrder', function() {
var services = {
'chain': ['db'],
'db': ['daemon', 'p2p'],
'daemon': [],
'p2p': []
};
it('should return the services in the correct order', function() {
var node = new Node({});
var order = node.getServiceOrder(services);
node.getServices = function() {
return {
'chain': ['db'],
'db': ['daemon', 'p2p'],
'daemon': [],
'p2p': []
};
};
var order = node.getServiceOrder();
order.should.deep.equal(['daemon', 'p2p', 'db', 'chain']);
});
});