refactor: use es6 maps for everything.
This commit is contained in:
parent
5eb3e478da
commit
aa05bb5df7
@ -80,9 +80,8 @@ function Chain(options) {
|
||||
this.height = -1;
|
||||
this.synced = false;
|
||||
|
||||
this.orphanMap = {};
|
||||
this.orphanPrev = {};
|
||||
this.orphanCount = 0;
|
||||
this.orphanMap = new Map();
|
||||
this.orphanPrev = new Map();
|
||||
|
||||
this.db = new ChainDB(this);
|
||||
}
|
||||
@ -1488,7 +1487,7 @@ Chain.prototype.verifyCheckpoint = function verifyCheckpoint(prev, hash) {
|
||||
Chain.prototype.storeOrphan = function storeOrphan(block, flags, id) {
|
||||
var hash = block.hash('hex');
|
||||
var height = block.getCoinbaseHeight();
|
||||
var orphan = this.orphanPrev[block.prevBlock];
|
||||
var orphan = this.orphanPrev.get(block.prevBlock);
|
||||
|
||||
// The orphan chain forked.
|
||||
if (orphan) {
|
||||
@ -1526,13 +1525,12 @@ Chain.prototype.addOrphan = function addOrphan(orphan) {
|
||||
var block = orphan.block;
|
||||
var hash = block.hash('hex');
|
||||
|
||||
assert(!this.orphanMap[hash]);
|
||||
assert(!this.orphanPrev[block.prevBlock]);
|
||||
assert(this.orphanCount >= 0);
|
||||
assert(!this.orphanMap.has(hash));
|
||||
assert(!this.orphanPrev.has(block.prevBlock));
|
||||
assert(this.orphanMap.size >= 0);
|
||||
|
||||
this.orphanMap[hash] = orphan;
|
||||
this.orphanPrev[block.prevBlock] = orphan;
|
||||
this.orphanCount += 1;
|
||||
this.orphanMap.set(hash, orphan);
|
||||
this.orphanPrev.set(block.prevBlock, orphan);
|
||||
|
||||
return orphan;
|
||||
};
|
||||
@ -1548,13 +1546,12 @@ Chain.prototype.removeOrphan = function removeOrphan(orphan) {
|
||||
var block = orphan.block;
|
||||
var hash = block.hash('hex');
|
||||
|
||||
assert(this.orphanMap[hash]);
|
||||
assert(this.orphanPrev[block.prevBlock]);
|
||||
assert(this.orphanCount > 0);
|
||||
assert(this.orphanMap.has(hash));
|
||||
assert(this.orphanPrev.has(block.prevBlock));
|
||||
assert(this.orphanMap.size > 0);
|
||||
|
||||
delete this.orphanMap[hash];
|
||||
delete this.orphanPrev[block.prevBlock];
|
||||
this.orphanCount -= 1;
|
||||
this.orphanMap.delete(hash);
|
||||
this.orphanPrev.delete(block.prevBlock);
|
||||
|
||||
return orphan;
|
||||
};
|
||||
@ -1567,7 +1564,7 @@ Chain.prototype.removeOrphan = function removeOrphan(orphan) {
|
||||
*/
|
||||
|
||||
Chain.prototype.hasNextOrphan = function hasNextOrphan(hash) {
|
||||
return this.orphanPrev[hash] != null;
|
||||
return this.orphanPrev.has(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1578,7 +1575,7 @@ Chain.prototype.hasNextOrphan = function hasNextOrphan(hash) {
|
||||
*/
|
||||
|
||||
Chain.prototype.resolveOrphan = function resolveOrphan(hash) {
|
||||
var orphan = this.orphanPrev[hash];
|
||||
var orphan = this.orphanPrev.get(hash);
|
||||
|
||||
if (!orphan)
|
||||
return;
|
||||
@ -1591,14 +1588,13 @@ Chain.prototype.resolveOrphan = function resolveOrphan(hash) {
|
||||
*/
|
||||
|
||||
Chain.prototype.purgeOrphans = function purgeOrphans() {
|
||||
var count = this.orphanCount;
|
||||
var count = this.orphanMap.size;
|
||||
|
||||
if (count === 0)
|
||||
return;
|
||||
|
||||
this.orphanMap = {};
|
||||
this.orphanPrev = {};
|
||||
this.orphanCount = 0;
|
||||
this.orphanMap.clear();
|
||||
this.orphanPrev.clear();
|
||||
|
||||
this.logger.debug('Purged %d orphans.', count);
|
||||
};
|
||||
@ -1610,13 +1606,9 @@ Chain.prototype.purgeOrphans = function purgeOrphans() {
|
||||
|
||||
Chain.prototype.limitOrphans = function limitOrphans() {
|
||||
var now = util.now();
|
||||
var hashes = Object.keys(this.orphanMap);
|
||||
var i, hash, orphan, oldest;
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
orphan = this.orphanMap[hash];
|
||||
var orphan, oldest;
|
||||
|
||||
for (orphan of this.orphanMap.values()) {
|
||||
if (now < orphan.ts + 60 * 60) {
|
||||
if (!oldest || orphan.ts < oldest.ts)
|
||||
oldest = orphan;
|
||||
@ -1626,7 +1618,7 @@ Chain.prototype.limitOrphans = function limitOrphans() {
|
||||
this.removeOrphan(orphan);
|
||||
}
|
||||
|
||||
if (this.orphanCount < this.options.maxOrphans)
|
||||
if (this.orphanMap.size < this.options.maxOrphans)
|
||||
return;
|
||||
|
||||
if (!oldest)
|
||||
@ -1724,7 +1716,7 @@ Chain.prototype.hasEntry = function hasEntry(hash) {
|
||||
*/
|
||||
|
||||
Chain.prototype.getOrphan = function getOrphan(hash) {
|
||||
return this.orphanMap[hash] || null;
|
||||
return this.orphanMap.get(hash) || null;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1734,7 +1726,7 @@ Chain.prototype.getOrphan = function getOrphan(hash) {
|
||||
*/
|
||||
|
||||
Chain.prototype.hasOrphan = function hasOrphan(hash) {
|
||||
return this.orphanMap[hash] != null;
|
||||
return this.orphanMap.has(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1907,7 +1899,7 @@ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) {
|
||||
assert(hash);
|
||||
|
||||
for (;;) {
|
||||
orphan = this.orphanMap[hash];
|
||||
orphan = this.orphanMap.get(hash);
|
||||
|
||||
if (!orphan)
|
||||
break;
|
||||
|
||||
@ -935,12 +935,9 @@ ChainDB.prototype.getCoinView = async function getCoinView(tx) {
|
||||
|
||||
ChainDB.prototype.getSpentView = async function getSpentView(tx) {
|
||||
var view = await this.getCoinView(tx);
|
||||
var entries = view.toArray();
|
||||
var i, coins, meta;
|
||||
|
||||
for (i = 0; i < entries.length; i++) {
|
||||
coins = entries[i];
|
||||
var coins, meta;
|
||||
|
||||
for (coins of view.map.values()) {
|
||||
if (!coins.isEmpty())
|
||||
continue;
|
||||
|
||||
@ -1703,12 +1700,9 @@ ChainDB.prototype.removeBlock = async function removeBlock(entry) {
|
||||
*/
|
||||
|
||||
ChainDB.prototype.saveView = function saveView(view) {
|
||||
var i, coins, raw;
|
||||
var coins, raw;
|
||||
|
||||
view = view.toArray();
|
||||
|
||||
for (i = 0; i < view.length; i++) {
|
||||
coins = view[i];
|
||||
for (coins of view.map.values()) {
|
||||
if (coins.isEmpty()) {
|
||||
this.del(layout.c(coins.hash));
|
||||
this.coinCache.unpush(coins.hash);
|
||||
@ -2181,7 +2175,7 @@ StateCache.prototype._init = function _init() {
|
||||
for (i = 0; i < this.network.deploys.length; i++) {
|
||||
deployment = this.network.deploys[i];
|
||||
assert(!this.bits[deployment.bit]);
|
||||
this.bits[deployment.bit] = {};
|
||||
this.bits[deployment.bit] = new Map();
|
||||
}
|
||||
};
|
||||
|
||||
@ -2190,8 +2184,8 @@ StateCache.prototype.set = function set(bit, entry, state) {
|
||||
|
||||
assert(cache);
|
||||
|
||||
if (cache[entry.hash] !== state) {
|
||||
cache[entry.hash] = state;
|
||||
if (cache.get(entry.hash) !== state) {
|
||||
cache.set(entry.hash, state);
|
||||
this.updates.push(new CacheUpdate(bit, entry.hash, state));
|
||||
}
|
||||
};
|
||||
@ -2202,7 +2196,7 @@ StateCache.prototype.get = function get(bit, entry) {
|
||||
|
||||
assert(cache);
|
||||
|
||||
state = cache[entry.hash];
|
||||
state = cache.get(entry.hash);
|
||||
|
||||
if (state == null)
|
||||
return -1;
|
||||
@ -2221,7 +2215,7 @@ StateCache.prototype.drop = function drop() {
|
||||
update = this.updates[i];
|
||||
cache = this.bits[update.bit];
|
||||
assert(cache);
|
||||
delete cache[update.hash];
|
||||
cache.delete(update.hash);
|
||||
}
|
||||
|
||||
this.updates.length = 0;
|
||||
@ -2230,7 +2224,7 @@ StateCache.prototype.drop = function drop() {
|
||||
StateCache.prototype.insert = function insert(bit, hash, state) {
|
||||
var cache = this.bits[bit];
|
||||
assert(cache);
|
||||
cache[hash] = state;
|
||||
cache.set(hash, state);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -26,7 +26,7 @@ function CoinView() {
|
||||
if (!(this instanceof CoinView))
|
||||
return new CoinView();
|
||||
|
||||
this.map = {};
|
||||
this.map = new Map();
|
||||
this.undo = new UndoCoins();
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ function CoinView() {
|
||||
*/
|
||||
|
||||
CoinView.prototype.get = function get(hash) {
|
||||
return this.map[hash];
|
||||
return this.map.get(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ CoinView.prototype.get = function get(hash) {
|
||||
*/
|
||||
|
||||
CoinView.prototype.has = function has(hash) {
|
||||
return this.map[hash] != null;
|
||||
return this.map.has(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -56,7 +56,7 @@ CoinView.prototype.has = function has(hash) {
|
||||
*/
|
||||
|
||||
CoinView.prototype.add = function add(coins) {
|
||||
this.map[coins.hash] = coins;
|
||||
this.map.set(coins.hash, coins);
|
||||
return coins;
|
||||
};
|
||||
|
||||
@ -67,10 +67,10 @@ CoinView.prototype.add = function add(coins) {
|
||||
*/
|
||||
|
||||
CoinView.prototype.remove = function remove(hash) {
|
||||
if (!this.map[hash])
|
||||
if (!this.map.has(hash))
|
||||
return false;
|
||||
|
||||
delete this.map[hash];
|
||||
this.map.delete(hash);
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -304,7 +304,7 @@ CoinView.prototype.isCoinbase = function isCoinbase(input) {
|
||||
*/
|
||||
|
||||
CoinView.prototype.readCoins = async function readCoins(db, hash) {
|
||||
var coins = this.map[hash];
|
||||
var coins = this.map.get(hash);
|
||||
|
||||
if (!coins) {
|
||||
coins = await db.getCoins(hash);
|
||||
@ -312,7 +312,7 @@ CoinView.prototype.readCoins = async function readCoins(db, hash) {
|
||||
if (!coins)
|
||||
return;
|
||||
|
||||
this.map[hash] = coins;
|
||||
this.map.set(hash, coins);
|
||||
}
|
||||
|
||||
return coins;
|
||||
@ -371,14 +371,11 @@ CoinView.prototype.spendInputs = async function spendInputs(db, tx) {
|
||||
*/
|
||||
|
||||
CoinView.prototype.toArray = function toArray() {
|
||||
var keys = Object.keys(this.map);
|
||||
var out = [];
|
||||
var i, hash;
|
||||
var coins;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
hash = keys[i];
|
||||
out.push(this.map[hash]);
|
||||
}
|
||||
for (coins of this.map.values())
|
||||
out.push(coins);
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
@ -158,15 +158,15 @@ UndoCoins.prototype.apply = function apply(view, outpoint) {
|
||||
if (undo.height !== -1) {
|
||||
coins = new Coins();
|
||||
|
||||
assert(!view.map[hash]);
|
||||
view.map[hash] = coins;
|
||||
assert(!view.map.has(hash));
|
||||
view.map.set(hash, coins);
|
||||
|
||||
coins.hash = hash;
|
||||
coins.coinbase = undo.coinbase;
|
||||
coins.height = undo.height;
|
||||
coins.version = undo.version;
|
||||
} else {
|
||||
coins = view.map[hash];
|
||||
coins = view.map.get(hash);
|
||||
assert(coins);
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ function HTTPBase(options) {
|
||||
this.server = null;
|
||||
this.io = null;
|
||||
this.sockets = new List();
|
||||
this.channels = {};
|
||||
this.channels = new Map();
|
||||
this.routes = new Routes();
|
||||
this.mounts = [];
|
||||
this.stack = [];
|
||||
@ -552,7 +552,7 @@ HTTPBase.prototype._initSockets = function _initSockets() {
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.to = function to(name) {
|
||||
var list = this.channels[name];
|
||||
var list = this.channels.get(name);
|
||||
var i, args, item, socket;
|
||||
|
||||
if (!list)
|
||||
@ -630,13 +630,10 @@ HTTPBase.prototype.addSocket = function addSocket(ws) {
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.removeSocket = function removeSocket(socket) {
|
||||
var keys = Object.keys(socket.channels);
|
||||
var i, key;
|
||||
var key;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
for (key of socket.channels.keys())
|
||||
this.leaveChannel(socket, key);
|
||||
}
|
||||
|
||||
assert(this.sockets.remove(socket));
|
||||
};
|
||||
@ -649,21 +646,21 @@ HTTPBase.prototype.removeSocket = function removeSocket(socket) {
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.joinChannel = function joinChannel(socket, name) {
|
||||
var list = this.channels[name];
|
||||
var item = socket.channels[name];
|
||||
var list = this.channels.get(name);
|
||||
var item = socket.channels.get(name);
|
||||
|
||||
if (item)
|
||||
return;
|
||||
|
||||
if (!list) {
|
||||
list = new List();
|
||||
this.channels[name] = list;
|
||||
this.channels.set(name, list);
|
||||
}
|
||||
|
||||
item = new ListItem(socket);
|
||||
list.push(item);
|
||||
|
||||
socket.channels[name] = item;
|
||||
socket.channels.set(name, item);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -674,8 +671,8 @@ HTTPBase.prototype.joinChannel = function joinChannel(socket, name) {
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.leaveChannel = function leaveChannel(socket, name) {
|
||||
var list = this.channels[name];
|
||||
var item = socket.channels[name];
|
||||
var list = this.channels.get(name);
|
||||
var item = socket.channels.get(name);
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
@ -684,9 +681,9 @@ HTTPBase.prototype.leaveChannel = function leaveChannel(socket, name) {
|
||||
assert(list.remove(item));
|
||||
|
||||
if (list.size === 0)
|
||||
delete this.channels[name];
|
||||
this.channels.delete(name);
|
||||
|
||||
delete socket.channels[name];
|
||||
socket.channels.delete(name);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -696,7 +693,7 @@ HTTPBase.prototype.leaveChannel = function leaveChannel(socket, name) {
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.channel = function channel(name) {
|
||||
var list = this.channels[name];
|
||||
var list = this.channels.get(name);
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
@ -1558,7 +1555,7 @@ function WebSocket(socket, ctx) {
|
||||
this.socket = socket;
|
||||
this.remoteAddress = socket.conn.remoteAddress;
|
||||
this.hooks = {};
|
||||
this.channels = {};
|
||||
this.channels = new Map();
|
||||
this.auth = false;
|
||||
this.filter = null;
|
||||
this.prev = null;
|
||||
|
||||
@ -67,7 +67,7 @@ function RPC(node) {
|
||||
this.boundChain = false;
|
||||
this.nonce1 = 0;
|
||||
this.nonce2 = 0;
|
||||
this.merkleMap = {};
|
||||
this.merkleMap = new Map();
|
||||
this.pollers = [];
|
||||
|
||||
this.init();
|
||||
@ -225,16 +225,12 @@ RPC.prototype.stop = async function stop(args, help) {
|
||||
RPC.prototype.getNetworkInfo = async function getNetworkInfo(args, help) {
|
||||
var hosts = this.pool.hosts;
|
||||
var locals = [];
|
||||
var i, keys, key, local;
|
||||
var local;
|
||||
|
||||
if (help || args.length !== 0)
|
||||
throw new RPCError(errs.MISC_ERROR, 'getnetworkinfo');
|
||||
|
||||
keys = hosts.local.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
local = hosts.local.get(key);
|
||||
for (local of hosts.local.values()) {
|
||||
locals.push({
|
||||
address: local.addr.host,
|
||||
port: local.addr.port,
|
||||
@ -398,7 +394,7 @@ RPC.prototype.getPeerInfo = async function getPeerInfo(args, help) {
|
||||
throw new RPCError(errs.MISC_ERROR, 'getpeerinfo');
|
||||
|
||||
for (peer = this.pool.peers.head(); peer; peer = peer.next) {
|
||||
offset = this.network.time.known[peer.hostname()];
|
||||
offset = this.network.time.known.get(peer.hostname());
|
||||
|
||||
if (offset == null)
|
||||
offset = 0;
|
||||
@ -475,17 +471,14 @@ RPC.prototype.setBan = async function setBan(args, help) {
|
||||
};
|
||||
|
||||
RPC.prototype.listBanned = async function listBanned(args, help) {
|
||||
var i, banned, keys, host, time;
|
||||
var banned, host, time;
|
||||
|
||||
if (help || args.length !== 0)
|
||||
throw new RPCError(errs.MISC_ERROR, 'listbanned');
|
||||
|
||||
banned = [];
|
||||
keys = Object.keys(this.pool.hosts.banned);
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
host = keys[i];
|
||||
time = this.pool.hosts.banned[host];
|
||||
for ([host, time] of this.pool.hosts.banned) {
|
||||
banned.push({
|
||||
address: host,
|
||||
banned_until: time + this.pool.options.banTime,
|
||||
@ -704,7 +697,7 @@ RPC.prototype.getMempoolInfo = async function getMempoolInfo(args, help) {
|
||||
throw new RPCError(errs.MISC_ERROR, 'No mempool available.');
|
||||
|
||||
return {
|
||||
size: this.mempool.totalTX,
|
||||
size: this.mempool.map.size,
|
||||
bytes: this.mempool.getSize(),
|
||||
usage: this.mempool.getSize(),
|
||||
maxmempool: this.mempool.options.maxSize,
|
||||
@ -814,7 +807,7 @@ RPC.prototype.getRawMempool = async function getRawMempool(args, help) {
|
||||
var valid = new Validator([args]);
|
||||
var verbose = valid.bool(0, false);
|
||||
var out = {};
|
||||
var i, hashes, hash, entry;
|
||||
var entry, hashes;
|
||||
|
||||
if (help || args.length > 1)
|
||||
throw new RPCError(errs.MISC_ERROR, 'getrawmempool ( verbose )');
|
||||
@ -823,17 +816,8 @@ RPC.prototype.getRawMempool = async function getRawMempool(args, help) {
|
||||
throw new RPCError(errs.MISC_ERROR, 'No mempool available.');
|
||||
|
||||
if (verbose) {
|
||||
hashes = this.mempool.getSnapshot();
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
entry = this.mempool.getEntry(hash);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
for (entry of this.mempool.map.values())
|
||||
out[entry.txid()] = this.entryToJSON(entry);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -1075,7 +1059,7 @@ RPC.prototype._submitWork = async function _submitWork(data) {
|
||||
if (!header.verify())
|
||||
return false;
|
||||
|
||||
nonces = this.merkleMap[header.merkleRoot];
|
||||
nonces = this.merkleMap.get(header.merkleRoot);
|
||||
|
||||
if (!nonces)
|
||||
return false;
|
||||
@ -2291,7 +2275,7 @@ RPC.prototype.refreshBlock = function refreshBlock() {
|
||||
|
||||
this.attempt = null;
|
||||
this.lastActivity = 0;
|
||||
this.merkleMap = {};
|
||||
this.merkleMap.clear();
|
||||
this.nonce1 = 0;
|
||||
this.nonce2 = 0;
|
||||
this.pollers = [];
|
||||
@ -2370,7 +2354,7 @@ RPC.prototype.updateWork = async function updateWork() {
|
||||
root = attempt.getRoot(n1, n2);
|
||||
root = root.toString('hex');
|
||||
|
||||
this.merkleMap[root] = new Nonces(n1, n2);
|
||||
this.merkleMap.set(root, new Nonces(n1, n2));
|
||||
|
||||
return attempt;
|
||||
}
|
||||
@ -2390,7 +2374,7 @@ RPC.prototype.updateWork = async function updateWork() {
|
||||
|
||||
this.attempt = attempt;
|
||||
this.lastActivity = util.now();
|
||||
this.merkleMap[root] = new Nonces(n1, n2);
|
||||
this.merkleMap.set(root, new Nonces(n1, n2));
|
||||
|
||||
return attempt;
|
||||
};
|
||||
@ -2454,7 +2438,7 @@ RPC.prototype._addBlock = async function _addBlock(block) {
|
||||
};
|
||||
|
||||
RPC.prototype.totalTX = function totalTX() {
|
||||
return this.mempool ? this.mempool.totalTX : 0;
|
||||
return this.mempool ? this.mempool.map.size : 0;
|
||||
};
|
||||
|
||||
RPC.prototype.getSoftforks = function getSoftforks() {
|
||||
|
||||
@ -104,7 +104,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
||||
this.use(this.jsonRPC(this.rpc));
|
||||
|
||||
this.get('/', async function(req, res) {
|
||||
var totalTX = this.mempool ? this.mempool.totalTX : 0;
|
||||
var totalTX = this.mempool ? this.mempool.map.size : 0;
|
||||
var size = this.mempool ? this.mempool.getSize() : 0;
|
||||
var addr = this.pool.hosts.getLocal();
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ var policy = require('../protocol/policy');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var encoding = require('../utils/encoding');
|
||||
var Map = require('../utils/map');
|
||||
var Logger = require('../node/logger');
|
||||
|
||||
/*
|
||||
@ -490,7 +489,7 @@ PolicyEstimator.prototype.reset = function reset() {
|
||||
this.priUnlikely = 0;
|
||||
this.priLikely = INF_PRIORITY;
|
||||
|
||||
this.map.reset();
|
||||
this.map.clear();
|
||||
this.bestHeight = 0;
|
||||
|
||||
this.init();
|
||||
@ -511,7 +510,7 @@ PolicyEstimator.prototype.removeTX = function removeTX(hash) {
|
||||
|
||||
this.feeStats.removeTX(item.blockHeight, this.bestHeight, item.bucketIndex);
|
||||
|
||||
this.map.remove(hash);
|
||||
this.map.delete(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -26,7 +26,6 @@ var encoding = require('../utils/encoding');
|
||||
var layout = require('./layout');
|
||||
var LDB = require('../db/ldb');
|
||||
var Fees = require('./fees');
|
||||
var Map = require('../utils/map');
|
||||
var CoinView = require('../coins/coinview');
|
||||
var Coins = require('../coins/coins');
|
||||
var Heap = require('../utils/heap');
|
||||
@ -51,7 +50,6 @@ var VerifyResult = errors.VerifyResult;
|
||||
* @property {Boolean} loaded
|
||||
* @property {Object} db
|
||||
* @property {Number} size
|
||||
* @property {Number} totalOrphans
|
||||
* @property {Lock} locker
|
||||
* @property {Number} freeCount
|
||||
* @property {Number} lastTime
|
||||
@ -82,17 +80,15 @@ function Mempool(options) {
|
||||
this.cache = new MempoolCache(this.options);
|
||||
|
||||
this.size = 0;
|
||||
this.totalOrphans = 0;
|
||||
this.totalTX = 0;
|
||||
this.freeCount = 0;
|
||||
this.lastTime = 0;
|
||||
this.lastFlush = 0;
|
||||
this.tip = this.network.genesis.hash;
|
||||
|
||||
this.waiting = {};
|
||||
this.orphans = {};
|
||||
this.map = {};
|
||||
this.spents = {};
|
||||
this.waiting = new Map();
|
||||
this.orphans = new Map();
|
||||
this.map = new Map();
|
||||
this.spents = new Map();
|
||||
this.rejects = new RollingFilter(120000, 0.000001);
|
||||
|
||||
this.coinIndex = new CoinIndex();
|
||||
@ -196,7 +192,7 @@ Mempool.prototype.addBlock = async function addBlock(block, txs) {
|
||||
Mempool.prototype._addBlock = async function addBlock(block, txs) {
|
||||
var i, entries, entry, tx, hash;
|
||||
|
||||
if (this.totalTX === 0) {
|
||||
if (this.map.size === 0) {
|
||||
this.tip = block.hash;
|
||||
return;
|
||||
}
|
||||
@ -277,7 +273,7 @@ Mempool.prototype._removeBlock = async function removeBlock(block, txs) {
|
||||
var total = 0;
|
||||
var i, tx, hash;
|
||||
|
||||
if (this.totalTX === 0) {
|
||||
if (this.map.size === 0) {
|
||||
this.tip = block.prevBlock;
|
||||
return;
|
||||
}
|
||||
@ -337,16 +333,14 @@ Mempool.prototype.reset = async function reset() {
|
||||
*/
|
||||
|
||||
Mempool.prototype._reset = async function reset() {
|
||||
this.logger.info('Mempool reset (%d txs removed).', this.totalTX);
|
||||
this.logger.info('Mempool reset (%d txs removed).', this.map.size);
|
||||
|
||||
this.size = 0;
|
||||
this.totalOrphans = 0;
|
||||
this.totalTX = 0;
|
||||
|
||||
this.waiting = {};
|
||||
this.orphans = {};
|
||||
this.map = {};
|
||||
this.spents = {};
|
||||
this.waiting.clear();
|
||||
this.orphans.clear();
|
||||
this.map.clear();
|
||||
this.spents.clear();
|
||||
this.coinIndex.reset();
|
||||
this.txIndex.reset();
|
||||
|
||||
@ -453,7 +447,7 @@ Mempool.prototype.limitSize = function limitSize(added) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getTX = function getTX(hash) {
|
||||
var entry = this.map[hash];
|
||||
var entry = this.map.get(hash);
|
||||
if (!entry)
|
||||
return;
|
||||
return entry.tx;
|
||||
@ -466,7 +460,7 @@ Mempool.prototype.getTX = function getTX(hash) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getEntry = function getEntry(hash) {
|
||||
return this.map[hash];
|
||||
return this.map.get(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -477,7 +471,7 @@ Mempool.prototype.getEntry = function getEntry(hash) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getCoin = function getCoin(hash, index) {
|
||||
var entry = this.map[hash];
|
||||
var entry = this.map.get(hash);
|
||||
|
||||
if (!entry)
|
||||
return;
|
||||
@ -503,7 +497,7 @@ Mempool.prototype.getCoin = function getCoin(hash, index) {
|
||||
|
||||
Mempool.prototype.isSpent = function isSpent(hash, index) {
|
||||
var key = Outpoint.toKey(hash, index);
|
||||
return this.spents[key] != null;
|
||||
return this.spents.has(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -515,7 +509,7 @@ Mempool.prototype.isSpent = function isSpent(hash, index) {
|
||||
|
||||
Mempool.prototype.getSpent = function getSpent(hash, index) {
|
||||
var key = Outpoint.toKey(hash, index);
|
||||
return this.spents[key];
|
||||
return this.spents.get(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -527,7 +521,7 @@ Mempool.prototype.getSpent = function getSpent(hash, index) {
|
||||
|
||||
Mempool.prototype.getSpentTX = function getSpentTX(hash, index) {
|
||||
var key = Outpoint.toKey(hash, index);
|
||||
var entry = this.spents[key];
|
||||
var entry = this.spents.get(key);
|
||||
|
||||
if (!entry)
|
||||
return;
|
||||
@ -633,7 +627,7 @@ Mempool.prototype.getMeta = function getMeta(hash) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.hasEntry = function hasEntry(hash) {
|
||||
return this.map[hash] != null;
|
||||
return this.map.has(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1098,7 +1092,7 @@ Mempool.prototype.addEntry = async function addEntry(entry, view) {
|
||||
|
||||
this.logger.debug(
|
||||
'Added %s to mempool (txs=%d).',
|
||||
tx.txid(), this.totalTX);
|
||||
tx.txid(), this.map.size);
|
||||
|
||||
this.cache.save(entry);
|
||||
|
||||
@ -1406,20 +1400,14 @@ Mempool.prototype.hasDepends = function hasDepends(tx) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getBalance = function getBalance() {
|
||||
var hashes = this.getSnapshot();
|
||||
var total = 0;
|
||||
var i, j, tx, hash, coin;
|
||||
var i, hash, entry, tx, coin;
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
tx = this.getTX(hash);
|
||||
for ([hash, entry] of this.map) {
|
||||
tx = entry.tx;
|
||||
|
||||
assert(tx);
|
||||
|
||||
hash = tx.hash('hex');
|
||||
|
||||
for (j = 0; j < tx.outputs.length; j++) {
|
||||
coin = this.getCoin(hash, j);
|
||||
for (i = 0; i < tx.outputs.length; i++) {
|
||||
coin = this.getCoin(hash, i);
|
||||
if (coin)
|
||||
total += coin.value;
|
||||
}
|
||||
@ -1434,18 +1422,11 @@ Mempool.prototype.getBalance = function getBalance() {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getHistory = function getHistory() {
|
||||
var hashes = this.getSnapshot();
|
||||
var txs = [];
|
||||
var i, hash, tx;
|
||||
var entry;
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
tx = this.getTX(hash);
|
||||
|
||||
assert(tx);
|
||||
|
||||
txs.push(tx);
|
||||
}
|
||||
for (entry of this.map.values())
|
||||
txs.push(entry.tx);
|
||||
|
||||
return txs;
|
||||
};
|
||||
@ -1457,7 +1438,7 @@ Mempool.prototype.getHistory = function getHistory() {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getOrphan = function getOrphan(hash) {
|
||||
return this.orphans[hash];
|
||||
return this.orphans.get(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1466,7 +1447,7 @@ Mempool.prototype.getOrphan = function getOrphan(hash) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.hasOrphan = function hasOrphan(hash) {
|
||||
return this.orphans[hash] != null;
|
||||
return this.orphans.has(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1504,14 +1485,13 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx, missing, id) {
|
||||
for (i = 0; i < missing.length; i++) {
|
||||
prev = missing[i];
|
||||
|
||||
if (!this.waiting[prev])
|
||||
this.waiting[prev] = new Map();
|
||||
if (!this.waiting.has(prev))
|
||||
this.waiting.set(prev, new Set());
|
||||
|
||||
this.waiting[prev].insert(hash);
|
||||
this.waiting.get(prev).add(hash);
|
||||
}
|
||||
|
||||
this.orphans[hash] = new Orphan(tx, missing.length, id);
|
||||
this.totalOrphans++;
|
||||
this.orphans.set(hash, new Orphan(tx, missing.length, id));
|
||||
|
||||
this.logger.debug('Added orphan %s to mempool.', tx.txid());
|
||||
|
||||
@ -1578,30 +1558,27 @@ Mempool.prototype.handleOrphans = async function handleOrphans(parent) {
|
||||
|
||||
Mempool.prototype.resolveOrphans = function resolveOrphans(parent) {
|
||||
var hash = parent.hash('hex');
|
||||
var map = this.waiting[hash];
|
||||
var set = this.waiting.get(hash);
|
||||
var resolved = [];
|
||||
var i, hashes, orphanHash, orphan;
|
||||
var orphanHash, orphan;
|
||||
|
||||
if (!map)
|
||||
if (!set)
|
||||
return resolved;
|
||||
|
||||
hashes = map.keys();
|
||||
assert(hashes.length > 0);
|
||||
assert(set.size > 0);
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
orphanHash = hashes[i];
|
||||
for (orphanHash of set.keys()) {
|
||||
orphan = this.getOrphan(orphanHash);
|
||||
|
||||
assert(orphan);
|
||||
|
||||
if (--orphan.missing === 0) {
|
||||
delete this.orphans[orphanHash];
|
||||
this.totalOrphans--;
|
||||
this.orphans.delete(orphanHash);
|
||||
resolved.push(orphan);
|
||||
}
|
||||
}
|
||||
|
||||
delete this.waiting[hash];
|
||||
this.waiting.delete(hash);
|
||||
|
||||
return resolved;
|
||||
};
|
||||
@ -1614,7 +1591,7 @@ Mempool.prototype.resolveOrphans = function resolveOrphans(parent) {
|
||||
|
||||
Mempool.prototype.removeOrphan = function removeOrphan(hash) {
|
||||
var orphan = this.getOrphan(hash);
|
||||
var i, tx, map, prevout, prev;
|
||||
var i, tx, set, prevout, prev;
|
||||
|
||||
if (!orphan)
|
||||
return false;
|
||||
@ -1622,8 +1599,7 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
|
||||
try {
|
||||
tx = orphan.toTX();
|
||||
} catch (e) {
|
||||
delete this.orphans[hash];
|
||||
this.totalOrphans--;
|
||||
this.orphans.delete(hash);
|
||||
this.logger.warning('%s %s',
|
||||
'Warning: possible memory corruption.',
|
||||
'Orphan failed deserialization.');
|
||||
@ -1634,21 +1610,20 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
|
||||
|
||||
for (i = 0; i < prevout.length; i++) {
|
||||
prev = prevout[i];
|
||||
map = this.waiting[prev];
|
||||
set = this.waiting.get(prev);
|
||||
|
||||
if (!map)
|
||||
if (!set)
|
||||
continue;
|
||||
|
||||
assert(map.has(hash));
|
||||
assert(set.has(hash));
|
||||
|
||||
map.remove(hash);
|
||||
set.delete(hash);
|
||||
|
||||
if (map.size === 0)
|
||||
delete this.waiting[prev];
|
||||
if (set.size === 0)
|
||||
this.waiting.delete(prev);
|
||||
}
|
||||
|
||||
delete this.orphans[hash];
|
||||
this.totalOrphans--;
|
||||
this.orphans.delete(hash);
|
||||
|
||||
this.emit('remove orphan', tx);
|
||||
|
||||
@ -1661,14 +1636,18 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.limitOrphans = function limitOrphans() {
|
||||
var hashes = Object.keys(this.orphans);
|
||||
var index, hash;
|
||||
|
||||
if (this.totalOrphans < this.options.maxOrphans)
|
||||
if (this.orphans.size < this.options.maxOrphans)
|
||||
return false;
|
||||
|
||||
index = random.randomRange(0, hashes.length);
|
||||
hash = hashes[index];
|
||||
index = random.randomRange(0, this.orphans.size);
|
||||
|
||||
for (hash of this.orphans.keys()) {
|
||||
if (index === 0)
|
||||
break;
|
||||
index--;
|
||||
}
|
||||
|
||||
this.logger.debug('Removing orphan %s from mempool.', util.revHex(hash));
|
||||
|
||||
@ -1785,7 +1764,13 @@ Mempool.prototype.findMissing = function findMissing(tx, view) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getSnapshot = function getSnapshot() {
|
||||
return Object.keys(this.map);
|
||||
var keys = [];
|
||||
var hash;
|
||||
|
||||
for (hash of this.map.keys())
|
||||
keys.push(hash);
|
||||
|
||||
return keys;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1823,22 +1808,21 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) {
|
||||
var hash = tx.hash('hex');
|
||||
var i, input, key;
|
||||
|
||||
assert(!this.map[hash]);
|
||||
this.map[hash] = entry;
|
||||
assert(!this.map.has(hash));
|
||||
this.map.set(hash, entry);
|
||||
|
||||
assert(!tx.isCoinbase());
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
key = input.prevout.toKey();
|
||||
this.spents[key] = entry;
|
||||
this.spents.set(key, entry);
|
||||
}
|
||||
|
||||
if (this.options.indexAddress && view)
|
||||
this.indexEntry(entry, view);
|
||||
|
||||
this.size += entry.memUsage();
|
||||
this.totalTX++;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1852,22 +1836,21 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) {
|
||||
var hash = tx.hash('hex');
|
||||
var i, input, key;
|
||||
|
||||
assert(this.map[hash]);
|
||||
delete this.map[hash];
|
||||
assert(this.map.has(hash));
|
||||
this.map.delete(hash);
|
||||
|
||||
assert(!tx.isCoinbase());
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
key = input.prevout.toKey();
|
||||
delete this.spents[key];
|
||||
this.spents.delete(key);
|
||||
}
|
||||
|
||||
if (this.options.indexAddress)
|
||||
this.unindexEntry(entry);
|
||||
|
||||
this.size -= entry.memUsage();
|
||||
this.totalTX--;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2186,47 +2169,40 @@ MempoolOptions.fromOptions = function fromOptions(options) {
|
||||
|
||||
function TXIndex() {
|
||||
// Map of addr->entries.
|
||||
this.index = {};
|
||||
this.index = new Map();
|
||||
|
||||
// Map of txid->addrs.
|
||||
this.map = {};
|
||||
this.map = new Map();
|
||||
}
|
||||
|
||||
TXIndex.prototype.reset = function reset() {
|
||||
this.index = {};
|
||||
this.map = {};
|
||||
this.index.clear();
|
||||
this.map.clear();
|
||||
};
|
||||
|
||||
TXIndex.prototype.get = function get(addr) {
|
||||
var items = this.index[addr];
|
||||
var items = this.index.get(addr);
|
||||
var out = [];
|
||||
var i, keys, entry;
|
||||
var entry;
|
||||
|
||||
if (!items)
|
||||
return out;
|
||||
|
||||
keys = items.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
entry = items.get(keys[i]);
|
||||
for (entry of items.values())
|
||||
out.push(entry.tx);
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
TXIndex.prototype.getMeta = function getMeta(addr) {
|
||||
var items = this.index[addr];
|
||||
var items = this.index.get(addr);
|
||||
var out = [];
|
||||
var i, entry, keys, meta;
|
||||
var entry, meta;
|
||||
|
||||
if (!items)
|
||||
return out;
|
||||
|
||||
keys = items.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
entry = items.get(keys[i]);
|
||||
for (entry of items.values()) {
|
||||
meta = TXMeta.fromTX(entry.tx);
|
||||
meta.ps = entry.ts;
|
||||
out.push(meta);
|
||||
@ -2239,48 +2215,46 @@ TXIndex.prototype.insert = function insert(entry, view) {
|
||||
var tx = entry.tx;
|
||||
var hash = tx.hash('hex');
|
||||
var addrs = tx.getHashes(view, 'hex');
|
||||
var i, addr, items;
|
||||
var addr, items;
|
||||
|
||||
if (addrs.length === 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < addrs.length; i++) {
|
||||
addr = addrs[i];
|
||||
items = this.index[addr];
|
||||
for (addr of addrs) {
|
||||
items = this.index.get(addr);
|
||||
|
||||
if (!items) {
|
||||
items = new Map();
|
||||
this.index[addr] = items;
|
||||
this.index.set(addr, items);
|
||||
}
|
||||
|
||||
assert(!items.has(hash));
|
||||
items.set(hash, entry);
|
||||
}
|
||||
|
||||
this.map[hash] = addrs;
|
||||
this.map.set(hash, addrs);
|
||||
};
|
||||
|
||||
TXIndex.prototype.remove = function remove(hash) {
|
||||
var addrs = this.map[hash];
|
||||
var i, addr, items;
|
||||
var addrs = this.map.get(hash);
|
||||
var addr, items;
|
||||
|
||||
if (!addrs)
|
||||
return;
|
||||
|
||||
for (i = 0; i < addrs.length; i++) {
|
||||
addr = addrs[i];
|
||||
items = this.index[addr];
|
||||
for (addr of addrs) {
|
||||
items = this.index.get(addr);
|
||||
|
||||
assert(items);
|
||||
assert(items.has(hash));
|
||||
|
||||
items.remove(hash);
|
||||
items.delete(hash);
|
||||
|
||||
if (items.size === 0)
|
||||
delete this.index[addr];
|
||||
this.index.delete(addr);
|
||||
}
|
||||
|
||||
delete this.map[hash];
|
||||
this.map.delete(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2291,32 +2265,27 @@ TXIndex.prototype.remove = function remove(hash) {
|
||||
|
||||
function CoinIndex() {
|
||||
// Map of addr->coins.
|
||||
this.index = {};
|
||||
this.index = new Map();
|
||||
|
||||
// Map of outpoint->addr.
|
||||
this.map = {};
|
||||
this.map = new Map();
|
||||
}
|
||||
|
||||
CoinIndex.prototype.reset = function reset() {
|
||||
this.index = {};
|
||||
this.map = {};
|
||||
this.index.clear();
|
||||
this.map.clear();
|
||||
};
|
||||
|
||||
CoinIndex.prototype.get = function get(addr) {
|
||||
var items = this.index[addr];
|
||||
var items = this.index.get(addr);
|
||||
var out = [];
|
||||
var i, keys, coin;
|
||||
var coin;
|
||||
|
||||
if (!items)
|
||||
return out;
|
||||
|
||||
keys = items.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
coin = items.get(keys[i]);
|
||||
assert(coin);
|
||||
for (coin of items.values())
|
||||
out.push(coin.toCoin());
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
@ -2330,11 +2299,11 @@ CoinIndex.prototype.insert = function insert(tx, index) {
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
items = this.index[addr];
|
||||
items = this.index.get(addr);
|
||||
|
||||
if (!items) {
|
||||
items = new Map();
|
||||
this.index[addr] = items;
|
||||
this.index.set(addr, items);
|
||||
}
|
||||
|
||||
key = Outpoint.toKey(hash, index);
|
||||
@ -2342,27 +2311,27 @@ CoinIndex.prototype.insert = function insert(tx, index) {
|
||||
assert(!items.has(key));
|
||||
items.set(key, new IndexedCoin(tx, index));
|
||||
|
||||
this.map[key] = addr;
|
||||
this.map.set(key, addr);
|
||||
};
|
||||
|
||||
CoinIndex.prototype.remove = function remove(hash, index) {
|
||||
var key = Outpoint.toKey(hash, index);
|
||||
var addr = this.map[key];
|
||||
var addr = this.map.get(key);
|
||||
var items;
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
items = this.index[addr];
|
||||
items = this.index.get(addr);
|
||||
|
||||
assert(items);
|
||||
assert(items.has(key));
|
||||
items.remove(key);
|
||||
|
||||
if (items.size === 0)
|
||||
delete this.index[addr];
|
||||
this.index.delete(addr);
|
||||
|
||||
delete this.map[key];
|
||||
this.map.delete(key);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -258,8 +258,8 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
var depMap = {};
|
||||
var queue = new Heap(cmpRate);
|
||||
var priority = this.options.priorityWeight > 0;
|
||||
var i, j, entry, item, tx, hash, input;
|
||||
var prev, deps, hashes, weight, sigops, block;
|
||||
var i, entry, item, tx, hash, input;
|
||||
var prev, deps, weight, sigops, block;
|
||||
|
||||
if (priority)
|
||||
queue.set(cmpPriority);
|
||||
@ -272,19 +272,15 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
assert(this.mempool.tip === this.chain.tip.hash,
|
||||
'Mempool/chain tip mismatch! Unsafe to create block.');
|
||||
|
||||
hashes = this.mempool.getSnapshot();
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
entry = this.mempool.getEntry(hash);
|
||||
for (entry of this.mempool.map.values()) {
|
||||
item = BlockEntry.fromEntry(entry, attempt);
|
||||
tx = item.tx;
|
||||
|
||||
if (tx.isCoinbase())
|
||||
throw new Error('Cannot add coinbase to block.');
|
||||
|
||||
for (j = 0; j < tx.inputs.length; j++) {
|
||||
input = tx.inputs[j];
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
prev = input.prevout.hash;
|
||||
|
||||
if (!this.mempool.hasEntry(prev))
|
||||
@ -351,8 +347,8 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
if (!deps)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < deps.length; j++) {
|
||||
item = deps[j];
|
||||
for (i = 0; i < deps.length; i++) {
|
||||
item = deps[i];
|
||||
if (--item.depCount === 0)
|
||||
queue.insert(item);
|
||||
}
|
||||
|
||||
@ -311,16 +311,13 @@ CompactBlock.prototype.toRequest = function toRequest() {
|
||||
|
||||
CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
|
||||
var have = {};
|
||||
var hashes = mempool.getSnapshot();
|
||||
var i, id, index, hash, tx;
|
||||
var id, index, hash, entry, tx;
|
||||
|
||||
if (this.count === this.totalTX)
|
||||
return true;
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
tx = mempool.getTX(hash);
|
||||
assert(tx);
|
||||
for (entry of mempool.map.values()) {
|
||||
tx = entry.tx;
|
||||
hash = tx.hash();
|
||||
|
||||
if (witness)
|
||||
|
||||
@ -15,7 +15,6 @@ var Network = require('../protocol/network');
|
||||
var NetAddress = require('../primitives/netaddress');
|
||||
var List = require('../utils/list');
|
||||
var murmur3 = require('../utils/murmur3');
|
||||
var Map = require('../utils/map');
|
||||
var common = require('./common');
|
||||
var seeds = require('./seeds');
|
||||
var dns = require('./dns');
|
||||
@ -42,14 +41,14 @@ function HostList(options) {
|
||||
this.dnsSeeds = [];
|
||||
this.dnsNodes = [];
|
||||
|
||||
this.map = {};
|
||||
this.map = new Map();
|
||||
this.fresh = [];
|
||||
this.totalFresh = 0;
|
||||
this.used = [];
|
||||
this.totalUsed = 0;
|
||||
this.nodes = [];
|
||||
this.local = new Map();
|
||||
this.banned = {};
|
||||
this.banned = new Map();
|
||||
|
||||
this.timer = null;
|
||||
this.needsFlush = false;
|
||||
@ -152,10 +151,8 @@ HostList.prototype._init = function init() {
|
||||
this.pushLocal(this.address, scores.MANUAL);
|
||||
this.addLocal(options.host, options.port, scores.BIND);
|
||||
|
||||
for (i = 0; i < hosts.length; i++) {
|
||||
host = hosts[i];
|
||||
for (host of hosts)
|
||||
this.addLocal(host, port, scores.IF);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -231,10 +228,9 @@ HostList.prototype.stop = function stop() {
|
||||
|
||||
HostList.prototype.injectSeeds = function injectSeeds() {
|
||||
var nodes = seeds.get(this.network.type);
|
||||
var i, node, addr;
|
||||
var node, addr;
|
||||
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
for (node of nodes) {
|
||||
addr = NetAddress.fromHostname(node, this.network);
|
||||
|
||||
if (!addr.isRoutable())
|
||||
@ -343,19 +339,15 @@ HostList.prototype.isFull = function isFull() {
|
||||
*/
|
||||
|
||||
HostList.prototype.reset = function reset() {
|
||||
var i, bucket;
|
||||
var bucket;
|
||||
|
||||
this.map = {};
|
||||
this.map.clear();
|
||||
|
||||
for (i = 0; i < this.fresh.length; i++) {
|
||||
bucket = this.fresh[i];
|
||||
for (bucket of this.fresh)
|
||||
bucket.clear();
|
||||
|
||||
for (bucket of this.used)
|
||||
bucket.reset();
|
||||
}
|
||||
|
||||
for (i = 0; i < this.used.length; i++) {
|
||||
bucket = this.used[i];
|
||||
bucket.reset();
|
||||
}
|
||||
|
||||
this.totalFresh = 0;
|
||||
this.totalUsed = 0;
|
||||
@ -369,7 +361,7 @@ HostList.prototype.reset = function reset() {
|
||||
*/
|
||||
|
||||
HostList.prototype.ban = function ban(host) {
|
||||
this.banned[host] = util.now();
|
||||
this.banned.set(host, util.now());
|
||||
};
|
||||
|
||||
/**
|
||||
@ -378,7 +370,7 @@ HostList.prototype.ban = function ban(host) {
|
||||
*/
|
||||
|
||||
HostList.prototype.unban = function unban(host) {
|
||||
delete this.banned[host];
|
||||
this.banned.delete(host);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -386,7 +378,7 @@ HostList.prototype.unban = function unban(host) {
|
||||
*/
|
||||
|
||||
HostList.prototype.clearBanned = function clearBanned() {
|
||||
this.banned = {};
|
||||
this.banned.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -396,13 +388,13 @@ HostList.prototype.clearBanned = function clearBanned() {
|
||||
*/
|
||||
|
||||
HostList.prototype.isBanned = function isBanned(host) {
|
||||
var time = this.banned[host];
|
||||
var time = this.banned.get(host);
|
||||
|
||||
if (time == null)
|
||||
return false;
|
||||
|
||||
if (util.now() > time + this.options.banTime) {
|
||||
delete this.banned[host];
|
||||
this.banned.delete(host);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -418,7 +410,7 @@ HostList.prototype.getHost = function getHost() {
|
||||
var now = this.network.now();
|
||||
var buckets = null;
|
||||
var factor = 1;
|
||||
var index, key, bucket, entry, num;
|
||||
var index, bucket, entry, num;
|
||||
|
||||
if (this.totalFresh > 0)
|
||||
buckets = this.fresh;
|
||||
@ -445,8 +437,11 @@ HostList.prototype.getHost = function getHost() {
|
||||
while (index--)
|
||||
entry = entry.next;
|
||||
} else {
|
||||
key = bucket.keys()[index];
|
||||
entry = bucket.get(key);
|
||||
for (entry of bucket.values()) {
|
||||
if (index === 0)
|
||||
break;
|
||||
index--;
|
||||
}
|
||||
}
|
||||
|
||||
num = util.random(0, 1 << 30);
|
||||
@ -507,7 +502,7 @@ HostList.prototype.add = function add(addr, src) {
|
||||
|
||||
assert(addr.port !== 0);
|
||||
|
||||
entry = this.map[addr.hostname];
|
||||
entry = this.map.get(addr.hostname);
|
||||
|
||||
if (entry) {
|
||||
// No source means we're inserting
|
||||
@ -578,7 +573,7 @@ HostList.prototype.add = function add(addr, src) {
|
||||
bucket.set(entry.key(), entry);
|
||||
entry.refCount++;
|
||||
|
||||
this.map[entry.key()] = entry;
|
||||
this.map.set(entry.key(), entry);
|
||||
this.needsFlush = true;
|
||||
|
||||
return true;
|
||||
@ -590,18 +585,14 @@ HostList.prototype.add = function add(addr, src) {
|
||||
*/
|
||||
|
||||
HostList.prototype.evictFresh = function evictFresh(bucket) {
|
||||
var keys = bucket.keys();
|
||||
var i, key, entry, old;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = bucket.get(key);
|
||||
var entry, old;
|
||||
|
||||
for (entry of bucket.values()) {
|
||||
if (this.isStale(entry)) {
|
||||
bucket.remove(entry.key());
|
||||
bucket.delete(entry.key());
|
||||
|
||||
if (--entry.refCount === 0) {
|
||||
delete this.map[entry.key()];
|
||||
this.map.delete(entry.key());
|
||||
this.totalFresh--;
|
||||
}
|
||||
|
||||
@ -620,10 +611,10 @@ HostList.prototype.evictFresh = function evictFresh(bucket) {
|
||||
if (!old)
|
||||
return;
|
||||
|
||||
bucket.remove(old.key());
|
||||
bucket.delete(old.key());
|
||||
|
||||
if (--old.refCount === 0) {
|
||||
delete this.map[old.key()];
|
||||
this.map.delete(old.key());
|
||||
this.totalFresh--;
|
||||
}
|
||||
};
|
||||
@ -667,7 +658,7 @@ HostList.prototype.isStale = function isStale(entry) {
|
||||
*/
|
||||
|
||||
HostList.prototype.remove = function remove(hostname) {
|
||||
var entry = this.map[hostname];
|
||||
var entry = this.map.get(hostname);
|
||||
var i, head, bucket;
|
||||
|
||||
if (!entry)
|
||||
@ -680,8 +671,7 @@ HostList.prototype.remove = function remove(hostname) {
|
||||
while (head.prev)
|
||||
head = head.prev;
|
||||
|
||||
for (i = 0; i < this.used.length; i++) {
|
||||
bucket = this.used[i];
|
||||
for (bucket of this.used) {
|
||||
if (bucket.head === head) {
|
||||
bucket.remove(entry);
|
||||
this.totalUsed--;
|
||||
@ -691,9 +681,8 @@ HostList.prototype.remove = function remove(hostname) {
|
||||
|
||||
assert(i < this.used.length);
|
||||
} else {
|
||||
for (i = 0; i < this.fresh.length; i++) {
|
||||
bucket = this.fresh[i];
|
||||
if (bucket.remove(entry.key()))
|
||||
for (bucket of this.fresh) {
|
||||
if (bucket.delete(entry.key()))
|
||||
entry.refCount--;
|
||||
}
|
||||
|
||||
@ -701,7 +690,7 @@ HostList.prototype.remove = function remove(hostname) {
|
||||
assert(entry.refCount === 0);
|
||||
}
|
||||
|
||||
delete this.map[entry.key()];
|
||||
this.map.delete(entry.key());
|
||||
|
||||
return entry.addr;
|
||||
};
|
||||
@ -712,7 +701,7 @@ HostList.prototype.remove = function remove(hostname) {
|
||||
*/
|
||||
|
||||
HostList.prototype.markAttempt = function markAttempt(hostname) {
|
||||
var entry = this.map[hostname];
|
||||
var entry = this.map.get(hostname);
|
||||
var now = this.network.now();
|
||||
|
||||
if (!entry)
|
||||
@ -728,7 +717,7 @@ HostList.prototype.markAttempt = function markAttempt(hostname) {
|
||||
*/
|
||||
|
||||
HostList.prototype.markSuccess = function markSuccess(hostname) {
|
||||
var entry = this.map[hostname];
|
||||
var entry = this.map.get(hostname);
|
||||
var now = this.network.now();
|
||||
|
||||
if (!entry)
|
||||
@ -745,9 +734,9 @@ HostList.prototype.markSuccess = function markSuccess(hostname) {
|
||||
*/
|
||||
|
||||
HostList.prototype.markAck = function markAck(hostname, services) {
|
||||
var entry = this.map[hostname];
|
||||
var entry = this.map.get(hostname);
|
||||
var now = this.network.now();
|
||||
var i, bucket, evicted, old, fresh;
|
||||
var bucket, evicted, old, fresh;
|
||||
|
||||
if (!entry)
|
||||
return;
|
||||
@ -765,9 +754,8 @@ HostList.prototype.markAck = function markAck(hostname, services) {
|
||||
assert(entry.refCount > 0);
|
||||
|
||||
// Remove from fresh.
|
||||
for (i = 0; i < this.fresh.length; i++) {
|
||||
bucket = this.fresh[i];
|
||||
if (bucket.remove(entry.key())) {
|
||||
for (bucket of this.fresh) {
|
||||
if (bucket.delete(entry.key())) {
|
||||
entry.refCount--;
|
||||
old = bucket;
|
||||
}
|
||||
@ -830,15 +818,11 @@ HostList.prototype.evictUsed = function evictUsed(bucket) {
|
||||
*/
|
||||
|
||||
HostList.prototype.toArray = function toArray() {
|
||||
var keys = Object.keys(this.map);
|
||||
var out = [];
|
||||
var i, key, entry;
|
||||
var entry;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = this.map[key];
|
||||
for (entry of this.map.values())
|
||||
out.push(entry.addr);
|
||||
}
|
||||
|
||||
assert.equal(out.length, this.size());
|
||||
|
||||
@ -993,21 +977,18 @@ HostList.prototype.pushLocal = function pushLocal(addr, score) {
|
||||
*/
|
||||
|
||||
HostList.prototype.getLocal = function getLocal(src) {
|
||||
var keys = this.local.keys();
|
||||
var bestReach = -1;
|
||||
var bestScore = -1;
|
||||
var bestDest = null;
|
||||
var i, key, dest, reach;
|
||||
var dest, reach;
|
||||
|
||||
if (!src)
|
||||
src = this.address;
|
||||
|
||||
if (keys.length === 0)
|
||||
if (this.local.length === 0)
|
||||
return null;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
dest = this.local.get(key);
|
||||
for (dest of this.local.values()) {
|
||||
reach = src.getReachability(dest.addr);
|
||||
|
||||
if (reach < bestReach)
|
||||
@ -1121,7 +1102,7 @@ HostList.prototype.populateSeed = async function populateSeed(seed) {
|
||||
|
||||
HostList.prototype.populate = async function populate(target) {
|
||||
var addrs = [];
|
||||
var i, addr, hosts, host;
|
||||
var addr, hosts, host;
|
||||
|
||||
assert(target.type === IP.types.DNS, 'Resolved host passed.');
|
||||
|
||||
@ -1134,8 +1115,7 @@ HostList.prototype.populate = async function populate(target) {
|
||||
return addrs;
|
||||
}
|
||||
|
||||
for (i = 0; i < hosts.length; i++) {
|
||||
host = hosts[i];
|
||||
for (host of hosts) {
|
||||
addr = NetAddress.fromHost(host, target.port, this.network);
|
||||
addrs.push(addr);
|
||||
}
|
||||
@ -1152,24 +1132,19 @@ HostList.prototype.toJSON = function toJSON() {
|
||||
var addrs = [];
|
||||
var fresh = [];
|
||||
var used = [];
|
||||
var i, keys, key, bucket, entry;
|
||||
var bucket, entry, key, keys;
|
||||
|
||||
keys = Object.keys(this.map);
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = this.map[key];
|
||||
for (entry of this.map.values())
|
||||
addrs.push(entry.toJSON());
|
||||
}
|
||||
|
||||
for (i = 0; i < this.fresh.length; i++) {
|
||||
bucket = this.fresh[i];
|
||||
keys = bucket.keys();
|
||||
for (bucket of this.fresh) {
|
||||
keys = [];
|
||||
for (key of bucket.keys())
|
||||
keys.push(key);
|
||||
fresh.push(keys);
|
||||
}
|
||||
|
||||
for (i = 0; i < this.used.length; i++) {
|
||||
bucket = this.used[i];
|
||||
for (bucket of this.used) {
|
||||
keys = [];
|
||||
for (entry = bucket.head; entry; entry = entry.next)
|
||||
keys.push(entry.key());
|
||||
@ -1193,12 +1168,12 @@ HostList.prototype.toJSON = function toJSON() {
|
||||
|
||||
HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
var sources = {};
|
||||
var map = {};
|
||||
var map = new Map();
|
||||
var fresh = [];
|
||||
var totalFresh = 0;
|
||||
var used = [];
|
||||
var totalUsed = 0;
|
||||
var i, j, bucket, keys, key, addr, entry, src;
|
||||
var i, bucket, keys, key, addr, entry, src;
|
||||
|
||||
assert(json && typeof json === 'object');
|
||||
|
||||
@ -1207,8 +1182,7 @@ HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
|
||||
assert(Array.isArray(json.addrs));
|
||||
|
||||
for (i = 0; i < json.addrs.length; i++) {
|
||||
addr = json.addrs[i];
|
||||
for (addr of json.addrs) {
|
||||
entry = HostEntry.fromJSON(addr, this.network);
|
||||
src = sources[entry.src.hostname];
|
||||
|
||||
@ -1220,20 +1194,18 @@ HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
|
||||
entry.src = src;
|
||||
|
||||
map[entry.key()] = entry;
|
||||
map.set(entry.key(), entry);
|
||||
}
|
||||
|
||||
assert(Array.isArray(json.fresh));
|
||||
assert(json.fresh.length <= this.options.maxBuckets,
|
||||
'Buckets mismatch.');
|
||||
|
||||
for (i = 0; i < json.fresh.length; i++) {
|
||||
keys = json.fresh[i];
|
||||
for (keys of json.fresh) {
|
||||
bucket = new Map();
|
||||
|
||||
for (j = 0; j < keys.length; j++) {
|
||||
key = keys[j];
|
||||
entry = map[key];
|
||||
for (key of keys) {
|
||||
entry = map.get(key);
|
||||
assert(entry);
|
||||
if (entry.refCount === 0)
|
||||
totalFresh++;
|
||||
@ -1258,9 +1230,8 @@ HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
keys = json.used[i];
|
||||
bucket = new List();
|
||||
|
||||
for (j = 0; j < keys.length; j++) {
|
||||
key = keys[j];
|
||||
entry = map[key];
|
||||
for (key of keys) {
|
||||
entry = map.get(key);
|
||||
assert(entry);
|
||||
assert(entry.refCount === 0);
|
||||
assert(!entry.used);
|
||||
@ -1278,13 +1249,8 @@ HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
assert(used.length === this.used.length,
|
||||
'Buckets mismatch.');
|
||||
|
||||
keys = Object.keys(map);
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = map[key];
|
||||
for (entry of map.values())
|
||||
assert(entry.used || entry.refCount > 0);
|
||||
}
|
||||
|
||||
this.map = map;
|
||||
this.fresh = fresh;
|
||||
|
||||
@ -11,7 +11,6 @@ var assert = require('assert');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var Map = require('../utils/map');
|
||||
var Parser = require('./parser');
|
||||
var Framer = require('./framer');
|
||||
var packets = require('./packets');
|
||||
@ -1053,7 +1052,7 @@ Peer.prototype.sendFeeRate = function sendFeeRate(rate) {
|
||||
|
||||
Peer.prototype.destroy = function destroy() {
|
||||
var connected = this.connected;
|
||||
var i, keys, cmd, entry, jobs, job;
|
||||
var i, cmd, entry, jobs, job;
|
||||
|
||||
if (this.destroyed)
|
||||
return;
|
||||
@ -1100,12 +1099,8 @@ Peer.prototype.destroy = function destroy() {
|
||||
job.reject(new Error('Peer was destroyed.'));
|
||||
}
|
||||
|
||||
keys = this.responseMap.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
cmd = keys[i];
|
||||
entry = this.responseMap.get(cmd);
|
||||
this.responseMap.remove(cmd);
|
||||
for ([cmd, entry] of this.responseMap) {
|
||||
this.responseMap.delete(cmd);
|
||||
entry.reject(new Error('Peer was destroyed.'));
|
||||
}
|
||||
|
||||
@ -1288,13 +1283,10 @@ Peer.prototype.fulfill = function fulfill(packet) {
|
||||
*/
|
||||
|
||||
Peer.prototype.maybeTimeout = function maybeTimeout() {
|
||||
var keys = this.responseMap.keys();
|
||||
var now = util.ms();
|
||||
var i, key, entry, name, ts, block, mult;
|
||||
var key, entry, name, ts, block, mult;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
entry = this.responseMap.get(key);
|
||||
for ([key, entry] of this.responseMap) {
|
||||
if (now > entry.timeout) {
|
||||
name = packets.typesByVal[key];
|
||||
this.error('Peer is stalling (%s).', name.toLowerCase());
|
||||
@ -1321,11 +1313,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
|
||||
}
|
||||
|
||||
if (this.options.isFull() || !this.syncing) {
|
||||
keys = this.blockMap.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
ts = this.blockMap.get(key);
|
||||
for (ts of this.blockMap.values()) {
|
||||
if (now > ts + Peer.BLOCK_TIMEOUT) {
|
||||
this.error('Peer is stalling (block).');
|
||||
this.destroy();
|
||||
@ -1333,11 +1321,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
|
||||
}
|
||||
}
|
||||
|
||||
keys = this.txMap.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
ts = this.txMap.get(key);
|
||||
for (ts of this.txMap.values()) {
|
||||
if (now > ts + Peer.TX_TIMEOUT) {
|
||||
this.error('Peer is stalling (tx).');
|
||||
this.destroy();
|
||||
@ -1345,11 +1329,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
|
||||
}
|
||||
}
|
||||
|
||||
keys = this.compactBlocks.keys();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
block = this.compactBlocks.get(key);
|
||||
for (block of this.compactBlocks.values()) {
|
||||
if (now > block.now + Peer.RESPONSE_TIMEOUT) {
|
||||
this.error('Peer is stalling (blocktxn).');
|
||||
this.destroy();
|
||||
@ -1426,7 +1406,7 @@ Peer.prototype.response = function response(type, payload) {
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
this.responseMap.remove(type);
|
||||
this.responseMap.delete(type);
|
||||
|
||||
return entry;
|
||||
};
|
||||
|
||||
133
lib/net/pool.js
133
lib/net/pool.js
@ -32,7 +32,6 @@ var dns = require('./dns');
|
||||
var HostList = require('./hostlist');
|
||||
var UPNP = require('./upnp');
|
||||
var InvItem = require('../primitives/invitem');
|
||||
var Map = require('../utils/map');
|
||||
var packets = require('./packets');
|
||||
var services = common.services;
|
||||
var invTypes = InvItem.types;
|
||||
@ -94,9 +93,9 @@ function Pool(options) {
|
||||
this.syncing = false;
|
||||
this.spvFilter = null;
|
||||
this.txFilter = null;
|
||||
this.blockMap = new Map();
|
||||
this.txMap = new Map();
|
||||
this.compactBlocks = new Map();
|
||||
this.blockMap = new Set();
|
||||
this.txMap = new Set();
|
||||
this.compactBlocks = new Set();
|
||||
this.invMap = new Map();
|
||||
this.pendingFilter = null;
|
||||
this.pendingRefill = null;
|
||||
@ -345,7 +344,7 @@ Pool.prototype.disconnect = async function disconnect() {
|
||||
*/
|
||||
|
||||
Pool.prototype._disconnect = async function disconnect() {
|
||||
var i, item, hashes, hash;
|
||||
var item;
|
||||
|
||||
assert(this.loaded, 'Pool is not loaded.');
|
||||
|
||||
@ -354,18 +353,13 @@ Pool.prototype._disconnect = async function disconnect() {
|
||||
|
||||
this.disconnecting = true;
|
||||
|
||||
hashes = this.invMap.keys();
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
item = this.invMap.get(hash);
|
||||
for (item of this.invMap.values())
|
||||
item.resolve();
|
||||
}
|
||||
|
||||
this.peers.destroy();
|
||||
|
||||
this.blockMap.reset();
|
||||
this.txMap.reset();
|
||||
this.blockMap.clear();
|
||||
this.txMap.clear();
|
||||
|
||||
if (this.pendingFilter != null) {
|
||||
clearTimeout(this.pendingFilter);
|
||||
@ -761,11 +755,11 @@ Pool.prototype.stopSync = function stopSync() {
|
||||
peer.merkleMap = null;
|
||||
peer.blockTime = -1;
|
||||
peer.blockMap.reset();
|
||||
peer.compactBlocks.reset();
|
||||
peer.compactBlocks.clear();
|
||||
}
|
||||
|
||||
this.blockMap.reset();
|
||||
this.compactBlocks.reset();
|
||||
this.blockMap.clear();
|
||||
this.compactBlocks.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -986,13 +980,9 @@ Pool.prototype.getNextTip = function getNextTip(height) {
|
||||
Pool.prototype.announceList = function announceList(peer) {
|
||||
var blocks = [];
|
||||
var txs = [];
|
||||
var hashes = this.invMap.keys();
|
||||
var i, hash, item;
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
item = this.invMap.get(hash);
|
||||
var item;
|
||||
|
||||
for (item of this.invMap.values()) {
|
||||
switch (item.type) {
|
||||
case invTypes.BLOCK:
|
||||
blocks.push(item.msg);
|
||||
@ -2481,7 +2471,7 @@ Pool.prototype.logStatus = function logStatus(block) {
|
||||
util.date(block.ts),
|
||||
this.chain.height,
|
||||
(this.chain.getProgress() * 100).toFixed(2) + '%',
|
||||
this.chain.orphanCount,
|
||||
this.chain.orphanMap.size,
|
||||
this.blockMap.size,
|
||||
block.bits,
|
||||
this.peers.size());
|
||||
@ -2543,7 +2533,7 @@ Pool.prototype._handleTX = async function handleTX(peer, packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
peer.merkleMap.insert(hash);
|
||||
peer.merkleMap.add(hash);
|
||||
|
||||
block.addTX(tx);
|
||||
|
||||
@ -2776,7 +2766,7 @@ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packe
|
||||
peer.merkleBlock = block;
|
||||
peer.merkleTime = util.ms();
|
||||
peer.merkleMatches = block.tree.matches.length;
|
||||
peer.merkleMap = new Map();
|
||||
peer.merkleMap = new Set();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2861,7 +2851,7 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet)
|
||||
}
|
||||
peer.blockMap.set(hash, util.ms());
|
||||
assert(!this.blockMap.has(hash));
|
||||
this.blockMap.insert(hash);
|
||||
this.blockMap.add(hash);
|
||||
}
|
||||
|
||||
if (!this.mempool) {
|
||||
@ -2919,7 +2909,7 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet)
|
||||
assert(!peer.compactBlocks.has(hash));
|
||||
peer.compactBlocks.set(hash, block);
|
||||
|
||||
this.compactBlocks.insert(hash);
|
||||
this.compactBlocks.add(hash);
|
||||
|
||||
this.logger.debug(
|
||||
'Received non-full compact block %s tx=%d/%d (%s).',
|
||||
@ -3000,10 +2990,10 @@ Pool.prototype.handleBlockTxn = async function handleBlockTxn(peer, packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
peer.compactBlocks.remove(res.hash);
|
||||
peer.compactBlocks.delete(res.hash);
|
||||
|
||||
assert(this.compactBlocks.has(res.hash));
|
||||
this.compactBlocks.remove(res.hash);
|
||||
this.compactBlocks.delete(res.hash);
|
||||
|
||||
if (!block.fillMissing(res)) {
|
||||
this.logger.warning(
|
||||
@ -3248,33 +3238,22 @@ Pool.prototype.refill = function refill() {
|
||||
*/
|
||||
|
||||
Pool.prototype.removePeer = function removePeer(peer) {
|
||||
var i, hashes, hash;
|
||||
var hash;
|
||||
|
||||
this.peers.remove(peer);
|
||||
|
||||
hashes = peer.blockMap.keys();
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
for (hash of peer.blockMap.keys())
|
||||
this.resolveBlock(peer, hash);
|
||||
}
|
||||
|
||||
hashes = peer.txMap.keys();
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
for (hash of peer.txMap.keys())
|
||||
this.resolveTX(peer, hash);
|
||||
}
|
||||
|
||||
hashes = peer.compactBlocks.keys();
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i];
|
||||
for (hash of peer.compactBlocks.keys()) {
|
||||
assert(this.compactBlocks.has(hash));
|
||||
this.compactBlocks.remove(hash);
|
||||
this.compactBlocks.delete(hash);
|
||||
}
|
||||
|
||||
peer.compactBlocks.reset();
|
||||
peer.compactBlocks.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3469,7 +3448,7 @@ Pool.prototype.getBlock = function getBlock(peer, hashes) {
|
||||
if (this.blockMap.has(hash))
|
||||
continue;
|
||||
|
||||
this.blockMap.insert(hash);
|
||||
this.blockMap.add(hash);
|
||||
peer.blockMap.set(hash, now);
|
||||
|
||||
if (this.chain.synced)
|
||||
@ -3516,7 +3495,7 @@ Pool.prototype.getTX = function getTX(peer, hashes) {
|
||||
if (this.txMap.has(hash))
|
||||
continue;
|
||||
|
||||
this.txMap.insert(hash);
|
||||
this.txMap.add(hash);
|
||||
peer.txMap.set(hash, now);
|
||||
|
||||
now += 50;
|
||||
@ -3620,10 +3599,10 @@ Pool.prototype.resolveTX = function resolveTX(peer, hash) {
|
||||
if (!peer.txMap.has(hash))
|
||||
return false;
|
||||
|
||||
peer.txMap.remove(hash);
|
||||
peer.txMap.delete(hash);
|
||||
|
||||
assert(this.txMap.has(hash));
|
||||
this.txMap.remove(hash);
|
||||
this.txMap.delete(hash);
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -3639,10 +3618,10 @@ Pool.prototype.resolveBlock = function resolveBlock(peer, hash) {
|
||||
if (!peer.blockMap.has(hash))
|
||||
return false;
|
||||
|
||||
peer.blockMap.remove(hash);
|
||||
peer.blockMap.delete(hash);
|
||||
|
||||
assert(this.blockMap.has(hash));
|
||||
this.blockMap.remove(hash);
|
||||
this.blockMap.delete(hash);
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -4168,8 +4147,8 @@ PoolOptions.prototype._resolve = function resolve(name) {
|
||||
*/
|
||||
|
||||
function PeerList() {
|
||||
this.map = {};
|
||||
this.ids = {};
|
||||
this.map = new Map();
|
||||
this.ids = new Map();
|
||||
this.list = new List();
|
||||
this.load = null;
|
||||
this.inbound = 0;
|
||||
@ -4211,11 +4190,11 @@ PeerList.prototype.size = function size() {
|
||||
PeerList.prototype.add = function add(peer) {
|
||||
assert(this.list.push(peer));
|
||||
|
||||
assert(!this.map[peer.hostname()]);
|
||||
this.map[peer.hostname()] = peer;
|
||||
assert(!this.map.has(peer.hostname()));
|
||||
this.map.set(peer.hostname(), peer);
|
||||
|
||||
assert(!this.ids[peer.id]);
|
||||
this.ids[peer.id] = peer;
|
||||
assert(!this.ids.has(peer.id));
|
||||
this.ids.set(peer.id, peer);
|
||||
|
||||
if (peer.outbound)
|
||||
this.outbound++;
|
||||
@ -4231,11 +4210,11 @@ PeerList.prototype.add = function add(peer) {
|
||||
PeerList.prototype.remove = function remove(peer) {
|
||||
assert(this.list.remove(peer));
|
||||
|
||||
assert(this.ids[peer.id]);
|
||||
delete this.ids[peer.id];
|
||||
assert(this.ids.has(peer.id));
|
||||
this.ids.delete(peer.id);
|
||||
|
||||
assert(this.map[peer.hostname()]);
|
||||
delete this.map[peer.hostname()];
|
||||
assert(this.map.has(peer.hostname()));
|
||||
this.map.delete(peer.hostname());
|
||||
|
||||
if (peer === this.load) {
|
||||
assert(peer.loader);
|
||||
@ -4256,7 +4235,7 @@ PeerList.prototype.remove = function remove(peer) {
|
||||
*/
|
||||
|
||||
PeerList.prototype.get = function get(hostname) {
|
||||
return this.map[hostname];
|
||||
return this.map.get(hostname);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4266,7 +4245,7 @@ PeerList.prototype.get = function get(hostname) {
|
||||
*/
|
||||
|
||||
PeerList.prototype.has = function has(hostname) {
|
||||
return this.map[hostname] != null;
|
||||
return this.map.has(hostname);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4276,7 +4255,7 @@ PeerList.prototype.has = function has(hostname) {
|
||||
*/
|
||||
|
||||
PeerList.prototype.find = function find(id) {
|
||||
return this.ids[id];
|
||||
return this.ids.get(id);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4394,7 +4373,7 @@ BroadcastItem.prototype.cleanup = function cleanup() {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
|
||||
this.pool.invMap.remove(this.hash);
|
||||
this.pool.invMap.delete(this.hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4490,8 +4469,8 @@ BroadcastItem.prototype.inspect = function inspect() {
|
||||
*/
|
||||
|
||||
function NonceList() {
|
||||
this.map = {};
|
||||
this.hosts = {};
|
||||
this.map = new Map();
|
||||
this.hosts = new Map();
|
||||
}
|
||||
|
||||
NonceList.prototype.alloc = function alloc(hostname) {
|
||||
@ -4500,10 +4479,10 @@ NonceList.prototype.alloc = function alloc(hostname) {
|
||||
for (;;) {
|
||||
nonce = util.nonce();
|
||||
key = nonce.toString('hex');
|
||||
if (!this.map[key]) {
|
||||
this.map[key] = hostname;
|
||||
assert(!this.hosts[hostname]);
|
||||
this.hosts[hostname] = key;
|
||||
if (!this.map.has(key)) {
|
||||
this.map.set(key, hostname);
|
||||
assert(!this.hosts.has(hostname));
|
||||
this.hosts.set(hostname, key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4513,19 +4492,19 @@ NonceList.prototype.alloc = function alloc(hostname) {
|
||||
|
||||
NonceList.prototype.has = function has(nonce) {
|
||||
var key = nonce.toString('hex');
|
||||
return this.map[key] != null;
|
||||
return this.map.has(key);
|
||||
};
|
||||
|
||||
NonceList.prototype.remove = function remove(hostname) {
|
||||
var key = this.hosts[hostname];
|
||||
var key = this.hosts.get(hostname);
|
||||
|
||||
if (!key)
|
||||
return false;
|
||||
|
||||
delete this.hosts[hostname];
|
||||
this.hosts.delete(hostname);
|
||||
|
||||
assert(this.map[key]);
|
||||
delete this.map[key];
|
||||
assert(this.map.has(key));
|
||||
this.map.delete(key);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -34,7 +34,7 @@ function TimeData(limit) {
|
||||
limit = 200;
|
||||
|
||||
this.samples = [];
|
||||
this.known = {};
|
||||
this.known = new Map();
|
||||
this.limit = limit;
|
||||
this.offset = 0;
|
||||
this._checked = false;
|
||||
@ -55,10 +55,10 @@ TimeData.prototype.add = function add(id, time) {
|
||||
if (this.samples.length >= this.limit)
|
||||
return;
|
||||
|
||||
if (this.known[id] != null)
|
||||
if (this.known.has(id))
|
||||
return;
|
||||
|
||||
this.known[id] = sample;
|
||||
this.known.set(id, sample);
|
||||
|
||||
util.binaryInsert(this.samples, sample, compare);
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ function SigCache(size) {
|
||||
|
||||
this.size = size;
|
||||
this.keys = [];
|
||||
this.valid = {};
|
||||
this.valid = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ SigCache.prototype.resize = function resize(size) {
|
||||
|
||||
this.size = size;
|
||||
this.keys.length = 0;
|
||||
this.valid = {};
|
||||
this.valid.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -63,12 +63,12 @@ SigCache.prototype.add = function add(hash, sig, key) {
|
||||
if (this.size === 0)
|
||||
return;
|
||||
|
||||
this.valid[hash] = new SigCacheEntry(sig, key);
|
||||
this.valid.set(hash, new SigCacheEntry(sig, key));
|
||||
|
||||
if (this.keys.length >= this.size) {
|
||||
i = Math.floor(Math.random() * this.keys.length);
|
||||
k = this.keys[i];
|
||||
delete this.valid[k];
|
||||
this.valid.delete(k);
|
||||
this.keys[i] = hash;
|
||||
} else {
|
||||
this.keys.push(hash);
|
||||
@ -84,7 +84,7 @@ SigCache.prototype.add = function add(hash, sig, key) {
|
||||
*/
|
||||
|
||||
SigCache.prototype.has = function has(hash, sig, key) {
|
||||
var entry = this.valid[hash];
|
||||
var entry = this.valid.get(hash);
|
||||
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
@ -21,7 +21,7 @@ function LRU(capacity, getSize) {
|
||||
if (!(this instanceof LRU))
|
||||
return new LRU(capacity, getSize);
|
||||
|
||||
this.map = Object.create(null);
|
||||
this.map = new Map();
|
||||
this.size = 0;
|
||||
this.items = 0;
|
||||
this.head = null;
|
||||
@ -70,7 +70,7 @@ LRU.prototype._compact = function _compact() {
|
||||
break;
|
||||
this.size -= this._getSize(item);
|
||||
this.items--;
|
||||
delete this.map[item.key];
|
||||
this.map.delete(item.key);
|
||||
next = item.next;
|
||||
item.prev = null;
|
||||
item.next = null;
|
||||
@ -94,7 +94,7 @@ LRU.prototype.reset = function reset() {
|
||||
var item, next;
|
||||
|
||||
for (item = this.head; item; item = next) {
|
||||
delete this.map[item.key];
|
||||
this.map.delete(item.key);
|
||||
this.items--;
|
||||
next = item.next;
|
||||
item.prev = null;
|
||||
@ -122,7 +122,7 @@ LRU.prototype.set = function set(key, value) {
|
||||
|
||||
key = key + '';
|
||||
|
||||
item = this.map[key];
|
||||
item = this.map.get(key);
|
||||
|
||||
if (item) {
|
||||
this.size -= this._getSize(item);
|
||||
@ -136,7 +136,7 @@ LRU.prototype.set = function set(key, value) {
|
||||
|
||||
item = new LRUItem(key, value);
|
||||
|
||||
this.map[key] = item;
|
||||
this.map.set(key, item);
|
||||
|
||||
this._appendList(item);
|
||||
|
||||
@ -160,7 +160,7 @@ LRU.prototype.get = function get(key) {
|
||||
|
||||
key = key + '';
|
||||
|
||||
item = this.map[key];
|
||||
item = this.map.get(key);
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
@ -180,7 +180,7 @@ LRU.prototype.get = function get(key) {
|
||||
LRU.prototype.has = function get(key) {
|
||||
if (this.capacity === 0)
|
||||
return false;
|
||||
return this.map[key] != null;
|
||||
return this.map.has(key + '');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -197,7 +197,7 @@ LRU.prototype.remove = function remove(key) {
|
||||
|
||||
key = key + '';
|
||||
|
||||
item = this.map[key];
|
||||
item = this.map.get(key);
|
||||
|
||||
if (!item)
|
||||
return false;
|
||||
@ -205,7 +205,7 @@ LRU.prototype.remove = function remove(key) {
|
||||
this.size -= this._getSize(item);
|
||||
this.items--;
|
||||
|
||||
delete this.map[key];
|
||||
this.map.delete(key);
|
||||
|
||||
this._removeList(item);
|
||||
|
||||
|
||||
136
lib/utils/map.js
136
lib/utils/map.js
@ -1,136 +0,0 @@
|
||||
/*!
|
||||
* map.js - hash table for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
* Map
|
||||
* @alias module:utils.Map
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function Map() {
|
||||
if (!(this instanceof Map))
|
||||
return new Map();
|
||||
|
||||
this.map = Object.create(null);
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get map keys.
|
||||
* @returns {String[]}
|
||||
*/
|
||||
|
||||
Map.prototype.keys = function keys() {
|
||||
return Object.keys(this.map);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get map values.
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
|
||||
Map.prototype.values = function values() {
|
||||
var keys = Object.keys(this.map);
|
||||
var values = [];
|
||||
var i, key;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
values.push(this.map[key]);
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get item from map.
|
||||
* @param {String} key
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
|
||||
Map.prototype.get = function get(key) {
|
||||
return this.map[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether map has an item.
|
||||
* @param {String} key
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Map.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}
|
||||
*/
|
||||
|
||||
Map.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}
|
||||
*/
|
||||
|
||||
Map.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.
|
||||
*/
|
||||
|
||||
Map.prototype.reset = function reset() {
|
||||
this.map = Object.create(null);
|
||||
this.size = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert a key.
|
||||
* Equivalent to `this.set([key], true)`.
|
||||
* @param {String} key
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Map.prototype.insert = function insert(key) {
|
||||
return this.set(key, true);
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = Map;
|
||||
@ -20,8 +20,8 @@ function MappedLock() {
|
||||
if (!(this instanceof MappedLock))
|
||||
return MappedLock.create();
|
||||
|
||||
this.jobs = Object.create(null);
|
||||
this.busy = Object.create(null);
|
||||
this.jobs = new Map();
|
||||
this.busy = new Set();
|
||||
this.destroyed = false;
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ MappedLock.create = function create() {
|
||||
*/
|
||||
|
||||
MappedLock.prototype.has = function has(name) {
|
||||
return this.busy[name] === true;
|
||||
return this.busy.has(name);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -56,7 +56,7 @@ MappedLock.prototype.has = function has(name) {
|
||||
*/
|
||||
|
||||
MappedLock.prototype.hasPending = function hasPending(name) {
|
||||
return this.jobs[name] != null;
|
||||
return this.jobs.has(name);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -80,19 +80,19 @@ MappedLock.prototype.lock = function lock(key, force) {
|
||||
return Promise.resolve(nop);
|
||||
|
||||
if (force) {
|
||||
assert(this.busy[key]);
|
||||
assert(this.busy.has(key));
|
||||
return Promise.resolve(nop);
|
||||
}
|
||||
|
||||
if (this.busy[key]) {
|
||||
if (this.busy.has(key)) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (!self.jobs[key])
|
||||
self.jobs[key] = [];
|
||||
self.jobs[key].push(new Job(resolve, reject));
|
||||
if (!self.jobs.has(key))
|
||||
self.jobs.set(key, []);
|
||||
self.jobs.get(key).push(new Job(resolve, reject));
|
||||
});
|
||||
}
|
||||
|
||||
this.busy[key] = true;
|
||||
this.busy.add(key);
|
||||
|
||||
return Promise.resolve(this.unlock(key));
|
||||
};
|
||||
@ -107,11 +107,11 @@ MappedLock.prototype.lock = function lock(key, force) {
|
||||
MappedLock.prototype.unlock = function unlock(key) {
|
||||
var self = this;
|
||||
return function unlocker() {
|
||||
var jobs = self.jobs[key];
|
||||
var jobs = self.jobs.get(key);
|
||||
var job;
|
||||
|
||||
assert(self.destroyed || self.busy[key]);
|
||||
delete self.busy[key];
|
||||
assert(self.destroyed || self.busy.has(key));
|
||||
self.busy.delete(key);
|
||||
|
||||
if (!jobs)
|
||||
return;
|
||||
@ -122,9 +122,9 @@ MappedLock.prototype.unlock = function unlock(key) {
|
||||
assert(job);
|
||||
|
||||
if (jobs.length === 0)
|
||||
delete self.jobs[key];
|
||||
self.jobs.delete(key);
|
||||
|
||||
self.busy[key] = true;
|
||||
self.busy.add(key);
|
||||
|
||||
job.resolve(unlocker);
|
||||
};
|
||||
@ -137,23 +137,18 @@ MappedLock.prototype.unlock = function unlock(key) {
|
||||
MappedLock.prototype.destroy = function destroy() {
|
||||
var err = new Error('Lock was destroyed.');
|
||||
var map = this.jobs;
|
||||
var keys = Object.keys(map);
|
||||
var i, j, key, jobs, job;
|
||||
var jobs, job;
|
||||
|
||||
assert(!this.destroyed, 'Lock is already destroyed.');
|
||||
|
||||
this.destroyed = true;
|
||||
|
||||
this.jobs = Object.create(null);
|
||||
this.busy = Object.create(null);
|
||||
this.jobs = new Map();
|
||||
this.busy = new Map();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
jobs = map[key];
|
||||
for (j = 0; j < jobs.length; j++) {
|
||||
job = jobs[j];
|
||||
for (jobs of map.values()) {
|
||||
for (job of jobs)
|
||||
job.reject(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -163,7 +158,6 @@ MappedLock.prototype.destroy = function destroy() {
|
||||
* @ignore
|
||||
* @param {Function} resolve
|
||||
* @param {Function} reject
|
||||
* @param {String?} name
|
||||
*/
|
||||
|
||||
function Job(resolve, reject) {
|
||||
|
||||
@ -45,7 +45,7 @@ function TXDB(wallet) {
|
||||
this.options = wallet.db.options;
|
||||
this.coinCache = new LRU(10000);
|
||||
|
||||
this.locked = {};
|
||||
this.locked = new Set();
|
||||
this.state = null;
|
||||
this.pending = null;
|
||||
this.events = [];
|
||||
@ -1612,7 +1612,7 @@ TXDB.prototype.unlockTX = function unlockTX(tx) {
|
||||
|
||||
TXDB.prototype.lockCoin = function lockCoin(coin) {
|
||||
var key = coin.toKey();
|
||||
this.locked[key] = true;
|
||||
this.locked.add(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1622,7 +1622,7 @@ TXDB.prototype.lockCoin = function lockCoin(coin) {
|
||||
|
||||
TXDB.prototype.unlockCoin = function unlockCoin(coin) {
|
||||
var key = coin.toKey();
|
||||
delete this.locked[key];
|
||||
return this.locked.delete(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1632,7 +1632,7 @@ TXDB.prototype.unlockCoin = function unlockCoin(coin) {
|
||||
|
||||
TXDB.prototype.isLocked = function isLocked(coin) {
|
||||
var key = coin.toKey();
|
||||
return this.locked[key] === true;
|
||||
return this.locked.has(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1661,14 +1661,11 @@ TXDB.prototype.filterLocked = function filterLocked(coins) {
|
||||
*/
|
||||
|
||||
TXDB.prototype.getLocked = function getLocked() {
|
||||
var keys = Object.keys(this.locked);
|
||||
var outpoints = [];
|
||||
var i, key;
|
||||
var key;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
for (key of this.locked.keys())
|
||||
outpoints.push(Outpoint.fromKey(key));
|
||||
}
|
||||
|
||||
return outpoints;
|
||||
};
|
||||
|
||||
@ -84,7 +84,7 @@ function WalletDB(options) {
|
||||
}
|
||||
|
||||
this.state = new ChainState();
|
||||
this.wallets = Object.create(null);
|
||||
this.wallets = new Map();
|
||||
this.depth = 0;
|
||||
this.rescanning = false;
|
||||
this.bound = false;
|
||||
@ -182,19 +182,15 @@ WalletDB.prototype._open = async function open() {
|
||||
*/
|
||||
|
||||
WalletDB.prototype._close = async function close() {
|
||||
var keys = Object.keys(this.wallets);
|
||||
var i, key, wallet;
|
||||
var wallet;
|
||||
|
||||
await this.disconnect();
|
||||
|
||||
if (this.http && this.options.listen)
|
||||
await this.http.close();
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
wallet = this.wallets[key];
|
||||
for (wallet of this.wallets.values())
|
||||
await wallet.destroy();
|
||||
}
|
||||
|
||||
await this.db.close();
|
||||
|
||||
@ -809,8 +805,8 @@ WalletDB.prototype.dump = function dump() {
|
||||
*/
|
||||
|
||||
WalletDB.prototype.register = function register(wallet) {
|
||||
assert(!this.wallets[wallet.wid]);
|
||||
this.wallets[wallet.wid] = wallet;
|
||||
assert(!this.wallets.has(wallet.wid));
|
||||
this.wallets.set(wallet.wid, wallet);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -820,8 +816,8 @@ WalletDB.prototype.register = function register(wallet) {
|
||||
*/
|
||||
|
||||
WalletDB.prototype.unregister = function unregister(wallet) {
|
||||
assert(this.wallets[wallet.wid]);
|
||||
delete this.wallets[wallet.wid];
|
||||
assert(this.wallets.has(wallet.wid));
|
||||
this.wallets.delete(wallet.wid);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -886,7 +882,7 @@ WalletDB.prototype.get = async function get(id) {
|
||||
*/
|
||||
|
||||
WalletDB.prototype._get = async function get(wid) {
|
||||
var wallet = this.wallets[wid];
|
||||
var wallet = this.wallets.get(wid);
|
||||
var data;
|
||||
|
||||
if (wallet)
|
||||
|
||||
@ -484,7 +484,7 @@ function Worker(id) {
|
||||
|
||||
this.id = id != null ? id : -1;
|
||||
this.child = null;
|
||||
this.pending = {};
|
||||
this.pending = new Map();
|
||||
|
||||
this.env = {
|
||||
BCOIN_MASTER_URL: process.env.BCOIN_MASTER_URL || WorkerPool.MASTER_URL,
|
||||
@ -777,9 +777,9 @@ Worker.prototype.execute = function execute(packet, timeout) {
|
||||
Worker.prototype._execute = function _execute(packet, timeout, resolve, reject) {
|
||||
var job = new PendingJob(this, packet.id, resolve, reject);
|
||||
|
||||
assert(!this.pending[packet.id], 'ID overflow.');
|
||||
assert(!this.pending.has(packet.id), 'ID overflow.');
|
||||
|
||||
this.pending[packet.id] = job;
|
||||
this.pending.set(packet.id, job);
|
||||
|
||||
job.start(timeout);
|
||||
|
||||
@ -793,7 +793,7 @@ Worker.prototype._execute = function _execute(packet, timeout, resolve, reject)
|
||||
*/
|
||||
|
||||
Worker.prototype.resolveJob = function resolveJob(id, result) {
|
||||
var job = this.pending[id];
|
||||
var job = this.pending.get(id);
|
||||
|
||||
if (!job)
|
||||
throw new Error('Job ' + id + ' is not in progress.');
|
||||
@ -808,7 +808,7 @@ Worker.prototype.resolveJob = function resolveJob(id, result) {
|
||||
*/
|
||||
|
||||
Worker.prototype.rejectJob = function rejectJob(id, err) {
|
||||
var job = this.pending[id];
|
||||
var job = this.pending.get(id);
|
||||
|
||||
if (!job)
|
||||
throw new Error('Job ' + id + ' is not in progress.');
|
||||
@ -821,14 +821,10 @@ Worker.prototype.rejectJob = function rejectJob(id, err) {
|
||||
*/
|
||||
|
||||
Worker.prototype.killJobs = function killJobs() {
|
||||
var keys = Object.keys(this.pending);
|
||||
var i, key, job;
|
||||
var job;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
job = this.pending[key];
|
||||
for (job of this.pending.values())
|
||||
job.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -889,8 +885,8 @@ PendingJob.prototype.cleanup = function cleanup() {
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
assert(this.worker.pending[this.id]);
|
||||
delete this.worker.pending[this.id];
|
||||
assert(this.worker.pending.has(this.id));
|
||||
this.worker.pending.delete(this.id);
|
||||
|
||||
return job;
|
||||
};
|
||||
|
||||
@ -294,7 +294,7 @@ describe('Block', function() {
|
||||
var block = Block.fromRaw(cmpct1[1], 'hex');
|
||||
var cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex');
|
||||
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
|
||||
var map = {};
|
||||
var map = new Map();
|
||||
var i, tx, mempool, result;
|
||||
|
||||
assert(cblock1.init());
|
||||
@ -304,16 +304,11 @@ describe('Block', function() {
|
||||
|
||||
for (i = 0; i < block.txs.length; i++) {
|
||||
tx = block.txs[i];
|
||||
map[tx.hash('hex')] = tx;
|
||||
map.set(tx.hash('hex'), { tx: tx });
|
||||
}
|
||||
|
||||
mempool = {
|
||||
getSnapshot: function() {
|
||||
return Object.keys(map);
|
||||
},
|
||||
getTX: function(hash) {
|
||||
return map[hash];
|
||||
}
|
||||
map: map
|
||||
};
|
||||
|
||||
assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291);
|
||||
@ -333,29 +328,21 @@ describe('Block', function() {
|
||||
var block = Block.fromRaw(cmpct1[1], 'hex');
|
||||
var cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex');
|
||||
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
|
||||
var map = {};
|
||||
var i, tx, mid, keys, mempool, result, req, res;
|
||||
var map = new Map();
|
||||
var i, tx, mempool, result, req, res;
|
||||
|
||||
assert(cblock1.init());
|
||||
|
||||
assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]);
|
||||
assert.equal(cblock2.toRaw().toString('hex'), cmpct1[0]);
|
||||
|
||||
for (i = 0; i < block.txs.length; i++) {
|
||||
for (i = 0; i < block.txs.length >>> 1; i++) {
|
||||
tx = block.txs[i];
|
||||
map[tx.hash('hex')] = tx;
|
||||
map.set(tx.hash('hex'), { tx: tx });
|
||||
}
|
||||
|
||||
mid = block.txs.length >>> 1;
|
||||
keys = Object.keys(map).slice(0, mid);
|
||||
|
||||
mempool = {
|
||||
getSnapshot: function() {
|
||||
return keys;
|
||||
},
|
||||
getTX: function(hash) {
|
||||
return map[hash];
|
||||
}
|
||||
map: map
|
||||
};
|
||||
|
||||
assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291);
|
||||
@ -389,7 +376,7 @@ describe('Block', function() {
|
||||
var block = Block.fromRaw(cmpct2block);
|
||||
var cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex');
|
||||
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
|
||||
var map = {};
|
||||
var map = new Map();
|
||||
var i, tx, result, mempool;
|
||||
|
||||
assert(cblock1.init());
|
||||
@ -399,16 +386,11 @@ describe('Block', function() {
|
||||
|
||||
for (i = 0; i < block.txs.length; i++) {
|
||||
tx = block.txs[i];
|
||||
map[tx.hash('hex')] = tx;
|
||||
map.set(tx.hash('hex'), { tx: tx });
|
||||
}
|
||||
|
||||
mempool = {
|
||||
getSnapshot: function() {
|
||||
return Object.keys(map);
|
||||
},
|
||||
getTX: function(hash) {
|
||||
return map[hash];
|
||||
}
|
||||
map: map
|
||||
};
|
||||
|
||||
result = cblock1.fillMempool(false, mempool);
|
||||
@ -426,29 +408,21 @@ describe('Block', function() {
|
||||
var block = Block.fromRaw(cmpct2block);
|
||||
var cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex');
|
||||
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
|
||||
var map = {};
|
||||
var i, tx, mid, keys, mempool, result, req, res;
|
||||
var map = new Map();
|
||||
var i, tx, mempool, result, req, res;
|
||||
|
||||
assert(cblock1.init());
|
||||
|
||||
assert.equal(cblock1.toRaw().toString('hex'), cmpct2);
|
||||
assert.equal(cblock2.toRaw().toString('hex'), cmpct2);
|
||||
|
||||
for (i = 0; i < block.txs.length; i++) {
|
||||
for (i = 0; i < block.txs.length >>> 1; i++) {
|
||||
tx = block.txs[i];
|
||||
map[tx.hash('hex')] = tx;
|
||||
map.set(tx.hash('hex'), { tx: tx });
|
||||
}
|
||||
|
||||
mid = block.txs.length >>> 1;
|
||||
keys = Object.keys(map).slice(0, mid);
|
||||
|
||||
mempool = {
|
||||
getSnapshot: function() {
|
||||
return keys;
|
||||
},
|
||||
getTX: function(hash) {
|
||||
return map[hash];
|
||||
}
|
||||
map: map
|
||||
};
|
||||
|
||||
result = cblock1.fillMempool(false, mempool);
|
||||
|
||||
@ -594,7 +594,7 @@ describe('Node', function() {
|
||||
missing = await node.mempool.addTX(tx);
|
||||
assert(!missing || missing.length === 0);
|
||||
|
||||
assert.equal(node.mempool.totalTX, 1);
|
||||
assert.equal(node.mempool.map.size, 1);
|
||||
});
|
||||
|
||||
it('should add lesser transaction to mempool', async function() {
|
||||
@ -620,7 +620,7 @@ describe('Node', function() {
|
||||
missing = await node.mempool.addTX(tx);
|
||||
assert(!missing || missing.length === 0);
|
||||
|
||||
assert.equal(node.mempool.totalTX, 2);
|
||||
assert.equal(node.mempool.map.size, 2);
|
||||
});
|
||||
|
||||
it('should get a block template', async function() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user