diff --git a/lib/services/db.js b/lib/services/db.js index b4e493b6..a5da6568 100644 --- a/lib/services/db.js +++ b/lib/services/db.js @@ -51,6 +51,8 @@ function DB(options) { this.levelupStore = options.store; } + this.retryInterval = 60000; + this.subscriptions = { transaction: [], block: [] @@ -217,11 +219,24 @@ DB.prototype.loadTip = function(callback) { var hash = tipData.toString('hex'); - self.getBlock(hash, function(err, tip) { + var times = 0; + async.retry({times: 3, interval: self.retryInterval}, function(done) { + self.getBlock(hash, function(err, tip) { + if(err) { + times++; + log.warn('Bitcoind does not have our tip (' + hash + '). Bitcoind may have crashed and needs to catch up.'); + if(times < 3) { + log.warn('Retrying in ' + (self.retryInterval / 1000) + ' seconds.'); + } + return done(err); + } + + done(null, tip); + }); + }, function(err, tip) { if(err) { - log.warn('Database is in an inconsistent state, a reindex is needed. Could not get current tip:', - hash - ); + log.warn('Giving up after 3 tries. Please report this bug to https://github.com/bitpay/bitcore-node/issues'); + log.warn('Please reindex your database.'); return callback(err); } diff --git a/test/services/db.unit.js b/test/services/db.unit.js index 1a3bf7d2..a5032845 100644 --- a/test/services/db.unit.js +++ b/test/services/db.unit.js @@ -306,7 +306,7 @@ describe('DB Service', function() { }); }); - it('give error from getBlock', function(done) { + it('should try 3 times before giving error from getBlock', function(done) { var node = { network: Networks.testnet, datadir: 'testdir', @@ -319,6 +319,7 @@ describe('DB Service', function() { } }; var db = new DB({node: node}); + db.retryInterval = 10; var tipHash = '00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206'; db.store = { get: sinon.stub().callsArgWith(2, null, new Buffer(tipHash, 'hex')) @@ -326,6 +327,7 @@ describe('DB Service', function() { db.getBlock = sinon.stub().callsArgWith(1, new Error('test')); db.loadTip(function(err) { should.exist(err); + db.getBlock.callCount.should.equal(3); err.message.should.equal('test'); done(); });