Added a block cache to speed up syncing.

This commit is contained in:
Chris Kleeschulte 2017-10-24 17:46:34 -04:00
parent cb06d8a3cb
commit ad650c383e
No known key found for this signature in database
GPG Key ID: 33195D27EF6BDB7F
3 changed files with 32 additions and 16 deletions

View File

@ -29,6 +29,7 @@ var BlockService = function(options) {
this._blocksInQueue = 0;
this._recentBlockHashesCount = options.recentBlockHashesCount || 50; // if you expect this chain to reorg deeper than 50, set this
this._recentBlockHashes = new LRU(this._recentBlockHashesCount);
this._readAheadBlockCount = options.readAheadBlockCount || 2; // this is the number of blocks to direct the p2p service to read aheead
};
inherits(BlockService, BaseService);
@ -943,13 +944,13 @@ BlockService.prototype._sync = function() {
log.debug('Block Service: querying header service for next block using tip: ' + self._tip.hash);
self._header.getNextHash(self._tip, function(err, targetHash, nextHash) {
self._header.getEndHash(self._tip, self._readAheadBlockCount, function(err, targetHash, endHash) {
if(err) {
return self._handleError(err);
}
if (!targetHash && !nextHash) {
if (!targetHash && !endHash) {
return self.emit('synced');
}
@ -974,7 +975,7 @@ BlockService.prototype._sync = function() {
self._p2p.getP2PBlock({
filter: {
startHash: self._tip.hash,
endHash: nextHash
endHash: endHash
},
blockHash: targetHash
}, self._syncBlock.bind(self));

View File

@ -852,12 +852,13 @@ HeaderService.prototype._sync = function() {
};
// this gets the header that is +2 places from hash or returns 0 if there is no such
HeaderService.prototype.getNextHash = function(tip, callback) {
HeaderService.prototype.getEndHash = function(tip, blockCount, callback) {
assert(blockCount >= 1, 'Header Service: block count to getEndHash must be at least 1.');
var self = this;
var numResultsNeeded = Math.min((self._tip.height - tip.height), 2);
var numResultsNeeded = Math.min((self._tip.height - tip.height), blockCount + 1);
if (numResultsNeeded === 0 && self._tip.hash === tip.hash) {
return callback();
@ -867,14 +868,14 @@ HeaderService.prototype.getNextHash = function(tip, callback) {
return callback(new Error('Header Service: block service is mis-aligned '));
}
var start = self._encoding.encodeHeaderHeightKey(tip.height + 1);
var end = self._encoding.encodeHeaderHeightKey(tip.height + 3);
var startingHeight = tip.height + 1;
var start = self._encoding.encodeHeaderHeightKey(startingHeight);
var end = self._encoding.encodeHeaderHeightKey(startingHeight + blockCount);
var results = [];
var criteria = {
gte: start,
lt: end
lte: end
};
var stream = self._db.createReadStream(criteria);
@ -895,19 +896,18 @@ HeaderService.prototype.getNextHash = function(tip, callback) {
return streamErr;
}
assert(results.length === numResultsNeeded, 'GetNextHash returned incorrect number of results.');
assert(results.length === numResultsNeeded, 'getEndHash returned incorrect number of results.');
if (!results[1]) {
results[1] = 0;
}
var index = numResultsNeeded - 1;
var endHash = index <= 0 || !results[index] ? 0 : results[index];
if (self._slowMode) {
return setTimeout(function() {
callback(null, results[0], results[1]);
callback(null, results[0], endHash);
}, self._slowMode);
}
callback(null, results[0], results[1]);
callback(null, results[0], endHash);
});

View File

@ -27,6 +27,10 @@ var P2P = function(options) {
this._currentBestHeight = null;
this._latestBits = 0x1d00ffff;
this._outgoingTxs = LRU(100); // these are outgoing txs that are awaiting getdata messages
this._blockCache = options.blockCacheCount || LRU({
max: 10,
maxAge: 1000 * 60 * 5}); // keep this modest to avoid memory dumps [hash -> block]
};
util.inherits(P2P, BaseService);
@ -53,8 +57,18 @@ P2P.prototype.getNumberOfPeers = function() {
};
P2P.prototype.getP2PBlock = function(opts, callback) {
// opts is { filter: {<start and end hashes>}, blockHash: block hash we want }
var self = this;
// do we already have this block in our cache?
var block = self._blockCache.get(opts.blockHash);
if (block) {
return callback(block);
}
var peer = self._getPeer();
var blockFilter = self._setResourceFilter(opts.filter, 'blocks');
@ -291,6 +305,7 @@ P2P.prototype._initPubSub = function() {
};
P2P.prototype._onPeerBlock = function(peer, message) {
this._blockCache.set(message.block.rhash(), message.block);
this.emit(message.block.rhash(), message.block);
this._broadcast(this.subscriptions.block, 'p2p/block', message.block);
};