pool: move sync method out of peer.

This commit is contained in:
Christopher Jeffrey 2017-01-20 22:24:45 -08:00
parent de0a60340b
commit 6016d96202
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 124 additions and 67 deletions

View File

@ -57,6 +57,14 @@ exports.SENDHEADERS_VERSION = 7012;
exports.COMPACT_VERSION = 70014;
/**
* Minimum version for bip152+segwit.
* @const {Number}
* @default
*/
exports.COMPACT_WITNESS_VERSION = 70015;
/**
* Service bits.
* @enum {Number}

View File

@ -118,7 +118,7 @@ function Peer(pool) {
this.merkleBlock = null;
this.merkleTime = -1;
this.merkleMatches = 0;
this.syncSent = false;
this.syncing = false;
this.sentAddr = false;
this.sentGetAddr = false;
this.challenge = null;
@ -1181,7 +1181,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
}
}
if (!this.pool.syncing || this.chain.synced)
if (!this.syncing || this.chain.synced)
return;
if (!this.isLoader())
@ -1337,14 +1337,12 @@ Peer.prototype.blockType = function blockType() {
if (this.options.spv)
return invTypes.FILTERED_BLOCK;
if (this.outbound && this.chain.synced) {
if (this.options.compact && this.compactMode !== -1) {
if (!this.options.witness || this.compactWitness)
return invTypes.CMPCT_BLOCK;
}
if (this.options.compact && this.outbound) {
if (this.hasCompact())
return invTypes.CMPCT_BLOCK;
}
if (this.hasWitness())
if (this.options.witness && this.hasWitness())
return invTypes.WITNESS_BLOCK;
return invTypes.BLOCK;
@ -1356,7 +1354,7 @@ Peer.prototype.blockType = function blockType() {
*/
Peer.prototype.txType = function txType() {
if (this.hasWitness())
if (this.options.witness && this.hasWitness())
return invTypes.WITNESS_TX;
return invTypes.TX;
@ -1729,6 +1727,11 @@ Peer.prototype.handleVersion = co(function* handleVersion(packet) {
if (!(this.services & services.WITNESS))
throw new Error('Peer does not support segregated witness.');
}
if (this.options.compact) {
if (!this.hasCompact())
throw new Error('Peer does not support compact blocks.');
}
}
this.send(new packets.VerackPacket());
@ -2240,58 +2243,6 @@ Peer.prototype.reject = function reject(msg, code, reason, score) {
this.increaseBan(score);
};
/**
* Start syncing from peer.
* @returns {Promise}
*/
Peer.prototype.sync = co(function* sync() {
var locator, tip, watermark;
if (!this.pool.syncing)
return false;
if (!this.handshake)
return false;
if (this.syncSent)
return false;
if (!(this.services & services.NETWORK))
return false;
if (this.options.witness && !this.hasWitness())
return false;
if (!this.isLoader()) {
if (!this.chain.synced)
return false;
}
// Ask for the mempool if we're synced.
if (this.network.requestMempool) {
if (this.isLoader() && this.chain.synced)
this.sendMempool();
}
this.syncSent = true;
this.lastBlock = util.ms();
if (this.pool.headersFirst) {
tip = this.chain.tip;
watermark = this.pool.headerTip;
this.sendGetHeaders([tip.hash], watermark.hash);
return true;
}
locator = yield this.chain.getLocator();
this.sendGetBlocks(locator);
return true;
});
/**
* Test whether required services are available.
* @param {Number} services
@ -2311,6 +2262,24 @@ Peer.prototype.hasWitness = function hasWitness() {
return (this.services & services.WITNESS) !== 0;
};
/**
* Test whether the peer supports compact blocks.
* @returns {Boolean}
*/
Peer.prototype.hasCompact = function hasCompact() {
if (this.version < common.COMPACT_VERSION)
return false;
if (!this.options.witness)
return true;
if (!(this.services & services.WITNESS))
return false;
return this.version >= common.COMPACT_WITNESS_VERSION;
};
/**
* Inspect the peer.
* @returns {String}

View File

@ -505,7 +505,7 @@ Pool.prototype.setLoader = function setLoader(peer) {
assert(peer.outbound);
this.peers.load = peer;
peer.sync();
this.sendSync(peer);
this.emit('loader', peer);
};
@ -538,7 +538,7 @@ Pool.prototype.sync = function sync() {
for (peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
peer.sync();
this.sendSync(peer);
}
};
@ -556,11 +556,90 @@ Pool.prototype.forceSync = function forceSync() {
for (peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
peer.syncSent = false;
peer.sync();
peer.syncing = false;
this.sendSync(peer);
}
};
/**
* Stop the sync.
* @private
*/
Pool.prototype.stopSync = function stopSync() {
var peer;
if (!this.syncing)
return;
this.syncing = false;
for (peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
peer.syncing = false;
}
};
/**
* Start syncing from peer.
* @param {Peer} peer
* @returns {Promise}
*/
Pool.prototype.sendSync = co(function* sendSync(peer) {
var locator, tip, watermark;
if (!this.syncing)
return false;
if (!peer.handshake)
return false;
if (peer.syncing)
return false;
if (!(peer.services & services.NETWORK))
return false;
if (this.options.witness && !peer.hasWitness())
return false;
if (!peer.isLoader()) {
if (!this.chain.synced)
return false;
}
// Ask for the mempool if we're synced.
if (this.network.requestMempool) {
if (peer.isLoader() && this.chain.synced)
peer.sendMempool();
}
peer.syncing = true;
peer.lastBlock = util.ms();
if (this.pool.headersFirst) {
tip = this.chain.tip;
watermark = this.headerTip;
peer.sendGetHeaders([tip.hash], watermark.hash);
return true;
}
try {
locator = yield this.chain.getLocator();
} catch (e) {
this.emit('error', e);
return;
}
peer.sendGetBlocks(locator);
return true;
});
/**
* Send `mempool` to all peers.
*/
@ -880,7 +959,7 @@ Pool.prototype.handleOpen = function handleOpen(peer) {
// We want compact blocks!
if (this.options.compact) {
if (peer.version >= common.COMPACT_VERSION)
if (peer.hasCompact())
peer.sendCompact(this.options.blockMode);
}
@ -900,7 +979,8 @@ Pool.prototype.handleOpen = function handleOpen(peer) {
peer.sendFeeRate(this.options.feeRate);
// Start syncing the chain.
peer.sync();
if (peer.outbound)
this.sendSync(peer);
if (peer.outbound) {
this.hosts.markAck(peer.hostname, peer.services);