refactor: use maps and sets wherever possible.
This commit is contained in:
parent
590c4350e9
commit
7eefb773be
@ -22,10 +22,10 @@ const x509 = exports;
|
||||
|
||||
/**
|
||||
* Map of trusted root certs.
|
||||
* @type {Object}
|
||||
* @type {Set}
|
||||
*/
|
||||
|
||||
x509.trusted = {};
|
||||
x509.trusted = new Set();
|
||||
|
||||
/**
|
||||
* Whether to allow untrusted root
|
||||
@ -127,7 +127,7 @@ x509.getCAName = function getCAName(cert) {
|
||||
x509.isTrusted = function isTrusted(cert) {
|
||||
let fingerprint = digest.sha256(cert.raw);
|
||||
let hash = fingerprint.toString('hex');
|
||||
return x509.trusted[hash] === true;
|
||||
return x509.trusted.has(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -154,7 +154,7 @@ x509.setTrust = function setTrust(certs) {
|
||||
hash = digest.sha256(cert.raw);
|
||||
hash = hash.toString('hex');
|
||||
|
||||
x509.trusted[hash] = true;
|
||||
x509.trusted.add(hash);
|
||||
}
|
||||
};
|
||||
|
||||
@ -174,7 +174,7 @@ x509.setFingerprints = function setFingerprints(hashes) {
|
||||
assert(hash.length === 32, 'Fingerprint must be a sha256 hash.');
|
||||
|
||||
hash = hash.toString('hex');
|
||||
x509.trusted[hash] = true;
|
||||
x509.trusted.add(hash);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1144,7 +1144,7 @@ ChainDB.prototype.getCoinsByAddress = async function getCoinsByAddress(addrs) {
|
||||
*/
|
||||
|
||||
ChainDB.prototype.getHashesByAddress = async function getHashesByAddress(addrs) {
|
||||
let hashes = {};
|
||||
let hashes = Object.create(null);
|
||||
|
||||
if (!this.options.indexTX || !this.options.indexAddress)
|
||||
return [];
|
||||
|
||||
@ -566,15 +566,14 @@ LowlevelUp.prototype.values = async function _values(options) {
|
||||
*/
|
||||
|
||||
LowlevelUp.prototype.dump = async function dump() {
|
||||
let records = {};
|
||||
let records = Object.create(null);
|
||||
|
||||
let items = await this.range({
|
||||
gte: LOW,
|
||||
lte: HIGH
|
||||
});
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i];
|
||||
for (let item of items) {
|
||||
let key = item.key.toString('hex');
|
||||
let value = item.value.toString('hex');
|
||||
records[key] = value;
|
||||
|
||||
@ -1509,7 +1509,7 @@ function WebSocket(socket, ctx) {
|
||||
this.context = ctx;
|
||||
this.socket = socket;
|
||||
this.remoteAddress = socket.conn.remoteAddress;
|
||||
this.hooks = {};
|
||||
this.hooks = Object.create(null);
|
||||
this.channels = new Map();
|
||||
this.auth = false;
|
||||
this.filter = null;
|
||||
|
||||
@ -228,7 +228,7 @@ RequestOptions.prototype.getHeaders = function getHeaders() {
|
||||
if (this.headers)
|
||||
return this.headers;
|
||||
|
||||
headers = {};
|
||||
headers = Object.create(null);
|
||||
|
||||
headers['User-Agent'] = this.agent;
|
||||
|
||||
|
||||
@ -855,7 +855,7 @@ RPC.prototype.getTXOutProof = async function getTXOutProof(args, help) {
|
||||
let valid = new Validator([args]);
|
||||
let txids = valid.array(0);
|
||||
let hash = valid.hash(1);
|
||||
let uniq = {};
|
||||
let uniq = new Set();
|
||||
let block, last;
|
||||
|
||||
if (help || (args.length !== 1 && args.length !== 2)) {
|
||||
@ -880,10 +880,10 @@ RPC.prototype.getTXOutProof = async function getTXOutProof(args, help) {
|
||||
if (!txid)
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid TXID.');
|
||||
|
||||
if (uniq[txid])
|
||||
if (uniq.has(txid))
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Duplicate txid.');
|
||||
|
||||
uniq[txid] = true;
|
||||
uniq.add(txid);
|
||||
txids[i] = txid;
|
||||
last = txid;
|
||||
}
|
||||
@ -1269,7 +1269,7 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb
|
||||
let scale = attempt.witness ? 1 : consensus.WITNESS_SCALE_FACTOR;
|
||||
let mutable = ['time', 'transactions', 'prevblock'];
|
||||
let txs = [];
|
||||
let index = {};
|
||||
let index = new Map();
|
||||
let vbavailable = {};
|
||||
let vbrules = [];
|
||||
let json;
|
||||
@ -1293,7 +1293,7 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb
|
||||
// Build an index of every transaction.
|
||||
for (let i = 0; i < attempt.items.length; i++) {
|
||||
let entry = attempt.items[i];
|
||||
index[entry.hash] = i + 1;
|
||||
index.set(entry.hash, i + 1);
|
||||
}
|
||||
|
||||
// Calculate dependencies for each transaction.
|
||||
@ -1304,7 +1304,7 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb
|
||||
|
||||
for (let j = 0; j < tx.inputs.length; j++) {
|
||||
let input = tx.inputs[j];
|
||||
let dep = index[input.prevout.hash];
|
||||
let dep = index.get(input.prevout.hash);
|
||||
|
||||
if (dep == null)
|
||||
continue;
|
||||
@ -1634,7 +1634,8 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h
|
||||
let inputs = valid.array(0);
|
||||
let sendTo = valid.obj(1);
|
||||
let locktime = valid.u32(2);
|
||||
let tx, addrs;
|
||||
let uniq = new Set();
|
||||
let tx;
|
||||
|
||||
if (help || args.length < 2 || args.length > 3) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
@ -1675,7 +1676,6 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h
|
||||
}
|
||||
|
||||
valid = new Validator([sendTo]);
|
||||
addrs = {};
|
||||
|
||||
for (let key of Object.keys(sendTo)) {
|
||||
let addr, b58, value, output;
|
||||
@ -1698,10 +1698,10 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h
|
||||
addr = parseAddress(key, this.network);
|
||||
b58 = addr.toString(this.network);
|
||||
|
||||
if (addrs[b58])
|
||||
if (uniq.has(b58))
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Duplicate address');
|
||||
|
||||
addrs[b58] = true;
|
||||
uniq.add(b58);
|
||||
|
||||
value = valid.btc(key);
|
||||
|
||||
@ -1814,8 +1814,8 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help)
|
||||
let secrets = valid.array(2);
|
||||
let sighash = valid.str(3);
|
||||
let type = Script.hashType.ALL;
|
||||
let map = new Map();
|
||||
let keys = [];
|
||||
let map = {};
|
||||
let tx;
|
||||
|
||||
if (help || args.length < 1 || args.length > 4) {
|
||||
@ -1841,7 +1841,7 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help)
|
||||
for (let i = 0; i < secrets.length; i++) {
|
||||
let secret = valid.str(i, '');
|
||||
let key = parseSecret(secret, this.network);
|
||||
map[key.getPublicKey('hex')] = key;
|
||||
map.set(key.getPublicKey('hex'), key);
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
@ -1886,7 +1886,7 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help)
|
||||
if (!op.data)
|
||||
continue;
|
||||
|
||||
key = map[op.data.toString('hex')];
|
||||
key = map.get(op.data.toString('hex'));
|
||||
|
||||
if (key) {
|
||||
key.script = redeem;
|
||||
|
||||
@ -25,7 +25,7 @@ function RPCBase() {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.logger = Logger.global;
|
||||
this.calls = {};
|
||||
this.calls = Object.create(null);
|
||||
this.mounts = [];
|
||||
this.locker = new Lock();
|
||||
}
|
||||
|
||||
@ -1144,7 +1144,7 @@ Mempool.prototype.removeSpenders = function removeSpenders(entry) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.countAncestors = function countAncestors(entry) {
|
||||
return this._countAncestors(entry, 0, {}, entry, nop);
|
||||
return this._countAncestors(entry, new Set(), entry, nop);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1157,21 +1157,20 @@ Mempool.prototype.countAncestors = function countAncestors(entry) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.updateAncestors = function updateAncestors(entry, map) {
|
||||
return this._countAncestors(entry, 0, {}, entry, map);
|
||||
return this._countAncestors(entry, new Set(), entry, map);
|
||||
};
|
||||
|
||||
/**
|
||||
* Traverse ancestors and count.
|
||||
* @private
|
||||
* @param {MempoolEntry} entry
|
||||
* @param {Number} count
|
||||
* @param {Object} set
|
||||
* @param {MempoolEntry} child
|
||||
* @param {Function} map
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Mempool.prototype._countAncestors = function countAncestors(entry, count, set, child, map) {
|
||||
Mempool.prototype._countAncestors = function countAncestors(entry, set, child, map) {
|
||||
let tx = entry.tx;
|
||||
|
||||
for (let input of tx.inputs) {
|
||||
@ -1181,24 +1180,23 @@ Mempool.prototype._countAncestors = function countAncestors(entry, count, set, c
|
||||
if (!parent)
|
||||
continue;
|
||||
|
||||
if (set[hash])
|
||||
if (set.has(hash))
|
||||
continue;
|
||||
|
||||
set[hash] = true;
|
||||
count += 1;
|
||||
set.add(hash);
|
||||
|
||||
map(parent, child);
|
||||
|
||||
if (count > this.options.maxAncestors)
|
||||
if (set.size > this.options.maxAncestors)
|
||||
break;
|
||||
|
||||
count = this._countAncestors(parent, count, set, child, map);
|
||||
this._countAncestors(parent, set, child, map);
|
||||
|
||||
if (count > this.options.maxAncestors)
|
||||
if (set.size > this.options.maxAncestors)
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
return set.size;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1209,7 +1207,7 @@ Mempool.prototype._countAncestors = function countAncestors(entry, count, set, c
|
||||
*/
|
||||
|
||||
Mempool.prototype.countDescendants = function countDescendants(entry) {
|
||||
return this._countDescendants(entry, 0, {});
|
||||
return this._countDescendants(entry, new Set());
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1217,12 +1215,11 @@ Mempool.prototype.countDescendants = function countDescendants(entry) {
|
||||
* descendants a transaction may have.
|
||||
* @private
|
||||
* @param {MempoolEntry} entry
|
||||
* @param {Number} count
|
||||
* @param {Object} set
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Mempool.prototype._countDescendants = function countDescendants(entry, count, set) {
|
||||
Mempool.prototype._countDescendants = function countDescendants(entry, set) {
|
||||
let tx = entry.tx;
|
||||
let hash = tx.hash('hex');
|
||||
|
||||
@ -1235,16 +1232,15 @@ Mempool.prototype._countDescendants = function countDescendants(entry, count, se
|
||||
|
||||
next = child.hash('hex');
|
||||
|
||||
if (set[next])
|
||||
if (set.has(next))
|
||||
continue;
|
||||
|
||||
set[next] = true;
|
||||
count += 1;
|
||||
set.add(next);
|
||||
|
||||
count = this._countDescendants(child, count, set);
|
||||
this._countDescendants(child, set);
|
||||
}
|
||||
|
||||
return count;
|
||||
return set.size;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1254,7 +1250,7 @@ Mempool.prototype._countDescendants = function countDescendants(entry, count, se
|
||||
*/
|
||||
|
||||
Mempool.prototype.getAncestors = function getAncestors(entry) {
|
||||
return this._getAncestors(entry, [], {});
|
||||
return this._getAncestors(entry, [], new Set());
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1276,10 +1272,10 @@ Mempool.prototype._getAncestors = function getAncestors(entry, entries, set) {
|
||||
if (!parent)
|
||||
continue;
|
||||
|
||||
if (set[hash])
|
||||
if (set.has(hash))
|
||||
continue;
|
||||
|
||||
set[hash] = true;
|
||||
set.add(hash);
|
||||
entries.push(parent);
|
||||
|
||||
this._getAncestors(parent, entries, set);
|
||||
@ -1295,7 +1291,7 @@ Mempool.prototype._getAncestors = function getAncestors(entry, entries, set) {
|
||||
*/
|
||||
|
||||
Mempool.prototype.getDescendants = function getDescendants(entry) {
|
||||
return this._getDescendants(entry, [], {});
|
||||
return this._getDescendants(entry, [], new Set());
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1319,10 +1315,10 @@ Mempool.prototype._getDescendants = function getDescendants(entry, entries, set)
|
||||
|
||||
next = child.hash('hex');
|
||||
|
||||
if (set[next])
|
||||
if (set.has(next))
|
||||
continue;
|
||||
|
||||
set[next] = true;
|
||||
set.add(next);
|
||||
entries.push(child);
|
||||
|
||||
this._getDescendants(child, entries, set);
|
||||
|
||||
@ -256,7 +256,7 @@ Miner.prototype.getAddress = function getAddress() {
|
||||
Miner.prototype.assemble = function assemble(attempt) {
|
||||
let priority = this.options.priorityWeight > 0;
|
||||
let queue = new Heap(cmpRate);
|
||||
let depMap = {};
|
||||
let depMap = new Map();
|
||||
|
||||
if (priority)
|
||||
queue.set(cmpPriority);
|
||||
@ -284,10 +284,10 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
|
||||
item.depCount += 1;
|
||||
|
||||
if (!depMap[hash])
|
||||
depMap[hash] = [];
|
||||
if (!depMap.has(hash))
|
||||
depMap.set(hash, []);
|
||||
|
||||
depMap[hash].push(item);
|
||||
depMap.get(hash).push(item);
|
||||
}
|
||||
|
||||
if (item.depCount > 0)
|
||||
@ -339,7 +339,7 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
attempt.fees += item.fee;
|
||||
attempt.items.push(item);
|
||||
|
||||
deps = depMap[hash];
|
||||
deps = depMap.get(hash);
|
||||
|
||||
if (!deps)
|
||||
continue;
|
||||
|
||||
@ -1140,7 +1140,7 @@ HostList.prototype.toJSON = function toJSON() {
|
||||
*/
|
||||
|
||||
HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
let sources = {};
|
||||
let sources = new Map();
|
||||
let map = new Map();
|
||||
let totalFresh = 0;
|
||||
let totalUsed = 0;
|
||||
@ -1156,12 +1156,12 @@ HostList.prototype.fromJSON = function fromJSON(json) {
|
||||
|
||||
for (let addr of json.addrs) {
|
||||
let entry = HostEntry.fromJSON(addr, this.network);
|
||||
let src = sources[entry.src.hostname];
|
||||
let src = sources.get(entry.src.hostname);
|
||||
|
||||
// Save some memory.
|
||||
if (!src) {
|
||||
src = entry.src;
|
||||
sources[src.hostname] = src;
|
||||
sources.set(src.hostname, src);
|
||||
}
|
||||
|
||||
entry.src = src;
|
||||
|
||||
@ -77,7 +77,7 @@ exports.types = {
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.typesByVal = util.revMap(exports.types);
|
||||
exports.typesByVal = util.reverse(exports.types);
|
||||
|
||||
/**
|
||||
* Base Packet
|
||||
@ -1474,7 +1474,7 @@ RejectPacket.codes = {
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
RejectPacket.codesByVal = util.revMap(RejectPacket.codes);
|
||||
RejectPacket.codesByVal = util.reverse(RejectPacket.codes);
|
||||
|
||||
RejectPacket.prototype.cmd = 'reject';
|
||||
RejectPacket.prototype.type = exports.types.REJECT;
|
||||
|
||||
@ -55,7 +55,7 @@ SOCKS.states = {
|
||||
RESOLVE_DONE: 7
|
||||
};
|
||||
|
||||
SOCKS.statesByVal = util.revMap(SOCKS.states);
|
||||
SOCKS.statesByVal = util.reverse(SOCKS.states);
|
||||
|
||||
SOCKS.errors = [
|
||||
'',
|
||||
|
||||
@ -262,7 +262,7 @@ UPNP.prototype.resolve = async function resolve(location, targets) {
|
||||
|
||||
UPNP.parseHeader = function parseHeader(str) {
|
||||
let lines = str.split(/\r?\n/);
|
||||
let headers = {};
|
||||
let headers = Object.create(null);
|
||||
|
||||
for (let line of lines) {
|
||||
let index, left, right;
|
||||
@ -635,7 +635,7 @@ function parseServices(el) {
|
||||
}
|
||||
|
||||
function parseService(el) {
|
||||
let service = {};
|
||||
let service = Object.create(null);
|
||||
|
||||
for (let child of el.children) {
|
||||
if (child.children.length > 0)
|
||||
|
||||
@ -33,7 +33,7 @@ function Logger(options) {
|
||||
this.closing = false;
|
||||
this.filename = null;
|
||||
this.stream = null;
|
||||
this.contexts = {};
|
||||
this.contexts = Object.create(null);
|
||||
this.locker = new Lock();
|
||||
|
||||
if (options)
|
||||
|
||||
@ -42,7 +42,7 @@ function Node(options) {
|
||||
this.network = Network.get(this.config.network);
|
||||
this.startTime = -1;
|
||||
this.bound = [];
|
||||
this.plugins = {};
|
||||
this.plugins = Object.create(null);
|
||||
this.stack = [];
|
||||
|
||||
this.logger = null;
|
||||
|
||||
@ -57,7 +57,7 @@ Address.types = {
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
Address.typesByVal = util.revMap(Address.types);
|
||||
Address.typesByVal = util.reverse(Address.types);
|
||||
|
||||
/**
|
||||
* Inject properties from options object.
|
||||
|
||||
@ -514,7 +514,7 @@ Block.prototype.getClaimed = function getClaimed() {
|
||||
*/
|
||||
|
||||
Block.prototype.getPrevout = function getPrevout() {
|
||||
let prevout = {};
|
||||
let prevout = Object.create(null);
|
||||
|
||||
for (let i = 1; i < this.txs.length; i++) {
|
||||
let tx = this.txs[i];
|
||||
|
||||
@ -51,7 +51,7 @@ InvItem.types = {
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
InvItem.typesByVal = util.revMap(InvItem.types);
|
||||
InvItem.typesByVal = util.reverse(InvItem.types);
|
||||
|
||||
/**
|
||||
* Witness bit for inv types.
|
||||
|
||||
@ -524,18 +524,18 @@ MerkleBlock.fromBlock = function fromBlock(block, filter) {
|
||||
*/
|
||||
|
||||
MerkleBlock.fromHashes = function fromHashes(block, hashes) {
|
||||
let filter = {};
|
||||
let filter = new Set();
|
||||
let matches = [];
|
||||
|
||||
for (let hash of hashes) {
|
||||
if (Buffer.isBuffer(hash))
|
||||
hash = hash.toString('hex');
|
||||
filter[hash] = true;
|
||||
filter.add(hash);
|
||||
}
|
||||
|
||||
for (let tx of block.txs) {
|
||||
let hash = tx.hash('hex');
|
||||
matches.push(filter[hash] ? 1 : 0);
|
||||
matches.push(filter.has(hash) ? 1 : 0);
|
||||
}
|
||||
|
||||
return MerkleBlock.fromMatches(block, matches);
|
||||
|
||||
@ -1013,7 +1013,7 @@ TX.prototype.getOutputValue = function getOutputValue() {
|
||||
*/
|
||||
|
||||
TX.prototype._getInputAddresses = function getInputAddresses(view) {
|
||||
let table = {};
|
||||
let table = Object.create(null);
|
||||
let addrs = [];
|
||||
|
||||
if (this.isCoinbase())
|
||||
@ -1045,7 +1045,7 @@ TX.prototype._getInputAddresses = function getInputAddresses(view) {
|
||||
*/
|
||||
|
||||
TX.prototype._getOutputAddresses = function getOutputAddresses() {
|
||||
let table = {};
|
||||
let table = Object.create(null);
|
||||
let addrs = [];
|
||||
|
||||
for (let output of this.outputs) {
|
||||
@ -1423,7 +1423,7 @@ TX.prototype.isSane = function isSane() {
|
||||
*/
|
||||
|
||||
TX.prototype.checkSanity = function checkSanity() {
|
||||
let prevout = {};
|
||||
let prevout = new Set();
|
||||
let total = 0;
|
||||
|
||||
if (this.inputs.length === 0)
|
||||
@ -1450,9 +1450,9 @@ TX.prototype.checkSanity = function checkSanity() {
|
||||
|
||||
for (let input of this.inputs) {
|
||||
let key = input.prevout.toKey();
|
||||
if (prevout[key])
|
||||
if (prevout.has(key))
|
||||
return [false, 'bad-txns-inputs-duplicate', 100];
|
||||
prevout[key] = true;
|
||||
prevout.add(key);
|
||||
}
|
||||
|
||||
if (this.isCoinbase()) {
|
||||
@ -1944,7 +1944,7 @@ TX.prototype.getRate = function getRate(view, size) {
|
||||
*/
|
||||
|
||||
TX.prototype.getPrevout = function getPrevout() {
|
||||
let prevout = {};
|
||||
let prevout = Object.create(null);
|
||||
|
||||
if (this.isCoinbase())
|
||||
return [];
|
||||
|
||||
@ -162,7 +162,7 @@ exports.opcodes = {
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
exports.opcodesByVal = util.revMap(exports.opcodes);
|
||||
exports.opcodesByVal = util.reverse(exports.opcodes);
|
||||
|
||||
/**
|
||||
* Script and locktime flags. See {@link VerifyFlags}.
|
||||
@ -267,7 +267,7 @@ exports.hashType = {
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
exports.hashTypeByVal = util.revMap(exports.hashType);
|
||||
exports.hashTypeByVal = util.reverse(exports.hashType);
|
||||
|
||||
/**
|
||||
* Output script types.
|
||||
@ -292,7 +292,7 @@ exports.types = {
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
exports.typesByVal = util.revMap(exports.types);
|
||||
exports.typesByVal = util.reverse(exports.types);
|
||||
|
||||
/**
|
||||
* False stack return value.
|
||||
|
||||
@ -27,7 +27,7 @@ function Lock(named) {
|
||||
this.busy = false;
|
||||
this.destroyed = false;
|
||||
|
||||
this.map = Object.create(null);
|
||||
this.map = new Map();
|
||||
this.current = null;
|
||||
|
||||
this.unlocker = this.unlock.bind(this);
|
||||
@ -54,12 +54,19 @@ Lock.create = function create(named) {
|
||||
*/
|
||||
|
||||
Lock.prototype.has = function has(name) {
|
||||
let count;
|
||||
|
||||
assert(this.named, 'Must use named jobs.');
|
||||
|
||||
if (this.current === name)
|
||||
return true;
|
||||
|
||||
return this.map[name] > 0;
|
||||
count = this.map.get(name);
|
||||
|
||||
if (count == null)
|
||||
return false;
|
||||
|
||||
return count > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -70,8 +77,16 @@ Lock.prototype.has = function has(name) {
|
||||
*/
|
||||
|
||||
Lock.prototype.hasPending = function hasPending(name) {
|
||||
let count;
|
||||
|
||||
assert(this.named, 'Must use named jobs.');
|
||||
return this.map[name] > 0;
|
||||
|
||||
count = this.map.get(name);
|
||||
|
||||
if (count == null)
|
||||
return false;
|
||||
|
||||
return count > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -105,9 +120,10 @@ Lock.prototype.lock = function lock(arg1, arg2) {
|
||||
|
||||
if (this.busy) {
|
||||
if (name) {
|
||||
if (!this.map[name])
|
||||
this.map[name] = 0;
|
||||
this.map[name]++;
|
||||
let count = this.map.get(name);
|
||||
if (!count)
|
||||
count = 0;
|
||||
this.map.set(name, count + 1);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this.jobs.push(new Job(resolve, reject, name));
|
||||
@ -141,9 +157,12 @@ Lock.prototype.unlock = function unlock() {
|
||||
job = this.jobs.shift();
|
||||
|
||||
if (job.name) {
|
||||
assert(this.map[job.name] > 0);
|
||||
if (--this.map[job.name] === 0)
|
||||
delete this.map[job.name];
|
||||
let count = this.map.get(job.name);
|
||||
assert(count > 0);
|
||||
if (--count === 0)
|
||||
this.map.delete(job.name);
|
||||
else
|
||||
this.map.set(job.name, count);
|
||||
}
|
||||
|
||||
this.busy = true;
|
||||
@ -167,7 +186,7 @@ Lock.prototype.destroy = function destroy() {
|
||||
|
||||
this.busy = false;
|
||||
this.jobs.length = 0;
|
||||
this.map = Object.create(null);
|
||||
this.map.clear();
|
||||
this.current = null;
|
||||
|
||||
for (let job of jobs)
|
||||
|
||||
@ -642,50 +642,20 @@ util.hex32 = function hex32(num) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert an array to a map.
|
||||
* @param {String[]} items
|
||||
* @returns {Object} Map.
|
||||
* Reverse an object's keys and values.
|
||||
* @param {Object} obj
|
||||
* @returns {Object} Reversed object.
|
||||
*/
|
||||
|
||||
util.toMap = function toMap(items) {
|
||||
let map = {};
|
||||
|
||||
for (let value of items)
|
||||
map[value] = true;
|
||||
|
||||
return map;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverse a map.
|
||||
* @param {Object} map
|
||||
* @returns {Object} Reversed map.
|
||||
*/
|
||||
|
||||
util.revMap = function revMap(map) {
|
||||
util.reverse = function reverse(obj) {
|
||||
let reversed = {};
|
||||
|
||||
for (let key of Object.keys(map))
|
||||
reversed[map[key]] = key;
|
||||
for (let key of Object.keys(obj))
|
||||
reversed[obj[key]] = key;
|
||||
|
||||
return reversed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get object values.
|
||||
* @param {Object} map
|
||||
* @returns {Array} Values.
|
||||
*/
|
||||
|
||||
util.values = function values(map) {
|
||||
let items = [];
|
||||
|
||||
for (let key of Object.keys(map))
|
||||
items.push(map[key]);
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform a binary search on a sorted array.
|
||||
* @param {Array} items
|
||||
|
||||
@ -81,36 +81,38 @@ common.sortCoins = function sortCoins(coins) {
|
||||
*/
|
||||
|
||||
common.sortDeps = function sortDeps(txs) {
|
||||
let depMap = {};
|
||||
let count = {};
|
||||
let map = new Map();
|
||||
let depMap = new Map();
|
||||
let depCount = new Map();
|
||||
let result = [];
|
||||
let top = [];
|
||||
let map = {};
|
||||
|
||||
for (let tx of txs) {
|
||||
let hash = tx.hash('hex');
|
||||
map[hash] = tx;
|
||||
map.set(hash, tx);
|
||||
}
|
||||
|
||||
for (let tx of txs) {
|
||||
for (let [hash, tx] of map) {
|
||||
let hash = tx.hash('hex');
|
||||
let hasDeps = false;
|
||||
|
||||
count[hash] = 0;
|
||||
depCount.set(hash, 0);
|
||||
|
||||
for (let input of tx.inputs) {
|
||||
let prev = input.prevout.hash;
|
||||
let count;
|
||||
|
||||
if (!map[prev])
|
||||
if (!map.has(prev))
|
||||
continue;
|
||||
|
||||
count[hash] += 1;
|
||||
count = depCount.get(hash);
|
||||
depCount.set(hash, count + 1);
|
||||
hasDeps = true;
|
||||
|
||||
if (!depMap[prev])
|
||||
depMap[prev] = [];
|
||||
if (!depMap.has(prev))
|
||||
depMap.set(prev, []);
|
||||
|
||||
depMap[prev].push(tx);
|
||||
depMap.get(prev).push(tx);
|
||||
}
|
||||
|
||||
if (hasDeps)
|
||||
@ -121,7 +123,7 @@ common.sortDeps = function sortDeps(txs) {
|
||||
|
||||
for (let tx of top) {
|
||||
let hash = tx.hash('hex');
|
||||
let deps = depMap[hash];
|
||||
let deps = depMap.get(hash);
|
||||
|
||||
result.push(tx);
|
||||
|
||||
@ -130,9 +132,12 @@ common.sortDeps = function sortDeps(txs) {
|
||||
|
||||
for (let tx of deps) {
|
||||
let hash = tx.hash('hex');
|
||||
let count = depCount.get(hash);
|
||||
|
||||
if (--count[hash] === 0)
|
||||
if (--count === 0)
|
||||
top.push(tx);
|
||||
|
||||
depCount.set(hash, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -238,7 +238,7 @@ function BlockMapRecord(height) {
|
||||
|
||||
this.height = height != null ? height : -1;
|
||||
this.txs = [];
|
||||
this.index = {};
|
||||
this.index = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,7 +256,7 @@ BlockMapRecord.prototype.fromRaw = function fromRaw(data) {
|
||||
let hash = br.readHash('hex');
|
||||
let tx = TXMapRecord.fromReader(hash, br);
|
||||
this.txs.push(tx);
|
||||
this.index[tx.hash] = tx;
|
||||
this.index.set(tx.hash, tx);
|
||||
}
|
||||
|
||||
return this;
|
||||
@ -319,13 +319,13 @@ BlockMapRecord.prototype.toRaw = function toRaw() {
|
||||
*/
|
||||
|
||||
BlockMapRecord.prototype.add = function add(hash, wid) {
|
||||
let tx = this.index[hash];
|
||||
let tx = this.index.get(hash);
|
||||
|
||||
if (!tx) {
|
||||
tx = new TXMapRecord(hash);
|
||||
tx.wids.push(wid);
|
||||
this.txs.push(tx);
|
||||
this.index[tx.hash] = tx;
|
||||
this.index.set(tx.hash, tx);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ BlockMapRecord.prototype.add = function add(hash, wid) {
|
||||
*/
|
||||
|
||||
BlockMapRecord.prototype.remove = function remove(hash, wid) {
|
||||
let tx = this.index[hash];
|
||||
let tx = this.index.get(hash);
|
||||
|
||||
if (!tx)
|
||||
return false;
|
||||
@ -351,7 +351,7 @@ BlockMapRecord.prototype.remove = function remove(hash, wid) {
|
||||
if (tx.wids.length === 0) {
|
||||
let result = util.binaryRemove(this.txs, tx, cmpid);
|
||||
assert(result);
|
||||
delete this.index[tx.hash];
|
||||
this.index.delete(tx.hash);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -458,8 +458,8 @@ RPC.prototype.getReceivedByAccount = async function getReceivedByAccount(args, h
|
||||
let name = valid.str(0);
|
||||
let minconf = valid.u32(0, 0);
|
||||
let height = this.wdb.state.height;
|
||||
let filter = new Set();
|
||||
let total = 0;
|
||||
let filter = {};
|
||||
let lastConf = -1;
|
||||
let paths, txs;
|
||||
|
||||
@ -474,7 +474,7 @@ RPC.prototype.getReceivedByAccount = async function getReceivedByAccount(args, h
|
||||
paths = await wallet.getPaths(name);
|
||||
|
||||
for (let path of paths)
|
||||
filter[path.hash] = true;
|
||||
filter.add(path.hash);
|
||||
|
||||
txs = await wallet.getHistory(name);
|
||||
|
||||
@ -489,7 +489,7 @@ RPC.prototype.getReceivedByAccount = async function getReceivedByAccount(args, h
|
||||
|
||||
for (let output of wtx.tx.outputs) {
|
||||
let hash = output.getHash('hex');
|
||||
if (hash && filter[hash])
|
||||
if (hash && filter.has(hash))
|
||||
total += output.value;
|
||||
}
|
||||
}
|
||||
@ -903,21 +903,21 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch
|
||||
let wallet = this.wallet;
|
||||
let paths = await wallet.getPaths();
|
||||
let height = this.wdb.state.height;
|
||||
let map = new Map();
|
||||
let out = [];
|
||||
let result = [];
|
||||
let map = {};
|
||||
let txs;
|
||||
|
||||
for (let path of paths) {
|
||||
let addr = path.toAddress();
|
||||
map[path.hash] = {
|
||||
map.set(path.hash, {
|
||||
involvesWatchonly: wallet.watchOnly,
|
||||
address: addr.toString(this.network),
|
||||
account: path.name,
|
||||
amount: 0,
|
||||
confirmations: -1,
|
||||
label: '',
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
txs = await wallet.getHistory();
|
||||
@ -936,7 +936,7 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch
|
||||
continue;
|
||||
|
||||
hash = addr.getHash('hex');
|
||||
entry = map[hash];
|
||||
entry = map.get(hash);
|
||||
|
||||
if (entry) {
|
||||
if (entry.confirmations === -1 || conf < entry.confirmations)
|
||||
@ -947,18 +947,16 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch
|
||||
}
|
||||
}
|
||||
|
||||
for (let key of Object.keys(map)) {
|
||||
let entry = map[key];
|
||||
for (let entry of map.values())
|
||||
out.push(entry);
|
||||
}
|
||||
|
||||
if (account) {
|
||||
let map = {};
|
||||
let map = new Map();
|
||||
|
||||
for (let entry of out) {
|
||||
let item = map[entry.account];
|
||||
let item = map.get(entry.account);
|
||||
if (!item) {
|
||||
map[entry.account] = entry;
|
||||
map.set(entry.account, entry);
|
||||
entry.address = undefined;
|
||||
continue;
|
||||
}
|
||||
@ -967,10 +965,8 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch
|
||||
|
||||
out = [];
|
||||
|
||||
for (let key of Object.keys(map)) {
|
||||
let entry = map[key];
|
||||
for (let entry of map.values())
|
||||
out.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
for (let entry of out) {
|
||||
@ -1158,8 +1154,8 @@ RPC.prototype.listUnspent = async function listUnspent(args, help) {
|
||||
let maxDepth = valid.u32(1, 9999999);
|
||||
let addrs = valid.array(2);
|
||||
let height = this.wdb.state.height;
|
||||
let map = new Set();
|
||||
let out = [];
|
||||
let map = {};
|
||||
let coins;
|
||||
|
||||
if (help || args.length > 3) {
|
||||
@ -1173,10 +1169,10 @@ RPC.prototype.listUnspent = async function listUnspent(args, help) {
|
||||
let addr = valid.str(i, '');
|
||||
let hash = parseHash(addr, this.network);
|
||||
|
||||
if (map[hash])
|
||||
if (map.has(hash))
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Duplicate address.');
|
||||
|
||||
map[hash] = true;
|
||||
map.add(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1199,7 +1195,7 @@ RPC.prototype.listUnspent = async function listUnspent(args, help) {
|
||||
hash = coin.getHash('hex');
|
||||
|
||||
if (addrs) {
|
||||
if (!hash || !map[hash])
|
||||
if (!hash || !map.has(hash))
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1319,8 +1315,8 @@ RPC.prototype.sendMany = async function sendMany(args, help) {
|
||||
let sendTo = valid.obj(1);
|
||||
let minconf = valid.u32(2, 1);
|
||||
let subtractFee = valid.bool(4, false);
|
||||
let uniq = new Set();
|
||||
let outputs = [];
|
||||
let uniq = {};
|
||||
let options, tx;
|
||||
|
||||
if (help || args.length < 2 || args.length > 5) {
|
||||
@ -1346,10 +1342,10 @@ RPC.prototype.sendMany = async function sendMany(args, help) {
|
||||
if (value == null)
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.');
|
||||
|
||||
if (uniq[hash])
|
||||
if (uniq.has(hash))
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.');
|
||||
|
||||
uniq[hash] = true;
|
||||
uniq.add(hash);
|
||||
|
||||
output = new Output();
|
||||
output.value = value;
|
||||
|
||||
@ -3070,7 +3070,7 @@ function BlockRecord(hash, height, ts) {
|
||||
this.height = height != null ? height : -1;
|
||||
this.ts = ts || 0;
|
||||
this.hashes = [];
|
||||
this.index = {};
|
||||
this.index = new Set();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3080,10 +3080,10 @@ function BlockRecord(hash, height, ts) {
|
||||
*/
|
||||
|
||||
BlockRecord.prototype.add = function add(hash) {
|
||||
if (this.index[hash])
|
||||
if (this.index.has(hash))
|
||||
return false;
|
||||
|
||||
this.index[hash] = true;
|
||||
this.index.add(hash);
|
||||
this.hashes.push(hash);
|
||||
|
||||
return true;
|
||||
@ -3098,10 +3098,10 @@ BlockRecord.prototype.add = function add(hash) {
|
||||
BlockRecord.prototype.remove = function remove(hash) {
|
||||
let index;
|
||||
|
||||
if (!this.index[hash])
|
||||
if (!this.index.has(hash))
|
||||
return false;
|
||||
|
||||
delete this.index[hash];
|
||||
this.index.delete(hash);
|
||||
|
||||
// Fast case
|
||||
if (this.hashes[this.hashes.length - 1] === hash) {
|
||||
@ -3136,7 +3136,7 @@ BlockRecord.prototype.fromRaw = function fromRaw(data) {
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
let hash = br.readHash('hex');
|
||||
this.index[hash] = true;
|
||||
this.index.add(hash);
|
||||
this.hashes.push(hash);
|
||||
}
|
||||
|
||||
|
||||
@ -1956,8 +1956,8 @@ Wallet.prototype._setLookahead = async function setLookahead(acct, lookahead) {
|
||||
*/
|
||||
|
||||
Wallet.prototype.syncOutputDepth = async function syncOutputDepth(details) {
|
||||
let accounts = new Map();
|
||||
let derived = [];
|
||||
let accounts = {};
|
||||
|
||||
if (!details)
|
||||
return derived;
|
||||
@ -1971,15 +1971,13 @@ Wallet.prototype.syncOutputDepth = async function syncOutputDepth(details) {
|
||||
if (path.index === -1)
|
||||
continue;
|
||||
|
||||
if (!accounts[path.account])
|
||||
accounts[path.account] = [];
|
||||
if (!accounts.has(path.account))
|
||||
accounts.set(path.account, []);
|
||||
|
||||
accounts[path.account].push(path);
|
||||
accounts.get(path.account).push(path);
|
||||
}
|
||||
|
||||
accounts = util.values(accounts);
|
||||
|
||||
for (let paths of accounts) {
|
||||
for (let paths of accounts.values()) {
|
||||
let acct = paths[0].account;
|
||||
let receive = -1;
|
||||
let change = -1;
|
||||
|
||||
@ -68,7 +68,7 @@ async function updateTXDB() {
|
||||
batch.del(key);
|
||||
}
|
||||
|
||||
txs = util.values(txs);
|
||||
txs = getValues(txs);
|
||||
|
||||
await batch.write();
|
||||
await db.close();
|
||||
@ -129,6 +129,15 @@ function fromExtended(data, saveCoins) {
|
||||
return tx;
|
||||
}
|
||||
|
||||
function getValues(map) {
|
||||
let items = [];
|
||||
|
||||
for (let key of Object.keys(map))
|
||||
items.push(map[key]);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await db.open();
|
||||
batch = db.batch();
|
||||
|
||||
@ -19,7 +19,7 @@ tests.ca = {
|
||||
};
|
||||
|
||||
x509.allowUntrusted = true;
|
||||
x509.trusted = {};
|
||||
x509.trusted.clear();
|
||||
|
||||
describe('BIP70', function() {
|
||||
function testRequest(data) {
|
||||
|
||||
@ -29,10 +29,10 @@ function MemWallet(options) {
|
||||
this.changeDepth = 1;
|
||||
this.receive = null;
|
||||
this.change = null;
|
||||
this.map = {};
|
||||
this.coins = {};
|
||||
this.spent = {};
|
||||
this.paths = {};
|
||||
this.map = new Set();
|
||||
this.coins = new Map();
|
||||
this.spent = new Map();
|
||||
this.paths = new Map();
|
||||
this.balance = 0;
|
||||
this.txs = 0;
|
||||
this.filter = Bloom.fromRate(1000000, 0.001, -1);
|
||||
@ -105,7 +105,7 @@ MemWallet.prototype.createReceive = function createReceive() {
|
||||
let key = this.deriveReceive(index);
|
||||
let hash = key.getHash('hex');
|
||||
this.filter.add(hash, 'hex');
|
||||
this.paths[hash] = new Path(hash, 0, index);
|
||||
this.paths.set(hash, new Path(hash, 0, index));
|
||||
this.receive = key;
|
||||
return key;
|
||||
};
|
||||
@ -115,7 +115,7 @@ MemWallet.prototype.createChange = function createChange() {
|
||||
let key = this.deriveChange(index);
|
||||
let hash = key.getHash('hex');
|
||||
this.filter.add(hash, 'hex');
|
||||
this.paths[hash] = new Path(hash, 1, index);
|
||||
this.paths.set(hash, new Path(hash, 1, index));
|
||||
this.change = key;
|
||||
return key;
|
||||
};
|
||||
@ -145,22 +145,22 @@ MemWallet.prototype.deriveKey = function deriveKey(branch, index) {
|
||||
};
|
||||
|
||||
MemWallet.prototype.getKey = function getKey(hash) {
|
||||
let path = this.paths[hash];
|
||||
let path = this.paths.get(hash);
|
||||
if (!path)
|
||||
return;
|
||||
return this.derivePath(path);
|
||||
};
|
||||
|
||||
MemWallet.prototype.getPath = function getPath(hash) {
|
||||
return this.paths[hash];
|
||||
return this.paths.get(hash);
|
||||
};
|
||||
|
||||
MemWallet.prototype.getCoin = function getCoin(key) {
|
||||
return this.coins[key];
|
||||
return this.coins.get(key);
|
||||
};
|
||||
|
||||
MemWallet.prototype.getUndo = function getUndo(key) {
|
||||
return this.spent[key];
|
||||
return this.spent.get(key);
|
||||
};
|
||||
|
||||
MemWallet.prototype.addCoin = function addCoin(coin) {
|
||||
@ -169,22 +169,22 @@ MemWallet.prototype.addCoin = function addCoin(coin) {
|
||||
|
||||
this.filter.add(op.toRaw());
|
||||
|
||||
delete this.spent[key];
|
||||
this.spent.delete(key);
|
||||
|
||||
this.coins[key] = coin;
|
||||
this.coins.set(key, coin);
|
||||
this.balance += coin.value;
|
||||
};
|
||||
|
||||
MemWallet.prototype.removeCoin = function removeCoin(key) {
|
||||
let coin = this.coins[key];
|
||||
let coin = this.coins.get(key);
|
||||
|
||||
if (!coin)
|
||||
return;
|
||||
|
||||
this.spent[key] = coin;
|
||||
this.spent.set(key, coin);
|
||||
this.balance -= coin.value;
|
||||
|
||||
delete this.coins[key];
|
||||
this.coins.delete(key);
|
||||
};
|
||||
|
||||
MemWallet.prototype.getAddress = function getAddress() {
|
||||
@ -200,7 +200,12 @@ MemWallet.prototype.getChange = function getChange() {
|
||||
};
|
||||
|
||||
MemWallet.prototype.getCoins = function getCoins() {
|
||||
return util.values(this.coins);
|
||||
let coins = [];
|
||||
|
||||
for (let coin of this.coins.values())
|
||||
coins.push(coin);
|
||||
|
||||
return coins;
|
||||
};
|
||||
|
||||
MemWallet.prototype.syncKey = function syncKey(path) {
|
||||
@ -245,7 +250,7 @@ MemWallet.prototype.addTX = function addTX(tx, height) {
|
||||
if (height == null)
|
||||
height = -1;
|
||||
|
||||
if (this.map[hash])
|
||||
if (this.map.has(hash))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
@ -282,7 +287,7 @@ MemWallet.prototype.addTX = function addTX(tx, height) {
|
||||
|
||||
if (result) {
|
||||
this.txs++;
|
||||
this.map[hash] = true;
|
||||
this.map.add(hash);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -293,7 +298,7 @@ MemWallet.prototype.removeTX = function removeTX(tx, height) {
|
||||
let result = false;
|
||||
let i, op, coin, input;
|
||||
|
||||
if (!this.map[hash])
|
||||
if (!this.map.has(hash))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < tx.outputs.length; i++) {
|
||||
@ -324,7 +329,7 @@ MemWallet.prototype.removeTX = function removeTX(tx, height) {
|
||||
if (result)
|
||||
this.txs--;
|
||||
|
||||
delete this.map[hash];
|
||||
this.map.delete(hash);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user