peer: use list for request queue.

This commit is contained in:
Christopher Jeffrey 2016-12-16 14:02:06 -08:00
parent 463ebd9bd3
commit 7971e56765
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 60 additions and 71 deletions

View File

@ -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':

View File

@ -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;

View File

@ -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) {