refactor: use maps and sets wherever possible.

This commit is contained in:
Christopher Jeffrey 2017-07-25 05:15:47 -07:00
parent 590c4350e9
commit 7eefb773be
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
31 changed files with 200 additions and 203 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -55,7 +55,7 @@ SOCKS.states = {
RESOLVE_DONE: 7
};
SOCKS.statesByVal = util.revMap(SOCKS.states);
SOCKS.statesByVal = util.reverse(SOCKS.states);
SOCKS.errors = [
'',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,7 +19,7 @@ tests.ca = {
};
x509.allowUntrusted = true;
x509.trusted = {};
x509.trusted.clear();
describe('BIP70', function() {
function testRequest(data) {

View File

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