peer: use list for request queue.
This commit is contained in:
parent
463ebd9bd3
commit
7971e56765
@ -547,21 +547,21 @@ function parseType(type) {
|
||||
if (/form-urlencoded/i.test(type))
|
||||
return 'form';
|
||||
|
||||
if (/text\/plain/i.test(type))
|
||||
return 'text';
|
||||
|
||||
if (/\/x?html/i.test(type))
|
||||
return 'html';
|
||||
|
||||
if (/text\/plain/i.test(type))
|
||||
return 'text';
|
||||
|
||||
return 'binary';
|
||||
}
|
||||
|
||||
function getType(type) {
|
||||
switch (type) {
|
||||
case 'form':
|
||||
return 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
case 'json':
|
||||
return 'application/json; charset=utf-8';
|
||||
case 'form':
|
||||
return 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
case 'html':
|
||||
return 'text/html; charset=utf-8';
|
||||
case 'text':
|
||||
|
||||
@ -821,7 +821,7 @@ Peer.prototype.sendFeeRate = function sendFeeRate(rate) {
|
||||
*/
|
||||
|
||||
Peer.prototype.destroy = function destroy() {
|
||||
var i, j, keys, cmd, queue, hash;
|
||||
var i, j, keys, cmd, queue, entry, hash;
|
||||
|
||||
if (this.destroyed)
|
||||
return;
|
||||
@ -860,16 +860,17 @@ Peer.prototype.destroy = function destroy() {
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
cmd = keys[i];
|
||||
queue = this.requestMap[cmd];
|
||||
|
||||
for (j = 0; j < queue.length; j++)
|
||||
queue[j].destroy();
|
||||
for (entry = queue.head; entry; entry = entry.next)
|
||||
entry.stop();
|
||||
delete this.requestMap[cmd];
|
||||
}
|
||||
|
||||
keys = Object.keys(this.compactBlocks);
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
hash = keys[i];
|
||||
this.compactBlocks[hash].destroy();
|
||||
entry = this.compactBlocks[hash];
|
||||
entry.destroy();
|
||||
}
|
||||
|
||||
this.emit('close');
|
||||
@ -1024,7 +1025,7 @@ Peer.prototype.request = function request(cmd) {
|
||||
entry = new RequestEntry(self, cmd, resolve, reject);
|
||||
|
||||
if (!self.requestMap[cmd])
|
||||
self.requestMap[cmd] = [];
|
||||
self.requestMap[cmd] = new List();
|
||||
|
||||
self.requestMap[cmd].push(entry);
|
||||
});
|
||||
@ -1039,27 +1040,19 @@ Peer.prototype.request = function request(cmd) {
|
||||
|
||||
Peer.prototype.response = function response(cmd, payload) {
|
||||
var queue = this.requestMap[cmd];
|
||||
var entry, res;
|
||||
var entry;
|
||||
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
entry = queue[0];
|
||||
entry = queue.shift();
|
||||
assert(entry);
|
||||
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
res = entry.resolve(payload);
|
||||
|
||||
if (res === false)
|
||||
return false;
|
||||
|
||||
queue.shift();
|
||||
|
||||
if (queue.length === 0)
|
||||
if (queue.size === 0)
|
||||
delete this.requestMap[cmd];
|
||||
|
||||
entry.destroy();
|
||||
entry.stop();
|
||||
entry.resolve(payload);
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -1260,7 +1253,7 @@ Peer.prototype.fire = function fire(cmd, payload) {
|
||||
|
||||
Peer.prototype.handleFilterLoad = co(function* handleFilterLoad(packet) {
|
||||
if (!packet.isWithinConstraints()) {
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1278,7 +1271,7 @@ Peer.prototype.handleFilterAdd = co(function* handleFilterAdd(packet) {
|
||||
var data = packet.data;
|
||||
|
||||
if (data.length > constants.script.MAX_PUSH) {
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1329,7 +1322,7 @@ Peer.prototype.handleFeeFilter = co(function* handleFeeFilter(packet) {
|
||||
var rate = packet.rate;
|
||||
|
||||
if (!(rate >= 0 && rate <= constants.MAX_MONEY)) {
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2040,7 +2033,7 @@ Peer.prototype.handleInv = co(function* handleInv(packet) {
|
||||
var i, item;
|
||||
|
||||
if (items.length > 50000) {
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2093,7 +2086,7 @@ Peer.prototype.handleHeaders = co(function* handleHeaders(packet) {
|
||||
headers.length, this.hostname);
|
||||
|
||||
if (headers.length > 2000) {
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2406,7 +2399,7 @@ Peer.prototype.handleGetBlockTxn = co(function* handleGetBlockTxn(packet) {
|
||||
this.logger.debug(
|
||||
'Peer sent getblocktxn for non-existent block (%s).',
|
||||
this.hostname);
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2446,7 +2439,7 @@ Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(packet) {
|
||||
delete this.compactBlocks[res.hash];
|
||||
|
||||
if (!block.fillMissing(res)) {
|
||||
this.setMisbehavior(100);
|
||||
this.increaseBan(100);
|
||||
this.logger.warning('Peer sent non-full blocktxn (%s).', this.hostname);
|
||||
return;
|
||||
}
|
||||
@ -2598,22 +2591,13 @@ Peer.prototype.isMisbehaving = function isMisbehaving() {
|
||||
return this.pool.hosts.isMisbehaving(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the peer is ignored.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Peer.prototype.isIgnored = function isIgnored() {
|
||||
return this.pool.hosts.isIgnored(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Increase banscore on peer.
|
||||
* @param {Number} score
|
||||
*/
|
||||
|
||||
Peer.prototype.setMisbehavior = function setMisbehavior(score) {
|
||||
return this.pool.setMisbehavior(this, score);
|
||||
Peer.prototype.increaseBan = function increaseBan(score) {
|
||||
return this.pool.increaseBan(this, score);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2636,7 +2620,7 @@ Peer.prototype.ignore = function ignore() {
|
||||
Peer.prototype.reject = function reject(obj, code, reason, score) {
|
||||
this.sendReject(code, reason, obj);
|
||||
if (score > 0)
|
||||
this.setMisbehavior(score);
|
||||
this.increaseBan(score);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2759,27 +2743,26 @@ function RequestEntry(peer, cmd, resolve, reject) {
|
||||
this.cmd = cmd;
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
this.id = RequestEntry.uid++;
|
||||
this.onTimeout = this._onTimeout.bind(this);
|
||||
this.timeout = setTimeout(this.onTimeout, this.peer.requestTimeout);
|
||||
this.prev = null;
|
||||
this.next = null;
|
||||
}
|
||||
|
||||
RequestEntry.uid = 0;
|
||||
|
||||
RequestEntry.prototype._onTimeout = function _onTimeout() {
|
||||
var queue = this.peer.requestMap[this.cmd];
|
||||
|
||||
if (!queue)
|
||||
return;
|
||||
|
||||
if (util.binaryRemove(queue, this, compare)) {
|
||||
if (queue.length === 0)
|
||||
if (queue.remove(this)) {
|
||||
if (queue.size === 0)
|
||||
delete this.peer.requestMap[this.cmd];
|
||||
this.reject(new Error('Timed out: ' + this.cmd));
|
||||
}
|
||||
};
|
||||
|
||||
RequestEntry.prototype.destroy = function destroy() {
|
||||
RequestEntry.prototype.stop = function stop() {
|
||||
if (this.timeout != null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
|
||||
@ -807,7 +807,7 @@ Pool.prototype._handleHeaders = co(function* handleHeaders(headers, peer) {
|
||||
hash = header.hash('hex');
|
||||
|
||||
if (last && header.prevBlock !== last) {
|
||||
peer.setMisbehavior(100);
|
||||
peer.increaseBan(100);
|
||||
throw new Error('Bad header chain.');
|
||||
}
|
||||
|
||||
@ -983,7 +983,7 @@ Pool.prototype.handleBlock = co(function* handleBlock(block, peer) {
|
||||
|
||||
if (err.reason === 'bad-prevblk') {
|
||||
if (this.options.headers) {
|
||||
peer.setMisbehavior(10);
|
||||
peer.increaseBan(10);
|
||||
throw err;
|
||||
}
|
||||
this.logger.debug('Peer sent an orphan block. Resolving.');
|
||||
@ -1334,7 +1334,7 @@ Pool.prototype.handleAlert = function handleAlert(alert, peer) {
|
||||
this.logger.warning('Peer sent a phony alert packet (%s).', peer.hostname);
|
||||
// Let's look at it because why not?
|
||||
this.logger.debug(alert);
|
||||
peer.setMisbehavior(100);
|
||||
peer.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1356,7 +1356,7 @@ Pool.prototype.handleAlert = function handleAlert(alert, peer) {
|
||||
&& alert.statusBar === 'URGENT: Alert key compromised, upgrade required')) {
|
||||
this.logger.warning('Misuse of last alert ID (%s).', peer.hostname);
|
||||
this.logger.debug(alert);
|
||||
peer.setMisbehavior(100);
|
||||
peer.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1367,7 +1367,7 @@ Pool.prototype.handleAlert = function handleAlert(alert, peer) {
|
||||
this.logger.warning('The Japanese government sent an alert packet.');
|
||||
this.logger.warning('Here is their IP: %s.', peer.hostname);
|
||||
this.logger.info(alert);
|
||||
peer.setMisbehavior(100);
|
||||
peer.increaseBan(100);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1466,7 +1466,7 @@ Pool.prototype.addInbound = function addInbound(socket) {
|
||||
|
||||
peer = this.acceptPeer(socket);
|
||||
|
||||
this.logger.info('Added leech peer (%s).', peer.hostname);
|
||||
this.logger.info('Added inbound peer (%s).', peer.hostname);
|
||||
|
||||
this.peers.add(peer);
|
||||
|
||||
@ -1889,7 +1889,7 @@ Pool.prototype.setFeeRate = function setFeeRate(rate) {
|
||||
* @returns {Boolean} Whether the peer was banned.
|
||||
*/
|
||||
|
||||
Pool.prototype.setMisbehavior = function setMisbehavior(peer, score) {
|
||||
Pool.prototype.increaseBan = function increaseBan(peer, score) {
|
||||
peer.banScore += score;
|
||||
|
||||
if (peer.banScore >= constants.BAN_SCORE) {
|
||||
@ -1986,7 +1986,7 @@ Pool.prototype.getIP = co(function* getIP() {
|
||||
*/
|
||||
|
||||
Pool.prototype.getIP2 = co(function* getIP2() {
|
||||
var res, ip;
|
||||
var res, match, ip;
|
||||
|
||||
if (request.unsupported)
|
||||
throw new Error('Could not find IP.');
|
||||
@ -1998,12 +1998,17 @@ Pool.prototype.getIP2 = co(function* getIP2() {
|
||||
timeout: 3000
|
||||
});
|
||||
|
||||
ip = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body);
|
||||
match = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body);
|
||||
|
||||
if (!ip || IP.version(ip[1]) === -1)
|
||||
if (!match)
|
||||
throw new Error('Could not find IP.');
|
||||
|
||||
return IP.normalize(ip[1]);
|
||||
ip = match[1];
|
||||
|
||||
if (IP.version(ip) === -1)
|
||||
throw new Error('Could not parse IP.');
|
||||
|
||||
return IP.normalize(ip);
|
||||
});
|
||||
|
||||
/**
|
||||
@ -2233,15 +2238,15 @@ HostList.prototype.unban = function unban(addr) {
|
||||
HostList.prototype.isMisbehaving = function isMisbehaving(addr) {
|
||||
var time = this.misbehaving[addr.host];
|
||||
|
||||
if (time != null) {
|
||||
if (util.now() > time + constants.BAN_TIME) {
|
||||
delete this.misbehaving[addr.host];
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (time == null)
|
||||
return false;
|
||||
|
||||
if (util.now() > time + constants.BAN_TIME) {
|
||||
delete this.misbehaving[addr.host];
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2285,8 +2290,8 @@ HostList.prototype.addSeed = function addSeed(hostname) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate from seed.
|
||||
* @param {String} seed
|
||||
* Discover hosts from seeds.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
HostList.prototype.discover = co(function* discover() {
|
||||
@ -2304,7 +2309,8 @@ HostList.prototype.discover = co(function* discover() {
|
||||
|
||||
/**
|
||||
* Populate from seed.
|
||||
* @param {String} seed
|
||||
* @param {Object} seed
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
HostList.prototype.populate = co(function* populate(seed) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user