refactor: style for const/let and returns.

This commit is contained in:
Christopher Jeffrey 2017-07-30 10:41:58 -07:00
parent 6f3988e861
commit 55cf07a871
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
113 changed files with 1618 additions and 1521 deletions

View File

@ -1,16 +1,17 @@
{
"extends": "eslint:recommended",
"env": {
"browser": true,
"es6": true,
"node": true,
"mocha": true
"mocha": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 8
},
"rules": {
"strict": 2,
"consistent-return": "off",
"func-name-matching": "off",
"indent": ["error", 2, {
"SwitchCase": 1,
"CallExpression": {
@ -18,28 +19,37 @@
},
"ArrayExpression": "off"
}],
"handle-callback-err": "off",
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "always"],
"no-console": 0,
"no-buffer-constructor": "error",
"no-console": "off",
"no-cond-assign": "off",
"no-extra-semi": "off",
"no-fallthrough": "off",
"no-func-assign": "off",
"no-param-reassign": "off",
"no-shadow-restricted-names": "error",
"no-tabs": "error",
"no-unused-vars": ["error", {
"vars": "all",
"args": "none",
"ignoreRestSiblings": false
}],
"no-func-assign": 0,
"no-cond-assign": 0,
"no-unreachable": 0,
"no-fallthrough": 0,
"no-useless-escape": 0,
"no-unsafe-finally": 0,
"no-extra-semi": 0,
"handle-callback-err": 0,
"no-buffer-constructor": 2,
"no-tabs": 2,
"no-use-before-define": ["error", {
"functions": false,
"classes": false
}],
"no-unreachable": "off",
"no-useless-escape": "off",
"no-unsafe-finally": "off",
"no-var": "error",
"prefer-const": ["error", {
"destructuring": "all",
"ignoreReadBeforeAssign": true
}]
}],
"quotes": ["error", "single"],
"semi": ["error", "always"],
"strict": "error",
"valid-jsdoc": "error"
}
}

View File

@ -19,6 +19,7 @@ const btx = { tx: block.txs[397], view: new CoinView() };
const tx3 = parseTX('../test/data/tx3.hex');
const hex = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8');
const raw = Buffer.from(hex.trim(), 'hex');
const tx = TX.fromRaw(raw);
{
const tx = json.txs[397];
@ -153,25 +154,25 @@ for (let i = 0; i < 100; i++) {
});
}
const tx = mtx.toTX();
const tx2 = mtx.toTX();
{
const end = bench('input hashes');
for (let i = 0; i < 1000; i++)
tx.getInputHashes(null, 'hex');
tx2.getInputHashes(null, 'hex');
end(1000);
}
{
const end = bench('output hashes');
for (let i = 0; i < 1000; i++)
tx.getOutputHashes('hex');
tx2.getOutputHashes('hex');
end(1000);
}
{
const end = bench('all hashes');
for (let i = 0; i < 1000; i++)
tx.getHashes(null, 'hex');
tx2.getHashes(null, 'hex');
end(1000);
}

View File

@ -24,6 +24,7 @@ const walletdb = new WalletDB({
const wallet = await walletdb.create();
const addrs = [];
let tx;
// Accounts
{
@ -65,7 +66,7 @@ const walletdb = new WalletDB({
mtx.addOutput(addrs[(i + 1) % addrs.length], 50460);
mtx.addOutput(addrs[(i + 2) % addrs.length], 50460);
mtx.addOutput(addrs[(i + 3) % addrs.length], 50460);
const tx = mtx.toTX();
tx = mtx.toTX();
jobs.push(walletdb.addTX(tx));
}
@ -88,7 +89,7 @@ const walletdb = new WalletDB({
mtx.addOutput(addrs[(i + 1) % addrs.length], 50460);
mtx.addOutput(addrs[(i + 2) % addrs.length], 50460);
mtx.addOutput(addrs[(i + 3) % addrs.length], 50460);
const tx = mtx.toTX();
tx = mtx.toTX();
jobs.push(walletdb.addTX(tx));
}

View File

@ -19,10 +19,9 @@ if (process.argv.indexOf('--version') !== -1
throw new Error('Could not exit.');
}
const bcoin = require('../');
const plugin = require('../lib/wallet/plugin');
const FullNode = require('../lib/node/fullnode');
const node = new bcoin.fullnode({
const node = new FullNode({
config: true,
argv: true,
env: true,
@ -37,8 +36,10 @@ const node = new bcoin.fullnode({
});
// Temporary hack
if (!node.config.bool('no-wallet') && !node.has('walletdb'))
if (!node.config.bool('no-wallet') && !node.has('walletdb')) {
const plugin = require('../lib/wallet/plugin');
node.use(plugin);
}
process.on('unhandledRejection', (err, promise) => {
throw err;

View File

@ -5,11 +5,11 @@
process.title = 'bcoin';
const assert = require('assert');
const bcoin = require('../');
const plugin = require('../lib/wallet/plugin');
const util = bcoin.util;
const SPVNode = require('../lib/node/spvnode');
const util = require('../lib/utils/util');
const Outpoint = require('../lib/primitives/outpoint');
const node = bcoin.spvnode({
const node = SPVNode({
config: true,
argv: true,
env: true,
@ -24,8 +24,10 @@ const node = bcoin.spvnode({
});
// Temporary hack
if (!node.has('walletdb'))
if (!node.has('walletdb')) {
const plugin = require('../lib/wallet/plugin');
node.use(plugin);
}
process.on('unhandledRejection', (err, promise) => {
throw err;
@ -38,7 +40,7 @@ process.on('unhandledRejection', (err, promise) => {
if (node.config.bool('test')) {
node.pool.watchAddress('1VayNert3x1KzbpzMGt2qdqrAThiRovi8');
node.pool.watchOutpoint(new bcoin.outpoint());
node.pool.watchOutpoint(new Outpoint());
node.on('block', (block) => {
assert(block.txs.length >= 1);
if (block.txs.length > 1)

View File

@ -141,7 +141,7 @@ PaymentDetails.prototype.getData = function getData(enc) {
let data = this.merchantData;
if (!data)
return;
return null;
if (!enc)
return data;

View File

@ -92,6 +92,8 @@ x509.getSubjectOID = function getSubjectOID(cert, oid) {
if (entry.type === oid)
return entry.value;
}
return null;
};
/**

View File

@ -350,7 +350,7 @@ Chain.prototype.verify = async function verify(block, prev, flags) {
}
// Check the commitment hash for segwit.
let commit = null;
let commit;
if (state.hasWitness()) {
commit = block.getCommitmentHash();
if (commit) {
@ -581,11 +581,12 @@ Chain.prototype.verifyDuplicates = async function verifyDuplicates(block, prev,
*/
Chain.prototype.verifyInputs = async function verifyInputs(block, prev, state) {
const view = new CoinView();
if (this.options.spv)
return view;
const interval = this.network.halvingInterval;
const view = new CoinView();
const height = prev.height + 1;
const historical = prev.isHistorical();
const jobs = [];
@ -1598,7 +1599,7 @@ Chain.prototype.resolveOrphan = function resolveOrphan(hash) {
const orphan = this.orphanPrev.get(hash);
if (!orphan)
return;
return null;
return this.removeOrphan(orphan);
};
@ -1626,8 +1627,8 @@ Chain.prototype.purgeOrphans = function purgeOrphans() {
Chain.prototype.limitOrphans = function limitOrphans() {
const now = util.now();
let oldest = null;
let oldest;
for (const orphan of this.orphanMap.values()) {
if (now < orphan.time + 60 * 60) {
if (!oldest || orphan.time < oldest.time)
@ -1896,9 +1897,9 @@ Chain.prototype._getLocator = async function getLocator(start) {
hash = await this.db.getHash(height);
assert(hash);
} else {
const entry = await entry.getAncestor(height);
assert(entry);
hash = entry.hash;
const ancestor = await entry.getAncestor(height);
assert(ancestor);
hash = ancestor.hash;
}
hashes.push(hash);

View File

@ -309,7 +309,7 @@ ChainDB.prototype.getHash = async function getHash(height) {
assert(typeof height === 'number');
if (height < 0)
return;
return null;
const entry = this.cacheHeight.get(height);
@ -319,7 +319,7 @@ ChainDB.prototype.getHash = async function getHash(height) {
const hash = await this.db.get(layout.H(height));
if (!hash)
return;
return null;
return hash.toString('hex');
};
@ -335,26 +335,25 @@ ChainDB.prototype.getEntryByHeight = async function getEntryByHeight(height) {
assert(typeof height === 'number');
if (height < 0)
return;
return null;
const cache = this.cacheHeight.get(height);
if (cache)
return cache;
let hash = await this.db.get(layout.H(height));
const data = await this.db.get(layout.H(height));
if (!hash)
return;
if (!data)
return null;
hash = hash.toString('hex');
const hash = data.toString('hex');
const state = this.chain.state;
const entry = await this.getEntryByHash(hash);
if (!entry)
return;
return null;
// By the time getEntry has completed,
// a reorg may have occurred. This entry
@ -376,7 +375,7 @@ ChainDB.prototype.getEntryByHash = async function getEntryByHash(hash) {
assert(typeof hash === 'string');
if (hash === encoding.NULL_HASH)
return;
return null;
const cache = this.cacheHash.get(hash);
@ -386,7 +385,7 @@ ChainDB.prototype.getEntryByHash = async function getEntryByHash(hash) {
const raw = await this.db.get(layout.e(hash));
if (!raw)
return;
return null;
const entry = ChainEntry.fromRaw(this.chain, raw);
@ -441,7 +440,7 @@ ChainDB.prototype.getState = async function getState() {
const data = await this.db.get(layout.R);
if (!data)
return;
return null;
return ChainState.fromRaw(data);
};
@ -472,7 +471,7 @@ ChainDB.prototype.getFlags = async function getFlags() {
const data = await this.db.get(layout.O);
if (!data)
return;
return null;
return ChainFlags.fromRaw(data);
};
@ -717,10 +716,11 @@ ChainDB.prototype.prune = async function prune(tip) {
if (flags.prune)
throw new Error('Chain is already pruned.');
const height = await this.getHeight(tip);
if (height <= pruneAfter + keepBlocks)
return false;
const height = await this.getHeight(tip);
const start = pruneAfter + 1;
const end = height - keepBlocks;
const batch = this.db.batch();
@ -765,7 +765,7 @@ ChainDB.prototype.getNextHash = async function getNextHash(hash) {
const data = await this.db.get(layout.n(hash));
if (!data)
return;
return null;
return data.toString('hex');
};
@ -788,12 +788,12 @@ ChainDB.prototype.isMainChain = async function isMainChain(hash) {
if (hash === encoding.NULL_HASH)
return false;
let entry = this.cacheHash.get(hash);
const cacheHash = this.cacheHash.get(hash);
if (entry) {
entry = this.cacheHeight.get(entry.height);
if (entry)
return entry.hash === hash;
if (cacheHash) {
const cacheHeight = this.cacheHeight.get(cacheHash.height);
if (cacheHeight)
return cacheHeight.hash === hash;
}
if (await this.getNextHash(hash))
@ -838,7 +838,7 @@ ChainDB.prototype.getTips = function getTips() {
ChainDB.prototype.readCoin = async function readCoin(prevout) {
if (this.options.spv)
return;
return null;
const {hash, index} = prevout;
const key = prevout.toKey();
@ -852,7 +852,7 @@ ChainDB.prototype.readCoin = async function readCoin(prevout) {
const raw = await this.db.get(layout.c(hash, index));
if (!raw)
return;
return null;
if (state === this.state)
this.coinCache.set(key, raw);
@ -873,7 +873,7 @@ ChainDB.prototype.getCoin = async function getCoin(hash, index) {
const coin = await this.readCoin(prevout);
if (!coin)
return;
return null;
return coin.toCoin(prevout);
};
@ -971,7 +971,7 @@ ChainDB.prototype.getBlock = async function getBlock(hash) {
const data = await this.getRawBlock(hash);
if (!data)
return;
return null;
return Block.fromRaw(data);
};
@ -985,12 +985,12 @@ ChainDB.prototype.getBlock = async function getBlock(hash) {
ChainDB.prototype.getRawBlock = async function getRawBlock(block) {
if (this.options.spv)
return;
return null;
const hash = await this.getHash(block);
if (!hash)
return;
return null;
return await this.db.get(layout.b(hash));
};
@ -1033,12 +1033,12 @@ ChainDB.prototype.getBlockView = async function getBlockView(block) {
ChainDB.prototype.getMeta = async function getMeta(hash) {
if (!this.options.indexTX)
return;
return null;
const data = await this.db.get(layout.t(hash));
if (!data)
return;
return null;
return TXMeta.fromRaw(data);
};
@ -1052,8 +1052,10 @@ ChainDB.prototype.getMeta = async function getMeta(hash) {
ChainDB.prototype.getTX = async function getTX(hash) {
const meta = await this.getMeta(hash);
if (!meta)
return;
return null;
return meta.tx;
};
@ -1064,7 +1066,7 @@ ChainDB.prototype.getTX = async function getTX(hash) {
ChainDB.prototype.hasTX = function hasTX(hash) {
if (!this.options.indexTX)
return Promise.resolve();
return Promise.resolve(false);
return this.db.has(layout.t(hash));
};
@ -1077,14 +1079,14 @@ ChainDB.prototype.hasTX = function hasTX(hash) {
*/
ChainDB.prototype.getCoinsByAddress = async function getCoinsByAddress(addrs) {
const coins = [];
if (!this.options.indexAddress)
return coins;
return [];
if (!Array.isArray(addrs))
addrs = [addrs];
const coins = [];
for (const addr of addrs) {
const hash = Address.getHash(addr);
@ -1112,11 +1114,11 @@ ChainDB.prototype.getCoinsByAddress = async function getCoinsByAddress(addrs) {
*/
ChainDB.prototype.getHashesByAddress = async function getHashesByAddress(addrs) {
const hashes = Object.create(null);
if (!this.options.indexTX || !this.options.indexAddress)
return [];
const hashes = Object.create(null);
for (const addr of addrs) {
const hash = Address.getHash(addr);
@ -1158,15 +1160,14 @@ ChainDB.prototype.getTXByAddress = async function getTXByAddress(addrs) {
*/
ChainDB.prototype.getMetaByAddress = async function getTXByAddress(addrs) {
const txs = [];
if (!this.options.indexTX || !this.options.indexAddress)
return txs;
return [];
if (!Array.isArray(addrs))
addrs = [addrs];
const hashes = await this.getHashesByAddress(addrs);
const txs = [];
for (const hash of hashes) {
const tx = await this.getMeta(hash);
@ -1638,7 +1639,7 @@ ChainDB.prototype.saveBlock = async function saveBlock(entry, block, view) {
ChainDB.prototype.removeBlock = async function removeBlock(entry) {
if (this.options.spv)
return;
return new CoinView();
const block = await this.getBlock(entry.hash);
@ -1734,10 +1735,11 @@ ChainDB.prototype.connectBlock = async function connectBlock(entry, block, view)
*/
ChainDB.prototype.disconnectBlock = async function disconnectBlock(entry, block) {
const view = new CoinView();
if (this.options.spv)
return view;
const view = new CoinView();
const hash = block.hash();
const undo = await this.getUndoCoins(hash);

View File

@ -130,8 +130,10 @@ ChainEntry.fromOptions = function fromOptions(chain, options, prev) {
ChainEntry.prototype.getProof = function getProof() {
const target = consensus.fromCompact(this.bits);
if (target.isNeg() || target.cmpn(0) === 0)
return new BN(0);
return ChainEntry.MAX_CHAINWORK.div(target.iaddn(1));
};
@ -194,7 +196,7 @@ ChainEntry.prototype.isMainChain = async function isMainChain() {
ChainEntry.prototype.getAncestor = async function getAncestor(height) {
if (height < 0)
return;
return null;
assert(height >= 0);
assert(height <= this.height);
@ -237,8 +239,10 @@ ChainEntry.prototype.getPrevCache = function getPrevCache() {
ChainEntry.prototype.getNext = async function getNext() {
const hash = await this.chain.db.getNextHash(this.hash);
if (!hash)
return;
return null;
return await this.chain.db.getEntry(hash);
};
@ -252,11 +256,11 @@ ChainEntry.prototype.getNextEntry = async function getNextEntry() {
const entry = await this.chain.db.getEntry(this.height + 1);
if (!entry)
return;
return null;
// Not on main chain.
if (entry.prevBlock !== this.hash)
return;
return null;
return entry;
};

View File

@ -75,10 +75,9 @@ const layout = {
return key.slice(1, 65);
},
Cc: function Cc(key) {
let hash, index;
assert(typeof key === 'string');
let hash, index;
if (key.length === 139) {
hash = key.slice(65, 129);
index = +key.slice(129);

View File

@ -76,11 +76,11 @@ const layout = {
},
T: function T(addr, hash) {
let len = addr.length;
let key;
if (typeof addr === 'string')
len /= 2;
let key;
if (len === 32) {
key = Buffer.allocUnsafe(65);
key[0] = 0xab; // W + T
@ -99,13 +99,13 @@ const layout = {
},
C: function C(addr, hash, index) {
let len = addr.length;
let key;
assert(typeof index === 'number');
if (typeof addr === 'string')
len /= 2;
let key;
if (len === 32) {
key = Buffer.allocUnsafe(69);
key[0] = 0x9a; // W + C
@ -130,10 +130,9 @@ const layout = {
return key.toString('hex', 1, 33);
},
Cc: function Cc(key) {
let hash, index;
assert(Buffer.isBuffer(key));
let hash, index;
if (key.length === 69) {
hash = key.toString('hex', 33, 65);
index = key.readUInt32BE(65, 0);
@ -165,7 +164,7 @@ function write(data, str, off) {
if (Buffer.isBuffer(str))
return str.copy(data, off);
assert(typeof str === 'string');
data.write(str, off, 'hex');
return data.write(str, off, 'hex');
}
function pair(prefix, hash) {

View File

@ -334,6 +334,10 @@ function decompressKey(key) {
return out;
}
// Make eslint happy.
compressValue;
decompressValue;
/*
* Expose
*/

View File

@ -123,8 +123,7 @@ AEAD.prototype.auth = function auth(data) {
AEAD.prototype.finish = function finish() {
const len = Buffer.allocUnsafe(16);
let lo = 0;
let hi = 0;
let lo, hi;
// The RFC says these are supposed to be
// uint32le, but their own fucking test

View File

@ -8,6 +8,8 @@
* Entered into the public domain by Vincent Rijmen.
*/
/* eslint no-use-before-define: "off" */
'use strict';
const assert = require('assert');

View File

@ -6,6 +6,8 @@
'use strict';
const assert = require('assert');
/**
* memcmp in constant time (can only return true or false).
* This protects us against timing attacks when
@ -19,11 +21,8 @@
*/
module.exports = function ccmp(a, b) {
if (!Buffer.isBuffer(a))
return false;
if (!Buffer.isBuffer(b))
return false;
assert(Buffer.isBuffer(a));
assert(Buffer.isBuffer(b));
if (b.length === 0)
return a.length === 0;

View File

@ -95,12 +95,12 @@ HmacDRBG.prototype.update = function update(seed) {
};
HmacDRBG.prototype.generate = function generate(len) {
const data = Buffer.allocUnsafe(len);
let pos = 0;
if (this.rounds > RESEED_INTERVAL)
throw new Error('Reseed is required.');
const data = Buffer.allocUnsafe(len);
let pos = 0;
while (pos < len) {
this.V = digest.hmac(HASH_ALG, this.V, this.K);
this.V.copy(data, pos);

View File

@ -155,15 +155,21 @@ Poly1305.prototype.update = function update(data) {
// handle leftover
if (this.leftover) {
let want = 16 - this.leftover;
if (want > bytes)
want = bytes;
for (let i = 0; i < want; i++)
this.buffer[this.leftover + i] = data[m + i];
bytes -= want;
m += want;
this.leftover += want;
if (this.leftover < 16)
return;
this.blocks(this.buffer, 16, 0);
this.leftover = 0;
}
@ -262,8 +268,10 @@ Poly1305.prototype.finish = function finish() {
// zero out the state
for (let i = 0; i < 10; i++)
this.h[i] = 0;
for (let i = 0; i < 10; i++)
this.r[i] = 0;
for (let i = 0; i < 8; i++)
this.pad[i] = 0;

View File

@ -101,12 +101,12 @@ schnorr.sign = function sign(msg, key, pubNonce) {
const prv = new BN(key);
const drbg = schnorr.drbg(msg, key, pubNonce);
const len = curve.n.byteLength();
let pn = null;
let sig = null;
let pn;
if (pubNonce)
pn = curve.decodePoint(pubNonce);
let sig;
while (!sig) {
const k = new BN(drbg.generate(len));
sig = schnorr.trySign(msg, prv, k, pn);
@ -210,8 +210,7 @@ schnorr.recover = function recover(signature, msg) {
schnorr.combineSigs = function combineSigs(sigs) {
let s = new BN(0);
let r = null;
let last = null;
let r, last;
for (let i = 0; i < sigs.length; i++) {
const sig = new Signature(sigs[i]);
@ -325,8 +324,8 @@ schnorr.drbg = function drbg(msg, priv, data) {
schnorr.generateNoncePair = function generateNoncePair(msg, priv, data) {
const drbg = schnorr.drbg(msg, priv, data);
const len = curve.n.byteLength();
let k;
let k;
for (;;) {
k = new BN(drbg.generate(len));

View File

@ -146,7 +146,7 @@ ec.recover = function recover(msg, sig, j, compress) {
try {
point = secp256k1.recoverPubKey(msg, sig, j);
} catch (e) {
return;
return null;
}
return Buffer.from(point.encode('array', compress));
@ -191,7 +191,8 @@ ec.verify = function verify(msg, sig, key) {
ec.publicKeyVerify = function publicKeyVerify(key) {
try {
return secp256k1.keyPair({ pub: key }).validate();
const pub = secp256k1.keyPair({ pub: key });
return pub.validate();
} catch (e) {
return false;
}
@ -324,13 +325,14 @@ function normalizeLength(sig) {
function getLength(buf, p) {
const initial = buf[p.place++];
const len = initial & 0xf;
let off = p.place;
let val = 0;
if (!(initial & 0x80))
return initial;
const len = initial & 0xf;
let off = p.place;
let val = 0;
for (let i = 0; i < len; i++, off++) {
val <<= 8;
val |= buf[off];

View File

@ -127,13 +127,13 @@ ec.recover = function recover(msg, sig, j, compress) {
try {
sig = secp256k1.signatureImport(sig);
} catch (e) {
return;
return null;
}
try {
key = secp256k1.recover(msg, sig, j, compress);
} catch (e) {
return;
return null;
}
return key;
@ -195,13 +195,11 @@ ec.privateKeyVerify = function privateKeyVerify(key) {
*/
ec.sign = function sign(msg, key) {
let sig;
assert(Buffer.isBuffer(msg));
assert(Buffer.isBuffer(key));
// Sign message
sig = secp256k1.sign(msg, key);
let sig = secp256k1.sign(msg, key);
// Ensure low S value
sig = secp256k1.signatureNormalize(sig.signature);
@ -239,10 +237,10 @@ ec.toDER = function toDER(sig) {
*/
ec.isLowS = function isLowS(sig) {
let rs, s;
let s;
try {
rs = secp256k1.signatureImport(sig);
const rs = secp256k1.signatureImport(sig);
s = rs.slice(32, 64);
} catch (e) {
return false;

View File

@ -167,6 +167,7 @@ SHA256.prototype._finish = function _finish(out) {
*/
SHA256.prototype.transform = function transform(chunk, pos) {
const w = this.w;
let a = this.s[0];
let b = this.s[1];
let c = this.s[2];
@ -175,7 +176,6 @@ SHA256.prototype.transform = function transform(chunk, pos) {
let f = this.s[5];
let g = this.s[6];
let h = this.s[7];
const w = this.w;
let i = 0;
for (; i < 16; i++)
@ -185,13 +185,11 @@ SHA256.prototype.transform = function transform(chunk, pos) {
w[i] = sigma1(w[i - 2]) + w[i - 7] + sigma0(w[i - 15]) + w[i - 16];
for (i = 0; i < 64; i++) {
let t1, t2;
t1 = h + Sigma1(e);
let t1 = h + Sigma1(e);
t1 += Ch(e, f, g);
t1 += K[i] + w[i];
t2 = Sigma0(a);
let t2 = Sigma0(a);
t2 += Maj(a, b, c);
h = g;

View File

@ -33,7 +33,6 @@ function siphash24(data, key, shift) {
const f1 = U64(0, 0xff);
const k0 = U64.fromRaw(key, 0);
const k1 = U64.fromRaw(key, 8);
let p = 0;
// Init
const v0 = c0.ixor(k0);
@ -42,6 +41,7 @@ function siphash24(data, key, shift) {
const v3 = c3.ixor(k1);
// Blocks
let p = 0;
for (let i = 0; i < blocks; i++) {
const d = U64.fromRaw(data, p);
p += 8;

View File

@ -271,7 +271,7 @@ LowlevelUp.prototype.get = function get(key) {
this.binding.get(key, (err, result) => {
if (err) {
if (isNotFound(err)) {
resolve();
resolve(null);
return;
}
reject(err);

View File

@ -45,7 +45,7 @@ MemDB.prototype.search = function search(key) {
const node = this.tree.search(key);
if (!node)
return;
return undefined;
return node.value;
};
@ -449,13 +449,13 @@ Iterator.prototype.init = function init() {
Iterator.prototype.next = function next(callback) {
const options = this.options;
const iter = this.iter;
let key, value, result;
if (!this.iter) {
setImmediate(() => callback(new Error('Cannot call next.')));
return;
}
let result;
if (options.reverse) {
result = iter.prev();
@ -499,8 +499,8 @@ Iterator.prototype.next = function next(callback) {
this.total += 1;
}
key = iter.key;
value = iter.value;
let key = iter.key;
let value = iter.value;
if (!options.keys)
key = DUMMY;

View File

@ -65,13 +65,12 @@ common.cache = new LRU(500);
*/
common.parsePath = function parsePath(path, max) {
const parts = path.split('/');
const root = parts.shift();
const result = [];
if (max == null)
max = common.MAX_INDEX;
const parts = path.split('/');
const root = parts.shift();
if (root !== 'm'
&& root !== 'M'
&& root !== 'm\''
@ -79,6 +78,8 @@ common.parsePath = function parsePath(path, max) {
throw new Error('Bad path root.');
}
const result = [];
for (let index of parts) {
const hardened = index[index.length - 1] === '\'';

View File

@ -177,11 +177,6 @@ Mnemonic.prototype.getPhrase = function getPhrase() {
if (this.phrase)
return this.phrase;
let phrase = [];
const wordlist = Mnemonic.getWordlist(this.language);
const ent = this.getEntropy();
// Include the first `ENT / 32` bits
// of the hash (the checksum).
const bits = this.bits + (this.bits / 32);
@ -189,12 +184,16 @@ Mnemonic.prototype.getPhrase = function getPhrase() {
// Append the hash to the entropy to
// make things easy when grabbing
// the checksum bits.
const ent = this.getEntropy();
const entropy = Buffer.allocUnsafe(Math.ceil(bits / 8));
ent.copy(entropy, 0);
digest.sha256(ent).copy(entropy, ent.length);
// Build the mnemonic by reading
// 11 bit indexes from the entropy.
const wordlist = Mnemonic.getWordlist(this.language);
let phrase = [];
for (let i = 0; i < bits / 11; i++) {
let index = 0;
for (let j = 0; j < 11; j++) {

View File

@ -413,11 +413,9 @@ HDPrivateKey.prototype.equal = function equal(obj) {
*/
HDPrivateKey.prototype.compare = function compare(key) {
let cmp;
assert(HDPrivateKey.isHDPrivateKey(key));
cmp = this.depth - key.depth;
let cmp = this.depth - key.depth;
if (cmp !== 0)
return cmp;

View File

@ -335,11 +335,9 @@ HDPublicKey.prototype.equal = function equal(obj) {
*/
HDPublicKey.prototype.compare = function compare(key) {
let cmp;
assert(HDPublicKey.isHDPublicKey(key));
cmp = this.depth - key.depth;
let cmp = this.depth - key.depth;
if (cmp !== 0)
return cmp;

View File

@ -186,16 +186,22 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
let realm = options.realm;
if (user) {
if (typeof user === 'string')
if (typeof user === 'string') {
assert(user.length <= 255, 'Username too long.');
user = Buffer.from(user, 'utf8');
}
assert(Buffer.isBuffer(user));
assert(user.length <= 255, 'Username too long.');
user = digest.hash256(user);
}
if (typeof pass === 'string')
if (typeof pass === 'string') {
assert(pass.length <= 255, 'Password too long.');
pass = Buffer.from(pass, 'utf8');
}
assert(Buffer.isBuffer(pass));
assert(pass.length <= 255, 'Password too long.');
pass = digest.hash256(pass);
if (!realm)
@ -215,6 +221,9 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
if (!hdr)
return fail(res);
if (hdr.length > 1000)
return fail(res);
const parts = hdr.split(' ');
if (parts.length !== 2)
@ -230,6 +239,9 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
const password = items.join(':');
if (user) {
if (username.length > 255)
return fail(res);
const raw = Buffer.from(username, 'utf8');
const hash = digest.hash256(raw);
@ -237,6 +249,9 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
return fail(res);
}
if (password.length > 255)
return fail(res);
const raw = Buffer.from(password, 'utf8');
const hash = digest.hash256(raw);
@ -345,7 +360,9 @@ HTTPBase.prototype._readBody = function _readBody(req, enc, options, resolve, re
reject(new Error('Request body timed out.'));
}, options.timeout);
let cleanup = () => {
/* eslint no-use-before-define: "off" */
const cleanup = () => {
req.removeListener('data', onData);
req.removeListener('error', onError);
req.removeListener('end', onEnd);
@ -356,7 +373,7 @@ HTTPBase.prototype._readBody = function _readBody(req, enc, options, resolve, re
}
};
let onData = (data) => {
const onData = (data) => {
total += data.length;
hasData = true;
@ -368,12 +385,12 @@ HTTPBase.prototype._readBody = function _readBody(req, enc, options, resolve, re
body += decode.write(data);
};
let onError = (err) => {
const onError = (err) => {
cleanup();
reject(err);
};
let onEnd = () => {
const onEnd = () => {
cleanup();
if (hasData) {
@ -493,11 +510,10 @@ HTTPBase.prototype.handleHooks = async function handleHooks(req, res) {
*/
HTTPBase.prototype._initSockets = function _initSockets() {
let IOServer;
if (!this.config.sockets)
return;
let IOServer;
try {
IOServer = require('socket.io');
} catch (e) {
@ -608,12 +624,13 @@ HTTPBase.prototype.removeSocket = function removeSocket(socket) {
*/
HTTPBase.prototype.joinChannel = function joinChannel(socket, name) {
let list = this.channels.get(name);
let item = socket.channels.get(name);
if (item)
return;
let list = this.channels.get(name);
if (!list) {
list = new List();
this.channels.set(name, list);
@ -633,12 +650,13 @@ HTTPBase.prototype.joinChannel = function joinChannel(socket, name) {
*/
HTTPBase.prototype.leaveChannel = function leaveChannel(socket, name) {
const list = this.channels.get(name);
const item = socket.channels.get(name);
if (!item)
return;
const list = this.channels.get(name);
assert(list);
assert(list.remove(item));
@ -658,7 +676,7 @@ HTTPBase.prototype.channel = function channel(name) {
const list = this.channels.get(name);
if (!list)
return;
return null;
assert(list.size > 0);
@ -1088,7 +1106,7 @@ Route.prototype.match = function _match(pathname) {
const match = this.regex.exec(pathname);
if (!match)
return;
return null;
const params = Object.create(null);
@ -1135,7 +1153,7 @@ function Routes() {
Routes.prototype.getHandlers = function getHandlers(method) {
if (!method)
return;
return null;
method = method.toUpperCase();
@ -1149,7 +1167,7 @@ Routes.prototype.getHandlers = function getHandlers(method) {
case 'DELETE':
return this.del;
default:
return;
return null;
}
};
@ -1535,13 +1553,14 @@ WebSocket.prototype.init = function init() {
WebSocket.prototype.onevent = async function onevent(packet) {
const args = (packet.data || []).slice();
const type = args.shift() || '';
let ack, result;
let ack;
if (typeof args[args.length - 1] === 'function')
ack = args.pop();
else
ack = this.socket.ack(packet.id);
let result;
try {
result = await this.fire(type, args);
} catch (e) {
@ -1568,7 +1587,7 @@ WebSocket.prototype.fire = async function fire(type, args) {
const handler = this.hooks[type];
if (!handler)
return;
return undefined;
return await handler.call(this.context, args);
};
@ -1617,8 +1636,8 @@ function parsePairs(str, limit) {
for (const pair of parts) {
const index = pair.indexOf('=');
let key, value;
let key, value;
if (index === -1) {
key = pair;
value = '';

View File

@ -195,14 +195,13 @@ HTTPClient.prototype.onDisconnect = function onDisconnect() {
*/
HTTPClient.prototype._request = async function _request(method, endpoint, json) {
let query;
if (this.token) {
if (!json)
json = {};
json.token = this.token;
}
let query;
if (json && method === 'get') {
query = json;
json = null;
@ -221,7 +220,7 @@ HTTPClient.prototype._request = async function _request(method, endpoint, json)
});
if (res.statusCode === 404)
return;
return null;
if (res.statusCode === 401)
throw new Error('Unauthorized (bad API key).');
@ -457,22 +456,6 @@ HTTPClient.prototype.leave = function leave(id) {
});
};
/**
* Listen for events on all wallets.
*/
HTTPClient.prototype.all = function all(token) {
return this.join('!all', token);
};
/**
* Unlisten for events on all wallets.
*/
HTTPClient.prototype.none = function none() {
return this.leave('!all');
};
/**
* Get list of all wallet IDs.
* @returns {Promise}
@ -974,7 +957,7 @@ HTTPClient.prototype.createNested = function createNested(id, options) {
function toHex(obj) {
if (!obj)
return;
return null;
if (obj.toRaw)
obj = obj.toRaw();

View File

@ -424,8 +424,6 @@ Request.prototype.finish = function finish(err) {
};
Request.prototype._onResponse = function _onResponse(response) {
let type = response.headers['content-type'];
const length = response.headers['content-length'];
const location = response.headers['location'];
if (location) {
@ -440,13 +438,16 @@ Request.prototype._onResponse = function _onResponse(response) {
return;
}
type = parseType(type);
const contentType = response.headers['content-type'];
const type = parseType(contentType);
if (!this.options.isExpected(type)) {
this.finish(new Error('Wrong content-type for response.'));
return;
}
const length = response.headers['content-length'];
if (this.options.isOverflow(length)) {
this.finish(new Error('Response exceeded limit.'));
return;

File diff suppressed because it is too large Load Diff

View File

@ -112,8 +112,6 @@ RPCBase.prototype.call = async function call(body, query) {
}
for (const cmd of cmds) {
let result;
if (!cmd || typeof cmd !== 'object') {
out.push({
result: null,
@ -183,6 +181,7 @@ RPCBase.prototype.call = async function call(body, query) {
cmd.method = 'getworklp';
}
let result;
try {
result = await this.execute(cmd);
} catch (err) {

View File

@ -143,12 +143,12 @@ HTTPServer.prototype.initRouter = function initRouter() {
this.get('/coin/address/:address', async (req, res) => {
const valid = req.valid();
const address = valid.str('address');
const result = [];
enforce(address, 'Address is required.');
enforce(!this.chain.options.spv, 'Cannot get coins in SPV mode.');
const coins = await this.node.getCoinsByAddress(address);
const result = [];
for (const coin of coins)
result.push(coin.getJSON(this.network));
@ -180,12 +180,12 @@ HTTPServer.prototype.initRouter = function initRouter() {
this.post('/coin/address', async (req, res) => {
const valid = req.valid();
const address = valid.array('addresses');
const result = [];
enforce(address, 'Address is required.');
enforce(!this.chain.options.spv, 'Cannot get coins in SPV mode.');
const coins = await this.node.getCoinsByAddress(address);
const result = [];
for (const coin of coins)
result.push(coin.getJSON(this.network));
@ -217,12 +217,12 @@ HTTPServer.prototype.initRouter = function initRouter() {
this.get('/tx/address/:address', async (req, res) => {
const valid = req.valid();
const address = valid.str('address');
const result = [];
enforce(address, 'Address is required.');
enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.');
const metas = await this.node.getMetaByAddress(address);
const result = [];
for (const meta of metas) {
const view = await this.node.getMetaView(meta);
@ -236,12 +236,12 @@ HTTPServer.prototype.initRouter = function initRouter() {
this.post('/tx/address', async (req, res) => {
const valid = req.valid();
const address = valid.array('address');
const result = [];
enforce(address, 'Address is required.');
enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.');
const metas = await this.node.getMetaByAddress(address);
const result = [];
for (const meta of metas) {
const view = await this.node.getMetaView(meta);
@ -285,11 +285,10 @@ HTTPServer.prototype.initRouter = function initRouter() {
// Mempool snapshot
this.get('/mempool', async (req, res) => {
const result = [];
enforce(this.mempool, 'No mempool available.');
const hashes = this.mempool.getSnapshot();
const result = [];
for (const hash of hashes)
result.push(util.revHex(hash));
@ -361,16 +360,21 @@ HTTPServer.prototype.initSockets = function initSockets() {
HTTPServer.prototype.handleSocket = function handleSocket(socket) {
socket.hook('auth', (args) => {
const valid = new Validator([args]);
const hash = this.options.apiHash;
const key = valid.str(0);
if (socket.auth)
throw new Error('Already authed.');
if (!this.options.noAuth) {
if (!ccmp(hash256(key), hash))
throw new Error('Bad key.');
const valid = new Validator([args]);
const key = valid.str(0, '');
if (key.length > 255)
throw new Error('Invalid API key.');
const data = Buffer.from(key, 'utf8');
const hash = digest.hash256(data);
if (!ccmp(hash, this.options.apiHash))
throw new Error('Invalid API key.');
}
socket.auth = true;
@ -593,10 +597,10 @@ HTTPServer.prototype.bindChain = function bindChain() {
*/
HTTPServer.prototype.filterBlock = function filterBlock(socket, block) {
const txs = [];
if (!socket.filter)
return txs;
return [];
const txs = [];
for (const tx of block.txs) {
if (this.filterTX(socket, tx))
@ -615,11 +619,11 @@ HTTPServer.prototype.filterBlock = function filterBlock(socket, block) {
*/
HTTPServer.prototype.filterTX = function filterTX(socket, tx) {
let found = false;
if (!socket.filter)
return false;
let found = false;
for (let i = 0; i < tx.outputs.length; i++) {
const output = tx.outputs[i];
const hash = output.getHash();
@ -697,7 +701,7 @@ function HTTPOptions(options) {
this.logger = null;
this.node = null;
this.apiKey = base58.encode(random.randomBytes(20));
this.apiHash = hash256(this.apiKey);
this.apiHash = digest.hash256(Buffer.from(this.apiKey, 'utf8'));
this.noAuth = false;
this.prefix = null;
@ -736,10 +740,10 @@ HTTPOptions.prototype.fromOptions = function fromOptions(options) {
if (options.apiKey != null) {
assert(typeof options.apiKey === 'string',
'API key must be a string.');
assert(options.apiKey.length <= 200,
'API key must be under 200 bytes.');
assert(options.apiKey.length <= 255,
'API key must be under 256 bytes.');
this.apiKey = options.apiKey;
this.apiHash = hash256(this.apiKey);
this.apiHash = digest.hash256(Buffer.from(this.apiKey, 'utf8'));
}
if (options.noAuth != null) {
@ -804,16 +808,6 @@ HTTPOptions.fromOptions = function fromOptions(options) {
* Helpers
*/
function hash256(data) {
if (typeof data !== 'string')
return Buffer.alloc(0);
if (data.length > 200)
return Buffer.alloc(0);
return digest.hash256(Buffer.from(data, 'utf8'));
}
function enforce(value, msg) {
if (!value) {
const err = new Error(msg);

View File

@ -447,14 +447,16 @@ PolicyEstimator.VERSION = 0;
PolicyEstimator.prototype.init = function init() {
const minFee = this.minTrackedFee;
const minPri = this.minTrackedPri;
const fee = [];
const priority = [];
for (let b = minFee; b <= MAX_FEERATE; b *= FEE_SPACING)
fee.push(b);
fee.push(INF_FEERATE);
const priority = [];
for (let b = minPri; b <= MAX_PRIORITY; b *= PRI_SPACING)
priority.push(b);
@ -694,7 +696,7 @@ PolicyEstimator.prototype.estimateFee = function estimateFee(target, smart) {
'Too many confirmations for estimate.');
if (!smart) {
rate = this.feeStats.estimateMedian(
const rate = this.feeStats.estimateMedian(
target, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT,
true, this.bestHeight);

View File

@ -41,7 +41,7 @@ function write(data, str, off) {
if (Buffer.isBuffer(str))
return str.copy(data, off);
assert(typeof str === 'string');
data.write(str, off, 'hex');
return data.write(str, off, 'hex');
}
/*

View File

@ -105,8 +105,6 @@ util.inherits(Mempool, AsyncObject);
*/
Mempool.prototype._open = async function open() {
const size = (this.options.maxSize / 1024).toFixed(2);
await this.chain.open();
await this.cache.open();
@ -143,6 +141,8 @@ Mempool.prototype._open = async function open() {
this.tip = this.chain.tip.hash;
const size = (this.options.maxSize / 1024).toFixed(2);
this.logger.info('Mempool loaded (maxsize=%dkb).', size);
};
@ -361,12 +361,13 @@ Mempool.prototype._reset = async function reset() {
Mempool.prototype.limitSize = function limitSize(added) {
const maxSize = this.options.maxSize;
const threshold = maxSize - (maxSize / 10);
const expiryTime = this.options.expiryTime;
if (this.size <= maxSize)
return false;
const threshold = maxSize - (maxSize / 10);
const expiryTime = this.options.expiryTime;
const now = util.now();
let start = util.hrtime();
const queue = new Heap(cmpRate);
@ -431,8 +432,10 @@ Mempool.prototype.limitSize = function limitSize(added) {
Mempool.prototype.getTX = function getTX(hash) {
const entry = this.map.get(hash);
if (!entry)
return;
return null;
return entry.tx;
};
@ -457,13 +460,13 @@ Mempool.prototype.getCoin = function getCoin(hash, index) {
const entry = this.map.get(hash);
if (!entry)
return;
return null;
if (this.isSpent(hash, index))
return;
return null;
if (index >= entry.tx.outputs.length)
return;
return null;
return Coin.fromTX(entry.tx, index, -1);
};
@ -507,7 +510,7 @@ Mempool.prototype.getSpentTX = function getSpentTX(hash, index) {
const entry = this.spents.get(key);
if (!entry)
return;
return null;
return entry.tx;
};
@ -519,11 +522,11 @@ Mempool.prototype.getSpentTX = function getSpentTX(hash, index) {
*/
Mempool.prototype.getCoinsByAddress = function getCoinsByAddress(addrs) {
const out = [];
if (!Array.isArray(addrs))
addrs = [addrs];
const out = [];
for (const addr of addrs) {
const hash = Address.getHash(addr, 'hex');
const coins = this.coinIndex.get(hash);
@ -542,11 +545,11 @@ Mempool.prototype.getCoinsByAddress = function getCoinsByAddress(addrs) {
*/
Mempool.prototype.getTXByAddress = function getTXByAddress(addrs) {
const out = [];
if (!Array.isArray(addrs))
addrs = [addrs];
const out = [];
for (const addr of addrs) {
const hash = Address.getHash(addr, 'hex');
const txs = this.txIndex.get(hash);
@ -565,11 +568,11 @@ Mempool.prototype.getTXByAddress = function getTXByAddress(addrs) {
*/
Mempool.prototype.getMetaByAddress = function getMetaByAddress(addrs) {
const out = [];
if (!Array.isArray(addrs))
addrs = [addrs];
const out = [];
for (const addr of addrs) {
const hash = Address.getHash(addr, 'hex');
const txs = this.txIndex.getMeta(hash);
@ -591,7 +594,7 @@ Mempool.prototype.getMeta = function getMeta(hash) {
const entry = this.getEntry(hash);
if (!entry)
return;
return null;
const meta = TXMeta.fromTX(entry.tx);
meta.mtime = entry.time;
@ -685,11 +688,10 @@ Mempool.prototype.addTX = async function addTX(tx, id) {
*/
Mempool.prototype._addTX = async function _addTX(tx, id) {
let missing;
if (id == null)
id = -1;
let missing;
try {
missing = await this.insertTX(tx, id);
} catch (err) {
@ -859,7 +861,6 @@ Mempool.prototype.insertTX = async function insertTX(tx, id) {
Mempool.prototype.verify = async function verify(entry, view) {
const height = this.chain.height + 1;
const lockFlags = common.lockFlags.STANDARD_LOCKTIME_FLAGS;
let flags = Script.flags.STANDARD_VERIFY_FLAGS;
const tx = entry.tx;
// Verify sequence locks.
@ -949,6 +950,7 @@ Mempool.prototype.verify = async function verify(entry, view) {
throw new VerifyError(tx, 'invalid', reason, score);
// Script verification.
let flags = Script.flags.STANDARD_VERIFY_FLAGS;
try {
await this.verifyInputs(tx, view, flags);
} catch (err) {
@ -1414,8 +1416,6 @@ Mempool.prototype.hasOrphan = function hasOrphan(hash) {
*/
Mempool.prototype.storeOrphan = function storeOrphan(tx, missing, id) {
const hash = tx.hash('hex');
if (tx.getWeight() > policy.MAX_TX_WEIGHT) {
this.logger.debug('Ignoring large orphan: %s', tx.txid());
if (!tx.hasWitness())
@ -1436,6 +1436,8 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx, missing, id) {
this.limitOrphans();
const hash = tx.hash('hex');
for (const prev of missing) {
if (!this.waiting.has(prev))
this.waiting.set(prev, new Set());
@ -1510,13 +1512,14 @@ Mempool.prototype.handleOrphans = async function handleOrphans(parent) {
Mempool.prototype.resolveOrphans = function resolveOrphans(parent) {
const hash = parent.hash('hex');
const set = this.waiting.get(hash);
const resolved = [];
if (!set)
return resolved;
return [];
assert(set.size > 0);
const resolved = [];
for (const orphanHash of set.keys()) {
const orphan = this.getOrphan(orphanHash);
@ -1541,11 +1544,11 @@ Mempool.prototype.resolveOrphans = function resolveOrphans(parent) {
Mempool.prototype.removeOrphan = function removeOrphan(hash) {
const orphan = this.getOrphan(hash);
let tx;
if (!orphan)
return false;
let tx;
try {
tx = orphan.toTX();
} catch (e) {
@ -1553,7 +1556,7 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) {
this.logger.warning('%s %s',
'Warning: possible memory corruption.',
'Orphan failed deserialization.');
return;
return false;
}
for (const prev of tx.getPrevout()) {
@ -1587,8 +1590,8 @@ Mempool.prototype.limitOrphans = function limitOrphans() {
return false;
let index = random.randomRange(0, this.orphans.size);
let hash = null;
let hash;
for (hash of this.orphans.keys()) {
if (index === 0)
break;
@ -1690,7 +1693,7 @@ Mempool.prototype.findMissing = function findMissing(tx, view) {
}
if (missing.length === 0)
return;
return null;
return missing;
};
@ -2115,10 +2118,11 @@ TXIndex.prototype.reset = function reset() {
TXIndex.prototype.get = function get(addr) {
const items = this.index.get(addr);
const out = [];
if (!items)
return out;
return [];
const out = [];
for (const entry of items.values())
out.push(entry.tx);
@ -2128,10 +2132,11 @@ TXIndex.prototype.get = function get(addr) {
TXIndex.prototype.getMeta = function getMeta(addr) {
const items = this.index.get(addr);
const out = [];
if (!items)
return out;
return [];
const out = [];
for (const entry of items.values()) {
const meta = TXMeta.fromTX(entry.tx);
@ -2207,10 +2212,11 @@ CoinIndex.prototype.reset = function reset() {
CoinIndex.prototype.get = function get(addr) {
const items = this.index.get(addr);
const out = [];
if (!items)
return out;
return [];
const out = [];
for (const coin of items.values())
out.push(coin.toCoin());
@ -2332,18 +2338,18 @@ MempoolCache.prototype.getTip = async function getTip() {
const hash = await this.db.get(layout.R);
if (!hash)
return;
return null;
return hash.toString('hex');
};
MempoolCache.prototype.getFees = async function getFees() {
const data = await this.db.get(layout.F);
let fees;
if (!data)
return;
return null;
let fees;
try {
fees = Fees.fromRaw(data);
} catch (e) {

View File

@ -97,8 +97,8 @@ MempoolEntry.prototype.fromTX = function fromTX(tx, view, height) {
const size = tx.getSigopsSize(sigops);
const priority = tx.getPriority(view, height, size);
const fee = tx.getFee(view);
let dependencies = false;
let dependencies = false;
for (const {prevout} of tx.inputs) {
if (view.getHeight(prevout) === -1) {
dependencies = true;

View File

@ -128,8 +128,7 @@ CPUMiner.prototype._start = async function start() {
if (this.stopping)
break;
let block = null;
let block;
try {
block = await this.mineAsync(this.job);
} catch (e) {
@ -145,8 +144,7 @@ CPUMiner.prototype._start = async function start() {
if (!block)
continue;
let entry = null;
let entry;
try {
entry = await this.chain.add(block);
} catch (e) {
@ -295,6 +293,7 @@ CPUMiner.prototype.findNonce = function findNonce(job) {
const data = job.getHeader();
const target = job.attempt.target;
const interval = CPUMiner.INTERVAL;
let min = 0;
let max = interval;
let nonce;
@ -322,16 +321,17 @@ CPUMiner.prototype.findNonce = function findNonce(job) {
*/
CPUMiner.prototype.findNonceAsync = async function findNonceAsync(job) {
if (!this.workers)
return this.findNonce(job);
const data = job.getHeader();
const target = job.attempt.target;
const interval = CPUMiner.INTERVAL;
let min = 0;
let max = interval;
let nonce;
if (!this.workers)
return this.findNonce(job);
while (max <= 0xffffffff) {
nonce = await this.workers.mine(data, target, min, max);
@ -357,10 +357,9 @@ CPUMiner.prototype.findNonceAsync = async function findNonceAsync(job) {
*/
CPUMiner.prototype.mine = function mine(job) {
let nonce;
job.start = util.now();
let nonce;
for (;;) {
nonce = this.findNonce(job);
@ -394,7 +393,7 @@ CPUMiner.prototype.mineAsync = async function mineAsync(job) {
break;
if (job.destroyed)
return;
return null;
job.updateNonce();

View File

@ -259,7 +259,7 @@ Miner.prototype.assemble = function assemble(attempt) {
if (!this.mempool) {
attempt.refresh();
return [];
return;
}
assert(this.mempool.tip === this.chain.tip.hash,

View File

@ -178,7 +178,7 @@ BIP150.prototype.reply = function reply(data) {
if (this.isAuthed()) {
this.auth = true;
this.emit('auth');
return;
return null;
}
assert(this.outbound, 'No challenge received before reply on inbound.');
@ -321,6 +321,8 @@ BIP150.prototype.findAuthorized = function findAuthorized(hash) {
if (ccmp(msg, hash))
return key;
}
return null;
};
/**
@ -630,12 +632,11 @@ AuthDB.prototype.lookup = async function lookup() {
*/
AuthDB.prototype.populate = async function populate(addr, key) {
let hosts;
assert(addr.type === IP.types.DNS, 'Resolved host passed.');
this.logger.info('Resolving authorized hosts from: %s.', addr.host);
let hosts;
try {
hosts = await this.resolve(addr.host);
} catch (e) {
@ -665,8 +666,8 @@ AuthDB.prototype.readKnown = async function readKnown() {
return;
const file = path.join(this.prefix, 'known-peers');
let text;
let text;
try {
text = await fs.readFile(file, 'utf8');
} catch (e) {
@ -702,8 +703,8 @@ AuthDB.prototype.parseKnown = function parseKnown(text) {
continue;
const hostname = parts[0].trim().split(',');
let host, ip;
let host, ip;
if (hostname.length >= 2) {
host = hostname[0];
ip = hostname[1];
@ -742,8 +743,8 @@ AuthDB.prototype.readAuth = async function readAuth() {
return;
const file = path.join(this.prefix, 'authorized-peers');
let text;
let text;
try {
text = await fs.readFile(file, 'utf8');
} catch (e) {

View File

@ -300,7 +300,7 @@ CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
if (this.count === this.totalTX)
return true;
const have = new Set();
const set = new Set();
for (const {tx} of mempool.map.values()) {
let hash = tx.hash();
@ -314,7 +314,7 @@ CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
if (index == null)
continue;
if (have.has(index)) {
if (set.has(index)) {
// Siphash collision, just request it.
this.available[index] = null;
this.count--;
@ -322,7 +322,7 @@ CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
}
this.available[index] = tx;
have.add(index);
set.add(index);
this.count++;
// We actually may have a siphash collision
@ -619,7 +619,6 @@ TXRequest.prototype.fromReader = function fromReader(br) {
this.hash = br.readHash('hex');
const count = br.readVarint();
let offset = 0;
for (let i = 0; i < count; i++) {
const index = br.readVarint();
@ -627,6 +626,8 @@ TXRequest.prototype.fromReader = function fromReader(br) {
this.indexes.push(index);
}
let offset = 0;
for (let i = 0; i < count; i++) {
let index = this.indexes[i];
index += offset;

View File

@ -22,34 +22,24 @@ const external = exports;
*/
external.getIPv4 = async function getIPv4() {
let res = null;
try {
res = await request({
const res = await request({
method: 'GET',
uri: 'http://ipv4.icanhazip.com',
expect: 'txt',
timeout: 2000
});
} catch (e) {
return await external.getIPv42();
}
let ip = null;
try {
const str = res.body.trim();
const raw = IP.toBuffer(str);
if (!IP.isIPv4(raw))
throw new Error('Could not find IPv4.');
ip = IP.toString(raw);
return IP.toString(raw);
} catch (e) {
return await external.getIPv42();
}
return ip;
};
/**

View File

@ -403,9 +403,7 @@ HostList.prototype.isBanned = function isBanned(host) {
*/
HostList.prototype.getHost = function getHost() {
const now = this.network.now();
let buckets = null;
let factor = 1;
if (this.totalFresh > 0)
buckets = this.fresh;
@ -416,7 +414,10 @@ HostList.prototype.getHost = function getHost() {
}
if (!buckets)
return;
return null;
const now = this.network.now();
let factor = 1;
for (;;) {
let index = util.random(0, buckets.length);
@ -653,7 +654,7 @@ HostList.prototype.remove = function remove(hostname) {
const entry = this.map.get(hostname);
if (!entry)
return;
return null;
if (entry.used) {
let head = entry;
@ -832,7 +833,7 @@ HostList.prototype.addSeed = function addSeed(host) {
if (ip.type === IP.types.DNS) {
// Defer for resolution.
this.dnsSeeds.push(ip);
return;
return null;
}
const addr = NetAddress.fromHost(ip.host, ip.port, this.network);
@ -854,7 +855,7 @@ HostList.prototype.addNode = function addNode(host) {
if (ip.type === IP.types.DNS) {
// Defer for resolution.
this.dnsNodes.push(ip);
return;
return null;
}
const addr = NetAddress.fromHost(ip.host, ip.port, this.network);

View File

@ -102,8 +102,7 @@ Parser.prototype.parse = function parse(data) {
return;
}
let payload = null;
let payload;
try {
payload = this.parsePayload(this.header.cmd, data);
} catch (e) {

View File

@ -511,10 +511,12 @@ Peer.prototype._open = async function open() {
Peer.prototype.initConnect = function initConnect() {
if (this.connected) {
assert(!this.outbound);
return;
return Promise.resolve();
}
return new Promise((resolve, reject) => {
/* eslint no-use-before-define: "off" */
const cleanup = () => {
if (this.connectTimeout != null) {
clearTimeout(this.connectTimeout);
@ -703,8 +705,6 @@ Peer.prototype.finalize = async function finalize() {
*/
Peer.prototype.announceBlock = function announceBlock(blocks) {
const inv = [];
if (!this.handshake)
return;
@ -714,6 +714,8 @@ Peer.prototype.announceBlock = function announceBlock(blocks) {
if (!Array.isArray(blocks))
blocks = [blocks];
const inv = [];
for (const block of blocks) {
assert(block instanceof Block);
@ -753,8 +755,6 @@ Peer.prototype.announceBlock = function announceBlock(blocks) {
*/
Peer.prototype.announceTX = function announceTX(txs) {
const inv = [];
if (!this.handshake)
return;
@ -769,6 +769,8 @@ Peer.prototype.announceTX = function announceTX(txs) {
if (!Array.isArray(txs))
txs = [txs];
const inv = [];
for (const tx of txs) {
assert(tx instanceof TX);
@ -830,20 +832,21 @@ Peer.prototype.queueInv = function queueInv(items) {
*/
Peer.prototype.flushInv = function flushInv() {
const queue = this.invQueue.slice();
const items = [];
if (this.destroyed)
return;
const queue = this.invQueue;
if (queue.length === 0)
return;
this.invQueue.length = 0;
this.invQueue = [];
this.logger.spam('Serving %d inv items to %s.',
queue.length, this.hostname());
const items = [];
for (const item of queue) {
if (!this.invFilter.added(item.hash, 'hex'))
continue;
@ -1336,7 +1339,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() {
Peer.prototype.request = function request(type, timeout) {
if (this.destroyed)
return;
return null;
let entry = this.responseMap.get(type);
@ -1361,7 +1364,7 @@ Peer.prototype.response = function response(type, payload) {
const entry = this.responseMap.get(type);
if (!entry)
return;
return null;
this.responseMap.delete(type);
@ -1989,12 +1992,12 @@ Peer.prototype.handleAuthPropose = async function handleAuthPropose(packet) {
Peer.prototype.sendGetHeaders = function sendGetHeaders(locator, stop) {
const packet = new packets.GetHeadersPacket(locator, stop);
let hash = null;
let end = null;
let hash = null;
if (packet.locator.length > 0)
hash = util.revHex(packet.locator[0]);
let end = null;
if (stop)
end = util.revHex(stop);
@ -2017,12 +2020,12 @@ Peer.prototype.sendGetHeaders = function sendGetHeaders(locator, stop) {
Peer.prototype.sendGetBlocks = function getBlocks(locator, stop) {
const packet = new packets.GetBlocksPacket(locator, stop);
let hash = null;
let end = null;
let hash = null;
if (packet.locator.length > 0)
hash = util.revHex(packet.locator[0]);
let end = null;
if (stop)
end = util.revHex(stop);

View File

@ -463,15 +463,14 @@ Pool.prototype.discoverGateway = async function discoverGateway() {
// Pointless if we're not listening.
if (!this.options.listen)
return;
return false;
// UPNP is always optional, since
// it's likely to not work anyway.
if (!this.options.upnp)
return;
let wan = null;
return false;
let wan;
try {
this.logger.debug('Discovering internet gateway (upnp).');
wan = await UPNP.discover();
@ -481,8 +480,7 @@ Pool.prototype.discoverGateway = async function discoverGateway() {
return false;
}
let host = null;
let host;
try {
host = await wan.getExternalIP();
} catch (e) {
@ -523,7 +521,6 @@ Pool.prototype.discoverSeeds = async function discoverSeeds(checkPeers) {
const size = this.hosts.size();
let total = 0;
for (let peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.outbound)
continue;
@ -569,8 +566,7 @@ Pool.prototype.discoverExternal = async function discoverExternal() {
if (this.hosts.local.size > 0)
return;
let host4 = null;
let host4;
try {
host4 = await external.getIPv4();
} catch (e) {
@ -581,8 +577,7 @@ Pool.prototype.discoverExternal = async function discoverExternal() {
if (host4 && this.hosts.addLocal(host4, port, scores.HTTP))
this.logger.info('External IPv4 found (http): %s.', host4);
let host6 = null;
let host6;
try {
host6 = await external.getIPv6();
} catch (e) {
@ -767,8 +762,7 @@ Pool.prototype.resync = async function resync(force) {
if (!this.syncing)
return;
let locator = null;
let locator;
try {
locator = await this.chain.getLocator();
} catch (e) {
@ -834,8 +828,7 @@ Pool.prototype.sendSync = async function sendSync(peer) {
peer.syncing = true;
peer.blockTime = util.ms();
let locator = null;
let locator;
try {
locator = await this.chain.getLocator();
} catch (e) {
@ -1000,13 +993,13 @@ Pool.prototype.getBroadcasted = function getBroadcasted(peer, item) {
const entry = this.invMap.get(item.hash);
if (!entry)
return;
return null;
if (type !== entry.type) {
this.logger.debug(
'Peer requested item with the wrong type (%s).',
peer.hostname());
return;
return null;
}
this.logger.debug(
@ -1037,19 +1030,19 @@ Pool.prototype.getItem = async function getItem(peer, item) {
return entry;
if (this.options.selfish)
return;
return null;
if (item.isTX()) {
if (!this.mempool)
return;
return null;
return this.mempool.getTX(item.hash);
}
if (this.chain.options.spv)
return;
return null;
if (this.chain.options.prune)
return;
return null;
return await this.chain.db.getBlock(item.hash);
};
@ -1683,8 +1676,6 @@ Pool.prototype._handleInv = async function handleInv(peer, packet) {
*/
Pool.prototype.handleBlockInv = async function handleBlockInv(peer, hashes) {
const items = [];
assert(hashes.length > 0);
if (!this.syncing)
@ -1712,7 +1703,8 @@ Pool.prototype.handleBlockInv = async function handleBlockInv(peer, hashes) {
hashes.length,
peer.hostname());
let exists = null;
const items = [];
let exists;
for (let i = 0; i < hashes.length; i++) {
const hash = hashes[i];
@ -1968,8 +1960,6 @@ Pool.prototype.handleNotFound = async function handleNotFound(peer, packet) {
*/
Pool.prototype.handleGetBlocks = async function handleGetBlocks(peer, packet) {
const blocks = [];
if (!this.chain.synced)
return;
@ -1987,6 +1977,8 @@ Pool.prototype.handleGetBlocks = async function handleGetBlocks(peer, packet) {
if (hash)
hash = await this.chain.db.getNextHash(hash);
const blocks = [];
while (hash) {
blocks.push(new InvItem(invTypes.BLOCK, hash));
@ -2025,8 +2017,7 @@ Pool.prototype.handleGetHeaders = async function handleGetHeaders(peer, packet)
if (this.chain.options.prune)
return;
let hash = null;
let hash;
if (packet.locator.length > 0) {
hash = await this.chain.findLocator(packet.locator);
if (hash)
@ -2035,8 +2026,7 @@ Pool.prototype.handleGetHeaders = async function handleGetHeaders(peer, packet)
hash = packet.stop;
}
let entry = null;
let entry;
if (hash)
entry = await this.chain.db.getEntry(hash);
@ -2270,8 +2260,7 @@ Pool.prototype._addBlock = async function addBlock(peer, block, flags) {
peer.blockTime = util.ms();
let entry = null;
let entry;
try {
entry = await this.chain.add(block, flags, peer.id);
} catch (err) {
@ -2535,8 +2524,7 @@ Pool.prototype._handleTX = async function handleTX(peer, packet) {
return;
}
let missing = null;
let missing;
try {
missing = await this.mempool.addTX(tx, peer.id);
} catch (err) {
@ -2594,8 +2582,6 @@ Pool.prototype.handleReject = async function handleReject(peer, packet) {
*/
Pool.prototype.handleMempool = async function handleMempool(peer, packet) {
const items = [];
if (!this.mempool)
return;
@ -2613,6 +2599,8 @@ Pool.prototype.handleMempool = async function handleMempool(peer, packet) {
return;
}
const items = [];
for (const hash of this.mempool.map.keys())
items.push(new InvItem(invTypes.TX, hash));
@ -2775,7 +2763,6 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet)
const block = packet.block;
const hash = block.hash('hex');
const witness = peer.compactWitness;
const flags = chainCommon.flags.VERIFY_BODY;
if (!this.syncing)
return;
@ -2862,6 +2849,7 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet)
this.logger.debug(
'Received full compact block %s (%s).',
block.rhash(), peer.hostname());
const flags = chainCommon.flags.VERIFY_BODY;
await this.addBlock(peer, block.toBlock(), flags);
return;
}
@ -3080,9 +3068,6 @@ Pool.prototype.addInbound = function addInbound(socket) {
*/
Pool.prototype.getHost = function getHost() {
const services = this.options.getRequiredServices();
const now = this.network.now();
for (const addr of this.hosts.nodes) {
if (this.peers.has(addr.hostname))
continue;
@ -3090,6 +3075,9 @@ Pool.prototype.getHost = function getHost() {
return addr;
}
const services = this.options.getRequiredServices();
const now = this.network.now();
for (let i = 0; i < 100; i++) {
const entry = this.hosts.getHost();
@ -3121,6 +3109,8 @@ Pool.prototype.getHost = function getHost() {
return entry.addr;
}
return null;
};
/**
@ -4389,20 +4379,20 @@ function NonceList() {
}
NonceList.prototype.alloc = function alloc(hostname) {
let nonce, key;
for (;;) {
nonce = util.nonce();
key = nonce.toString('hex');
if (!this.map.has(key)) {
this.map.set(key, hostname);
assert(!this.hosts.has(hostname));
this.hosts.set(hostname, key);
break;
}
}
const nonce = util.nonce();
const key = nonce.toString('hex');
return nonce;
if (this.map.has(key))
continue;
this.map.set(key, hostname);
assert(!this.hosts.has(hostname));
this.hosts.set(hostname, key);
return nonce;
}
};
NonceList.prototype.has = function has(nonce) {

View File

@ -101,8 +101,6 @@ ProxySocket.prototype._init = function _init() {
};
ProxySocket.prototype.connect = function connect(port, host) {
let nonce = 0;
this.remoteAddress = host;
this.remotePort = port;
@ -116,14 +114,17 @@ ProxySocket.prototype.connect = function connect(port, host) {
return;
}
if (this.info.pow) {
let pow = new BufferWriter();
let nonce = 0;
pow.writeU32(nonce);
pow.writeBytes(this.snonce);
pow.writeU32(port);
pow.writeString(host, 'ascii');
pow = pow.render();
if (this.info.pow) {
const bw = new BufferWriter();
bw.writeU32(nonce);
bw.writeBytes(this.snonce);
bw.writeU32(port);
bw.writeString(host, 'ascii');
const pow = bw.render();
util.log(
'Solving proof of work to create socket (%d, %s) -- please wait.',

View File

@ -428,8 +428,7 @@ SOCKS.prototype.handleProxy = function handleProxy(data) {
return;
}
let addr = null;
let addr;
try {
addr = parseAddr(data, 3);
} catch (e) {
@ -487,8 +486,7 @@ SOCKS.prototype.handleResolve = function handleResolve(data) {
return;
}
let addr = null;
let addr;
try {
addr = parseAddr(data, 3);
} catch (e) {
@ -569,8 +567,7 @@ Proxy.prototype.connect = async function connect(port, host) {
destPort: port
};
let socket = null;
let socket;
try {
socket = await SOCKS.proxy(options);
} catch (e) {
@ -708,9 +705,7 @@ function parseAddr(data, offset) {
br.seek(offset);
const type = br.readU8();
let host = null;
let port = 0;
let host, port;
switch (type) {
case 0x01: {

View File

@ -191,8 +191,7 @@ UPNP.prototype.handleMsg = async function handleMsg(msg) {
if (!this.socket)
return;
let headers = null;
let headers;
try {
headers = UPNP.parseHeader(msg);
} catch (e) {
@ -271,7 +270,7 @@ UPNP.parseHeader = function parseHeader(str) {
const index = line.indexOf(':');
if (index === -1) {
left = line.toLowerCase();
const left = line.toLowerCase();
headers[left] = '';
continue;
}
@ -615,6 +614,8 @@ XMLElement.prototype.find = function find(name) {
if (child)
return child;
}
return null;
};
/*
@ -649,6 +650,8 @@ function findService(services, name) {
if (service.serviceType === name)
return service;
}
return null;
}
function extractServices(services, targets) {
@ -657,13 +660,15 @@ function extractServices(services, targets) {
if (service)
return service;
}
return null;
}
function findIP(el) {
const child = el.find('NewExternalIPAddress');
if (!child)
return;
return null;
return IP.normalize(child.text);
}
@ -672,7 +677,7 @@ function findError(el) {
const child = el.find('UPnPError');
if (!child)
return;
return null;
let code = -1;
const ccode = child.find('errorCode');

View File

@ -702,8 +702,7 @@ Config.prototype.parseArg = function parseArg(argv) {
assert(Array.isArray(argv));
let key = null;
let key;
for (let i = 2; i < argv.length; i++) {
let arg = argv[i];
let value, alias, equals;

View File

@ -379,16 +379,16 @@ FullNode.prototype.getBlock = function getBlock(hash) {
* @returns {Promise} - Returns {@link Coin}.
*/
FullNode.prototype.getCoin = function getCoin(hash, index) {
FullNode.prototype.getCoin = async function getCoin(hash, index) {
const coin = this.mempool.getCoin(hash, index);
if (coin)
return Promise.resolve(coin);
return coin;
if (this.mempool.isSpent(hash, index))
return Promise.resolve();
return null;
return this.chain.db.getCoin(hash, index);
return await this.chain.db.getCoin(hash, index);
};
/**
@ -483,8 +483,10 @@ FullNode.prototype.getTXByAddress = async function getTXByAddress(addrs) {
FullNode.prototype.getTX = async function getTX(hash) {
const mtx = await this.getMeta(hash);
if (!mtx)
return;
return null;
return mtx.tx;
};

View File

@ -253,8 +253,6 @@ Logger.prototype._close = async function close() {
*/
Logger.prototype.truncate = async function truncate() {
const maxSize = Logger.MAX_FILE_SIZE;
if (!this.filename)
return;
@ -263,8 +261,7 @@ Logger.prototype.truncate = async function truncate() {
assert(!this.stream);
let stat = null;
let stat;
try {
stat = await fs.stat(this.filename);
} catch (e) {
@ -273,6 +270,8 @@ Logger.prototype.truncate = async function truncate() {
throw e;
}
const maxSize = Logger.MAX_FILE_SIZE;
if (stat.size <= maxSize + (maxSize / 10))
return;
@ -390,11 +389,11 @@ Logger.prototype.setLevel = function setLevel(name) {
*/
Logger.prototype.error = function error(...args) {
const err = args[0];
if (this.level < Logger.levels.ERROR)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.ERROR, null, err);
@ -408,11 +407,11 @@ Logger.prototype.error = function error(...args) {
*/
Logger.prototype.warning = function warning(...args) {
const err = args[0];
if (this.level < Logger.levels.WARNING)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.WARNING, null, err);
@ -426,11 +425,11 @@ Logger.prototype.warning = function warning(...args) {
*/
Logger.prototype.info = function info(...args) {
const err = args[0];
if (this.level < Logger.levels.INFO)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.INFO, null, err);
@ -444,11 +443,11 @@ Logger.prototype.info = function info(...args) {
*/
Logger.prototype.debug = function debug(...args) {
const err = args[0];
if (this.level < Logger.levels.DEBUG)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.DEBUG, null, err);
@ -462,11 +461,11 @@ Logger.prototype.debug = function debug(...args) {
*/
Logger.prototype.spam = function spam(...args) {
const err = args[0];
if (this.level < Logger.levels.SPAM)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.SPAM, null, err);
@ -518,7 +517,6 @@ Logger.prototype.context = function _context(module) {
Logger.prototype.writeConsole = function writeConsole(level, module, args) {
const name = Logger.levelsByVal[level];
let msg = '';
assert(name, 'Invalid log level.');
@ -526,7 +524,7 @@ Logger.prototype.writeConsole = function writeConsole(level, module, args) {
return;
if (!process.stdout) {
msg += `[${name}] `;
let msg = `[${name}] `;
if (module)
msg += `(${module}) `;
@ -544,13 +542,15 @@ Logger.prototype.writeConsole = function writeConsole(level, module, args) {
: console.log(msg);
}
let msg;
if (this.colors) {
const color = Logger.styles[level];
assert(color);
msg += `\x1b[${color}m[${name}]\x1b[m `;
msg = `\x1b[${color}m[${name}]\x1b[m `;
} else {
msg += `[${name}] `;
msg = `[${name}] `;
}
if (module)
@ -573,7 +573,6 @@ Logger.prototype.writeConsole = function writeConsole(level, module, args) {
Logger.prototype.writeStream = function writeStream(level, module, args) {
const name = Logger.prefixByVal[level];
let msg = '';
assert(name, 'Invalid log level.');
@ -583,7 +582,7 @@ Logger.prototype.writeStream = function writeStream(level, module, args) {
if (this.closing)
return;
msg += `[${name}:${util.date()}] `;
let msg = `[${name}:${util.date()}] `;
if (module)
msg += `(${module}) `;
@ -703,11 +702,11 @@ LoggerContext.prototype.setLevel = function setLevel(name) {
*/
LoggerContext.prototype.error = function error(...args) {
const err = args[0];
if (this.logger.level < Logger.levels.ERROR)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.ERROR, err);
@ -721,11 +720,11 @@ LoggerContext.prototype.error = function error(...args) {
*/
LoggerContext.prototype.warning = function warning(...args) {
const err = args[0];
if (this.logger.level < Logger.levels.WARNING)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.WARNING, err);
@ -739,11 +738,11 @@ LoggerContext.prototype.warning = function warning(...args) {
*/
LoggerContext.prototype.info = function info(...args) {
const err = args[0];
if (this.logger.level < Logger.levels.INFO)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.INFO, err);
@ -757,11 +756,11 @@ LoggerContext.prototype.info = function info(...args) {
*/
LoggerContext.prototype.debug = function debug(...args) {
const err = args[0];
if (this.logger.level < Logger.levels.DEBUG)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.DEBUG, err);
@ -775,11 +774,11 @@ LoggerContext.prototype.debug = function debug(...args) {
*/
LoggerContext.prototype.spam = function spam(...args) {
const err = args[0];
if (this.logger.level < Logger.levels.SPAM)
return;
const err = args[0];
if (err instanceof Error)
return this.logError(Logger.levels.SPAM, err);
@ -839,12 +838,9 @@ Logger.global = new Logger();
function openStream(filename) {
return new Promise((resolve, reject) => {
const stream = fs.createWriteStream(filename, { flags: 'a' });
/* eslint no-use-before-define: "off" */
const cleanup = () => {
stream.removeListener('error', onError);
stream.removeListener('open', onOpen);
};
const stream = fs.createWriteStream(filename, { flags: 'a' });
const onError = (err) => {
try {
@ -861,6 +857,11 @@ function openStream(filename) {
resolve(stream);
};
const cleanup = () => {
stream.removeListener('error', onError);
stream.removeListener('open', onOpen);
};
stream.once('error', onError);
stream.once('open', onOpen);
});
@ -868,10 +869,7 @@ function openStream(filename) {
function closeStream(stream) {
return new Promise((resolve, reject) => {
const cleanup = () => {
stream.removeListener('error', onError);
stream.removeListener('close', onClose);
};
/* eslint no-use-before-define: "off" */
const onError = (err) => {
cleanup();
@ -883,6 +881,11 @@ function closeStream(stream) {
resolve(stream);
};
const cleanup = () => {
stream.removeListener('error', onError);
stream.removeListener('close', onClose);
};
stream.removeAllListeners('error');
stream.removeAllListeners('close');
stream.once('error', onError);

View File

@ -352,7 +352,7 @@ Node.prototype.get = function get(name) {
return this.http;
}
return this.plugins[name];
return this.plugins[name] || null;
};
/**

View File

@ -460,6 +460,8 @@ Address.prototype.fromScript = function fromScript(script) {
this.version = -1;
return this;
}
return null;
};
/**
@ -484,6 +486,8 @@ Address.prototype.fromWitness = function fromWitness(witness) {
this.version = 0;
return this;
}
return null;
};
/**
@ -506,6 +510,8 @@ Address.prototype.fromInputScript = function fromInputScript(script) {
this.version = -1;
return this;
}
return null;
};
/**
@ -824,11 +830,11 @@ Address.prototype.isUnknown = function isUnknown() {
*/
Address.getHash = function getHash(data, enc, network) {
let hash;
if (!data)
throw new Error('Object is not an address.');
let hash;
if (typeof data === 'string') {
if (data.length === 40 || data.length === 64)
return enc === 'hex' ? data : Buffer.from(data, 'hex');

View File

@ -379,7 +379,7 @@ Block.prototype.getCommitmentHash = function getCommitmentHash(enc) {
return null;
const coinbase = this.txs[0];
let hash = null;
let hash;
for (let i = coinbase.outputs.length - 1; i >= 0; i--) {
const output = coinbase.outputs[i];

View File

@ -123,7 +123,7 @@ Input.prototype.getType = function getType(coin) {
Input.prototype.getRedeem = function getRedeem(coin) {
if (this.isCoinbase())
return;
return null;
if (!coin) {
if (this.witness.isScripthashInput())
@ -132,7 +132,7 @@ Input.prototype.getRedeem = function getRedeem(coin) {
if (this.script.isScripthashInput())
return this.script.getRedeem();
return;
return null;
}
let prev = coin.script;
@ -159,12 +159,12 @@ Input.prototype.getRedeem = function getRedeem(coin) {
Input.prototype.getSubtype = function getSubtype(coin) {
if (this.isCoinbase())
return;
return null;
const redeem = this.getRedeem(coin);
if (!redeem)
return;
return null;
const type = redeem.getType();
@ -181,7 +181,7 @@ Input.prototype.getSubtype = function getSubtype(coin) {
Input.prototype.getAddress = function getAddress(coin) {
if (this.isCoinbase())
return;
return null;
if (coin)
return coin.getAddress();
@ -202,7 +202,7 @@ Input.prototype.getHash = function getHash(enc) {
const addr = this.getAddress();
if (!addr)
return;
return null;
return addr.getHash(enc);
};
@ -284,10 +284,9 @@ Input.prototype.toJSON = function toJSON(network, coin) {
*/
Input.prototype.getJSON = function getJSON(network, coin) {
let addr;
network = Network.get(network);
let addr;
if (!coin) {
addr = this.getAddress();
if (addr)

View File

@ -58,13 +58,11 @@ function KeyRing(options, network) {
*/
KeyRing.prototype.fromOptions = function fromOptions(options, network) {
let key = toKey(options);
const script = options.script;
const compressed = options.compressed;
if (!network)
network = options.network;
let key = toKey(options);
if (Buffer.isBuffer(key))
return this.fromKey(key, network);
@ -86,10 +84,13 @@ KeyRing.prototype.fromOptions = function fromOptions(options, network) {
this.nested = options.nested;
}
if (script)
return this.fromScript(key, script, compressed, network);
const script = options.script;
const compress = options.compressed;
this.fromKey(key, compressed, network);
if (script)
return this.fromScript(key, script, compress, network);
return this.fromKey(key, compress, network);
};
/**
@ -121,22 +122,22 @@ KeyRing.prototype.refresh = function refresh() {
* Inject data from private key.
* @private
* @param {Buffer} key
* @param {Boolean?} compressed
* @param {Boolean?} compress
* @param {(NetworkType|Network)?} network
*/
KeyRing.prototype.fromPrivate = function fromPrivate(key, compressed, network) {
KeyRing.prototype.fromPrivate = function fromPrivate(key, compress, network) {
assert(Buffer.isBuffer(key), 'Private key must be a buffer.');
assert(secp256k1.privateKeyVerify(key), 'Not a valid private key.');
if (typeof compressed !== 'boolean') {
network = compressed;
compressed = null;
if (typeof compress !== 'boolean') {
network = compress;
compress = null;
}
this.network = Network.get(network);
this.privateKey = key;
this.publicKey = secp256k1.publicKeyCreate(key, compressed !== false);
this.publicKey = secp256k1.publicKeyCreate(key, compress !== false);
return this;
};
@ -144,13 +145,13 @@ KeyRing.prototype.fromPrivate = function fromPrivate(key, compressed, network) {
/**
* Instantiate keyring from a private key.
* @param {Buffer} key
* @param {Boolean?} compressed
* @param {Boolean?} compress
* @param {(NetworkType|Network)?} network
* @returns {KeyRing}
*/
KeyRing.fromPrivate = function fromPrivate(key, compressed, network) {
return new KeyRing().fromPrivate(key, compressed, network);
KeyRing.fromPrivate = function fromPrivate(key, compress, network) {
return new KeyRing().fromPrivate(key, compress, network);
};
/**
@ -171,29 +172,31 @@ KeyRing.prototype.fromPublic = function fromPublic(key, network) {
/**
* Generate a keyring.
* @private
* @param {Boolean?} compress
* @param {(Network|NetworkType)?} network
* @returns {KeyRing}
*/
KeyRing.prototype.generate = function generate(compressed, network) {
if (typeof compressed !== 'boolean') {
network = compressed;
compressed = null;
KeyRing.prototype.generate = function generate(compress, network) {
if (typeof compress !== 'boolean') {
network = compress;
compress = null;
}
const key = secp256k1.generatePrivateKey();
return this.fromKey(key, compressed, network);
return this.fromKey(key, compress, network);
};
/**
* Generate a keyring.
* @param {Boolean?} compress
* @param {(Network|NetworkType)?} network
* @returns {KeyRing}
*/
KeyRing.generate = function generate(compressed, network) {
return new KeyRing().generate(compressed, network);
KeyRing.generate = function generate(compress, network) {
return new KeyRing().generate(compress, network);
};
/**
@ -211,19 +214,20 @@ KeyRing.fromPublic = function fromPublic(key, network) {
* Inject data from public key.
* @private
* @param {Buffer} privateKey
* @param {Boolean?} compress
* @param {(NetworkType|Network)?} network
*/
KeyRing.prototype.fromKey = function fromKey(key, compressed, network) {
KeyRing.prototype.fromKey = function fromKey(key, compress, network) {
assert(Buffer.isBuffer(key), 'Key must be a buffer.');
if (typeof compressed !== 'boolean') {
network = compressed;
compressed = null;
if (typeof compress !== 'boolean') {
network = compress;
compress = null;
}
if (key.length === 32)
return this.fromPrivate(key, compressed !== false, network);
return this.fromPrivate(key, compress !== false, network);
return this.fromPublic(key, network);
};
@ -231,12 +235,13 @@ KeyRing.prototype.fromKey = function fromKey(key, compressed, network) {
/**
* Instantiate keyring from a public key.
* @param {Buffer} publicKey
* @param {Boolean?} compress
* @param {(NetworkType|Network)?} network
* @returns {KeyRing}
*/
KeyRing.fromKey = function fromKey(key, compressed, network) {
return new KeyRing().fromKey(key, compressed, network);
KeyRing.fromKey = function fromKey(key, compress, network) {
return new KeyRing().fromKey(key, compress, network);
};
/**
@ -244,18 +249,19 @@ KeyRing.fromKey = function fromKey(key, compressed, network) {
* @private
* @param {Buffer} key
* @param {Script} script
* @param {Boolean?} compress
* @param {(NetworkType|Network)?} network
*/
KeyRing.prototype.fromScript = function fromScript(key, script, compressed, network) {
KeyRing.prototype.fromScript = function fromScript(key, script, compress, network) {
assert(script instanceof Script, 'Non-script passed into KeyRing.');
if (typeof compressed !== 'boolean') {
network = compressed;
compressed = null;
if (typeof compress !== 'boolean') {
network = compress;
compress = null;
}
this.fromKey(key, compressed, network);
this.fromKey(key, compress, network);
this.script = script;
return this;
@ -265,12 +271,13 @@ KeyRing.prototype.fromScript = function fromScript(key, script, compressed, netw
* Instantiate keyring from script.
* @param {Buffer} key
* @param {Script} script
* @param {Boolean?} compress
* @param {(NetworkType|Network)?} network
* @returns {KeyRing}
*/
KeyRing.fromScript = function fromScript(key, script, compressed, network) {
return new KeyRing().fromScript(key, script, compressed, network);
KeyRing.fromScript = function fromScript(key, script, compress, network) {
return new KeyRing().fromScript(key, script, compress, network);
};
/**
@ -336,16 +343,16 @@ KeyRing.prototype.fromSecret = function fromSecret(data, network) {
const key = br.readBytes(32);
let compressed = false;
let compress = false;
if (br.left() > 4) {
assert(br.readU8() === 1, 'Bad compression flag.');
compressed = true;
compress = true;
}
br.verifyChecksum();
return this.fromPrivate(key, compressed, network);
return this.fromPrivate(key, compress, network);
};
/**
@ -367,7 +374,7 @@ KeyRing.fromSecret = function fromSecret(data, network) {
KeyRing.prototype.getPrivateKey = function getPrivateKey(enc) {
if (!this.privateKey)
return;
return null;
if (enc === 'base58')
return this.toSecret();
@ -410,7 +417,7 @@ KeyRing.prototype.getScript = function getScript() {
KeyRing.prototype.getProgram = function getProgram() {
if (!this.witness)
return;
return null;
if (!this._program) {
let program;
@ -436,7 +443,7 @@ KeyRing.prototype.getProgram = function getProgram() {
KeyRing.prototype.getNestedHash = function getNestedHash(enc) {
if (!this.witness)
return;
return null;
if (!this._nestedHash)
this._nestedHash = this.getProgram().hash160();
@ -454,7 +461,7 @@ KeyRing.prototype.getNestedHash = function getNestedHash(enc) {
KeyRing.prototype.getNestedAddress = function getNestedAddress(enc) {
if (!this.witness)
return;
return null;
if (!this._nestedAddress) {
const hash = this.getNestedHash();
@ -491,7 +498,7 @@ KeyRing.prototype.getScriptHash = function getScriptHash(enc) {
KeyRing.prototype.getScriptHash160 = function getScriptHash256(enc) {
if (!this.script)
return;
return null;
if (!this._scriptHash160)
this._scriptHash160 = this.script.hash160();
@ -509,7 +516,7 @@ KeyRing.prototype.getScriptHash160 = function getScriptHash256(enc) {
KeyRing.prototype.getScriptHash256 = function getScriptHash256(enc) {
if (!this.script)
return;
return null;
if (!this._scriptHash256)
this._scriptHash256 = this.script.sha256();
@ -527,7 +534,7 @@ KeyRing.prototype.getScriptHash256 = function getScriptHash256(enc) {
KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) {
if (!this.script)
return;
return null;
if (!this._scriptAddress) {
let addr;
@ -602,8 +609,10 @@ KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) {
KeyRing.prototype.getHash = function getHash(enc) {
if (this.nested)
return this.getNestedHash(enc);
if (this.script)
return this.getScriptHash(enc);
return this.getKeyHash(enc);
};
@ -616,8 +625,10 @@ KeyRing.prototype.getHash = function getHash(enc) {
KeyRing.prototype.getAddress = function getAddress(enc) {
if (this.nested)
return this.getNestedAddress(enc);
if (this.script)
return this.getScriptAddress(enc);
return this.getKeyAddress(enc);
};
@ -885,9 +896,9 @@ KeyRing.prototype.fromReader = function fromReader(br, network) {
const key = br.readVarBytes();
if (key.length === 32) {
const compressed = br.readU8() === 1;
const compress = br.readU8() === 1;
this.privateKey = key;
this.publicKey = secp256k1.publicKeyCreate(key, compressed);
this.publicKey = secp256k1.publicKeyCreate(key, compress);
} else {
this.publicKey = key;
assert(secp256k1.publicKeyVerify(key), 'Invalid public key.');

View File

@ -109,25 +109,24 @@ MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
MemBlock.prototype.parseCoinbaseHeight = function parseCoinbaseHeight() {
const br = new BufferReader(this._raw, true);
let count;
br.seek(80);
count = br.readVarint();
const txCount = br.readVarint();
if (count === 0)
if (txCount === 0)
return -1;
br.seek(4);
count = br.readVarint();
let inCount = br.readVarint();
if (count === 0) {
if (inCount === 0) {
if (br.readU8() !== 0)
count = br.readVarint();
inCount = br.readVarint();
}
if (count === 0)
if (inCount === 0)
return -1;
br.seek(36);

View File

@ -228,7 +228,7 @@ MerkleBlock.prototype.extractTree = function extractTree() {
}
const left = traverse(height - 1, pos * 2);
let right = null;
let right;
if (pos * 2 + 1 < width(height - 1)) {
right = traverse(height - 1, pos * 2 + 1);
@ -563,7 +563,7 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) {
return leaves[pos];
const left = hash(height - 1, pos * 2, leaves);
let right = null;
let right;
if (pos * 2 + 1 < width(height - 1))
right = hash(height - 1, pos * 2 + 1, leaves);

View File

@ -733,22 +733,12 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) {
// Multisig
if (prev.isMultisig()) {
const keys = [];
// Grab `m` value (number of sigs required).
const m = prev.getSmall(0);
if (vector.getSmall(0) !== 0)
throw new Error('Input has not been templated.');
// Grab `n` value (number of keys).
const n = prev.getSmall(prev.length - 2);
// Grab the redeem script's keys to figure
// out where our key should go.
for (let i = 1; i < prev.length - 2; i++)
keys.push(prev.get(i));
if (vector.getSmall(0) !== 0)
throw new Error('Input has not been templated.');
// Too many signature slots. Abort.
if (vector.length - 1 > n)
return false;
@ -760,6 +750,9 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) {
total++;
}
// Grab `m` value (number of sigs required).
const m = prev.getSmall(0);
// Signatures are already finalized.
if (total === m && vector.length - 1 === m)
return true;
@ -769,6 +762,12 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) {
while (vector.length - 1 < n)
vector.push(opcodes.OP_0);
// Grab the redeem script's keys to figure
// out where our key should go.
const keys = [];
for (let i = 1; i < prev.length - 2; i++)
keys.push(prev.get(i));
// Find the key index so we can place
// the signature in the same index.
let keyIndex = util.indexOf(keys, ring.publicKey);
@ -919,17 +918,17 @@ MTX.prototype.isVectorSigned = function isVectorSigned(prev, vector) {
// Grab `m` value (number of required sigs).
const m = prev.getSmall(0);
// Ensure we have the correct number
// of required signatures.
if (vector.length - 1 !== m)
return false;
// Ensure all members are signatures.
for (let i = 1; i < vector.length; i++) {
if (!Script.isSignature(vector.get(i)))
return false;
}
// Ensure we have the correct number
// of required signatures.
if (vector.length - 1 !== m)
return false;
return true;
}
@ -1839,8 +1838,10 @@ function sortRandom(a, b) {
function sortValue(a, b) {
if (a.height === -1 && b.height !== -1)
return 1;
if (a.height !== -1 && b.height === -1)
return -1;
return b.value - a.value;
}

View File

@ -144,8 +144,10 @@ Output.prototype.getAddress = function getAddress() {
Output.prototype.getHash = function getHash(enc) {
const addr = this.getAddress();
if (!addr)
return;
return null;
return addr.getHash(enc);
};
@ -204,12 +206,11 @@ Output.prototype.getJSON = function getJSON(network) {
Output.prototype.getDustThreshold = function getDustThreshold(rate) {
const scale = consensus.WITNESS_SCALE_FACTOR;
let size;
if (this.script.isUnspendable())
return 0;
size = this.getSize();
let size = this.getSize();
if (this.script.isProgram()) {
// 75% segwit discount applied to script size.

View File

@ -303,7 +303,6 @@ TX.prototype.frame = function frame() {
}
let raw;
if (this.hasWitness())
raw = this.frameWitness();
else
@ -1116,14 +1115,13 @@ TX.prototype.getAddresses = function getAddresses(view) {
*/
TX.prototype.getInputHashes = function getInputHashes(view, enc) {
const hashes = [];
if (enc === 'hex') {
const [, table] = this._getInputAddresses(view);
return Object.keys(table);
}
const addrs = this.getInputAddresses(view);
const hashes = [];
for (const addr of addrs)
hashes.push(addr.getHash());
@ -1137,14 +1135,13 @@ TX.prototype.getInputHashes = function getInputHashes(view, enc) {
*/
TX.prototype.getOutputHashes = function getOutputHashes(enc) {
const hashes = [];
if (enc === 'hex') {
const [, table] = this._getOutputAddresses();
return Object.keys(table);
}
const addrs = this.getOutputAddresses();
const hashes = [];
for (const addr of addrs)
hashes.push(addr.getHash());
@ -1159,14 +1156,13 @@ TX.prototype.getOutputHashes = function getOutputHashes(enc) {
*/
TX.prototype.getHashes = function getHashes(view, enc) {
const hashes = [];
if (enc === 'hex') {
const [, table] = this._getAddresses(view);
return Object.keys(table);
}
const addrs = this.getAddresses(view);
const hashes = [];
for (const addr of addrs)
hashes.push(addr.getHash());
@ -1407,9 +1403,6 @@ TX.prototype.isSane = function isSane() {
*/
TX.prototype.checkSanity = function checkSanity() {
const prevout = new Set();
let total = 0;
if (this.inputs.length === 0)
return [false, 'bad-txns-vin-empty', 100];
@ -1419,6 +1412,8 @@ TX.prototype.checkSanity = function checkSanity() {
if (this.getBaseSize() > consensus.MAX_BLOCK_SIZE)
return [false, 'bad-txns-oversize', 100];
let total = 0;
for (const output of this.outputs) {
if (output.value < 0)
return [false, 'bad-txns-vout-negative', 100];
@ -1432,10 +1427,14 @@ TX.prototype.checkSanity = function checkSanity() {
return [false, 'bad-txns-txouttotal-toolarge', 100];
}
const prevout = new Set();
for (const input of this.inputs) {
const key = input.prevout.toKey();
if (prevout.has(key))
return [false, 'bad-txns-inputs-duplicate', 100];
prevout.add(key);
}
@ -1479,8 +1478,6 @@ TX.prototype.isStandard = function isStandard() {
*/
TX.prototype.checkStandard = function checkStandard() {
let nulldata = 0;
if (this.version < 1 || this.version > policy.MAX_TX_VERSION)
return [false, 'version', 0];
@ -1495,6 +1492,8 @@ TX.prototype.checkStandard = function checkStandard() {
return [false, 'scriptsig-not-pushonly', 0];
}
let nulldata = 0;
for (const output of this.outputs) {
if (!output.script.isStandard())
return [false, 'scriptpubkey', 0];
@ -1706,10 +1705,10 @@ TX.prototype.verifyInputs = function verifyInputs(view, height) {
*/
TX.prototype.checkInputs = function checkInputs(view, height) {
let total = 0;
assert(typeof height === 'number');
let total = 0;
for (const {prevout} of this.inputs) {
let coin = view.getEntry(prevout);
@ -1781,16 +1780,16 @@ TX.prototype.getModifiedSize = function getModifiedSize(size) {
*/
TX.prototype.getPriority = function getPriority(view, height, size) {
let sum = 0;
assert(typeof height === 'number', 'Must pass in height.');
if (this.isCoinbase())
return sum;
return 0;
if (size == null)
size = this.getVirtualSize();
let sum = 0;
for (const {prevout} of this.inputs) {
const coin = view.getOutput(prevout);
@ -1818,10 +1817,10 @@ TX.prototype.getPriority = function getPriority(view, height, size) {
*/
TX.prototype.getChainValue = function getChainValue(view) {
let value = 0;
if (this.isCoinbase())
return value;
return 0;
let value = 0;
for (const {prevout} of this.inputs) {
const coin = view.getOutput(prevout);
@ -1829,9 +1828,9 @@ TX.prototype.getChainValue = function getChainValue(view) {
if (!coin)
continue;
const coinHeight = view.getHeight(prevout);
const height = view.getHeight(prevout);
if (coinHeight === -1)
if (height === -1)
continue;
value += coin.value;
@ -1917,11 +1916,11 @@ TX.prototype.getRate = function getRate(view, size) {
*/
TX.prototype.getPrevout = function getPrevout() {
const prevout = Object.create(null);
if (this.isCoinbase())
return [];
const prevout = Object.create(null);
for (const input of this.inputs)
prevout[input.prevout.hash] = true;

View File

@ -116,8 +116,10 @@ Network.prototype._init = function _init() {
Network.prototype.byBit = function byBit(bit) {
const index = util.binarySearch(this.deploys, bit, cmpBit);
if (index === -1)
return null;
return this.deploys[index];
};

View File

@ -217,8 +217,6 @@ exports.BLOCK_PRIORITY_THRESHOLD = exports.FREE_THRESHOLD;
*/
exports.getMinFee = function getMinFee(size, rate) {
let fee;
if (rate == null)
rate = exports.MIN_RELAY;
@ -228,7 +226,7 @@ exports.getMinFee = function getMinFee(size, rate) {
if (size === 0)
return 0;
fee = Math.floor(rate * size / 1000);
let fee = Math.floor(rate * size / 1000);
if (fee === 0 && rate > 0)
fee = rate;
@ -246,8 +244,6 @@ exports.getMinFee = function getMinFee(size, rate) {
*/
exports.getRoundFee = function getRoundFee(size, rate) {
let fee;
if (rate == null)
rate = exports.MIN_RELAY;
@ -257,7 +253,7 @@ exports.getRoundFee = function getRoundFee(size, rate) {
if (size === 0)
return 0;
fee = rate * Math.ceil(size / 1000);
let fee = rate * Math.ceil(size / 1000);
if (fee === 0 && rate > 0)
fee = rate;

View File

@ -49,14 +49,14 @@ util.inherits(TimeData, EventEmitter);
*/
TimeData.prototype.add = function add(id, time) {
const sample = time - util.now();
if (this.samples.length >= this.limit)
return;
if (this.known.has(id))
return;
const sample = time - util.now();
this.known.set(id, sample);
util.binaryInsert(this.samples, sample, compare);

View File

@ -555,50 +555,49 @@ exports.formatCode = function formatCode(code) {
const out = [];
for (const op of code) {
const data = op.data;
let value = op.value;
if (op.data) {
// Direct push
if (!exports.opcodesByVal[op.value]) {
let size = op.value.toString(16);
if (size.length < 2)
size = '0' + size;
out.push(`0x${size} 0x${op.data.toString('hex')}`);
continue;
}
if (data) {
let size = data.length.toString(16);
// Pushdatas
const symbol = exports.opcodesByVal[op.value];
let size = op.data.length.toString(16);
while (size.length % 2 !== 0)
size = '0' + size;
if (!exports.opcodesByVal[value]) {
value = value.toString(16);
if (value.length < 2)
value = '0' + value;
value = `0x${value} 0x${data.toString('hex')}`;
out.push(value);
continue;
}
out.push(`${symbol} 0x${size} 0x${op.data.toString('hex')}`);
value = exports.opcodesByVal[value];
value = `${value} 0x${size} 0x${data.toString('hex')}`;
out.push(value);
continue;
}
assert(typeof value === 'number');
if (exports.opcodesByVal[value]) {
value = exports.opcodesByVal[value];
out.push(value);
// Opcodes
if (exports.opcodesByVal[op.value]) {
const symbol = exports.opcodesByVal[op.value];
out.push(symbol);
continue;
}
if (value === -1) {
// Bad push
if (op.value === -1) {
out.push('OP_INVALIDOPCODE');
break;
}
value = value.toString(16);
// Unknown opcodes
let symbol = op.value.toString(16);
if (value.length < 2)
value = '0' + value;
if (symbol.length < 2)
symbol = '0' + symbol;
value = `0x${value}`;
out.push(value);
out.push(`0x${symbol}`);
}
return out.join(' ');
@ -646,29 +645,28 @@ exports.formatItem = function formatItem(data, decode) {
*/
exports.formatASM = function formatASM(code, decode) {
if (code.length > 0) {
if (code[0].value === exports.opcodes.OP_RETURN)
decode = false;
}
const out = [];
if (code.length > 0 && code[0].value === exports.opcodes.OP_RETURN)
decode = false;
for (const op of code) {
let data = op.data;
let value = op.value;
if (value === -1) {
if (op.value === -1) {
out.push('[error]');
break;
}
if (data) {
data = exports.formatItem(data, decode);
if (op.data) {
const data = exports.formatItem(op.data, decode);
out.push(data);
continue;
}
value = exports.opcodesByVal[value] || 'OP_UNKNOWN';
const symbol = exports.opcodesByVal[op.value] || 'OP_UNKNOWN';
out.push(value);
out.push(symbol);
}
return out.join(' ');

View File

@ -186,7 +186,6 @@ Opcode.prototype.getSize = function getSize() {
Opcode.prototype.fromReader = function fromReader(br) {
const op = br.readU8();
let size;
if (op >= 0x01 && op <= 0x4b) {
if (br.left() < op) {
@ -199,6 +198,8 @@ Opcode.prototype.fromReader = function fromReader(br) {
return this;
}
let size;
switch (op) {
case opcodes.OP_PUSHDATA1:
if (br.left() < 1) {

View File

@ -411,11 +411,11 @@ Script.fromJSON = function fromJSON(json) {
*/
Script.prototype.getSubscript = function getSubscript(lastSep) {
const code = [];
if (lastSep === 0)
return this.clone();
const code = [];
for (let i = lastSep; i < this.code.length; i++) {
const op = this.code[i];
@ -483,25 +483,26 @@ Script.prototype.removeSeparators = function removeSeparators() {
*/
Script.prototype.execute = function execute(stack, flags, tx, index, value, version) {
const state = [];
const alt = [];
let lastSep = 0;
let opCount = 0;
let negate = 0;
let minimal = false;
if (flags == null)
flags = Script.flags.STANDARD_VERIFY_FLAGS;
if (version == null)
version = 0;
if (flags & Script.flags.VERIFY_MINIMALDATA)
minimal = true;
if (this.getSize() > consensus.MAX_SCRIPT_SIZE)
throw new ScriptError('SCRIPT_SIZE');
const state = [];
const alt = [];
let lastSep = 0;
let opCount = 0;
let negate = 0;
let minimal = false;
if (flags & Script.flags.VERIFY_MINIMALDATA)
minimal = true;
for (let ip = 0; ip < this.code.length; ip++) {
const op = this.code[ip];
@ -1667,15 +1668,15 @@ Script.fromCommitment = function fromCommitment(hash, flags) {
Script.prototype.getRedeem = function getRedeem() {
if (this.code.length === 0)
return;
return null;
if (!this.isPushOnly())
return;
return null;
const redeem = this.code[this.code.length - 1];
if (!redeem.data)
return;
return null;
return Script.fromRaw(redeem.data);
};
@ -1987,7 +1988,7 @@ Script.prototype.isCommitment = function isCommitment() {
Script.prototype.getCommitmentHash = function getCommitmentHash() {
if (!this.isCommitment())
return;
return null;
return this.raw.slice(6, 38);
};
@ -2021,7 +2022,7 @@ Script.prototype.isProgram = function isProgram() {
Script.prototype.toProgram = function toProgram() {
if (!this.isProgram())
return;
return null;
const version = common.getSmall(this.raw[0]);
const data = this.raw.slice(2);
@ -2671,12 +2672,11 @@ Script.prototype.fromString = function fromString(code) {
if (code.length === 0)
return this;
code = code.split(/\s+/);
const items = code.split(/\s+/);
const bw = new BufferWriter();
for (let op of code) {
let symbol = op;
for (const item of items) {
let symbol = item;
if (!util.isUpperCase(symbol))
symbol = symbol.toUpperCase();
@ -2684,29 +2684,37 @@ Script.prototype.fromString = function fromString(code) {
if (!util.startsWith(symbol, 'OP_'))
symbol = `OP_${symbol}`;
if (opcodes[symbol] == null) {
if (op[0] === '\'') {
assert(op[op.length - 1] === '\'', 'Unknown opcode.');
op = op.slice(1, -1);
op = Opcode.fromString(op);
const value = opcodes[symbol];
if (value == null) {
if (item[0] === '\'') {
assert(item[item.length - 1] === '\'', 'Unknown opcode.');
const str = item.slice(1, -1);
const op = Opcode.fromString(str);
bw.writeBytes(op.toRaw());
continue;
}
if (/^-?\d+$/.test(op)) {
op = new BN(op, 10);
op = Opcode.fromNumber(op);
if (/^-?\d+$/.test(item)) {
const num = new BN(item, 10);
const op = Opcode.fromNumber(num);
bw.writeBytes(op.toRaw());
continue;
}
assert(op.indexOf('0x') === 0, 'Unknown opcode.');
op = op.substring(2);
assert(util.isHex(op), 'Unknown opcode.');
op = Buffer.from(op, 'hex');
bw.writeBytes(op);
assert(item.indexOf('0x') === 0, 'Unknown opcode.');
const str = item.substring(2);
const data = Buffer.from(str, 'hex');
assert(data.length === str.length / 2, 'Unknown opcode.');
bw.writeBytes(data);
continue;
}
bw.writeU8(opcodes[symbol]);
bw.writeU8(value);
}
return this.fromRaw(bw.render());
@ -2738,8 +2746,6 @@ Script.fromString = function fromString(code) {
*/
Script.verify = function verify(input, witness, output, tx, i, value, flags) {
let hadWitness = false;
if (flags == null)
flags = Script.flags.STANDARD_VERIFY_FLAGS;
@ -2766,6 +2772,8 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
if (stack.length === 0 || !Script.bool(stack.top(-1)))
throw new ScriptError('EVAL_FALSE');
let hadWitness = false;
if ((flags & Script.flags.VERIFY_WITNESS) && output.isProgram()) {
hadWitness = true;
@ -2852,12 +2860,13 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, value) {
const program = output.toProgram();
const stack = witness.toStack();
let redeem;
assert(program, 'verifyProgram called on non-witness-program.');
assert((flags & Script.flags.VERIFY_WITNESS) !== 0);
const stack = witness.toStack();
let redeem;
if (program.version === 0) {
if (program.data.length === 32) {
if (stack.length === 0)
@ -2923,11 +2932,6 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val
*/
Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, value) {
let mastRoot = new BufferWriter();
let scriptRoot = new BufferWriter();
let scripts = new BufferWriter();
let version = 0;
assert(program.version === 1);
assert((flags & Script.flags.VERIFY_MAST) !== 0);
@ -2943,11 +2947,14 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
throw new ScriptError('INVALID_MAST_STACK');
let ops = subscripts;
let scriptRoot = new BufferWriter();
scriptRoot.writeU8(subscripts);
if (metadata[metadata.length - 1] === 0x00)
throw new ScriptError('INVALID_MAST_STACK');
let version = 0;
for (let j = 1; j < metadata.length; j++)
version |= metadata[i] << 8 * (j - 1);
@ -2959,6 +2966,7 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
throw new ScriptError('DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM');
}
let mastRoot = new BufferWriter();
mastRoot.writeU32(version);
const pathdata = stack.top(-2);
@ -3004,6 +3012,7 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
throw new ScriptError('INVALID_MAST_STACK');
}
let scripts = new BufferWriter();
scripts.writeBytes(output.raw);
for (let j = 0; j < subscripts; j++) {

View File

@ -162,12 +162,11 @@ ScriptNum.prototype.toJSON = function toJSON() {
};
ScriptNum.prototype.fromString = function fromString(str, base) {
let nonzero = 0;
let negative = false;
if (!base)
base = 10;
let negative = false;
if (str[0] === '-') {
assert(str.length > 1, 'Non-numeric string passed.');
str = str.substring(1);
@ -179,6 +178,7 @@ ScriptNum.prototype.fromString = function fromString(str, base) {
this.value = 0;
if (base === 10 || base === 'dec') {
let nonzero = 0;
for (let i = 0; i < str.length; i++) {
let ch = str[i];
@ -204,6 +204,7 @@ ScriptNum.prototype.fromString = function fromString(str, base) {
}
if (base === 16 || base === 'hex') {
let nonzero = 0;
for (let i = 0; i < str.length; i++) {
let ch = str[i];
@ -320,20 +321,20 @@ ScriptNum.fromRaw = function fromRaw(data, minimal, limit) {
ScriptNum.prototype.toRaw = function toRaw() {
let value = this.value;
let negative = false;
let offset, size;
// Zeroes are always empty arrays.
if (value === 0)
return EMPTY_ARRAY;
// Need to append sign bit.
let negative = false;
if (value < 0) {
negative = true;
value = -value;
}
// Gauge buffer size.
let offset, size;
if (value <= 0xff) {
offset = (value & 0x80) ? 1 : 0;
size = 1;

View File

@ -183,7 +183,7 @@ Stack.prototype.remove = function remove(i) {
i = this.items.length + i;
if (i >= this.items.length)
return;
return undefined;
return this.items.splice(i, 1)[0];
};

View File

@ -78,13 +78,11 @@ Witness.prototype.__defineSetter__('length', function(length) {
Witness.prototype.fromOptions = function fromOptions(options) {
assert(options, 'Witness data is required.');
let items = options.items;
if (Array.isArray(options))
return this.fromArray(options);
if (!items)
items = options;
if (items)
this.fromArray(items);
if (options.items)
return this.fromArray(options.items);
return this;
};
@ -294,12 +292,12 @@ Witness.prototype.test = function test(filter) {
Witness.prototype.getRedeem = function getRedeem() {
if (this.items.length === 0)
return;
return null;
const redeem = this.items[this.items.length - 1];
if (!redeem)
return;
return null;
return Script.fromRaw(redeem);
};
@ -496,8 +494,10 @@ Witness.prototype.getSmall = function getSmall(i) {
Witness.prototype.getNumber = function getNumber(i) {
const item = this.items[i];
if (!item || item.length > 5)
return;
return null;
return common.num(item, false, 5);
};
@ -509,8 +509,10 @@ Witness.prototype.getNumber = function getNumber(i) {
Witness.prototype.getString = function getString(i) {
const item = this.items[i];
if (!item)
return;
return null;
return item.toString('utf8');
};

View File

@ -123,8 +123,10 @@ ASN1.readSeq = function readSeq(br) {
ASN1.implicit = function implicit(br, type) {
const tag = ASN1.readTag(br);
if (tag.type !== type)
throw new Error(`Unexpected tag: ${tag.type}.`);
return tag;
};
@ -138,10 +140,12 @@ ASN1.implicit = function implicit(br, type) {
ASN1.explicit = function explicit(br, type) {
const offset = br.offset;
const tag = ASN1.readTag(br);
if (tag.type !== type) {
br.offset = offset;
return false;
}
return true;
};
@ -158,15 +162,15 @@ ASN1.seq = function seq(br) {
/**
* Read implicit int.
* @param {BufferReader} br
* @param {Boolean?} readNum
* @param {Boolean?} cast
* @returns {Buffer|Number}
*/
ASN1.readInt = function readInt(br, readNum) {
ASN1.readInt = function readInt(br, cast) {
const tag = ASN1.implicit(br, 0x02);
const num = br.readBytes(tag.size);
if (readNum)
if (cast)
return num.readUIntBE(0, num.length);
return num;
@ -183,6 +187,7 @@ ASN1.readInt = function readInt(br, readNum) {
ASN1.readExplicitInt = function readExplicitInt(br, type, readNum) {
if (!ASN1.explicit(br, type))
return -1;
return ASN1.readInt(br, readNum);
};
@ -210,7 +215,7 @@ ASN1.readString = function readString(br) {
switch (tag.type) {
case 0x03: { // bitstr
const str = br.readBytes(tag.size);
return ASN1.alignBitstr(str);
return ASN1.alignBitstr(str).toString('utf8');
}
// Note:
// Fuck all these.

View File

@ -183,7 +183,7 @@ AsyncEmitter.prototype.listeners = function listeners(type) {
const listeners = this._events[type];
if (!listeners)
return result;
return [];
const result = [];
@ -236,7 +236,7 @@ AsyncEmitter.prototype.emit = function emit(type) {
return;
}
let args = null;
let args;
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
@ -299,7 +299,7 @@ AsyncEmitter.prototype.fire = async function fire(type) {
return;
}
let args = null;
let args;
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];

View File

@ -197,7 +197,7 @@ AsyncObject.prototype.fireHook = async function fireHook(type) {
if (!listeners || listeners.length === 0)
return;
let args = null;
let args;
for (const handler of listeners) {
switch (arguments.length) {

View File

@ -27,10 +27,9 @@ exports.encode = function encode(data) {
let str = '';
let mode = 0;
let left = 0;
let i, ch;
for (i = 0; i < data.length; i++) {
ch = data[i];
for (let i = 0; i < data.length; i++) {
const ch = data[i];
switch (mode) {
case 0:
str += base32[ch >>> 3];
@ -64,7 +63,7 @@ exports.encode = function encode(data) {
if (mode > 0) {
str += base32[left];
for (i = 0; i < padding[mode]; i++)
for (let i = 0; i < padding[mode]; i++)
str += '=';
}
@ -82,10 +81,10 @@ exports.decode = function decode(str) {
let mode = 0;
let left = 0;
let j = 0;
let i, ch;
let i;
for (i = 0; i < str.length; i++) {
ch = unbase32[str[i]];
const ch = unbase32[str[i]];
if (ch == null)
break;

View File

@ -74,7 +74,6 @@ function polymod(pre) {
*/
function serialize(hrp, data) {
let str = '';
let chk = 1;
let i;
@ -92,6 +91,8 @@ function serialize(hrp, data) {
chk = polymod(chk);
let str = '';
for (let i = 0; i < hrp.length; i++) {
const ch = hrp.charCodeAt(i);
chk = polymod(chk) ^ (ch & 0x1f);

View File

@ -262,8 +262,8 @@ Bloom.fromRate = function fromRate(items, rate, update) {
assert(typeof rate === 'number', '`rate` must be a number.');
assert(rate >= 0 && rate <= 1, '`rate` must be between 0.0 and 1.0.');
let size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0;
size = Math.max(8, size);
const bits = (-1 / LN2SQUARED * items * Math.log(rate)) | 0;
const size = Math.max(8, bits);
if (update !== -1) {
assert(size <= Bloom.MAX_BLOOM_FILTER_SIZE * 8,

View File

@ -21,6 +21,8 @@ const assert = require('assert');
function exec(gen) {
return new Promise((resolve, reject) => {
/* eslint no-use-before-define: "off" */
const step = (value, rejection) => {
let next;

View File

@ -899,12 +899,12 @@ encoding.readVarint2BN = function readVarint2BN(data, off) {
*/
encoding.writeVarint2BN = function writeVarint2BN(dst, num, off) {
const tmp = [];
let len = 0;
if (num.bitLength() <= 53)
return encoding.writeVarint2(dst, num.toNumber());
const tmp = [];
let len = 0;
for (;;) {
tmp[len] = (num.words[0] & 0x7f) | (len ? 0x80 : 0x00);
if (num.cmpn(0x7f) <= 0)
@ -929,13 +929,13 @@ encoding.writeVarint2BN = function writeVarint2BN(dst, num, off) {
*/
encoding.sizeVarint2BN = function sizeVarint2BN(num) {
let size = 0;
if (num.bitLength() <= 53)
return encoding.sizeVarint(num.toNumber());
num = num.clone();
let size = 0;
for (;;) {
size++;
if (num.cmpn(0x7f) <= 0)

View File

@ -85,11 +85,11 @@ exports.writeFile = co.promisify(fs.writeFile);
exports.writeFileSync = fs.writeFileSync;
exports.mkdirpSync = function mkdirpSync(dir, mode) {
let [path, parts] = getParts(dir);
if (mode == null)
mode = 0o750;
let [path, parts] = getParts(dir);
for (const part of parts) {
path += part;
@ -109,11 +109,11 @@ exports.mkdirpSync = function mkdirpSync(dir, mode) {
};
exports.mkdirp = async function mkdirp(dir, mode) {
let [path, parts] = getParts(dir);
if (mode == null)
mode = 0o750;
let [path, parts] = getParts(dir);
for (const part of parts) {
path += part;
@ -138,6 +138,7 @@ function getParts(path) {
path = path.replace(/\/+\.?$/, '');
const parts = path.split(/\/+/);
let root = '';
if (process.platform === 'win32') {

View File

@ -63,12 +63,11 @@ GCSFilter.prototype.match = function match(key, data) {
};
GCSFilter.prototype.matchAny = function matchAny(key, items) {
assert(items.length > 0);
const br = new BitReader(this.data);
const last1 = new Int64(0);
const values = [];
let i, last2;
assert(items.length > 0);
for (const item of items) {
const hash = siphash(item, key).imod(this.m);
@ -77,8 +76,8 @@ GCSFilter.prototype.matchAny = function matchAny(key, items) {
values.sort(compare);
last2 = values[0];
i = 1;
let last2 = values[0];
let i = 1;
for (;;) {
const cmp = last1.cmp(last2);
@ -160,10 +159,6 @@ GCSFilter.prototype.toRaw = function toRaw() {
};
GCSFilter.prototype.fromItems = function fromItems(P, key, items) {
const bw = new BitWriter();
let last = new Int64(0);
const values = [];
assert(typeof P === 'number' && isFinite(P));
assert(P >= 0 && P <= 32);
@ -178,6 +173,8 @@ GCSFilter.prototype.fromItems = function fromItems(P, key, items) {
this.p = P;
this.m = Int64(this.n).ishln(this.p);
const values = [];
for (const item of items) {
assert(Buffer.isBuffer(item));
const hash = siphash(item, key).imod(this.m);
@ -186,6 +183,9 @@ GCSFilter.prototype.fromItems = function fromItems(P, key, items) {
values.sort(compare);
const bw = new BitWriter();
let last = new Int64(0);
for (const hash of values) {
const rem = hash.sub(last).imaskn(this.p);
const value = hash.sub(last).isub(rem).ishrn(this.p);
@ -439,8 +439,6 @@ BitReader.prototype.readBit = function readBit() {
};
BitReader.prototype.readByte = function readByte() {
let ch;
if (this.pos >= this.stream.length)
throw new Error('EOF');
@ -454,12 +452,12 @@ BitReader.prototype.readByte = function readByte() {
}
if (this.remain === 8) {
ch = this.stream[this.pos];
const ch = this.stream[this.pos];
this.pos += 1;
return ch;
}
ch = this.stream[this.pos] & ((1 << this.remain) - 1);
let ch = this.stream[this.pos] & ((1 << this.remain) - 1);
ch <<= 8 - this.remain;
this.pos += 1;
@ -473,11 +471,11 @@ BitReader.prototype.readByte = function readByte() {
};
BitReader.prototype.readBits = function readBits(count) {
let num = 0;
assert(count >= 0);
assert(count <= 32);
let num = 0;
while (count >= 8) {
num <<= 8;
num |= this.readByte();
@ -494,11 +492,11 @@ BitReader.prototype.readBits = function readBits(count) {
};
BitReader.prototype.readBits64 = function readBits(count) {
const num = new Int64();
assert(count >= 0);
assert(count <= 64);
const num = new Int64();
if (count > 32) {
num.hi = this.readBits(count - 32);
num.lo = this.readBits(32);

View File

@ -80,7 +80,7 @@ Heap.prototype.insert = function insert(item) {
Heap.prototype.shift = function shift() {
if (this.items.length === 0)
return;
return null;
const n = this.items.length - 1;
@ -98,12 +98,12 @@ Heap.prototype.shift = function shift() {
Heap.prototype.remove = function remove(i) {
if (this.items.length === 0)
return;
return null;
const n = this.items.length - 1;
if (i < 0 || i > n)
return;
return null;
if (n !== i) {
this.swap(i, n);

View File

@ -269,10 +269,10 @@ IP.isMapped = function isMapped(raw) {
*/
IP.toBuffer = function toBuffer(str) {
const raw = Buffer.allocUnsafe(16);
assert(typeof str === 'string');
const raw = Buffer.allocUnsafe(16);
if (IP.isV4String(str)) {
raw.fill(0);
raw[10] = 0xff;
@ -329,8 +329,6 @@ IP.parseV4 = function parseV4(str, raw, offset) {
IP.parseV6 = function parseV6(str, raw, offset) {
const parts = str.split(':');
let missing = 8 - parts.length;
const start = offset;
let colon = false;
assert(parts.length >= 2, 'Not an IPv6 address.');
@ -339,6 +337,9 @@ IP.parseV6 = function parseV6(str, raw, offset) {
missing--;
}
const start = offset;
let colon = false;
for (let i = 0; i < parts.length; i++) {
let word = parts[i];
@ -855,13 +856,13 @@ IP.getReachability = function getReachability(src, dest) {
const IPV6_STRONG = 5;
const PRIVATE = 6;
if (!IP.isRoutable(src))
return UNREACHABLE;
const srcNet = IP.getNetwork(src);
const destNet = IP.getNetwork(dest);
const types = IP.types;
if (!IP.isRoutable(src))
return UNREACHABLE;
switch (destNet) {
case types.IPV4:
switch (srcNet) {
@ -958,16 +959,7 @@ IP.hasPrefix = function hasPrefix(raw, prefix) {
IP.isEqual = function isEqual(a, b) {
assert(a.length === 16);
assert(b.length === 16);
if (a.compare)
return a.compare(b) === 0;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i])
return false;
}
return true;
return a.equals(b);
};
/**
@ -994,7 +986,6 @@ IP.getInterfaces = function _getInterfaces(name, family) {
continue;
let raw;
try {
raw = IP.toBuffer(details.address);
} catch (e) {

View File

@ -55,7 +55,7 @@ List.prototype.shift = function shift() {
const item = this.head;
if (!item)
return;
return null;
this.remove(item);
@ -91,7 +91,7 @@ List.prototype.pop = function pop() {
const item = this.tail;
if (!item)
return;
return null;
this.remove(item);

View File

@ -174,10 +174,10 @@ Lock.prototype.destroy = function destroy() {
this.destroyed = true;
const jobs = this.jobs.slice();
const jobs = this.jobs;
this.busy = false;
this.jobs.length = 0;
this.jobs = [];
this.map.clear();
this.current = null;

View File

@ -62,7 +62,6 @@ LRU.prototype._compact = function _compact() {
return;
let item, next;
for (item = this.head; item; item = next) {
if (this.size <= this.capacity)
break;
@ -150,14 +149,14 @@ LRU.prototype.set = function set(key, value) {
LRU.prototype.get = function get(key) {
if (this.capacity === 0)
return;
return null;
key = key + '';
const item = this.map.get(key);
if (!item)
return;
return null;
this._removeList(item);
this._appendList(item);
@ -185,7 +184,7 @@ LRU.prototype.has = function get(key) {
LRU.prototype.remove = function remove(key) {
if (this.capacity === 0)
return;
return false;
key = key + '';

View File

@ -132,10 +132,10 @@ MappedLock.prototype.unlock = function unlock(key) {
*/
MappedLock.prototype.destroy = function destroy() {
const map = this.jobs;
assert(!this.destroyed, 'Lock is already destroyed.');
const map = this.jobs;
this.destroyed = true;
this.jobs = new Map();

View File

@ -72,14 +72,14 @@ function mul32(a, b) {
const blo = b & 0xffff;
const ahi = a >>> 16;
const bhi = b >>> 16;
let r, lo, hi;
lo = alo * blo;
hi = (ahi * blo + bhi * alo) & 0xffff;
let lo = alo * blo;
let hi = (ahi * blo + bhi * alo) & 0xffff;
hi += lo >>> 16;
lo &= 0xffff;
r = (hi << 16) | lo;
let r = (hi << 16) | lo;
if (r < 0)
r += 0x100000000;

View File

@ -22,41 +22,56 @@ const PEM = exports;
*/
PEM.parse = function parse(pem) {
let buf = '';
const chunks = [];
let s, tag, type;
let chunk = '';
let tag;
while (pem.length) {
if (s = /^-----BEGIN ([^\-]+)-----/.exec(pem)) {
pem = pem.substring(s[0].length);
tag = s[1];
let m;
if (m = /^-----BEGIN ([^\-]+)-----/.exec(pem)) {
pem = pem.substring(m[0].length);
tag = m[1];
continue;
}
if (s = /^-----END ([^\-]+)-----/.exec(pem)) {
pem = pem.substring(s[0].length);
assert(tag === s[1], 'Tag mismatch.');
buf = Buffer.from(buf, 'base64');
type = tag.split(' ')[0].toLowerCase();
chunks.push({ tag: tag, type: type, data: buf });
buf = '';
if (m = /^-----END ([^\-]+)-----/.exec(pem)) {
pem = pem.substring(m[0].length);
assert(tag === m[1], 'Tag mismatch.');
const type = tag.split(' ')[0].toLowerCase();
const data = Buffer.from(chunk, 'base64');
chunks.push({
tag: tag,
type: type,
data: data
});
chunk = '';
tag = null;
continue;
}
if (s = /^[a-zA-Z0-9\+=\/]+/.exec(pem)) {
pem = pem.substring(s[0].length);
buf += s[0];
if (m = /^[a-zA-Z0-9\+=\/]+/.exec(pem)) {
pem = pem.substring(m[0].length);
chunk += m[0];
continue;
}
if (s = /^\s+/.exec(pem)) {
pem = pem.substring(s[0].length);
if (m = /^\s+/.exec(pem)) {
pem = pem.substring(m[0].length);
continue;
}
throw new Error('PEM parse error.');
}
assert(chunks.length !== 0, 'PEM parse error.');
assert(!tag, 'Un-ended tag.');
assert(buf.length === 0, 'Trailing data.');
assert(chunk.length === 0, 'Trailing data.');
return chunks;
};
@ -72,13 +87,16 @@ PEM.decode = function decode(pem) {
const chunks = PEM.parse(pem);
const body = chunks[0];
const extra = chunks[1];
let params, alg;
let params = null;
if (extra) {
if (extra.tag.indexOf('PARAMETERS') !== -1)
params = extra.data;
}
let alg = null;
switch (body.type) {
case 'dsa':
alg = 'dsa';
@ -121,6 +139,6 @@ PEM.encode = function encode(der, type, suffix) {
return ''
+ `-----BEGIN ${type}-----\n`
+ `${pem}`
+ pem
+ `-----END ${type}-----\n`;
};

View File

@ -46,41 +46,56 @@ ProtoReader.prototype.readVarint = function _readVarint() {
ProtoReader.prototype.readFieldValue = function readFieldValue(tag, opt) {
const field = this.readField(tag, opt);
if (!field)
return -1;
assert(field.value != null);
return field.value;
};
ProtoReader.prototype.readFieldU64 = function readFieldU64(tag, opt) {
const field = this.readField(tag, opt);
if (!field)
return -1;
assert(field.type === wireType.VARINT || field.type === wireType.FIXED64);
return field.value;
};
ProtoReader.prototype.readFieldU32 = function readFieldU32(tag, opt) {
const field = this.readField(tag, opt);
if (!field)
return -1;
assert(field.type === wireType.VARINT || field.type === wireType.FIXED32);
return field.value;
};
ProtoReader.prototype.readFieldBytes = function readFieldBytes(tag, opt) {
const field = this.readField(tag, opt);
if (!field)
return null;
assert(field.data);
return field.data;
};
ProtoReader.prototype.readFieldString = function readFieldString(tag, opt, enc) {
const field = this.readField(tag, opt);
if (!field)
return null;
assert(field.data);
return field.data.toString(enc || 'utf8');
};

View File

@ -44,44 +44,50 @@ util.inherits(ProtoWriter, BufferWriter);
ProtoWriter.prototype.writeVarint = function _writeVarint(num) {
const size = sizeVarint(num);
let value;
// Avoid an extra allocation until
// we make bufferwriter more hackable.
// More insanity here...
switch (size) {
case 6:
value = slipVarint(num);
case 6: {
const value = slipVarint(num);
this.writeU32BE(value / 0x10000 | 0);
this.writeU16BE(value & 0xffff);
break;
case 5:
value = slipVarint(num);
}
case 5: {
const value = slipVarint(num);
this.writeU32BE(value / 0x100 | 0);
this.writeU8(value & 0xff);
break;
case 4:
value = slipVarint(num);
}
case 4: {
const value = slipVarint(num);
this.writeU32BE(value);
break;
case 3:
value = slipVarint(num);
}
case 3: {
const value = slipVarint(num);
this.writeU16BE(value >> 8);
this.writeU8(value & 0xff);
break;
case 2:
value = slipVarint(num);
}
case 2: {
const value = slipVarint(num);
this.writeU16BE(value);
break;
case 1:
value = slipVarint(num);
}
case 1: {
const value = slipVarint(num);
this.writeU8(value);
break;
default:
value = Buffer.allocUnsafe(size);
}
default: {
const value = Buffer.allocUnsafe(size);
writeVarint(value, num, 0);
this.writeBytes(value);
break;
}
}
};
@ -119,13 +125,11 @@ ProtoWriter.prototype.writeFieldString = function writeFieldString(tag, data, en
*/
function writeVarint(data, num, off) {
let ch;
assert(util.isSafeInteger(num), 'Number exceeds 2^53-1.');
do {
assert(off < data.length);
ch = num & 0x7f;
let ch = num & 0x7f;
num -= num % 0x80;
num /= 0x80;
if (num !== 0)
@ -138,15 +142,14 @@ function writeVarint(data, num, off) {
};
function slipVarint(num) {
assert(util.isSafeInteger(num), 'Number exceeds 2^53-1.');
let data = 0;
let size = 0;
let ch;
assert(util.isSafeInteger(num), 'Number exceeds 2^53-1.');
do {
assert(size < 7);
ch = num & 0x7f;
let ch = num & 0x7f;
num -= num % 0x80;
num /= 0x80;
if (num !== 0)
@ -160,10 +163,10 @@ function slipVarint(num) {
}
function sizeVarint(num) {
let size = 0;
assert(util.isSafeInteger(num), 'Number exceeds 2^53-1.');
let size = 0;
do {
num -= num % 0x80;
num /= 0x80;

View File

@ -58,6 +58,8 @@ RBT.prototype.search = function search(key) {
else
current = current.right;
}
return null;
};
/**
@ -118,13 +120,11 @@ RBT.prototype.insert = function insert(key, value) {
*/
RBT.prototype.insertFixup = function insertFixup(x) {
let y;
x.color = RED;
while (x !== this.root && x.parent.color === RED) {
if (x.parent === x.parent.parent.left) {
y = x.parent.parent.right;
const y = x.parent.parent.right;
if (!y.isNull() && y.color === RED) {
x.parent.color = BLACK;
y.color = BLACK;
@ -140,7 +140,7 @@ RBT.prototype.insertFixup = function insertFixup(x) {
this.rotr(x.parent.parent);
}
} else {
y = x.parent.parent.left;
const y = x.parent.parent.left;
if (!y.isNull() && y.color === RED) {
x.parent.color = BLACK;
y.color = BLACK;
@ -183,6 +183,8 @@ RBT.prototype.remove = function remove(key) {
else
current = current.right;
}
return null;
};
/**
@ -225,11 +227,9 @@ RBT.prototype.removeNode = function removeNode(z) {
*/
RBT.prototype.removeFixup = function removeFixup(x) {
let w;
while (x !== this.root && x.color === BLACK) {
if (x === x.parent.left) {
w = x.parent.right;
let w = x.parent.right;
if (w.color === RED) {
w.color = BLACK;
@ -255,7 +255,7 @@ RBT.prototype.removeFixup = function removeFixup(x) {
x = this.root;
}
} else {
w = x.parent.left;
let w = x.parent.left;
if (w.color === RED) {
w.color = BLACK;
@ -294,6 +294,7 @@ RBT.prototype.removeFixup = function removeFixup(x) {
RBT.prototype.rotl = function rotl(x) {
const y = x.right;
x.right = y.left;
if (!y.left.isNull())
@ -322,6 +323,7 @@ RBT.prototype.rotl = function rotl(x) {
RBT.prototype.rotr = function rotr(x) {
const y = x.left;
x.left = y.right;
if (!y.right.isNull())
@ -352,8 +354,10 @@ RBT.prototype.rotr = function rotr(x) {
RBT.prototype.min = function min(z) {
if (z.isNull())
return z;
while (!z.left.isNull())
z = z.left;
return z;
};
@ -367,8 +371,10 @@ RBT.prototype.min = function min(z) {
RBT.prototype.max = function max(z) {
if (z.isNull())
return z;
while (!z.right.isNull())
z = z.right;
return z;
};
@ -380,18 +386,21 @@ RBT.prototype.max = function max(z) {
*/
RBT.prototype.successor = function successor(x) {
let y;
if (!x.right.isNull()) {
x = x.right;
while (!x.left.isNull())
x = x.left;
return x;
}
y = x.parent;
let y = x.parent;
while (!y.isNull() && x === y.right) {
x = y;
y = y.parent;
}
return y;
};
@ -403,18 +412,21 @@ RBT.prototype.successor = function successor(x) {
*/
RBT.prototype.predecessor = function predecessor(x) {
let y;
if (!x.left.isNull()) {
x = x.left;
while (!x.right.isNull())
x = x.right;
return x;
}
y = x.parent;
let y = x.parent;
while (!y.isNull() && x === y.left) {
x = y;
y = y.parent;
}
return y;
};
@ -425,14 +437,18 @@ RBT.prototype.predecessor = function predecessor(x) {
*/
RBT.prototype.clone = function clone() {
let current = this.root;
if (this.root.isNull())
return SENTINEL;
const stack = [];
let current = this.root;
let left = true;
let parent, copy, snapshot;
let parent, snapshot;
for (;;) {
if (!current.isNull()) {
copy = current.clone();
const copy = current.clone();
if (parent)
copy.parent = parent;
@ -465,6 +481,8 @@ RBT.prototype.clone = function clone() {
current = current.right;
}
assert(snapshot);
return snapshot;
};
@ -475,12 +493,10 @@ RBT.prototype.clone = function clone() {
*/
RBT.prototype.snapshot = function snapshot() {
let node = SENTINEL;
if (this.root.isNull())
return node;
return SENTINEL;
node = this.root.clone();
const node = this.root.clone();
copyLeft(node, node.left);
copyRight(node, node.right);
@ -607,11 +623,11 @@ Iterator.prototype.seek = function seek(key) {
*/
Iterator.prototype.seekMin = function seekMin(key) {
assert(key != null, 'No key passed to seek.');
let root = this.current;
let current = SENTINEL;
assert(key != null, 'No key passed to seek.');
while (!root.isNull()) {
const cmp = this.tree.compare(root.key, key);
@ -639,11 +655,11 @@ Iterator.prototype.seekMin = function seekMin(key) {
*/
Iterator.prototype.seekMax = function seekMax(key) {
assert(key != null, 'No key passed to seek.');
let root = this.current;
let current = SENTINEL;
assert(key != null, 'No key passed to seek.');
while (!root.isNull()) {
const cmp = this.tree.compare(root.key, key);

View File

@ -60,6 +60,7 @@ RollingFilter.prototype.fromRate = function fromRate(items, rate) {
const limit = (items + 1) / 2 | 0;
const max = limit * 3;
let size = -1 * n * max / Math.log(1.0 - Math.exp(logRate / n));
size = Math.ceil(size);
@ -161,19 +162,16 @@ RollingFilter.prototype.add = function add(val, enc) {
const hash = this.hash(val, i);
const bits = hash & 0x3f;
const pos = (hash >>> 6) % this.items;
let pos1 = (pos & ~1) * 8;
let pos2 = (pos | 1) * 8;
const pos1 = (pos & ~1) * 8;
const pos2 = (pos | 1) * 8;
const bit = bits % 8;
const oct = (bits - bit) / 8;
pos1 += oct;
pos2 += oct;
this.filter[pos1 + oct] &= ~(1 << bit);
this.filter[pos1 + oct] |= (this.generation & 1) << bit;
this.filter[pos1] &= ~(1 << bit);
this.filter[pos1] |= (this.generation & 1) << bit;
this.filter[pos2] &= ~(1 << bit);
this.filter[pos2] |= (this.generation >>> 1) << bit;
this.filter[pos2 + oct] &= ~(1 << bit);
this.filter[pos2 + oct] |= (this.generation >>> 1) << bit;
}
};
@ -193,20 +191,17 @@ RollingFilter.prototype.test = function test(val, enc) {
for (let i = 0; i < this.n; i++) {
const hash = this.hash(val, i);
let bits = hash & 0x3f;
const bits = hash & 0x3f;
const pos = (hash >>> 6) % this.items;
let pos1 = (pos & ~1) * 8;
let pos2 = (pos | 1) * 8;
const pos1 = (pos & ~1) * 8;
const pos2 = (pos | 1) * 8;
const bit = bits % 8;
const oct = (bits - bit) / 8;
pos1 += oct;
pos2 += oct;
const bit1 = (this.filter[pos1 + oct] >>> bit) & 1;
const bit2 = (this.filter[pos2 + oct] >>> bit) & 1;
bits = (this.filter[pos1] >>> bit) & 1;
bits |= (this.filter[pos2] >>> bit) & 1;
if (bits === 0)
if ((bit1 | bit2) === 0)
return false;
}

View File

@ -38,12 +38,12 @@ const inspectOptions = {
util.hrtime = function hrtime(time) {
if (!process.hrtime) {
let now = util.ms();
const now = util.ms();
if (time) {
time = time[0] * 1000 + time[1] / 1e6;
now -= time;
return now;
const [hi, lo] = time;
const start = hi * 1000 + lo / 1e6;
return now - start;
}
const ms = now % 1000;
@ -53,8 +53,8 @@ util.hrtime = function hrtime(time) {
}
if (time) {
const elapsed = process.hrtime(time);
return elapsed[0] * 1000 + elapsed[1] / 1e6;
const [hi, lo] = process.hrtime(time);
return hi * 1000 + lo / 1e6;
}
return process.hrtime();
@ -519,7 +519,9 @@ util.indexOf = function indexOf(items, data) {
for (let i = 0; i < items.length; i++) {
const item = items[i];
assert(Buffer.isBuffer(item));
if (item.equals(data))
return i;
}
@ -537,7 +539,9 @@ util.indexOf = function indexOf(items, data) {
util.pad8 = function pad8(num) {
assert(typeof num === 'number');
assert(num >= 0);
num = num + '';
switch (num.length) {
case 1:
return '00' + num;
@ -546,6 +550,7 @@ util.pad8 = function pad8(num) {
case 3:
return num;
}
assert(false);
};
@ -559,7 +564,9 @@ util.pad8 = function pad8(num) {
util.pad32 = function pad32(num) {
assert(typeof num === 'number');
assert(num >= 0);
num = num + '';
switch (num.length) {
case 1:
return '000000000' + num;
@ -581,9 +588,9 @@ util.pad32 = function pad32(num) {
return '0' + num;
case 10:
return num;
default:
assert(false);
}
assert(false);
};
/**
@ -596,15 +603,17 @@ util.pad32 = function pad32(num) {
util.hex8 = function hex8(num) {
assert(typeof num === 'number');
assert(num >= 0);
num = num.toString(16);
switch (num.length) {
case 1:
return '0' + num;
case 2:
return num;
default:
assert(false);
}
assert(false);
};
/**
@ -617,7 +626,9 @@ util.hex8 = function hex8(num) {
util.hex32 = function hex32(num) {
assert(typeof num === 'number');
assert(num >= 0);
num = num.toString(16);
switch (num.length) {
case 1:
return '0000000' + num;
@ -635,9 +646,9 @@ util.hex32 = function hex32(num) {
return '0' + num;
case 8:
return num;
default:
assert(false);
}
assert(false);
};
/**

View File

@ -439,8 +439,9 @@ Validator.prototype.bool = function bool(key, fallback) {
if (value === null)
return fallback;
// bitcoin core mixes semantics of truthiness amoung rpc methods
// most "verbose" parameters are bools, but getrawtransaction is 1/0
// Bitcoin Core mixes semantics of truthiness
// amoung rpc methods most "verbose" parameters
// are bools, but getrawtransaction is 1/0.
if (value === 1)
return true;

View File

@ -344,9 +344,8 @@ Account.prototype.spliceKey = function spliceKey(key) {
Account.prototype.addSharedKey = async function addSharedKey(key) {
const result = this.pushKey(key);
const exists = await this._hasDuplicate();
if (exists) {
if (await this.hasDuplicate()) {
this.spliceKey(key);
throw new Error('Cannot add a key from another account.');
}
@ -363,7 +362,7 @@ Account.prototype.addSharedKey = async function addSharedKey(key) {
* @returns {Promise}
*/
Account.prototype._hasDuplicate = function _hasDuplicate() {
Account.prototype.hasDuplicate = function hasDuplicate() {
if (this.keys.length !== this.n - 1)
return false;
@ -511,15 +510,13 @@ Account.prototype.derivePath = function derivePath(path, master) {
if (path.encrypted) {
data = master.decipher(data, path.hash);
if (!data)
return;
return null;
}
const ring = WalletKey.fromImport(this, data);
return ring;
return WalletKey.fromImport(this, data);
}
case Path.types.ADDRESS: {
return;
return null;
}
default: {
assert(false, 'Bad key type.');
@ -538,8 +535,8 @@ Account.prototype.deriveKey = function deriveKey(branch, index, master) {
assert(typeof branch === 'number');
const keys = [];
let key;
let key;
if (master && master.key && !this.watchOnly) {
key = master.key.deriveBIP44(this.accountIndex);
key = key.derive(branch).derive(index);
@ -555,9 +552,9 @@ Account.prototype.deriveKey = function deriveKey(branch, index, master) {
case Account.types.MULTISIG:
keys.push(key.publicKey);
for (let shared of this.keys) {
shared = shared.derive(branch).derive(index);
keys.push(shared.publicKey);
for (const shared of this.keys) {
const key = shared.derive(branch).derive(index);
keys.push(key.publicKey);
}
ring.script = Script.fromMultisig(this.m, this.n, keys);
@ -800,7 +797,7 @@ Account.prototype.getAddress = function getAddress(enc) {
Account.prototype.getReceive = function getReceive(enc) {
if (!this.receive)
return;
return null;
return this.receive.getAddress(enc);
};
@ -812,7 +809,8 @@ Account.prototype.getReceive = function getReceive(enc) {
Account.prototype.getChange = function getChange(enc) {
if (!this.change)
return;
return null;
return this.change.getAddress(enc);
};
@ -824,7 +822,8 @@ Account.prototype.getChange = function getChange(enc) {
Account.prototype.getNested = function getNested(enc) {
if (!this.nested)
return;
return null;
return this.nested.getAddress(enc);
};
@ -1004,8 +1003,8 @@ Account.isAccount = function isAccount(obj) {
* Helpers
*/
function cmp(key1, key2) {
return key1.compare(key2);
function cmp(a, b) {
return a.compare(b);
}
/*

View File

@ -82,21 +82,21 @@ common.sortCoins = function sortCoins(coins) {
common.sortDeps = function sortDeps(txs) {
const map = new Map();
const depMap = new Map();
const depCount = new Map();
const result = [];
const top = [];
for (const tx of txs) {
const hash = tx.hash('hex');
map.set(hash, tx);
}
for (const [hash, tx] of map) {
let hasDeps = false;
const depMap = new Map();
const depCount = new Map();
const top = [];
for (const [hash, tx] of map) {
depCount.set(hash, 0);
let hasDeps = false;
for (const input of tx.inputs) {
const prev = input.prevout.hash;
@ -119,6 +119,8 @@ common.sortDeps = function sortDeps(txs) {
top.push(tx);
}
const result = [];
for (const tx of top) {
const hash = tx.hash('hex');
const deps = depMap.get(hash);

View File

@ -134,8 +134,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
return;
}
let wallet = null;
let wallet;
try {
wallet = await this.walletdb.auth(id, token);
} catch (err) {
@ -315,8 +314,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const old = valid.str('old');
const new_ = valid.str('new');
enforce(old || new_, 'Passphrase is required.');
await req.wallet.setPassphrase(old, new_);
res.send(200, { success: true });
});
@ -325,8 +327,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const passphrase = valid.str('passphrase');
const timeout = valid.u32('timeout');
enforce(passphrase, 'Passphrase is required.');
await req.wallet.unlock(passphrase, timeout);
res.send(200, { success: true });
});
@ -392,11 +397,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
for (const output of outputs) {
const valid = new Validator([output]);
let script = null;
let script;
if (valid.has('script')) {
script = valid.buf('script');
script = Script.fromRaw(script);
const raw = valid.buf('script');
script = Script.fromRaw(raw);
}
options.outputs.push({
@ -431,11 +436,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
for (const output of outputs) {
const valid = new Validator([output]);
let script = null;
let script;
if (valid.has('script')) {
script = valid.buf('script');
script = Script.fromRaw(script);
const raw = valid.buf('script');
script = Script.fromRaw(raw);
}
options.outputs.push({
@ -448,6 +453,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const tx = await req.wallet.createTX(options);
await req.wallet.sign(tx, passphrase);
res.send(200, tx.getJSON(this.network));
});
@ -471,8 +477,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const acct = valid.str('account');
const age = valid.u32('age');
enforce(age, 'Age is required.');
await req.wallet.zap(acct, age);
res.send(200, { success: true });
});
@ -480,8 +489,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
this.del('/:id/tx/:hash', async (req, res) => {
const valid = req.valid();
const hash = valid.hash('hash');
enforce(hash, 'Hash is required.');
await req.wallet.abandon(hash);
res.send(200, { success: true });
});
@ -513,8 +525,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const acct = valid.str('account');
const key = valid.str('accountKey');
enforce(key, 'Key is required.');
await req.wallet.addSharedKey(acct, key);
res.send(200, { success: true });
});
@ -523,8 +538,11 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const acct = valid.str('account');
const key = valid.str('accountKey');
enforce(key, 'Key is required.');
await req.wallet.removeSharedKey(acct, key);
res.send(200, { success: true });
});
@ -568,6 +586,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const acct = valid.str('account');
const address = await req.wallet.createReceive(acct);
res.send(200, address.toJSON());
});
@ -576,6 +595,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const acct = valid.str('account');
const address = await req.wallet.createChange(acct);
res.send(200, address.toJSON());
});
@ -584,6 +604,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const valid = req.valid();
const acct = valid.str('account');
const address = await req.wallet.createNested(acct);
res.send(200, address.toJSON());
});
@ -787,48 +808,36 @@ HTTPServer.prototype.initSockets = function initSockets() {
this.walletdb.on('tx', (id, tx, details) => {
const json = details.toJSON();
const channel = 'w:' + id;
this.to(channel, 'wallet tx', json);
this.to('!all', 'wallet tx', id, json);
this.to(`w:${id}`, 'wallet tx', json);
});
this.walletdb.on('confirmed', (id, tx, details) => {
const json = details.toJSON();
const channel = 'w:' + id;
this.to(channel, 'wallet confirmed', json);
this.to('!all', 'wallet confirmed', id, json);
this.to(`w:${id}`, 'wallet confirmed', json);
});
this.walletdb.on('unconfirmed', (id, tx, details) => {
const json = details.toJSON();
const channel = 'w:' + id;
this.to(channel, 'wallet unconfirmed', json);
this.to('!all', 'wallet unconfirmed', id, json);
this.to(`w:${id}`, 'wallet unconfirmed', json);
});
this.walletdb.on('conflict', (id, tx, details) => {
const json = details.toJSON();
const channel = 'w:' + id;
this.to(channel, 'wallet conflict', json);
this.to('!all', 'wallet conflict', id, json);
this.to(`w:${id}`, 'wallet conflict', json);
});
this.walletdb.on('balance', (id, balance) => {
const json = balance.toJSON();
const channel = 'w:' + id;
this.to(channel, 'wallet balance', json);
this.to('!all', 'wallet balance', id, json);
this.to(`w:${id}`, 'wallet balance', json);
});
this.walletdb.on('address', (id, receive) => {
const channel = 'w:' + id;
const json = [];
for (const addr of receive)
json.push(addr.toJSON());
this.to(channel, 'wallet address', json);
this.to('!all', 'wallet address', id, json);
this.to(`w:${id}`, 'wallet address', json);
});
};
@ -840,16 +849,21 @@ HTTPServer.prototype.initSockets = function initSockets() {
HTTPServer.prototype.handleSocket = function handleSocket(socket) {
socket.hook('wallet auth', (args) => {
const valid = new Validator([args]);
const key = valid.str(0);
if (socket.auth)
throw new Error('Already authed.');
if (!this.options.noAuth) {
const hash = hash256(key);
const valid = new Validator([args]);
const key = valid.str(0);
if (key.length > 255)
throw new Error('Invalid API key.');
const data = Buffer.from(key, 'utf8');
const hash = digest.hash256(data);
if (!ccmp(hash, this.options.apiHash))
throw new Error('Bad key.');
throw new Error('Invalid API key.');
}
socket.auth = true;
@ -873,21 +887,19 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) {
const valid = new Validator([args]);
const id = valid.str(0, '');
const token = valid.buf(1);
const channel = 'w:' + id;
if (!id)
throw new Error('Invalid parameter.');
if (!this.options.walletAuth) {
socket.join(channel);
socket.join(`w:${id}`);
return null;
}
if (!token)
throw new Error('Invalid parameter.');
let wallet = null;
let wallet;
try {
wallet = await this.walletdb.auth(id, token);
} catch (e) {
@ -900,7 +912,7 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) {
this.logger.info('Successful wallet auth for %s.', id);
socket.join(channel);
socket.join(`w:${id}`);
return null;
});
@ -908,12 +920,11 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) {
socket.hook('wallet leave', (args) => {
const valid = new Validator([args]);
const id = valid.str(0, '');
const channel = 'w:' + id;
if (!id)
throw new Error('Invalid parameter.');
socket.leave(channel);
socket.leave(`w:${id}`);
return null;
});
@ -934,7 +945,7 @@ function HTTPOptions(options) {
this.logger = null;
this.walletdb = null;
this.apiKey = base58.encode(random.randomBytes(20));
this.apiHash = hash256(this.apiKey);
this.apiHash = digest.hash256(Buffer.from(this.apiKey, 'utf8'));
this.serviceHash = this.apiHash;
this.noAuth = false;
this.walletAuth = false;
@ -977,7 +988,7 @@ HTTPOptions.prototype.fromOptions = function fromOptions(options) {
assert(options.apiKey.length <= 200,
'API key must be under 200 bytes.');
this.apiKey = options.apiKey;
this.apiHash = hash256(this.apiKey);
this.apiHash = digest.hash256(Buffer.from(this.apiKey, 'utf8'));
}
if (options.noAuth != null) {
@ -1047,16 +1058,6 @@ HTTPOptions.fromOptions = function fromOptions(options) {
* Helpers
*/
function hash256(data) {
if (typeof data !== 'string')
return Buffer.alloc(0);
if (data.length > 200)
return Buffer.alloc(0);
return digest.hash256(Buffer.from(data, 'utf8'));
}
function enforce(value, msg) {
if (!value) {
const err = new Error(msg);

Some files were not shown because too many files have changed in this diff Show More