Added a block cache to speed up syncing.
This commit is contained in:
parent
cb06d8a3cb
commit
ad650c383e
@ -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));
|
||||
|
||||
@ -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);
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user