better ping system.

This commit is contained in:
Christopher Jeffrey 2016-05-19 22:22:09 -07:00
parent bd3d17ef53
commit e97f1d0477
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 88 additions and 29 deletions

View File

@ -55,6 +55,9 @@ var constants = bcoin.protocol.constants;
* @property {BN} challenge - Local nonce.
* @property {Number} lastPong - Timestamp for last `pong`
* received (unix time).
* @property {Number} lastPing - Timestamp for last `ping`
* sent (unix time).
* @property {Number} minPing - Lowest ping time seen.
* @property {String} id - Peer's uid.
* @property {Number} banScore
* @emits Peer#ack
@ -98,8 +101,10 @@ function Peer(pool, options) {
this.localNonce = utils.nonce();
this.filterRate = -1;
this.challenge = utils.nonce();
this.lastPong = 0;
this.challenge = null;
this.lastPong = -1;
this.lastPing = -1;
this.minPing = -1;
this.banScore = 0;
@ -132,7 +137,7 @@ function Peer(pool, options) {
this.ping = {
timer: null,
interval: this.options.pingInterval || 30000
interval: this.options.pingInterval || 120000
};
this.queue = {
@ -186,13 +191,6 @@ Peer.prototype._init = function init() {
self._error(err);
});
this.ping.timer = setInterval(function() {
// self.challenge = utils.nonce();
self.write(self.framer.ping({
nonce: self.challenge
}));
}, this.ping.interval);
this.request('verack', function(err, payload) {
if (err) {
self._error(err);
@ -204,6 +202,10 @@ Peer.prototype._init = function init() {
self.emit('ack');
self.ts = utils.now();
self.ping.timer = setInterval(function() {
self.sendPing();
}, self.ping.interval);
if (self.options.headers) {
if (self.version && self.version.version > 70012)
self.write(self.framer.sendHeaders());
@ -259,12 +261,12 @@ Peer.prototype.createSocket = function createSocket(port, host) {
}
bcoin.debug(
'Connecting to %s:%d (priority=%s).',
'Connecting to %s (priority=%s).',
hostname, this.priority);
socket.once('connect', function() {
bcoin.debug(
'Connected to %s:%d (priority=%s).',
'Connected to %s (priority=%s).',
hostname, self.priority);
});
@ -314,6 +316,32 @@ Peer.prototype.sendInv = function sendInv(items) {
this.write(this.framer.inv(items));
};
/**
* Send a `ping` packet.
*/
Peer.prototype.sendPing = function sendPing() {
if (!this.version)
return;
if (this.version.version <= 60000) {
this.write(this.framer.packet('ping', new Buffer([])));
return;
}
if (this.challenge) {
bcoin.debug('Peer has not responded to ping (%s).', this.hostname);
return;
}
this.lastPing = utils.ms();
this.challenge = utils.nonce();
this.write(this.framer.ping({
nonce: this.challenge
}));
};
/**
* Test whether an is being watched by the peer.
* @param {BroadcastItem|TX} item
@ -367,8 +395,10 @@ Peer.prototype.destroy = function destroy() {
this.socket = null;
this.emit('close');
clearInterval(this.ping.timer);
this.ping.timer = null;
if (this.ping.timer) {
clearInterval(this.ping.timer);
this.ping.timer = null;
}
Object.keys(this.requests.map).forEach(function(cmd) {
var queue = this.requests.map[cmd];
@ -1220,19 +1250,40 @@ Peer.prototype._handleAddr = function handleAddr(addrs) {
};
Peer.prototype._handlePing = function handlePing(data) {
this.write(this.framer.pong({
nonce: data.nonce
}));
this.emit('ping', data);
this.write(this.framer.pong(data));
this.emit('ping', this.minPing);
};
Peer.prototype._handlePong = function handlePong(data) {
if (!this.challenge || this.challenge.cmp(data.nonce) !== 0)
return this.emit('pong', false);
var now = utils.ms();
this.lastPong = utils.now();
if (!this.challenge) {
bcoin.debug('Peer sent an unsolicited pong (%s).', this.hostname);
return;
}
return this.emit('pong', true);
if (data.nonce.cmp(this.challenge) !== 0) {
if (data.nonce.cmpn(0) === 0) {
bcoin.debug('Peer sent a zero nonce (%s).', this.hostname);
this.challenge = null;
return;
}
bcoin.debug('Peer sent the wrong nonce (%s).', this.hostname);
return;
}
if (now >= this.lastPing) {
this.lastPong = now;
if (this.minPing === -1)
this.minPing = now - this.lastPing;
this.minPing = Math.min(this.minPing, now - this.lastPing);
} else {
bcoin.debug('Timing mismatch (what?) (%s).', this.hostname);
}
this.challenge = null;
this.emit('pong', this.minPing);
};
Peer.prototype._handleGetAddr = function handleGetAddr() {
@ -1445,6 +1496,7 @@ Peer.prototype.inspect = function inspect() {
+ ' id=' + this.id
+ ' connected=' + this.connected
+ ' host=' + this.hostname
+ ' ping=' + this.minPing
+ '>';
};

View File

@ -868,17 +868,15 @@ utils.parseHost = function parseHost(addr) {
/**
* Concatenate a host and port.
* @param {Seed} seed
* @param {String} host
* @param {Number} port
* @returns {String}
*/
utils.hostname = function hostname(seed) {
var host = seed.host;
utils.hostname = function hostname(host, port) {
if (utils.isIP(host) === 6)
host = '[' + host + ']';
return host + ':' + seed.port;
return host + ':' + port;
};
/**
@ -1283,7 +1281,16 @@ utils.testTarget = function testTarget(hash, target) {
*/
utils.now = function now() {
return +new Date() / 1000 | 0;
return Math.floor(+new Date() / 1000);
};
/**
* Get current time in unix time (milliseconds).
* @returns {Number}
*/
utils.ms = function ms() {
return +new Date();
};
/**