net: use Map object for requested items.
This commit is contained in:
parent
bea77b0ec7
commit
fb0b2b53d7
@ -14,6 +14,7 @@ var NetAddress = require('../primitives/netaddress');
|
|||||||
var List = require('../utils/list');
|
var List = require('../utils/list');
|
||||||
var murmur3 = require('../utils/murmur3');
|
var murmur3 = require('../utils/murmur3');
|
||||||
var StaticWriter = require('../utils/staticwriter');
|
var StaticWriter = require('../utils/staticwriter');
|
||||||
|
var Map = require('../utils/map');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Host List
|
* Host List
|
||||||
@ -71,7 +72,7 @@ HostList.prototype._init = function init() {
|
|||||||
var i;
|
var i;
|
||||||
|
|
||||||
for (i = 0; i < this.maxBuckets; i++)
|
for (i = 0; i < this.maxBuckets; i++)
|
||||||
this.fresh.push(new MapBucket());
|
this.fresh.push(new Map());
|
||||||
|
|
||||||
for (i = 0; i < this.maxBuckets; i++)
|
for (i = 0; i < this.maxBuckets; i++)
|
||||||
this.used.push(new List());
|
this.used.push(new List());
|
||||||
@ -219,7 +220,7 @@ HostList.prototype.getHost = function getHost() {
|
|||||||
* Get fresh bucket for host.
|
* Get fresh bucket for host.
|
||||||
* @private
|
* @private
|
||||||
* @param {HostEntry} entry
|
* @param {HostEntry} entry
|
||||||
* @returns {MapBucket}
|
* @returns {Map}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HostList.prototype.freshBucket = function freshBucket(entry) {
|
HostList.prototype.freshBucket = function freshBucket(entry) {
|
||||||
@ -343,7 +344,7 @@ HostList.prototype.add = function add(addr, src) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Evict a host from fresh bucket.
|
* Evict a host from fresh bucket.
|
||||||
* @param {MapBucket} bucket
|
* @param {Map} bucket
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HostList.prototype.evictFresh = function evictFresh(bucket) {
|
HostList.prototype.evictFresh = function evictFresh(bucket) {
|
||||||
@ -806,97 +807,6 @@ HostList.fromJSON = function fromJSON(options, json) {
|
|||||||
return new HostEntry(options).fromJSON(json);
|
return new HostEntry(options).fromJSON(json);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* MapBucket
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
|
|
||||||
function MapBucket() {
|
|
||||||
if (!(this instanceof MapBucket))
|
|
||||||
return new MapBucket();
|
|
||||||
|
|
||||||
this.map = {};
|
|
||||||
this.size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get map keys.
|
|
||||||
* @returns {String[]}
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBucket.prototype.keys = function keys() {
|
|
||||||
return Object.keys(this.map);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get item from map.
|
|
||||||
* @param {String} key
|
|
||||||
* @returns {Object|null}
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBucket.prototype.get = function get(key) {
|
|
||||||
return this.map[key];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether map has an item.
|
|
||||||
* @param {String} key
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBucket.prototype.has = function has(key) {
|
|
||||||
return this.map[key] !== undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a key to value in map.
|
|
||||||
* @param {String} key
|
|
||||||
* @param {Object} value
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBucket.prototype.set = function set(key, value) {
|
|
||||||
var item = this.map[key];
|
|
||||||
|
|
||||||
assert(value !== undefined);
|
|
||||||
|
|
||||||
this.map[key] = value;
|
|
||||||
|
|
||||||
if (item === undefined) {
|
|
||||||
this.size++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an item from map.
|
|
||||||
* @param {String} key
|
|
||||||
* @returns {Object|null}
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBucket.prototype.remove = function remove(key) {
|
|
||||||
var item = this.map[key];
|
|
||||||
|
|
||||||
if (item === undefined)
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete this.map[key];
|
|
||||||
this.size--;
|
|
||||||
|
|
||||||
return item;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the map.
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapBucket.prototype.reset = function reset() {
|
|
||||||
this.map = {};
|
|
||||||
this.size = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HostEntry
|
* HostEntry
|
||||||
* @constructor
|
* @constructor
|
||||||
|
|||||||
@ -11,6 +11,7 @@ var assert = require('assert');
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var util = require('../utils/util');
|
var util = require('../utils/util');
|
||||||
var co = require('../utils/co');
|
var co = require('../utils/co');
|
||||||
|
var Map = require('../utils/map');
|
||||||
var Parser = require('./parser');
|
var Parser = require('./parser');
|
||||||
var Framer = require('./framer');
|
var Framer = require('./framer');
|
||||||
var packets = require('./packets');
|
var packets = require('./packets');
|
||||||
@ -113,8 +114,6 @@ function Peer(pool) {
|
|||||||
this.bip150 = null;
|
this.bip150 = null;
|
||||||
this.compactMode = -1;
|
this.compactMode = -1;
|
||||||
this.compactWitness = false;
|
this.compactWitness = false;
|
||||||
this.compactBlocks = {};
|
|
||||||
this.compactAmount = 0;
|
|
||||||
this.lastMerkle = null;
|
this.lastMerkle = null;
|
||||||
this.waitingTX = 0;
|
this.waitingTX = 0;
|
||||||
this.syncSent = false;
|
this.syncSent = false;
|
||||||
@ -134,10 +133,10 @@ function Peer(pool) {
|
|||||||
this.addrFilter = new Bloom.Rolling(5000, 0.001);
|
this.addrFilter = new Bloom.Rolling(5000, 0.001);
|
||||||
this.invFilter = new Bloom.Rolling(50000, 0.000001);
|
this.invFilter = new Bloom.Rolling(50000, 0.000001);
|
||||||
|
|
||||||
this.requestMap = {};
|
this.requestMap = new Map();
|
||||||
this.queueMap = {};
|
this.blockQueue = [];
|
||||||
|
this.compactBlocks = new Map();
|
||||||
this.responseMap = {};
|
this.responseMap = new Map();
|
||||||
|
|
||||||
if (this.options.bip151) {
|
if (this.options.bip151) {
|
||||||
this.bip151 = new BIP151();
|
this.bip151 = new BIP151();
|
||||||
@ -696,12 +695,12 @@ Peer.prototype.announceTX = function announceTX(txs) {
|
|||||||
Peer.prototype.announceList = function announceList() {
|
Peer.prototype.announceList = function announceList() {
|
||||||
var blocks = [];
|
var blocks = [];
|
||||||
var txs = [];
|
var txs = [];
|
||||||
var hashes = Object.keys(this.pool.invMap);
|
var hashes = this.pool.invMap.keys();
|
||||||
var i, hash, item;
|
var i, hash, item;
|
||||||
|
|
||||||
for (i = 0; i < hashes.length; i++) {
|
for (i = 0; i < hashes.length; i++) {
|
||||||
hash = hashes[i];
|
hash = hashes[i];
|
||||||
item = this.pool.invMap[hash];
|
item = this.pool.invMap.get(hash);
|
||||||
|
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case invTypes.BLOCK:
|
case invTypes.BLOCK:
|
||||||
@ -944,17 +943,16 @@ Peer.prototype.destroy = function destroy() {
|
|||||||
this.connectTimeout = null;
|
this.connectTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = Object.keys(this.responseMap);
|
keys = this.responseMap.keys();
|
||||||
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
for (i = 0; i < keys.length; i++) {
|
||||||
cmd = keys[i];
|
cmd = keys[i];
|
||||||
entry = this.responseMap[cmd];
|
entry = this.responseMap.get(cmd);
|
||||||
delete this.responseMap[cmd];
|
this.responseMap.remove(cmd);
|
||||||
entry.reject(new Error('Peer was destroyed.'));
|
entry.reject(new Error('Peer was destroyed.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.compactBlocks = {};
|
this.compactBlocks.reset();
|
||||||
this.compactAmount = 0;
|
|
||||||
|
|
||||||
this.locker.destroy();
|
this.locker.destroy();
|
||||||
|
|
||||||
@ -1033,9 +1031,12 @@ Peer.prototype.addTimeout = function addTimeout(packet) {
|
|||||||
|
|
||||||
switch (packet.type) {
|
switch (packet.type) {
|
||||||
case packetTypes.MEMPOOL:
|
case packetTypes.MEMPOOL:
|
||||||
case packetTypes.GETBLOCKS:
|
|
||||||
this.request(packetTypes.INV, timeout);
|
this.request(packetTypes.INV, timeout);
|
||||||
break;
|
break;
|
||||||
|
case packetTypes.GETBLOCKS:
|
||||||
|
if (!this.chain.synced)
|
||||||
|
this.request(packetTypes.INV, timeout);
|
||||||
|
break;
|
||||||
case packetTypes.GETHEADERS:
|
case packetTypes.GETHEADERS:
|
||||||
this.request(packetTypes.HEADERS, timeout * 2);
|
this.request(packetTypes.HEADERS, timeout * 2);
|
||||||
break;
|
break;
|
||||||
@ -1077,13 +1078,13 @@ Peer.prototype.fulfill = function fulfill(packet) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Peer.prototype.maybeTimeout = function maybeTimeout() {
|
Peer.prototype.maybeTimeout = function maybeTimeout() {
|
||||||
var keys = Object.keys(this.responseMap);
|
var keys = this.responseMap.keys();
|
||||||
var now = util.ms();
|
var now = util.ms();
|
||||||
var i, key, entry, name;
|
var i, key, entry, name;
|
||||||
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
for (i = 0; i < keys.length; i++) {
|
||||||
key = keys[i];
|
key = keys[i];
|
||||||
entry = this.responseMap[key];
|
entry = this.responseMap.get(key);
|
||||||
if (now > entry.timeout) {
|
if (now > entry.timeout) {
|
||||||
name = packets.typesByVal[key];
|
name = packets.typesByVal[key];
|
||||||
this.error('Peer is stalling (%s).', name.toLowerCase());
|
this.error('Peer is stalling (%s).', name.toLowerCase());
|
||||||
@ -1113,14 +1114,14 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Peer.prototype.request = function request(type, timeout) {
|
Peer.prototype.request = function request(type, timeout) {
|
||||||
var entry = this.responseMap[type];
|
var entry = this.responseMap.get(type);
|
||||||
|
|
||||||
if (this.destroyed)
|
if (this.destroyed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
entry = new RequestEntry();
|
entry = new RequestEntry();
|
||||||
this.responseMap[type] = entry;
|
this.responseMap.set(type, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.setTimeout(timeout);
|
entry.setTimeout(timeout);
|
||||||
@ -1136,12 +1137,12 @@ Peer.prototype.request = function request(type, timeout) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Peer.prototype.response = function response(type, payload) {
|
Peer.prototype.response = function response(type, payload) {
|
||||||
var entry = this.responseMap[type];
|
var entry = this.responseMap.get(type);
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delete this.responseMap[type];
|
this.responseMap.remove(type);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
};
|
};
|
||||||
@ -1880,7 +1881,7 @@ Peer.prototype.handleMempool = co(function* handleMempool(packet) {
|
|||||||
|
|
||||||
Peer.prototype.getBroadcasted = function getBroadcasted(item) {
|
Peer.prototype.getBroadcasted = function getBroadcasted(item) {
|
||||||
var type = item.isTX() ? invTypes.TX : invTypes.BLOCK;
|
var type = item.isTX() ? invTypes.TX : invTypes.BLOCK;
|
||||||
var entry = this.pool.invMap[item.hash];
|
var entry = this.pool.invMap.get(item.hash);
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return;
|
return;
|
||||||
@ -2420,7 +2421,7 @@ Peer.prototype.handleReject = co(function* handleReject(reject) {
|
|||||||
if (!reject.hash)
|
if (!reject.hash)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
entry = this.pool.invMap[reject.hash];
|
entry = this.pool.invMap.get(reject.hash);
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return;
|
return;
|
||||||
@ -2598,7 +2599,7 @@ Peer.prototype.handleCmpctBlock = co(function* handleCmpctBlock(packet) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.compactBlocks[hash]) {
|
if (this.compactBlocks.has(hash)) {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'Peer sent us a duplicate compact block (%s).',
|
'Peer sent us a duplicate compact block (%s).',
|
||||||
this.hostname);
|
this.hostname);
|
||||||
@ -2624,14 +2625,13 @@ Peer.prototype.handleCmpctBlock = co(function* handleCmpctBlock(packet) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.compactAmount >= 10) {
|
if (this.compactBlocks.size >= 10) {
|
||||||
this.logger.warning('Compact block DoS attempt (%s).', this.hostname);
|
this.logger.warning('Compact block DoS attempt (%s).', this.hostname);
|
||||||
this.destroy();
|
this.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.compactBlocks[hash] = block;
|
this.compactBlocks.set(hash, block);
|
||||||
this.compactAmount++;
|
|
||||||
|
|
||||||
this.send(new packets.GetBlockTxnPacket(block.toRequest()));
|
this.send(new packets.GetBlockTxnPacket(block.toRequest()));
|
||||||
|
|
||||||
@ -2695,17 +2695,15 @@ Peer.prototype.handleGetBlockTxn = co(function* handleGetBlockTxn(packet) {
|
|||||||
|
|
||||||
Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(packet) {
|
Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(packet) {
|
||||||
var res = packet.response;
|
var res = packet.response;
|
||||||
var block = this.compactBlocks[res.hash];
|
var block = this.compactBlocks.get(res.hash);
|
||||||
|
|
||||||
if (!block) {
|
if (!block) {
|
||||||
this.logger.debug('Peer sent unsolicited blocktxn (%s).', this.hostname);
|
this.logger.debug('Peer sent unsolicited blocktxn (%s).', this.hostname);
|
||||||
this.compactBlocks = {};
|
this.compactBlocks.reset();
|
||||||
this.compactAmount = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.compactBlocks[res.hash];
|
this.compactBlocks.remove(res.hash);
|
||||||
this.compactAmount--;
|
|
||||||
|
|
||||||
if (!block.fillMissing(res)) {
|
if (!block.fillMissing(res)) {
|
||||||
this.increaseBan(100);
|
this.increaseBan(100);
|
||||||
|
|||||||
100
lib/net/pool.js
100
lib/net/pool.js
@ -29,6 +29,7 @@ var tcp = require('./tcp');
|
|||||||
var dns = require('./dns');
|
var dns = require('./dns');
|
||||||
var HostList = require('./hostlist');
|
var HostList = require('./hostlist');
|
||||||
var InvItem = require('../primitives/invitem');
|
var InvItem = require('../primitives/invitem');
|
||||||
|
var Map = require('../utils/map');
|
||||||
var invTypes = InvItem.types;
|
var invTypes = InvItem.types;
|
||||||
var VerifyError = errors.VerifyError;
|
var VerifyError = errors.VerifyError;
|
||||||
var VerifyResult = errors.VerifyResult;
|
var VerifyResult = errors.VerifyResult;
|
||||||
@ -137,11 +138,11 @@ function Pool(options) {
|
|||||||
this.txFilter = null;
|
this.txFilter = null;
|
||||||
|
|
||||||
// Requested objects.
|
// Requested objects.
|
||||||
this.requestMap = {};
|
this.requestMap = new Map();
|
||||||
this.activeRequests = 0;
|
this.queueMap = new Map();
|
||||||
|
|
||||||
// Currently broadcasted objects.
|
// Currently broadcasted objects.
|
||||||
this.invMap = {};
|
this.invMap = new Map();
|
||||||
this.invTimeout = 60000;
|
this.invTimeout = 60000;
|
||||||
|
|
||||||
this.scheduled = false;
|
this.scheduled = false;
|
||||||
@ -382,18 +383,17 @@ Pool.prototype._close = co(function* close() {
|
|||||||
|
|
||||||
this.stopSync();
|
this.stopSync();
|
||||||
|
|
||||||
hashes = Object.keys(this.invMap);
|
hashes = this.invMap.keys();
|
||||||
|
|
||||||
for (i = 0; i < hashes.length; i++) {
|
for (i = 0; i < hashes.length; i++) {
|
||||||
hash = hashes[i];
|
hash = hashes[i];
|
||||||
item = this.invMap[hash];
|
item = this.invMap.get(hash);
|
||||||
item.resolve();
|
item.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.peers.destroy();
|
this.peers.destroy();
|
||||||
|
|
||||||
this.requestMap = {};
|
this.requestMap.reset();
|
||||||
this.activeRequests = 0;
|
|
||||||
|
|
||||||
this.hosts.reset();
|
this.hosts.reset();
|
||||||
|
|
||||||
@ -1012,8 +1012,8 @@ Pool.prototype.handleBlock = co(function* handleBlock(peer, block) {
|
|||||||
(this.chain.getProgress() * 100).toFixed(2) + '%',
|
(this.chain.getProgress() * 100).toFixed(2) + '%',
|
||||||
this.chain.total,
|
this.chain.total,
|
||||||
this.chain.orphanCount,
|
this.chain.orphanCount,
|
||||||
this.activeRequests,
|
this.requestMap.size,
|
||||||
0,
|
this.queueMap.size,
|
||||||
block.bits,
|
block.bits,
|
||||||
this.peers.size(),
|
this.peers.size(),
|
||||||
this.chain.locker.pending,
|
this.chain.locker.pending,
|
||||||
@ -1520,12 +1520,22 @@ Pool.prototype.removePeer = function removePeer(peer) {
|
|||||||
|
|
||||||
this.peers.remove(peer);
|
this.peers.remove(peer);
|
||||||
|
|
||||||
hashes = Object.keys(peer.requestMap);
|
hashes = peer.requestMap.keys();
|
||||||
|
|
||||||
for (i = 0; i < hashes.length; i++) {
|
for (i = 0; i < hashes.length; i++) {
|
||||||
hash = hashes[i];
|
hash = hashes[i];
|
||||||
this.fulfill(peer, hash);
|
this.fulfill(peer, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hashes = peer.blockQueue;
|
||||||
|
|
||||||
|
for (i = 0; i < hashes.length; i++) {
|
||||||
|
hash = hashes[i];
|
||||||
|
assert(this.queueMap.has(hash));
|
||||||
|
this.queueMap.remove(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
peer.blockQueue.length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1650,10 +1660,14 @@ Pool.prototype.getBlock = function getBlock(peer, hash) {
|
|||||||
if (peer.destroyed)
|
if (peer.destroyed)
|
||||||
throw new Error('Peer is destroyed (getdata).');
|
throw new Error('Peer is destroyed (getdata).');
|
||||||
|
|
||||||
if (this.requestMap[hash])
|
if (this.requestMap.has(hash))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
peer.queueMap[hash] = true;
|
if (this.queueMap.has(hash))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.queueMap.insert(hash);
|
||||||
|
peer.blockQueue.push(hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1668,7 +1682,11 @@ Pool.prototype.hasBlock = co(function* hasBlock(hash) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Check the pending requests.
|
// Check the pending requests.
|
||||||
if (this.requestMap[hash])
|
if (this.requestMap.has(hash))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Check the queued requests.
|
||||||
|
if (this.queueMap.has(hash))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1701,12 +1719,10 @@ Pool.prototype.getTX = function getTX(peer, hashes) {
|
|||||||
if (this.hasTX(hash))
|
if (this.hasTX(hash))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
assert(!this.requestMap[hash]);
|
assert(!this.requestMap.has(hash));
|
||||||
|
|
||||||
this.requestMap[hash] = true;
|
this.requestMap.insert(hash);
|
||||||
peer.requestMap[hash] = true;
|
peer.requestMap.insert(hash);
|
||||||
|
|
||||||
this.activeRequests++;
|
|
||||||
|
|
||||||
items.push(hash);
|
items.push(hash);
|
||||||
}
|
}
|
||||||
@ -1739,7 +1755,7 @@ Pool.prototype.hasTX = function hasTX(hash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the pending requests.
|
// Check the pending requests.
|
||||||
if (this.requestMap[hash])
|
if (this.requestMap.has(hash))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1771,39 +1787,39 @@ Pool.prototype.scheduleRequests = co(function* scheduleRequests(peer) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Pool.prototype.sendBlockRequests = function sendBlockRequests(peer) {
|
Pool.prototype.sendBlockRequests = function sendBlockRequests(peer) {
|
||||||
var queue = Object.keys(peer.queueMap);
|
var queue = peer.blockQueue;
|
||||||
var hashes = [];
|
var hashes = [];
|
||||||
var i, size, hash;
|
var i, size, hash;
|
||||||
|
|
||||||
|
if (peer.destroyed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (queue.length === 0)
|
if (queue.length === 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.options.spv) {
|
if (this.options.spv) {
|
||||||
if (this.activeRequests >= 2000)
|
if (this.requestMap.size >= 2000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size = Math.min(queue.length, 50000);
|
size = Math.min(queue.length, 50000);
|
||||||
} else {
|
} else {
|
||||||
size = this.network.getBatchSize(this.chain.height);
|
size = this.network.getBatchSize(this.chain.height);
|
||||||
|
|
||||||
if (this.activeRequests >= size)
|
if (this.requestMap.size >= size)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < queue.length; i++) {
|
for (i = 0; i < queue.length; i++) {
|
||||||
hash = queue[i];
|
hash = queue[i];
|
||||||
|
|
||||||
delete peer.queueMap[hash];
|
assert(this.queueMap.has(hash));
|
||||||
|
|
||||||
if (this.requestMap[hash])
|
this.queueMap.remove(hash);
|
||||||
continue;
|
|
||||||
|
|
||||||
assert(!this.requestMap[hash]);
|
assert(!this.requestMap.has(hash));
|
||||||
|
|
||||||
this.requestMap[hash] = true;
|
this.requestMap.insert(hash);
|
||||||
peer.requestMap[hash] = true;
|
peer.requestMap.insert(hash);
|
||||||
|
|
||||||
this.activeRequests++;
|
|
||||||
|
|
||||||
hashes.push(hash);
|
hashes.push(hash);
|
||||||
|
|
||||||
@ -1811,10 +1827,12 @@ Pool.prototype.sendBlockRequests = function sendBlockRequests(peer) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer.blockQueue = queue.slice(hashes.length);
|
||||||
|
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'Requesting %d/%d blocks from peer with getdata (%s).',
|
'Requesting %d/%d blocks from peer with getdata (%s).',
|
||||||
hashes.length,
|
hashes.length,
|
||||||
this.activeRequests,
|
this.requestMap.size,
|
||||||
peer.hostname);
|
peer.hostname);
|
||||||
|
|
||||||
peer.getBlock(hashes);
|
peer.getBlock(hashes);
|
||||||
@ -1828,15 +1846,13 @@ Pool.prototype.sendBlockRequests = function sendBlockRequests(peer) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Pool.prototype.fulfill = function fulfill(peer, hash) {
|
Pool.prototype.fulfill = function fulfill(peer, hash) {
|
||||||
if (!peer.requestMap[hash])
|
if (!peer.requestMap.has(hash))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
delete peer.requestMap[hash];
|
peer.requestMap.remove(hash);
|
||||||
|
|
||||||
assert(this.requestMap[hash]);
|
assert(this.requestMap.has(hash));
|
||||||
delete this.requestMap[hash];
|
this.requestMap.remove(hash);
|
||||||
|
|
||||||
this.activeRequests--;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -1849,7 +1865,7 @@ Pool.prototype.fulfill = function fulfill(peer, hash) {
|
|||||||
|
|
||||||
Pool.prototype.broadcast = function broadcast(msg) {
|
Pool.prototype.broadcast = function broadcast(msg) {
|
||||||
var hash = msg.hash('hex');
|
var hash = msg.hash('hex');
|
||||||
var item = this.invMap[hash];
|
var item = this.invMap.get(hash);
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
item.refresh();
|
item.refresh();
|
||||||
@ -2148,9 +2164,9 @@ BroadcastItem.prototype.addJob = function addJob(resolve, reject) {
|
|||||||
|
|
||||||
BroadcastItem.prototype.start = function start() {
|
BroadcastItem.prototype.start = function start() {
|
||||||
assert(!this.timeout, 'Already started.');
|
assert(!this.timeout, 'Already started.');
|
||||||
assert(!this.pool.invMap[this.hash], 'Already started.');
|
assert(!this.pool.invMap.has(this.hash), 'Already started.');
|
||||||
|
|
||||||
this.pool.invMap[this.hash] = this;
|
this.pool.invMap.set(this.hash, this);
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
|
|
||||||
@ -2199,12 +2215,12 @@ BroadcastItem.prototype.announce = function announce() {
|
|||||||
|
|
||||||
BroadcastItem.prototype.cleanup = function cleanup() {
|
BroadcastItem.prototype.cleanup = function cleanup() {
|
||||||
assert(this.timeout != null, 'Already finished.');
|
assert(this.timeout != null, 'Already finished.');
|
||||||
assert(this.pool.invMap[this.hash], 'Already finished.');
|
assert(this.pool.invMap.has(this.hash), 'Already finished.');
|
||||||
|
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = null;
|
this.timeout = null;
|
||||||
|
|
||||||
delete this.pool.invMap[this.hash];
|
this.pool.invMap.remove(this.hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user