net: resend sync on peer disconnection.

This commit is contained in:
Christopher Jeffrey 2017-03-07 18:59:46 -08:00
parent 6a229d597e
commit 2bbeb40ac5
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -173,7 +173,7 @@ Pool.prototype._init = function _init() {
});
this.chain.on('full', function() {
self.sync();
self.resync();
self.emit('full');
self.logger.info('Chain is fully synced (height=%d).', self.chain.height);
});
@ -686,44 +686,20 @@ Pool.prototype.startSync = function startSync() {
assert(this.connected, 'Pool is not connected!');
this.syncing = true;
this.sync();
this.resync(false);
};
/**
* Send a sync to each peer.
* @private
*/
Pool.prototype.sync = function sync() {
var peer;
if (!this.syncing)
return;
for (peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
this.sendSync(peer);
}
};
/**
* Force sending a sync to each peer.
* @private
* Force sending of a sync to each peer.
*/
Pool.prototype.forceSync = function forceSync() {
var peer;
if (!this.syncing)
if (!this.loaded)
return;
for (peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
peer.syncing = false;
this.sendSync(peer);
}
assert(this.connected, 'Pool is not connected!');
this.resync(true);
};
/**
@ -747,15 +723,43 @@ Pool.prototype.stopSync = function stopSync() {
};
/**
* Start syncing from peer.
* @method
* @param {Peer} peer
* Send a sync to each peer.
* @private
* @param {Boolean?} force
* @returns {Promise}
*/
Pool.prototype.sendSync = co(function* sendSync(peer) {
var locator;
Pool.prototype.resync = co(function* resync(force) {
var peer, locator;
if (!this.syncing)
return;
try {
locator = yield this.chain.getLocator();
} catch (e) {
this.emit('error', e);
return;
}
for (peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
if (!force && peer.syncing)
continue;
this.sendLocator(locator, peer);
}
});
/**
* Test whether a peer is sync-worthy.
* @param {Peer} peer
* @returns {Boolean}
*/
Pool.prototype.isSyncable = function isSyncable(peer) {
if (!this.syncing)
return false;
@ -765,9 +769,6 @@ Pool.prototype.sendSync = co(function* sendSync(peer) {
if (!peer.handshake)
return false;
if (peer.syncing)
return false;
if (!(peer.services & services.NETWORK))
return false;
@ -779,6 +780,54 @@ Pool.prototype.sendSync = co(function* sendSync(peer) {
return false;
}
return true;
};
/**
* Start syncing from peer.
* @method
* @param {Peer} peer
* @returns {Promise}
*/
Pool.prototype.sendSync = co(function* sendSync(peer) {
var locator;
if (peer.syncing)
return false;
if (!this.isSyncable(peer))
return false;
peer.syncing = true;
peer.blockTime = util.ms();
try {
locator = yield this.chain.getLocator();
} catch (e) {
peer.syncing = false;
peer.blockTime = -1;
this.emit('error', e);
return false;
}
return this.sendLocator(locator, peer);
});
/**
* Send a chain locator and start syncing from peer.
* @method
* @param {Hash[]} locator
* @param {Peer} peer
* @returns {Boolean}
*/
Pool.prototype.sendLocator = function sendLocator(locator, peer) {
var locator;
if (!this.isSyncable(peer))
return false;
// Ask for the mempool if we're synced.
if (this.network.requestMempool) {
if (peer.loader && this.chain.synced)
@ -788,16 +837,6 @@ Pool.prototype.sendSync = co(function* sendSync(peer) {
peer.syncing = true;
peer.blockTime = util.ms();
try {
locator = yield this.chain.getLocator();
} catch (e) {
this.emit('error', e);
return false;
}
if (peer.destroyed)
return false;
if (this.checkpoints) {
peer.sendGetHeaders(locator, this.headerTip.hash);
return true;
@ -806,7 +845,7 @@ Pool.prototype.sendSync = co(function* sendSync(peer) {
peer.sendGetBlocks(locator);
return true;
});
};
/**
* Send `mempool` to all peers.
@ -1336,6 +1375,7 @@ Pool.prototype.handleOpen = co(function* handleOpen(peer) {
Pool.prototype.handleClose = co(function* handleClose(peer, connected) {
var outbound = peer.outbound;
var loader = peer.loader;
var size = peer.requestMap.size;
this.removePeer(peer);
@ -1352,10 +1392,16 @@ Pool.prototype.handleClose = co(function* handleClose(peer, connected) {
if (!this.loaded)
return;
if (!outbound)
if (this.disconnecting)
return;
if (this.disconnecting)
if (this.chain.synced && !loader && size > 0) {
this.logger.debug('Peer with requested blocks disconnected.');
this.logger.debug('Resending sync...');
this.forceSync();
}
if (!outbound)
return;
this.refill();