refactor: use es6 maps for everything.

This commit is contained in:
Christopher Jeffrey 2017-06-29 00:22:20 -07:00
parent 5eb3e478da
commit aa05bb5df7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
24 changed files with 403 additions and 732 deletions

View File

@ -80,9 +80,8 @@ function Chain(options) {
this.height = -1; this.height = -1;
this.synced = false; this.synced = false;
this.orphanMap = {}; this.orphanMap = new Map();
this.orphanPrev = {}; this.orphanPrev = new Map();
this.orphanCount = 0;
this.db = new ChainDB(this); this.db = new ChainDB(this);
} }
@ -1488,7 +1487,7 @@ Chain.prototype.verifyCheckpoint = function verifyCheckpoint(prev, hash) {
Chain.prototype.storeOrphan = function storeOrphan(block, flags, id) { Chain.prototype.storeOrphan = function storeOrphan(block, flags, id) {
var hash = block.hash('hex'); var hash = block.hash('hex');
var height = block.getCoinbaseHeight(); var height = block.getCoinbaseHeight();
var orphan = this.orphanPrev[block.prevBlock]; var orphan = this.orphanPrev.get(block.prevBlock);
// The orphan chain forked. // The orphan chain forked.
if (orphan) { if (orphan) {
@ -1526,13 +1525,12 @@ Chain.prototype.addOrphan = function addOrphan(orphan) {
var block = orphan.block; var block = orphan.block;
var hash = block.hash('hex'); var hash = block.hash('hex');
assert(!this.orphanMap[hash]); assert(!this.orphanMap.has(hash));
assert(!this.orphanPrev[block.prevBlock]); assert(!this.orphanPrev.has(block.prevBlock));
assert(this.orphanCount >= 0); assert(this.orphanMap.size >= 0);
this.orphanMap[hash] = orphan; this.orphanMap.set(hash, orphan);
this.orphanPrev[block.prevBlock] = orphan; this.orphanPrev.set(block.prevBlock, orphan);
this.orphanCount += 1;
return orphan; return orphan;
}; };
@ -1548,13 +1546,12 @@ Chain.prototype.removeOrphan = function removeOrphan(orphan) {
var block = orphan.block; var block = orphan.block;
var hash = block.hash('hex'); var hash = block.hash('hex');
assert(this.orphanMap[hash]); assert(this.orphanMap.has(hash));
assert(this.orphanPrev[block.prevBlock]); assert(this.orphanPrev.has(block.prevBlock));
assert(this.orphanCount > 0); assert(this.orphanMap.size > 0);
delete this.orphanMap[hash]; this.orphanMap.delete(hash);
delete this.orphanPrev[block.prevBlock]; this.orphanPrev.delete(block.prevBlock);
this.orphanCount -= 1;
return orphan; return orphan;
}; };
@ -1567,7 +1564,7 @@ Chain.prototype.removeOrphan = function removeOrphan(orphan) {
*/ */
Chain.prototype.hasNextOrphan = function hasNextOrphan(hash) { 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) { Chain.prototype.resolveOrphan = function resolveOrphan(hash) {
var orphan = this.orphanPrev[hash]; var orphan = this.orphanPrev.get(hash);
if (!orphan) if (!orphan)
return; return;
@ -1591,14 +1588,13 @@ Chain.prototype.resolveOrphan = function resolveOrphan(hash) {
*/ */
Chain.prototype.purgeOrphans = function purgeOrphans() { Chain.prototype.purgeOrphans = function purgeOrphans() {
var count = this.orphanCount; var count = this.orphanMap.size;
if (count === 0) if (count === 0)
return; return;
this.orphanMap = {}; this.orphanMap.clear();
this.orphanPrev = {}; this.orphanPrev.clear();
this.orphanCount = 0;
this.logger.debug('Purged %d orphans.', count); this.logger.debug('Purged %d orphans.', count);
}; };
@ -1610,13 +1606,9 @@ Chain.prototype.purgeOrphans = function purgeOrphans() {
Chain.prototype.limitOrphans = function limitOrphans() { Chain.prototype.limitOrphans = function limitOrphans() {
var now = util.now(); var now = util.now();
var hashes = Object.keys(this.orphanMap); var orphan, oldest;
var i, hash, orphan, oldest;
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
orphan = this.orphanMap[hash];
for (orphan of this.orphanMap.values()) {
if (now < orphan.ts + 60 * 60) { if (now < orphan.ts + 60 * 60) {
if (!oldest || orphan.ts < oldest.ts) if (!oldest || orphan.ts < oldest.ts)
oldest = orphan; oldest = orphan;
@ -1626,7 +1618,7 @@ Chain.prototype.limitOrphans = function limitOrphans() {
this.removeOrphan(orphan); this.removeOrphan(orphan);
} }
if (this.orphanCount < this.options.maxOrphans) if (this.orphanMap.size < this.options.maxOrphans)
return; return;
if (!oldest) if (!oldest)
@ -1724,7 +1716,7 @@ Chain.prototype.hasEntry = function hasEntry(hash) {
*/ */
Chain.prototype.getOrphan = function getOrphan(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) { 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); assert(hash);
for (;;) { for (;;) {
orphan = this.orphanMap[hash]; orphan = this.orphanMap.get(hash);
if (!orphan) if (!orphan)
break; break;

View File

@ -935,12 +935,9 @@ ChainDB.prototype.getCoinView = async function getCoinView(tx) {
ChainDB.prototype.getSpentView = async function getSpentView(tx) { ChainDB.prototype.getSpentView = async function getSpentView(tx) {
var view = await this.getCoinView(tx); var view = await this.getCoinView(tx);
var entries = view.toArray(); var coins, meta;
var i, coins, meta;
for (i = 0; i < entries.length; i++) {
coins = entries[i];
for (coins of view.map.values()) {
if (!coins.isEmpty()) if (!coins.isEmpty())
continue; continue;
@ -1703,12 +1700,9 @@ ChainDB.prototype.removeBlock = async function removeBlock(entry) {
*/ */
ChainDB.prototype.saveView = function saveView(view) { ChainDB.prototype.saveView = function saveView(view) {
var i, coins, raw; var coins, raw;
view = view.toArray(); for (coins of view.map.values()) {
for (i = 0; i < view.length; i++) {
coins = view[i];
if (coins.isEmpty()) { if (coins.isEmpty()) {
this.del(layout.c(coins.hash)); this.del(layout.c(coins.hash));
this.coinCache.unpush(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++) { for (i = 0; i < this.network.deploys.length; i++) {
deployment = this.network.deploys[i]; deployment = this.network.deploys[i];
assert(!this.bits[deployment.bit]); 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); assert(cache);
if (cache[entry.hash] !== state) { if (cache.get(entry.hash) !== state) {
cache[entry.hash] = state; cache.set(entry.hash, state);
this.updates.push(new CacheUpdate(bit, 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); assert(cache);
state = cache[entry.hash]; state = cache.get(entry.hash);
if (state == null) if (state == null)
return -1; return -1;
@ -2221,7 +2215,7 @@ StateCache.prototype.drop = function drop() {
update = this.updates[i]; update = this.updates[i];
cache = this.bits[update.bit]; cache = this.bits[update.bit];
assert(cache); assert(cache);
delete cache[update.hash]; cache.delete(update.hash);
} }
this.updates.length = 0; this.updates.length = 0;
@ -2230,7 +2224,7 @@ StateCache.prototype.drop = function drop() {
StateCache.prototype.insert = function insert(bit, hash, state) { StateCache.prototype.insert = function insert(bit, hash, state) {
var cache = this.bits[bit]; var cache = this.bits[bit];
assert(cache); assert(cache);
cache[hash] = state; cache.set(hash, state);
}; };
/** /**

View File

@ -26,7 +26,7 @@ function CoinView() {
if (!(this instanceof CoinView)) if (!(this instanceof CoinView))
return new CoinView(); return new CoinView();
this.map = {}; this.map = new Map();
this.undo = new UndoCoins(); this.undo = new UndoCoins();
} }
@ -37,7 +37,7 @@ function CoinView() {
*/ */
CoinView.prototype.get = function get(hash) { 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) { 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) { CoinView.prototype.add = function add(coins) {
this.map[coins.hash] = coins; this.map.set(coins.hash, coins);
return coins; return coins;
}; };
@ -67,10 +67,10 @@ CoinView.prototype.add = function add(coins) {
*/ */
CoinView.prototype.remove = function remove(hash) { CoinView.prototype.remove = function remove(hash) {
if (!this.map[hash]) if (!this.map.has(hash))
return false; return false;
delete this.map[hash]; this.map.delete(hash);
return true; return true;
}; };
@ -304,7 +304,7 @@ CoinView.prototype.isCoinbase = function isCoinbase(input) {
*/ */
CoinView.prototype.readCoins = async function readCoins(db, hash) { CoinView.prototype.readCoins = async function readCoins(db, hash) {
var coins = this.map[hash]; var coins = this.map.get(hash);
if (!coins) { if (!coins) {
coins = await db.getCoins(hash); coins = await db.getCoins(hash);
@ -312,7 +312,7 @@ CoinView.prototype.readCoins = async function readCoins(db, hash) {
if (!coins) if (!coins)
return; return;
this.map[hash] = coins; this.map.set(hash, coins);
} }
return coins; return coins;
@ -371,14 +371,11 @@ CoinView.prototype.spendInputs = async function spendInputs(db, tx) {
*/ */
CoinView.prototype.toArray = function toArray() { CoinView.prototype.toArray = function toArray() {
var keys = Object.keys(this.map);
var out = []; var out = [];
var i, hash; var coins;
for (i = 0; i < keys.length; i++) { for (coins of this.map.values())
hash = keys[i]; out.push(coins);
out.push(this.map[hash]);
}
return out; return out;
}; };

View File

@ -158,15 +158,15 @@ UndoCoins.prototype.apply = function apply(view, outpoint) {
if (undo.height !== -1) { if (undo.height !== -1) {
coins = new Coins(); coins = new Coins();
assert(!view.map[hash]); assert(!view.map.has(hash));
view.map[hash] = coins; view.map.set(hash, coins);
coins.hash = hash; coins.hash = hash;
coins.coinbase = undo.coinbase; coins.coinbase = undo.coinbase;
coins.height = undo.height; coins.height = undo.height;
coins.version = undo.version; coins.version = undo.version;
} else { } else {
coins = view.map[hash]; coins = view.map.get(hash);
assert(coins); assert(coins);
} }

View File

@ -41,7 +41,7 @@ function HTTPBase(options) {
this.server = null; this.server = null;
this.io = null; this.io = null;
this.sockets = new List(); this.sockets = new List();
this.channels = {}; this.channels = new Map();
this.routes = new Routes(); this.routes = new Routes();
this.mounts = []; this.mounts = [];
this.stack = []; this.stack = [];
@ -552,7 +552,7 @@ HTTPBase.prototype._initSockets = function _initSockets() {
*/ */
HTTPBase.prototype.to = function to(name) { HTTPBase.prototype.to = function to(name) {
var list = this.channels[name]; var list = this.channels.get(name);
var i, args, item, socket; var i, args, item, socket;
if (!list) if (!list)
@ -630,13 +630,10 @@ HTTPBase.prototype.addSocket = function addSocket(ws) {
*/ */
HTTPBase.prototype.removeSocket = function removeSocket(socket) { HTTPBase.prototype.removeSocket = function removeSocket(socket) {
var keys = Object.keys(socket.channels); var key;
var i, key;
for (i = 0; i < keys.length; i++) { for (key of socket.channels.keys())
key = keys[i];
this.leaveChannel(socket, key); this.leaveChannel(socket, key);
}
assert(this.sockets.remove(socket)); assert(this.sockets.remove(socket));
}; };
@ -649,21 +646,21 @@ HTTPBase.prototype.removeSocket = function removeSocket(socket) {
*/ */
HTTPBase.prototype.joinChannel = function joinChannel(socket, name) { HTTPBase.prototype.joinChannel = function joinChannel(socket, name) {
var list = this.channels[name]; var list = this.channels.get(name);
var item = socket.channels[name]; var item = socket.channels.get(name);
if (item) if (item)
return; return;
if (!list) { if (!list) {
list = new List(); list = new List();
this.channels[name] = list; this.channels.set(name, list);
} }
item = new ListItem(socket); item = new ListItem(socket);
list.push(item); 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) { HTTPBase.prototype.leaveChannel = function leaveChannel(socket, name) {
var list = this.channels[name]; var list = this.channels.get(name);
var item = socket.channels[name]; var item = socket.channels.get(name);
if (!item) if (!item)
return; return;
@ -684,9 +681,9 @@ HTTPBase.prototype.leaveChannel = function leaveChannel(socket, name) {
assert(list.remove(item)); assert(list.remove(item));
if (list.size === 0) 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) { HTTPBase.prototype.channel = function channel(name) {
var list = this.channels[name]; var list = this.channels.get(name);
if (!list) if (!list)
return; return;
@ -1558,7 +1555,7 @@ function WebSocket(socket, ctx) {
this.socket = socket; this.socket = socket;
this.remoteAddress = socket.conn.remoteAddress; this.remoteAddress = socket.conn.remoteAddress;
this.hooks = {}; this.hooks = {};
this.channels = {}; this.channels = new Map();
this.auth = false; this.auth = false;
this.filter = null; this.filter = null;
this.prev = null; this.prev = null;

View File

@ -67,7 +67,7 @@ function RPC(node) {
this.boundChain = false; this.boundChain = false;
this.nonce1 = 0; this.nonce1 = 0;
this.nonce2 = 0; this.nonce2 = 0;
this.merkleMap = {}; this.merkleMap = new Map();
this.pollers = []; this.pollers = [];
this.init(); this.init();
@ -225,16 +225,12 @@ RPC.prototype.stop = async function stop(args, help) {
RPC.prototype.getNetworkInfo = async function getNetworkInfo(args, help) { RPC.prototype.getNetworkInfo = async function getNetworkInfo(args, help) {
var hosts = this.pool.hosts; var hosts = this.pool.hosts;
var locals = []; var locals = [];
var i, keys, key, local; var local;
if (help || args.length !== 0) if (help || args.length !== 0)
throw new RPCError(errs.MISC_ERROR, 'getnetworkinfo'); throw new RPCError(errs.MISC_ERROR, 'getnetworkinfo');
keys = hosts.local.keys(); for (local of hosts.local.values()) {
for (i = 0; i < keys.length; i++) {
key = keys[i];
local = hosts.local.get(key);
locals.push({ locals.push({
address: local.addr.host, address: local.addr.host,
port: local.addr.port, port: local.addr.port,
@ -398,7 +394,7 @@ RPC.prototype.getPeerInfo = async function getPeerInfo(args, help) {
throw new RPCError(errs.MISC_ERROR, 'getpeerinfo'); throw new RPCError(errs.MISC_ERROR, 'getpeerinfo');
for (peer = this.pool.peers.head(); peer; peer = peer.next) { 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) if (offset == null)
offset = 0; offset = 0;
@ -475,17 +471,14 @@ RPC.prototype.setBan = async function setBan(args, help) {
}; };
RPC.prototype.listBanned = async function listBanned(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) if (help || args.length !== 0)
throw new RPCError(errs.MISC_ERROR, 'listbanned'); throw new RPCError(errs.MISC_ERROR, 'listbanned');
banned = []; banned = [];
keys = Object.keys(this.pool.hosts.banned);
for (i = 0; i < keys.length; i++) { for ([host, time] of this.pool.hosts.banned) {
host = keys[i];
time = this.pool.hosts.banned[host];
banned.push({ banned.push({
address: host, address: host,
banned_until: time + this.pool.options.banTime, 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.'); throw new RPCError(errs.MISC_ERROR, 'No mempool available.');
return { return {
size: this.mempool.totalTX, size: this.mempool.map.size,
bytes: this.mempool.getSize(), bytes: this.mempool.getSize(),
usage: this.mempool.getSize(), usage: this.mempool.getSize(),
maxmempool: this.mempool.options.maxSize, maxmempool: this.mempool.options.maxSize,
@ -814,7 +807,7 @@ RPC.prototype.getRawMempool = async function getRawMempool(args, help) {
var valid = new Validator([args]); var valid = new Validator([args]);
var verbose = valid.bool(0, false); var verbose = valid.bool(0, false);
var out = {}; var out = {};
var i, hashes, hash, entry; var entry, hashes;
if (help || args.length > 1) if (help || args.length > 1)
throw new RPCError(errs.MISC_ERROR, 'getrawmempool ( verbose )'); 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.'); throw new RPCError(errs.MISC_ERROR, 'No mempool available.');
if (verbose) { if (verbose) {
hashes = this.mempool.getSnapshot(); for (entry of this.mempool.map.values())
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
entry = this.mempool.getEntry(hash);
if (!entry)
continue;
out[entry.txid()] = this.entryToJSON(entry); out[entry.txid()] = this.entryToJSON(entry);
}
return out; return out;
} }
@ -1075,7 +1059,7 @@ RPC.prototype._submitWork = async function _submitWork(data) {
if (!header.verify()) if (!header.verify())
return false; return false;
nonces = this.merkleMap[header.merkleRoot]; nonces = this.merkleMap.get(header.merkleRoot);
if (!nonces) if (!nonces)
return false; return false;
@ -2291,7 +2275,7 @@ RPC.prototype.refreshBlock = function refreshBlock() {
this.attempt = null; this.attempt = null;
this.lastActivity = 0; this.lastActivity = 0;
this.merkleMap = {}; this.merkleMap.clear();
this.nonce1 = 0; this.nonce1 = 0;
this.nonce2 = 0; this.nonce2 = 0;
this.pollers = []; this.pollers = [];
@ -2370,7 +2354,7 @@ RPC.prototype.updateWork = async function updateWork() {
root = attempt.getRoot(n1, n2); root = attempt.getRoot(n1, n2);
root = root.toString('hex'); root = root.toString('hex');
this.merkleMap[root] = new Nonces(n1, n2); this.merkleMap.set(root, new Nonces(n1, n2));
return attempt; return attempt;
} }
@ -2390,7 +2374,7 @@ RPC.prototype.updateWork = async function updateWork() {
this.attempt = attempt; this.attempt = attempt;
this.lastActivity = util.now(); this.lastActivity = util.now();
this.merkleMap[root] = new Nonces(n1, n2); this.merkleMap.set(root, new Nonces(n1, n2));
return attempt; return attempt;
}; };
@ -2454,7 +2438,7 @@ RPC.prototype._addBlock = async function _addBlock(block) {
}; };
RPC.prototype.totalTX = function totalTX() { 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() { RPC.prototype.getSoftforks = function getSoftforks() {

View File

@ -104,7 +104,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
this.use(this.jsonRPC(this.rpc)); this.use(this.jsonRPC(this.rpc));
this.get('/', async function(req, res) { 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 size = this.mempool ? this.mempool.getSize() : 0;
var addr = this.pool.hosts.getLocal(); var addr = this.pool.hosts.getLocal();

View File

@ -15,7 +15,6 @@ var policy = require('../protocol/policy');
var BufferReader = require('../utils/reader'); var BufferReader = require('../utils/reader');
var StaticWriter = require('../utils/staticwriter'); var StaticWriter = require('../utils/staticwriter');
var encoding = require('../utils/encoding'); var encoding = require('../utils/encoding');
var Map = require('../utils/map');
var Logger = require('../node/logger'); var Logger = require('../node/logger');
/* /*
@ -490,7 +489,7 @@ PolicyEstimator.prototype.reset = function reset() {
this.priUnlikely = 0; this.priUnlikely = 0;
this.priLikely = INF_PRIORITY; this.priLikely = INF_PRIORITY;
this.map.reset(); this.map.clear();
this.bestHeight = 0; this.bestHeight = 0;
this.init(); this.init();
@ -511,7 +510,7 @@ PolicyEstimator.prototype.removeTX = function removeTX(hash) {
this.feeStats.removeTX(item.blockHeight, this.bestHeight, item.bucketIndex); this.feeStats.removeTX(item.blockHeight, this.bestHeight, item.bucketIndex);
this.map.remove(hash); this.map.delete(hash);
}; };
/** /**

View File

@ -26,7 +26,6 @@ var encoding = require('../utils/encoding');
var layout = require('./layout'); var layout = require('./layout');
var LDB = require('../db/ldb'); var LDB = require('../db/ldb');
var Fees = require('./fees'); var Fees = require('./fees');
var Map = require('../utils/map');
var CoinView = require('../coins/coinview'); var CoinView = require('../coins/coinview');
var Coins = require('../coins/coins'); var Coins = require('../coins/coins');
var Heap = require('../utils/heap'); var Heap = require('../utils/heap');
@ -51,7 +50,6 @@ var VerifyResult = errors.VerifyResult;
* @property {Boolean} loaded * @property {Boolean} loaded
* @property {Object} db * @property {Object} db
* @property {Number} size * @property {Number} size
* @property {Number} totalOrphans
* @property {Lock} locker * @property {Lock} locker
* @property {Number} freeCount * @property {Number} freeCount
* @property {Number} lastTime * @property {Number} lastTime
@ -82,17 +80,15 @@ function Mempool(options) {
this.cache = new MempoolCache(this.options); this.cache = new MempoolCache(this.options);
this.size = 0; this.size = 0;
this.totalOrphans = 0;
this.totalTX = 0;
this.freeCount = 0; this.freeCount = 0;
this.lastTime = 0; this.lastTime = 0;
this.lastFlush = 0; this.lastFlush = 0;
this.tip = this.network.genesis.hash; this.tip = this.network.genesis.hash;
this.waiting = {}; this.waiting = new Map();
this.orphans = {}; this.orphans = new Map();
this.map = {}; this.map = new Map();
this.spents = {}; this.spents = new Map();
this.rejects = new RollingFilter(120000, 0.000001); this.rejects = new RollingFilter(120000, 0.000001);
this.coinIndex = new CoinIndex(); this.coinIndex = new CoinIndex();
@ -196,7 +192,7 @@ Mempool.prototype.addBlock = async function addBlock(block, txs) {
Mempool.prototype._addBlock = async function addBlock(block, txs) { Mempool.prototype._addBlock = async function addBlock(block, txs) {
var i, entries, entry, tx, hash; var i, entries, entry, tx, hash;
if (this.totalTX === 0) { if (this.map.size === 0) {
this.tip = block.hash; this.tip = block.hash;
return; return;
} }
@ -277,7 +273,7 @@ Mempool.prototype._removeBlock = async function removeBlock(block, txs) {
var total = 0; var total = 0;
var i, tx, hash; var i, tx, hash;
if (this.totalTX === 0) { if (this.map.size === 0) {
this.tip = block.prevBlock; this.tip = block.prevBlock;
return; return;
} }
@ -337,16 +333,14 @@ Mempool.prototype.reset = async function reset() {
*/ */
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.size = 0;
this.totalOrphans = 0;
this.totalTX = 0;
this.waiting = {}; this.waiting.clear();
this.orphans = {}; this.orphans.clear();
this.map = {}; this.map.clear();
this.spents = {}; this.spents.clear();
this.coinIndex.reset(); this.coinIndex.reset();
this.txIndex.reset(); this.txIndex.reset();
@ -453,7 +447,7 @@ Mempool.prototype.limitSize = function limitSize(added) {
*/ */
Mempool.prototype.getTX = function getTX(hash) { Mempool.prototype.getTX = function getTX(hash) {
var entry = this.map[hash]; var entry = this.map.get(hash);
if (!entry) if (!entry)
return; return;
return entry.tx; return entry.tx;
@ -466,7 +460,7 @@ Mempool.prototype.getTX = function getTX(hash) {
*/ */
Mempool.prototype.getEntry = function getEntry(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) { Mempool.prototype.getCoin = function getCoin(hash, index) {
var entry = this.map[hash]; var entry = this.map.get(hash);
if (!entry) if (!entry)
return; return;
@ -503,7 +497,7 @@ Mempool.prototype.getCoin = function getCoin(hash, index) {
Mempool.prototype.isSpent = function isSpent(hash, index) { Mempool.prototype.isSpent = function isSpent(hash, index) {
var key = Outpoint.toKey(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) { Mempool.prototype.getSpent = function getSpent(hash, index) {
var key = Outpoint.toKey(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) { Mempool.prototype.getSpentTX = function getSpentTX(hash, index) {
var key = Outpoint.toKey(hash, index); var key = Outpoint.toKey(hash, index);
var entry = this.spents[key]; var entry = this.spents.get(key);
if (!entry) if (!entry)
return; return;
@ -633,7 +627,7 @@ Mempool.prototype.getMeta = function getMeta(hash) {
*/ */
Mempool.prototype.hasEntry = function hasEntry(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( this.logger.debug(
'Added %s to mempool (txs=%d).', 'Added %s to mempool (txs=%d).',
tx.txid(), this.totalTX); tx.txid(), this.map.size);
this.cache.save(entry); this.cache.save(entry);
@ -1406,20 +1400,14 @@ Mempool.prototype.hasDepends = function hasDepends(tx) {
*/ */
Mempool.prototype.getBalance = function getBalance() { Mempool.prototype.getBalance = function getBalance() {
var hashes = this.getSnapshot();
var total = 0; var total = 0;
var i, j, tx, hash, coin; var i, hash, entry, tx, coin;
for (i = 0; i < hashes.length; i++) { for ([hash, entry] of this.map) {
hash = hashes[i]; tx = entry.tx;
tx = this.getTX(hash);
assert(tx); for (i = 0; i < tx.outputs.length; i++) {
coin = this.getCoin(hash, i);
hash = tx.hash('hex');
for (j = 0; j < tx.outputs.length; j++) {
coin = this.getCoin(hash, j);
if (coin) if (coin)
total += coin.value; total += coin.value;
} }
@ -1434,18 +1422,11 @@ Mempool.prototype.getBalance = function getBalance() {
*/ */
Mempool.prototype.getHistory = function getHistory() { Mempool.prototype.getHistory = function getHistory() {
var hashes = this.getSnapshot();
var txs = []; var txs = [];
var i, hash, tx; var entry;
for (i = 0; i < hashes.length; i++) { for (entry of this.map.values())
hash = hashes[i]; txs.push(entry.tx);
tx = this.getTX(hash);
assert(tx);
txs.push(tx);
}
return txs; return txs;
}; };
@ -1457,7 +1438,7 @@ Mempool.prototype.getHistory = function getHistory() {
*/ */
Mempool.prototype.getOrphan = function getOrphan(hash) { 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) { 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++) { for (i = 0; i < missing.length; i++) {
prev = missing[i]; prev = missing[i];
if (!this.waiting[prev]) if (!this.waiting.has(prev))
this.waiting[prev] = new Map(); 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.orphans.set(hash, new Orphan(tx, missing.length, id));
this.totalOrphans++;
this.logger.debug('Added orphan %s to mempool.', tx.txid()); 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) { Mempool.prototype.resolveOrphans = function resolveOrphans(parent) {
var hash = parent.hash('hex'); var hash = parent.hash('hex');
var map = this.waiting[hash]; var set = this.waiting.get(hash);
var resolved = []; var resolved = [];
var i, hashes, orphanHash, orphan; var orphanHash, orphan;
if (!map) if (!set)
return resolved; return resolved;
hashes = map.keys(); assert(set.size > 0);
assert(hashes.length > 0);
for (i = 0; i < hashes.length; i++) { for (orphanHash of set.keys()) {
orphanHash = hashes[i];
orphan = this.getOrphan(orphanHash); orphan = this.getOrphan(orphanHash);
assert(orphan); assert(orphan);
if (--orphan.missing === 0) { if (--orphan.missing === 0) {
delete this.orphans[orphanHash]; this.orphans.delete(orphanHash);
this.totalOrphans--;
resolved.push(orphan); resolved.push(orphan);
} }
} }
delete this.waiting[hash]; this.waiting.delete(hash);
return resolved; return resolved;
}; };
@ -1614,7 +1591,7 @@ Mempool.prototype.resolveOrphans = function resolveOrphans(parent) {
Mempool.prototype.removeOrphan = function removeOrphan(hash) { Mempool.prototype.removeOrphan = function removeOrphan(hash) {
var orphan = this.getOrphan(hash); var orphan = this.getOrphan(hash);
var i, tx, map, prevout, prev; var i, tx, set, prevout, prev;
if (!orphan) if (!orphan)
return false; return false;
@ -1622,8 +1599,7 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
try { try {
tx = orphan.toTX(); tx = orphan.toTX();
} catch (e) { } catch (e) {
delete this.orphans[hash]; this.orphans.delete(hash);
this.totalOrphans--;
this.logger.warning('%s %s', this.logger.warning('%s %s',
'Warning: possible memory corruption.', 'Warning: possible memory corruption.',
'Orphan failed deserialization.'); 'Orphan failed deserialization.');
@ -1634,21 +1610,20 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
for (i = 0; i < prevout.length; i++) { for (i = 0; i < prevout.length; i++) {
prev = prevout[i]; prev = prevout[i];
map = this.waiting[prev]; set = this.waiting.get(prev);
if (!map) if (!set)
continue; continue;
assert(map.has(hash)); assert(set.has(hash));
map.remove(hash); set.delete(hash);
if (map.size === 0) if (set.size === 0)
delete this.waiting[prev]; this.waiting.delete(prev);
} }
delete this.orphans[hash]; this.orphans.delete(hash);
this.totalOrphans--;
this.emit('remove orphan', tx); this.emit('remove orphan', tx);
@ -1661,14 +1636,18 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
*/ */
Mempool.prototype.limitOrphans = function limitOrphans() { Mempool.prototype.limitOrphans = function limitOrphans() {
var hashes = Object.keys(this.orphans);
var index, hash; var index, hash;
if (this.totalOrphans < this.options.maxOrphans) if (this.orphans.size < this.options.maxOrphans)
return false; return false;
index = random.randomRange(0, hashes.length); index = random.randomRange(0, this.orphans.size);
hash = hashes[index];
for (hash of this.orphans.keys()) {
if (index === 0)
break;
index--;
}
this.logger.debug('Removing orphan %s from mempool.', util.revHex(hash)); 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() { 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 hash = tx.hash('hex');
var i, input, key; var i, input, key;
assert(!this.map[hash]); assert(!this.map.has(hash));
this.map[hash] = entry; this.map.set(hash, entry);
assert(!tx.isCoinbase()); assert(!tx.isCoinbase());
for (i = 0; i < tx.inputs.length; i++) { for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i]; input = tx.inputs[i];
key = input.prevout.toKey(); key = input.prevout.toKey();
this.spents[key] = entry; this.spents.set(key, entry);
} }
if (this.options.indexAddress && view) if (this.options.indexAddress && view)
this.indexEntry(entry, view); this.indexEntry(entry, view);
this.size += entry.memUsage(); this.size += entry.memUsage();
this.totalTX++;
}; };
/** /**
@ -1852,22 +1836,21 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) {
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var i, input, key; var i, input, key;
assert(this.map[hash]); assert(this.map.has(hash));
delete this.map[hash]; this.map.delete(hash);
assert(!tx.isCoinbase()); assert(!tx.isCoinbase());
for (i = 0; i < tx.inputs.length; i++) { for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i]; input = tx.inputs[i];
key = input.prevout.toKey(); key = input.prevout.toKey();
delete this.spents[key]; this.spents.delete(key);
} }
if (this.options.indexAddress) if (this.options.indexAddress)
this.unindexEntry(entry); this.unindexEntry(entry);
this.size -= entry.memUsage(); this.size -= entry.memUsage();
this.totalTX--;
}; };
/** /**
@ -2186,47 +2169,40 @@ MempoolOptions.fromOptions = function fromOptions(options) {
function TXIndex() { function TXIndex() {
// Map of addr->entries. // Map of addr->entries.
this.index = {}; this.index = new Map();
// Map of txid->addrs. // Map of txid->addrs.
this.map = {}; this.map = new Map();
} }
TXIndex.prototype.reset = function reset() { TXIndex.prototype.reset = function reset() {
this.index = {}; this.index.clear();
this.map = {}; this.map.clear();
}; };
TXIndex.prototype.get = function get(addr) { TXIndex.prototype.get = function get(addr) {
var items = this.index[addr]; var items = this.index.get(addr);
var out = []; var out = [];
var i, keys, entry; var entry;
if (!items) if (!items)
return out; return out;
keys = items.keys(); for (entry of items.values())
for (i = 0; i < keys.length; i++) {
entry = items.get(keys[i]);
out.push(entry.tx); out.push(entry.tx);
}
return out; return out;
}; };
TXIndex.prototype.getMeta = function getMeta(addr) { TXIndex.prototype.getMeta = function getMeta(addr) {
var items = this.index[addr]; var items = this.index.get(addr);
var out = []; var out = [];
var i, entry, keys, meta; var entry, meta;
if (!items) if (!items)
return out; return out;
keys = items.keys(); for (entry of items.values()) {
for (i = 0; i < keys.length; i++) {
entry = items.get(keys[i]);
meta = TXMeta.fromTX(entry.tx); meta = TXMeta.fromTX(entry.tx);
meta.ps = entry.ts; meta.ps = entry.ts;
out.push(meta); out.push(meta);
@ -2239,48 +2215,46 @@ TXIndex.prototype.insert = function insert(entry, view) {
var tx = entry.tx; var tx = entry.tx;
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var addrs = tx.getHashes(view, 'hex'); var addrs = tx.getHashes(view, 'hex');
var i, addr, items; var addr, items;
if (addrs.length === 0) if (addrs.length === 0)
return; return;
for (i = 0; i < addrs.length; i++) { for (addr of addrs) {
addr = addrs[i]; items = this.index.get(addr);
items = this.index[addr];
if (!items) { if (!items) {
items = new Map(); items = new Map();
this.index[addr] = items; this.index.set(addr, items);
} }
assert(!items.has(hash)); assert(!items.has(hash));
items.set(hash, entry); items.set(hash, entry);
} }
this.map[hash] = addrs; this.map.set(hash, addrs);
}; };
TXIndex.prototype.remove = function remove(hash) { TXIndex.prototype.remove = function remove(hash) {
var addrs = this.map[hash]; var addrs = this.map.get(hash);
var i, addr, items; var addr, items;
if (!addrs) if (!addrs)
return; return;
for (i = 0; i < addrs.length; i++) { for (addr of addrs) {
addr = addrs[i]; items = this.index.get(addr);
items = this.index[addr];
assert(items); assert(items);
assert(items.has(hash)); assert(items.has(hash));
items.remove(hash); items.delete(hash);
if (items.size === 0) 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() { function CoinIndex() {
// Map of addr->coins. // Map of addr->coins.
this.index = {}; this.index = new Map();
// Map of outpoint->addr. // Map of outpoint->addr.
this.map = {}; this.map = new Map();
} }
CoinIndex.prototype.reset = function reset() { CoinIndex.prototype.reset = function reset() {
this.index = {}; this.index.clear();
this.map = {}; this.map.clear();
}; };
CoinIndex.prototype.get = function get(addr) { CoinIndex.prototype.get = function get(addr) {
var items = this.index[addr]; var items = this.index.get(addr);
var out = []; var out = [];
var i, keys, coin; var coin;
if (!items) if (!items)
return out; return out;
keys = items.keys(); for (coin of items.values())
for (i = 0; i < keys.length; i++) {
coin = items.get(keys[i]);
assert(coin);
out.push(coin.toCoin()); out.push(coin.toCoin());
}
return out; return out;
}; };
@ -2330,11 +2299,11 @@ CoinIndex.prototype.insert = function insert(tx, index) {
if (!addr) if (!addr)
return; return;
items = this.index[addr]; items = this.index.get(addr);
if (!items) { if (!items) {
items = new Map(); items = new Map();
this.index[addr] = items; this.index.set(addr, items);
} }
key = Outpoint.toKey(hash, index); key = Outpoint.toKey(hash, index);
@ -2342,27 +2311,27 @@ CoinIndex.prototype.insert = function insert(tx, index) {
assert(!items.has(key)); assert(!items.has(key));
items.set(key, new IndexedCoin(tx, index)); items.set(key, new IndexedCoin(tx, index));
this.map[key] = addr; this.map.set(key, addr);
}; };
CoinIndex.prototype.remove = function remove(hash, index) { CoinIndex.prototype.remove = function remove(hash, index) {
var key = Outpoint.toKey(hash, index); var key = Outpoint.toKey(hash, index);
var addr = this.map[key]; var addr = this.map.get(key);
var items; var items;
if (!addr) if (!addr)
return; return;
items = this.index[addr]; items = this.index.get(addr);
assert(items); assert(items);
assert(items.has(key)); assert(items.has(key));
items.remove(key); items.remove(key);
if (items.size === 0) if (items.size === 0)
delete this.index[addr]; this.index.delete(addr);
delete this.map[key]; this.map.delete(key);
}; };
/** /**

View File

@ -258,8 +258,8 @@ Miner.prototype.assemble = function assemble(attempt) {
var depMap = {}; var depMap = {};
var queue = new Heap(cmpRate); var queue = new Heap(cmpRate);
var priority = this.options.priorityWeight > 0; var priority = this.options.priorityWeight > 0;
var i, j, entry, item, tx, hash, input; var i, entry, item, tx, hash, input;
var prev, deps, hashes, weight, sigops, block; var prev, deps, weight, sigops, block;
if (priority) if (priority)
queue.set(cmpPriority); queue.set(cmpPriority);
@ -272,19 +272,15 @@ Miner.prototype.assemble = function assemble(attempt) {
assert(this.mempool.tip === this.chain.tip.hash, assert(this.mempool.tip === this.chain.tip.hash,
'Mempool/chain tip mismatch! Unsafe to create block.'); 'Mempool/chain tip mismatch! Unsafe to create block.');
hashes = this.mempool.getSnapshot(); for (entry of this.mempool.map.values()) {
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
entry = this.mempool.getEntry(hash);
item = BlockEntry.fromEntry(entry, attempt); item = BlockEntry.fromEntry(entry, attempt);
tx = item.tx; tx = item.tx;
if (tx.isCoinbase()) if (tx.isCoinbase())
throw new Error('Cannot add coinbase to block.'); throw new Error('Cannot add coinbase to block.');
for (j = 0; j < tx.inputs.length; j++) { for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[j]; input = tx.inputs[i];
prev = input.prevout.hash; prev = input.prevout.hash;
if (!this.mempool.hasEntry(prev)) if (!this.mempool.hasEntry(prev))
@ -351,8 +347,8 @@ Miner.prototype.assemble = function assemble(attempt) {
if (!deps) if (!deps)
continue; continue;
for (j = 0; j < deps.length; j++) { for (i = 0; i < deps.length; i++) {
item = deps[j]; item = deps[i];
if (--item.depCount === 0) if (--item.depCount === 0)
queue.insert(item); queue.insert(item);
} }

View File

@ -311,16 +311,13 @@ CompactBlock.prototype.toRequest = function toRequest() {
CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) { CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
var have = {}; var have = {};
var hashes = mempool.getSnapshot(); var id, index, hash, entry, tx;
var i, id, index, hash, tx;
if (this.count === this.totalTX) if (this.count === this.totalTX)
return true; return true;
for (i = 0; i < hashes.length; i++) { for (entry of mempool.map.values()) {
hash = hashes[i]; tx = entry.tx;
tx = mempool.getTX(hash);
assert(tx);
hash = tx.hash(); hash = tx.hash();
if (witness) if (witness)

View File

@ -15,7 +15,6 @@ var Network = require('../protocol/network');
var NetAddress = require('../primitives/netaddress'); 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 Map = require('../utils/map');
var common = require('./common'); var common = require('./common');
var seeds = require('./seeds'); var seeds = require('./seeds');
var dns = require('./dns'); var dns = require('./dns');
@ -42,14 +41,14 @@ function HostList(options) {
this.dnsSeeds = []; this.dnsSeeds = [];
this.dnsNodes = []; this.dnsNodes = [];
this.map = {}; this.map = new Map();
this.fresh = []; this.fresh = [];
this.totalFresh = 0; this.totalFresh = 0;
this.used = []; this.used = [];
this.totalUsed = 0; this.totalUsed = 0;
this.nodes = []; this.nodes = [];
this.local = new Map(); this.local = new Map();
this.banned = {}; this.banned = new Map();
this.timer = null; this.timer = null;
this.needsFlush = false; this.needsFlush = false;
@ -152,10 +151,8 @@ HostList.prototype._init = function init() {
this.pushLocal(this.address, scores.MANUAL); this.pushLocal(this.address, scores.MANUAL);
this.addLocal(options.host, options.port, scores.BIND); this.addLocal(options.host, options.port, scores.BIND);
for (i = 0; i < hosts.length; i++) { for (host of hosts)
host = hosts[i];
this.addLocal(host, port, scores.IF); this.addLocal(host, port, scores.IF);
}
}; };
/** /**
@ -231,10 +228,9 @@ HostList.prototype.stop = function stop() {
HostList.prototype.injectSeeds = function injectSeeds() { HostList.prototype.injectSeeds = function injectSeeds() {
var nodes = seeds.get(this.network.type); var nodes = seeds.get(this.network.type);
var i, node, addr; var node, addr;
for (i = 0; i < nodes.length; i++) { for (node of nodes) {
node = nodes[i];
addr = NetAddress.fromHostname(node, this.network); addr = NetAddress.fromHostname(node, this.network);
if (!addr.isRoutable()) if (!addr.isRoutable())
@ -343,19 +339,15 @@ HostList.prototype.isFull = function isFull() {
*/ */
HostList.prototype.reset = function reset() { HostList.prototype.reset = function reset() {
var i, bucket; var bucket;
this.map = {}; this.map.clear();
for (i = 0; i < this.fresh.length; i++) { for (bucket of this.fresh)
bucket = this.fresh[i]; bucket.clear();
for (bucket of this.used)
bucket.reset(); bucket.reset();
}
for (i = 0; i < this.used.length; i++) {
bucket = this.used[i];
bucket.reset();
}
this.totalFresh = 0; this.totalFresh = 0;
this.totalUsed = 0; this.totalUsed = 0;
@ -369,7 +361,7 @@ HostList.prototype.reset = function reset() {
*/ */
HostList.prototype.ban = function ban(host) { 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) { 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() { 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) { HostList.prototype.isBanned = function isBanned(host) {
var time = this.banned[host]; var time = this.banned.get(host);
if (time == null) if (time == null)
return false; return false;
if (util.now() > time + this.options.banTime) { if (util.now() > time + this.options.banTime) {
delete this.banned[host]; this.banned.delete(host);
return false; return false;
} }
@ -418,7 +410,7 @@ HostList.prototype.getHost = function getHost() {
var now = this.network.now(); var now = this.network.now();
var buckets = null; var buckets = null;
var factor = 1; var factor = 1;
var index, key, bucket, entry, num; var index, bucket, entry, num;
if (this.totalFresh > 0) if (this.totalFresh > 0)
buckets = this.fresh; buckets = this.fresh;
@ -445,8 +437,11 @@ HostList.prototype.getHost = function getHost() {
while (index--) while (index--)
entry = entry.next; entry = entry.next;
} else { } else {
key = bucket.keys()[index]; for (entry of bucket.values()) {
entry = bucket.get(key); if (index === 0)
break;
index--;
}
} }
num = util.random(0, 1 << 30); num = util.random(0, 1 << 30);
@ -507,7 +502,7 @@ HostList.prototype.add = function add(addr, src) {
assert(addr.port !== 0); assert(addr.port !== 0);
entry = this.map[addr.hostname]; entry = this.map.get(addr.hostname);
if (entry) { if (entry) {
// No source means we're inserting // No source means we're inserting
@ -578,7 +573,7 @@ HostList.prototype.add = function add(addr, src) {
bucket.set(entry.key(), entry); bucket.set(entry.key(), entry);
entry.refCount++; entry.refCount++;
this.map[entry.key()] = entry; this.map.set(entry.key(), entry);
this.needsFlush = true; this.needsFlush = true;
return true; return true;
@ -590,18 +585,14 @@ HostList.prototype.add = function add(addr, src) {
*/ */
HostList.prototype.evictFresh = function evictFresh(bucket) { HostList.prototype.evictFresh = function evictFresh(bucket) {
var keys = bucket.keys(); var entry, old;
var i, key, entry, old;
for (i = 0; i < keys.length; i++) {
key = keys[i];
entry = bucket.get(key);
for (entry of bucket.values()) {
if (this.isStale(entry)) { if (this.isStale(entry)) {
bucket.remove(entry.key()); bucket.delete(entry.key());
if (--entry.refCount === 0) { if (--entry.refCount === 0) {
delete this.map[entry.key()]; this.map.delete(entry.key());
this.totalFresh--; this.totalFresh--;
} }
@ -620,10 +611,10 @@ HostList.prototype.evictFresh = function evictFresh(bucket) {
if (!old) if (!old)
return; return;
bucket.remove(old.key()); bucket.delete(old.key());
if (--old.refCount === 0) { if (--old.refCount === 0) {
delete this.map[old.key()]; this.map.delete(old.key());
this.totalFresh--; this.totalFresh--;
} }
}; };
@ -667,7 +658,7 @@ HostList.prototype.isStale = function isStale(entry) {
*/ */
HostList.prototype.remove = function remove(hostname) { HostList.prototype.remove = function remove(hostname) {
var entry = this.map[hostname]; var entry = this.map.get(hostname);
var i, head, bucket; var i, head, bucket;
if (!entry) if (!entry)
@ -680,8 +671,7 @@ HostList.prototype.remove = function remove(hostname) {
while (head.prev) while (head.prev)
head = head.prev; head = head.prev;
for (i = 0; i < this.used.length; i++) { for (bucket of this.used) {
bucket = this.used[i];
if (bucket.head === head) { if (bucket.head === head) {
bucket.remove(entry); bucket.remove(entry);
this.totalUsed--; this.totalUsed--;
@ -691,9 +681,8 @@ HostList.prototype.remove = function remove(hostname) {
assert(i < this.used.length); assert(i < this.used.length);
} else { } else {
for (i = 0; i < this.fresh.length; i++) { for (bucket of this.fresh) {
bucket = this.fresh[i]; if (bucket.delete(entry.key()))
if (bucket.remove(entry.key()))
entry.refCount--; entry.refCount--;
} }
@ -701,7 +690,7 @@ HostList.prototype.remove = function remove(hostname) {
assert(entry.refCount === 0); assert(entry.refCount === 0);
} }
delete this.map[entry.key()]; this.map.delete(entry.key());
return entry.addr; return entry.addr;
}; };
@ -712,7 +701,7 @@ HostList.prototype.remove = function remove(hostname) {
*/ */
HostList.prototype.markAttempt = function markAttempt(hostname) { HostList.prototype.markAttempt = function markAttempt(hostname) {
var entry = this.map[hostname]; var entry = this.map.get(hostname);
var now = this.network.now(); var now = this.network.now();
if (!entry) if (!entry)
@ -728,7 +717,7 @@ HostList.prototype.markAttempt = function markAttempt(hostname) {
*/ */
HostList.prototype.markSuccess = function markSuccess(hostname) { HostList.prototype.markSuccess = function markSuccess(hostname) {
var entry = this.map[hostname]; var entry = this.map.get(hostname);
var now = this.network.now(); var now = this.network.now();
if (!entry) if (!entry)
@ -745,9 +734,9 @@ HostList.prototype.markSuccess = function markSuccess(hostname) {
*/ */
HostList.prototype.markAck = function markAck(hostname, services) { HostList.prototype.markAck = function markAck(hostname, services) {
var entry = this.map[hostname]; var entry = this.map.get(hostname);
var now = this.network.now(); var now = this.network.now();
var i, bucket, evicted, old, fresh; var bucket, evicted, old, fresh;
if (!entry) if (!entry)
return; return;
@ -765,9 +754,8 @@ HostList.prototype.markAck = function markAck(hostname, services) {
assert(entry.refCount > 0); assert(entry.refCount > 0);
// Remove from fresh. // Remove from fresh.
for (i = 0; i < this.fresh.length; i++) { for (bucket of this.fresh) {
bucket = this.fresh[i]; if (bucket.delete(entry.key())) {
if (bucket.remove(entry.key())) {
entry.refCount--; entry.refCount--;
old = bucket; old = bucket;
} }
@ -830,15 +818,11 @@ HostList.prototype.evictUsed = function evictUsed(bucket) {
*/ */
HostList.prototype.toArray = function toArray() { HostList.prototype.toArray = function toArray() {
var keys = Object.keys(this.map);
var out = []; var out = [];
var i, key, entry; var entry;
for (i = 0; i < keys.length; i++) { for (entry of this.map.values())
key = keys[i];
entry = this.map[key];
out.push(entry.addr); out.push(entry.addr);
}
assert.equal(out.length, this.size()); assert.equal(out.length, this.size());
@ -993,21 +977,18 @@ HostList.prototype.pushLocal = function pushLocal(addr, score) {
*/ */
HostList.prototype.getLocal = function getLocal(src) { HostList.prototype.getLocal = function getLocal(src) {
var keys = this.local.keys();
var bestReach = -1; var bestReach = -1;
var bestScore = -1; var bestScore = -1;
var bestDest = null; var bestDest = null;
var i, key, dest, reach; var dest, reach;
if (!src) if (!src)
src = this.address; src = this.address;
if (keys.length === 0) if (this.local.length === 0)
return null; return null;
for (i = 0; i < keys.length; i++) { for (dest of this.local.values()) {
key = keys[i];
dest = this.local.get(key);
reach = src.getReachability(dest.addr); reach = src.getReachability(dest.addr);
if (reach < bestReach) if (reach < bestReach)
@ -1121,7 +1102,7 @@ HostList.prototype.populateSeed = async function populateSeed(seed) {
HostList.prototype.populate = async function populate(target) { HostList.prototype.populate = async function populate(target) {
var addrs = []; var addrs = [];
var i, addr, hosts, host; var addr, hosts, host;
assert(target.type === IP.types.DNS, 'Resolved host passed.'); assert(target.type === IP.types.DNS, 'Resolved host passed.');
@ -1134,8 +1115,7 @@ HostList.prototype.populate = async function populate(target) {
return addrs; return addrs;
} }
for (i = 0; i < hosts.length; i++) { for (host of hosts) {
host = hosts[i];
addr = NetAddress.fromHost(host, target.port, this.network); addr = NetAddress.fromHost(host, target.port, this.network);
addrs.push(addr); addrs.push(addr);
} }
@ -1152,24 +1132,19 @@ HostList.prototype.toJSON = function toJSON() {
var addrs = []; var addrs = [];
var fresh = []; var fresh = [];
var used = []; var used = [];
var i, keys, key, bucket, entry; var bucket, entry, key, keys;
keys = Object.keys(this.map); for (entry of this.map.values())
for (i = 0; i < keys.length; i++) {
key = keys[i];
entry = this.map[key];
addrs.push(entry.toJSON()); addrs.push(entry.toJSON());
}
for (i = 0; i < this.fresh.length; i++) { for (bucket of this.fresh) {
bucket = this.fresh[i]; keys = [];
keys = bucket.keys(); for (key of bucket.keys())
keys.push(key);
fresh.push(keys); fresh.push(keys);
} }
for (i = 0; i < this.used.length; i++) { for (bucket of this.used) {
bucket = this.used[i];
keys = []; keys = [];
for (entry = bucket.head; entry; entry = entry.next) for (entry = bucket.head; entry; entry = entry.next)
keys.push(entry.key()); keys.push(entry.key());
@ -1193,12 +1168,12 @@ HostList.prototype.toJSON = function toJSON() {
HostList.prototype.fromJSON = function fromJSON(json) { HostList.prototype.fromJSON = function fromJSON(json) {
var sources = {}; var sources = {};
var map = {}; var map = new Map();
var fresh = []; var fresh = [];
var totalFresh = 0; var totalFresh = 0;
var used = []; var used = [];
var totalUsed = 0; 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'); assert(json && typeof json === 'object');
@ -1207,8 +1182,7 @@ HostList.prototype.fromJSON = function fromJSON(json) {
assert(Array.isArray(json.addrs)); assert(Array.isArray(json.addrs));
for (i = 0; i < json.addrs.length; i++) { for (addr of json.addrs) {
addr = json.addrs[i];
entry = HostEntry.fromJSON(addr, this.network); entry = HostEntry.fromJSON(addr, this.network);
src = sources[entry.src.hostname]; src = sources[entry.src.hostname];
@ -1220,20 +1194,18 @@ HostList.prototype.fromJSON = function fromJSON(json) {
entry.src = src; entry.src = src;
map[entry.key()] = entry; map.set(entry.key(), entry);
} }
assert(Array.isArray(json.fresh)); assert(Array.isArray(json.fresh));
assert(json.fresh.length <= this.options.maxBuckets, assert(json.fresh.length <= this.options.maxBuckets,
'Buckets mismatch.'); 'Buckets mismatch.');
for (i = 0; i < json.fresh.length; i++) { for (keys of json.fresh) {
keys = json.fresh[i];
bucket = new Map(); bucket = new Map();
for (j = 0; j < keys.length; j++) { for (key of keys) {
key = keys[j]; entry = map.get(key);
entry = map[key];
assert(entry); assert(entry);
if (entry.refCount === 0) if (entry.refCount === 0)
totalFresh++; totalFresh++;
@ -1258,9 +1230,8 @@ HostList.prototype.fromJSON = function fromJSON(json) {
keys = json.used[i]; keys = json.used[i];
bucket = new List(); bucket = new List();
for (j = 0; j < keys.length; j++) { for (key of keys) {
key = keys[j]; entry = map.get(key);
entry = map[key];
assert(entry); assert(entry);
assert(entry.refCount === 0); assert(entry.refCount === 0);
assert(!entry.used); assert(!entry.used);
@ -1278,13 +1249,8 @@ HostList.prototype.fromJSON = function fromJSON(json) {
assert(used.length === this.used.length, assert(used.length === this.used.length,
'Buckets mismatch.'); 'Buckets mismatch.');
keys = Object.keys(map); for (entry of map.values())
for (i = 0; i < keys.length; i++) {
key = keys[i];
entry = map[key];
assert(entry.used || entry.refCount > 0); assert(entry.used || entry.refCount > 0);
}
this.map = map; this.map = map;
this.fresh = fresh; this.fresh = fresh;

View File

@ -11,7 +11,6 @@ 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');
@ -1053,7 +1052,7 @@ Peer.prototype.sendFeeRate = function sendFeeRate(rate) {
Peer.prototype.destroy = function destroy() { Peer.prototype.destroy = function destroy() {
var connected = this.connected; var connected = this.connected;
var i, keys, cmd, entry, jobs, job; var i, cmd, entry, jobs, job;
if (this.destroyed) if (this.destroyed)
return; return;
@ -1100,12 +1099,8 @@ Peer.prototype.destroy = function destroy() {
job.reject(new Error('Peer was destroyed.')); job.reject(new Error('Peer was destroyed.'));
} }
keys = this.responseMap.keys(); for ([cmd, entry] of this.responseMap) {
this.responseMap.delete(cmd);
for (i = 0; i < keys.length; i++) {
cmd = keys[i];
entry = this.responseMap.get(cmd);
this.responseMap.remove(cmd);
entry.reject(new Error('Peer was destroyed.')); entry.reject(new Error('Peer was destroyed.'));
} }
@ -1288,13 +1283,10 @@ Peer.prototype.fulfill = function fulfill(packet) {
*/ */
Peer.prototype.maybeTimeout = function maybeTimeout() { Peer.prototype.maybeTimeout = function maybeTimeout() {
var keys = this.responseMap.keys();
var now = util.ms(); 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++) { for ([key, entry] of this.responseMap) {
key = keys[i];
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());
@ -1321,11 +1313,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
} }
if (this.options.isFull() || !this.syncing) { if (this.options.isFull() || !this.syncing) {
keys = this.blockMap.keys(); for (ts of this.blockMap.values()) {
for (i = 0; i < keys.length; i++) {
key = keys[i];
ts = this.blockMap.get(key);
if (now > ts + Peer.BLOCK_TIMEOUT) { if (now > ts + Peer.BLOCK_TIMEOUT) {
this.error('Peer is stalling (block).'); this.error('Peer is stalling (block).');
this.destroy(); this.destroy();
@ -1333,11 +1321,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
} }
} }
keys = this.txMap.keys(); for (ts of this.txMap.values()) {
for (i = 0; i < keys.length; i++) {
key = keys[i];
ts = this.txMap.get(key);
if (now > ts + Peer.TX_TIMEOUT) { if (now > ts + Peer.TX_TIMEOUT) {
this.error('Peer is stalling (tx).'); this.error('Peer is stalling (tx).');
this.destroy(); this.destroy();
@ -1345,11 +1329,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
} }
} }
keys = this.compactBlocks.keys(); for (block of this.compactBlocks.values()) {
for (i = 0; i < keys.length; i++) {
key = keys[i];
block = this.compactBlocks.get(key);
if (now > block.now + Peer.RESPONSE_TIMEOUT) { if (now > block.now + Peer.RESPONSE_TIMEOUT) {
this.error('Peer is stalling (blocktxn).'); this.error('Peer is stalling (blocktxn).');
this.destroy(); this.destroy();
@ -1426,7 +1406,7 @@ Peer.prototype.response = function response(type, payload) {
if (!entry) if (!entry)
return; return;
this.responseMap.remove(type); this.responseMap.delete(type);
return entry; return entry;
}; };

View File

@ -32,7 +32,6 @@ var dns = require('./dns');
var HostList = require('./hostlist'); var HostList = require('./hostlist');
var UPNP = require('./upnp'); var UPNP = require('./upnp');
var InvItem = require('../primitives/invitem'); var InvItem = require('../primitives/invitem');
var Map = require('../utils/map');
var packets = require('./packets'); var packets = require('./packets');
var services = common.services; var services = common.services;
var invTypes = InvItem.types; var invTypes = InvItem.types;
@ -94,9 +93,9 @@ function Pool(options) {
this.syncing = false; this.syncing = false;
this.spvFilter = null; this.spvFilter = null;
this.txFilter = null; this.txFilter = null;
this.blockMap = new Map(); this.blockMap = new Set();
this.txMap = new Map(); this.txMap = new Set();
this.compactBlocks = new Map(); this.compactBlocks = new Set();
this.invMap = new Map(); this.invMap = new Map();
this.pendingFilter = null; this.pendingFilter = null;
this.pendingRefill = null; this.pendingRefill = null;
@ -345,7 +344,7 @@ Pool.prototype.disconnect = async function disconnect() {
*/ */
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.'); assert(this.loaded, 'Pool is not loaded.');
@ -354,18 +353,13 @@ Pool.prototype._disconnect = async function disconnect() {
this.disconnecting = true; this.disconnecting = true;
hashes = this.invMap.keys(); for (item of this.invMap.values())
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
item = this.invMap.get(hash);
item.resolve(); item.resolve();
}
this.peers.destroy(); this.peers.destroy();
this.blockMap.reset(); this.blockMap.clear();
this.txMap.reset(); this.txMap.clear();
if (this.pendingFilter != null) { if (this.pendingFilter != null) {
clearTimeout(this.pendingFilter); clearTimeout(this.pendingFilter);
@ -761,11 +755,11 @@ Pool.prototype.stopSync = function stopSync() {
peer.merkleMap = null; peer.merkleMap = null;
peer.blockTime = -1; peer.blockTime = -1;
peer.blockMap.reset(); peer.blockMap.reset();
peer.compactBlocks.reset(); peer.compactBlocks.clear();
} }
this.blockMap.reset(); this.blockMap.clear();
this.compactBlocks.reset(); this.compactBlocks.clear();
}; };
/** /**
@ -986,13 +980,9 @@ Pool.prototype.getNextTip = function getNextTip(height) {
Pool.prototype.announceList = function announceList(peer) { Pool.prototype.announceList = function announceList(peer) {
var blocks = []; var blocks = [];
var txs = []; var txs = [];
var hashes = this.invMap.keys(); var item;
var i, hash, item;
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
item = this.invMap.get(hash);
for (item of this.invMap.values()) {
switch (item.type) { switch (item.type) {
case invTypes.BLOCK: case invTypes.BLOCK:
blocks.push(item.msg); blocks.push(item.msg);
@ -2481,7 +2471,7 @@ Pool.prototype.logStatus = function logStatus(block) {
util.date(block.ts), util.date(block.ts),
this.chain.height, this.chain.height,
(this.chain.getProgress() * 100).toFixed(2) + '%', (this.chain.getProgress() * 100).toFixed(2) + '%',
this.chain.orphanCount, this.chain.orphanMap.size,
this.blockMap.size, this.blockMap.size,
block.bits, block.bits,
this.peers.size()); this.peers.size());
@ -2543,7 +2533,7 @@ Pool.prototype._handleTX = async function handleTX(peer, packet) {
return; return;
} }
peer.merkleMap.insert(hash); peer.merkleMap.add(hash);
block.addTX(tx); block.addTX(tx);
@ -2776,7 +2766,7 @@ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packe
peer.merkleBlock = block; peer.merkleBlock = block;
peer.merkleTime = util.ms(); peer.merkleTime = util.ms();
peer.merkleMatches = block.tree.matches.length; 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()); peer.blockMap.set(hash, util.ms());
assert(!this.blockMap.has(hash)); assert(!this.blockMap.has(hash));
this.blockMap.insert(hash); this.blockMap.add(hash);
} }
if (!this.mempool) { if (!this.mempool) {
@ -2919,7 +2909,7 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet)
assert(!peer.compactBlocks.has(hash)); assert(!peer.compactBlocks.has(hash));
peer.compactBlocks.set(hash, block); peer.compactBlocks.set(hash, block);
this.compactBlocks.insert(hash); this.compactBlocks.add(hash);
this.logger.debug( this.logger.debug(
'Received non-full compact block %s tx=%d/%d (%s).', 'Received non-full compact block %s tx=%d/%d (%s).',
@ -3000,10 +2990,10 @@ Pool.prototype.handleBlockTxn = async function handleBlockTxn(peer, packet) {
return; return;
} }
peer.compactBlocks.remove(res.hash); peer.compactBlocks.delete(res.hash);
assert(this.compactBlocks.has(res.hash)); assert(this.compactBlocks.has(res.hash));
this.compactBlocks.remove(res.hash); this.compactBlocks.delete(res.hash);
if (!block.fillMissing(res)) { if (!block.fillMissing(res)) {
this.logger.warning( this.logger.warning(
@ -3248,33 +3238,22 @@ Pool.prototype.refill = function refill() {
*/ */
Pool.prototype.removePeer = function removePeer(peer) { Pool.prototype.removePeer = function removePeer(peer) {
var i, hashes, hash; var hash;
this.peers.remove(peer); this.peers.remove(peer);
hashes = peer.blockMap.keys(); for (hash of peer.blockMap.keys())
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
this.resolveBlock(peer, hash); this.resolveBlock(peer, hash);
}
hashes = peer.txMap.keys(); for (hash of peer.txMap.keys())
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
this.resolveTX(peer, hash); this.resolveTX(peer, hash);
}
hashes = peer.compactBlocks.keys(); for (hash of peer.compactBlocks.keys()) {
for (i = 0; i < hashes.length; i++) {
hash = hashes[i];
assert(this.compactBlocks.has(hash)); 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)) if (this.blockMap.has(hash))
continue; continue;
this.blockMap.insert(hash); this.blockMap.add(hash);
peer.blockMap.set(hash, now); peer.blockMap.set(hash, now);
if (this.chain.synced) if (this.chain.synced)
@ -3516,7 +3495,7 @@ Pool.prototype.getTX = function getTX(peer, hashes) {
if (this.txMap.has(hash)) if (this.txMap.has(hash))
continue; continue;
this.txMap.insert(hash); this.txMap.add(hash);
peer.txMap.set(hash, now); peer.txMap.set(hash, now);
now += 50; now += 50;
@ -3620,10 +3599,10 @@ Pool.prototype.resolveTX = function resolveTX(peer, hash) {
if (!peer.txMap.has(hash)) if (!peer.txMap.has(hash))
return false; return false;
peer.txMap.remove(hash); peer.txMap.delete(hash);
assert(this.txMap.has(hash)); assert(this.txMap.has(hash));
this.txMap.remove(hash); this.txMap.delete(hash);
return true; return true;
}; };
@ -3639,10 +3618,10 @@ Pool.prototype.resolveBlock = function resolveBlock(peer, hash) {
if (!peer.blockMap.has(hash)) if (!peer.blockMap.has(hash))
return false; return false;
peer.blockMap.remove(hash); peer.blockMap.delete(hash);
assert(this.blockMap.has(hash)); assert(this.blockMap.has(hash));
this.blockMap.remove(hash); this.blockMap.delete(hash);
return true; return true;
}; };
@ -4168,8 +4147,8 @@ PoolOptions.prototype._resolve = function resolve(name) {
*/ */
function PeerList() { function PeerList() {
this.map = {}; this.map = new Map();
this.ids = {}; this.ids = new Map();
this.list = new List(); this.list = new List();
this.load = null; this.load = null;
this.inbound = 0; this.inbound = 0;
@ -4211,11 +4190,11 @@ PeerList.prototype.size = function size() {
PeerList.prototype.add = function add(peer) { PeerList.prototype.add = function add(peer) {
assert(this.list.push(peer)); assert(this.list.push(peer));
assert(!this.map[peer.hostname()]); assert(!this.map.has(peer.hostname()));
this.map[peer.hostname()] = peer; this.map.set(peer.hostname(), peer);
assert(!this.ids[peer.id]); assert(!this.ids.has(peer.id));
this.ids[peer.id] = peer; this.ids.set(peer.id, peer);
if (peer.outbound) if (peer.outbound)
this.outbound++; this.outbound++;
@ -4231,11 +4210,11 @@ PeerList.prototype.add = function add(peer) {
PeerList.prototype.remove = function remove(peer) { PeerList.prototype.remove = function remove(peer) {
assert(this.list.remove(peer)); assert(this.list.remove(peer));
assert(this.ids[peer.id]); assert(this.ids.has(peer.id));
delete this.ids[peer.id]; this.ids.delete(peer.id);
assert(this.map[peer.hostname()]); assert(this.map.has(peer.hostname()));
delete this.map[peer.hostname()]; this.map.delete(peer.hostname());
if (peer === this.load) { if (peer === this.load) {
assert(peer.loader); assert(peer.loader);
@ -4256,7 +4235,7 @@ PeerList.prototype.remove = function remove(peer) {
*/ */
PeerList.prototype.get = function get(hostname) { 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) { 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) { 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); clearTimeout(this.timeout);
this.timeout = null; 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() { function NonceList() {
this.map = {}; this.map = new Map();
this.hosts = {}; this.hosts = new Map();
} }
NonceList.prototype.alloc = function alloc(hostname) { NonceList.prototype.alloc = function alloc(hostname) {
@ -4500,10 +4479,10 @@ NonceList.prototype.alloc = function alloc(hostname) {
for (;;) { for (;;) {
nonce = util.nonce(); nonce = util.nonce();
key = nonce.toString('hex'); key = nonce.toString('hex');
if (!this.map[key]) { if (!this.map.has(key)) {
this.map[key] = hostname; this.map.set(key, hostname);
assert(!this.hosts[hostname]); assert(!this.hosts.has(hostname));
this.hosts[hostname] = key; this.hosts.set(hostname, key);
break; break;
} }
} }
@ -4513,19 +4492,19 @@ NonceList.prototype.alloc = function alloc(hostname) {
NonceList.prototype.has = function has(nonce) { NonceList.prototype.has = function has(nonce) {
var key = nonce.toString('hex'); var key = nonce.toString('hex');
return this.map[key] != null; return this.map.has(key);
}; };
NonceList.prototype.remove = function remove(hostname) { NonceList.prototype.remove = function remove(hostname) {
var key = this.hosts[hostname]; var key = this.hosts.get(hostname);
if (!key) if (!key)
return false; return false;
delete this.hosts[hostname]; this.hosts.delete(hostname);
assert(this.map[key]); assert(this.map.has(key));
delete this.map[key]; this.map.delete(key);
return true; return true;
}; };

View File

@ -34,7 +34,7 @@ function TimeData(limit) {
limit = 200; limit = 200;
this.samples = []; this.samples = [];
this.known = {}; this.known = new Map();
this.limit = limit; this.limit = limit;
this.offset = 0; this.offset = 0;
this._checked = false; this._checked = false;
@ -55,10 +55,10 @@ TimeData.prototype.add = function add(id, time) {
if (this.samples.length >= this.limit) if (this.samples.length >= this.limit)
return; return;
if (this.known[id] != null) if (this.known.has(id))
return; return;
this.known[id] = sample; this.known.set(id, sample);
util.binaryInsert(this.samples, sample, compare); util.binaryInsert(this.samples, sample, compare);

View File

@ -32,7 +32,7 @@ function SigCache(size) {
this.size = size; this.size = size;
this.keys = []; this.keys = [];
this.valid = {}; this.valid = new Map();
} }
/** /**
@ -46,7 +46,7 @@ SigCache.prototype.resize = function resize(size) {
this.size = size; this.size = size;
this.keys.length = 0; 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) if (this.size === 0)
return; return;
this.valid[hash] = new SigCacheEntry(sig, key); this.valid.set(hash, new SigCacheEntry(sig, key));
if (this.keys.length >= this.size) { if (this.keys.length >= this.size) {
i = Math.floor(Math.random() * this.keys.length); i = Math.floor(Math.random() * this.keys.length);
k = this.keys[i]; k = this.keys[i];
delete this.valid[k]; this.valid.delete(k);
this.keys[i] = hash; this.keys[i] = hash;
} else { } else {
this.keys.push(hash); this.keys.push(hash);
@ -84,7 +84,7 @@ SigCache.prototype.add = function add(hash, sig, key) {
*/ */
SigCache.prototype.has = function has(hash, sig, key) { SigCache.prototype.has = function has(hash, sig, key) {
var entry = this.valid[hash]; var entry = this.valid.get(hash);
if (!entry) if (!entry)
return false; return false;

View File

@ -21,7 +21,7 @@ function LRU(capacity, getSize) {
if (!(this instanceof LRU)) if (!(this instanceof LRU))
return new LRU(capacity, getSize); return new LRU(capacity, getSize);
this.map = Object.create(null); this.map = new Map();
this.size = 0; this.size = 0;
this.items = 0; this.items = 0;
this.head = null; this.head = null;
@ -70,7 +70,7 @@ LRU.prototype._compact = function _compact() {
break; break;
this.size -= this._getSize(item); this.size -= this._getSize(item);
this.items--; this.items--;
delete this.map[item.key]; this.map.delete(item.key);
next = item.next; next = item.next;
item.prev = null; item.prev = null;
item.next = null; item.next = null;
@ -94,7 +94,7 @@ LRU.prototype.reset = function reset() {
var item, next; var item, next;
for (item = this.head; item; item = next) { for (item = this.head; item; item = next) {
delete this.map[item.key]; this.map.delete(item.key);
this.items--; this.items--;
next = item.next; next = item.next;
item.prev = null; item.prev = null;
@ -122,7 +122,7 @@ LRU.prototype.set = function set(key, value) {
key = key + ''; key = key + '';
item = this.map[key]; item = this.map.get(key);
if (item) { if (item) {
this.size -= this._getSize(item); this.size -= this._getSize(item);
@ -136,7 +136,7 @@ LRU.prototype.set = function set(key, value) {
item = new LRUItem(key, value); item = new LRUItem(key, value);
this.map[key] = item; this.map.set(key, item);
this._appendList(item); this._appendList(item);
@ -160,7 +160,7 @@ LRU.prototype.get = function get(key) {
key = key + ''; key = key + '';
item = this.map[key]; item = this.map.get(key);
if (!item) if (!item)
return; return;
@ -180,7 +180,7 @@ LRU.prototype.get = function get(key) {
LRU.prototype.has = function get(key) { LRU.prototype.has = function get(key) {
if (this.capacity === 0) if (this.capacity === 0)
return false; return false;
return this.map[key] != null; return this.map.has(key + '');
}; };
/** /**
@ -197,7 +197,7 @@ LRU.prototype.remove = function remove(key) {
key = key + ''; key = key + '';
item = this.map[key]; item = this.map.get(key);
if (!item) if (!item)
return false; return false;
@ -205,7 +205,7 @@ LRU.prototype.remove = function remove(key) {
this.size -= this._getSize(item); this.size -= this._getSize(item);
this.items--; this.items--;
delete this.map[key]; this.map.delete(key);
this._removeList(item); this._removeList(item);

View File

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

View File

@ -20,8 +20,8 @@ function MappedLock() {
if (!(this instanceof MappedLock)) if (!(this instanceof MappedLock))
return MappedLock.create(); return MappedLock.create();
this.jobs = Object.create(null); this.jobs = new Map();
this.busy = Object.create(null); this.busy = new Set();
this.destroyed = false; this.destroyed = false;
} }
@ -45,7 +45,7 @@ MappedLock.create = function create() {
*/ */
MappedLock.prototype.has = function has(name) { 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) { 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); return Promise.resolve(nop);
if (force) { if (force) {
assert(this.busy[key]); assert(this.busy.has(key));
return Promise.resolve(nop); return Promise.resolve(nop);
} }
if (this.busy[key]) { if (this.busy.has(key)) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
if (!self.jobs[key]) if (!self.jobs.has(key))
self.jobs[key] = []; self.jobs.set(key, []);
self.jobs[key].push(new Job(resolve, reject)); self.jobs.get(key).push(new Job(resolve, reject));
}); });
} }
this.busy[key] = true; this.busy.add(key);
return Promise.resolve(this.unlock(key)); return Promise.resolve(this.unlock(key));
}; };
@ -107,11 +107,11 @@ MappedLock.prototype.lock = function lock(key, force) {
MappedLock.prototype.unlock = function unlock(key) { MappedLock.prototype.unlock = function unlock(key) {
var self = this; var self = this;
return function unlocker() { return function unlocker() {
var jobs = self.jobs[key]; var jobs = self.jobs.get(key);
var job; var job;
assert(self.destroyed || self.busy[key]); assert(self.destroyed || self.busy.has(key));
delete self.busy[key]; self.busy.delete(key);
if (!jobs) if (!jobs)
return; return;
@ -122,9 +122,9 @@ MappedLock.prototype.unlock = function unlock(key) {
assert(job); assert(job);
if (jobs.length === 0) if (jobs.length === 0)
delete self.jobs[key]; self.jobs.delete(key);
self.busy[key] = true; self.busy.add(key);
job.resolve(unlocker); job.resolve(unlocker);
}; };
@ -137,23 +137,18 @@ MappedLock.prototype.unlock = function unlock(key) {
MappedLock.prototype.destroy = function destroy() { MappedLock.prototype.destroy = function destroy() {
var err = new Error('Lock was destroyed.'); var err = new Error('Lock was destroyed.');
var map = this.jobs; var map = this.jobs;
var keys = Object.keys(map); var jobs, job;
var i, j, key, jobs, job;
assert(!this.destroyed, 'Lock is already destroyed.'); assert(!this.destroyed, 'Lock is already destroyed.');
this.destroyed = true; this.destroyed = true;
this.jobs = Object.create(null); this.jobs = new Map();
this.busy = Object.create(null); this.busy = new Map();
for (i = 0; i < keys.length; i++) { for (jobs of map.values()) {
key = keys[i]; for (job of jobs)
jobs = map[key];
for (j = 0; j < jobs.length; j++) {
job = jobs[j];
job.reject(err); job.reject(err);
}
} }
}; };
@ -163,7 +158,6 @@ MappedLock.prototype.destroy = function destroy() {
* @ignore * @ignore
* @param {Function} resolve * @param {Function} resolve
* @param {Function} reject * @param {Function} reject
* @param {String?} name
*/ */
function Job(resolve, reject) { function Job(resolve, reject) {

View File

@ -45,7 +45,7 @@ function TXDB(wallet) {
this.options = wallet.db.options; this.options = wallet.db.options;
this.coinCache = new LRU(10000); this.coinCache = new LRU(10000);
this.locked = {}; this.locked = new Set();
this.state = null; this.state = null;
this.pending = null; this.pending = null;
this.events = []; this.events = [];
@ -1612,7 +1612,7 @@ TXDB.prototype.unlockTX = function unlockTX(tx) {
TXDB.prototype.lockCoin = function lockCoin(coin) { TXDB.prototype.lockCoin = function lockCoin(coin) {
var key = coin.toKey(); 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) { TXDB.prototype.unlockCoin = function unlockCoin(coin) {
var key = coin.toKey(); 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) { TXDB.prototype.isLocked = function isLocked(coin) {
var key = coin.toKey(); 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() { TXDB.prototype.getLocked = function getLocked() {
var keys = Object.keys(this.locked);
var outpoints = []; var outpoints = [];
var i, key; var key;
for (i = 0; i < keys.length; i++) { for (key of this.locked.keys())
key = keys[i];
outpoints.push(Outpoint.fromKey(key)); outpoints.push(Outpoint.fromKey(key));
}
return outpoints; return outpoints;
}; };

View File

@ -84,7 +84,7 @@ function WalletDB(options) {
} }
this.state = new ChainState(); this.state = new ChainState();
this.wallets = Object.create(null); this.wallets = new Map();
this.depth = 0; this.depth = 0;
this.rescanning = false; this.rescanning = false;
this.bound = false; this.bound = false;
@ -182,19 +182,15 @@ WalletDB.prototype._open = async function open() {
*/ */
WalletDB.prototype._close = async function close() { WalletDB.prototype._close = async function close() {
var keys = Object.keys(this.wallets); var wallet;
var i, key, wallet;
await this.disconnect(); await this.disconnect();
if (this.http && this.options.listen) if (this.http && this.options.listen)
await this.http.close(); await this.http.close();
for (i = 0; i < keys.length; i++) { for (wallet of this.wallets.values())
key = keys[i];
wallet = this.wallets[key];
await wallet.destroy(); await wallet.destroy();
}
await this.db.close(); await this.db.close();
@ -809,8 +805,8 @@ WalletDB.prototype.dump = function dump() {
*/ */
WalletDB.prototype.register = function register(wallet) { WalletDB.prototype.register = function register(wallet) {
assert(!this.wallets[wallet.wid]); assert(!this.wallets.has(wallet.wid));
this.wallets[wallet.wid] = wallet; this.wallets.set(wallet.wid, wallet);
}; };
/** /**
@ -820,8 +816,8 @@ WalletDB.prototype.register = function register(wallet) {
*/ */
WalletDB.prototype.unregister = function unregister(wallet) { WalletDB.prototype.unregister = function unregister(wallet) {
assert(this.wallets[wallet.wid]); assert(this.wallets.has(wallet.wid));
delete this.wallets[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) { WalletDB.prototype._get = async function get(wid) {
var wallet = this.wallets[wid]; var wallet = this.wallets.get(wid);
var data; var data;
if (wallet) if (wallet)

View File

@ -484,7 +484,7 @@ function Worker(id) {
this.id = id != null ? id : -1; this.id = id != null ? id : -1;
this.child = null; this.child = null;
this.pending = {}; this.pending = new Map();
this.env = { this.env = {
BCOIN_MASTER_URL: process.env.BCOIN_MASTER_URL || WorkerPool.MASTER_URL, 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) { Worker.prototype._execute = function _execute(packet, timeout, resolve, reject) {
var job = new PendingJob(this, packet.id, 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); job.start(timeout);
@ -793,7 +793,7 @@ Worker.prototype._execute = function _execute(packet, timeout, resolve, reject)
*/ */
Worker.prototype.resolveJob = function resolveJob(id, result) { Worker.prototype.resolveJob = function resolveJob(id, result) {
var job = this.pending[id]; var job = this.pending.get(id);
if (!job) if (!job)
throw new Error('Job ' + id + ' is not in progress.'); 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) { Worker.prototype.rejectJob = function rejectJob(id, err) {
var job = this.pending[id]; var job = this.pending.get(id);
if (!job) if (!job)
throw new Error('Job ' + id + ' is not in progress.'); 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() { Worker.prototype.killJobs = function killJobs() {
var keys = Object.keys(this.pending); var job;
var i, key, job;
for (i = 0; i < keys.length; i++) { for (job of this.pending.values())
key = keys[i];
job = this.pending[key];
job.destroy(); job.destroy();
}
}; };
/** /**
@ -889,8 +885,8 @@ PendingJob.prototype.cleanup = function cleanup() {
this.timer = null; this.timer = null;
} }
assert(this.worker.pending[this.id]); assert(this.worker.pending.has(this.id));
delete this.worker.pending[this.id]; this.worker.pending.delete(this.id);
return job; return job;
}; };

View File

@ -294,7 +294,7 @@ describe('Block', function() {
var block = Block.fromRaw(cmpct1[1], 'hex'); var block = Block.fromRaw(cmpct1[1], 'hex');
var cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex'); var cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex');
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
var map = {}; var map = new Map();
var i, tx, mempool, result; var i, tx, mempool, result;
assert(cblock1.init()); assert(cblock1.init());
@ -304,16 +304,11 @@ describe('Block', function() {
for (i = 0; i < block.txs.length; i++) { for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i]; tx = block.txs[i];
map[tx.hash('hex')] = tx; map.set(tx.hash('hex'), { tx: tx });
} }
mempool = { mempool = {
getSnapshot: function() { map: map
return Object.keys(map);
},
getTX: function(hash) {
return map[hash];
}
}; };
assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291); assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291);
@ -333,29 +328,21 @@ describe('Block', function() {
var block = Block.fromRaw(cmpct1[1], 'hex'); var block = Block.fromRaw(cmpct1[1], 'hex');
var cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex'); var cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex');
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
var map = {}; var map = new Map();
var i, tx, mid, keys, mempool, result, req, res; var i, tx, mempool, result, req, res;
assert(cblock1.init()); assert(cblock1.init());
assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]); assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]);
assert.equal(cblock2.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]; 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 = { mempool = {
getSnapshot: function() { map: map
return keys;
},
getTX: function(hash) {
return map[hash];
}
}; };
assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291); assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291);
@ -389,7 +376,7 @@ describe('Block', function() {
var block = Block.fromRaw(cmpct2block); var block = Block.fromRaw(cmpct2block);
var cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex'); var cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex');
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
var map = {}; var map = new Map();
var i, tx, result, mempool; var i, tx, result, mempool;
assert(cblock1.init()); assert(cblock1.init());
@ -399,16 +386,11 @@ describe('Block', function() {
for (i = 0; i < block.txs.length; i++) { for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i]; tx = block.txs[i];
map[tx.hash('hex')] = tx; map.set(tx.hash('hex'), { tx: tx });
} }
mempool = { mempool = {
getSnapshot: function() { map: map
return Object.keys(map);
},
getTX: function(hash) {
return map[hash];
}
}; };
result = cblock1.fillMempool(false, mempool); result = cblock1.fillMempool(false, mempool);
@ -426,29 +408,21 @@ describe('Block', function() {
var block = Block.fromRaw(cmpct2block); var block = Block.fromRaw(cmpct2block);
var cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex'); var cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex');
var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); var cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce);
var map = {}; var map = new Map();
var i, tx, mid, keys, mempool, result, req, res; var i, tx, mempool, result, req, res;
assert(cblock1.init()); assert(cblock1.init());
assert.equal(cblock1.toRaw().toString('hex'), cmpct2); assert.equal(cblock1.toRaw().toString('hex'), cmpct2);
assert.equal(cblock2.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]; 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 = { mempool = {
getSnapshot: function() { map: map
return keys;
},
getTX: function(hash) {
return map[hash];
}
}; };
result = cblock1.fillMempool(false, mempool); result = cblock1.fillMempool(false, mempool);

View File

@ -594,7 +594,7 @@ describe('Node', function() {
missing = await node.mempool.addTX(tx); missing = await node.mempool.addTX(tx);
assert(!missing || missing.length === 0); 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() { it('should add lesser transaction to mempool', async function() {
@ -620,7 +620,7 @@ describe('Node', function() {
missing = await node.mempool.addTX(tx); missing = await node.mempool.addTX(tx);
assert(!missing || missing.length === 0); 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() { it('should get a block template', async function() {