Added a reset tip routine.
This commit is contained in:
parent
d299856fdc
commit
dcf1426221
@ -28,6 +28,7 @@ var BlockService = function(options) {
|
|||||||
this._blockCount = 0;
|
this._blockCount = 0;
|
||||||
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.network];
|
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.network];
|
||||||
this._initialSync = true;
|
this._initialSync = true;
|
||||||
|
this._reorgBackToBlock = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
inherits(BlockService, BaseService);
|
inherits(BlockService, BaseService);
|
||||||
@ -167,10 +168,28 @@ BlockService.prototype.getRawBlock = function(hash, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockService.prototype._reorgBackTo = function(callback) {
|
||||||
|
var self = this;
|
||||||
|
self._header.getBlockHeader(self._reorgBackToBlock, function(err, header) {
|
||||||
|
if (err || !header) {
|
||||||
|
return callback(err || new Error('Header not found to reorg back to.'));
|
||||||
|
}
|
||||||
|
log.info('Block Service: we found the block to reorg back to, commencing reorg...');
|
||||||
|
self._handleReorg(header.hash, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
BlockService.prototype._checkTip = function(callback) {
|
BlockService.prototype._checkTip = function(callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
log.info('Block Service: checking the saved tip...');
|
||||||
|
|
||||||
|
if (self._reorgBackToBlock) {
|
||||||
|
log.warn('Block Service: we were asked to reorg back to block: ' + self._reorgBackToBlock);
|
||||||
|
return self._reorgBackTo(callback);
|
||||||
|
}
|
||||||
|
|
||||||
self._header.getBlockHeader(self._tip.height, function(err, header) {
|
self._header.getBlockHeader(self._tip.height, function(err, header) {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -209,8 +228,8 @@ BlockService.prototype._findCommonAncestor = function(callback) {
|
|||||||
return headers.get(hash);
|
return headers.get(hash);
|
||||||
}, function(next) {
|
}, function(next) {
|
||||||
self._getBlock(hash, function(err, block) {
|
self._getBlock(hash, function(err, block) {
|
||||||
if(err) {
|
if(err || !block) {
|
||||||
return next(err);
|
return next(err || new Error('block must be found in order to find common ancestor.'));
|
||||||
}
|
}
|
||||||
hash = bcoin.util.revHex(block.prevBlock);
|
hash = bcoin.util.revHex(block.prevBlock);
|
||||||
next();
|
next();
|
||||||
@ -224,6 +243,85 @@ BlockService.prototype._findCommonAncestor = function(callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockService.prototype._resetTip = function(callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (!self._tipResetNeeded) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
self._tipResetNeeded = false;
|
||||||
|
|
||||||
|
log.warn('Block Service: resetting tip due to a non-existent tip block...');
|
||||||
|
|
||||||
|
var block;
|
||||||
|
var header = self._header.getLastHeader();
|
||||||
|
var height = header.height;
|
||||||
|
|
||||||
|
self._header.getAllHeaders(function(err, headers) {
|
||||||
|
|
||||||
|
if (err || !headers) {
|
||||||
|
return callback(err || new Error('headers required'));
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info('Block Service: retrieved all the headers for lookups');
|
||||||
|
async.until(function() {
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
}, function(next) {
|
||||||
|
|
||||||
|
self._getBlock(header.hash, function(err, _block) {
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_block) {
|
||||||
|
log.warn('Block Service: block: ' + header.hash + ' was not found, proceeding to older blocks.');
|
||||||
|
}
|
||||||
|
|
||||||
|
block = _block;
|
||||||
|
header = headers.getIndex(--height);
|
||||||
|
assert(header, 'Header not found for reset.');
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
log.warn('Block Service: trying block: ' + header.hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}, function(err) {
|
||||||
|
|
||||||
|
if (err || !block) {
|
||||||
|
return callback(err ||
|
||||||
|
new Error('Block Service: none of the blocks from the headers match what is already indexed in the block service.'));
|
||||||
|
}
|
||||||
|
self._setTip({ hash: block.rhash(), height: height + 1 });
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
BlockService.prototype._performSanityCheck = function(tip, callback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
// is our tip saved in our database? If not, then find the latest block that is in
|
||||||
|
// in our database and set the tip to that
|
||||||
|
self._getBlock(tip.hash, function(err, block) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (block) {
|
||||||
|
return callback(null, tip);
|
||||||
|
}
|
||||||
|
return callback(null, false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
BlockService.prototype.start = function(callback) {
|
BlockService.prototype.start = function(callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -243,13 +341,23 @@ BlockService.prototype.start = function(callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self._blockProcessor = async.queue(self._onBlock.bind(self));
|
self._performSanityCheck(tip, function(err, tip) {
|
||||||
|
|
||||||
self._setListeners();
|
if (err) {
|
||||||
assert(tip.height >= 0, 'tip is not initialized');
|
return callback(err);
|
||||||
self._setTip(tip);
|
}
|
||||||
self._bus = self.node.openBus({remoteAddress: 'localhost-block'});
|
|
||||||
callback();
|
if (!tip) {
|
||||||
|
self._tipResetNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._blockProcessor = async.queue(self._onBlock.bind(self));
|
||||||
|
self._setListeners();
|
||||||
|
self._setTip(tip);
|
||||||
|
self._bus = self.node.openBus({remoteAddress: 'localhost-block'});
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -410,21 +518,26 @@ BlockService.prototype.onHeaders = function(callback) {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
async.retry(function(next) {
|
self._resetTip(function(err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
async.retry(function(next) {
|
||||||
|
|
||||||
next(self._blockProcessor.length() !== 0);
|
next(self._blockProcessor.length() !== 0);
|
||||||
|
|
||||||
}, function() {
|
}, function() {
|
||||||
|
|
||||||
self._checkTip(function(err) {
|
self._checkTip(function(err) {
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self._startSync();
|
self._startSync();
|
||||||
callback();
|
callback();
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user