better ping system.
This commit is contained in:
parent
bd3d17ef53
commit
e97f1d0477
@ -55,6 +55,9 @@ var constants = bcoin.protocol.constants;
|
|||||||
* @property {BN} challenge - Local nonce.
|
* @property {BN} challenge - Local nonce.
|
||||||
* @property {Number} lastPong - Timestamp for last `pong`
|
* @property {Number} lastPong - Timestamp for last `pong`
|
||||||
* received (unix time).
|
* 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 {String} id - Peer's uid.
|
||||||
* @property {Number} banScore
|
* @property {Number} banScore
|
||||||
* @emits Peer#ack
|
* @emits Peer#ack
|
||||||
@ -98,8 +101,10 @@ function Peer(pool, options) {
|
|||||||
this.localNonce = utils.nonce();
|
this.localNonce = utils.nonce();
|
||||||
this.filterRate = -1;
|
this.filterRate = -1;
|
||||||
|
|
||||||
this.challenge = utils.nonce();
|
this.challenge = null;
|
||||||
this.lastPong = 0;
|
this.lastPong = -1;
|
||||||
|
this.lastPing = -1;
|
||||||
|
this.minPing = -1;
|
||||||
|
|
||||||
this.banScore = 0;
|
this.banScore = 0;
|
||||||
|
|
||||||
@ -132,7 +137,7 @@ function Peer(pool, options) {
|
|||||||
|
|
||||||
this.ping = {
|
this.ping = {
|
||||||
timer: null,
|
timer: null,
|
||||||
interval: this.options.pingInterval || 30000
|
interval: this.options.pingInterval || 120000
|
||||||
};
|
};
|
||||||
|
|
||||||
this.queue = {
|
this.queue = {
|
||||||
@ -186,13 +191,6 @@ Peer.prototype._init = function init() {
|
|||||||
self._error(err);
|
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) {
|
this.request('verack', function(err, payload) {
|
||||||
if (err) {
|
if (err) {
|
||||||
self._error(err);
|
self._error(err);
|
||||||
@ -204,6 +202,10 @@ Peer.prototype._init = function init() {
|
|||||||
self.emit('ack');
|
self.emit('ack');
|
||||||
self.ts = utils.now();
|
self.ts = utils.now();
|
||||||
|
|
||||||
|
self.ping.timer = setInterval(function() {
|
||||||
|
self.sendPing();
|
||||||
|
}, self.ping.interval);
|
||||||
|
|
||||||
if (self.options.headers) {
|
if (self.options.headers) {
|
||||||
if (self.version && self.version.version > 70012)
|
if (self.version && self.version.version > 70012)
|
||||||
self.write(self.framer.sendHeaders());
|
self.write(self.framer.sendHeaders());
|
||||||
@ -259,12 +261,12 @@ Peer.prototype.createSocket = function createSocket(port, host) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bcoin.debug(
|
bcoin.debug(
|
||||||
'Connecting to %s:%d (priority=%s).',
|
'Connecting to %s (priority=%s).',
|
||||||
hostname, this.priority);
|
hostname, this.priority);
|
||||||
|
|
||||||
socket.once('connect', function() {
|
socket.once('connect', function() {
|
||||||
bcoin.debug(
|
bcoin.debug(
|
||||||
'Connected to %s:%d (priority=%s).',
|
'Connected to %s (priority=%s).',
|
||||||
hostname, self.priority);
|
hostname, self.priority);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -314,6 +316,32 @@ Peer.prototype.sendInv = function sendInv(items) {
|
|||||||
this.write(this.framer.inv(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.
|
* Test whether an is being watched by the peer.
|
||||||
* @param {BroadcastItem|TX} item
|
* @param {BroadcastItem|TX} item
|
||||||
@ -367,8 +395,10 @@ Peer.prototype.destroy = function destroy() {
|
|||||||
this.socket = null;
|
this.socket = null;
|
||||||
this.emit('close');
|
this.emit('close');
|
||||||
|
|
||||||
clearInterval(this.ping.timer);
|
if (this.ping.timer) {
|
||||||
this.ping.timer = null;
|
clearInterval(this.ping.timer);
|
||||||
|
this.ping.timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(this.requests.map).forEach(function(cmd) {
|
Object.keys(this.requests.map).forEach(function(cmd) {
|
||||||
var queue = this.requests.map[cmd];
|
var queue = this.requests.map[cmd];
|
||||||
@ -1220,19 +1250,40 @@ Peer.prototype._handleAddr = function handleAddr(addrs) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype._handlePing = function handlePing(data) {
|
Peer.prototype._handlePing = function handlePing(data) {
|
||||||
this.write(this.framer.pong({
|
this.write(this.framer.pong(data));
|
||||||
nonce: data.nonce
|
this.emit('ping', this.minPing);
|
||||||
}));
|
|
||||||
this.emit('ping', data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Peer.prototype._handlePong = function handlePong(data) {
|
Peer.prototype._handlePong = function handlePong(data) {
|
||||||
if (!this.challenge || this.challenge.cmp(data.nonce) !== 0)
|
var now = utils.ms();
|
||||||
return this.emit('pong', false);
|
|
||||||
|
|
||||||
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() {
|
Peer.prototype._handleGetAddr = function handleGetAddr() {
|
||||||
@ -1445,6 +1496,7 @@ Peer.prototype.inspect = function inspect() {
|
|||||||
+ ' id=' + this.id
|
+ ' id=' + this.id
|
||||||
+ ' connected=' + this.connected
|
+ ' connected=' + this.connected
|
||||||
+ ' host=' + this.hostname
|
+ ' host=' + this.hostname
|
||||||
|
+ ' ping=' + this.minPing
|
||||||
+ '>';
|
+ '>';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -868,17 +868,15 @@ utils.parseHost = function parseHost(addr) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Concatenate a host and port.
|
* Concatenate a host and port.
|
||||||
* @param {Seed} seed
|
* @param {String} host
|
||||||
|
* @param {Number} port
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.hostname = function hostname(seed) {
|
utils.hostname = function hostname(host, port) {
|
||||||
var host = seed.host;
|
|
||||||
|
|
||||||
if (utils.isIP(host) === 6)
|
if (utils.isIP(host) === 6)
|
||||||
host = '[' + host + ']';
|
host = '[' + host + ']';
|
||||||
|
return host + ':' + port;
|
||||||
return host + ':' + seed.port;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1283,7 +1281,16 @@ utils.testTarget = function testTarget(hash, target) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
utils.now = function now() {
|
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();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user