From 6f3988e861c11901ab48dec0819d444e1f9e0d30 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 27 Jul 2017 14:51:55 -0700 Subject: [PATCH] refactor: use const as much as possible. --- bench/bech32.js | 31 +-- bench/buffer.js | 39 ++-- bench/chacha.js | 72 +++---- bench/coins-old.js | 39 ---- bench/coins.js | 53 ++--- bench/merkle.js | 5 +- bench/mnemonic.js | 11 +- bench/script.js | 36 +--- bench/tx.js | 195 ++++++++++-------- bench/walletdb.js | 166 ++++++++-------- bin/cli | 38 ++-- examples/chain.js | 4 +- examples/client.js | 42 ++-- examples/miner.js | 8 +- examples/peer.js | 5 +- examples/wallet.js | 13 +- lib/bip70/paymentrequest.js | 41 ++-- lib/bip70/x509.js | 23 +-- lib/blockchain/chain.js | 130 ++++++------ lib/blockchain/chaindb.js | 155 ++++++--------- lib/blockchain/chainentry.js | 13 +- lib/btc/amount.js | 30 ++- lib/btc/uri.js | 22 +-- lib/coins/coinentry.js | 31 ++- lib/coins/coinview.js | 18 +- lib/coins/compress.js | 59 +++--- lib/crypto/aead.js | 7 +- lib/crypto/aes-browser.js | 75 +++---- lib/crypto/ccmp.js | 4 +- lib/crypto/chacha20.js | 6 +- lib/crypto/digest-browser.js | 7 +- lib/crypto/ecdsa.js | 15 +- lib/crypto/hkdf.js | 8 +- lib/crypto/merkle.js | 3 +- lib/crypto/pbkdf2-browser.js | 10 +- lib/crypto/poly1305.js | 27 ++- lib/crypto/rsa-browser.js | 47 ++--- lib/crypto/rsa.js | 17 +- lib/crypto/schnorr.js | 49 +++-- lib/crypto/scrypt.js | 16 +- lib/crypto/secp256k1-browser.js | 52 ++--- lib/crypto/siphash.js | 22 +-- lib/db/lowlevelup.js | 21 +- lib/db/memdb.js | 12 +- lib/hd/mnemonic.js | 43 ++-- lib/hd/private.js | 39 ++-- lib/hd/public.js | 33 ++-- lib/http/base.js | 48 ++--- lib/http/client.js | 6 +- lib/http/request.js | 4 +- lib/http/rpc.js | 340 ++++++++++++++------------------ lib/http/server.js | 66 +++---- lib/http/wallet.js | 4 +- lib/mempool/fees.js | 57 +++--- lib/mempool/mempool.js | 77 ++++---- lib/mining/cpuminer.js | 13 +- lib/mining/miner.js | 19 +- lib/mining/template.js | 43 ++-- lib/net/bip150.js | 52 ++--- lib/net/bip151.js | 30 ++- lib/net/bip152.js | 48 ++--- lib/net/external.js | 36 ++-- lib/net/framer.js | 5 +- lib/net/hostlist.js | 63 +++--- lib/net/packets.js | 4 +- lib/net/parser.js | 24 ++- lib/net/peer.js | 56 ++---- lib/net/pool.js | 195 +++++++++--------- lib/net/socks.js | 113 ++++++----- lib/net/upnp.js | 85 ++++---- lib/node/config.js | 60 +++--- lib/node/logger.js | 34 ++-- lib/node/node.js | 4 +- lib/primitives/address.js | 26 +-- lib/primitives/block.js | 51 ++--- lib/primitives/input.js | 17 +- lib/primitives/keyring.js | 63 +++--- lib/primitives/memblock.js | 4 +- lib/primitives/merkleblock.js | 33 ++-- lib/primitives/mtx.js | 100 ++++------ lib/primitives/netaddress.js | 4 +- lib/primitives/tx.js | 118 +++++------ lib/protocol/network.js | 4 +- lib/protocol/networks.js | 18 +- lib/script/common.js | 20 +- lib/script/opcode.js | 7 +- lib/script/script.js | 197 ++++++++---------- lib/script/scriptnum.js | 4 +- lib/script/sigcache.js | 6 +- lib/script/stack.js | 6 +- lib/script/witness.js | 8 +- lib/utils/asn1.js | 40 ++-- lib/utils/asyncemitter.js | 60 +++--- lib/utils/asyncobject.js | 6 +- lib/utils/base58.js | 42 ++-- lib/utils/bech32.js | 57 +++--- lib/utils/bloom.js | 10 +- lib/utils/co.js | 8 +- lib/utils/encoding.js | 34 ++-- lib/utils/fs.js | 7 +- lib/utils/gcs.js | 28 +-- lib/utils/heap.js | 23 +-- lib/utils/ip.js | 25 ++- lib/utils/lock.js | 16 +- lib/utils/lru.js | 20 +- lib/utils/mappedlock.js | 3 +- lib/utils/protoreader.js | 7 +- lib/utils/rbt.js | 7 +- lib/utils/reader.js | 116 +++++------ lib/utils/rollingfilter.js | 22 +-- lib/utils/staticwriter.js | 8 +- lib/utils/util.js | 47 ++--- lib/utils/validator.js | 18 +- lib/utils/writer.js | 4 +- lib/wallet/account.js | 66 +++---- lib/wallet/client.js | 15 +- lib/wallet/common.js | 3 +- lib/wallet/http.js | 83 ++++---- lib/wallet/masterkey.js | 27 +-- lib/wallet/plugin.js | 3 +- lib/wallet/rpc.js | 226 +++++++++------------ lib/wallet/server.js | 7 +- lib/wallet/txdb.js | 130 +++++------- lib/wallet/wallet.js | 201 ++++++++----------- lib/wallet/walletdb.js | 124 +++++------- lib/workers/framer.js | 3 +- lib/workers/packets.js | 9 +- lib/workers/workerpool.js | 9 +- migrate/chaindb0to1.js | 23 +-- migrate/chaindb1to2.js | 46 ++--- migrate/chaindb2to3.js | 59 +++--- migrate/coins-old.js | 69 +++---- migrate/coins/coins.js | 29 +-- migrate/coins/coinview.js | 11 +- migrate/coins/compress.js | 30 ++- migrate/compress-old.js | 24 +-- migrate/ensure-tip-index.js | 27 ++- migrate/walletdb2to3.js | 81 ++++---- migrate/walletdb3to4.js | 33 ++-- migrate/walletdb4to5.js | 17 +- migrate/walletdb5to6.js | 82 ++++---- scripts/dump.js | 7 +- scripts/gen.js | 19 +- test/aes-test.js | 28 +-- test/bech32-test.js | 4 +- test/bip150-test.js | 20 +- test/bip70-test.js | 87 ++++---- test/block-test.js | 106 +++++----- test/chachapoly-test.js | 21 +- test/chain-test.js | 200 ++++++++----------- test/coins-test.js | 34 ++-- test/gcs-test.js | 25 +-- test/hd-test.js | 3 +- test/http-test.js | 13 +- test/mempool-test.js | 89 ++++----- test/mnemonic-test.js | 12 +- test/node-test.js | 181 +++++++---------- test/protocol-test.js | 16 +- test/script-test.js | 50 ++--- test/scrypt-test.js | 2 + test/tx-test.js | 109 +++++----- test/utils-test.js | 51 ++--- test/wallet-test.js | 282 ++++++++++++-------------- 163 files changed, 3141 insertions(+), 4227 deletions(-) delete mode 100644 bench/coins-old.js diff --git a/bench/bech32.js b/bench/bech32.js index 9021d174..3b19c307 100644 --- a/bench/bech32.js +++ b/bench/bech32.js @@ -3,24 +3,25 @@ const Address = require('../lib/primitives/address'); const random = require('../lib/crypto/random'); const bench = require('./bench'); - -let i, end, addr; - const addrs = []; -end = bench('serialize'); -for (i = 0; i < 100000; i++) { - addr = Address.fromProgram(0, random.randomBytes(20)); - addrs.push(addr.toBech32()); +{ + const end = bench('serialize'); + for (let i = 0; i < 100000; i++) { + const addr = Address.fromProgram(0, random.randomBytes(20)); + addrs.push(addr.toBech32()); + } + end(100000); } -end(i); -end = bench('parse'); -for (i = 0; i < 100000; i++) { - addr = addrs[i]; - addr = Address.fromBech32(addr); - addrs[i] = addr; +{ + const end = bench('parse'); + for (let i = 0; i < 100000; i++) { + const b32 = addrs[i]; + const addr = Address.fromBech32(b32); + addrs[i] = addr; + } + end(100000); } -end(i); -console.error(addrs); +console.error(addrs[0][0]); diff --git a/bench/buffer.js b/bench/buffer.js index f2af99cc..818d86d0 100644 --- a/bench/buffer.js +++ b/bench/buffer.js @@ -6,26 +6,27 @@ const BufferWriter = require('../lib/utils/writer'); const StaticWriter = require('../lib/utils/staticwriter'); const bench = require('./bench'); -let wtx = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); -let i, tx, end; +const hex = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); +const raw = Buffer.from(hex.trim(), 'hex'); +const tx = TX.fromRaw(raw); -wtx = Buffer.from(wtx.trim(), 'hex'); -tx = TX.fromRaw(wtx); - -end = bench('serialize (static-writer)'); -for (i = 0; i < 10000; i++) { - tx._raw = null; - tx._size = -1; - tx._witness = -1; - tx.writeWitness(new StaticWriter(tx.getWitnessSizes().total)).render(); +{ + const end = bench('serialize (static-writer)'); + for (let i = 0; i < 10000; i++) { + tx.refresh(); + const {size} = tx.getWitnessSizes(); + const bw = new StaticWriter(size); + tx.toWitnessWriter(bw).render(); + } + end(10000); } -end(i); -end = bench('serialize (buffer-writer)'); -for (i = 0; i < 10000; i++) { - tx._raw = null; - tx._size = -1; - tx._witness = -1; - tx.writeWitness(new BufferWriter()).render(); +{ + const end = bench('serialize (buffer-writer)'); + for (let i = 0; i < 10000; i++) { + tx.refresh(); + const bw = new BufferWriter(); + tx.toWitnessWriter(bw).render(); + } + end(10000); } -end(i); diff --git a/bench/chacha.js b/bench/chacha.js index c8a58ff4..00249d33 100644 --- a/bench/chacha.js +++ b/bench/chacha.js @@ -4,47 +4,53 @@ const ChaCha20 = require('../lib/crypto/chacha20'); const Poly1305 = require('../lib/crypto/poly1305'); const digest = require('../lib/crypto/digest'); const bench = require('./bench'); -let i, chacha, iv, poly, key, data, end; console.log('note: rate measured in kb/s'); -chacha = new ChaCha20(); -key = Buffer.allocUnsafe(32); -key.fill(2); -iv = Buffer.from('0102030405060708', 'hex'); -chacha.init(key, iv, 0); -data = Buffer.allocUnsafe(32); -for (i = 0; i < 32; i++) - data[i] = i; -end = bench('encrypt'); -for (i = 0; i < 1000000; i++) - chacha.encrypt(data); -end(i * 32 / 1024); +const chacha = new ChaCha20(); +const poly = new Poly1305(); +const key = Buffer.alloc(32, 0x02); +const iv = Buffer.from('0102030405060708', 'hex'); +const chunk = Buffer.allocUnsafe(32); +const data = Buffer.allocUnsafe(32); -poly = new Poly1305(); -key = Buffer.allocUnsafe(32); -key.fill(2); -poly.init(key); +for (let i = 0; i < 32; i++) + chunk[i] = i; -data = Buffer.allocUnsafe(32); -for (i = 0; i < 32; i++) +for (let i = 0; i < 32; i++) data[i] = i & 0xff; -end = bench('update'); -for (i = 0; i < 1000000; i++) - poly.update(data); -end(i * 32 / 1024); +chacha.init(key, iv, 0); +poly.init(key); -end = bench('finish'); -for (i = 0; i < 1000000; i++) { - poly.init(key); - poly.update(data); - poly.finish(); +{ + const end = bench('encrypt'); + for (let i = 0; i < 1000000; i++) + chacha.encrypt(chunk); + end(1000000 * 32 / 1024); +} + +{ + const end = bench('update'); + for (let i = 0; i < 1000000; i++) + poly.update(data); + end(1000000 * 32 / 1024); +} + +{ + const end = bench('finish'); + for (let i = 0; i < 1000000; i++) { + poly.init(key); + poly.update(data); + poly.finish(); + } + end(1000000 * 32 / 1024); } -end(i * 32 / 1024); // For reference: -end = bench('sha256'); -for (i = 0; i < 1000000; i++) - digest.hash256(data); -end(i * 32 / 1024); +{ + const end = bench('sha256'); + for (let i = 0; i < 1000000; i++) + digest.hash256(data); + end(1000000 * 32 / 1024); +} diff --git a/bench/coins-old.js b/bench/coins-old.js deleted file mode 100644 index 4fcf5dfc..00000000 --- a/bench/coins-old.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const bench = require('./bench'); -const Coins = require('../migrate/coins-old'); -const TX = require('../lib/primitives/tx'); - -let wtx = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); -wtx = TX.fromRaw(wtx.trim(), 'hex'); - -let coins = Coins.fromTX(wtx); -let i, j, end, raw, hash; - -//raw = coins.toRaw(); -//console.log(Coins.fromRaw(raw)); - -end = bench('serialize'); -for (i = 0; i < 10000; i++) - raw = coins.toRaw(); -end(i); - -end = bench('parse'); -for (i = 0; i < 10000; i++) - Coins.fromRaw(raw); -end(i); - -end = bench('parse-single'); -hash = wtx.hash('hex'); -for (i = 0; i < 10000; i++) - Coins.parseCoin(raw, hash, 5); -end(i); - -coins = Coins.fromRaw(raw); -end = bench('get'); - -for (i = 0; i < 10000; i++) - for (j = 0; j < coins.outputs.length; j++) - coins.get(j); -end(i * coins.outputs.length); diff --git a/bench/coins.js b/bench/coins.js index 4201b9dd..074cfc1a 100644 --- a/bench/coins.js +++ b/bench/coins.js @@ -5,31 +5,32 @@ const Coins = require('../lib/coins/coins'); const TX = require('../lib/primitives/tx'); const bench = require('./bench'); -let raw = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); -const wtx = TX.fromRaw(raw.trim(), 'hex'); -let coins = Coins.fromTX(wtx, 1); -let i, j, end, hash; +const hex = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); +const wtx = TX.fromRaw(hex.trim(), 'hex'); +const coins = Coins.fromTX(wtx, 1); +const raw = coins.toRaw(); -end = bench('serialize'); -for (i = 0; i < 10000; i++) - raw = coins.toRaw(); -end(i); - -end = bench('parse'); -for (i = 0; i < 10000; i++) - Coins.fromRaw(raw); -end(i); - -end = bench('parse-single'); -hash = wtx.hash('hex'); -for (i = 0; i < 10000; i++) - Coins.parseCoin(raw, hash, 5); -end(i); - -coins = Coins.fromRaw(raw); -end = bench('get'); -for (i = 0; i < 10000; i++) { - for (j = 0; j < coins.outputs.length; j++) - coins.get(j); +{ + const end = bench('serialize'); + for (let i = 0; i < 10000; i++) { + coins.toRaw(); + } + end(10000); +} + +{ + const end = bench('parse'); + for (let i = 0; i < 10000; i++) { + Coins.fromRaw(raw); + } + end(10000); +} + +{ + const end = bench('get'); + for (let i = 0; i < 10000; i++) { + for (let j = 0; j < coins.outputs.length; j++) + coins.get(j); + } + end(10000 * coins.outputs.length); } -end(i * coins.outputs.length); diff --git a/bench/merkle.js b/bench/merkle.js index c171a68b..85f6d6a0 100644 --- a/bench/merkle.js +++ b/bench/merkle.js @@ -12,11 +12,10 @@ for (let i = 0; i < 3000; i++) { const end = bench('tree'); - let i; - for (i = 0; i < 1000; i++) { + for (let i = 0; i < 1000; i++) { const [n, m] = merkle.createTree(leaves.slice()); assert(n); assert(!m); } - end(i); + end(1000); } diff --git a/bench/mnemonic.js b/bench/mnemonic.js index afd73065..a2d217a6 100644 --- a/bench/mnemonic.js +++ b/bench/mnemonic.js @@ -9,11 +9,12 @@ const mnemonic = new Mnemonic(); HD.fromMnemonic(mnemonic); const phrase = mnemonic.getPhrase(); -let i, end; assert.equal(Mnemonic.fromPhrase(phrase).getPhrase(), phrase); -end = bench('fromPhrase'); -for (i = 0; i < 10000; i++) - Mnemonic.fromPhrase(phrase); -end(i); +{ + const end = bench('fromPhrase'); + for (let i = 0; i < 10000; i++) + Mnemonic.fromPhrase(phrase); + end(10000); +} diff --git a/bench/script.js b/bench/script.js index c867073a..e138b43c 100644 --- a/bench/script.js +++ b/bench/script.js @@ -1,37 +1,17 @@ 'use strict'; -const assert = require('assert'); const random = require('../lib/crypto/random'); const Script = require('../lib/script/script'); const bench = require('./bench'); -const opcodes = Script.opcodes; -let i, hashes, end; -Script.prototype.fromPubkeyhashOld = function fromScripthash(hash) { - assert(Buffer.isBuffer(hash) && hash.length === 20); - this.push(opcodes.OP_DUP); - this.push(opcodes.OP_HASH160); - this.push(hash); - this.push(opcodes.OP_EQUALVERIFY); - this.push(opcodes.OP_CHECKSIG); - this.compile(); - return this; -}; +const hashes = []; -Script.fromPubkeyhashOld = function fromScripthash(hash) { - return new Script().fromPubkeyhashOld(hash); -}; - -hashes = []; -for (i = 0; i < 100000; i++) +for (let i = 0; i < 100000; i++) hashes.push(random.randomBytes(20)); -end = bench('old'); -for (i = 0; i < hashes.length; i++) - Script.fromPubkeyhashOld(hashes[i]); -end(i); - -end = bench('hash'); -for (i = 0; i < hashes.length; i++) - Script.fromPubkeyhash(hashes[i]); -end(i); +{ + const end = bench('hash'); + for (let i = 0; i < hashes.length; i++) + Script.fromPubkeyhash(hashes[i]); + end(100000); +} diff --git a/bench/tx.js b/bench/tx.js index 8e5c70aa..07614609 100644 --- a/bench/tx.js +++ b/bench/tx.js @@ -17,106 +17,127 @@ const block = Block.fromJSON(json); const btx = { tx: block.txs[397], view: new CoinView() }; const tx3 = parseTX('../test/data/tx3.hex'); -let wtx = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); -let i, tx, end, flags, input; +const hex = fs.readFileSync(`${__dirname}/../test/data/wtx.hex`, 'utf8'); +const raw = Buffer.from(hex.trim(), 'hex'); -wtx = Buffer.from(wtx.trim(), 'hex'); - -tx = json.txs[397]; -for (i = 0; i < tx.inputs.length; i++) { - input = tx.inputs[i]; - btx.view.addCoin(Coin.fromJSON(input.coin)); +{ + const tx = json.txs[397]; + for (const input of tx.inputs) + btx.view.addCoin(Coin.fromJSON(input.coin)); } function parseTX(file) { const data = fs.readFileSync(`${__dirname}/${file}`, 'utf8'); const parts = data.trim().split(/\n+/); - let raw = parts[0]; + const raw = parts[0]; const tx = TX.fromRaw(raw.trim(), 'hex'); const view = new CoinView(); - let i, prev; - for (i = 1; i < parts.length; i++) { - raw = parts[i]; - prev = TX.fromRaw(raw.trim(), 'hex'); + for (let i = 1; i < parts.length; i++) { + const raw = parts[i]; + const prev = TX.fromRaw(raw.trim(), 'hex'); view.addTX(prev, -1); } return { tx: tx, view: view }; } -end = bench('parse'); -for (i = 0; i < 1000; i++) - tx = TX.fromRaw(wtx); -end(i); - -end = bench('serialize'); -for (i = 0; i < 1000; i++) { - tx._raw = null; - tx.toRaw(); +{ + const end = bench('parse'); + for (let i = 0; i < 1000; i++) + TX.fromRaw(raw); + end(1000); } -end(i); -end = bench('hash'); -for (i = 0; i < 3000; i++) { - tx3.tx.hash(); - tx3.tx._hash = null; +{ + const end = bench('serialize'); + for (let i = 0; i < 1000; i++) { + tx._raw = null; + tx.toRaw(); + } + end(1000); } -end(i); -end = bench('witness hash'); -for (i = 0; i < 3000; i++) { - tx.witnessHash(); - tx._whash = null; +{ + const end = bench('hash'); + for (let i = 0; i < 3000; i++) { + tx3.tx.hash(); + tx3.tx._hash = null; + } + end(3000); } -end(i); -end = bench('sanity'); -for (i = 0; i < 1000; i++) - tx.isSane(); -end(i); +{ + const end = bench('witness hash'); + for (let i = 0; i < 3000; i++) { + tx.witnessHash(); + tx._whash = null; + } + end(3000); +} -end = bench('input hashes'); -for (i = 0; i < 1000; i++) - tx.getInputHashes(null, 'hex'); -end(i); +{ + const end = bench('sanity'); + for (let i = 0; i < 1000; i++) + tx.isSane(); + end(1000); +} -end = bench('output hashes'); -for (i = 0; i < 1000; i++) - tx.getOutputHashes('hex'); -end(i); +{ + const end = bench('input hashes'); + for (let i = 0; i < 1000; i++) + tx.getInputHashes(null, 'hex'); + end(1000); +} -end = bench('all hashes'); -for (i = 0; i < 1000; i++) - tx.getHashes(null, 'hex'); -end(i); +{ + const end = bench('output hashes'); + for (let i = 0; i < 1000; i++) + tx.getOutputHashes('hex'); + end(1000); +} -end = bench('verify'); -for (i = 0; i < 3000; i++) - tx3.tx.verify(tx3.view, Script.flags.VERIFY_P2SH); -end(i * tx3.tx.inputs.length); +{ + const end = bench('all hashes'); + for (let i = 0; i < 1000; i++) + tx.getHashes(null, 'hex'); + end(1000); +} -end = bench('verify2'); -const script = tx3.view.getOutputFor(tx3.tx.inputs[0]).script; -for (i = 0; i < 100000; i++) - tx3.tx.signatureHashV0(0, script, Script.hashType.ALL); -end(i); +{ + const end = bench('verify'); + for (let i = 0; i < 3000; i++) + tx3.tx.verify(tx3.view, Script.flags.VERIFY_P2SH); + end(3000 * tx3.tx.inputs.length); +} -end = bench('fee'); -for (i = 0; i < 1000; i++) - tx3.tx.getFee(tx3.view); -end(i); +{ + const end = bench('verify2'); + const script = tx3.view.getOutputFor(tx3.tx.inputs[0]).script; + for (let i = 0; i < 100000; i++) + tx3.tx.signatureHashV0(0, script, Script.hashType.ALL); + end(100000); +} -flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_DERSIG; -end = bench('verify multisig'); -for (i = 0; i < 3000; i++) - btx.tx.verify(btx.view, flags); -end(i * btx.tx.inputs.length); +{ + const end = bench('fee'); + for (let i = 0; i < 1000; i++) + tx3.tx.getFee(tx3.view); + end(1000); +} -tx = new MTX(); +{ + const flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_DERSIG; + const end = bench('verify multisig'); + for (let i = 0; i < 3000; i++) + btx.tx.verify(btx.view, flags); + end(3000 * btx.tx.inputs.length); +} -for (i = 0; i < 100; i++) { - tx.addInput({ +const mtx = new MTX(); + +for (let i = 0; i < 100; i++) { + mtx.addInput({ prevout: { hash: encoding.NULL_HASH, index: 0 @@ -126,25 +147,31 @@ for (i = 0; i < 100; i++) { random.randomBytes(33) ] }); - tx.addOutput({ + mtx.addOutput({ address: Address.fromHash(random.randomBytes(20)), value: 0 }); } -tx = tx.toTX(); +const tx = mtx.toTX(); -end = bench('input hashes'); -for (i = 0; i < 1000; i++) - tx.getInputHashes(null, 'hex'); -end(i); +{ + const end = bench('input hashes'); + for (let i = 0; i < 1000; i++) + tx.getInputHashes(null, 'hex'); + end(1000); +} -end = bench('output hashes'); -for (i = 0; i < 1000; i++) - tx.getOutputHashes('hex'); -end(i); +{ + const end = bench('output hashes'); + for (let i = 0; i < 1000; i++) + tx.getOutputHashes('hex'); + end(1000); +} -end = bench('all hashes'); -for (i = 0; i < 1000; i++) - tx.getHashes(null, 'hex'); -end(i); +{ + const end = bench('all hashes'); + for (let i = 0; i < 1000; i++) + tx.getHashes(null, 'hex'); + end(1000); +} diff --git a/bench/walletdb.js b/bench/walletdb.js index 99f85826..9a134a62 100644 --- a/bench/walletdb.js +++ b/bench/walletdb.js @@ -5,115 +5,127 @@ const random = require('../lib/crypto/random'); const WalletDB = require('../lib/wallet/walletdb'); const MTX = require('../lib/primitives/mtx'); const Outpoint = require('../lib/primitives/outpoint'); -let walletdb; function dummy() { const hash = random.randomBytes(32).toString('hex'); return new Outpoint(hash, 0); } -walletdb = new WalletDB({ +const walletdb = new WalletDB({ name: 'wallet-test', db: 'memory', resolution: false, verify: false }); -async function runBench() { - let i, j, wallet, addrs, jobs, end; - let result, tx, mtx, options; - +(async () => { // Open and Create await walletdb.open(); - wallet = await walletdb.create(); - addrs = []; + + const wallet = await walletdb.create(); + const addrs = []; // Accounts - jobs = []; - for (i = 0; i < 1000; i++) - jobs.push(wallet.createAccount({})); + { + const jobs = []; + for (let i = 0; i < 1000; i++) + jobs.push(wallet.createAccount({})); - end = bench('accounts'); - result = await Promise.all(jobs); - end(1000); + const end = bench('accounts'); + const result = await Promise.all(jobs); + end(1000); - for (i = 0; i < result.length; i++) - addrs.push(result[i].receive.getAddress()); + for (const addr of result) + addrs.push(addr.receive.getAddress()); + } // Keys - jobs = []; - for (i = 0; i < 1000; i++) { - for (j = 0; j < 10; j++) - jobs.push(wallet.createReceive(i)); + { + const jobs = []; + for (let i = 0; i < 1000; i++) { + for (let j = 0; j < 10; j++) + jobs.push(wallet.createReceive(i)); + } + + const end = bench('keys'); + const result = await Promise.all(jobs); + end(1000 * 10); + + for (const addr of result) + addrs.push(addr.getAddress()); } - end = bench('keys'); - result = await Promise.all(jobs); - end(1000 * 10); - - for (i = 0; i < result.length; i++) - addrs.push(result[i].getAddress()); - // TX deposit - jobs = []; - for (i = 0; i < 10000; i++) { - mtx = new MTX(); - mtx.addOutpoint(dummy()); - mtx.addOutput(addrs[(i + 0) % addrs.length], 50460); - mtx.addOutput(addrs[(i + 1) % addrs.length], 50460); - mtx.addOutput(addrs[(i + 2) % addrs.length], 50460); - mtx.addOutput(addrs[(i + 3) % addrs.length], 50460); - tx = mtx.toTX(); + { + const jobs = []; + for (let i = 0; i < 10000; i++) { + const mtx = new MTX(); + mtx.addOutpoint(dummy()); + mtx.addOutput(addrs[(i + 0) % addrs.length], 50460); + 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(); - jobs.push(walletdb.addTX(tx)); + jobs.push(walletdb.addTX(tx)); + } + + const end = bench('deposit'); + await Promise.all(jobs); + end(10000); } - end = bench('deposit'); - result = await Promise.all(jobs); - end(10000); - // TX redemption - jobs = []; - for (i = 0; i < 10000; i++) { - mtx = new MTX(); - mtx.addTX(tx, 0); - mtx.addTX(tx, 1); - mtx.addTX(tx, 2); - mtx.addTX(tx, 3); - mtx.addOutput(addrs[(i + 0) % addrs.length], 50460); - mtx.addOutput(addrs[(i + 1) % addrs.length], 50460); - mtx.addOutput(addrs[(i + 2) % addrs.length], 50460); - mtx.addOutput(addrs[(i + 3) % addrs.length], 50460); - tx = mtx.toTX(); + { + const jobs = []; + for (let i = 0; i < 10000; i++) { + const mtx = new MTX(); + mtx.addTX(tx, 0); + mtx.addTX(tx, 1); + mtx.addTX(tx, 2); + mtx.addTX(tx, 3); + mtx.addOutput(addrs[(i + 0) % addrs.length], 50460); + 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(); - jobs.push(walletdb.addTX(tx)); + jobs.push(walletdb.addTX(tx)); + } + + const end = bench('redemption'); + await Promise.all(jobs); + end(10000); } - end = bench('redemption'); - result = await Promise.all(jobs); - end(10000); - // Balance - end = bench('balance'); - result = await wallet.getBalance(); - end(1); + { + const end = bench('balance'); + await wallet.getBalance(); + end(1); + } // Coins - end = bench('coins'); - result = await wallet.getCoins(); - end(1); + { + const end = bench('coins'); + await wallet.getCoins(); + end(1); + } // Create - end = bench('create'); - options = { - rate: 10000, - outputs: [{ - value: 50460, - address: addrs[0] - }] - }; - await wallet.createTX(options); - end(1); -} - -runBench().then(process.exit); + { + const end = bench('create'); + const options = { + rate: 10000, + outputs: [{ + value: 50460, + address: addrs[0] + }] + }; + await wallet.createTX(options); + end(1); + } +})().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/bin/cli b/bin/cli index 043f4e43..e5d0abaa 100755 --- a/bin/cli +++ b/bin/cli @@ -39,9 +39,7 @@ CLI.prototype.getWallets = async function getWallets() { }; CLI.prototype.createWallet = async function createWallet() { - let options, wallet; - - options = { + const options = { id: this.config.str([0, 'id']), type: this.config.str('type'), master: this.config.str('master'), @@ -59,7 +57,7 @@ CLI.prototype.createWallet = async function createWallet() { options.accountKey = this.config.str('watch'); } - wallet = await this.client.createWallet(options); + const wallet = await this.client.createWallet(options); this.log(wallet); }; @@ -110,9 +108,8 @@ CLI.prototype.getAccount = async function getAccount() { CLI.prototype.createAccount = async function createAccount() { const name = this.config.str([0, 'name']); - let options, account; - options = { + const options = { type: this.config.str('type'), m: this.config.num('m'), n: this.config.num('n'), @@ -120,7 +117,7 @@ CLI.prototype.createAccount = async function createAccount() { accountKey: this.config.str('watch') }; - account = await this.wallet.createAccount(name, options); + const account = await this.wallet.createAccount(name, options); this.log(account); }; @@ -155,15 +152,14 @@ CLI.prototype.getWallet = async function getWallet() { CLI.prototype.getTX = async function getTX() { const hash = this.config.str(0); - let txs, tx; if (util.isBase58(hash)) { - txs = await this.client.getTXByAddress(hash); + const txs = await this.client.getTXByAddress(hash); this.log(txs); return; } - tx = await this.client.getTX(hash); + const tx = await this.client.getTX(hash); if (!tx) { this.log('TX not found.'); @@ -175,12 +171,11 @@ CLI.prototype.getTX = async function getTX() { CLI.prototype.getBlock = async function getBlock() { let hash = this.config.str(0); - let block; if (hash.length !== 64) hash = +hash; - block = await this.client.getBlock(hash); + const block = await this.client.getBlock(hash); if (!block) { this.log('Block not found.'); @@ -193,15 +188,14 @@ CLI.prototype.getBlock = async function getBlock() { CLI.prototype.getCoin = async function getCoin() { const hash = this.config.str(0); const index = this.config.num(1); - let coins, coin; if (util.isBase58(hash)) { - coins = await this.client.getCoinsByAddress(hash); + const coins = await this.client.getCoinsByAddress(hash); this.log(coins); return; } - coin = await this.client.getCoin(hash, index); + const coin = await this.client.getCoin(hash, index); if (!coin) { this.log('Coin not found.'); @@ -277,7 +271,7 @@ CLI.prototype.getMempool = async function getMempool() { }; CLI.prototype.sendTX = async function sendTX() { - let output, options, tx; + let output; if (this.config.has('script')) { output = { @@ -291,7 +285,7 @@ CLI.prototype.sendTX = async function sendTX() { }; } - options = { + const options = { account: this.config.str('account'), passphrase: this.config.str('passphrase'), outputs: [output], @@ -300,13 +294,13 @@ CLI.prototype.sendTX = async function sendTX() { subtractFee: this.config.bool('subtract-fee') }; - tx = await this.wallet.send(options); + const tx = await this.wallet.send(options); this.log(tx); }; CLI.prototype.createTX = async function createTX() { - let output, options, tx; + let output; if (this.config.has('script')) { output = { @@ -320,7 +314,7 @@ CLI.prototype.createTX = async function createTX() { }; } - options = { + const options = { account: this.config.str('account'), passphrase: this.config.str('passphrase'), outputs: [output], @@ -328,7 +322,7 @@ CLI.prototype.createTX = async function createTX() { rate: this.config.amt('rate') }; - tx = await this.wallet.createTX(options); + const tx = await this.wallet.createTX(options); this.log(tx); }; @@ -461,7 +455,6 @@ CLI.prototype.unlock = async function unlock() { CLI.prototype.rpc = async function rpc() { const method = this.argv.shift(); const params = []; - let result; for (const arg of this.argv) { let param; @@ -473,6 +466,7 @@ CLI.prototype.rpc = async function rpc() { params.push(param); } + let result; try { result = await this.client.rpc.execute(method, params); } catch (e) { diff --git a/examples/chain.js b/examples/chain.js index 703b7dc2..37068d9c 100644 --- a/examples/chain.js +++ b/examples/chain.js @@ -7,11 +7,9 @@ const chain = new Chain({ }); (async () => { - let entry; - await chain.open(); - entry = await chain.getEntry(0); + const entry = await chain.getEntry(0); console.log(entry); })(); diff --git a/examples/client.js b/examples/client.js index 423fd6ff..816ce92e 100644 --- a/examples/client.js +++ b/examples/client.js @@ -7,9 +7,8 @@ const MTX = require('bcoin/lib/primitives/mtx'); const HTTP = require('bcoin/lib/http'); const FullNode = require('bcoin/lib/node/fullnode'); const plugin = require('bcoin/lib/wallet/plugin'); -let node, wallet; -node = new FullNode({ +const node = new FullNode({ network: 'regtest', apiKey: 'foo', walletAuth: true, @@ -18,22 +17,21 @@ node = new FullNode({ node.use(plugin); -wallet = new HTTP.Wallet({ +const wallet = new HTTP.Wallet({ network: 'regtest', apiKey: 'foo' }); async function fundWallet(wdb, addr) { - let tx; - // Coinbase - tx = new MTX(); - tx.addOutpoint(new Outpoint(encoding.NULL_HASH, 0)); - tx.addOutput(addr, 50460); - tx.addOutput(addr, 50460); - tx.addOutput(addr, 50460); - tx.addOutput(addr, 50460); - tx = tx.toTX(); + const mtx = new MTX(); + mtx.addOutpoint(new Outpoint(encoding.NULL_HASH, 0)); + mtx.addOutput(addr, 50460); + mtx.addOutput(addr, 50460); + mtx.addOutput(addr, 50460); + mtx.addOutput(addr, 50460); + + const tx = mtx.toTX(); wallet.once('balance', (balance) => { console.log('New Balance:'); @@ -55,9 +53,7 @@ async function fundWallet(wdb, addr) { } async function sendTX(addr, value) { - let options, tx; - - options = { + const options = { rate: 10000, outputs: [{ value: value, @@ -65,19 +61,18 @@ async function sendTX(addr, value) { }] }; - tx = await wallet.send(options); + const tx = await wallet.send(options); return tx.hash; } async function callNodeApi() { const info = await wallet.client.getInfo(); - let json; console.log('Server Info:'); console.log(info); - json = await wallet.client.rpc.execute('getblocktemplate', []); + const json = await wallet.client.rpc.execute('getblocktemplate', []); console.log('Block Template (RPC):'); console.log(json); @@ -85,11 +80,10 @@ async function callNodeApi() { (async () => { const wdb = node.require('walletdb'); - let w, acct, hash, balance, tx; await node.open(); - w = await wallet.create({ id: 'test' }); + const w = await wallet.create({ id: 'test' }); console.log('Wallet:'); console.log(w); @@ -97,23 +91,23 @@ async function callNodeApi() { // Fund default account. await fundWallet(wdb, w.account.receiveAddress); - balance = await wallet.getBalance(); + const balance = await wallet.getBalance(); console.log('Balance:'); console.log(balance); - acct = await wallet.createAccount('foo'); + const acct = await wallet.createAccount('foo'); console.log('Account:'); console.log(acct); // Send to our new account. - hash = await sendTX(acct.receiveAddress, 10000); + const hash = await sendTX(acct.receiveAddress, 10000); console.log('Sent TX:'); console.log(hash); - tx = await wallet.getTX(hash); + const tx = await wallet.getTX(hash); console.log('Sent TX details:'); console.log(tx); diff --git a/examples/miner.js b/examples/miner.js index e9ad7efe..2ef5ee7f 100644 --- a/examples/miner.js +++ b/examples/miner.js @@ -24,17 +24,15 @@ const miner = new Miner({ }); (async () => { - let tmpl, job, block; - await miner.open(); - tmpl = await miner.createBlock(); + const tmpl = await miner.createBlock(); console.log('Block template:'); console.log(tmpl); - job = await miner.cpu.createJob(); - block = await job.mineAsync(); + const job = await miner.cpu.createJob(); + const block = await job.mineAsync(); console.log('Mined block:'); console.log(block); diff --git a/examples/peer.js b/examples/peer.js index a9875799..e397ad73 100644 --- a/examples/peer.js +++ b/examples/peer.js @@ -6,9 +6,8 @@ const Peer = require('bcoin/lib/net/peer'); const NetAddress = require('bcoin/lib/primitives/netaddress'); const Network = require('bcoin/lib/protocol/network'); const network = Network.get('testnet'); -let peer, addr; -peer = Peer.fromOptions({ +const peer = Peer.fromOptions({ network: 'testnet', agent: 'my-subversion', hasWitness: () => { @@ -16,7 +15,7 @@ peer = Peer.fromOptions({ } }); -addr = NetAddress.fromHostname(process.argv[2], 'testnet'); +const addr = NetAddress.fromHostname(process.argv[2], 'testnet'); peer.connect(addr); peer.tryOpen(); diff --git a/examples/wallet.js b/examples/wallet.js index 2727969e..92bf8e3a 100644 --- a/examples/wallet.js +++ b/examples/wallet.js @@ -16,30 +16,29 @@ const walletdb = new WalletDB({ }); (async () => { - let wallet, acct, mtx, tx, wtx; - await walletdb.open(); - wallet = await walletdb.create(); + const wallet = await walletdb.create(); console.log('Created wallet'); console.log(wallet); - acct = await wallet.createAccount({ + const acct = await wallet.createAccount({ name: 'foo' }); console.log('Created account'); console.log(acct); - mtx = new MTX(); + const mtx = new MTX(); mtx.addOutpoint(dummy()); mtx.addOutput(acct.getReceive(), 50460); - tx = mtx.toTX(); + + const tx = mtx.toTX(); await walletdb.addTX(tx); - wtx = await wallet.getTX(tx.hash('hex')); + const wtx = await wallet.getTX(tx.hash('hex')); console.log('Added transaction'); console.log(wtx); diff --git a/lib/bip70/paymentrequest.js b/lib/bip70/paymentrequest.js index 52a1e305..6ecb810d 100644 --- a/lib/bip70/paymentrequest.js +++ b/lib/bip70/paymentrequest.js @@ -150,12 +150,10 @@ PaymentRequest.prototype.toRaw = function toRaw() { */ PaymentRequest.prototype.getAlgorithm = function getAlgorithm() { - let parts; - if (!this.pkiType) throw new Error('No PKI type available.'); - parts = this.pkiType.split('+'); + const parts = this.pkiType.split('+'); if (parts.length !== 2) throw new Error('Could not parse PKI algorithm.'); @@ -176,11 +174,10 @@ PaymentRequest.prototype.getAlgorithm = function getAlgorithm() { PaymentRequest.prototype.signatureData = function signatureData() { const signature = this.signature; - let data; this.signature = Buffer.alloc(0); - data = this.toRaw(); + const data = this.toRaw(); this.signature = signature; @@ -227,12 +224,11 @@ PaymentRequest.prototype.setChain = function setChain(chain) { PaymentRequest.prototype.getChain = function getChain() { const chain = []; - let br; if (!this.pkiData) return chain; - br = new ProtoReader(this.pkiData); + const br = new ProtoReader(this.pkiData); while (br.nextTag() === 1) chain.push(br.readFieldBytes(1)); @@ -243,21 +239,19 @@ PaymentRequest.prototype.getChain = function getChain() { /** * Sign payment request (chain must be set). * @param {Buffer} key - * @param {Buffer[]?} chain + * @param {Buffer[]?} certs */ -PaymentRequest.prototype.sign = function sign(key, chain) { - let alg, msg; - - if (chain) - this.setChain(chain); +PaymentRequest.prototype.sign = function sign(key, certs) { + if (certs) + this.setChain(certs); if (!this.pkiType) this.pkiType = 'x509+sha256'; - alg = this.getAlgorithm(); - msg = this.signatureData(); - chain = this.getChain(); + const alg = this.getAlgorithm(); + const msg = this.signatureData(); + const chain = this.getChain(); this.signature = x509.signSubject(alg.hash, msg, key, chain); }; @@ -268,23 +262,22 @@ PaymentRequest.prototype.sign = function sign(key, chain) { */ PaymentRequest.prototype.verify = function verify() { - let alg, msg, sig, chain; - if (!this.pkiType || this.pkiType === 'none') return false; if (!this.signature) return false; + let alg; try { alg = this.getAlgorithm(); } catch (e) { return false; } - msg = this.signatureData(); - sig = this.signature; - chain = this.getChain(); + const msg = this.signatureData(); + const sig = this.signature; + const chain = this.getChain(); try { return x509.verifySubject(alg.hash, msg, sig, chain); @@ -315,17 +308,15 @@ PaymentRequest.prototype.verifyChain = function verifyChain() { */ PaymentRequest.prototype.getCA = function getCA() { - let chain, root; - if (!this.pkiType || this.pkiType === 'none') throw new Error('No CA found (pkiType).'); - chain = this.getChain(); + const chain = this.getChain(); if (chain.length === 0) throw new Error('No CA found (chain).'); - root = x509.parse(chain[chain.length - 1]); + const root = x509.parse(chain[chain.length - 1]); return new CA(root); }; diff --git a/lib/bip70/x509.js b/lib/bip70/x509.js index baf5258b..bf9f66d2 100644 --- a/lib/bip70/x509.js +++ b/lib/bip70/x509.js @@ -139,8 +139,6 @@ x509.setTrust = function setTrust(certs) { assert(Array.isArray(certs), 'Certs must be an array.'); for (let cert of certs) { - let hash; - if (typeof cert === 'string') { const pem = PEM.decode(cert); assert(pem.type === 'certificate', 'Must add certificates to trust.'); @@ -151,10 +149,10 @@ x509.setTrust = function setTrust(certs) { cert = x509.parse(cert); - hash = digest.sha256(cert.raw); - hash = hash.toString('hex'); + const hash = digest.sha256(cert.raw); + const fingerprint = hash.toString('hex'); - x509.trusted.add(hash); + x509.trusted.add(fingerprint); } }; @@ -217,7 +215,7 @@ x509.getSigAlgorithm = function getSigAlgorithm(cert) { */ x509.getCurve = function getCurve(params) { - let oid, curve; + let oid; try { oid = ASN1.parseOID(params); @@ -225,7 +223,7 @@ x509.getCurve = function getCurve(params) { throw new Error('Could not parse curve OID.'); } - curve = x509.curves[oid]; + const curve = x509.curves[oid]; if (!curve) throw new Error(`Unknown ECDSA curve: ${oid}.`); @@ -257,7 +255,7 @@ x509.getPublicKey = function getPublicKey(cert) { const alg = x509.getKeyAlgorithm(cert); const key = cert.tbs.pubkey.pubkey; const params = cert.tbs.pubkey.alg.params; - let curve; + let curve = null; if (alg.key === 'ecdsa') { if (!params) @@ -297,7 +295,7 @@ x509.getSigningKey = function getSigningKey(key, chain) { assert(chain.length !== 0, 'No chain available.'); if (typeof key === 'string') { - let curve; + let curve = null; key = PEM.decode(key); @@ -350,15 +348,12 @@ x509.signSubject = function signSubject(hash, msg, key, chain) { */ x509.getVerifyKey = function getVerifyKey(chain) { - let cert, key; - if (chain.length === 0) throw new Error('No verify key available (cert chain).'); - cert = x509.parse(chain[0]); - key = x509.getPublicKey(cert); + const cert = x509.parse(chain[0]); - return key; + return x509.getPublicKey(cert); }; /** diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 149cebb1..0607b551 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -97,8 +97,6 @@ util.inherits(Chain, AsyncObject); */ Chain.prototype._open = async function open() { - let tip, state; - this.logger.info('Chain is loading.'); if (this.options.checkpoints) @@ -115,7 +113,7 @@ Chain.prototype._open = async function open() { await this.db.open(); - tip = await this.db.getTip(); + const tip = await this.db.getTip(); assert(tip); @@ -126,7 +124,7 @@ Chain.prototype._open = async function open() { this.logger.memory(); - state = await this.getDeploymentState(); + const state = await this.getDeploymentState(); this.setDeploymentState(state); @@ -158,16 +156,14 @@ Chain.prototype._close = function close() { */ Chain.prototype.verifyContext = async function verifyContext(block, prev, flags) { - let state, view; - // Initial non-contextual verification. - state = await this.verify(block, prev, flags); + const state = await this.verify(block, prev, flags); // BIP30 - Verify there are no duplicate txids. await this.verifyDuplicates(block, prev, state); // Verify scripts, spend and add coins. - view = await this.verifyInputs(block, prev, state); + const view = await this.verifyInputs(block, prev, state); return [view, state]; }; @@ -230,7 +226,6 @@ Chain.prototype.verify = async function verify(block, prev, flags) { const hash = block.hash('hex'); const now = this.network.now(); const height = prev.height + 1; - let time, mtp, commit, state, bits; assert(typeof flags === 'number'); @@ -275,7 +270,7 @@ Chain.prototype.verify = async function verify(block, prev, flags) { return this.state; // Ensure the POW is what we expect. - bits = await this.getTarget(block.time, prev); + const bits = await this.getTarget(block.time, prev); if (block.bits !== bits) { throw new VerifyError(block, @@ -285,7 +280,7 @@ Chain.prototype.verify = async function verify(block, prev, flags) { } // Ensure the timestamp is correct. - mtp = await prev.getMedianTime(); + const mtp = await prev.getMedianTime(); if (block.time <= mtp) { throw new VerifyError(block, @@ -321,7 +316,7 @@ Chain.prototype.verify = async function verify(block, prev, flags) { throw new VerifyError(block, 'obsolete', 'bad-version', 0); // Get the new deployment state. - state = await this.getDeployments(block.time, prev); + const state = await this.getDeployments(block.time, prev); // Enforce BIP91/BIP148. if (state.hasBIP91() || state.hasBIP148()) { @@ -330,7 +325,7 @@ Chain.prototype.verify = async function verify(block, prev, flags) { } // Get timestamp for tx.isFinal(). - time = state.hasMTP() ? mtp : block.time; + const time = state.hasMTP() ? mtp : block.time; // Transactions must be finalized with // regards to nSequence and nLockTime. @@ -355,6 +350,7 @@ Chain.prototype.verify = async function verify(block, prev, flags) { } // Check the commitment hash for segwit. + let commit = null; if (state.hasWitness()) { commit = block.getCommitmentHash(); if (commit) { @@ -418,7 +414,6 @@ Chain.prototype.getDeployments = async function getDeployments(time, prev) { const deployments = this.network.deployments; const height = prev.height + 1; const state = new DeploymentState(); - let witness; // For some reason bitcoind has p2sh in the // mandatory flags by default, when in reality @@ -452,7 +447,7 @@ Chain.prototype.getDeployments = async function getDeployments(time, prev) { } // Check the state of the segwit deployment. - witness = await this.getState(prev, deployments.segwit); + const witness = await this.getState(prev, deployments.segwit); // Segregrated witness (bip141) is now usable // along with SCRIPT_VERIFY_NULLDUMMY (bip147). @@ -586,17 +581,18 @@ Chain.prototype.verifyDuplicates = async function verifyDuplicates(block, prev, */ Chain.prototype.verifyInputs = async function verifyInputs(block, prev, state) { + 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 = []; + let sigops = 0; let reward = 0; - if (this.options.spv) - return view; - // Check all transactions for (let i = 0; i < block.txs.length; i++) { const tx = block.txs[i]; @@ -755,14 +751,12 @@ Chain.prototype.findFork = async function findFork(fork, longer) { Chain.prototype.reorganize = async function reorganize(competitor) { const tip = this.tip; const fork = await this.findFork(tip, competitor); - const disconnect = []; - const connect = []; - let entry; assert(fork, 'No free space or data corruption.'); // Blocks to disconnect. - entry = tip; + const disconnect = []; + let entry = tip; while (entry.hash !== fork.hash) { disconnect.push(entry); entry = await entry.getPrevious(); @@ -770,6 +764,7 @@ Chain.prototype.reorganize = async function reorganize(competitor) { } // Blocks to connect. + const connect = []; entry = competitor; while (entry.hash !== fork.hash) { connect.push(entry); @@ -814,12 +809,12 @@ Chain.prototype.reorganize = async function reorganize(competitor) { Chain.prototype.reorganizeSPV = async function reorganizeSPV(competitor) { const tip = this.tip; const fork = await this.findFork(tip, competitor); - const disconnect = []; - let entry = tip; assert(fork, 'No free space or data corruption.'); // Buffer disconnected blocks. + const disconnect = []; + let entry = tip; while (entry.hash !== fork.hash) { disconnect.push(entry); entry = await entry.getPrevious(); @@ -864,7 +859,6 @@ Chain.prototype.reorganizeSPV = async function reorganizeSPV(competitor) { Chain.prototype.disconnect = async function disconnect(entry) { let block = await this.db.getBlock(entry.hash); - let prev, view; if (!block) { if (!this.options.spv) @@ -872,8 +866,8 @@ Chain.prototype.disconnect = async function disconnect(entry) { block = entry.toHeaders(); } - prev = await entry.getPrevious(); - view = await this.db.disconnect(entry, block); + const prev = await entry.getPrevious(); + const view = await this.db.disconnect(entry, block); assert(prev); @@ -898,8 +892,8 @@ Chain.prototype.disconnect = async function disconnect(entry) { Chain.prototype.reconnect = async function reconnect(entry) { const flags = common.flags.VERIFY_NONE; + let block = await this.db.getBlock(entry.hash); - let prev, view, state; if (!block) { if (!this.options.spv) @@ -907,9 +901,10 @@ Chain.prototype.reconnect = async function reconnect(entry) { block = entry.toHeaders(); } - prev = await entry.getPrevious(); + const prev = await entry.getPrevious(); assert(prev); + let view, state; try { [view, state] = await this.verifyContext(block, prev, flags); } catch (err) { @@ -950,8 +945,6 @@ Chain.prototype.reconnect = async function reconnect(entry) { */ Chain.prototype.setBestChain = async function setBestChain(entry, block, prev, flags) { - let view, state; - // A higher fork has arrived. // Time to reorganize the chain. if (entry.prevBlock !== this.tip.hash) { @@ -976,6 +969,7 @@ Chain.prototype.setBestChain = async function setBestChain(entry, block, prev, f // Do "contextual" verification on our block // now that we're certain its previous // block is in the chain. + let view, state; try { [view, state] = await this.verifyContext(block, prev, flags); } catch (err) { @@ -1085,14 +1079,13 @@ Chain.prototype.reset = async function reset(block) { Chain.prototype._reset = async function reset(block, silent) { const tip = await this.db.reset(block); - let state; // Reset state. this.tip = tip; this.height = tip.height; this.synced = false; - state = await this.getDeploymentState(); + const state = await this.getDeploymentState(); this.setDeploymentState(state); @@ -1242,7 +1235,6 @@ Chain.prototype.add = async function add(block, flags, id) { Chain.prototype._add = async function add(block, flags, id) { const hash = block.hash('hex'); - let entry, prev; if (flags == null) flags = common.flags.DEFAULT_FLAGS; @@ -1288,7 +1280,7 @@ Chain.prototype._add = async function add(block, flags, id) { } // Find the previous block entry. - prev = await this.db.getEntry(block.prevBlock); + const prev = await this.db.getEntry(block.prevBlock); // If previous block wasn't ever seen, // add it current to orphans and return. @@ -1298,7 +1290,7 @@ Chain.prototype._add = async function add(block, flags, id) { } // Connect the block. - entry = await this.connect(prev, block, flags); + const entry = await this.connect(prev, block, flags); // Handle any orphans. if (this.hasNextOrphan(hash)) @@ -1319,7 +1311,6 @@ Chain.prototype._add = async function add(block, flags, id) { Chain.prototype.connect = async function connect(prev, block, flags) { const start = util.hrtime(); - let entry; // Sanity check. assert(block.prevBlock === prev.hash); @@ -1348,7 +1339,7 @@ Chain.prototype.connect = async function connect(prev, block, flags) { } // Create a new chain entry. - entry = ChainEntry.fromBlock(this, block, prev); + const entry = ChainEntry.fromBlock(this, block, prev); // The block is on a alternate chain if the // chainwork is less than or equal to @@ -1442,15 +1433,13 @@ Chain.prototype.isSlow = function isSlow() { */ Chain.prototype.logStatus = function logStatus(start, block, entry) { - let elapsed; - if (!this.isSlow()) return; // Report memory for debugging. this.logger.memory(); - elapsed = util.hrtime(start); + const elapsed = util.hrtime(start); this.logger.info( 'Block %s (%d) added to chain (size=%d txs=%d time=%d).', @@ -1475,13 +1464,11 @@ Chain.prototype.logStatus = function logStatus(start, block, entry) { */ Chain.prototype.verifyCheckpoint = function verifyCheckpoint(prev, hash) { - let height, checkpoint; - if (!this.checkpoints) return true; - height = prev.height + 1; - checkpoint = this.network.checkpointMap[height]; + const height = prev.height + 1; + const checkpoint = this.network.checkpointMap[height]; if (!checkpoint) return true; @@ -1639,7 +1626,7 @@ Chain.prototype.purgeOrphans = function purgeOrphans() { Chain.prototype.limitOrphans = function limitOrphans() { const now = util.now(); - let oldest; + let oldest = null; for (const orphan of this.orphanMap.values()) { if (now < orphan.time + 60 * 60) { @@ -1874,25 +1861,23 @@ Chain.prototype.getLocator = async function getLocator(start) { */ Chain.prototype._getLocator = async function getLocator(start) { - const hashes = []; - let step = 1; - let height, entry, main, hash; - if (start == null) start = this.tip.hash; assert(typeof start === 'string'); - entry = await this.db.getEntry(start); + let entry = await this.db.getEntry(start); + const hashes = []; if (!entry) { entry = this.tip; hashes.push(start); } - hash = entry.hash; - height = entry.height; - main = await entry.isMainChain(); + let hash = entry.hash; + let height = entry.height; + const main = await entry.isMainChain(); + let step = 1; hashes.push(hash); @@ -1929,7 +1914,7 @@ Chain.prototype._getLocator = async function getLocator(start) { */ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) { - let root; + let root = null; assert(hash); @@ -1997,7 +1982,6 @@ Chain.prototype.getCurrentTarget = async function getCurrentTarget() { Chain.prototype.getTarget = async function getTarget(time, prev) { const pow = this.network.pow; - let first, height; // Genesis if (!prev) { @@ -2030,10 +2014,10 @@ Chain.prototype.getTarget = async function getTarget(time, prev) { } // Back 2 weeks - height = prev.height - (pow.retargetInterval - 1); + const height = prev.height - (pow.retargetInterval - 1); assert(height >= 0); - first = await prev.getAncestor(height); + const first = await prev.getAncestor(height); assert(first); return this.retarget(prev, first); @@ -2050,13 +2034,13 @@ Chain.prototype.getTarget = async function getTarget(time, prev) { Chain.prototype.retarget = function retarget(prev, first) { const pow = this.network.pow; const targetTimespan = pow.targetTimespan; - let actualTimespan, target; if (pow.noRetargeting) return prev.bits; - actualTimespan = prev.time - first.time; - target = consensus.fromCompact(prev.bits); + const target = consensus.fromCompact(prev.bits); + + let actualTimespan = prev.time - first.time; if (actualTimespan < targetTimespan / 4 | 0) actualTimespan = targetTimespan / 4 | 0; @@ -2121,8 +2105,6 @@ Chain.prototype.getState = async function getState(prev, deployment) { let window = this.network.minerWindow; let threshold = this.network.activationThreshold; const bit = deployment.bit; - const compute = []; - let entry, state; if (deployment.threshold !== -1) threshold = deployment.threshold; @@ -2141,19 +2123,19 @@ Chain.prototype.getState = async function getState(prev, deployment) { assert(((prev.height + 1) % window) === 0); } - entry = prev; - state = thresholdStates.DEFINED; + let entry = prev; + let state = thresholdStates.DEFINED; + const compute = []; while (entry) { const cached = this.db.stateCache.get(bit, entry); - let time, height; if (cached !== -1) { state = cached; break; } - time = await entry.getMedianTime(); + const time = await entry.getMedianTime(); if (time < deployment.startTime) { state = thresholdStates.DEFINED; @@ -2163,7 +2145,7 @@ Chain.prototype.getState = async function getState(prev, deployment) { compute.push(entry); - height = entry.height - window; + const height = entry.height - window; entry = await entry.getAncestor(height); } @@ -2326,12 +2308,10 @@ Chain.prototype.getLocks = async function getLocks(prev, tx, view, flags) { return [minHeight, minTime]; for (const {prevout, sequence} of tx.inputs) { - let height, time, entry; - if (sequence & disableFlag) continue; - height = view.getHeight(prevout); + let height = view.getHeight(prevout); if (height === -1) height = this.height + 1; @@ -2343,10 +2323,11 @@ Chain.prototype.getLocks = async function getLocks(prev, tx, view, flags) { } height = Math.max(height - 1, 0); - entry = await prev.getAncestor(height); + + const entry = await prev.getAncestor(height); assert(entry, 'Database is corrupt.'); - time = await entry.getMedianTime(); + let time = await entry.getMedianTime(); time += ((sequence & mask) << granularity) - 1; minTime = Math.max(minTime, time); } @@ -2366,7 +2347,6 @@ Chain.prototype.getLocks = async function getLocks(prev, tx, view, flags) { Chain.prototype.verifyLocks = async function verifyLocks(prev, tx, view, flags) { const [height, time] = await this.getLocks(prev, tx, view, flags); - let mtp; // Also catches case where // height is `-1`. Fall through. @@ -2376,7 +2356,7 @@ Chain.prototype.verifyLocks = async function verifyLocks(prev, tx, view, flags) if (time === -1) return true; - mtp = await prev.getMedianTime(); + const mtp = await prev.getMedianTime(); if (time >= mtp) return false; diff --git a/lib/blockchain/chaindb.js b/lib/blockchain/chaindb.js index d62be973..f74b6100 100644 --- a/lib/blockchain/chaindb.js +++ b/lib/blockchain/chaindb.js @@ -79,14 +79,12 @@ ChainDB.layout = layout; */ ChainDB.prototype.open = async function open() { - let state; - this.logger.info('Opening ChainDB...'); await this.db.open(); await this.db.checkVersion('V', 3); - state = await this.getState(); + const state = await this.getState(); if (state) { // Verify options have not changed. @@ -275,8 +273,6 @@ ChainDB.prototype.getCache = function getCache(block) { */ ChainDB.prototype.getHeight = async function getHeight(hash) { - let entry, height; - if (typeof hash === 'number') return hash; @@ -285,12 +281,12 @@ ChainDB.prototype.getHeight = async function getHeight(hash) { if (hash === encoding.NULL_HASH) return -1; - entry = this.cacheHash.get(hash); + const entry = this.cacheHash.get(hash); if (entry) return entry.height; - height = await this.db.get(layout.h(hash)); + const height = await this.db.get(layout.h(hash)); if (!height) return -1; @@ -307,8 +303,6 @@ ChainDB.prototype.getHeight = async function getHeight(hash) { */ ChainDB.prototype.getHash = async function getHash(height) { - let entry, hash; - if (typeof height === 'string') return height; @@ -317,12 +311,12 @@ ChainDB.prototype.getHash = async function getHash(height) { if (height < 0) return; - entry = this.cacheHeight.get(height); + const entry = this.cacheHeight.get(height); if (entry) return entry.hash; - hash = await this.db.get(layout.H(height)); + const hash = await this.db.get(layout.H(height)); if (!hash) return; @@ -338,27 +332,26 @@ ChainDB.prototype.getHash = async function getHash(height) { */ ChainDB.prototype.getEntryByHeight = async function getEntryByHeight(height) { - let state, entry, hash; - assert(typeof height === 'number'); if (height < 0) return; - entry = this.cacheHeight.get(height); + const cache = this.cacheHeight.get(height); - if (entry) - return entry; + if (cache) + return cache; - hash = await this.db.get(layout.H(height)); + let hash = await this.db.get(layout.H(height)); if (!hash) return; hash = hash.toString('hex'); - state = this.chain.state; - entry = await this.getEntryByHash(hash); + const state = this.chain.state; + + const entry = await this.getEntryByHash(hash); if (!entry) return; @@ -380,24 +373,22 @@ ChainDB.prototype.getEntryByHeight = async function getEntryByHeight(height) { */ ChainDB.prototype.getEntryByHash = async function getEntryByHash(hash) { - let entry, raw; - assert(typeof hash === 'string'); if (hash === encoding.NULL_HASH) return; - entry = this.cacheHash.get(hash); + const cache = this.cacheHash.get(hash); - if (entry) - return entry; + if (cache) + return cache; - raw = await this.db.get(layout.e(hash)); + const raw = await this.db.get(layout.e(hash)); if (!raw) return; - entry = ChainEntry.fromRaw(this.chain, raw); + const entry = ChainEntry.fromRaw(this.chain, raw); // There's no efficient way to check whether // this is in the main chain or not, so @@ -626,13 +617,12 @@ ChainDB.prototype.writeDeployments = function writeDeployments(batch) { ChainDB.prototype.checkDeployments = async function checkDeployments() { const raw = await this.db.get(layout.V); - const invalid = []; - let br, count; assert(raw, 'No deployment table found.'); - br = new BufferReader(raw); - count = br.readU8(); + const br = new BufferReader(raw); + const count = br.readU8(); + const invalid = []; for (let i = 0; i < count; i++) { const bit = br.readU8(); @@ -663,7 +653,7 @@ ChainDB.prototype.checkDeployments = async function checkDeployments() { */ ChainDB.prototype.verifyDeployments = async function verifyDeployments() { - let invalid, batch; + let invalid; try { invalid = await this.checkDeployments(); @@ -678,7 +668,7 @@ ChainDB.prototype.verifyDeployments = async function verifyDeployments() { if (invalid.length === 0) return true; - batch = this.db.batch(); + const batch = this.db.batch(); for (const bit of invalid) { this.logger.warning('Versionbit deployment params modified.'); @@ -721,9 +711,8 @@ ChainDB.prototype.prune = async function prune(tip) { const options = this.options; const keepBlocks = this.network.block.keepBlocks; const pruneAfter = this.network.block.pruneAfterHeight; - let flags = await this.getFlags(); - const height = await this.getHeight(tip); - let start, end, batch; + + const flags = await this.getFlags(); if (flags.prune) throw new Error('Chain is already pruned.'); @@ -731,9 +720,10 @@ ChainDB.prototype.prune = async function prune(tip) { if (height <= pruneAfter + keepBlocks) return false; - start = pruneAfter + 1; - end = height - keepBlocks; - batch = this.db.batch(); + const height = await this.getHeight(tip); + const start = pruneAfter + 1; + const end = height - keepBlocks; + const batch = this.db.batch(); for (let i = start; i <= end; i++) { const hash = await this.getHash(i); @@ -748,7 +738,7 @@ ChainDB.prototype.prune = async function prune(tip) { try { options.prune = true; - flags = ChainFlags.fromOptions(options); + const flags = ChainFlags.fromOptions(options); assert(flags.prune); batch.put(layout.O, flags.toRaw()); @@ -788,8 +778,6 @@ ChainDB.prototype.getNextHash = async function getNextHash(hash) { */ ChainDB.prototype.isMainChain = async function isMainChain(hash) { - let entry; - assert(typeof hash === 'string'); if (hash === this.chain.tip.hash @@ -800,7 +788,7 @@ ChainDB.prototype.isMainChain = async function isMainChain(hash) { if (hash === encoding.NULL_HASH) return false; - entry = this.cacheHash.get(hash); + let entry = this.cacheHash.get(hash); if (entry) { entry = this.cacheHeight.get(entry.height); @@ -849,20 +837,19 @@ ChainDB.prototype.getTips = function getTips() { */ ChainDB.prototype.readCoin = async function readCoin(prevout) { - const {hash, index} = prevout; - const key = prevout.toKey(); - const state = this.state; - let raw; - if (this.options.spv) return; - raw = this.coinCache.get(key); + const {hash, index} = prevout; + const key = prevout.toKey(); + const state = this.state; - if (raw) - return CoinEntry.fromRaw(raw); + const cache = this.coinCache.get(key); - raw = await this.db.get(layout.c(hash, index)); + if (cache) + return CoinEntry.fromRaw(cache); + + const raw = await this.db.get(layout.c(hash, index)); if (!raw) return; @@ -943,12 +930,10 @@ ChainDB.prototype.getSpentView = async function getSpentView(tx) { const view = await this.getCoinView(tx); for (const [hash, coins] of view.map) { - let meta; - if (!coins.isEmpty()) continue; - meta = await this.getMeta(hash); + const meta = await this.getMeta(hash); if (!meta) continue; @@ -968,8 +953,10 @@ ChainDB.prototype.getSpentView = async function getSpentView(tx) { ChainDB.prototype.getUndoCoins = async function getUndoCoins(hash) { const data = await this.db.get(layout.u(hash)); + if (!data) return new UndoCoins(); + return UndoCoins.fromRaw(data); }; @@ -997,12 +984,10 @@ ChainDB.prototype.getBlock = async function getBlock(hash) { */ ChainDB.prototype.getRawBlock = async function getRawBlock(block) { - let hash; - if (this.options.spv) return; - hash = await this.getHash(block); + const hash = await this.getHash(block); if (!hash) return; @@ -1047,12 +1032,10 @@ ChainDB.prototype.getBlockView = async function getBlockView(block) { */ ChainDB.prototype.getMeta = async function getMeta(hash) { - let data; - if (!this.options.indexTX) return; - data = await this.db.get(layout.t(hash)); + const data = await this.db.get(layout.t(hash)); if (!data) return; @@ -1176,7 +1159,6 @@ ChainDB.prototype.getTXByAddress = async function getTXByAddress(addrs) { ChainDB.prototype.getMetaByAddress = async function getTXByAddress(addrs) { const txs = []; - let hashes; if (!this.options.indexTX || !this.options.indexAddress) return txs; @@ -1184,7 +1166,7 @@ ChainDB.prototype.getMetaByAddress = async function getTXByAddress(addrs) { if (!Array.isArray(addrs)) addrs = [addrs]; - hashes = await this.getHashesByAddress(addrs); + const hashes = await this.getHashesByAddress(addrs); for (const hash of hashes) { const tx = await this.getMeta(hash); @@ -1205,9 +1187,6 @@ ChainDB.prototype.getMetaByAddress = async function getTXByAddress(addrs) { */ ChainDB.prototype.scan = async function scan(start, filter, iter) { - let total = 0; - let entry; - if (start == null) start = this.network.genesis.hash; @@ -1216,7 +1195,7 @@ ChainDB.prototype.scan = async function scan(start, filter, iter) { else this.logger.info('Scanning from block %s.', util.revHex(start)); - entry = await this.getEntry(start); + let entry = await this.getEntry(start); if (!entry) return; @@ -1224,6 +1203,8 @@ ChainDB.prototype.scan = async function scan(start, filter, iter) { if (!(await entry.isMainChain())) throw new Error('Cannot rescan an alternate chain.'); + let total = 0; + while (entry) { const block = await this.getBlock(entry.hash); const txs = []; @@ -1419,10 +1400,9 @@ ChainDB.prototype._reconnect = async function reconnect(entry, block, view) { */ ChainDB.prototype.disconnect = async function disconnect(entry, block) { - let view; - this.start(); + let view; try { view = await this._disconnect(entry, block); } catch (e) { @@ -1445,8 +1425,6 @@ ChainDB.prototype.disconnect = async function disconnect(entry, block) { */ ChainDB.prototype._disconnect = async function disconnect(entry, block) { - let view; - // Remove hash->next-block index. this.del(layout.n(entry.prevBlock)); @@ -1458,7 +1436,7 @@ ChainDB.prototype._disconnect = async function disconnect(entry, block) { this.saveUpdates(); // Disconnect inputs. - view = await this.disconnectBlock(entry, block); + const view = await this.disconnectBlock(entry, block); // Revert chain state to previous tip. this.put(layout.R, this.pending.commit(entry.prevBlock)); @@ -1495,7 +1473,6 @@ ChainDB.prototype.saveUpdates = function saveUpdates() { ChainDB.prototype.reset = async function reset(block) { const entry = await this.getEntry(block); - let tip; if (!entry) throw new Error('Block not found.'); @@ -1512,7 +1489,7 @@ ChainDB.prototype.reset = async function reset(block) { // the chain. await this.removeChains(); - tip = await this.getTip(); + let tip = await this.getTip(); assert(tip); this.logger.debug('Resetting main chain to: %s', entry.rhash()); @@ -1660,12 +1637,10 @@ ChainDB.prototype.saveBlock = async function saveBlock(entry, block, view) { */ ChainDB.prototype.removeBlock = async function removeBlock(entry) { - let block; - if (this.options.spv) return; - block = await this.getBlock(entry.hash); + const block = await this.getBlock(entry.hash); if (!block) throw new Error('Block not found.'); @@ -1684,15 +1659,13 @@ ChainDB.prototype.removeBlock = async function removeBlock(entry) { ChainDB.prototype.saveView = function saveView(view) { for (const [hash, coins] of view.map) { for (const [index, coin] of coins.outputs) { - let raw; - if (coin.spent) { this.del(layout.c(hash, index)); this.coinCache.unpush(hash + index); continue; } - raw = coin.toRaw(); + const raw = coin.toRaw(); this.put(layout.c(hash, index), raw); this.coinCache.push(hash + index, raw); @@ -1710,11 +1683,11 @@ ChainDB.prototype.saveView = function saveView(view) { */ ChainDB.prototype.connectBlock = async function connectBlock(entry, block, view) { - const hash = block.hash(); - if (this.options.spv) return; + const hash = block.hash(); + this.pending.connect(block); // Genesis block's coinbase is unspendable. @@ -1761,14 +1734,12 @@ ChainDB.prototype.connectBlock = async function connectBlock(entry, block, view) */ ChainDB.prototype.disconnectBlock = async function disconnectBlock(entry, block) { - const view = new CoinView(); - const hash = block.hash(); - let undo; - if (this.options.spv) return view; - undo = await this.getUndoCoins(hash); + const view = new CoinView(); + const hash = block.hash(); + const undo = await this.getUndoCoins(hash); this.pending.disconnect(block); @@ -1822,20 +1793,18 @@ ChainDB.prototype.disconnectBlock = async function disconnectBlock(entry, block) */ ChainDB.prototype.pruneBlock = async function pruneBlock(entry) { - let height, hash; - if (this.options.spv) return; if (!this.options.prune) return; - height = entry.height - this.network.block.keepBlocks; + const height = entry.height - this.network.block.keepBlocks; if (height <= this.network.block.pruneAfterHeight) return; - hash = await this.getHash(height); + const hash = await this.getHash(height); if (!hash) return; @@ -2044,11 +2013,10 @@ ChainFlags.prototype.toRaw = function toRaw() { ChainFlags.prototype.fromRaw = function fromRaw(data) { const br = new BufferReader(data); - let flags; this.network = Network.fromMagic(br.readU32()); - flags = br.readU32(); + const flags = br.readU32(); this.spv = (flags & 1) !== 0; this.witness = (flags & 2) !== 0; @@ -2177,11 +2145,10 @@ StateCache.prototype.set = function set(bit, entry, state) { StateCache.prototype.get = function get(bit, entry) { const cache = this.bits[bit]; - let state; assert(cache); - state = cache.get(entry.hash); + const state = cache.get(entry.hash); if (state == null) return -1; diff --git a/lib/blockchain/chainentry.js b/lib/blockchain/chainentry.js index 401961b8..e64dca74 100644 --- a/lib/blockchain/chainentry.js +++ b/lib/blockchain/chainentry.js @@ -166,14 +166,12 @@ ChainEntry.prototype.isGenesis = function isGenesis() { */ ChainEntry.prototype.isMainChain = async function isMainChain() { - let entry; - if (this.hash === this.chain.tip.hash || this.hash === this.chain.network.genesis.hash) { return true; } - entry = this.chain.db.getCache(this.height); + const entry = this.chain.db.getCache(this.height); if (entry) { if (entry.hash === this.hash) @@ -195,8 +193,6 @@ ChainEntry.prototype.isMainChain = async function isMainChain() { */ ChainEntry.prototype.getAncestor = async function getAncestor(height) { - let entry = this; - if (height < 0) return; @@ -206,6 +202,7 @@ ChainEntry.prototype.getAncestor = async function getAncestor(height) { if (await this.isMainChain()) return await this.chain.db.getEntry(height); + let entry = this; while (entry.height !== height) { entry = await entry.getPrevious(); assert(entry); @@ -273,7 +270,6 @@ ChainEntry.prototype.getNextEntry = async function getNextEntry() { ChainEntry.prototype.getMedianTime = async function getMedianTime(time) { let timespan = ChainEntry.MEDIAN_TIMESPAN; - let entry = this; const median = []; // In case we ever want to check @@ -284,12 +280,11 @@ ChainEntry.prototype.getMedianTime = async function getMedianTime(time) { timespan -= 1; } + let entry = this; for (let i = 0; i < timespan && entry; i++) { - let cache; - median.push(entry.time); - cache = entry.getPrevCache(); + const cache = entry.getPrevCache(); if (cache) { entry = cache; diff --git a/lib/btc/amount.js b/lib/btc/amount.js index e3a5879c..49fa3e5b 100644 --- a/lib/btc/amount.js +++ b/lib/btc/amount.js @@ -335,11 +335,10 @@ Amount.btc = function btc(value, num) { */ Amount.serialize = function serialize(value, exp, num) { - let negative = false; - let hi, lo, result; - assert(util.isInt(value), 'Non-satoshi value for conversion.'); + let negative = false; + if (value < 0) { value = -value; negative = true; @@ -352,15 +351,15 @@ Amount.serialize = function serialize(value, exp, num) { while (value.length < exp + 1) value = '0' + value; - hi = value.slice(0, -exp); - lo = value.slice(-exp); + const hi = value.slice(0, -exp); + let lo = value.slice(-exp); lo = lo.replace(/0+$/, ''); if (lo.length === 0) lo += '0'; - result = `${hi}.${lo}`; + let result = `${hi}.${lo}`; if (negative) result = '-' + result; @@ -425,12 +424,6 @@ Amount.value = function _value(value, num) { */ Amount.parse = function parse(value, exp, num) { - let negative = false; - const mult = pow10(exp); - const maxLo = modSafe(mult); - const maxHi = divSafe(mult); - let parts, hi, lo, result; - if (num && typeof value === 'number') { assert(util.isNumber(value), 'Non-BTC value for conversion.'); value = value.toString(10); @@ -438,17 +431,22 @@ Amount.parse = function parse(value, exp, num) { assert(util.isFloat(value), 'Non-BTC value for conversion.'); + const mult = pow10(exp); + const maxLo = modSafe(mult); + const maxHi = divSafe(mult); + let negative = false; + if (value[0] === '-') { negative = true; value = value.substring(1); } - parts = value.split('.'); + const parts = value.split('.'); assert(parts.length <= 2, 'Bad decimal point.'); - hi = parts[0] || '0'; - lo = parts[1] || '0'; + let hi = parts[0] || '0'; + let lo = parts[1] || '0'; hi = hi.replace(/^0+/, ''); lo = lo.replace(/0+$/, ''); @@ -468,7 +466,7 @@ Amount.parse = function parse(value, exp, num) { assert(hi < maxHi || (hi === maxHi && lo <= maxLo), 'Number exceeds 2^53-1.'); - result = hi * mult + lo; + let result = hi * mult + lo; if (negative) result = -result; diff --git a/lib/btc/uri.js b/lib/btc/uri.js index 9f8c08d3..aff5695a 100644 --- a/lib/btc/uri.js +++ b/lib/btc/uri.js @@ -93,32 +93,31 @@ URI.fromOptions = function fromOptions(options) { */ URI.prototype.fromString = function fromString(str, network) { - let prefix, index, query, address; - assert(typeof str === 'string'); assert(str.length > 8, 'Not a bitcoin URI.'); - prefix = str.substring(0, 8); + const prefix = str.substring(0, 8); assert(prefix === 'bitcoin:', 'Not a bitcoin URI.'); str = str.substring(8); - index = str.indexOf('?'); + const index = str.indexOf('?'); + let addr, qs; if (index === -1) { - address = str; + addr = str; } else { - address = str.substring(0, index); - query = str.substring(index + 1); + addr = str.substring(0, index); + qs = str.substring(index + 1); } - this.address.fromString(address, network); + this.address.fromString(addr, network); - if (!query) + if (!qs) return this; - query = parsePairs(query); + const query = parsePairs(qs); if (query.amount) { assert(query.amount.length > 0, 'Value is empty.'); @@ -156,10 +155,11 @@ URI.fromString = function fromString(str, network) { URI.prototype.toString = function toString() { let str = 'bitcoin:'; - const query = []; str += this.address.toString(); + const query = []; + if (this.amount !== -1) query.push(`amount=${Amount.btc(this.amount)}`); diff --git a/lib/coins/coinentry.js b/lib/coins/coinentry.js index 52f31c16..05ca7d0f 100644 --- a/lib/coins/coinentry.js +++ b/lib/coins/coinentry.js @@ -148,12 +148,10 @@ CoinEntry.fromTX = function fromTX(tx, index, height) { */ CoinEntry.prototype.getSize = function getSize() { - let size; - if (this.raw) return this.raw.length; - size = 0; + let size = 0; size += encoding.sizeVarint(this.version); size += 4; size += compress.size(this.output); @@ -167,15 +165,14 @@ CoinEntry.prototype.getSize = function getSize() { */ CoinEntry.prototype.toWriter = function toWriter(bw) { - let flags = 0; - let height = this.height; - let field; - if (this.raw) { bw.writeBytes(this.raw); return bw; } + let height = this.height; + let flags = 0; + // We save 29 bits for the height. // This should be good for the next 4000 years. if (height === -1) @@ -184,7 +181,7 @@ CoinEntry.prototype.toWriter = function toWriter(bw) { if (this.coinbase) flags |= 1; - field = (height * 8) | flags; + const field = (height * 8) | flags; bw.writeVarint(this.version); bw.writeU32(field); @@ -199,13 +196,11 @@ CoinEntry.prototype.toWriter = function toWriter(bw) { */ CoinEntry.prototype.toRaw = function toRaw() { - let size, bw; - if (this.raw) return this.raw; - size = this.getSize(); - bw = new StaticWriter(size); + const size = this.getSize(); + const bw = new StaticWriter(size); this.toWriter(bw); @@ -221,18 +216,16 @@ CoinEntry.prototype.toRaw = function toRaw() { */ CoinEntry.prototype.fromReader = function fromReader(br) { - let field, flags, height; + const version = br.readVarint(); + const field = br.readU32(); - this.version = br.readVarint(); - - field = br.readU32(); - - height = field / 8 | 0; - flags = field & 0x07; + const flags = field & 0x07; + let height = field / 8 | 0; if (height === 0x1fffffff) height = -1; + this.version = version; this.coinbase = (flags & 1) !== 0; this.height = height; diff --git a/lib/coins/coinview.js b/lib/coins/coinview.js index 3674b8e6..ee929c54 100644 --- a/lib/coins/coinview.js +++ b/lib/coins/coinview.js @@ -189,12 +189,11 @@ CoinView.prototype.addOutput = function addOutput(prevout, output) { CoinView.prototype.spendEntry = function spendEntry(prevout) { const {hash, index} = prevout; const coins = this.get(hash); - let coin; if (!coins) return null; - coin = coins.spend(index); + const coin = coins.spend(index); if (!coin) return null; @@ -408,12 +407,12 @@ CoinView.prototype.isCoinbaseFor = function isCoinbaseFor(input) { */ CoinView.prototype.readCoin = async function readCoin(db, prevout) { - let coin = this.getEntry(prevout); + const cache = this.getEntry(prevout); - if (coin) - return coin; + if (cache) + return cache; - coin = await db.readCoin(prevout); + const coin = await db.readCoin(prevout); if (!coin) return null; @@ -451,12 +450,11 @@ CoinView.prototype.readInputs = async function readInputs(db, tx) { CoinView.prototype.spendInputs = async function spendInputs(db, tx) { if (tx.inputs.length < 4) { const jobs = []; - let coins; for (const {prevout} of tx.inputs) jobs.push(this.readCoin(db, prevout)); - coins = await Promise.all(jobs); + const coins = await Promise.all(jobs); for (const coin of coins) { if (!coin || coin.spent) @@ -537,12 +535,10 @@ CoinView.prototype.toWriter = function toWriter(bw, tx) { CoinView.prototype.fromReader = function fromReader(br, tx) { for (const {prevout} of tx.inputs) { - let coin; - if (br.readU8() === 0) continue; - coin = CoinEntry.fromReader(br); + const coin = CoinEntry.fromReader(br); this.addEntry(prevout, coin); } diff --git a/lib/coins/compress.js b/lib/coins/compress.js index 2cc50bff..74ed2029 100644 --- a/lib/coins/compress.js +++ b/lib/coins/compress.js @@ -58,9 +58,9 @@ function compressScript(script, bw) { // Only works if the key is valid. // Saves up to 35 bytes. if (script.isPubkey(true)) { - let key = script.code[0].data; - if (publicKeyVerify(key)) { - key = compressKey(key); + const data = script.code[0].data; + if (publicKeyVerify(data)) { + const key = compressKey(data); bw.writeBytes(key); return bw; } @@ -80,42 +80,44 @@ function compressScript(script, bw) { */ function decompressScript(script, br) { - let size, data; - // Decompress the script. switch (br.readU8()) { - case 0: - data = br.readBytes(20, true); - script.fromPubkeyhash(data); + case 0: { + const hash = br.readBytes(20, true); + script.fromPubkeyhash(hash); break; - case 1: - data = br.readBytes(20, true); - script.fromScripthash(data); + } + case 1: { + const hash = br.readBytes(20, true); + script.fromScripthash(hash); break; + } case 2: case 3: case 4: - case 5: + case 5: { br.offset -= 1; - data = br.readBytes(33, true); + const data = br.readBytes(33, true); // Decompress the key. If this fails, // we have database corruption! - data = decompressKey(data); - script.fromPubkey(data); + const key = decompressKey(data); + script.fromPubkey(key); break; - default: + } + default: { br.offset -= 1; - size = br.readVarint() - COMPRESS_TYPES; + const size = br.readVarint() - COMPRESS_TYPES; if (size > consensus.MAX_SCRIPT_SIZE) { // This violates consensus rules. // We don't need to read it. script.fromNulldata(EMPTY_BUFFER); br.seek(size); } else { - data = br.readBytes(size); + const data = br.readBytes(size); script.fromRaw(data); } break; + } } return script; @@ -127,8 +129,6 @@ function decompressScript(script, br) { */ function sizeScript(script) { - let size; - if (script.isPubkeyhash(true)) return 21; @@ -141,7 +141,7 @@ function sizeScript(script) { return 33; } - size = 0; + let size = 0; size += encoding.sizeVarint(script.raw.length + COMPRESS_TYPES); size += script.raw.length; @@ -193,19 +193,17 @@ function sizeOutput(output) { */ function compressValue(value) { - let exp, last; - if (value === 0) return 0; - exp = 0; + let exp = 0; while (value % 10 === 0 && exp < 9) { value /= 10; exp++; } if (exp < 9) { - last = value % 10; + const last = value % 10; value = (value - last) / 10; return 1 + 10 * (9 * value + last - 1) + exp; } @@ -220,18 +218,18 @@ function compressValue(value) { */ function decompressValue(value) { - let exp, n, last; - if (value === 0) return 0; value--; - exp = value % 10; + let exp = value % 10; + value = (value - exp) / 10; + let n; if (exp < 9) { - last = value % 9; + const last = value % 9; value = (value - last) / 9; n = value * 10 + last + 1; } else { @@ -309,7 +307,6 @@ function compressKey(key) { function decompressKey(key) { const format = key[0]; - let out; assert(key.length === 33); @@ -328,7 +325,7 @@ function decompressKey(key) { } // Decompress the key. - out = secp256k1.publicKeyConvert(key, false); + const out = secp256k1.publicKeyConvert(key, false); // Reset the first byte so as not to // mutate the original buffer. diff --git a/lib/crypto/aead.js b/lib/crypto/aead.js index 494bb8be..4295252d 100644 --- a/lib/crypto/aead.js +++ b/lib/crypto/aead.js @@ -123,7 +123,8 @@ AEAD.prototype.auth = function auth(data) { AEAD.prototype.finish = function finish() { const len = Buffer.allocUnsafe(16); - let lo, hi; + let lo = 0; + let hi = 0; // The RFC says these are supposed to be // uint32le, but their own fucking test @@ -154,14 +155,12 @@ AEAD.prototype.finish = function finish() { */ AEAD.prototype.pad16 = function pad16(size) { - let pad; - size %= 16; if (size === 0) return; - pad = Buffer.allocUnsafe(16 - size); + const pad = Buffer.allocUnsafe(16 - size); pad.fill(0); this.poly1305.update(pad); diff --git a/lib/crypto/aes-browser.js b/lib/crypto/aes-browser.js index 1d34ebaf..34060170 100644 --- a/lib/crypto/aes-browser.js +++ b/lib/crypto/aes-browser.js @@ -86,16 +86,14 @@ AESKey.prototype.destroy = function destroy() { */ AESKey.prototype.getEncryptKey = function getEncryptKey() { - let i = 0; - let key, kp; - assert(this.userKey, 'Cannot use key once it is destroyed.'); if (this.encryptKey) return this.encryptKey; - key = new Uint32Array(60); - kp = 0; + const key = new Uint32Array(60); + let kp = 0; + let i = 0; key[kp + 0] = readU32(this.userKey, 0); key[kp + 1] = readU32(this.userKey, 4); @@ -195,17 +193,15 @@ AESKey.prototype.getEncryptKey = function getEncryptKey() { */ AESKey.prototype.getDecryptKey = function getDecryptKey() { - let kp, enc, key; - assert(this.userKey, 'Cannot use key once it is destroyed.'); if (this.decryptKey) return this.decryptKey; // First, start with an encryption schedule. - enc = this.getEncryptKey(); - key = new Uint32Array(60); - kp = 0; + const enc = this.getEncryptKey(); + const key = new Uint32Array(60); + let kp = 0; for (let i = 0; i < enc.length; i++) key[i] = enc[i]; @@ -264,22 +260,21 @@ AESKey.prototype.getDecryptKey = function getDecryptKey() { */ AESKey.prototype.encryptBlock = function encryptBlock(input) { - let output, kp, key, r, s0, s1, s2, s3, t0, t1, t2, t3; - assert(this.userKey, 'Cannot use key once it is destroyed.'); - key = this.getEncryptKey(); - kp = 0; + const key = this.getEncryptKey(); + let kp = 0; // Map byte array block to cipher // state and add initial round key. - s0 = readU32(input, 0) ^ key[0]; - s1 = readU32(input, 4) ^ key[1]; - s2 = readU32(input, 8) ^ key[2]; - s3 = readU32(input, 12) ^ key[3]; + let s0 = readU32(input, 0) ^ key[0]; + let s1 = readU32(input, 4) ^ key[1]; + let s2 = readU32(input, 8) ^ key[2]; + let s3 = readU32(input, 12) ^ key[3]; // Nr - 1 full rounds - r = this.rounds >>> 1; + let r = this.rounds >>> 1; + let t0, t1, t2, t3; for (;;) { t0 = TE0[(s0 >>> 24) & 0xff] @@ -353,7 +348,7 @@ AESKey.prototype.encryptBlock = function encryptBlock(input) { ^ (TE1[(t2 >>> 0) & 0xff] & 0x000000ff) ^ key[kp + 3]; - output = Buffer.allocUnsafe(16); + const output = Buffer.allocUnsafe(16); writeU32(output, s0, 0); writeU32(output, s1, 4); writeU32(output, s2, 8); @@ -369,22 +364,21 @@ AESKey.prototype.encryptBlock = function encryptBlock(input) { */ AESKey.prototype.decryptBlock = function decryptBlock(input) { - let output, kp, key, r, s0, s1, s2, s3, t0, t1, t2, t3; - assert(this.userKey, 'Cannot use AESKey once it is destroyed.'); - key = this.getDecryptKey(); - kp = 0; + const key = this.getDecryptKey(); + let kp = 0; // Map byte array block to cipher // state and add initial round key. - s0 = readU32(input, 0) ^ key[kp + 0]; - s1 = readU32(input, 4) ^ key[kp + 1]; - s2 = readU32(input, 8) ^ key[kp + 2]; - s3 = readU32(input, 12) ^ key[kp + 3]; + let s0 = readU32(input, 0) ^ key[kp + 0]; + let s1 = readU32(input, 4) ^ key[kp + 1]; + let s2 = readU32(input, 8) ^ key[kp + 2]; + let s3 = readU32(input, 12) ^ key[kp + 3]; // Nr - 1 full rounds - r = this.rounds >>> 1; + let r = this.rounds >>> 1; + let t0, t1, t2, t3; for (;;) { t0 = TD0[(s0 >>> 24) & 0xff] @@ -458,7 +452,7 @@ AESKey.prototype.decryptBlock = function decryptBlock(input) { ^ (TD4[(t0 >>> 0) & 0xff] << 0) ^ key[kp + 3]; - output = Buffer.allocUnsafe(16); + const output = Buffer.allocUnsafe(16); writeU32(output, s0, 0); writeU32(output, s1, 4); writeU32(output, s2, 8); @@ -497,15 +491,14 @@ function AESCipher(key, iv, bits, mode) { AESCipher.prototype.update = function update(data) { const blocks = []; - let trailing, len; if (this.waiting) { data = concat(this.waiting, data); this.waiting = null; } - trailing = data.length % 16; - len = data.length - trailing; + const trailing = data.length % 16; + const len = data.length - trailing; // Encrypt all blocks except for the last. for (let i = 0; i < len; i += 16) { @@ -583,24 +576,22 @@ function AESDecipher(key, iv, bits, mode) { AESDecipher.prototype.update = function update(data) { const blocks = []; - let trailing, len; if (this.waiting) { data = concat(this.waiting, data); this.waiting = null; } - trailing = data.length % 16; - len = data.length - trailing; + const trailing = data.length % 16; + const len = data.length - trailing; // Decrypt all blocks. for (let i = 0; i < len; i += 16) { const chunk = this.prev; - let block; this.prev = data.slice(i, i + 16); - block = this.key.decryptBlock(this.prev); + let block = this.key.decryptBlock(this.prev); if (this.mode === 'cbc') block = xor(block, chunk); @@ -629,17 +620,15 @@ AESDecipher.prototype.update = function update(data) { */ AESDecipher.prototype.final = function final() { - let b, n, block; - this.key.destroy(); assert(!this.waiting, 'Bad decrypt (trailing bytes).'); assert(this.lastBlock, 'Bad decrypt (no data).'); // Check padding on the last block. - block = this.lastBlock; - b = 16; - n = block[b - 1]; + let block = this.lastBlock; + let b = 16; + const n = block[b - 1]; if (n === 0 || n > b) throw new Error('Bad decrypt (padding).'); diff --git a/lib/crypto/ccmp.js b/lib/crypto/ccmp.js index 29193fb0..45c9eef7 100644 --- a/lib/crypto/ccmp.js +++ b/lib/crypto/ccmp.js @@ -19,8 +19,6 @@ */ module.exports = function ccmp(a, b) { - let res; - if (!Buffer.isBuffer(a)) return false; @@ -30,7 +28,7 @@ module.exports = function ccmp(a, b) { if (b.length === 0) return a.length === 0; - res = a.length ^ b.length; + let res = a.length ^ b.length; for (let i = 0; i < a.length; i++) res |= a[i] ^ b[i % b.length]; diff --git a/lib/crypto/chacha20.js b/lib/crypto/chacha20.js index 1870af69..42e8db16 100644 --- a/lib/crypto/chacha20.js +++ b/lib/crypto/chacha20.js @@ -148,13 +148,11 @@ ChaCha20.prototype.encrypt = function encrypt(data) { */ ChaCha20.prototype.setCounter = function setCounter(counter) { - let lo, hi; - if (!counter) counter = 0; - lo = counter % 0x100000000; - hi = (counter - lo) / 0x100000000; + const lo = counter % 0x100000000; + const hi = (counter - lo) / 0x100000000; this.state[12] = lo; diff --git a/lib/crypto/digest-browser.js b/lib/crypto/digest-browser.js index fc6a320a..81d9c2f0 100644 --- a/lib/crypto/digest-browser.js +++ b/lib/crypto/digest-browser.js @@ -24,12 +24,10 @@ const POOL64 = Buffer.allocUnsafe(64); */ exports.hash = function _hash(alg, data) { - let hash; - if (alg === 'sha256') return sha256.digest(data); - hash = hashjs[alg]; + const hash = hashjs[alg]; assert(hash != null, 'Unknown algorithm.'); @@ -115,11 +113,10 @@ exports.root256 = function root256(left, right) { exports.hmac = function _hmac(alg, data, key) { const hash = hashjs[alg]; - let hmac; assert(hash != null, 'Unknown algorithm.'); - hmac = hashjs.hmac(hash, key); + const hmac = hashjs.hmac(hash, key); return Buffer.from(hmac.update(data).digest()); }; diff --git a/lib/crypto/ecdsa.js b/lib/crypto/ecdsa.js index 8c5540d8..4639156b 100644 --- a/lib/crypto/ecdsa.js +++ b/lib/crypto/ecdsa.js @@ -25,16 +25,14 @@ const digest = require('./digest'); */ exports.verify = function verify(curve, alg, msg, sig, key) { - let ec, hash; - assert(typeof curve === 'string', 'No curve selected.'); assert(typeof alg === 'string', 'No algorithm selected.'); assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); - ec = elliptic.ec(curve); - hash = digest.hash(alg, msg); + const ec = elliptic.ec(curve); + const hash = digest.hash(alg, msg); try { return ec.verify(hash, sig, key); @@ -54,17 +52,14 @@ exports.verify = function verify(curve, alg, msg, sig, key) { */ exports.sign = function sign(curve, alg, msg, key) { - let ec, hash, sig; - assert(typeof curve === 'string', 'No curve selected.'); assert(typeof alg === 'string', 'No algorithm selected.'); assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(key)); - ec = elliptic.ec(curve); - hash = digest.hash(alg, msg); - - sig = ec.sign(hash, key, { canonical: true }); + const ec = elliptic.ec(curve); + const hash = digest.hash(alg, msg); + const sig = ec.sign(hash, key, { canonical: true }); return Buffer.from(sig.toDER()); }; diff --git a/lib/crypto/hkdf.js b/lib/crypto/hkdf.js index 567d76fd..64f4c9df 100644 --- a/lib/crypto/hkdf.js +++ b/lib/crypto/hkdf.js @@ -36,22 +36,22 @@ exports.extract = function extract(ikm, key, alg) { exports.expand = function expand(prk, info, len, alg) { const size = digest.hash(alg, Buffer.alloc(0)).length; const blocks = Math.ceil(len / size); - let okm, buf, out; if (blocks > 255) throw new Error('Too many blocks.'); - okm = Buffer.allocUnsafe(len); + const okm = Buffer.allocUnsafe(len); if (blocks === 0) return okm; - buf = Buffer.allocUnsafe(size + info.length + 1); + const buf = Buffer.allocUnsafe(size + info.length + 1); // First round: info.copy(buf, size); buf[buf.length - 1] = 1; - out = digest.hmac(alg, buf.slice(size), prk); + + let out = digest.hmac(alg, buf.slice(size), prk); out.copy(okm, 0); for (let i = 1; i < blocks; i++) { diff --git a/lib/crypto/merkle.js b/lib/crypto/merkle.js index 0da879f9..1adeeca1 100644 --- a/lib/crypto/merkle.js +++ b/lib/crypto/merkle.js @@ -36,14 +36,13 @@ exports.createTree = function createTree(leaves) { const k = Math.min(j + 1, size - 1); const left = nodes[i + j]; const right = nodes[i + k]; - let hash; if (k === j + 1 && k + 1 === size && left.equals(right)) { malleated = true; } - hash = digest.root256(left, right); + const hash = digest.root256(left, right); nodes.push(hash); } diff --git a/lib/crypto/pbkdf2-browser.js b/lib/crypto/pbkdf2-browser.js index 82e4fc4d..92b879cf 100644 --- a/lib/crypto/pbkdf2-browser.js +++ b/lib/crypto/pbkdf2-browser.js @@ -36,9 +36,8 @@ exports.derive = function derive(key, salt, iter, len, alg) { salt.copy(buf, 0); for (let i = 0; i < blocks; i++) { - let mac; buf.writeUInt32BE(i + 1, salt.length, true); - mac = digest.hmac(alg, buf, key); + let mac = digest.hmac(alg, buf, key); mac.copy(block, 0); for (let j = 1; j < iter; j++) { mac = digest.hmac(alg, mac, key); @@ -65,20 +64,19 @@ exports.derive = function derive(key, salt, iter, len, alg) { exports.deriveAsync = async function deriveAsync(key, salt, iter, len, alg) { const algo = { name: 'PBKDF2' }; const use = ['deriveBits']; - let options, imported, data; if (!subtle.importKey || !subtle.deriveBits) return exports.derive(key, salt, iter, len, alg); - options = { + const options = { name: 'PBKDF2', salt: salt, iterations: iter, hash: getHash(alg) }; - imported = await subtle.importKey('raw', key, algo, false, use); - data = await subtle.deriveBits(options, imported, len * 8); + const imported = await subtle.importKey('raw', key, algo, false, use); + const data = await subtle.deriveBits(options, imported, len * 8); return Buffer.from(data); }; diff --git a/lib/crypto/poly1305.js b/lib/crypto/poly1305.js index 7f371e03..33e7f96f 100644 --- a/lib/crypto/poly1305.js +++ b/lib/crypto/poly1305.js @@ -10,7 +10,7 @@ const native = require('../native').binding; /** * Poly1305 (used for bip151) - * @alias module:crypto.Poly1305 + * @alias module:crypto/chachapoly.Poly1305 * @constructor * @see https://github.com/floodyberry/poly1305-donna * @see https://tools.ietf.org/html/rfc7539#section-2.5 @@ -88,7 +88,6 @@ Poly1305.prototype.blocks = function blocks(data, bytes, m) { const t5 = data.readUInt16LE(m + 10, true); const t6 = data.readUInt16LE(m + 12, true); const t7 = data.readUInt16LE(m + 14, true); - let c = 0; this.h[0] += t0 & 0x1fff; this.h[1] += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; @@ -102,14 +101,19 @@ Poly1305.prototype.blocks = function blocks(data, bytes, m) { this.h[9] += ((t7 >>> 5)) | hibit; // h *= r, (partial) h %= p + let c = 0; for (let i = 0; i < 10; i++) { d[i] = c; for (let j = 0; j < 10; j++) { + let a = this.h[j]; + if (j <= i) - d[i] += this.r[i - j]; + a *= this.r[i - j]; else - d[i] += 5 * this.r[i + 10 - j]; + a *= 5 * this.r[i + 10 - j]; + + d[i] += a; // Sum(h[i] * r[i] * 5) will overflow slightly // above 6 products with an unclamped r, so @@ -151,21 +155,15 @@ 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; } @@ -194,7 +192,6 @@ Poly1305.prototype.update = function update(data) { Poly1305.prototype.finish = function finish() { const mac = Buffer.allocUnsafe(16); const g = new Uint16Array(10); - let c, mask, f; // process the remaining block if (this.leftover) { @@ -207,7 +204,7 @@ Poly1305.prototype.finish = function finish() { } // fully carry h - c = this.h[1] >>> 13; + let c = this.h[1] >>> 13; this.h[1] &= 0x1fff; for (let i = 2; i < 10; i++) { this.h[i] += c; @@ -233,7 +230,7 @@ Poly1305.prototype.finish = function finish() { } // select h if h < p, or h + -p if h >= p - mask = (c ^ 1) - 1; + let mask = (c ^ 1) - 1; for (let i = 0; i < 10; i++) g[i] &= mask; mask = ~mask; @@ -252,7 +249,7 @@ Poly1305.prototype.finish = function finish() { this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff; // mac = (h + pad) % (2^128) - f = this.h[0] + this.pad[0]; + let f = this.h[0] + this.pad[0]; this.h[0] = f; for (let i = 1; i < 8; i++) { f = this.h[i] + this.pad[i] + (f >>> 16); @@ -265,10 +262,8 @@ 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; diff --git a/lib/crypto/rsa-browser.js b/lib/crypto/rsa-browser.js index 11fa4123..4f86783c 100644 --- a/lib/crypto/rsa-browser.js +++ b/lib/crypto/rsa-browser.js @@ -44,33 +44,31 @@ rsa.prefixes = { */ rsa.verify = function verify(alg, msg, sig, key) { - const prefix = rsa.prefixes[alg]; - let hash, len, pub; - let N, e, k, m, em, ok; - assert(typeof alg === 'string', 'No algorithm selected.'); assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); + const prefix = rsa.prefixes[alg]; + if (!prefix) throw new Error('Unknown PKCS prefix.'); - hash = digest.hash(alg, msg); - len = prefix.length + hash.length; - pub = ASN1.parseRSAPublic(key); + const hash = digest.hash(alg, msg); + const len = prefix.length + hash.length; + const pub = ASN1.parseRSAPublic(key); - N = new BN(pub.modulus); - e = new BN(pub.publicExponent); - k = Math.ceil(N.bitLength() / 8); + const N = new BN(pub.modulus); + const e = new BN(pub.publicExponent); + const k = Math.ceil(N.bitLength() / 8); if (k < len + 11) throw new Error('Message too long.'); - m = rsa.encrypt(N, e, sig); - em = leftpad(m, k); + const m = rsa.encrypt(N, e, sig); + const em = leftpad(m, k); - ok = ceq(em[0], 0x00); + let ok = ceq(em[0], 0x00); ok &= ceq(em[1], 0x01); ok &= ccmp(em.slice(k - hash.length, k), hash); ok &= ccmp(em.slice(k - len, k - hash.length), prefix); @@ -91,29 +89,27 @@ rsa.verify = function verify(alg, msg, sig, key) { */ rsa.sign = function sign(alg, msg, key) { - const prefix = rsa.prefixes[alg]; - let hash, len, priv; - let N, D, k, em; - assert(typeof alg === 'string', 'No algorithm selected.'); assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(key)); + const prefix = rsa.prefixes[alg]; + if (!prefix) throw new Error('Unknown PKCS prefix.'); - hash = digest.hash(alg, msg); - len = prefix.length + hash.length; - priv = ASN1.parseRSAPrivate(key); + const hash = digest.hash(alg, msg); + const len = prefix.length + hash.length; + const priv = ASN1.parseRSAPrivate(key); - N = new BN(priv.modulus); - D = new BN(priv.privateExponent); - k = Math.ceil(N.bitLength() / 8); + const N = new BN(priv.modulus); + const D = new BN(priv.privateExponent); + const k = Math.ceil(N.bitLength() / 8); if (k < len + 11) throw new Error('Message too long.'); - em = Buffer.allocUnsafe(k); + const em = Buffer.allocUnsafe(k); em.fill(0); em[1] = 0x01; @@ -169,12 +165,11 @@ rsa.encrypt = function encrypt(N, e, m) { function leftpad(input, size) { let n = input.length; - let out; if (n > size) n = size; - out = Buffer.allocUnsafe(size); + const out = Buffer.allocUnsafe(size); out.fill(0); input.copy(out, out.length - n); diff --git a/lib/crypto/rsa.js b/lib/crypto/rsa.js index 903049bb..c8a3b57c 100644 --- a/lib/crypto/rsa.js +++ b/lib/crypto/rsa.js @@ -24,17 +24,14 @@ const PEM = require('../utils/pem'); */ exports.verify = function verify(alg, msg, sig, key) { - let pem, name, ctx; - assert(typeof alg === 'string', 'No algorithm selected.'); assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); - name = normalizeAlg('rsa', alg); - pem = PEM.encode(key, 'rsa', 'public key'); - - ctx = crypto.createVerify(name); + const name = normalizeAlg('rsa', alg); + const pem = PEM.encode(key, 'rsa', 'public key'); + const ctx = crypto.createVerify(name); try { ctx.update(msg); @@ -53,16 +50,14 @@ exports.verify = function verify(alg, msg, sig, key) { */ exports.sign = function sign(alg, msg, key) { - let pem, name, ctx; - assert(typeof alg === 'string', 'No algorithm selected.'); assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(key)); - name = normalizeAlg('rsa', alg); - pem = PEM.encode(key, 'rsa', 'private key'); + const name = normalizeAlg('rsa', alg); + const pem = PEM.encode(key, 'rsa', 'private key'); + const ctx = crypto.createSign(name); - ctx = crypto.createSign(name); ctx.update(msg); return ctx.sign(pem); diff --git a/lib/crypto/schnorr.js b/lib/crypto/schnorr.js index 915e5873..75529c7d 100644 --- a/lib/crypto/schnorr.js +++ b/lib/crypto/schnorr.js @@ -49,8 +49,6 @@ schnorr.hash = function _hash(msg, r) { */ schnorr.trySign = function trySign(msg, prv, k, pn) { - let r, h, s; - if (prv.cmpn(0) === 0) throw new Error('Bad private key.'); @@ -63,7 +61,7 @@ schnorr.trySign = function trySign(msg, prv, k, pn) { if (k.cmp(curve.n) >= 0) return null; - r = curve.g.mul(k); + let r = curve.g.mul(k); if (pn) r = r.add(pn); @@ -73,7 +71,7 @@ schnorr.trySign = function trySign(msg, prv, k, pn) { k = curve.n.sub(k); } - h = schnorr.hash(msg, r.getX()); + const h = schnorr.hash(msg, r.getX()); if (h.cmpn(0) === 0) return null; @@ -81,7 +79,7 @@ schnorr.trySign = function trySign(msg, prv, k, pn) { if (h.cmp(curve.n) >= 0) return null; - s = h.imul(prv); + let s = h.imul(prv); s = k.isub(s); s = s.umod(curve.n); @@ -103,13 +101,14 @@ 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 k, pn, sig; + let pn = null; + let sig = null; if (pubNonce) pn = curve.decodePoint(pubNonce); while (!sig) { - k = new BN(drbg.generate(len)); + const k = new BN(drbg.generate(len)); sig = schnorr.trySign(msg, prv, k, pn); } @@ -127,7 +126,6 @@ schnorr.sign = function sign(msg, key, pubNonce) { schnorr.verify = function verify(msg, signature, key) { const sig = new Signature(signature); const h = schnorr.hash(msg, sig.r); - let k, l, r, rl; if (h.cmp(curve.n) >= 0) throw new Error('Invalid hash.'); @@ -141,10 +139,10 @@ schnorr.verify = function verify(msg, signature, key) { if (sig.r.cmp(curve.p) > 0) throw new Error('Invalid R value.'); - k = curve.decodePoint(key); - l = k.mul(h); - r = curve.g.mul(sig.s); - rl = l.add(r); + const k = curve.decodePoint(key); + const l = k.mul(h); + const r = curve.g.mul(sig.s); + const rl = l.add(r); if (rl.y.isOdd()) throw new Error('Odd R value.'); @@ -162,7 +160,6 @@ schnorr.verify = function verify(msg, signature, key) { schnorr.recover = function recover(signature, msg) { const sig = new Signature(signature); const h = schnorr.hash(msg, sig.r); - let hinv, s, R, l, r, k, rl; if (h.cmp(curve.n) >= 0) throw new Error('Invalid hash.'); @@ -176,24 +173,25 @@ schnorr.recover = function recover(signature, msg) { if (sig.r.cmp(curve.p) > 0) throw new Error('Invalid R value.'); - hinv = h.invm(curve.n); + let hinv = h.invm(curve.n); hinv = hinv.umod(curve.n); - s = sig.s; + let s = sig.s; s = curve.n.sub(s); s = s.umod(curve.n); s = s.imul(hinv); s = s.umod(curve.n); - R = curve.pointFromX(sig.r, false); - l = R.mul(hinv); - r = curve.g.mul(s); - k = l.add(r); + const R = curve.pointFromX(sig.r, false); + let l = R.mul(hinv); + let r = curve.g.mul(s); + const k = l.add(r); l = k.mul(h); r = curve.g.mul(sig.s); - rl = l.add(r); + + const rl = l.add(r); if (rl.y.isOdd()) throw new Error('Odd R value.'); @@ -212,7 +210,8 @@ schnorr.recover = function recover(signature, msg) { schnorr.combineSigs = function combineSigs(sigs) { let s = new BN(0); - let r, last; + let r = null; + let last = null; for (let i = 0; i < sigs.length; i++) { const sig = new Signature(sigs[i]); @@ -248,18 +247,16 @@ schnorr.combineSigs = function combineSigs(sigs) { */ schnorr.combineKeys = function combineKeys(keys) { - let i, key, point; - if (keys.length === 0) throw new Error(); if (keys.length === 1) return keys[0]; - point = curve.decodePoint(keys[0]); + let point = curve.decodePoint(keys[0]); - for (i = 1; i < keys.length; i++) { - key = curve.decodePoint(keys[i]); + for (let i = 1; i < keys.length; i++) { + const key = curve.decodePoint(keys[i]); point = point.add(key); } diff --git a/lib/crypto/scrypt.js b/lib/crypto/scrypt.js index 9f1d5e58..638e609e 100644 --- a/lib/crypto/scrypt.js +++ b/lib/crypto/scrypt.js @@ -56,8 +56,6 @@ const native = require('../native').binding; */ function derive(passwd, salt, N, r, p, len) { - let B, V, XY; - if (r * p >= (1 << 30)) throw new Error('EFBIG'); @@ -67,10 +65,10 @@ function derive(passwd, salt, N, r, p, len) { if (N > 0xffffffff) throw new Error('EINVAL'); - XY = Buffer.allocUnsafe(256 * r); - V = Buffer.allocUnsafe(128 * r * N); + const XY = Buffer.allocUnsafe(256 * r); + const V = Buffer.allocUnsafe(128 * r * N); - B = pbkdf2.derive(passwd, salt, 1, p * 128 * r, 'sha256'); + const B = pbkdf2.derive(passwd, salt, 1, p * 128 * r, 'sha256'); for (let i = 0; i < p; i++) smix(B, i * 128 * r, r, N, V, XY); @@ -95,8 +93,6 @@ if (native) */ async function deriveAsync(passwd, salt, N, r, p, len) { - let B, V, XY; - if (r * p >= (1 << 30)) throw new Error('EFBIG'); @@ -106,10 +102,10 @@ async function deriveAsync(passwd, salt, N, r, p, len) { if (N > 0xffffffff) throw new Error('EINVAL'); - XY = Buffer.allocUnsafe(256 * r); - V = Buffer.allocUnsafe(128 * r * N); + const XY = Buffer.allocUnsafe(256 * r); + const V = Buffer.allocUnsafe(128 * r * N); - B = await pbkdf2.deriveAsync(passwd, salt, 1, p * 128 * r, 'sha256'); + const B = await pbkdf2.deriveAsync(passwd, salt, 1, p * 128 * r, 'sha256'); for (let i = 0; i < p; i++) await smixAsync(B, i * 128 * r, r, N, V, XY); diff --git a/lib/crypto/secp256k1-browser.js b/lib/crypto/secp256k1-browser.js index c576ebbf..b1e3908c 100644 --- a/lib/crypto/secp256k1-browser.js +++ b/lib/crypto/secp256k1-browser.js @@ -46,14 +46,12 @@ ec.generatePrivateKey = function generatePrivateKey() { */ ec.publicKeyCreate = function publicKeyCreate(priv, compress) { - let key; - assert(Buffer.isBuffer(priv)); if (compress == null) compress = true; - key = secp256k1.keyPair({ priv: priv }); + const key = secp256k1.keyPair({ priv: priv }); return Buffer.from(key.getPublic(compress, 'array')); }; @@ -103,12 +101,11 @@ ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) { ec.publicKeyTweakAdd = function publicKeyTweakAdd(publicKey, tweak, compress) { const key = curve.decodePoint(publicKey); const point = curve.g.mul(new BN(tweak)).add(key); - let pub; if (compress == null) compress = true; - pub = Buffer.from(point.encode('array', compress)); + const pub = Buffer.from(point.encode('array', compress)); if (!ec.publicKeyVerify(pub)) throw new Error('Public key is invalid.'); @@ -139,14 +136,13 @@ ec.ecdh = function ecdh(pub, priv) { */ ec.recover = function recover(msg, sig, j, compress) { - let point; - if (!j) j = 0; if (compress == null) compress = true; + let point; try { point = secp256k1.recoverPubKey(msg, sig, j); } catch (e) { @@ -224,13 +220,11 @@ ec.privateKeyVerify = function privateKeyVerify(key) { */ ec.sign = function sign(msg, key) { - let sig; - assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(key)); // Sign message and ensure low S value - sig = secp256k1.sign(msg, key, { canonical: true }); + const sig = secp256k1.sign(msg, key, { canonical: true }); // Convert to DER return Buffer.from(sig.toDER()); @@ -238,17 +232,15 @@ ec.sign = function sign(msg, key) { /** * Convert DER signature to R/S. - * @param {Buffer} sig + * @param {Buffer} raw * @returns {Buffer} R/S-formatted signature. */ -ec.fromDER = function fromDER(sig) { - let out; +ec.fromDER = function fromDER(raw) { + assert(Buffer.isBuffer(raw)); - assert(Buffer.isBuffer(sig)); - - sig = new Signature(sig); - out = Buffer.allocUnsafe(64); + const sig = new Signature(raw); + const out = Buffer.allocUnsafe(64); sig.r.toBuffer('be', 32).copy(out, 0); sig.s.toBuffer('be', 32).copy(out, 32); @@ -262,17 +254,15 @@ ec.fromDER = function fromDER(sig) { * @returns {Buffer} DER-formatted signature. */ -ec.toDER = function toDER(sig) { - let out; +ec.toDER = function toDER(raw) { + assert(Buffer.isBuffer(raw)); - assert(Buffer.isBuffer(sig)); - - out = new Signature({ - r: new BN(sig.slice(0, 32), 'be'), - s: new BN(sig.slice(32, 64), 'be') + const sig = new Signature({ + r: new BN(raw.slice(0, 32), 'be'), + s: new BN(raw.slice(32, 64), 'be') }); - return Buffer.from(out.toDER()); + return Buffer.from(sig.toDER()); }; /** @@ -281,9 +271,10 @@ ec.toDER = function toDER(sig) { * @returns {Boolean} */ -ec.isLowS = function isLowS(sig) { +ec.isLowS = function isLowS(raw) { + let sig; try { - sig = new Signature(sig); + sig = new Signature(raw); } catch (e) { return false; } @@ -306,12 +297,11 @@ ec.isLowS = function isLowS(sig) { function normalizeLength(sig) { let data = sig; const p = { place: 0 }; - let len, rlen, slen; if (data[p.place++] !== 0x30) return sig; - len = getLength(data, p); + const len = getLength(data, p); if (data.length > len + p.place) data = data.slice(0, len + p.place); @@ -319,13 +309,13 @@ function normalizeLength(sig) { if (data[p.place++] !== 0x02) return sig; - rlen = getLength(data, p); + const rlen = getLength(data, p); p.place += rlen; if (data[p.place++] !== 0x02) return sig; - slen = getLength(data, p); + const slen = getLength(data, p); if (data.length > slen + p.place) data = data.slice(0, slen + p.place); diff --git a/lib/crypto/siphash.js b/lib/crypto/siphash.js index 0dd92144..23b40328 100644 --- a/lib/crypto/siphash.js +++ b/lib/crypto/siphash.js @@ -34,13 +34,12 @@ function siphash24(data, key, shift) { const k0 = U64.fromRaw(key, 0); const k1 = U64.fromRaw(key, 8); let p = 0; - let v0, v1, v2, v3; // Init - v0 = c0.ixor(k0); - v1 = c1.ixor(k1); - v2 = c2.ixor(k0); - v3 = c3.ixor(k1); + const v0 = c0.ixor(k0); + const v1 = c1.ixor(k1); + const v2 = c2.ixor(k0); + const v3 = c3.ixor(k1); // Blocks for (let i = 0; i < blocks; i++) { @@ -153,18 +152,17 @@ function U64(hi, lo) { U64.prototype.iadd = function iadd(b) { const a = this; - let hi, lo, as, bs, s, c; // Credit to @indutny for this method. - lo = (a.lo + b.lo) | 0; + const lo = (a.lo + b.lo) | 0; - s = lo >> 31; - as = a.lo >> 31; - bs = b.lo >> 31; + const s = lo >> 31; + const as = a.lo >> 31; + const bs = b.lo >> 31; - c = ((as & bs) | (~s & (as ^ bs))) & 1; + const c = ((as & bs) | (~s & (as ^ bs))) & 1; - hi = ((a.hi + b.hi) | 0) + c; + const hi = ((a.hi + b.hi) | 0) + c; a.hi = hi | 0; a.lo = lo; diff --git a/lib/db/lowlevelup.js b/lib/db/lowlevelup.js index 8f1aca90..97dda37e 100644 --- a/lib/db/lowlevelup.js +++ b/lib/db/lowlevelup.js @@ -493,12 +493,11 @@ LowlevelUp.prototype.keys = async function _keys(options) { for (;;) { const item = await iter.next(); - let key; if (!item) break; - key = item.key; + let key = item.key; if (parse) { try { @@ -536,12 +535,11 @@ LowlevelUp.prototype.values = async function _values(options) { for (;;) { const item = await iter.next(); - let value; if (!item) break; - value = item.value; + let value = item.value; if (parse) { try { @@ -613,24 +611,23 @@ LowlevelUp.prototype.checkVersion = async function checkVersion(key, version) { */ LowlevelUp.prototype.clone = async function clone(path) { - const options = new LLUOptions(this.options); - const hwm = 256 << 20; - let total = 0; - let tmp, batch, iter; - if (!this.loaded) throw new Error('Database is closed.'); + const options = new LLUOptions(this.options); + const hwm = 256 << 20; + options.createIfMissing = true; options.errorIfExists = true; - tmp = new LowlevelUp(this.backend, path, options); + const tmp = new LowlevelUp(this.backend, path, options); await tmp.open(); - batch = tmp.batch(); + let batch = tmp.batch(); + let total = 0; - iter = this.iterator({ + const iter = this.iterator({ keys: true, values: true }); diff --git a/lib/db/memdb.js b/lib/db/memdb.js index ad94aa0b..327a9b24 100644 --- a/lib/db/memdb.js +++ b/lib/db/memdb.js @@ -37,14 +37,12 @@ function MemDB(location) { */ MemDB.prototype.search = function search(key) { - let node; - if (typeof key === 'string') key = Buffer.from(key, 'utf8'); assert(Buffer.isBuffer(key), 'Key must be a Buffer.'); - node = this.tree.search(key); + const node = this.tree.search(key); if (!node) return; @@ -149,8 +147,6 @@ MemDB.prototype.close = function close(callback) { */ MemDB.prototype.get = function get(key, options, callback) { - let value; - if (!callback) { callback = options; options = null; @@ -159,7 +155,7 @@ MemDB.prototype.get = function get(key, options, callback) { if (!options) options = {}; - value = this.search(key); + let value = this.search(key); if (!value) { const err = new Error('MEMDB_NOTFOUND: Key not found.'); @@ -221,14 +217,12 @@ MemDB.prototype.del = function del(key, options, callback) { */ MemDB.prototype.batch = function _batch(ops, options, callback) { - let batch; - if (!callback) { callback = options; options = null; } - batch = new Batch(this, options); + const batch = new Batch(this, options); if (ops) { batch.ops = ops; diff --git a/lib/hd/mnemonic.js b/lib/hd/mnemonic.js index c1c04b79..f0a4bf12 100644 --- a/lib/hd/mnemonic.js +++ b/lib/hd/mnemonic.js @@ -140,15 +140,13 @@ Mnemonic.prototype.destroy = function destroy() { */ Mnemonic.prototype.toSeed = function toSeed(passphrase) { - let phrase, passwd; - if (!passphrase) passphrase = this.passphrase; this.passphrase = passphrase; - phrase = nfkd(this.getPhrase()); - passwd = nfkd('mnemonic' + passphrase); + const phrase = nfkd(this.getPhrase()); + const passwd = nfkd('mnemonic' + passphrase); return pbkdf2.derive( Buffer.from(phrase, 'utf8'), @@ -176,25 +174,22 @@ Mnemonic.prototype.getEntropy = function getEntropy() { */ Mnemonic.prototype.getPhrase = function getPhrase() { - let phrase, wordlist, bits, ent, entropy; - if (this.phrase) return this.phrase; - phrase = []; - wordlist = Mnemonic.getWordlist(this.language); + let phrase = []; + const wordlist = Mnemonic.getWordlist(this.language); - ent = this.getEntropy(); - bits = this.bits; + const ent = this.getEntropy(); // Include the first `ENT / 32` bits // of the hash (the checksum). - bits += bits / 32; + const bits = this.bits + (this.bits / 32); // Append the hash to the entropy to // make things easy when grabbing // the checksum bits. - entropy = Buffer.allocUnsafe(Math.ceil(bits / 8)); + const entropy = Buffer.allocUnsafe(Math.ceil(bits / 8)); ent.copy(entropy, 0); digest.sha256(ent).copy(entropy, ent.length); @@ -234,9 +229,6 @@ Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) { let bits = words.length * 11; const cbits = bits % 32; const cbytes = Math.ceil(cbits / 8); - const lang = Mnemonic.getLanguage(words[0]); - const wordlist = Mnemonic.getWordlist(lang); - let ent, entropy, chk; bits -= cbits; @@ -245,9 +237,12 @@ Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) { assert(bits % 32 === 0); assert(cbits !== 0, 'Invalid checksum.'); - ent = Buffer.allocUnsafe(Math.ceil((bits + cbits) / 8)); + const ent = Buffer.allocUnsafe(Math.ceil((bits + cbits) / 8)); ent.fill(0); + const lang = Mnemonic.getLanguage(words[0]); + const wordlist = Mnemonic.getWordlist(lang); + // Rebuild entropy bytes. for (let i = 0; i < words.length; i++) { const word = words[i]; @@ -265,16 +260,16 @@ Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) { } } - entropy = ent.slice(0, ent.length - cbytes); - ent = ent.slice(ent.length - cbytes); - chk = digest.sha256(entropy); + const entropy = ent.slice(0, ent.length - cbytes); + const chk1 = ent.slice(ent.length - cbytes); + const chk2 = digest.sha256(entropy); // Verify checksum. for (let i = 0; i < cbits; i++) { const bit = i % 8; const oct = (i - bit) / 8; - const a = (ent[oct] >>> (7 - bit)) & 1; - const b = (chk[oct] >>> (7 - bit)) & 1; + const a = (chk1[oct] >>> (7 - bit)) & 1; + const b = (chk2[oct] >>> (7 - bit)) & 1; if (a !== b) throw new Error('Invalid checksum.'); } @@ -342,10 +337,8 @@ Mnemonic.fromEntropy = function fromEntropy(entropy, lang) { */ Mnemonic.getLanguage = function getLanguage(word) { - let lang, wordlist; - - for (lang of Mnemonic.languages) { - wordlist = Mnemonic.getWordlist(lang); + for (const lang of Mnemonic.languages) { + const wordlist = Mnemonic.getWordlist(lang); if (util.binarySearch(wordlist, word, util.strcmp) !== -1) return lang; } diff --git a/lib/hd/private.js b/lib/hd/private.js index 248e60e2..91b682f2 100644 --- a/lib/hd/private.js +++ b/lib/hd/private.js @@ -178,8 +178,6 @@ HDPrivateKey.prototype.destroy = function destroy(pub) { */ HDPrivateKey.prototype.derive = function derive(index, hardened) { - let bw, id, data, hash, left, right, key, child; - assert(typeof index === 'number'); if (hardened && index < common.HARDENED) @@ -191,13 +189,13 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) { if (this.depth >= 0xff) throw new Error('Depth too high.'); - id = this.getID(index); - child = common.cache.get(id); + const id = this.getID(index); + const cache = common.cache.get(id); - if (child) - return child; + if (cache) + return cache; - bw = new StaticWriter(37); + const bw = new StaticWriter(37); if (index >= common.HARDENED) { bw.writeU8(0); @@ -208,12 +206,13 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) { bw.writeU32BE(index); } - data = bw.render(); + const data = bw.render(); - hash = digest.hmac('sha512', data, this.chainCode); - left = hash.slice(0, 32); - right = hash.slice(32, 64); + const hash = digest.hmac('sha512', data, this.chainCode); + const left = hash.slice(0, 32); + const right = hash.slice(32, 64); + let key; try { key = secp256k1.privateKeyTweakAdd(this.privateKey, left); } catch (e) { @@ -223,7 +222,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) { if (!this.fingerPrint) this.fingerPrint = digest.hash160(this.publicKey).slice(0, 4); - child = new HDPrivateKey(); + const child = new HDPrivateKey(); child.network = this.network; child.depth = this.depth + 1; child.parentFingerPrint = this.fingerPrint; @@ -313,15 +312,13 @@ HDPrivateKey.prototype.isBIP45 = function isBIP45() { */ HDPrivateKey.isBase58 = function isBase58(data, network) { - let prefix; - if (typeof data !== 'string') return false; if (data.length < 4) return false; - prefix = data.substring(0, 4); + const prefix = data.substring(0, 4); try { Network.fromPrivate58(prefix, network); @@ -339,15 +336,13 @@ HDPrivateKey.isBase58 = function isBase58(data, network) { */ HDPrivateKey.isRaw = function isRaw(data, network) { - let version; - if (!Buffer.isBuffer(data)) return false; if (data.length < 4) return false; - version = data.readUInt32BE(0, true); + const version = data.readUInt32BE(0, true); try { Network.fromPrivate(version, network); @@ -458,8 +453,6 @@ HDPrivateKey.prototype.compare = function compare(key) { */ HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) { - let hash, left, right; - assert(Buffer.isBuffer(seed)); if (!(seed.length * 8 >= common.MIN_ENTROPY @@ -467,9 +460,9 @@ HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) { throw new Error('Entropy not in range.'); } - hash = digest.hmac('sha512', seed, common.SEED_SALT); - left = hash.slice(0, 32); - right = hash.slice(32, 64); + const hash = digest.hmac('sha512', seed, common.SEED_SALT); + const left = hash.slice(0, 32); + const right = hash.slice(32, 64); // Only a 1 in 2^127 chance of happening. if (!secp256k1.privateKeyVerify(left)) diff --git a/lib/hd/public.js b/lib/hd/public.js index f07d1ff5..f2ae4b4c 100644 --- a/lib/hd/public.js +++ b/lib/hd/public.js @@ -152,8 +152,6 @@ HDPublicKey.prototype.destroy = function destroy() { */ HDPublicKey.prototype.derive = function derive(index, hardened) { - let bw, id, data, hash, left, right, key, child; - assert(typeof index === 'number'); if (index >= common.HARDENED || hardened) @@ -165,21 +163,24 @@ HDPublicKey.prototype.derive = function derive(index, hardened) { if (this.depth >= 0xff) throw new Error('Depth too high.'); - id = this.getID(index); - child = common.cache.get(id); + const id = this.getID(index); + const cache = common.cache.get(id); - if (child) - return child; + if (cache) + return cache; + + const bw = new StaticWriter(37); - bw = new StaticWriter(37); bw.writeBytes(this.publicKey); bw.writeU32BE(index); - data = bw.render(); - hash = digest.hmac('sha512', data, this.chainCode); - left = hash.slice(0, 32); - right = hash.slice(32, 64); + const data = bw.render(); + const hash = digest.hmac('sha512', data, this.chainCode); + const left = hash.slice(0, 32); + const right = hash.slice(32, 64); + + let key; try { key = secp256k1.publicKeyTweakAdd(this.publicKey, left, true); } catch (e) { @@ -189,7 +190,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened) { if (!this.fingerPrint) this.fingerPrint = digest.hash160(this.publicKey).slice(0, 4); - child = new HDPublicKey(); + const child = new HDPublicKey(); child.network = this.network; child.depth = this.depth + 1; child.parentFingerPrint = this.fingerPrint; @@ -409,15 +410,13 @@ HDPublicKey.fromJSON = function fromJSON(json, network) { */ HDPublicKey.isBase58 = function isBase58(data, network) { - let prefix; - if (typeof data !== 'string') return false; if (data.length < 4) return false; - prefix = data.substring(0, 4); + const prefix = data.substring(0, 4); try { Network.fromPublic58(prefix, network); @@ -435,15 +434,13 @@ HDPublicKey.isBase58 = function isBase58(data, network) { */ HDPublicKey.isRaw = function isRaw(data, network) { - let version; - if (!Buffer.isBuffer(data)) return false; if (data.length < 4) return false; - version = data.readUInt32BE(0, true); + const version = data.readUInt32BE(0, true); try { Network.fromPublic(version, network); diff --git a/lib/http/base.js b/lib/http/base.js index 8dad9019..fdda42b6 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -121,8 +121,6 @@ HTTPBase.prototype._initRouter = function _initRouter() { */ HTTPBase.prototype.handleRequest = async function handleRequest(req, res) { - let routes; - if (await this.handleMounts(req, res)) return; @@ -131,7 +129,7 @@ HTTPBase.prototype.handleRequest = async function handleRequest(req, res) { if (await this.handleStack(req, res)) return; - routes = this.routes.getHandlers(req.method); + const routes = this.routes.getHandlers(req.method); if (!routes) throw new Error(`No routes found for method: ${req.method}.`); @@ -212,13 +210,12 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) { } return async (req, res) => { - let auth = req.headers['authorization']; - let parts, username, password, hash; + const hdr = req.headers['authorization']; - if (!auth) + if (!hdr) return fail(res); - parts = auth.split(' '); + const parts = hdr.split(' '); if (parts.length !== 2) return fail(res); @@ -226,22 +223,22 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) { if (parts[0] !== 'Basic') return fail(res); - auth = Buffer.from(parts[1], 'base64').toString('utf8'); - parts = auth.split(':'); + const auth = Buffer.from(parts[1], 'base64').toString('utf8'); + const items = auth.split(':'); - username = parts.shift(); - password = parts.join(':'); + const username = items.shift(); + const password = items.join(':'); if (user) { - hash = Buffer.from(username, 'utf8'); - hash = digest.hash256(hash); + const raw = Buffer.from(username, 'utf8'); + const hash = digest.hash256(raw); if (!ccmp(hash, user)) return fail(res); } - hash = Buffer.from(password, 'utf8'); - hash = digest.hash256(hash); + const raw = Buffer.from(password, 'utf8'); + const hash = digest.hash256(raw); if (!ccmp(hash, pass)) return fail(res); @@ -284,17 +281,17 @@ HTTPBase.prototype.bodyParser = function bodyParser(options) { HTTPBase.prototype.parseBody = async function parseBody(req, options) { let body = Object.create(null); - let type = req.contentType; - let data; if (req.method === 'GET') return body; - data = await this.readBody(req, 'utf8', options); + const data = await this.readBody(req, 'utf8', options); if (!data) return body; + let type = req.contentType; + if (options.contentType) type = options.contentType; @@ -400,8 +397,6 @@ HTTPBase.prototype._readBody = function _readBody(req, enc, options, resolve, re HTTPBase.prototype.jsonRPC = function jsonRPC(rpc) { return async (req, res) => { - let json; - if (req.method !== 'POST') return; @@ -411,7 +406,7 @@ HTTPBase.prototype.jsonRPC = function jsonRPC(rpc) { if (typeof req.body.method !== 'string') return; - json = await rpc.call(req.body, req.query); + let json = await rpc.call(req.body, req.query); json = JSON.stringify(json); json += '\n'; @@ -1086,18 +1081,16 @@ Route.prototype.compile = function compile() { }; Route.prototype.match = function _match(pathname) { - let match, params; - this.compile(); assert(this.regex); - match = this.regex.exec(pathname); + const match = this.regex.exec(pathname); if (!match) return; - params = Object.create(null); + const params = Object.create(null); for (let i = 1; i < match.length; i++) { const item = match[i]; @@ -1233,7 +1226,6 @@ Request.prototype.parse = function parse(url) { let pathname = uri.pathname; let query = Object.create(null); let trailing = false; - let path, parts; if (pathname) { pathname = pathname.replace(/\/{2,}/g, '/'); @@ -1260,12 +1252,12 @@ Request.prototype.parse = function parse(url) { if (pathname.length > 1) assert(pathname[pathname.length - 1] !== '/'); - path = pathname; + let path = pathname; if (path[0] === '/') path = path.substring(1); - parts = path.split('/'); + let parts = path.split('/'); if (parts.length === 1) { if (parts[0].length === 0) diff --git a/lib/http/client.js b/lib/http/client.js index 5cb028c8..f80a28bf 100644 --- a/lib/http/client.js +++ b/lib/http/client.js @@ -195,7 +195,7 @@ HTTPClient.prototype.onDisconnect = function onDisconnect() { */ HTTPClient.prototype._request = async function _request(method, endpoint, json) { - let query, network, res; + let query; if (this.token) { if (!json) @@ -208,7 +208,7 @@ HTTPClient.prototype._request = async function _request(method, endpoint, json) json = null; } - res = await request({ + const res = await request({ method: method, uri: this.uri + endpoint, pool: true, @@ -235,7 +235,7 @@ HTTPClient.prototype._request = async function _request(method, endpoint, json) if (!res.body) throw new Error('Bad response (no body).'); - network = res.headers['x-bcoin-network']; + const network = res.headers['x-bcoin-network']; if (network && network !== this.network.type) throw new Error('Bad response (wrong network).'); diff --git a/lib/http/request.js b/lib/http/request.js index 022120bc..2cc3f509 100644 --- a/lib/http/request.js +++ b/lib/http/request.js @@ -223,12 +223,10 @@ RequestOptions.prototype.getBackend = function getBackend() { }; RequestOptions.prototype.getHeaders = function getHeaders() { - let headers; - if (this.headers) return this.headers; - headers = Object.create(null); + const headers = Object.create(null); headers['User-Agent'] = this.agent; diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 58a8ae73..2449059b 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -185,12 +185,10 @@ RPC.prototype.getInfo = async function getInfo(args, help) { }; RPC.prototype.help = async function _help(args, help) { - let json; - if (args.length === 0) return 'Select a command.'; - json = { + const json = { method: args[0], params: [] }; @@ -281,14 +279,13 @@ RPC.prototype.addNode = async function addNode(args, help) { RPC.prototype.disconnectNode = async function disconnectNode(args, help) { const valid = new Validator([args]); - let addr = valid.str(0, ''); - let peer; + const str = valid.str(0, ''); if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'disconnectnode "node"'); - addr = parseIP(addr, this.network); - peer = this.pool.peers.get(addr.hostname); + const addr = parseIP(str, this.network); + const peer = this.pool.peers.get(addr.hostname); if (peer) peer.destroy(); @@ -301,7 +298,7 @@ RPC.prototype.getAddedNodeInfo = async function getAddedNodeInfo(args, help) { const valid = new Validator([args]); const addr = valid.str(0, ''); const result = []; - let target; + let target = null; if (help || args.length > 1) throw new RPCError(errs.MISC_ERROR, 'getaddednodeinfo ( "node" )'); @@ -310,8 +307,6 @@ RPC.prototype.getAddedNodeInfo = async function getAddedNodeInfo(args, help) { target = parseIP(addr, this.network); for (const node of hosts.nodes) { - let peer; - if (target) { if (node.host !== target.host) continue; @@ -320,7 +315,7 @@ RPC.prototype.getAddedNodeInfo = async function getAddedNodeInfo(args, help) { continue; } - peer = this.pool.peers.get(node.hostname); + const peer = this.pool.peers.get(node.hostname); if (!peer || !peer.connected) { result.push({ @@ -392,9 +387,9 @@ RPC.prototype.getPeerInfo = async function getPeerInfo(args, help) { if (offset == null) offset = 0; - for (let hash in peer.blockMap.keys()) { - hash = util.revHex(hash); - hashes.push(hash); + for (const hash in peer.blockMap.keys()) { + const str = util.revHex(hash); + hashes.push(str); } peers.push({ @@ -442,7 +437,7 @@ RPC.prototype.ping = async function ping(args, help) { RPC.prototype.setBan = async function setBan(args, help) { const valid = new Validator([args]); - let addr = valid.str(0, ''); + const str = valid.str(0, ''); const action = valid.str(1, ''); if (help @@ -452,7 +447,7 @@ RPC.prototype.setBan = async function setBan(args, help) { 'setban "ip(/netmask)" "add|remove" (bantime) (absolute)'); } - addr = parseNetAddress(addr, this.network); + const addr = parseNetAddress(str, this.network); switch (action) { case 'add': @@ -537,7 +532,6 @@ RPC.prototype.getBlock = async function getBlock(args, help) { const hash = valid.hash(0); const verbose = valid.bool(1, true); const details = valid.bool(2, false); - let entry, block; if (help || args.length < 1 || args.length > 3) throw new RPCError(errs.MISC_ERROR, 'getblock "hash" ( verbose )'); @@ -545,12 +539,12 @@ RPC.prototype.getBlock = async function getBlock(args, help) { if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid block hash.'); - entry = await this.chain.db.getEntry(hash); + const entry = await this.chain.db.getEntry(hash); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Block not found'); - block = await this.chain.db.getBlock(entry.hash); + const block = await this.chain.db.getBlock(entry.hash); if (!block) { if (this.chain.options.spv) @@ -573,7 +567,6 @@ RPC.prototype.getBlockByHeight = async function getBlockByHeight(args, help) { const height = valid.u32(0, -1); const verbose = valid.bool(1, true); const details = valid.bool(2, false); - let entry, block; if (help || args.length < 1 || args.length > 3) { throw new RPCError(errs.MISC_ERROR, @@ -583,12 +576,12 @@ RPC.prototype.getBlockByHeight = async function getBlockByHeight(args, help) { if (height === -1) throw new RPCError(errs.TYPE_ERROR, 'Invalid block height.'); - entry = await this.chain.db.getEntry(height); + const entry = await this.chain.db.getEntry(height); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Block not found'); - block = await this.chain.db.getBlock(entry.hash); + const block = await this.chain.db.getBlock(entry.hash); if (!block) { if (this.chain.options.spv) @@ -609,7 +602,6 @@ RPC.prototype.getBlockByHeight = async function getBlockByHeight(args, help) { RPC.prototype.getBlockHash = async function getBlockHash(args, help) { const valid = new Validator([args]); const height = valid.u32(0); - let hash; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'getblockhash index'); @@ -617,7 +609,7 @@ RPC.prototype.getBlockHash = async function getBlockHash(args, help) { if (height == null || height > this.chain.height) throw new RPCError(errs.INVALID_PARAMETER, 'Block height out of range.'); - hash = await this.chain.db.getHash(height); + const hash = await this.chain.db.getHash(height); if (!hash) throw new RPCError(errs.MISC_ERROR, 'Not found.'); @@ -629,7 +621,6 @@ RPC.prototype.getBlockHeader = async function getBlockHeader(args, help) { const valid = new Validator([args]); const hash = valid.hash(0); const verbose = valid.bool(1, true); - let entry; if (help || args.length < 1 || args.length > 2) throw new RPCError(errs.MISC_ERROR, 'getblockheader "hash" ( verbose )'); @@ -637,7 +628,7 @@ RPC.prototype.getBlockHeader = async function getBlockHeader(args, help) { if (!hash) throw new RPCError(errs.MISC_ERROR, 'Invalid block hash.'); - entry = await this.chain.db.getEntry(hash); + const entry = await this.chain.db.getEntry(hash); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Block not found'); @@ -649,22 +640,19 @@ RPC.prototype.getBlockHeader = async function getBlockHeader(args, help) { }; RPC.prototype.getChainTips = async function getChainTips(args, help) { - let tips, result; - if (help || args.length !== 0) throw new RPCError(errs.MISC_ERROR, 'getchaintips'); - tips = await this.chain.db.getTips(); - result = []; + const tips = await this.chain.db.getTips(); + const result = []; for (const hash of tips) { const entry = await this.chain.db.getEntry(hash); - let fork, main; assert(entry); - fork = await this.findFork(entry); - main = await entry.isMainChain(); + const fork = await this.findFork(entry); + const main = await entry.isMainChain(); result.push({ height: entry.height, @@ -705,7 +693,6 @@ RPC.prototype.getMempoolAncestors = async function getMempoolAncestors(args, hel const hash = valid.hash(0); const verbose = valid.bool(1, false); const out = []; - let entries, entry; if (help || args.length < 1 || args.length > 2) throw new RPCError(errs.MISC_ERROR, 'getmempoolancestors txid (verbose)'); @@ -716,12 +703,12 @@ RPC.prototype.getMempoolAncestors = async function getMempoolAncestors(args, hel if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid TXID.'); - entry = this.mempool.getEntry(hash); + const entry = this.mempool.getEntry(hash); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Transaction not in mempool.'); - entries = this.mempool.getAncestors(entry); + const entries = this.mempool.getAncestors(entry); if (verbose) { for (const entry of entries) @@ -739,7 +726,6 @@ RPC.prototype.getMempoolDescendants = async function getMempoolDescendants(args, const hash = valid.hash(0); const verbose = valid.bool(1, false); const out = []; - let entries, entry; if (help || args.length < 1 || args.length > 2) throw new RPCError(errs.MISC_ERROR, 'getmempooldescendants txid (verbose)'); @@ -750,12 +736,12 @@ RPC.prototype.getMempoolDescendants = async function getMempoolDescendants(args, if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid TXID.'); - entry = this.mempool.getEntry(hash); + const entry = this.mempool.getEntry(hash); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Transaction not in mempool.'); - entries = this.mempool.getDescendants(entry); + const entries = this.mempool.getDescendants(entry); if (verbose) { for (const entry of entries) @@ -771,7 +757,6 @@ RPC.prototype.getMempoolDescendants = async function getMempoolDescendants(args, RPC.prototype.getMempoolEntry = async function getMempoolEntry(args, help) { const valid = new Validator([args]); const hash = valid.hash(0); - let entry; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'getmempoolentry txid'); @@ -782,7 +767,7 @@ RPC.prototype.getMempoolEntry = async function getMempoolEntry(args, help) { if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid TXID.'); - entry = this.mempool.getEntry(hash); + const entry = this.mempool.getEntry(hash); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Transaction not in mempool.'); @@ -794,7 +779,6 @@ RPC.prototype.getRawMempool = async function getRawMempool(args, help) { const valid = new Validator([args]); const verbose = valid.bool(0, false); const out = {}; - let hashes; if (help || args.length > 1) throw new RPCError(errs.MISC_ERROR, 'getrawmempool ( verbose )'); @@ -809,7 +793,7 @@ RPC.prototype.getRawMempool = async function getRawMempool(args, help) { return out; } - hashes = this.mempool.getSnapshot(); + const hashes = this.mempool.getSnapshot(); return hashes.map(util.revHex); }; @@ -856,11 +840,10 @@ RPC.prototype.getTXOut = async function getTXOut(args, help) { }; RPC.prototype.getTXOutProof = async function getTXOutProof(args, help) { - let valid = new Validator([args]); + const valid = new Validator([args]); const txids = valid.array(0); const hash = valid.hash(1); const uniq = new Set(); - let block, last; if (help || (args.length !== 1 && args.length !== 2)) { throw new RPCError(errs.MISC_ERROR, @@ -876,10 +859,12 @@ RPC.prototype.getTXOutProof = async function getTXOutProof(args, help) { if (!txids || txids.length === 0) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid TXIDs.'); - valid = new Validator([txids]); + const items = new Validator([txids]); + let last = null; + let block = null; for (let i = 0; i < txids.length; i++) { - const txid = valid.hash(i); + const txid = items.hash(i); if (!txid) throw new RPCError(errs.TYPE_ERROR, 'Invalid TXID.'); @@ -925,7 +910,6 @@ RPC.prototype.verifyTXOutProof = async function verifyTXOutProof(args, help) { const valid = new Validator([args]); const data = valid.buf(0); const out = []; - let block, entry, tree; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'verifytxoutproof "proof"'); @@ -933,17 +917,17 @@ RPC.prototype.verifyTXOutProof = async function verifyTXOutProof(args, help) { if (!data) throw new RPCError(errs.TYPE_ERROR, 'Invalid hex string.'); - block = MerkleBlock.fromRaw(data); + const block = MerkleBlock.fromRaw(data); if (!block.verify()) return out; - entry = await this.chain.db.getEntry(block.hash('hex')); + const entry = await this.chain.db.getEntry(block.hash('hex')); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Block not found in chain.'); - tree = block.getTree(); + const tree = block.getTree(); for (const hash of tree.matches) out.push(util.revHex(hash)); @@ -1024,8 +1008,6 @@ RPC.prototype.submitWork = async function submitWork(data) { RPC.prototype._submitWork = async function _submitWork(data) { const attempt = this.attempt; - let header, nonce, time, nonces; - let n1, n2, proof, block, entry; if (!attempt) return false; @@ -1033,10 +1015,10 @@ RPC.prototype._submitWork = async function _submitWork(data) { if (data.length !== 128) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid work size.'); - data = data.slice(0, 80); - data = swap32(data); + const raw = data.slice(0, 80); + swap32(raw); - header = Headers.fromHead(data); + const header = Headers.fromHead(raw); if (header.prevBlock !== attempt.prevBlock || header.bits !== attempt.bits) { @@ -1046,21 +1028,22 @@ RPC.prototype._submitWork = async function _submitWork(data) { if (!header.verify()) return false; - nonces = this.merkleMap.get(header.merkleRoot); + const nonces = this.merkleMap.get(header.merkleRoot); if (!nonces) return false; - [n1, n2] = nonces; - nonce = header.nonce; - time = header.time; + const [n1, n2] = nonces; + const nonce = header.nonce; + const time = header.time; - proof = attempt.getProof(n1, n2, time, nonce); + const proof = attempt.getProof(n1, n2, time, nonce); if (!proof.verify(attempt.target)) return false; - block = attempt.commit(proof); + const block = attempt.commit(proof); + let entry = null; try { entry = await this.chain.add(block); @@ -1096,20 +1079,19 @@ RPC.prototype._createWork = async function _createWork() { const n1 = this.nonce1; const n2 = this.nonce2; const time = attempt.time; - let data, root, head; - data = Buffer.allocUnsafe(128); + const data = Buffer.allocUnsafe(128); data.fill(0); - root = attempt.getRoot(n1, n2); - head = attempt.getHeader(root, time, 0); + const root = attempt.getRoot(n1, n2); + const head = attempt.getHeader(root, time, 0); head.copy(data, 0); data[80] = 0x80; data.writeUInt32BE(80 * 8, data.length - 4, true); - data = swap32(data); + swap32(data); return { data: data.toString('hex'), @@ -1143,14 +1125,13 @@ RPC.prototype.getWork = async function getWork(args, help) { RPC.prototype.submitBlock = async function submitBlock(args, help) { const valid = new Validator([args]); const data = valid.buf(0); - let block; if (help || args.length < 1 || args.length > 2) { throw new RPCError(errs.MISC_ERROR, 'submitblock "hexdata" ( "jsonparametersobject" )'); } - block = Block.fromRaw(data); + const block = Block.fromRaw(data); return await this.addBlock(block); }; @@ -1178,12 +1159,10 @@ RPC.prototype.getBlockTemplate = async function getBlockTemplate(args, help) { throw new RPCError(errs.INVALID_PARAMETER, 'Invalid mode.'); if (mode === 'proposal') { - let block; - if (!data) throw new RPCError(errs.TYPE_ERROR, 'Missing data parameter.'); - block = Block.fromRaw(data); + const block = Block.fromRaw(data); if (block.prevBlock !== this.chain.tip.hash) return 'inconclusive-not-best-prevblk'; @@ -1276,7 +1255,6 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb const index = new Map(); const vbavailable = {}; const vbrules = []; - let json; // The miner doesn't support // versionbits. Force them to @@ -1376,7 +1354,7 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb version >>>= 0; - json = { + const json = { capabilities: ['proposal'], mutable: mutable, version: version, @@ -1507,7 +1485,6 @@ RPC.prototype.prioritiseTransaction = async function prioritiseTransaction(args, const hash = valid.hash(0); const pri = valid.num(1); const fee = valid.i64(2); - let entry; if (help || args.length !== 3) { throw new RPCError(errs.MISC_ERROR, @@ -1523,7 +1500,7 @@ RPC.prototype.prioritiseTransaction = async function prioritiseTransaction(args, if (pri == null || fee == null) throw new RPCError(errs.TYPE_ERROR, 'Invalid fee or priority.'); - entry = this.mempool.getEntry(hash); + const entry = this.mempool.getEntry(hash); if (!entry) throw new RPCError(errs.MISC_ERROR, 'Transaction not in mempool.'); @@ -1536,7 +1513,6 @@ RPC.prototype.prioritiseTransaction = async function prioritiseTransaction(args, RPC.prototype.verifyBlock = async function verifyBlock(args, help) { const valid = new Validator([args]); const data = valid.buf(0); - let block; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'verifyblock "block-hex"'); @@ -1547,7 +1523,7 @@ RPC.prototype.verifyBlock = async function verifyBlock(args, help) { if (this.chain.options.spv) throw new RPCError(errs.MISC_ERROR, 'Cannot verify block in SPV mode.'); - block = Block.fromRaw(data); + const block = Block.fromRaw(data); try { await this.chain.verifyBlock(block); @@ -1615,7 +1591,7 @@ RPC.prototype.generate = async function generate(args, help) { RPC.prototype.generateToAddress = async function _generateToAddress(args, help) { const valid = new Validator([args]); const blocks = valid.u32(0, 1); - let addr = valid.str(1, ''); + const str = valid.str(1, ''); const tries = valid.u32(2); if (help || args.length < 2 || args.length > 3) { @@ -1623,7 +1599,7 @@ RPC.prototype.generateToAddress = async function _generateToAddress(args, help) 'generatetoaddress numblocks address ( maxtries )'); } - addr = parseAddress(addr, this.network); + const addr = parseAddress(str, this.network); return await this.mineBlocks(blocks, addr, tries); }; @@ -1633,12 +1609,11 @@ RPC.prototype.generateToAddress = async function _generateToAddress(args, help) */ RPC.prototype.createRawTransaction = async function createRawTransaction(args, help) { - let valid = new Validator([args]); + const valid = new Validator([args]); const inputs = valid.array(0); const sendTo = valid.obj(1); const locktime = valid.u32(2); const uniq = new Set(); - let tx; if (help || args.length < 2 || args.length > 3) { throw new RPCError(errs.MISC_ERROR, @@ -1653,13 +1628,13 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h 'Invalid parameters (inputs and sendTo).'); } - tx = new MTX(); + const tx = new MTX(); if (locktime != null) tx.locktime = locktime; - for (let input of tx.inputs) { - const valid = new Validator([input]); + for (const obj of tx.inputs) { + const valid = new Validator([obj]); const hash = valid.hash('txid'); const index = valid.u32('vout'); let sequence = valid.u32('sequence', 0xffffffff); @@ -1670,7 +1645,7 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h if (!hash || index == null) throw new RPCError(errs.TYPE_ERROR, 'Invalid outpoint.'); - input = new Input(); + const input = new Input(); input.prevout.hash = hash; input.prevout.index = index; input.sequence = sequence; @@ -1678,19 +1653,16 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h tx.inputs.push(input); } - valid = new Validator([sendTo]); + const sends = new Validator([sendTo]); for (const key of Object.keys(sendTo)) { - let addr, b58, value, output; - if (key === 'data') { - const value = valid.buf(key); - let output; + const value = sends.buf(key); if (!value) throw new RPCError(errs.TYPE_ERROR, 'Invalid nulldata..'); - output = new Output(); + const output = new Output(); output.value = 0; output.script.fromNulldata(value); tx.outputs.push(output); @@ -1698,20 +1670,20 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h continue; } - addr = parseAddress(key, this.network); - b58 = addr.toString(this.network); + const addr = parseAddress(key, this.network); + const b58 = addr.toString(this.network); if (uniq.has(b58)) throw new RPCError(errs.INVALID_PARAMETER, 'Duplicate address'); uniq.add(b58); - value = valid.btc(key); + const value = sends.btc(key); if (value == null) throw new RPCError(errs.TYPE_ERROR, 'Invalid output value.'); - output = new Output(); + const output = new Output(); output.value = value; output.script.fromAddress(addr); @@ -1724,7 +1696,6 @@ RPC.prototype.createRawTransaction = async function createRawTransaction(args, h RPC.prototype.decodeRawTransaction = async function decodeRawTransaction(args, help) { const valid = new Validator([args]); const data = valid.buf(0); - let tx; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'decoderawtransaction "hexstring"'); @@ -1732,7 +1703,7 @@ RPC.prototype.decodeRawTransaction = async function decodeRawTransaction(args, h if (!data) throw new RPCError(errs.TYPE_ERROR, 'Invalid hex string.'); - tx = TX.fromRaw(data); + const tx = TX.fromRaw(data); return this.txToJSON(tx); }; @@ -1740,29 +1711,27 @@ RPC.prototype.decodeRawTransaction = async function decodeRawTransaction(args, h RPC.prototype.decodeScript = async function decodeScript(args, help) { const valid = new Validator([args]); const data = valid.buf(0); - let script, addr; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'decodescript "hex"'); - script = new Script(); + let script = new Script(); if (data) script = Script.fromRaw(data); - addr = Address.fromScripthash(script.hash160()); + const addr = Address.fromScripthash(script.hash160()); - script = this.scriptToJSON(script); - script.p2sh = addr.toString(this.network); + const json = this.scriptToJSON(script); + json.p2sh = addr.toString(this.network); - return script; + return json; }; RPC.prototype.getRawTransaction = async function getRawTransaction(args, help) { const valid = new Validator([args]); const hash = valid.hash(0); const verbose = valid.bool(1, false); - let json, meta, tx, entry; if (help || args.length < 1 || args.length > 2) throw new RPCError(errs.MISC_ERROR, 'getrawtransaction "txid" ( verbose )'); @@ -1770,20 +1739,22 @@ RPC.prototype.getRawTransaction = async function getRawTransaction(args, help) { if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid TXID.'); - meta = await this.node.getMeta(hash); + const meta = await this.node.getMeta(hash); if (!meta) throw new RPCError(errs.MISC_ERROR, 'Transaction not found.'); - tx = meta.tx; + const tx = meta.tx; if (!verbose) return tx.toRaw().toString('hex'); + let entry = null; + if (meta.block) entry = await this.chain.db.getEntry(meta.block); - json = this.txToJSON(tx, entry); + const json = this.txToJSON(tx, entry); json.time = meta.mtime; json.hex = tx.toRaw().toString('hex'); @@ -1793,7 +1764,6 @@ RPC.prototype.getRawTransaction = async function getRawTransaction(args, help) { RPC.prototype.sendRawTransaction = async function sendRawTransaction(args, help) { const valid = new Validator([args]); const data = valid.buf(0); - let tx; if (help || args.length < 1 || args.length > 2) { throw new RPCError(errs.MISC_ERROR, @@ -1803,7 +1773,7 @@ RPC.prototype.sendRawTransaction = async function sendRawTransaction(args, help) if (!data) throw new RPCError(errs.TYPE_ERROR, 'Invalid hex string.'); - tx = TX.fromRaw(data); + const tx = TX.fromRaw(data); this.node.relay(tx); @@ -1819,7 +1789,6 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help) const type = Script.hashType.ALL; const map = new Map(); const keys = []; - let tx; if (help || args.length < 1 || args.length > 4) { throw new RPCError(errs.MISC_ERROR, @@ -1836,7 +1805,7 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help) if (!this.mempool) throw new RPCError(errs.MISC_ERROR, 'No mempool available.'); - tx = MTX.fromRaw(data); + const tx = MTX.fromRaw(data); tx.view = await this.mempool.getSpentView(tx); if (secrets) { @@ -1857,14 +1826,13 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help) let script = valid.buf('scriptPubKey'); const value = valid.btc('amount'); let redeem = valid.buf('redeemScript'); - let coin; if (!hash || index == null || !script || value == null) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid UTXO.'); script = Script.fromRaw(script); - coin = new Output(); + const coin = new Output(); coin.script = script; coin.value = value; @@ -1884,12 +1852,10 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help) redeem = Script.fromRaw(redeem); for (const op of redeem.code) { - let key; - if (!op.data) continue; - key = map.get(op.data.toString('hex')); + const key = map.get(op.data.toString('hex')); if (key) { key.script = redeem; @@ -1931,11 +1897,10 @@ RPC.prototype.signRawTransaction = async function signRawTransaction(args, help) */ RPC.prototype.createMultisig = async function createMultisig(args, help) { - let valid = new Validator([args]); + const valid = new Validator([args]); const keys = valid.array(1, []); const m = valid.u32(0, 0); const n = keys.length; - let script, addr; if (help || args.length < 2 || args.length > 2) throw new RPCError(errs.MISC_ERROR, 'createmultisig nrequired ["key",...]'); @@ -1943,10 +1908,10 @@ RPC.prototype.createMultisig = async function createMultisig(args, help) { if (m < 1 || n < m || n > 16) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid m and n values.'); - valid = new Validator([keys]); + const items = new Validator([keys]); for (let i = 0; i < keys.length; i++) { - const key = valid.buf(i); + const key = items.buf(i); if (!key) throw new RPCError(errs.TYPE_ERROR, 'Invalid key.'); @@ -1957,12 +1922,12 @@ RPC.prototype.createMultisig = async function createMultisig(args, help) { keys[i] = key; } - script = Script.fromMultisig(m, n, keys); + const script = Script.fromMultisig(m, n, keys); if (script.getSize() > consensus.MAX_SCRIPT_PUSH) throw new RPCError(errs.VERIFY_ERROR, 'Redeem script exceeds size limit.'); - addr = script.getAddress(); + const addr = script.getAddress(); return { address: addr.toString(this.network), @@ -1973,7 +1938,6 @@ RPC.prototype.createMultisig = async function createMultisig(args, help) { RPC.prototype.createWitnessAddress = async function createWitnessAddress(args, help) { const valid = new Validator([args]); const raw = valid.buf(0); - let script, program, addr; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'createwitnessaddress "script"'); @@ -1981,9 +1945,9 @@ RPC.prototype.createWitnessAddress = async function createWitnessAddress(args, h if (!raw) throw new RPCError(errs.TYPE_ERROR, 'Invalid script hex.'); - script = Script.fromRaw(raw); - program = script.forWitness(); - addr = program.getAddress(); + const script = Script.fromRaw(raw); + const program = script.forWitness(); + const addr = program.getAddress(); return { address: addr.toString(this.network), @@ -1993,21 +1957,21 @@ RPC.prototype.createWitnessAddress = async function createWitnessAddress(args, h RPC.prototype.validateAddress = async function validateAddress(args, help) { const valid = new Validator([args]); - const b58 = valid.str(0, ''); - let addr, script; + const str = valid.str(0, ''); + let addr; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'validateaddress "bitcoinaddress"'); try { - addr = Address.fromString(b58, this.network); + addr = Address.fromString(str, this.network); } catch (e) { return { isvalid: false }; } - script = Script.fromAddress(addr); + const script = Script.fromAddress(addr); return { isvalid: true, @@ -2022,48 +1986,42 @@ RPC.prototype.verifyMessage = async function verifyMessage(args, help) { const valid = new Validator([args]); const b58 = valid.str(0, ''); const sig = valid.buf(1, null, 'base64'); - let msg = valid.str(2); - let addr, key; + const str = valid.str(2); if (help || args.length !== 3) { throw new RPCError(errs.MISC_ERROR, 'verifymessage "bitcoinaddress" "signature" "message"'); } - if (!sig || !msg) + if (!sig || !str) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameters.'); - addr = parseAddress(b58, this.network); + const addr = parseAddress(b58, this.network); + const msg = Buffer.from(MAGIC_STRING + str, 'utf8'); + const hash = digest.hash256(msg); - msg = Buffer.from(MAGIC_STRING + msg, 'utf8'); - msg = digest.hash256(msg); - - key = secp256k1.recover(msg, sig, 0, true); + const key = secp256k1.recover(hash, sig, 0, true); if (!key) return false; - key = digest.hash160(key); - - return ccmp(key, addr.hash); + return ccmp(digest.hash160(key), addr.hash); }; RPC.prototype.signMessageWithPrivkey = async function signMessageWithPrivkey(args, help) { const valid = new Validator([args]); - let key = valid.str(0, ''); - let msg = valid.str(1, ''); - let sig; + const wif = valid.str(0, ''); + const str = valid.str(1, ''); if (help || args.length !== 2) { throw new RPCError(errs.MISC_ERROR, 'signmessagewithprivkey "privkey" "message"'); } - key = parseSecret(key, this.network); - msg = Buffer.from(MAGIC_STRING + msg, 'utf8'); - msg = digest.hash256(msg); - - sig = key.sign(msg); + const key = parseSecret(wif, this.network); + const msg = Buffer.from(MAGIC_STRING + str, 'utf8'); + const hash = digest.hash256(msg); + const sig = key.sign(hash); return sig.toString('base64'); }; @@ -2071,7 +2029,6 @@ RPC.prototype.signMessageWithPrivkey = async function signMessageWithPrivkey(arg RPC.prototype.estimateFee = async function estimateFee(args, help) { const valid = new Validator([args]); let blocks = valid.u32(0, 1); - let fee; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'estimatefee nblocks'); @@ -2082,7 +2039,7 @@ RPC.prototype.estimateFee = async function estimateFee(args, help) { if (blocks < 1) blocks = 1; - fee = this.fees.estimateFee(blocks, false); + const fee = this.fees.estimateFee(blocks, false); if (fee === 0) return -1; @@ -2109,7 +2066,6 @@ RPC.prototype.estimatePriority = async function estimatePriority(args, help) { RPC.prototype.estimateSmartFee = async function estimateSmartFee(args, help) { const valid = new Validator([args]); let blocks = valid.u32(0, 1); - let fee; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'estimatesmartfee nblocks'); @@ -2120,7 +2076,7 @@ RPC.prototype.estimateSmartFee = async function estimateSmartFee(args, help) { if (blocks < 1) blocks = 1; - fee = this.fees.estimateFee(blocks, true); + let fee = this.fees.estimateFee(blocks, true); if (fee === 0) fee = -1; @@ -2136,7 +2092,6 @@ RPC.prototype.estimateSmartFee = async function estimateSmartFee(args, help) { RPC.prototype.estimateSmartPriority = async function estimateSmartPriority(args, help) { const valid = new Validator([args]); let blocks = valid.u32(0, 1); - let pri; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'estimatesmartpriority nblocks'); @@ -2147,7 +2102,7 @@ RPC.prototype.estimateSmartPriority = async function estimateSmartPriority(args, if (blocks < 1) blocks = 1; - pri = this.fees.estimatePriority(blocks, true); + const pri = this.fees.estimatePriority(blocks, true); return { priority: pri, @@ -2188,7 +2143,6 @@ RPC.prototype.reconsiderBlock = async function reconsiderBlock(args, help) { RPC.prototype.setMockTime = async function setMockTime(args, help) { const valid = new Validator([args]); const time = valid.u32(0); - let delta; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'setmocktime timestamp'); @@ -2198,7 +2152,7 @@ RPC.prototype.setMockTime = async function setMockTime(args, help) { this.network.time.offset = 0; - delta = this.network.now() - time; + const delta = this.network.now() - time; this.network.time.offset = -delta; @@ -2229,20 +2183,18 @@ RPC.prototype.setLogLevel = async function setLogLevel(args, help) { */ RPC.prototype.handleLongpoll = async function handleLongpoll(lpid) { - let watched, lastTX; - if (lpid.length !== 74) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid longpoll ID.'); - watched = lpid.slice(0, 64); - lastTX = +lpid.slice(64, 74); + const watched = lpid.slice(0, 64); + const lastTX = +lpid.slice(64, 74); - if (!util.isHex(watched) || !util.isNumber(lastTX) || lastTX < 0) + if (!util.isHex(watched) || !util.isUInt32(lastTX)) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid longpoll ID.'); - watched = util.revHex(watched); + const hash = util.revHex(watched); - if (this.chain.tip.hash !== watched) + if (this.chain.tip.hash !== hash) return; await this.longpoll(); @@ -2311,7 +2263,6 @@ RPC.prototype.getTemplate = async function getTemplate() { RPC.prototype.updateWork = async function updateWork() { let attempt = this.attempt; - let root, n1, n2; this.bindChain(); @@ -2328,13 +2279,13 @@ RPC.prototype.updateWork = async function updateWork() { this.nonce1++; } - n1 = this.nonce1; - n2 = this.nonce2; + const n1 = this.nonce1; + const n2 = this.nonce2; - root = attempt.getRoot(n1, n2); - root = root.toString('hex'); + const root = attempt.getRoot(n1, n2); + const hash = root.toString('hex'); - this.merkleMap.set(root, [n1, n2]); + this.merkleMap.set(hash, [n1, n2]); return attempt; } @@ -2346,15 +2297,15 @@ RPC.prototype.updateWork = async function updateWork() { attempt = await this.miner.createBlock(); - n1 = this.nonce1; - n2 = this.nonce2; + const n1 = this.nonce1; + const n2 = this.nonce2; - root = attempt.getRoot(n1, n2); - root = root.toString('hex'); + const root = attempt.getRoot(n1, n2); + const hash = root.toString('hex'); this.attempt = attempt; this.lastActivity = util.now(); - this.merkleMap.set(root, [n1, n2]); + this.merkleMap.set(hash, [n1, n2]); return attempt; }; @@ -2371,11 +2322,9 @@ RPC.prototype.addBlock = async function addBlock(block) { }; RPC.prototype._addBlock = async function _addBlock(block) { - let entry, prev; - this.logger.info('Handling submitted block: %s.', block.rhash()); - prev = await this.chain.db.getEntry(block.prevBlock); + const prev = await this.chain.db.getEntry(block.prevBlock); if (prev) { const state = await this.chain.getDeployments(block.time, prev); @@ -2397,6 +2346,8 @@ RPC.prototype._addBlock = async function _addBlock(block) { } } + let entry = null; + try { entry = await this.chain._add(block); } catch (err) { @@ -2435,7 +2386,7 @@ RPC.prototype.getBIP9Softforks = async function getBIP9Softforks() { for (const deployment of this.network.deploys) { const state = await this.chain.getState(tip, deployment); - let status; + let status = null; switch (state) { case common.thresholdStates.DEFINED: @@ -2471,7 +2422,6 @@ RPC.prototype.getBIP9Softforks = async function getBIP9Softforks() { RPC.prototype.getHashRate = async function getHashRate(lookup, height) { let tip = this.chain.tip; - let minTime, maxTime, workDiff, timeDiff, ps, entry; if (height != null) tip = await this.chain.db.getEntry(height); @@ -2485,9 +2435,9 @@ RPC.prototype.getHashRate = async function getHashRate(lookup, height) { if (lookup > tip.height) lookup = tip.height; - minTime = tip.time; - maxTime = minTime; - entry = tip; + let minTime = tip.time; + let maxTime = minTime; + let last = tip; for (let i = 0; i < lookup; i++) { const entry = await entry.getPrevious(); @@ -2497,14 +2447,15 @@ RPC.prototype.getHashRate = async function getHashRate(lookup, height) { minTime = Math.min(entry.time, minTime); maxTime = Math.max(entry.time, maxTime); + last = entry; } if (minTime === maxTime) return 0; - workDiff = tip.chainwork.sub(entry.chainwork); - timeDiff = maxTime - minTime; - ps = +workDiff.toString(10) / timeDiff; + const workDiff = tip.chainwork.sub(last.chainwork); + const timeDiff = maxTime - minTime; + const ps = +workDiff.toString(10) / timeDiff; return ps; }; @@ -2611,10 +2562,9 @@ RPC.prototype.txToJSON = function txToJSON(tx, entry) { RPC.prototype.scriptToJSON = function scriptToJSON(script, hex) { const type = script.getType(); - let addr = script.getAddress(); - let out; + const addr = script.getAddress(); - out = { + const json = { asm: script.toASM(), hex: undefined, type: Script.typesByVal[type], @@ -2624,17 +2574,17 @@ RPC.prototype.scriptToJSON = function scriptToJSON(script, hex) { }; if (hex) - out.hex = script.toJSON(); + json.hex = script.toJSON(); if (script.isMultisig()) - out.reqSigs = script.getSmall(0); + json.reqSigs = script.getSmall(0); if (addr) { - addr = addr.toString(this.network); - out.addresses.push(addr); + const str = addr.toString(this.network); + json.addresses.push(str); } - return out; + return json; }; RPC.prototype.headerToJSON = async function headerToJSON(entry) { diff --git a/lib/http/server.js b/lib/http/server.js index ba48e2e8..cc47fc06 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -144,12 +144,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const address = valid.str('address'); const result = []; - let coins; enforce(address, 'Address is required.'); enforce(!this.chain.options.spv, 'Cannot get coins in SPV mode.'); - coins = await this.node.getCoinsByAddress(address); + const coins = await this.node.getCoinsByAddress(address); for (const coin of coins) result.push(coin.getJSON(this.network)); @@ -162,13 +161,12 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const hash = valid.hash('hash'); const index = valid.u32('index'); - let coin; enforce(hash, 'Hash is required.'); enforce(index != null, 'Index is required.'); enforce(!this.chain.options.spv, 'Cannot get coins in SPV mode.'); - coin = await this.node.getCoin(hash, index); + const coin = await this.node.getCoin(hash, index); if (!coin) { res.send(404); @@ -183,12 +181,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const address = valid.array('addresses'); const result = []; - let coins; enforce(address, 'Address is required.'); enforce(!this.chain.options.spv, 'Cannot get coins in SPV mode.'); - coins = await this.node.getCoinsByAddress(address); + const coins = await this.node.getCoinsByAddress(address); for (const coin of coins) result.push(coin.getJSON(this.network)); @@ -200,19 +197,18 @@ HTTPServer.prototype.initRouter = function initRouter() { this.get('/tx/:hash', async (req, res) => { const valid = req.valid(); const hash = valid.hash('hash'); - let meta, view; enforce(hash, 'Hash is required.'); enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.'); - meta = await this.node.getMeta(hash); + const meta = await this.node.getMeta(hash); if (!meta) { res.send(404); return; } - view = await this.node.getMetaView(meta); + const view = await this.node.getMetaView(meta); res.send(200, meta.getJSON(this.network, view)); }); @@ -222,12 +218,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const address = valid.str('address'); const result = []; - let metas; enforce(address, 'Address is required.'); enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.'); - metas = await this.node.getMetaByAddress(address); + const metas = await this.node.getMetaByAddress(address); for (const meta of metas) { const view = await this.node.getMetaView(meta); @@ -242,12 +237,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const address = valid.array('address'); const result = []; - let metas; enforce(address, 'Address is required.'); enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.'); - metas = await this.node.getMetaByAddress(address); + const metas = await this.node.getMetaByAddress(address); for (const meta of metas) { const view = await this.node.getMetaView(meta); @@ -261,7 +255,6 @@ HTTPServer.prototype.initRouter = function initRouter() { this.get('/block/:block', async (req, res) => { const valid = req.valid(); let hash = valid.get('block'); - let block, view, height; enforce(typeof hash === 'string', 'Hash or height required.'); enforce(!this.chain.options.spv, 'Cannot get block in SPV mode.'); @@ -271,21 +264,21 @@ HTTPServer.prototype.initRouter = function initRouter() { else hash = +hash; - block = await this.chain.db.getBlock(hash); + const block = await this.chain.db.getBlock(hash); if (!block) { res.send(404); return; } - view = await this.chain.db.getBlockView(block); + const view = await this.chain.db.getBlockView(block); if (!view) { res.send(404); return; } - height = await this.chain.db.getHeight(hash); + const height = await this.chain.db.getHeight(hash); res.send(200, block.getJSON(this.network, view, height)); }); @@ -293,11 +286,10 @@ HTTPServer.prototype.initRouter = function initRouter() { // Mempool snapshot this.get('/mempool', async (req, res) => { const result = []; - let hashes; enforce(this.mempool, 'No mempool available.'); - hashes = this.mempool.getSnapshot(); + const hashes = this.mempool.getSnapshot(); for (const hash of hashes) result.push(util.revHex(hash)); @@ -309,11 +301,10 @@ HTTPServer.prototype.initRouter = function initRouter() { this.post('/broadcast', async (req, res) => { const valid = req.valid(); const raw = valid.buf('tx'); - let tx; enforce(raw, 'TX is required.'); - tx = TX.fromRaw(raw); + const tx = TX.fromRaw(raw); await this.node.sendTX(tx); @@ -324,14 +315,13 @@ HTTPServer.prototype.initRouter = function initRouter() { this.get('/fee', async (req, res) => { const valid = req.valid(); const blocks = valid.u32('blocks'); - let fee; if (!this.fees) { res.send(200, { rate: this.network.feeRate }); return; } - fee = this.fees.estimateFee(blocks); + const fee = this.fees.estimateFee(blocks); res.send(200, { rate: fee }); }); @@ -443,24 +433,23 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) { socket.hook('get entry', async (args) => { const valid = new Validator([args]); const block = valid.numhash(0); - let entry; if (block == null) throw new Error('Invalid parameter.'); - entry = await this.chain.db.getEntry(block); - - if (!(await entry.isMainChain())) - entry = null; + const entry = await this.chain.db.getEntry(block); if (!entry) return null; + if (!(await entry.isMainChain())) + return null; + return entry.toRaw(); }); socket.hook('add filter', (args) => { - let valid = new Validator([args]); + const valid = new Validator([args]); const chunks = valid.array(0); if (!chunks) @@ -469,10 +458,10 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) { if (!socket.filter) throw new Error('No filter set.'); - valid = new Validator([chunks]); + const items = new Validator([chunks]); for (let i = 0; i < chunks.length; i++) { - const data = valid.buf(i); + const data = items.buf(i); if (!data) throw new Error('Bad data chunk.'); @@ -504,12 +493,11 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) { socket.hook('send', (args) => { const valid = new Validator([args]); const data = valid.buf(0); - let tx; if (!data) throw new Error('Invalid parameter.'); - tx = TX.fromRaw(data); + const tx = TX.fromRaw(data); this.node.send(tx); @@ -539,12 +527,11 @@ HTTPServer.prototype.bindChain = function bindChain() { this.chain.on('connect', (entry, block, view) => { const list = this.channel('chain'); - let raw; if (!list) return; - raw = entry.toRaw(); + const raw = entry.toRaw(); this.to('chain', 'chain connect', raw); @@ -557,12 +544,11 @@ HTTPServer.prototype.bindChain = function bindChain() { this.chain.on('disconnect', (entry, block, view) => { const list = this.channel('chain'); - let raw; if (!list) return; - raw = entry.toRaw(); + const raw = entry.toRaw(); this.to('chain', 'chain disconnect', raw); this.to('chain', 'block disconnect', raw); @@ -570,24 +556,22 @@ HTTPServer.prototype.bindChain = function bindChain() { this.chain.on('reset', (tip) => { const list = this.channel('chain'); - let raw; if (!list) return; - raw = tip.toRaw(); + const raw = tip.toRaw(); this.to('chain', 'chain reset', raw); }); pool.on('tx', (tx) => { const list = this.channel('mempool'); - let raw; if (!list) return; - raw = tx.toRaw(); + const raw = tx.toRaw(); for (let item = list.head; item; item = item.next) { const socket = item.value; diff --git a/lib/http/wallet.js b/lib/http/wallet.js index 6c7035d4..a79847c1 100644 --- a/lib/http/wallet.js +++ b/lib/http/wallet.js @@ -123,12 +123,10 @@ HTTPWallet.prototype.open = async function open(options) { */ HTTPWallet.prototype.create = async function create(options) { - let wallet; - await this.client.open(); await this.client.sendWalletAuth(); - wallet = await this.client.createWallet(options); + const wallet = await this.client.createWallet(options); this.id = wallet.id; this.token = wallet.token; diff --git a/lib/mempool/fees.js b/lib/mempool/fees.js index 345d0f11..c5226189 100644 --- a/lib/mempool/fees.js +++ b/lib/mempool/fees.js @@ -133,12 +133,10 @@ ConfirmStats.prototype.clearCurrent = function clearCurrent(height) { */ ConfirmStats.prototype.record = function record(blocks, val) { - let bucketIndex; - if (blocks < 1) return; - bucketIndex = this.bucketMap.search(val); + const bucketIndex = this.bucketMap.search(val); for (let i = blocks; i <= this.curBlockConf.length; i++) this.curBlockConf[i - 1][bucketIndex]++; @@ -173,21 +171,20 @@ ConfirmStats.prototype.updateAverages = function updateAverages() { */ ConfirmStats.prototype.estimateMedian = function estimateMedian(target, needed, breakpoint, greater, height) { - let conf = 0; - let total = 0; - let extra = 0; const max = this.buckets.length - 1; const start = greater ? max : 0; const step = greater ? -1 : 1; + const bins = this.unconfTX.length; + let conf = 0; + let total = 0; + let extra = 0; let near = start; let far = start; let bestNear = start; let bestFar = start; let found = false; - const bins = this.unconfTX.length; let median = -1; let sum = 0; - let minBucket, maxBucket; for (let i = start; i >= 0 && i <= max; i += step) { far = i; @@ -218,8 +215,8 @@ ConfirmStats.prototype.estimateMedian = function estimateMedian(target, needed, } } - minBucket = bestNear < bestFar ? bestNear : bestFar; - maxBucket = bestNear > bestFar ? bestNear : bestFar; + const minBucket = bestNear < bestFar ? bestNear : bestFar; + const maxBucket = bestNear > bestFar ? bestNear : bestFar; for (let i = minBucket; i <= maxBucket; i++) sum += this.txAvg[i]; @@ -540,7 +537,6 @@ PolicyEstimator.prototype.isPriPoint = function isPriPoint(fee, priority) { PolicyEstimator.prototype.processTX = function processTX(entry, current) { const height = entry.height; const hash = entry.hash('hex'); - let fee, rate, priority, item; if (this.map.has(hash)) { this.logger.debug('Mempool tx %s already tracked.', entry.txid()); @@ -559,28 +555,25 @@ PolicyEstimator.prototype.processTX = function processTX(entry, current) { if (entry.dependencies) return; - fee = entry.getFee(); - rate = entry.getRate(); - priority = entry.getPriority(height); + const fee = entry.getFee(); + const rate = entry.getRate(); + const priority = entry.getPriority(height); this.logger.spam('Processing mempool tx %s.', entry.txid()); if (fee === 0 || this.isPriPoint(rate, priority)) { - item = new StatEntry(); + const item = new StatEntry(); item.blockHeight = height; item.bucketIndex = this.priStats.addTX(height, priority); + this.map.set(hash, item); } else if (this.isFeePoint(rate, priority)) { - item = new StatEntry(); + const item = new StatEntry(); item.blockHeight = height; item.bucketIndex = this.feeStats.addTX(height, rate); - } - - if (!item) { + this.map.set(hash, item); + } else { this.logger.spam('Not adding tx %s.', entry.txid()); - return; } - - this.map.set(hash, item); }; /** @@ -590,13 +583,11 @@ PolicyEstimator.prototype.processTX = function processTX(entry, current) { */ PolicyEstimator.prototype.processBlockTX = function processBlockTX(height, entry) { - let blocks, fee, rate, priority; - // Requires other mempool txs in order to be confirmed. Ignore. if (entry.dependencies) return; - blocks = height - entry.height; + const blocks = height - entry.height; if (blocks <= 0) { this.logger.debug( @@ -607,9 +598,9 @@ PolicyEstimator.prototype.processBlockTX = function processBlockTX(height, entry return; } - fee = entry.getFee(); - rate = entry.getRate(); - priority = entry.getPriority(height); + const fee = entry.getFee(); + const rate = entry.getRate(); + const priority = entry.getPriority(height); if (fee === 0 || this.isPriPoint(rate, priority)) this.priStats.record(blocks, priority); @@ -692,8 +683,6 @@ PolicyEstimator.prototype.processBlock = function processBlock(height, entries, */ PolicyEstimator.prototype.estimateFee = function estimateFee(target, smart) { - let rate; - if (!target) target = 1; @@ -715,7 +704,7 @@ PolicyEstimator.prototype.estimateFee = function estimateFee(target, smart) { return Math.floor(rate); } - rate = -1; + let rate = -1; while (rate < 0 && target <= this.feeStats.maxConfirms) { rate = this.feeStats.estimateMedian( target++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, @@ -738,8 +727,6 @@ PolicyEstimator.prototype.estimateFee = function estimateFee(target, smart) { */ PolicyEstimator.prototype.estimatePriority = function estimatePriority(target, smart) { - let priority; - if (!target) target = 1; @@ -751,13 +738,13 @@ PolicyEstimator.prototype.estimatePriority = function estimatePriority(target, s 'Too many confirmations for estimate.'); if (!smart) { - priority = this.priStats.estimateMedian( + const priority = this.priStats.estimateMedian( target, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, this.bestHeight); return Math.floor(priority); } - priority = -1; + let priority = -1; while (priority < 0 && target <= this.priStats.maxConfirms) { priority = this.priStats.estimateMedian( target++, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index 414004ce..45f42ad8 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -185,14 +185,12 @@ Mempool.prototype.addBlock = async function addBlock(block, txs) { */ Mempool.prototype._addBlock = async function addBlock(block, txs) { - let entries; - if (this.map.size === 0) { this.tip = block.hash; return; } - entries = []; + const entries = []; for (let i = txs.length - 1; i >= 1; i--) { const tx = txs[i]; @@ -265,13 +263,13 @@ Mempool.prototype.removeBlock = async function removeBlock(block, txs) { */ Mempool.prototype._removeBlock = async function removeBlock(block, txs) { - let total = 0; - if (this.map.size === 0) { this.tip = block.prevBlock; return; } + let total = 0; + for (let i = 1; i < txs.length; i++) { const tx = txs[i]; const hash = tx.hash('hex'); @@ -365,14 +363,13 @@ Mempool.prototype.limitSize = function limitSize(added) { const maxSize = this.options.maxSize; const threshold = maxSize - (maxSize / 10); const expiryTime = this.options.expiryTime; - const now = util.now(); - let queue, start; if (this.size <= maxSize) return false; - start = util.hrtime(); - queue = new Heap(cmpRate); + const now = util.now(); + let start = util.hrtime(); + const queue = new Heap(cmpRate); for (const entry of this.map.values()) { if (this.hasDepends(entry.tx)) @@ -592,12 +589,11 @@ Mempool.prototype.getMetaByAddress = function getMetaByAddress(addrs) { Mempool.prototype.getMeta = function getMeta(hash) { const entry = this.getEntry(hash); - let meta; if (!entry) return; - meta = TXMeta.fromTX(entry.tx); + const meta = TXMeta.fromTX(entry.tx); meta.mtime = entry.time; return meta; @@ -722,17 +718,16 @@ Mempool.prototype._addTX = async function _addTX(tx, id) { */ Mempool.prototype.insertTX = async function insertTX(tx, id) { + assert(!tx.mutable, 'Cannot add mutable TX to mempool.'); + const lockFlags = common.lockFlags.STANDARD_LOCKTIME_FLAGS; const height = this.chain.height; const hash = tx.hash('hex'); - let valid, reason, score, entry, view, missing; - - assert(!tx.mutable, 'Cannot add mutable TX to mempool.'); // Basic sanity checks. // This is important because it ensures // other functions will be overflow safe. - [valid, reason, score] = tx.checkSanity(); + const [valid, reason, score] = tx.checkSanity(); if (!valid) throw new VerifyError(tx, 'invalid', reason, score); @@ -823,10 +818,10 @@ Mempool.prototype.insertTX = async function insertTX(tx, id) { // Get coin viewpoint as it // pertains to the mempool. - view = await this.getCoinView(tx); + const view = await this.getCoinView(tx); // Find missing outpoints. - missing = this.findMissing(tx, view); + const missing = this.findMissing(tx, view); // Maybe store as an orphan. if (missing) @@ -834,7 +829,7 @@ Mempool.prototype.insertTX = async function insertTX(tx, id) { // Create a new mempool entry // at current chain height. - entry = MempoolEntry.fromTX(tx, view, height); + const entry = MempoolEntry.fromTX(tx, view, height); // Contextual verification. await this.verify(entry, view); @@ -866,7 +861,6 @@ Mempool.prototype.verify = async function verify(entry, view) { const lockFlags = common.lockFlags.STANDARD_LOCKTIME_FLAGS; let flags = Script.flags.STANDARD_VERIFY_FLAGS; const tx = entry.tx; - let fee, reason, score, minFee; // Verify sequence locks. if (!(await this.verifyLocks(tx, view, lockFlags))) { @@ -904,7 +898,7 @@ Mempool.prototype.verify = async function verify(entry, view) { } // Make sure this guy gave a decent fee. - minFee = policy.getMinFee(entry.size, this.options.minRelay); + const minFee = policy.getMinFee(entry.size, this.options.minRelay); if (this.options.relayPriority && entry.fee < minFee) { if (!entry.isFree(height)) { @@ -949,7 +943,7 @@ Mempool.prototype.verify = async function verify(entry, view) { } // Contextual sanity checks. - [fee, reason, score] = tx.checkInputs(view, height); + const [fee, reason, score] = tx.checkInputs(view, height); if (fee === -1) throw new VerifyError(tx, 'invalid', reason, score); @@ -958,28 +952,28 @@ Mempool.prototype.verify = async function verify(entry, view) { try { await this.verifyInputs(tx, view, flags); } catch (err) { - let valid; - if (tx.hasWitness()) throw err; // Try without segwit and cleanstack. flags &= ~Script.flags.VERIFY_WITNESS; flags &= ~Script.flags.VERIFY_CLEANSTACK; - valid = await this.verifyResult(tx, view, flags); + + const valid1 = await this.verifyResult(tx, view, flags); // If it failed, the first verification // was the only result we needed. - if (!valid) + if (!valid1) throw err; // If it succeeded, segwit may be causing the // failure. Try with segwit but without cleanstack. flags |= Script.flags.VERIFY_CLEANSTACK; - valid = await this.verifyResult(tx, view, flags); + + const valid2 = await this.verifyResult(tx, view, flags); // Cleanstack was causing the failure. - if (valid) + if (valid2) throw err; // Do not insert into reject cache. @@ -989,9 +983,8 @@ Mempool.prototype.verify = async function verify(entry, view) { // Paranoid checks. if (this.options.paranoidChecks) { - let valid; - flags = Script.flags.MANDATORY_VERIFY_FLAGS; - valid = await this.verifyResult(tx, view, flags); + const flags = Script.flags.MANDATORY_VERIFY_FLAGS; + const valid = await this.verifyResult(tx, view, flags); assert(valid, 'BUG: Verify failed for mandatory but not standard.'); } }; @@ -1225,12 +1218,11 @@ Mempool.prototype._countDescendants = function countDescendants(entry, set) { for (let i = 0; i < tx.outputs.length; i++) { const child = this.getSpent(hash, i); - let next; if (!child) continue; - next = child.hash('hex'); + const next = child.hash('hex'); if (set.has(next)) continue; @@ -1308,12 +1300,11 @@ Mempool.prototype._getDescendants = function getDescendants(entry, entries, set) for (let i = 0; i < tx.outputs.length; i++) { const child = this.getSpent(hash, i); - let next; if (!child) continue; - next = child.hash('hex'); + const next = child.hash('hex'); if (set.has(next)) continue; @@ -1592,12 +1583,11 @@ Mempool.prototype.removeOrphan = function removeOrphan(hash) { */ Mempool.prototype.limitOrphans = function limitOrphans() { - let index, hash; - if (this.orphans.size < this.options.maxOrphans) return false; - index = random.randomRange(0, this.orphans.size); + let index = random.randomRange(0, this.orphans.size); + let hash = null; for (hash of this.orphans.keys()) { if (index === 0) @@ -1605,6 +1595,8 @@ Mempool.prototype.limitOrphans = function limitOrphans() { index--; } + assert(hash); + this.logger.debug('Removing orphan %s from mempool.', util.revHex(hash)); this.removeOrphan(hash); @@ -1660,14 +1652,13 @@ Mempool.prototype.getCoinView = async function getCoinView(tx) { for (const {prevout} of tx.inputs) { const entry = this.getEntry(prevout.hash); - let coin; if (entry) { view.addTX(entry.tx, -1); continue; } - coin = await this.chain.db.readCoin(prevout); + const coin = await this.chain.db.readCoin(prevout); if (!coin) { const coins = new Coins(); @@ -2231,19 +2222,18 @@ CoinIndex.prototype.insert = function insert(tx, index) { const output = tx.outputs[index]; const hash = tx.hash('hex'); const addr = output.getHash('hex'); - let items, key; if (!addr) return; - items = this.index.get(addr); + let items = this.index.get(addr); if (!items) { items = new Map(); this.index.set(addr, items); } - key = Outpoint.toKey(hash, index); + const key = Outpoint.toKey(hash, index); assert(!items.has(key)); items.set(key, new IndexedCoin(tx, index)); @@ -2254,12 +2244,11 @@ CoinIndex.prototype.insert = function insert(tx, index) { CoinIndex.prototype.remove = function remove(hash, index) { const key = Outpoint.toKey(hash, index); const addr = this.map.get(key); - let items; if (!addr) return; - items = this.index.get(addr); + const items = this.index.get(addr); assert(items); assert(items.has(key)); diff --git a/lib/mining/cpuminer.js b/lib/mining/cpuminer.js index 9fe6f1ed..9abc0fa0 100644 --- a/lib/mining/cpuminer.js +++ b/lib/mining/cpuminer.js @@ -108,16 +108,12 @@ CPUMiner.prototype.start = function start() { */ CPUMiner.prototype._start = async function start() { - let job; - assert(!this.running, 'Miner is already running.'); this.running = true; this.stopping = false; for (;;) { - let block, entry; - this.job = null; try { @@ -132,6 +128,8 @@ CPUMiner.prototype._start = async function start() { if (this.stopping) break; + let block = null; + try { block = await this.mineAsync(this.job); } catch (e) { @@ -147,6 +145,8 @@ CPUMiner.prototype._start = async function start() { if (!block) continue; + let entry = null; + try { entry = await this.chain.add(block); } catch (e) { @@ -178,7 +178,7 @@ CPUMiner.prototype._start = async function start() { this.emit('block', block, entry); } - job = this.stopJob; + const job = this.stopJob; if (job) { this.stopJob = null; @@ -473,12 +473,11 @@ CPUJob.prototype.commit = function commit(nonce) { const n1 = this.nonce1; const n2 = this.nonce2; const time = attempt.time; - let proof; assert(!this.committed, 'Job already committed.'); this.committed = true; - proof = attempt.getProof(n1, n2, time, nonce); + const proof = attempt.getProof(n1, n2, time, nonce); return attempt.commit(proof); }; diff --git a/lib/mining/miner.js b/lib/mining/miner.js index 6875838a..55d2b4b4 100644 --- a/lib/mining/miner.js +++ b/lib/mining/miner.js @@ -122,7 +122,6 @@ Miner.prototype.createBlock = async function createBlock(tip, address) { Miner.prototype._createBlock = async function createBlock(tip, address) { let version = this.options.version; - let time, mtp, locktime, target, attempt, state; if (!tip) tip = this.chain.tip; @@ -133,18 +132,15 @@ Miner.prototype._createBlock = async function createBlock(tip, address) { if (version === -1) version = await this.chain.computeBlockVersion(tip); - mtp = await tip.getMedianTime(); - time = Math.max(this.network.now(), mtp + 1); - locktime = time; + const mtp = await tip.getMedianTime(); + const time = Math.max(this.network.now(), mtp + 1); - state = await this.chain.getDeployments(time, tip); + const state = await this.chain.getDeployments(time, tip); + const target = await this.chain.getTarget(time, tip); - if (state.hasMTP()) - locktime = mtp; + const locktime = state.hasMTP() ? mtp : time; - target = await this.chain.getTarget(time, tip); - - attempt = new BlockTemplate({ + const attempt = new BlockTemplate({ prevBlock: tip.hash, height: tip.height + 1, version: version, @@ -302,7 +298,6 @@ Miner.prototype.assemble = function assemble(attempt) { const hash = item.hash; let weight = attempt.weight; let sigops = attempt.sigops; - let deps; if (!tx.isFinal(attempt.height, attempt.locktime)) continue; @@ -339,7 +334,7 @@ Miner.prototype.assemble = function assemble(attempt) { attempt.fees += item.fee; attempt.items.push(item); - deps = depMap.get(hash); + const deps = depMap.get(hash); if (!deps) continue; diff --git a/lib/mining/template.js b/lib/mining/template.js index 433b998d..2f3a9644 100644 --- a/lib/mining/template.js +++ b/lib/mining/template.js @@ -173,14 +173,13 @@ BlockTemplate.fromOptions = function fromOptions(options) { BlockTemplate.prototype.getWitnessHash = function getWitnessHash() { const nonce = encoding.ZERO_HASH; const leaves = []; - let root, malleated; leaves.push(encoding.ZERO_HASH); for (const item of this.items) leaves.push(item.tx.witnessHash()); - [root, malleated] = merkle.createRoot(leaves); + const [root, malleated] = merkle.createRoot(leaves); assert(!malleated); @@ -237,11 +236,9 @@ BlockTemplate.prototype.getReward = function getReward() { BlockTemplate.prototype.createCoinbase = function createCoinbase(hash) { const scale = consensus.WITNESS_SCALE_FACTOR; const cb = new TX(); - let padding = 0; - let input, output, commit; // Coinbase input. - input = new Input(); + const input = new Input(); // Height (required in v2+ blocks) input.script.push(new BN(this.height)); @@ -267,7 +264,7 @@ BlockTemplate.prototype.createCoinbase = function createCoinbase(hash) { cb.inputs.push(input); // Reward output. - output = new Output(); + const output = new Output(); output.script.fromPubkeyhash(encoding.ZERO_HASH160); output.value = this.getReward(); @@ -277,13 +274,13 @@ BlockTemplate.prototype.createCoinbase = function createCoinbase(hash) { // need to set up the commitment. if (this.witness) { // Commitment output. - commit = new Output(); + const commit = new Output(); commit.script.fromCommitment(hash); cb.outputs.push(commit); } // Padding for the CB height (constant size). - padding = 5 - input.script.code[0].getSize(); + const padding = 5 - input.script.code[0].getSize(); assert(padding >= 0); // Reserved size. @@ -332,7 +329,6 @@ BlockTemplate.prototype.refresh = function refresh() { const cb = this.createCoinbase(hash); const raw = cb.toNormal(); let size = 0; - let left, right; size += 4; // version size += 1; // varint inputs length @@ -341,11 +337,11 @@ BlockTemplate.prototype.refresh = function refresh() { // Cut off right after the nonce // push and before the sequence. - left = raw.slice(0, size); + const left = raw.slice(0, size); // Include the sequence. size += 4 + 4; // nonce1 + nonce2 - right = raw.slice(size); + const right = raw.slice(size); this.commitment = hash; this.left = left; @@ -362,13 +358,12 @@ BlockTemplate.prototype.refresh = function refresh() { BlockTemplate.prototype.getRawCoinbase = function getRawCoinbase(nonce1, nonce2) { let size = 0; - let bw; size += this.left.length; size += 4 + 4; size += this.right.length; - bw = new StaticWriter(size); + const bw = new StaticWriter(size); bw.writeBytes(this.left); bw.writeU32BE(nonce1); bw.writeU32BE(nonce2); @@ -437,10 +432,9 @@ BlockTemplate.prototype.getProof = function getProof(nonce1, nonce2, time, nonce BlockTemplate.prototype.getCoinbase = function getCoinbase(nonce1, nonce2) { const raw = this.getRawCoinbase(nonce1, nonce2); const tx = TX.fromRaw(raw); - let input; if (this.witness) { - input = tx.inputs[0]; + const input = tx.inputs[0]; input.witness.push(encoding.ZERO_HASH); input.witness.compile(); tx.refresh(); @@ -462,7 +456,6 @@ BlockTemplate.prototype.commit = function commit(proof) { const time = proof.time; const nonce = proof.nonce; const block = new Block(); - let tx; block.version = this.version; block.prevBlock = this.prevBlock; @@ -471,7 +464,7 @@ BlockTemplate.prototype.commit = function commit(proof) { block.bits = this.bits; block.nonce = nonce; - tx = this.getCoinbase(n1, n2); + const tx = this.getCoinbase(n1, n2); block.txs.push(tx); @@ -529,13 +522,11 @@ BlockTemplate.prototype.setAddress = function setAddress(address) { */ BlockTemplate.prototype.addTX = function addTX(tx, view) { - let item, weight, sigops; - assert(!tx.mutable, 'Cannot add mutable TX to block.'); - item = BlockEntry.fromTX(tx, view, this); - weight = item.tx.getWeight(); - sigops = item.sigops; + const item = BlockEntry.fromTX(tx, view, this); + const weight = item.tx.getWeight(); + const sigops = item.sigops; if (!tx.isFinal(this.height, this.locktime)) return false; @@ -567,16 +558,14 @@ BlockTemplate.prototype.addTX = function addTX(tx, view) { */ BlockTemplate.prototype.pushTX = function pushTX(tx, view) { - let item, weight, sigops; - assert(!tx.mutable, 'Cannot add mutable TX to block.'); if (!view) view = new CoinView(); - item = BlockEntry.fromTX(tx, view, this); - weight = item.tx.getWeight(); - sigops = item.sigops; + const item = BlockEntry.fromTX(tx, view, this); + const weight = item.tx.getWeight(); + const sigops = item.sigops; this.weight += weight; this.sigops += sigops; diff --git a/lib/net/bip150.js b/lib/net/bip150.js index e762eb76..5cab81d0 100644 --- a/lib/net/bip150.js +++ b/lib/net/bip150.js @@ -122,7 +122,6 @@ BIP150.prototype.isAuthed = function isAuthed() { BIP150.prototype.challenge = function challenge(hash) { const type = this.outbound ? 'r' : 'i'; - let msg, sig; assert(this.bip151.handshake, 'No BIP151 handshake before challenge.'); assert(!this.challengeReceived, 'Peer challenged twice.'); @@ -131,7 +130,7 @@ BIP150.prototype.challenge = function challenge(hash) { if (hash.equals(encoding.ZERO_HASH)) throw new Error('Auth failure.'); - msg = this.hash(this.input.sid, type, this.publicKey); + const msg = this.hash(this.input.sid, type, this.publicKey); if (!ccmp(hash, msg)) return encoding.ZERO_SIG64; @@ -141,7 +140,7 @@ BIP150.prototype.challenge = function challenge(hash) { this.emit('auth'); } - sig = secp256k1.sign(msg, this.privateKey); + const sig = secp256k1.sign(msg, this.privateKey); // authreply return secp256k1.fromDER(sig); @@ -157,7 +156,6 @@ BIP150.prototype.challenge = function challenge(hash) { BIP150.prototype.reply = function reply(data) { const type = this.outbound ? 'i' : 'r'; - let sig, msg, result; assert(this.challengeSent, 'Unsolicited reply.'); assert(!this.replyReceived, 'Peer replied twice.'); @@ -169,10 +167,10 @@ BIP150.prototype.reply = function reply(data) { if (!this.peerIdentity) return random.randomBytes(32); - sig = secp256k1.toDER(data); - msg = this.hash(this.output.sid, type, this.peerIdentity); + const sig = secp256k1.toDER(data); + const msg = this.hash(this.output.sid, type, this.peerIdentity); - result = secp256k1.verify(msg, sig, this.peerIdentity); + const result = secp256k1.verify(msg, sig, this.peerIdentity); if (!result) return random.randomBytes(32); @@ -197,14 +195,12 @@ BIP150.prototype.reply = function reply(data) { */ BIP150.prototype.propose = function propose(hash) { - let match; - assert(!this.outbound, 'Outbound peer tried to propose.'); assert(!this.challengeSent, 'Unsolicited propose.'); assert(!this.proposeReceived, 'Peer proposed twice.'); this.proposeReceived = true; - match = this.findAuthorized(hash); + const match = this.findAuthorized(hash); if (!match) return encoding.ZERO_HASH; @@ -228,13 +224,11 @@ BIP150.prototype.propose = function propose(hash) { */ BIP150.prototype.toChallenge = function toChallenge() { - let msg; - assert(this.bip151.handshake, 'No BIP151 handshake before challenge.'); assert(this.outbound, 'Cannot challenge an inbound connection.'); assert(this.peerIdentity, 'Cannot challenge without a peer identity.'); - msg = this.hash(this.output.sid, 'i', this.peerIdentity); + const msg = this.hash(this.output.sid, 'i', this.peerIdentity); assert(!this.challengeSent, 'Cannot initiate challenge twice.'); this.challengeSent = true; @@ -540,15 +534,13 @@ AuthDB.prototype.close = async function close() { */ AuthDB.prototype.addKnown = function addKnown(host, key) { - let addr; - assert(typeof host === 'string', 'Known host must be a string.'); assert(Buffer.isBuffer(key) && key.length === 33, 'Invalid public key for known peer.'); - addr = IP.fromHostname(host); + const addr = IP.fromHostname(host); if (addr.type === IP.types.DNS) { // Defer this for resolution. @@ -604,12 +596,11 @@ AuthDB.prototype.setAuthorized = function setAuthorized(keys) { AuthDB.prototype.getKnown = function getKnown(hostname) { const known = this.known.get(hostname); - let addr; if (known) return known; - addr = IP.fromHostname(hostname); + const addr = IP.fromHostname(hostname); return this.known.get(addr.host); }; @@ -667,15 +658,14 @@ AuthDB.prototype.populate = async function populate(addr, key) { */ AuthDB.prototype.readKnown = async function readKnown() { - let file, text; - if (fs.unsupported) return; if (!this.prefix) return; - file = path.join(this.prefix, 'known-peers'); + const file = path.join(this.prefix, 'known-peers'); + let text; try { text = await fs.readFile(file, 'utf8'); @@ -698,8 +688,6 @@ AuthDB.prototype.parseKnown = function parseKnown(text) { const lines = text.split(/\n+/); for (let line of lines) { - let parts, hostname, host, ip, key; - line = line.trim(); if (line.length === 0) @@ -708,12 +696,13 @@ AuthDB.prototype.parseKnown = function parseKnown(text) { if (/^\s*#/.test(line)) continue; - parts = line.split(/\s+/); + const parts = line.split(/\s+/); if (parts.length < 2) continue; - hostname = parts[0].trim().split(','); + const hostname = parts[0].trim().split(','); + let host, ip; if (hostname.length >= 2) { host = hostname[0]; @@ -723,8 +712,8 @@ AuthDB.prototype.parseKnown = function parseKnown(text) { ip = hostname[0]; } - key = parts[1].trim(); - key = Buffer.from(key, 'hex'); + const hex = parts[1].trim(); + const key = Buffer.from(hex, 'hex'); if (key.length !== 33) throw new Error(`Invalid key: ${parts[1]}.`); @@ -746,15 +735,14 @@ AuthDB.prototype.parseKnown = function parseKnown(text) { */ AuthDB.prototype.readAuth = async function readAuth() { - let file, text; - if (fs.unsupported) return; if (!this.prefix) return; - file = path.join(this.prefix, 'authorized-peers'); + const file = path.join(this.prefix, 'authorized-peers'); + let text; try { text = await fs.readFile(file, 'utf8'); @@ -777,8 +765,6 @@ AuthDB.prototype.parseAuth = function parseAuth(text) { const lines = text.split(/\n+/); for (let line of lines) { - let key; - line = line.trim(); if (line.length === 0) @@ -787,7 +773,7 @@ AuthDB.prototype.parseAuth = function parseAuth(text) { if (/^\s*#/.test(line)) continue; - key = Buffer.from(line, 'hex'); + const key = Buffer.from(line, 'hex'); if (key.length !== 33) throw new Error(`Invalid key: ${line}.`); diff --git a/lib/net/bip151.js b/lib/net/bip151.js index a1ea5cf5..22d7139b 100644 --- a/lib/net/bip151.js +++ b/lib/net/bip151.js @@ -599,7 +599,6 @@ BIP151.prototype.packet = function _packet(cmd, body) { const size = this.packetSize(cmd, body); const bw = new StaticWriter(size); const payloadSize = size - 20; - let packet, payload; bw.writeU32(payloadSize); bw.writeVarString(cmd, 'ascii'); @@ -607,8 +606,8 @@ BIP151.prototype.packet = function _packet(cmd, body) { bw.writeBytes(body); bw.seek(16); - packet = bw.render(); - payload = packet.slice(4, 4 + payloadSize); + const packet = bw.render(); + const payload = packet.slice(4, 4 + payloadSize); this.maybeRekey(packet); @@ -645,35 +644,32 @@ BIP151.prototype.feed = function feed(data) { */ BIP151.prototype.read = function read(size) { - let pending, chunk, off, len; - assert(this.total >= size, 'Reading too much.'); if (size === 0) return Buffer.alloc(0); - pending = this.pending[0]; + const pending = this.pending[0]; if (pending.length > size) { - chunk = pending.slice(0, size); + const chunk = pending.slice(0, size); this.pending[0] = pending.slice(size); this.total -= chunk.length; return chunk; } if (pending.length === size) { - chunk = this.pending.shift(); + const chunk = this.pending.shift(); this.total -= chunk.length; return chunk; } - chunk = Buffer.allocUnsafe(size); - off = 0; - len = 0; + const chunk = Buffer.allocUnsafe(size); + let off = 0; while (off < chunk.length) { - pending = this.pending[0]; - len = pending.copy(chunk, off); + const pending = this.pending[0]; + const len = pending.copy(chunk, off); if (len === pending.length) this.pending.shift(); else @@ -695,8 +691,6 @@ BIP151.prototype.read = function read(size) { */ BIP151.prototype.parse = function parse(data) { - let payload, tag, br; - if (!this.hasSize) { const size = this.input.decryptSize(data); @@ -720,8 +714,8 @@ BIP151.prototype.parse = function parse(data) { return; } - payload = data.slice(0, this.waiting - 16); - tag = data.slice(this.waiting - 16, this.waiting); + const payload = data.slice(0, this.waiting - 16); + const tag = data.slice(this.waiting - 16, this.waiting); this.hasSize = false; this.waiting = 4; @@ -741,7 +735,7 @@ BIP151.prototype.parse = function parse(data) { this.input.decrypt(payload); this.input.sequence(); - br = new BufferReader(payload); + const br = new BufferReader(payload); while (br.left()) { let cmd, body; diff --git a/lib/net/bip152.js b/lib/net/bip152.js index c023c57d..090fb613 100644 --- a/lib/net/bip152.js +++ b/lib/net/bip152.js @@ -122,32 +122,30 @@ CompactBlock.prototype.verifyBody = function verifyBody() { CompactBlock.prototype.fromRaw = function fromRaw(data) { const br = new BufferReader(data); - let count; this.readHead(br); this.keyNonce = br.readBytes(8); this.sipKey = this.getKey(); - count = br.readVarint(); + const idCount = br.readVarint(); - this.totalTX += count; + this.totalTX += idCount; - for (let i = 0; i < count; i++) + for (let i = 0; i < idCount; i++) this.ids.push(br.readU32() + br.readU16() * 0x100000000); - count = br.readVarint(); + const txCount = br.readVarint(); - this.totalTX += count; + this.totalTX += txCount; - for (let i = 0; i < count; i++) { + for (let i = 0; i < txCount; i++) { const index = br.readVarint(); - let tx; assert(index <= 0xffff); assert(index < this.totalTX); - tx = TX.fromReader(br); + const tx = TX.fromReader(br); this.ptx.push([index, tx]); } @@ -299,22 +297,19 @@ CompactBlock.prototype.toRequest = function toRequest() { */ CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) { - let have; - if (this.count === this.totalTX) return true; - have = new Set(); + const have = new Set(); for (const {tx} of mempool.map.values()) { let hash = tx.hash(); - let id, index; if (witness) hash = tx.witnessHash(); - id = this.sid(hash); - index = this.idMap.get(id); + const id = this.sid(hash); + const index = this.idMap.get(id); if (index == null) continue; @@ -368,12 +363,10 @@ CompactBlock.prototype.fillMissing = function fillMissing(res) { */ CompactBlock.prototype.sid = function sid(hash) { - let hi, lo; - if (typeof hash === 'string') hash = Buffer.from(hash, 'hex'); - [hi, lo] = siphash256(hash, this.sipKey); + const [hi, lo] = siphash256(hash, this.sipKey); return (hi & 0xffff) * 0x100000000 + (lo >>> 0); }; @@ -406,9 +399,6 @@ CompactBlock.prototype.getKey = function getKey() { */ CompactBlock.prototype.init = function init() { - let last = -1; - let offset = 0; - if (this.totalTX === 0) throw new Error('Empty vectors.'); @@ -426,6 +416,9 @@ CompactBlock.prototype.init = function init() { for (let i = 0; i < this.totalTX; i++) this.available.push(null); + let last = -1; + let offset = 0; + for (let i = 0; i < this.ptx.length; i++) { const [index, tx] = this.ptx[i]; last += index + 1; @@ -506,12 +499,11 @@ CompactBlock.prototype.fromBlock = function fromBlock(block, witness, nonce) { for (let i = 1; i < block.txs.length; i++) { const tx = block.txs[i]; let hash = tx.hash(); - let id; if (witness) hash = tx.witnessHash(); - id = this.sid(hash); + const id = this.sid(hash); this.ids.push(id); } @@ -624,12 +616,10 @@ TXRequest.fromCompact = function fromCompact(block) { */ TXRequest.prototype.fromReader = function fromReader(br) { - let offset = 0; - let count; - this.hash = br.readHash('hex'); - count = br.readVarint(); + const count = br.readVarint(); + let offset = 0; for (let i = 0; i < count; i++) { const index = br.readVarint(); @@ -788,11 +778,9 @@ TXResponse.fromOptions = function fromOptions(options) { */ TXResponse.prototype.fromReader = function fromReader(br) { - let count; - this.hash = br.readHash('hex'); - count = br.readVarint(); + const count = br.readVarint(); for (let i = 0; i < count; i++) this.txs.push(TX.fromReader(br)); diff --git a/lib/net/external.js b/lib/net/external.js index 82b59276..37510dbc 100644 --- a/lib/net/external.js +++ b/lib/net/external.js @@ -22,7 +22,7 @@ const external = exports; */ external.getIPv4 = async function getIPv4() { - let res, ip; + let res = null; try { res = await request({ @@ -35,14 +35,16 @@ external.getIPv4 = async function getIPv4() { return await external.getIPv42(); } - try { - ip = res.body.trim(); - ip = IP.toBuffer(ip); + let ip = null; - if (!IP.isIPv4(ip)) + 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(ip); + ip = IP.toString(raw); } catch (e) { return await external.getIPv42(); } @@ -58,22 +60,20 @@ external.getIPv4 = async function getIPv4() { */ external.getIPv42 = async function getIPv42() { - let res, match, ip, raw; - - res = await request({ + const res = await request({ method: 'GET', uri: 'http://checkip.dyndns.org', expect: 'html', timeout: 2000 }); - match = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body); + const match = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body); if (!match) throw new Error('Could not find IPv4.'); - ip = match[1]; - raw = IP.toBuffer(ip); + const str = match[1]; + const raw = IP.toBuffer(str); if (!IP.isIPv4(raw)) throw new Error('Could not find IPv4.'); @@ -88,20 +88,18 @@ external.getIPv42 = async function getIPv42() { */ external.getIPv6 = async function getIPv6() { - let res, ip; - - res = await request({ + const res = await request({ method: 'GET', uri: 'http://ipv6.icanhazip.com', expect: 'txt', timeout: 2000 }); - ip = res.body.trim(); - ip = IP.toBuffer(ip); + const str = res.body.trim(); + const raw = IP.toBuffer(str); - if (!IP.isIPv6(ip)) + if (!IP.isIPv6(raw)) throw new Error('Could not find IPv6.'); - return IP.toString(ip); + return IP.toString(raw); }; diff --git a/lib/net/framer.js b/lib/net/framer.js index d1774332..1be307de 100644 --- a/lib/net/framer.js +++ b/lib/net/framer.js @@ -33,14 +33,11 @@ function Framer(network) { */ Framer.prototype.packet = function _packet(cmd, payload, checksum) { - let packet; - assert(payload, 'No payload.'); - assert(cmd.length < 12); assert(payload.length <= 0xffffffff); - packet = Buffer.allocUnsafe(24 + payload.length); + const packet = Buffer.allocUnsafe(24 + payload.length); // Magic value packet.writeUInt32LE(this.network.magic, 0, true); diff --git a/lib/net/hostlist.js b/lib/net/hostlist.js index 8e33a35c..a7561b50 100644 --- a/lib/net/hostlist.js +++ b/lib/net/hostlist.js @@ -253,7 +253,6 @@ HostList.prototype.injectSeeds = function injectSeeds() { HostList.prototype.loadFile = async function loadFile() { const filename = this.options.filename; - let data, json; if (fs.unsupported) return; @@ -264,6 +263,7 @@ HostList.prototype.loadFile = async function loadFile() { if (!filename) return; + let data; try { data = await fs.readFile(filename, 'utf8'); } catch (e) { @@ -272,7 +272,7 @@ HostList.prototype.loadFile = async function loadFile() { throw e; } - json = JSON.parse(data); + const json = JSON.parse(data); this.fromJSON(json); }; @@ -285,7 +285,6 @@ HostList.prototype.loadFile = async function loadFile() { HostList.prototype.flush = async function flush() { const filename = this.options.filename; - let json, data; if (fs.unsupported) return; @@ -303,8 +302,8 @@ HostList.prototype.flush = async function flush() { this.logger.debug('Writing hosts to %s.', filename); - json = this.toJSON(); - data = JSON.stringify(json); + const json = this.toJSON(); + const data = JSON.stringify(json); try { await fs.writeFile(filename, data, 'utf8'); @@ -422,13 +421,13 @@ HostList.prototype.getHost = function getHost() { for (;;) { let index = util.random(0, buckets.length); const bucket = buckets[index]; - let entry, num; if (bucket.size === 0) continue; index = util.random(0, bucket.size); + let entry; if (buckets === this.used) { entry = bucket.head; while (index--) @@ -441,7 +440,7 @@ HostList.prototype.getHost = function getHost() { } } - num = util.random(0, 1 << 30); + const num = util.random(0, 1 << 30); if (num < factor * entry.chance(now) * (1 << 30)) return entry; @@ -488,17 +487,15 @@ HostList.prototype.usedBucket = function usedBucket(entry) { */ HostList.prototype.add = function add(addr, src) { - const now = this.network.now(); - let penalty = 2 * 60 * 60; - let interval = 24 * 60 * 60; - let factor = 1; - let entry, bucket; - assert(addr.port !== 0); - entry = this.map.get(addr.hostname); + let entry = this.map.get(addr.hostname); if (entry) { + const now = this.network.now(); + let penalty = 2 * 60 * 60; + let interval = 24 * 60 * 60; + // No source means we're inserting // this ourselves. No penalty. if (!src) @@ -539,6 +536,7 @@ HostList.prototype.add = function add(addr, src) { // Stochastic test: previous refCount // N: 2^N times harder to increase it. + let factor = 1; for (let i = 0; i < entry.refCount; i++) factor *= 2; @@ -556,7 +554,7 @@ HostList.prototype.add = function add(addr, src) { this.totalFresh++; } - bucket = this.freshBucket(entry); + const bucket = this.freshBucket(entry); if (bucket.has(entry.key())) return false; @@ -579,7 +577,7 @@ HostList.prototype.add = function add(addr, src) { */ HostList.prototype.evictFresh = function evictFresh(bucket) { - let old; + let old = null; for (const entry of bucket.values()) { if (this.isStale(entry)) { @@ -730,12 +728,12 @@ HostList.prototype.markSuccess = function markSuccess(hostname) { HostList.prototype.markAck = function markAck(hostname, services) { const entry = this.map.get(hostname); - const now = this.network.now(); - let bucket, evicted, old, fresh; if (!entry) return; + const now = this.network.now(); + entry.addr.services |= services; entry.addr.services >>>= 0; @@ -749,6 +747,7 @@ HostList.prototype.markAck = function markAck(hostname, services) { assert(entry.refCount > 0); // Remove from fresh. + let old; for (const bucket of this.fresh) { if (bucket.delete(entry.key())) { entry.refCount--; @@ -761,7 +760,7 @@ HostList.prototype.markAck = function markAck(hostname, services) { this.totalFresh--; // Find room in used bucket. - bucket = this.usedBucket(entry); + const bucket = this.usedBucket(entry); if (bucket.size < this.options.maxEntries) { entry.used = true; @@ -771,8 +770,8 @@ HostList.prototype.markAck = function markAck(hostname, services) { } // No room. Evict. - evicted = this.evictUsed(bucket); - fresh = this.freshBucket(evicted); + const evicted = this.evictUsed(bucket); + let fresh = this.freshBucket(evicted); // Move to entry's old bucket if no room. if (fresh.size >= this.options.maxEntries) @@ -828,15 +827,15 @@ HostList.prototype.toArray = function toArray() { */ HostList.prototype.addSeed = function addSeed(host) { - let addr = IP.fromHostname(host, this.network.port); + const ip = IP.fromHostname(host, this.network.port); - if (addr.type === IP.types.DNS) { + if (ip.type === IP.types.DNS) { // Defer for resolution. - this.dnsSeeds.push(addr); + this.dnsSeeds.push(ip); return; } - addr = NetAddress.fromHost(addr.host, addr.port, this.network); + const addr = NetAddress.fromHost(ip.host, ip.port, this.network); this.add(addr); @@ -850,15 +849,15 @@ HostList.prototype.addSeed = function addSeed(host) { */ HostList.prototype.addNode = function addNode(host) { - let addr = IP.fromHostname(host, this.network.port); + const ip = IP.fromHostname(host, this.network.port); - if (addr.type === IP.types.DNS) { + if (ip.type === IP.types.DNS) { // Defer for resolution. - this.dnsNodes.push(addr); + this.dnsNodes.push(ip); return; } - addr = NetAddress.fromHost(addr.host, addr.port, this.network); + const addr = NetAddress.fromHost(ip.host, ip.port, this.network); this.nodes.push(addr); this.add(addr); @@ -939,15 +938,13 @@ HostList.prototype.addLocal = function addLocal(host, port, score) { */ HostList.prototype.pushLocal = function pushLocal(addr, score) { - let local; - if (!addr.isRoutable()) return false; if (this.local.has(addr.hostname)) return false; - local = new LocalAddress(addr, score); + const local = new LocalAddress(addr, score); this.local.set(addr.hostname, local); @@ -1076,12 +1073,12 @@ HostList.prototype.populateSeed = async function populateSeed(seed) { HostList.prototype.populate = async function populate(target) { const addrs = []; - let hosts; assert(target.type === IP.types.DNS, 'Resolved host passed.'); this.logger.info('Resolving host: %s.', target.host); + let hosts; try { hosts = await this.resolve(target.host); } catch (e) { diff --git a/lib/net/packets.js b/lib/net/packets.js index 849d715a..b5a77175 100644 --- a/lib/net/packets.js +++ b/lib/net/packets.js @@ -987,11 +987,9 @@ GetBlocksPacket.prototype.toRaw = function toRaw() { */ GetBlocksPacket.prototype.fromReader = function fromReader(br) { - let count; - this.version = br.readU32(); - count = br.readVarint(); + const count = br.readVarint(); assert(count <= 50000, 'Too many block hashes.'); diff --git a/lib/net/parser.js b/lib/net/parser.js index a2c6cde9..a53c1915 100644 --- a/lib/net/parser.js +++ b/lib/net/parser.js @@ -63,10 +63,9 @@ Parser.prototype.feed = function feed(data) { while (this.total >= this.waiting) { const chunk = Buffer.allocUnsafe(this.waiting); let off = 0; - let len = 0; while (off < chunk.length) { - len = this.pending[0].copy(chunk, off); + const len = this.pending[0].copy(chunk, off); if (len === this.pending[0].length) this.pending.shift(); else @@ -87,8 +86,6 @@ Parser.prototype.feed = function feed(data) { */ Parser.prototype.parse = function parse(data) { - let payload, checksum; - assert(data.length <= common.MAX_MESSAGE); if (!this.header) { @@ -96,7 +93,7 @@ Parser.prototype.parse = function parse(data) { return; } - checksum = digest.hash256(data).readUInt32LE(0, true); + const checksum = digest.hash256(data).readUInt32LE(0, true); if (checksum !== this.header.checksum) { this.waiting = 24; @@ -105,6 +102,8 @@ Parser.prototype.parse = function parse(data) { return; } + let payload = null; + try { payload = this.parsePayload(this.header.cmd, data); } catch (e) { @@ -127,26 +126,25 @@ Parser.prototype.parse = function parse(data) { */ Parser.prototype.parseHeader = function parseHeader(data) { - let i, magic, cmd, size, checksum; - - magic = data.readUInt32LE(0, true); + const magic = data.readUInt32LE(0, true); if (magic !== this.network.magic) { this.error('Invalid magic value: %s.', util.hex32(magic)); return null; } - // Count length of the cmd - for (i = 0; data[i + 4] !== 0 && i < 12; i++); + // Count length of the cmd. + let i = 0; + for (; data[i + 4] !== 0 && i < 12; i++); if (i === 12) { this.error('Non NULL-terminated command.'); return null; } - cmd = data.toString('ascii', 4, 4 + i); + const cmd = data.toString('ascii', 4, 4 + i); - size = data.readUInt32LE(16, true); + const size = data.readUInt32LE(16, true); if (size > common.MAX_MESSAGE) { this.waiting = 24; @@ -156,7 +154,7 @@ Parser.prototype.parseHeader = function parseHeader(data) { this.waiting = size; - checksum = data.readUInt32LE(20, true); + const checksum = data.readUInt32LE(20, true); return new Header(cmd, size, checksum); }; diff --git a/lib/net/peer.js b/lib/net/peer.js index b77c1a10..5e70dba7 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -341,7 +341,7 @@ Peer.prototype.setCipher = function setCipher(cipher) { }); this.bip151.on('packet', (cmd, body) => { - let payload; + let payload = null; try { payload = this.parser.parsePayload(cmd, body); } catch (e) { @@ -435,11 +435,9 @@ Peer.prototype.accept = function accept(socket) { */ Peer.prototype.connect = function connect(addr) { - let socket; - assert(!this.socket); - socket = this.options.createSocket(addr.port, addr.host); + const socket = this.options.createSocket(addr.port, addr.host); this.address = addr; this.outbound = true; @@ -525,7 +523,7 @@ Peer.prototype.initConnect = function initConnect() { this.socket.removeListener('error', onError); }; - let onError = (err) => { + const onError = (err) => { cleanup(); reject(err); }; @@ -805,8 +803,6 @@ Peer.prototype.announceTX = function announceTX(txs) { */ Peer.prototype.queueInv = function queueInv(items) { - let hasBlock = false; - if (!this.handshake) return; @@ -816,6 +812,8 @@ Peer.prototype.queueInv = function queueInv(items) { if (!Array.isArray(items)) items = [items]; + let hasBlock = false; + for (const item of items) { if (item.type === invTypes.BLOCK) hasBlock = true; @@ -1022,7 +1020,6 @@ Peer.prototype.sendFeeRate = function sendFeeRate(rate) { Peer.prototype.destroy = function destroy() { const connected = this.connected; - let jobs; if (this.destroyed) return; @@ -1059,7 +1056,7 @@ Peer.prototype.destroy = function destroy() { this.connectTimeout = null; } - jobs = this.drainQueue; + const jobs = this.drainQueue; this.drainSize = 0; this.drainQueue = []; @@ -1098,13 +1095,12 @@ Peer.prototype.write = function write(data) { */ Peer.prototype.send = function send(packet) { - let checksum; - if (this.destroyed) throw new Error('Peer is destroyed (send).'); // Used cached hashes as the // packet checksum for speed. + let checksum = null; if (packet.type === packetTypes.TX) { const tx = packet.tx; if (packet.witness) { @@ -1300,8 +1296,6 @@ Peer.prototype.maybeTimeout = function maybeTimeout() { } if (now > this.time + 60000) { - let mult; - assert(this.time !== 0); if (this.lastRecv === 0 || this.lastSend === 0) { @@ -1316,7 +1310,7 @@ Peer.prototype.maybeTimeout = function maybeTimeout() { return; } - mult = this.version <= common.PONG_VERSION ? 4 : 1; + const mult = this.version <= common.PONG_VERSION ? 4 : 1; if (now > this.lastRecv + Peer.TIMEOUT_INTERVAL * mult) { this.error('Peer is stalling (recv).'); @@ -1341,11 +1335,11 @@ Peer.prototype.maybeTimeout = function maybeTimeout() { */ Peer.prototype.request = function request(type, timeout) { - let entry = this.responseMap.get(type); - if (this.destroyed) return; + let entry = this.responseMap.get(type); + if (!entry) { entry = new RequestEntry(); this.responseMap.set(type, entry); @@ -1384,14 +1378,12 @@ Peer.prototype.response = function response(type, payload) { Peer.prototype.wait = function wait(type, timeout) { return new Promise((resolve, reject) => { - let entry; - if (this.destroyed) { reject(new Error('Peer is destroyed (request).')); return; } - entry = this.request(type); + const entry = this.request(type); entry.setTimeout(timeout); entry.addJob(resolve, reject); @@ -1405,18 +1397,16 @@ Peer.prototype.wait = function wait(type, timeout) { */ Peer.prototype.error = function error(err) { - let msg; - if (this.destroyed) return; if (typeof err === 'string') { - msg = util.fmt.apply(util, arguments); + const msg = util.fmt.apply(util, arguments); err = new Error(msg); } if (typeof err.code === 'string' && err.code[0] === 'E') { - msg = err.code; + const msg = err.code; err = new Error(msg); err.code = msg; err.message = `Socket Error: ${msg}`; @@ -1512,10 +1502,10 @@ Peer.prototype.getTX = function getTX(hashes) { */ Peer.prototype.getFullBlock = function getFullBlock(hash) { - let type = invTypes.BLOCK; - assert(!this.options.spv); + let type = invTypes.BLOCK; + if (this.hasWitness()) type |= InvItem.WITNESS_FLAG; @@ -1577,8 +1567,6 @@ Peer.prototype.readPacket = async function readPacket(packet) { */ Peer.prototype.handlePacket = async function handlePacket(packet) { - let entry; - if (this.destroyed) throw new Error('Destroyed peer sent a packet.'); @@ -1599,7 +1587,7 @@ Peer.prototype.handlePacket = async function handlePacket(packet) { this.bip150.reject(new Error('Message before BIP150 auth.')); } - entry = this.fulfill(packet); + const entry = this.fulfill(packet); switch (packet.type) { case packetTypes.VERSION: @@ -1951,12 +1939,10 @@ Peer.prototype.handleEncack = async function handleEncack(packet) { */ Peer.prototype.handleAuthChallenge = async function handleAuthChallenge(packet) { - let sig; - if (!this.bip150) return; - sig = this.bip150.challenge(packet.hash); + const sig = this.bip150.challenge(packet.hash); this.send(new packets.AuthReplyPacket(sig)); }; @@ -1969,12 +1955,10 @@ Peer.prototype.handleAuthChallenge = async function handleAuthChallenge(packet) */ Peer.prototype.handleAuthReply = async function handleAuthReply(packet) { - let hash; - if (!this.bip150) return; - hash = this.bip150.reply(packet.signature); + const hash = this.bip150.reply(packet.signature); if (hash) this.send(new packets.AuthProposePacket(hash)); @@ -1988,12 +1972,10 @@ Peer.prototype.handleAuthReply = async function handleAuthReply(packet) { */ Peer.prototype.handleAuthPropose = async function handleAuthPropose(packet) { - let hash; - if (!this.bip150) return; - hash = this.bip150.propose(packet.hash); + const hash = this.bip150.propose(packet.hash); this.send(new packets.AuthChallengePacket(hash)); }; diff --git a/lib/net/pool.js b/lib/net/pool.js index 6bfb532d..43160360 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -460,7 +460,6 @@ Pool.prototype.discover = async function discover() { Pool.prototype.discoverGateway = async function discoverGateway() { const src = this.options.publicPort; const dest = this.options.port; - let wan, host; // Pointless if we're not listening. if (!this.options.listen) @@ -471,6 +470,8 @@ Pool.prototype.discoverGateway = async function discoverGateway() { if (!this.options.upnp) return; + let wan = null; + try { this.logger.debug('Discovering internet gateway (upnp).'); wan = await UPNP.discover(); @@ -480,6 +481,8 @@ Pool.prototype.discoverGateway = async function discoverGateway() { return false; } + let host = null; + try { host = await wan.getExternalIP(); } catch (e) { @@ -513,13 +516,14 @@ Pool.prototype.discoverGateway = async function discoverGateway() { */ Pool.prototype.discoverSeeds = async function discoverSeeds(checkPeers) { - const max = Math.min(2, this.options.maxOutbound); - const size = this.hosts.size(); - let total = 0; - if (this.hosts.dnsSeeds.length === 0) return; + const max = Math.min(2, this.options.maxOutbound); + const size = this.hosts.size(); + + let total = 0; + for (let peer = this.peers.head(); peer; peer = peer.next) { if (!peer.outbound) continue; @@ -551,7 +555,6 @@ Pool.prototype.discoverSeeds = async function discoverSeeds(checkPeers) { Pool.prototype.discoverExternal = async function discoverExternal() { const port = this.options.publicPort; - let host4, host6; // Pointless if we're not listening. if (!this.options.listen) @@ -566,6 +569,8 @@ Pool.prototype.discoverExternal = async function discoverExternal() { if (this.hosts.local.size > 0) return; + let host4 = null; + try { host4 = await external.getIPv4(); } catch (e) { @@ -576,6 +581,8 @@ 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; + try { host6 = await external.getIPv6(); } catch (e) { @@ -594,29 +601,27 @@ Pool.prototype.discoverExternal = async function discoverExternal() { */ Pool.prototype.handleSocket = function handleSocket(socket) { - let host; - if (!socket.remoteAddress) { this.logger.debug('Ignoring disconnected peer.'); socket.destroy(); return; } - host = IP.normalize(socket.remoteAddress); + const ip = IP.normalize(socket.remoteAddress); if (this.peers.inbound >= this.options.maxInbound) { - this.logger.debug('Ignoring peer: too many inbound (%s).', host); + this.logger.debug('Ignoring peer: too many inbound (%s).', ip); socket.destroy(); return; } - if (this.hosts.isBanned(host)) { - this.logger.debug('Ignoring banned peer (%s).', host); + if (this.hosts.isBanned(ip)) { + this.logger.debug('Ignoring banned peer (%s).', ip); socket.destroy(); return; } - host = IP.toHostname(host, socket.remotePort); + const host = IP.toHostname(ip, socket.remotePort); assert(!this.peers.map[host], 'Port collision.'); @@ -630,8 +635,6 @@ Pool.prototype.handleSocket = function handleSocket(socket) { */ Pool.prototype.addLoader = function addLoader() { - let peer, addr; - if (!this.loaded) return; @@ -650,12 +653,12 @@ Pool.prototype.addLoader = function addLoader() { return; } - addr = this.getHost(); + const addr = this.getHost(); if (!addr) return; - peer = this.createOutbound(addr); + const peer = this.createOutbound(addr); this.logger.info('Adding loader peer (%s).', peer.hostname()); @@ -761,11 +764,11 @@ Pool.prototype.stopSync = function stopSync() { */ Pool.prototype.resync = async function resync(force) { - let locator; - if (!this.syncing) return; + let locator = null; + try { locator = await this.chain.getLocator(); } catch (e) { @@ -822,8 +825,6 @@ Pool.prototype.isSyncable = function isSyncable(peer) { */ Pool.prototype.sendSync = async function sendSync(peer) { - let locator; - if (peer.syncing) return false; @@ -833,6 +834,8 @@ Pool.prototype.sendSync = async function sendSync(peer) { peer.syncing = true; peer.blockTime = util.ms(); + let locator = null; + try { locator = await this.chain.getLocator(); } catch (e) { @@ -1061,11 +1064,11 @@ Pool.prototype.getItem = async function getItem(peer, item) { */ Pool.prototype.sendBlock = async function sendBlock(peer, item, witness) { - let block = this.getBroadcasted(peer, item); + const broadcasted = this.getBroadcasted(peer, item); // Check for a broadcasted item first. - if (block) { - peer.send(new packets.BlockPacket(block, witness)); + if (broadcasted) { + peer.send(new packets.BlockPacket(broadcasted, witness)); return true; } @@ -1078,7 +1081,7 @@ Pool.prototype.sendBlock = async function sendBlock(peer, item, witness) { // If we have the same serialization, we // can write the raw binary to the socket. if (witness || !this.options.hasWitness()) { - block = await this.chain.db.getRawBlock(item.hash); + const block = await this.chain.db.getRawBlock(item.hash); if (block) { peer.sendRaw('block', block); @@ -1088,7 +1091,7 @@ Pool.prototype.sendBlock = async function sendBlock(peer, item, witness) { return false; } - block = await this.chain.db.getBlock(item.hash); + const block = await this.chain.db.getBlock(item.hash); if (block) { peer.send(new packets.BlockPacket(block, witness)); @@ -1524,9 +1527,6 @@ Pool.prototype.handlePong = async function handlePong(peer, packet) { */ Pool.prototype.handleGetAddr = async function handleGetAddr(peer, packet) { - const items = []; - let addrs; - if (this.options.selfish) return; @@ -1539,7 +1539,8 @@ Pool.prototype.handleGetAddr = async function handleGetAddr(peer, packet) { peer.sentAddr = true; - addrs = this.hosts.toArray(); + const addrs = this.hosts.toArray(); + const items = []; for (const addr of addrs) { if (!peer.addrFilter.added(addr.hostname, 'ascii')) @@ -1630,15 +1631,16 @@ Pool.prototype.handleInv = async function handleInv(peer, packet) { Pool.prototype._handleInv = async function handleInv(peer, packet) { const items = packet.items; - const blocks = []; - const txs = []; - let unknown = -1; if (items.length > 50000) { peer.increaseBan(100); return; } + const blocks = []; + const txs = []; + let unknown = -1; + for (const item of items) { switch (item.type) { case invTypes.BLOCK: @@ -1682,7 +1684,6 @@ Pool.prototype._handleInv = async function handleInv(peer, packet) { Pool.prototype.handleBlockInv = async function handleBlockInv(peer, hashes) { const items = []; - let hash, exists; assert(hashes.length > 0); @@ -1691,7 +1692,7 @@ Pool.prototype.handleBlockInv = async function handleBlockInv(peer, hashes) { // Always keep track of the peer's best hash. if (!peer.loader || this.chain.synced) { - hash = hashes[hashes.length - 1]; + const hash = hashes[hashes.length - 1]; peer.bestHash = hash; } @@ -1711,6 +1712,8 @@ Pool.prototype.handleBlockInv = async function handleBlockInv(peer, hashes) { hashes.length, peer.hostname()); + let exists = null; + for (let i = 0; i < hashes.length; i++) { const hash = hashes[i]; @@ -1780,11 +1783,6 @@ Pool.prototype.handleTXInv = async function handleTXInv(peer, hashes) { Pool.prototype.handleGetData = async function handleGetData(peer, packet) { const items = packet.items; - const notFound = []; - let txs = 0; - let blocks = 0; - let compact = 0; - let unknown = -1; if (items.length > 50000) { this.logger.warning('Peer sent inv with >50k items (%s).', peer.hostname()); @@ -1793,6 +1791,12 @@ Pool.prototype.handleGetData = async function handleGetData(peer, packet) { return; } + const notFound = []; + let txs = 0; + let blocks = 0; + let compact = 0; + let unknown = -1; + for (const item of items) { if (item.isTX()) { const tx = await this.getItem(peer, item); @@ -1832,8 +1836,6 @@ Pool.prototype.handleGetData = async function handleGetData(peer, packet) { } case invTypes.FILTERED_BLOCK: case invTypes.WITNESS_FILTERED_BLOCK: { - let block; - if (!this.options.bip37) { this.logger.debug( 'Peer requested a merkleblock without bip37 enabled (%s).', @@ -1847,18 +1849,18 @@ Pool.prototype.handleGetData = async function handleGetData(peer, packet) { continue; } - block = await this.getItem(peer, item); + const block = await this.getItem(peer, item); if (!block) { notFound.push(item); continue; } - block = block.toMerkle(peer.spvFilter); + const merkle = block.toMerkle(peer.spvFilter); - peer.send(new packets.MerkleBlockPacket(block)); + peer.send(new packets.MerkleBlockPacket(merkle)); - for (const tx of block.txs) { + for (const tx of merkle.txs) { peer.send(new packets.TXPacket(tx, item.hasWitness())); txs++; } @@ -1869,7 +1871,6 @@ Pool.prototype.handleGetData = async function handleGetData(peer, packet) { } case invTypes.CMPCT_BLOCK: { const height = await this.chain.db.getHeight(item.hash); - let block; // Fallback to full block. if (height < this.chain.tip.height - 10) { @@ -1882,7 +1883,7 @@ Pool.prototype.handleGetData = async function handleGetData(peer, packet) { break; } - block = await this.getItem(peer, item); + const block = await this.getItem(peer, item); if (!block) { notFound.push(item); @@ -1968,7 +1969,6 @@ Pool.prototype.handleNotFound = async function handleNotFound(peer, packet) { Pool.prototype.handleGetBlocks = async function handleGetBlocks(peer, packet) { const blocks = []; - let hash; if (!this.chain.synced) return; @@ -1982,7 +1982,7 @@ Pool.prototype.handleGetBlocks = async function handleGetBlocks(peer, packet) { if (this.chain.options.prune) return; - hash = await this.chain.findLocator(packet.locator); + let hash = await this.chain.findLocator(packet.locator); if (hash) hash = await this.chain.db.getNextHash(hash); @@ -2013,9 +2013,6 @@ Pool.prototype.handleGetBlocks = async function handleGetBlocks(peer, packet) { */ Pool.prototype.handleGetHeaders = async function handleGetHeaders(peer, packet) { - const headers = []; - let hash, entry; - if (!this.chain.synced) return; @@ -2028,6 +2025,8 @@ Pool.prototype.handleGetHeaders = async function handleGetHeaders(peer, packet) if (this.chain.options.prune) return; + let hash = null; + if (packet.locator.length > 0) { hash = await this.chain.findLocator(packet.locator); if (hash) @@ -2036,9 +2035,13 @@ Pool.prototype.handleGetHeaders = async function handleGetHeaders(peer, packet) hash = packet.stop; } + let entry = null; + if (hash) entry = await this.chain.db.getEntry(hash); + const headers = []; + while (entry) { headers.push(entry.toHeaders()); @@ -2084,8 +2087,6 @@ Pool.prototype.handleHeaders = async function handleHeaders(peer, packet) { Pool.prototype._handleHeaders = async function handleHeaders(peer, packet) { const headers = packet.items; - let checkpoint = false; - let node; if (!this.checkpoints) return; @@ -2106,6 +2107,9 @@ Pool.prototype._handleHeaders = async function handleHeaders(peer, packet) { assert(this.headerChain.size > 0); + let checkpoint = false; + let node = null; + for (const header of headers) { const last = this.headerChain.tail; const hash = header.hash('hex'); @@ -2251,12 +2255,11 @@ Pool.prototype.addBlock = async function addBlock(peer, block, flags) { */ Pool.prototype._addBlock = async function addBlock(peer, block, flags) { - const hash = block.hash('hex'); - let entry; - if (!this.syncing) return; + const hash = block.hash('hex'); + if (!this.resolveBlock(peer, hash)) { this.logger.warning( 'Received unrequested block: %s (%s).', @@ -2267,6 +2270,8 @@ Pool.prototype._addBlock = async function addBlock(peer, block, flags) { peer.blockTime = util.ms(); + let entry = null; + try { entry = await this.chain.add(block, flags, peer.id); } catch (err) { @@ -2280,8 +2285,6 @@ Pool.prototype._addBlock = async function addBlock(peer, block, flags) { // Block was orphaned. if (!entry) { - let height; - if (this.checkpoints) { this.logger.warning( 'Peer sent orphan block with getheaders (%s).', @@ -2292,7 +2295,7 @@ Pool.prototype._addBlock = async function addBlock(peer, block, flags) { // During a getblocks sync, peers send // their best tip frequently. We can grab // the height commitment from the coinbase. - height = block.getCoinbaseHeight(); + const height = block.getCoinbaseHeight(); if (height !== -1) { peer.bestHash = hash; @@ -2328,8 +2331,6 @@ Pool.prototype._addBlock = async function addBlock(peer, block, flags) { */ Pool.prototype.resolveChain = async function resolveChain(peer, hash) { - const node = this.headerChain.head; - if (!this.checkpoints) return; @@ -2339,6 +2340,8 @@ Pool.prototype.resolveChain = async function resolveChain(peer, hash) { if (peer.destroyed) throw new Error('Peer was destroyed (header chain resolution).'); + const node = this.headerChain.head; + assert(node); if (hash !== node.hash) { @@ -2489,7 +2492,6 @@ Pool.prototype._handleTX = async function handleTX(peer, packet) { const hash = tx.hash('hex'); const flags = chainCommon.flags.VERIFY_NONE; const block = peer.merkleBlock; - let missing; if (block) { assert(peer.merkleMatches > 0); @@ -2533,6 +2535,8 @@ Pool.prototype._handleTX = async function handleTX(peer, packet) { return; } + let missing = null; + try { missing = await this.mempool.addTX(tx, peer.id); } catch (err) { @@ -2562,8 +2566,6 @@ Pool.prototype._handleTX = async function handleTX(peer, packet) { */ Pool.prototype.handleReject = async function handleReject(peer, packet) { - let entry; - this.logger.warning( 'Received reject (%s): msg=%s code=%s reason=%s hash=%s.', peer.hostname(), @@ -2575,7 +2577,7 @@ Pool.prototype.handleReject = async function handleReject(peer, packet) { if (!packet.hash) return; - entry = this.invMap.get(packet.hash); + const entry = this.invMap.get(packet.hash); if (!entry) return; @@ -2684,11 +2686,6 @@ Pool.prototype.handleMerkleBlock = async function handleMerkleBlock(peer, packet */ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packet) { - const block = packet.block; - const hash = block.hash('hex'); - const flags = chainCommon.flags.VERIFY_NONE; - let tree; - if (!this.syncing) return; @@ -2701,6 +2698,9 @@ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packe return; } + const block = packet.block; + const hash = block.hash('hex'); + if (!peer.blockMap.has(hash)) { this.logger.warning( 'Peer sent an unrequested merkleblock (%s).', @@ -2725,9 +2725,10 @@ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packe return; } - tree = block.getTree(); + const tree = block.getTree(); if (tree.matches.length === 0) { + const flags = chainCommon.flags.VERIFY_NONE; await this._addBlock(peer, block, flags); return; } @@ -2775,7 +2776,6 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet) const hash = block.hash('hex'); const witness = peer.compactWitness; const flags = chainCommon.flags.VERIFY_BODY; - let result; if (!this.syncing) return; @@ -2836,6 +2836,7 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet) return; } + let result; try { result = block.init(); } catch (e) { @@ -2855,9 +2856,9 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet) return; } - result = block.fillMempool(witness, this.mempool); + const full = block.fillMempool(witness, this.mempool); - if (result) { + if (full) { this.logger.debug( 'Received full compact block %s (%s).', block.rhash(), peer.hostname()); @@ -2897,7 +2898,6 @@ Pool.prototype.handleCmpctBlock = async function handleCmpctBlock(peer, packet) Pool.prototype.handleGetBlockTxn = async function handleGetBlockTxn(peer, packet) { const req = packet.request; - let res, item, block, height; if (this.chain.options.spv) return; @@ -2908,9 +2908,9 @@ Pool.prototype.handleGetBlockTxn = async function handleGetBlockTxn(peer, packet if (this.options.selfish) return; - item = new InvItem(invTypes.BLOCK, req.hash); + const item = new InvItem(invTypes.BLOCK, req.hash); - block = await this.getItem(peer, item); + const block = await this.getItem(peer, item); if (!block) { this.logger.debug( @@ -2920,7 +2920,7 @@ Pool.prototype.handleGetBlockTxn = async function handleGetBlockTxn(peer, packet return; } - height = await this.chain.db.getHeight(req.hash); + const height = await this.chain.db.getHeight(req.hash); if (height < this.chain.tip.height - 15) { this.logger.debug( @@ -2934,7 +2934,7 @@ Pool.prototype.handleGetBlockTxn = async function handleGetBlockTxn(peer, packet block.rhash(), peer.hostname()); - res = BIP152.TXResponse.fromBlock(block, req); + const res = BIP152.TXResponse.fromBlock(block, req); peer.send(new packets.BlockTxnPacket(res, peer.compactWitness)); }; @@ -3062,14 +3062,12 @@ Pool.prototype.handleUnknown = async function handleUnknown(peer, packet) { */ Pool.prototype.addInbound = function addInbound(socket) { - let peer; - if (!this.loaded) { socket.destroy(); return; } - peer = this.createInbound(socket); + const peer = this.createInbound(socket); this.logger.info('Added inbound peer (%s).', peer.hostname()); @@ -3094,12 +3092,11 @@ Pool.prototype.getHost = function getHost() { for (let i = 0; i < 100; i++) { const entry = this.hosts.getHost(); - let addr; if (!entry) break; - addr = entry.addr; + const addr = entry.addr; if (this.peers.has(addr.hostname)) continue; @@ -3133,8 +3130,6 @@ Pool.prototype.getHost = function getHost() { */ Pool.prototype.addOutbound = function addOutbound() { - let peer, addr; - if (!this.loaded) return; @@ -3146,12 +3141,12 @@ Pool.prototype.addOutbound = function addOutbound() { if (!this.peers.load) return; - addr = this.getHost(); + const addr = this.getHost(); if (!addr) return; - peer = this.createOutbound(addr); + const peer = this.createOutbound(addr); this.peers.add(peer); @@ -3387,9 +3382,6 @@ Pool.prototype.getBlocks = async function getBlocks(peer, tip, stop) { */ Pool.prototype.getBlock = function getBlock(peer, hashes) { - let now = util.ms(); - const items = []; - if (!this.loaded) return; @@ -3399,6 +3391,9 @@ Pool.prototype.getBlock = function getBlock(peer, hashes) { if (peer.destroyed) throw new Error('Peer is destroyed (getdata).'); + let now = util.ms(); + const items = []; + for (const hash of hashes) { if (this.blockMap.has(hash)) continue; @@ -3431,9 +3426,6 @@ Pool.prototype.getBlock = function getBlock(peer, hashes) { */ Pool.prototype.getTX = function getTX(peer, hashes) { - let now = util.ms(); - const items = []; - if (!this.loaded) return; @@ -3443,6 +3435,9 @@ Pool.prototype.getTX = function getTX(peer, hashes) { if (peer.destroyed) throw new Error('Peer is destroyed (getdata).'); + let now = util.ms(); + const items = []; + for (const hash of hashes) { if (this.txMap.has(hash)) continue; @@ -4044,12 +4039,10 @@ PoolOptions.prototype.hasNonce = function hasNonce(nonce) { */ PoolOptions.prototype.getRate = function getRate(hash) { - let entry; - if (!this.mempool) return -1; - entry = this.mempool.getEntry(hash); + const entry = this.mempool.getEntry(hash); if (!entry) return -1; @@ -4228,14 +4221,12 @@ PeerList.prototype.destroy = function destroy() { */ function BroadcastItem(pool, msg) { - let item; - if (!(this instanceof BroadcastItem)) return new BroadcastItem(pool, msg); assert(!msg.mutable, 'Cannot broadcast mutable item.'); - item = msg.toInv(); + const item = msg.toInv(); this.pool = pool; this.hash = item.hash; diff --git a/lib/net/socks.js b/lib/net/socks.js index ba35bbae..92d121c1 100644 --- a/lib/net/socks.js +++ b/lib/net/socks.js @@ -71,8 +71,6 @@ SOCKS.errors = [ ]; SOCKS.prototype.error = function error(err) { - let msg; - if (this.destroyed) return; @@ -82,7 +80,7 @@ SOCKS.prototype.error = function error(err) { return; } - msg = util.fmt.apply(util, arguments); + const msg = util.fmt.apply(util, arguments); this.emit('error', new Error(msg)); this.destroy(); }; @@ -300,7 +298,6 @@ SOCKS.prototype.handleHandshake = function handleHandshake(data) { SOCKS.prototype.sendAuth = function sendAuth() { const user = this.username; const pass = this.password; - let ulen, plen, size, packet; if (!user) { this.error('No username passed for SOCKS auth.'); @@ -312,17 +309,19 @@ SOCKS.prototype.sendAuth = function sendAuth() { return; } - ulen = Buffer.byteLength(user, 'ascii'); - plen = Buffer.byteLength(pass, 'ascii'); - size = 3 + ulen + plen; + const ulen = Buffer.byteLength(user, 'ascii'); + const plen = Buffer.byteLength(pass, 'ascii'); + const size = 3 + ulen + plen; - packet = new StaticWriter(size); - packet.writeU8(0x01); - packet.writeU8(ulen); - packet.writeString(user, 'ascii'); - packet.writeU8(plen); - packet.writeString(pass, 'ascii'); - packet = packet.render(); + const bw = new StaticWriter(size); + + bw.writeU8(0x01); + bw.writeU8(ulen); + bw.writeString(user, 'ascii'); + bw.writeU8(plen); + bw.writeString(pass, 'ascii'); + + const packet = bw.render(); this.state = SOCKS.states.AUTH; this.socket.write(packet); @@ -366,7 +365,7 @@ SOCKS.prototype.auth = function auth() { SOCKS.prototype.sendProxy = function sendProxy() { const host = this.destHost; const port = this.destPort; - let ip, len, type, name, packet; + let ip, len, type, name; switch (IP.getStringType(host)) { case IP.types.IPV4: @@ -388,28 +387,26 @@ SOCKS.prototype.sendProxy = function sendProxy() { break; } - packet = new StaticWriter(6 + len); + const bw = new StaticWriter(6 + len); - packet.writeU8(0x05); - packet.writeU8(0x01); - packet.writeU8(0x00); - packet.writeU8(type); + bw.writeU8(0x05); + bw.writeU8(0x01); + bw.writeU8(0x00); + bw.writeU8(type); if (type === 0x03) - packet.writeU8(name.length); + bw.writeU8(name.length); - packet.writeBytes(name); - packet.writeU16BE(port); + bw.writeBytes(name); + bw.writeU16BE(port); - packet = packet.render(); + const packet = bw.render(); this.state = SOCKS.states.PROXY; this.socket.write(packet); }; SOCKS.prototype.handleProxy = function handleProxy(data) { - let addr; - if (data.length < 6) { this.error('Bad packet size for SOCKS connect.'); return; @@ -431,6 +428,8 @@ SOCKS.prototype.handleProxy = function handleProxy(data) { return; } + let addr = null; + try { addr = parseAddr(data, 3); } catch (e) { @@ -449,24 +448,24 @@ SOCKS.prototype.handleProxy = function handleProxy(data) { SOCKS.prototype.sendResolve = function sendResolve() { const name = this.name; const len = Buffer.byteLength(name, 'utf8'); - let packet = new StaticWriter(7 + len); - packet.writeU8(0x05); - packet.writeU8(0xf0); - packet.writeU8(0x00); - packet.writeU8(0x03); - packet.writeU8(len); - packet.writeString(name, 'utf8'); - packet.writeU16BE(0); - packet = packet.render(); + const bw = new StaticWriter(7 + len); + + bw.writeU8(0x05); + bw.writeU8(0xf0); + bw.writeU8(0x00); + bw.writeU8(0x03); + bw.writeU8(len); + bw.writeString(name, 'utf8'); + bw.writeU16BE(0); + + const packet = bw.render(); this.state = SOCKS.states.RESOLVE; this.socket.write(packet); }; SOCKS.prototype.handleResolve = function handleResolve(data) { - let addr; - if (data.length < 6) { this.error('Bad packet size for tor resolve.'); return; @@ -488,6 +487,8 @@ SOCKS.prototype.handleResolve = function handleResolve(data) { return; } + let addr = null; + try { addr = parseAddr(data, 3); } catch (e) { @@ -557,11 +558,9 @@ function Proxy(host, port, user, pass) { util.inherits(Proxy, EventEmitter); Proxy.prototype.connect = async function connect(port, host) { - let options, socket; - assert(!this.socket, 'Already connected.'); - options = { + const options = { host: this.host, port: this.port, username: this.username, @@ -570,6 +569,8 @@ Proxy.prototype.connect = async function connect(port, host) { destPort: port }; + let socket = null; + try { socket = await SOCKS.proxy(options); } catch (e) { @@ -673,7 +674,6 @@ Proxy.prototype.destroy = function destroy() { function parseProxy(host) { const index = host.indexOf('@'); - let addr, left, right, parts; if (index === -1) { const addr = IP.fromHostname(host, 1080); @@ -683,13 +683,13 @@ function parseProxy(host) { }; } - left = host.substring(0, index); - right = host.substring(index + 1); + const left = host.substring(0, index); + const right = host.substring(index + 1); - parts = left.split(':'); + const parts = left.split(':'); assert(parts.length > 1, 'Bad username and password.'); - addr = IP.fromHostname(right, 1080); + const addr = IP.fromHostname(right, 1080); return { host: addr.host, @@ -701,25 +701,28 @@ function parseProxy(host) { function parseAddr(data, offset) { const br = new BufferReader(data); - let type, len, host, port; if (br.left() < offset + 2) throw new Error('Bad SOCKS address length.'); br.seek(offset); - type = br.readU8(); + const type = br.readU8(); + + let host = null; + let port = 0; switch (type) { - case 0x01: + case 0x01: { if (br.left() < 6) throw new Error('Bad SOCKS ipv4 length.'); host = IP.toString(br.readBytes(4)); port = br.readU16BE(); break; - case 0x03: - len = br.readU8(); + } + case 0x03: { + const len = br.readU8(); if (br.left() < len + 2) throw new Error('Bad SOCKS domain length.'); @@ -727,15 +730,18 @@ function parseAddr(data, offset) { host = br.readString(len, 'utf8'); port = br.readU16BE(); break; - case 0x04: + } + case 0x04: { if (br.left() < 18) throw new Error('Bad SOCKS ipv6 length.'); host = IP.toString(br.readBytes(16)); port = br.readU16BE(); break; - default: + } + default: { throw new Error(`Unknown SOCKS address type: ${type}.`); + } } return { @@ -755,9 +761,8 @@ exports.connect = function connect(proxy, destPort, destHost) { const port = addr.port; const user = addr.username; const pass = addr.password; - let socket; - socket = new Proxy(host, port, user, pass); + const socket = new Proxy(host, port, user, pass); socket.connect(destPort, destHost); return socket; diff --git a/lib/net/upnp.js b/lib/net/upnp.js index a99d61ff..ba30f4ab 100644 --- a/lib/net/upnp.js +++ b/lib/net/upnp.js @@ -153,7 +153,6 @@ UPNP.prototype.discover = async function discover() { UPNP.prototype._discover = async function discover() { const socket = dgram.createSocket('udp4'); - let msg; socket.on('error', (err) => { this.rejectJob(err); @@ -167,7 +166,7 @@ UPNP.prototype._discover = async function discover() { this.socket = socket; this.startTimeout(); - msg = '' + const msg = '' + 'M-SEARCH * HTTP/1.1\r\n' + `HOST: ${this.host}:${this.port}\r\n` + 'MAN: ssdp:discover\r\n' @@ -189,11 +188,11 @@ UPNP.prototype._discover = async function discover() { */ UPNP.prototype.handleMsg = async function handleMsg(msg) { - let headers; - if (!this.socket) return; + let headers = null; + try { headers = UPNP.parseHeader(msg); } catch (e) { @@ -218,24 +217,23 @@ UPNP.prototype.handleMsg = async function handleMsg(msg) { UPNP.prototype.resolve = async function resolve(location, targets) { const host = parseHost(location); - let res, xml, services, service; if (!targets) targets = UPNP.WAN_SERVICES; - res = await request({ + const res = await request({ method: 'GET', uri: location, timeout: UPNP.RESPONSE_TIMEOUT, expect: 'xml' }); - xml = XMLElement.fromRaw(res.body); + const xml = XMLElement.fromRaw(res.body); - services = parseServices(xml); + const services = parseServices(xml); assert(services.length > 0, 'No services found.'); - service = extractServices(services, targets); + const service = extractServices(services, targets); assert(service, 'No service found.'); assert(service.serviceId, 'No service ID found.'); assert(service.serviceId.length > 0, 'No service ID found.'); @@ -265,14 +263,12 @@ UPNP.parseHeader = function parseHeader(str) { const headers = Object.create(null); for (let line of lines) { - let index, left, right; - line = line.trim(); if (line.length === 0) continue; - index = line.indexOf(':'); + const index = line.indexOf(':'); if (index === -1) { left = line.toLowerCase(); @@ -280,8 +276,8 @@ UPNP.parseHeader = function parseHeader(str) { continue; } - left = line.substring(0, index); - right = line.substring(index + 1); + let left = line.substring(0, index); + let right = line.substring(index + 1); left = left.trim(); right = right.trim(); @@ -371,9 +367,8 @@ UPNPService.prototype.createRequest = function createRequest(action, args) { UPNPService.prototype.soapRequest = async function soapRequest(action, args) { const type = this.serviceType; const req = this.createRequest(action, args); - let res, xml, err; - res = await request({ + const res = await request({ method: 'POST', uri: this.controlURL, timeout: UPNP.RESPONSE_TIMEOUT, @@ -387,8 +382,8 @@ UPNPService.prototype.soapRequest = async function soapRequest(action, args) { body: req }); - xml = XMLElement.fromRaw(res.body); - err = findError(xml); + const xml = XMLElement.fromRaw(res.body); + const err = findError(xml); if (err) throw err; @@ -423,12 +418,11 @@ UPNPService.prototype.getExternalIP = async function getExternalIP() { UPNPService.prototype.addPortMapping = async function addPortMapping(remote, src, dest) { const action = 'AddPortMapping'; const local = IP.getPrivate(); - let xml, child; if (local.length === 0) throw new Error('Cannot determine local IP.'); - xml = await this.soapRequest(action, [ + const xml = await this.soapRequest(action, [ ['NewRemoteHost', remote], ['NewExternalPort', src], ['NewProtocol', 'TCP'], @@ -439,7 +433,7 @@ UPNPService.prototype.addPortMapping = async function addPortMapping(remote, src ['NewLeaseDuration', 0] ]); - child = xml.find('AddPortMappingResponse'); + const child = xml.find('AddPortMappingResponse'); if (!child) throw new Error('Port mapping failed.'); @@ -456,15 +450,14 @@ UPNPService.prototype.addPortMapping = async function addPortMapping(remote, src UPNPService.prototype.removePortMapping = async function removePortMapping(remote, port) { const action = 'DeletePortMapping'; - let xml, child; - xml = await this.soapRequest(action, [ + const xml = await this.soapRequest(action, [ ['NewRemoteHost', remote], ['NewExternalPort', port], ['NewProtocol', 'TCP'] ]); - child = xml.find('DeletePortMappingResponse'); + const child = xml.find('DeletePortMappingResponse'); if (!child) throw new Error('Port unmapping failed.'); @@ -493,15 +486,16 @@ function XMLElement(name) { XMLElement.fromRaw = function fromRaw(xml) { const sentinel = new XMLElement(''); + const stack = [sentinel]; + let current = sentinel; - const stack = []; let decl = false; - let m; - stack.push(sentinel); + while (xml.length > 0) { + let m = null; - while (xml.length) { - if (m = /^<\?xml[^<>]*\?>/i.exec(xml)) { + m = /^<\?xml[^<>]*\?>/i.exec(xml); + if (m) { xml = xml.substring(m[0].length); assert(current === sentinel, 'XML declaration inside element.'); assert(!decl, 'XML declaration seen twice.'); @@ -509,13 +503,14 @@ XMLElement.fromRaw = function fromRaw(xml) { continue; } - if (m = /^<([\w:]+)[^<>]*?(\/?)>/i.exec(xml)) { + m = /^<([\w:]+)[^<>]*?(\/?)>/i.exec(xml); + if (m) { + xml = xml.substring(m[0].length); + const name = m[1]; const trailing = m[2] === '/'; const element = new XMLElement(name); - xml = xml.substring(m[0].length); - if (trailing) { current.add(element); continue; @@ -528,14 +523,15 @@ XMLElement.fromRaw = function fromRaw(xml) { continue; } - if (m = /^<\/([\w:]+)[^<>]*>/i.exec(xml)) { - const name = m[1]; - let element; - + m = /^<\/([\w:]+)[^<>]*>/i.exec(xml); + if (m) { xml = xml.substring(m[0].length); + const name = m[1]; + assert(stack.length !== 1, 'No start tag.'); - element = stack.pop(); + + const element = stack.pop(); assert(element.name === name, 'Tag mismatch.'); current = stack[stack.length - 1]; @@ -546,9 +542,10 @@ XMLElement.fromRaw = function fromRaw(xml) { continue; } - if (m = /^([^<]+)/i.exec(xml)) { - const text = m[1]; + m = /^([^<]+)/i.exec(xml); + if (m) { xml = xml.substring(m[0].length); + const text = m[1]; current.text = text.trim(); continue; } @@ -673,19 +670,19 @@ function findIP(el) { function findError(el) { const child = el.find('UPnPError'); - let code = -1; - let desc = 'Unknown'; - let ccode, cdesc; if (!child) return; - ccode = child.find('errorCode'); - cdesc = child.find('errorDescription'); + let code = -1; + const ccode = child.find('errorCode'); if (ccode && /^\d+$/.test(ccode.text)) code = +ccode.text; + let desc = 'Unknown'; + const cdesc = child.find('errorDescription'); + if (cdesc) desc = cdesc.text; diff --git a/lib/node/config.js b/lib/node/config.js index 87b16120..40dcd826 100644 --- a/lib/node/config.js +++ b/lib/node/config.js @@ -108,12 +108,11 @@ Config.prototype.load = function load(options) { */ Config.prototype.open = function open(file) { - let path, text; - if (fs.unsupported) return; - path = this.getFile(file); + const path = this.getFile(file); + let text = null; try { text = fs.readFileSync(path, 'utf8'); @@ -193,15 +192,13 @@ Config.prototype.has = function has(key) { */ Config.prototype.get = function get(key, fallback) { - let keys, value; - if (fallback === undefined) fallback = null; if (Array.isArray(key)) { - keys = key; + const keys = key; for (const key of keys) { - value = this.get(key); + const value = this.get(key); if (value !== null) return value; } @@ -406,7 +403,6 @@ Config.prototype.bool = function bool(key, fallback) { Config.prototype.buf = function buf(key, fallback) { const value = this.get(key); - let data; if (fallback === undefined) fallback = null; @@ -420,7 +416,7 @@ Config.prototype.buf = function buf(key, fallback) { return value; } - data = Buffer.from(value, 'hex'); + const data = Buffer.from(value, 'hex'); if (data.length !== value.length / 2) throw new Error(`${key} must be a hex string.`); @@ -437,7 +433,6 @@ Config.prototype.buf = function buf(key, fallback) { Config.prototype.array = function array(key, fallback) { const value = this.get(key); - let result, parts; if (fallback === undefined) fallback = null; @@ -451,8 +446,8 @@ Config.prototype.array = function array(key, fallback) { return value; } - parts = value.trim().split(/\s*,\s*/); - result = []; + const parts = value.trim().split(/\s*,\s*/); + const result = []; for (const part of parts) { if (part.length === 0) @@ -582,7 +577,6 @@ Config.prototype.getNetwork = function getNetwork() { Config.prototype.getPrefix = function getPrefix() { let prefix = this.str('prefix'); - let network; if (prefix) { if (prefix[0] === '~') @@ -591,7 +585,8 @@ Config.prototype.getPrefix = function getPrefix() { } prefix = path.join(HOME, `.${this.module}`); - network = this.str('network'); + + const network = this.str('network'); if (network) { assert(isAlpha(network), 'Bad network.'); @@ -647,16 +642,13 @@ Config.prototype.location = function location(file) { */ Config.prototype.parseConfig = function parseConfig(text) { - let parts; - assert(typeof text === 'string', 'Config must be text.'); text = text.trim(); - parts = text.split(/\n+/); + + const parts = text.split(/\n+/); for (let line of parts) { - let key, value, eq, col, alias; - line = line.trim(); if (line.length === 0) @@ -665,12 +657,14 @@ Config.prototype.parseConfig = function parseConfig(text) { if (/^\s*#/.test(line)) continue; - eq = line.indexOf('='); - col = line.indexOf(':'); + let eq = line.indexOf('='); + const col = line.indexOf(':'); if (col !== -1 && (col < eq || eq === -1)) eq = col; + let key, value; + if (eq === -1) { key = line.trim(); value = ''; @@ -681,7 +675,8 @@ Config.prototype.parseConfig = function parseConfig(text) { key = key.replace(/\-/g, '').toLowerCase(); - alias = Config.alias.conf[key]; + const alias = Config.alias.conf[key]; + if (alias) key = alias; @@ -702,13 +697,13 @@ Config.prototype.parseConfig = function parseConfig(text) { */ Config.prototype.parseArg = function parseArg(argv) { - let key; - if (!argv || typeof argv !== 'object') argv = process.argv; assert(Array.isArray(argv)); + let key = null; + for (let i = 2; i < argv.length; i++) { let arg = argv[i]; let value, alias, equals; @@ -796,14 +791,12 @@ Config.prototype.parseEnv = function parseEnv(env) { assert(env && typeof env === 'object'); for (let key of Object.keys(env)) { - let value, alias; - if (key.indexOf(prefix) !== 0) continue; assert(typeof env[key] === 'string'); - value = env[key].trim(); + const value = env[key].trim(); key = key.substring(prefix.length); key = key.replace(/_/g, '').toLowerCase(); @@ -814,7 +807,8 @@ Config.prototype.parseEnv = function parseEnv(env) { if (value.length === 0) continue; - alias = Config.alias.env[key]; + const alias = Config.alias.env[key]; + if (alias) key = alias; @@ -869,8 +863,6 @@ Config.prototype.parseHash = function parseHash(hash) { */ Config.prototype.parseForm = function parseForm(query, map) { - let parts; - assert(typeof query === 'string'); if (query.length === 0) @@ -879,11 +871,12 @@ Config.prototype.parseForm = function parseForm(query, map) { if (query[0] === '?' || query[0] === '#') query = query.substring(1); - parts = query.split('&'); + const parts = query.split('&'); for (const pair of parts) { const index = pair.indexOf('='); - let key, value, alias; + + let key, value; if (index === -1) { key = pair; @@ -904,7 +897,8 @@ Config.prototype.parseForm = function parseForm(query, map) { if (value.length === 0) continue; - alias = Config.alias.env[key]; + const alias = Config.alias.env[key]; + if (alias) key = alias; diff --git a/lib/node/logger.js b/lib/node/logger.js index 8f1d047a..f9950e20 100644 --- a/lib/node/logger.js +++ b/lib/node/logger.js @@ -254,7 +254,6 @@ Logger.prototype._close = async function close() { Logger.prototype.truncate = async function truncate() { const maxSize = Logger.MAX_FILE_SIZE; - let stat, data, fd; if (!this.filename) return; @@ -264,6 +263,8 @@ Logger.prototype.truncate = async function truncate() { assert(!this.stream); + let stat = null; + try { stat = await fs.stat(this.filename); } catch (e) { @@ -277,9 +278,9 @@ Logger.prototype.truncate = async function truncate() { this.debug('Truncating log file to %d bytes.', maxSize); - fd = await fs.open(this.filename, 'r+'); + const fd = await fs.open(this.filename, 'r+'); + const data = Buffer.allocUnsafe(maxSize); - data = Buffer.allocUnsafe(maxSize); await fs.read(fd, data, 0, maxSize, stat.size - maxSize); await fs.ftruncate(fd, maxSize); await fs.write(fd, data, 0, maxSize, 0); @@ -518,7 +519,6 @@ Logger.prototype.context = function _context(module) { Logger.prototype.writeConsole = function writeConsole(level, module, args) { const name = Logger.levelsByVal[level]; let msg = ''; - let color; assert(name, 'Invalid log level.'); @@ -545,7 +545,7 @@ Logger.prototype.writeConsole = function writeConsole(level, module, args) { } if (this.colors) { - color = Logger.styles[level]; + const color = Logger.styles[level]; assert(color); msg += `\x1b[${color}m[${name}]\x1b[m `; @@ -604,8 +604,6 @@ Logger.prototype.writeStream = function writeStream(level, module, args) { */ Logger.prototype.logError = function logError(level, module, err) { - let msg; - if (this.closed) return; @@ -614,7 +612,7 @@ Logger.prototype.logError = function logError(level, module, err) { console.error(err); } - msg = (err.message + '').replace(/^ *Error: */, ''); + let msg = (err.message + '').replace(/^ *Error: */, ''); if (level !== Logger.levels.ERROR) msg = `Error: ${msg}`; @@ -843,6 +841,11 @@ function openStream(filename) { return new Promise((resolve, reject) => { const stream = fs.createWriteStream(filename, { flags: 'a' }); + const cleanup = () => { + stream.removeListener('error', onError); + stream.removeListener('open', onOpen); + }; + const onError = (err) => { try { stream.close(); @@ -858,11 +861,6 @@ function openStream(filename) { resolve(stream); }; - let cleanup = () => { - stream.removeListener('error', onError); - stream.removeListener('open', onOpen); - }; - stream.once('error', onError); stream.once('open', onOpen); }); @@ -870,6 +868,11 @@ function openStream(filename) { function closeStream(stream) { return new Promise((resolve, reject) => { + const cleanup = () => { + stream.removeListener('error', onError); + stream.removeListener('close', onClose); + }; + const onError = (err) => { cleanup(); reject(err); @@ -880,11 +883,6 @@ function closeStream(stream) { resolve(stream); }; - let cleanup = () => { - stream.removeListener('error', onError); - stream.removeListener('close', onClose); - }; - stream.removeAllListeners('error'); stream.removeAllListeners('close'); stream.once('error', onError); diff --git a/lib/node/node.js b/lib/node/node.js index 7f11f8eb..fe03392a 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -267,14 +267,12 @@ Node.prototype.uptime = function uptime() { */ Node.prototype.use = function use(plugin) { - let instance; - assert(plugin, 'Plugin must be an object.'); assert(typeof plugin.init === 'function', '`init` must be a function.'); assert(!this.loaded, 'Cannot add plugin after node is loaded.'); - instance = plugin.init(this); + const instance = plugin.init(this); assert(!instance.open || typeof instance.open === 'function', '`open` must be a function.'); diff --git a/lib/primitives/address.js b/lib/primitives/address.js index eb6ebdd4..d6487a11 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -135,13 +135,12 @@ Address.prototype.getType = function getType() { */ Address.prototype.getPrefix = function getPrefix(network) { - let prefixes; - if (!network) network = this.network; network = Network.get(network); - prefixes = network.addressPrefix; + + const prefixes = network.addressPrefix; switch (this.type) { case Address.types.PUBKEYHASH: @@ -223,7 +222,6 @@ Address.prototype.toBase58 = function toBase58(network) { Address.prototype.toBech32 = function toBech32(network) { const version = this.version; const hash = this.hash; - let hrp; assert(version !== -1, 'Cannot convert non-program address to bech32.'); @@ -232,7 +230,8 @@ Address.prototype.toBech32 = function toBech32(network) { network = this.network; network = Network.get(network); - hrp = network.addressPrefix.bech32; + + const hrp = network.addressPrefix.bech32; return bech32.encode(hrp, version, hash); }; @@ -308,16 +307,17 @@ Address.prototype.inspect = function inspect() { Address.prototype.fromRaw = function fromRaw(data, network) { const br = new BufferReader(data, true); - let version = -1; - let prefix, type, hash; if (data.length > 40) throw new Error('Address is too long.'); - prefix = br.readU8(); - network = Network.fromAddress(prefix, network); - type = Address.getType(prefix, network); + const prefix = br.readU8(); + network = Network.fromAddress(prefix, network); + + const type = Address.getType(prefix, network); + + let version = -1; if (data.length > 25) { version = br.readU8(); @@ -325,7 +325,7 @@ Address.prototype.fromRaw = function fromRaw(data, network) { throw new Error('Address version padding is non-zero.'); } - hash = br.readBytes(br.left() - 4); + const hash = br.readBytes(br.left() - 4); br.verifyChecksum(); @@ -382,11 +382,11 @@ Address.fromBase58 = function fromBase58(data, network) { Address.prototype.fromBech32 = function fromBech32(data, network) { const type = Address.types.WITNESS; - let addr; assert(typeof data === 'string'); - addr = bech32.decode(data); + const addr = bech32.decode(data); + network = Network.fromBech32(addr.hrp, network); return this.fromHash(addr.hash, type, addr.version, network); diff --git a/lib/primitives/block.js b/lib/primitives/block.js index 6410f3f6..385bcba0 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -120,12 +120,10 @@ Block.prototype.toNormal = function toNormal() { */ Block.prototype.toWriter = function toWriter(bw) { - let raw; - if (this.mutable) return this.writeWitness(bw); - raw = this.frame(); + const raw = this.frame(); bw.writeBytes(raw.data); return bw; @@ -152,8 +150,6 @@ Block.prototype.toNormalWriter = function toNormalWriter(bw) { */ Block.prototype.frame = function frame() { - let raw; - if (this.mutable) { assert(!this._raw); return this.frameWitness(); @@ -162,12 +158,12 @@ Block.prototype.frame = function frame() { if (this._raw) { assert(this._size >= 0); assert(this._witness >= 0); - raw = new RawBlock(this._size, this._witness); + const raw = new RawBlock(this._size, this._witness); raw.data = this._raw; return raw; } - raw = this.frameWitness(); + const raw = this.frameWitness(); this._raw = raw.data; this._size = raw.size; @@ -280,12 +276,11 @@ Block.prototype.indexOf = function indexOf(hash) { Block.prototype.createMerkleRoot = function createMerkleRoot(enc) { const leaves = []; - let root, malleated; for (const tx of this.txs) leaves.push(tx.hash()); - [root, malleated] = merkle.createRoot(leaves); + const [root, malleated] = merkle.createRoot(leaves); if (malleated) return null; @@ -312,7 +307,6 @@ Block.prototype.createWitnessNonce = function createWitnessNonce() { Block.prototype.createCommitmentHash = function createCommitmentHash(enc) { const nonce = this.getWitnessNonce(); const leaves = []; - let root, hash; assert(nonce, 'No witness nonce present.'); @@ -323,12 +317,12 @@ Block.prototype.createCommitmentHash = function createCommitmentHash(enc) { leaves.push(tx.witnessHash()); } - [root] = merkle.createRoot(leaves); + const [root] = merkle.createRoot(leaves); // Note: malleation check ignored here. // assert(!malleated); - hash = digest.root256(root, nonce); + const hash = digest.root256(root, nonce); return enc === 'hex' ? hash.toString('hex') @@ -354,17 +348,15 @@ Block.prototype.getMerkleRoot = function getMerkleRoot(enc) { */ Block.prototype.getWitnessNonce = function getWitnessNonce() { - let coinbase, input; - if (this.txs.length === 0) return null; - coinbase = this.txs[0]; + const coinbase = this.txs[0]; if (coinbase.inputs.length !== 1) return null; - input = coinbase.inputs[0]; + const input = coinbase.inputs[0]; if (input.witness.items.length !== 1) return null; @@ -383,12 +375,11 @@ Block.prototype.getWitnessNonce = function getWitnessNonce() { */ Block.prototype.getCommitmentHash = function getCommitmentHash(enc) { - let coinbase, hash; - if (this.txs.length === 0) return null; - coinbase = this.txs[0]; + const coinbase = this.txs[0]; + let hash = null; for (let i = coinbase.outputs.length - 1; i >= 0; i--) { const output = coinbase.outputs[i]; @@ -424,12 +415,8 @@ Block.prototype.verifyBody = function verifyBody() { */ Block.prototype.checkBody = function checkBody() { - let sigops = 0; - const scale = consensus.WITNESS_SCALE_FACTOR; - let root; - // Check merkle root. - root = this.createMerkleRoot('hex'); + const root = this.createMerkleRoot('hex'); // If the merkle is mutated, // we have duplicate txs. @@ -451,16 +438,18 @@ Block.prototype.checkBody = function checkBody() { return [false, 'bad-cb-missing', 100]; // Test all transactions. + const scale = consensus.WITNESS_SCALE_FACTOR; + let sigops = 0; + for (let i = 0; i < this.txs.length; i++) { const tx = this.txs[i]; - let valid, reason, score; // The rest of the txs must not be coinbases. if (i > 0 && tx.isCoinbase()) return [false, 'bad-cb-multiple', 100]; // Sanity checks. - [valid, reason, score] = tx.checkSanity(); + const [valid, reason, score] = tx.checkSanity(); if (!valid) return [valid, reason, score]; @@ -480,15 +469,13 @@ Block.prototype.checkBody = function checkBody() { */ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() { - let coinbase; - if (this.version < 2) return -1; if (this.txs.length === 0) return -1; - coinbase = this.txs[0]; + const coinbase = this.txs[0]; if (coinbase.inputs.length === 0) return -1; @@ -640,14 +627,12 @@ Block.fromJSON = function fromJSON(json) { */ Block.prototype.fromReader = function fromReader(br) { - let witness = 0; - let count; - br.start(); this.readHead(br); - count = br.readVarint(); + const count = br.readVarint(); + let witness = 0; for (let i = 0; i < count; i++) { const tx = TX.fromReader(br); diff --git a/lib/primitives/input.js b/lib/primitives/input.js index d5633615..6fa4932c 100644 --- a/lib/primitives/input.js +++ b/lib/primitives/input.js @@ -98,14 +98,14 @@ Input.prototype.clone = function clone() { */ Input.prototype.getType = function getType(coin) { - let type; - if (this.isCoinbase()) return 'coinbase'; if (coin) return coin.getType(); + let type; + if (this.witness.items.length > 0) type = this.witness.getInputType(); else @@ -122,8 +122,6 @@ Input.prototype.getType = function getType(coin) { */ Input.prototype.getRedeem = function getRedeem(coin) { - let redeem, prev; - if (this.isCoinbase()) return; @@ -137,7 +135,8 @@ Input.prototype.getRedeem = function getRedeem(coin) { return; } - prev = coin.script; + let prev = coin.script; + let redeem = null; if (prev.isScripthash()) { prev = this.script.getRedeem(); @@ -159,17 +158,15 @@ Input.prototype.getRedeem = function getRedeem(coin) { */ Input.prototype.getSubtype = function getSubtype(coin) { - let redeem, type; - if (this.isCoinbase()) return; - redeem = this.getRedeem(coin); + const redeem = this.getRedeem(coin); if (!redeem) return; - type = redeem.getType(); + const type = redeem.getType(); return Script.typesByVal[type].toLowerCase(); }; @@ -203,8 +200,10 @@ Input.prototype.getAddress = function getAddress(coin) { Input.prototype.getHash = function getHash(enc) { const addr = this.getAddress(); + if (!addr) return; + return addr.getHash(enc); }; diff --git a/lib/primitives/keyring.js b/lib/primitives/keyring.js index 8224df85..49e08a3b 100644 --- a/lib/primitives/keyring.js +++ b/lib/primitives/keyring.js @@ -176,14 +176,12 @@ KeyRing.prototype.fromPublic = function fromPublic(key, network) { */ KeyRing.prototype.generate = function generate(compressed, network) { - let key; - if (typeof compressed !== 'boolean') { network = compressed; compressed = null; } - key = secp256k1.generatePrivateKey(); + const key = secp256k1.generatePrivateKey(); return this.fromKey(key, compressed, network); }; @@ -331,18 +329,18 @@ KeyRing.prototype.toSecret = function toSecret(network) { KeyRing.prototype.fromSecret = function fromSecret(data, network) { const br = new BufferReader(base58.decode(data), true); - let version, key, compressed; - version = br.readU8(); + const version = br.readU8(); + network = Network.fromWIF(version, network); - key = br.readBytes(32); + const key = br.readBytes(32); + + let compressed = false; if (br.left() > 4) { assert(br.readU8() === 1, 'Bad compression flag.'); compressed = true; - } else { - compressed = false; } br.verifyChecksum(); @@ -411,17 +409,16 @@ KeyRing.prototype.getScript = function getScript() { */ KeyRing.prototype.getProgram = function getProgram() { - let hash, program; - if (!this.witness) return; if (!this._program) { + let program; if (!this.script) { - hash = digest.hash160(this.publicKey); + const hash = digest.hash160(this.publicKey); program = Script.fromProgram(0, hash); } else { - hash = this.script.sha256(); + const hash = this.script.sha256(); program = Script.fromProgram(0, hash); } this._program = program; @@ -456,15 +453,13 @@ KeyRing.prototype.getNestedHash = function getNestedHash(enc) { */ KeyRing.prototype.getNestedAddress = function getNestedAddress(enc) { - let hash, address; - if (!this.witness) return; if (!this._nestedAddress) { - hash = this.getNestedHash(); - address = Address.fromScripthash(hash, this.network); - this._nestedAddress = address; + const hash = this.getNestedHash(); + const addr = Address.fromScripthash(hash, this.network); + this._nestedAddress = addr; } if (enc === 'base58') @@ -531,20 +526,19 @@ KeyRing.prototype.getScriptHash256 = function getScriptHash256(enc) { */ KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) { - let hash, address; - if (!this.script) return; if (!this._scriptAddress) { + let addr; if (this.witness) { - hash = this.getScriptHash256(); - address = Address.fromWitnessScripthash(hash, this.network); + const hash = this.getScriptHash256(); + addr = Address.fromWitnessScripthash(hash, this.network); } else { - hash = this.getScriptHash160(); - address = Address.fromScripthash(hash, this.network); + const hash = this.getScriptHash160(); + addr = Address.fromScripthash(hash, this.network); } - this._scriptAddress = address; + this._scriptAddress = addr; } if (enc === 'base58') @@ -578,15 +572,16 @@ KeyRing.prototype.getKeyHash = function getKeyHash(enc) { */ KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) { - let hash, address; - if (!this._keyAddress) { - hash = this.getKeyHash(); + const hash = this.getKeyHash(); + let addr; + if (this.witness) - address = Address.fromWitnessPubkeyhash(hash, this.network); + addr = Address.fromWitnessPubkeyhash(hash, this.network); else - address = Address.fromPubkeyhash(hash, this.network); - this._keyAddress = address; + addr = Address.fromPubkeyhash(hash, this.network); + + this._keyAddress = addr; } if (enc === 'base58') @@ -880,16 +875,14 @@ KeyRing.prototype.toRaw = function toRaw() { */ KeyRing.prototype.fromReader = function fromReader(br, network) { - let field, key, script; - this.network = Network.get(network); - field = br.readU8(); + const field = br.readU8(); this.witness = (field & 1) !== 0; this.nested = (field & 2) !== 0; - key = br.readVarBytes(); + const key = br.readVarBytes(); if (key.length === 32) { const compressed = br.readU8() === 1; @@ -900,7 +893,7 @@ KeyRing.prototype.fromReader = function fromReader(br, network) { assert(secp256k1.publicKeyVerify(key), 'Invalid public key.'); } - script = br.readVarBytes(); + const script = br.readVarBytes(); if (script.length > 0) this.script = Script.fromRaw(script); diff --git a/lib/primitives/memblock.js b/lib/primitives/memblock.js index 498fe2c9..fc913a14 100644 --- a/lib/primitives/memblock.js +++ b/lib/primitives/memblock.js @@ -109,7 +109,7 @@ MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() { MemBlock.prototype.parseCoinbaseHeight = function parseCoinbaseHeight() { const br = new BufferReader(this._raw, true); - let count, script; + let count; br.seek(80); @@ -132,7 +132,7 @@ MemBlock.prototype.parseCoinbaseHeight = function parseCoinbaseHeight() { br.seek(36); - script = br.readVarBytes(); + const script = br.readVarBytes(); return Script.getCoinbaseHeight(script); }; diff --git a/lib/primitives/merkleblock.js b/lib/primitives/merkleblock.js index 85c93ad8..f397dcc9 100644 --- a/lib/primitives/merkleblock.js +++ b/lib/primitives/merkleblock.js @@ -184,31 +184,29 @@ MerkleBlock.prototype.getTree = function getTree() { */ MerkleBlock.prototype.extractTree = function extractTree() { - let bitsUsed = 0; - let hashUsed = 0; const matches = []; const indexes = []; const map = new Map(); - let failed = false; const hashes = this.hashes; const flags = this.flags; const totalTX = this.totalTX; + let bitsUsed = 0; + let hashUsed = 0; + let failed = false; let height = 0; - let root; const width = (height) => { return (totalTX + (1 << height) - 1) >>> height; }; const traverse = (height, pos) => { - let parent, hash, left, right; - if (bitsUsed >= flags.length * 8) { failed = true; return encoding.ZERO_HASH; } - parent = (flags[bitsUsed / 8 | 0] >>> (bitsUsed % 8)) & 1; + const parent = (flags[bitsUsed / 8 | 0] >>> (bitsUsed % 8)) & 1; + bitsUsed++; if (height === 0 || !parent) { @@ -217,7 +215,7 @@ MerkleBlock.prototype.extractTree = function extractTree() { return encoding.ZERO_HASH; } - hash = hashes[hashUsed++]; + const hash = hashes[hashUsed++]; if (height === 0 && parent) { const txid = hash.toString('hex'); @@ -229,7 +227,8 @@ MerkleBlock.prototype.extractTree = function extractTree() { return hash; } - left = traverse(height - 1, pos * 2); + const left = traverse(height - 1, pos * 2); + let right = null; if (pos * 2 + 1 < width(height - 1)) { right = traverse(height - 1, pos * 2 + 1); @@ -257,7 +256,7 @@ MerkleBlock.prototype.extractTree = function extractTree() { while (width(height) > 1) height++; - root = traverse(height, 0); + const root = traverse(height, 0); if (failed) throw new Error('Mutated merkle tree.'); @@ -373,13 +372,11 @@ MerkleBlock.prototype.toRaw = function toRaw() { */ MerkleBlock.prototype.fromReader = function fromReader(br) { - let count; - this.readHead(br); this.totalTX = br.readU32(); - count = br.readVarint(); + const count = br.readVarint(); for (let i = 0; i < count; i++) this.hashes.push(br.readHash()); @@ -556,19 +553,17 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) { const hashes = []; const totalTX = block.txs.length; let height = 0; - let flags, merkle; const width = (height) => { return (totalTX + (1 << height) - 1) >>> height; }; const hash = (height, pos, leaves) => { - let left, right; - if (height === 0) return leaves[pos]; - left = hash(height - 1, pos * 2, leaves); + const left = hash(height - 1, pos * 2, leaves); + let right = null; if (pos * 2 + 1 < width(height - 1)) right = hash(height - 1, pos * 2 + 1, leaves); @@ -611,13 +606,13 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) { traverse(height, 0, leaves, matches); - flags = Buffer.allocUnsafe((bits.length + 7) / 8 | 0); + const flags = Buffer.allocUnsafe((bits.length + 7) / 8 | 0); flags.fill(0); for (let p = 0; p < bits.length; p++) flags[p / 8 | 0] |= bits[p] << (p % 8); - merkle = new MerkleBlock(); + const merkle = new MerkleBlock(); merkle._hash = block._hash; merkle._hhash = block._hhash; merkle.version = block.version; diff --git a/lib/primitives/mtx.js b/lib/primitives/mtx.js index 351e567a..f4a23d62 100644 --- a/lib/primitives/mtx.js +++ b/lib/primitives/mtx.js @@ -172,11 +172,9 @@ MTX.prototype.addOutpoint = function addOutpoint(outpoint) { */ MTX.prototype.addCoin = function addCoin(coin) { - let input; - assert(coin instanceof Coin, 'Cannot add non-coin.'); - input = Input.fromCoin(coin); + const input = Input.fromCoin(coin); this.inputs.push(input); this.view.addCoin(coin); @@ -198,15 +196,13 @@ MTX.prototype.addCoin = function addCoin(coin) { */ MTX.prototype.addTX = function addTX(tx, index, height) { - let input, coin; - assert(tx instanceof TX, 'Cannot add non-transaction.'); if (height == null) height = -1; - input = Input.fromTX(tx, index); - coin = Coin.fromTX(tx, index, height); + const input = Input.fromTX(tx, index); + const coin = Coin.fromTX(tx, index, height); this.inputs.push(input); this.view.addCoin(coin); @@ -439,7 +435,6 @@ MTX.prototype.checkInputs = function checkInputs(height) { MTX.prototype.scriptInput = function scriptInput(index, coin, ring) { const input = this.inputs[index]; - let prev; assert(input, 'Input does not exist.'); assert(coin, 'No coin passed.'); @@ -452,7 +447,7 @@ MTX.prototype.scriptInput = function scriptInput(index, coin, ring) { } // Get the previous output's script - prev = coin.script; + let prev = coin.script; // This is easily the hardest part about // building a transaction with segwit: @@ -583,8 +578,6 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, ring) { // Multisig if (prev.isMultisig()) { - let n; - if (prev.indexOf(ring.publicKey) === -1) return false; @@ -594,7 +587,7 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, ring) { vector.set(0, opcodes.OP_0); // Grab `n` value (number of keys). - n = prev.getSmall(prev.length - 2); + const n = prev.getSmall(prev.length - 2); // Fill script with `n` signature slots. for (let i = 0; i < n; i++) @@ -635,18 +628,17 @@ MTX.prototype.signInputAsync = function signInputAsync(index, coin, ring, type, MTX.prototype.signInput = function signInput(index, coin, ring, type) { const input = this.inputs[index]; - let version = 0; - let redeem = false; const key = ring.privateKey; - let prev, value, vector, sig, result; assert(input, 'Input does not exist.'); assert(coin, 'No coin passed.'); // Get the previous output's script - prev = coin.script; - value = coin.value; - vector = input.script; + const value = coin.value; + let prev = coin.script; + let vector = input.script; + let version = 0; + let redeem = false; // Grab regular p2sh redeem script. if (prev.isScripthash()) { @@ -677,11 +669,11 @@ MTX.prototype.signInput = function signInput(index, coin, ring, type) { } // Create our signature. - sig = this.signature(index, prev, value, key, type, version); + const sig = this.signature(index, prev, value, key, type, version); if (redeem) { - redeem = vector.pop(); - result = this.signVector(prev, vector, sig, ring); + const redeem = vector.pop(); + const result = this.signVector(prev, vector, sig, ring); vector.push(redeem); vector.compile(); return result; @@ -741,9 +733,7 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) { // Multisig if (prev.isMultisig()) { - let total = 0; const keys = []; - let keyIndex; // Grab `m` value (number of sigs required). const m = prev.getSmall(0); @@ -764,6 +754,7 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) { return false; // Count the number of current signatures. + let total = 0; for (let i = 1; i < vector.length; i++) { if (Script.isSignature(vector.get(i))) total++; @@ -780,7 +771,7 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) { // Find the key index so we can place // the signature in the same index. - keyIndex = util.indexOf(keys, ring.publicKey); + let keyIndex = util.indexOf(keys, ring.publicKey); // Our public key is not in the prev_out // script. We tried to sign a transaction @@ -863,14 +854,13 @@ MTX.prototype.isSigned = function isSigned() { MTX.prototype.isInputSigned = function isInputSigned(index, coin) { const input = this.inputs[index]; - let prev, vector, redeem, result; assert(input, 'Input does not exist.'); assert(coin, 'No coin passed.'); - prev = coin.script; - vector = input.script; - redeem = false; + let prev = coin.script; + let vector = input.script; + let redeem = false; // Grab redeem script if possible. if (prev.isScripthash()) { @@ -896,8 +886,8 @@ MTX.prototype.isInputSigned = function isInputSigned(index, coin) { } if (redeem) { - redeem = vector.pop(); - result = this.isVectorSigned(prev, vector); + const redeem = vector.pop(); + const result = this.isVectorSigned(prev, vector); vector.push(redeem); return result; } @@ -954,14 +944,15 @@ MTX.prototype.isVectorSigned = function isVectorSigned(prev, vector) { */ MTX.prototype.template = function template(ring) { - let total = 0; - if (Array.isArray(ring)) { + let total = 0; for (const key of ring) total += this.template(key); return total; } + let total = 0; + for (let i = 0; i < this.inputs.length; i++) { const {prevout} = this.inputs[i]; const coin = this.view.getOutput(prevout); @@ -991,9 +982,8 @@ MTX.prototype.template = function template(ring) { */ MTX.prototype.sign = function sign(ring, type) { - let total = 0; - if (Array.isArray(ring)) { + let total = 0; for (const key of ring) total += this.sign(key, type); return total; @@ -1001,6 +991,8 @@ MTX.prototype.sign = function sign(ring, type) { assert(ring.privateKey, 'No private key available.'); + let total = 0; + for (let i = 0; i < this.inputs.length; i++) { const {prevout} = this.inputs[i]; const coin = this.view.getOutput(prevout); @@ -1066,8 +1058,6 @@ MTX.prototype.estimateSize = async function estimateSize(estimate) { // Add size for signatures and public keys for (const {prevout} of this.inputs) { const coin = this.view.getOutput(prevout); - let size = 0; - let prev; // We're out of luck here. // Just assume it's a p2pkh. @@ -1077,31 +1067,30 @@ MTX.prototype.estimateSize = async function estimateSize(estimate) { } // Previous output script. - prev = coin.script; + const prev = coin.script; // P2PK if (prev.isPubkey()) { // varint script size - size += 1; + total += 1; // OP_PUSHDATA0 [signature] - size += 1 + 73; - total += size; + total += 1 + 73; continue; } // P2PKH if (prev.isPubkeyhash()) { // varint script size - size += 1; + total += 1; // OP_PUSHDATA0 [signature] - size += 1 + 73; + total += 1 + 73; // OP_PUSHDATA0 [key] - size += 1 + 33; - total += size; + total += 1 + 33; continue; } if (prev.isMultisig()) { + let size = 0; // Bare Multisig // OP_0 size += 1; @@ -1115,6 +1104,7 @@ MTX.prototype.estimateSize = async function estimateSize(estimate) { // P2WPKH if (prev.isWitnessPubkeyhash()) { + let size = 0; // varint-items-len size += 1; // varint-len [signature] @@ -1129,7 +1119,7 @@ MTX.prototype.estimateSize = async function estimateSize(estimate) { // Call out to the custom estimator. if (estimate) { - size = await estimate(prev); + const size = await estimate(prev); if (size !== -1) { total += size; continue; @@ -1147,6 +1137,7 @@ MTX.prototype.estimateSize = async function estimateSize(estimate) { // P2WSH if (prev.isWitnessScripthash()) { + let size = 0; // varint-items-len size += 1; // 2-of-3 multisig input @@ -1186,12 +1177,11 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) { MTX.prototype.subtractFee = function subtractFee(fee, index) { if (typeof index === 'number') { const output = this.outputs[index]; - let min; if (!output) throw new Error('Subtraction index does not exist.'); - min = fee + output.getDustThreshold(); + const min = fee + output.getDustThreshold(); if (output.value < min) throw new Error('Could not subtract fee.'); @@ -1221,14 +1211,12 @@ MTX.prototype.subtractFee = function subtractFee(fee, index) { */ MTX.prototype.fund = async function fund(coins, options) { - let select, change; - assert(options, 'Options are required.'); assert(options.changeAddress, 'Change address is required.'); assert(this.inputs.length === 0, 'TX is already funded.'); // Select necessary coins. - select = await this.selectCoins(coins, options); + const select = await this.selectCoins(coins, options); // Add coins to transaction. for (const coin of select.chosen) @@ -1239,7 +1227,7 @@ MTX.prototype.fund = async function fund(coins, options) { this.subtractFee(select.fee, select.subtractFee); // Add a change output. - change = new Output(); + const change = new Output(); change.value = select.change; change.script.fromAddress(select.changeAddress); @@ -1262,7 +1250,7 @@ MTX.prototype.fund = async function fund(coins, options) { */ MTX.prototype.sortMembers = function sortMembers() { - let changeOutput; + let changeOutput = null; if (this.changeIndex !== -1) { changeOutput = this.outputs[this.changeIndex]; @@ -1649,8 +1637,6 @@ CoinSelector.prototype.isFull = function isFull() { */ CoinSelector.prototype.isSpendable = function isSpendable(coin) { - let depth; - if (this.height === -1) return true; @@ -1667,7 +1653,7 @@ CoinSelector.prototype.isSpendable = function isSpendable(coin) { if (this.depth === -1) return true; - depth = coin.getDepth(this.height); + const depth = coin.getDepth(this.height); if (depth < this.depth) return false; @@ -1759,15 +1745,13 @@ CoinSelector.prototype.select = async function select(coins) { */ CoinSelector.prototype.selectEstimate = async function selectEstimate() { - let change; - // Set minimum fee and do // an initial round of funding. this.fee = CoinSelector.MIN_FEE; this.fund(); // Add dummy output for change. - change = new Output(); + const change = new Output(); if (this.changeAddress) { change.script.fromAddress(this.changeAddress); diff --git a/lib/primitives/netaddress.js b/lib/primitives/netaddress.js index 1b7f77ea..3ead8704 100644 --- a/lib/primitives/netaddress.js +++ b/lib/primitives/netaddress.js @@ -278,11 +278,9 @@ NetAddress.fromHost = function fromHost(host, port, network) { */ NetAddress.prototype.fromHostname = function fromHostname(hostname, network) { - let addr; - network = Network.get(network); - addr = IP.fromHostname(hostname, network.port); + const addr = IP.fromHostname(hostname, network.port); return this.fromHost(addr.host, addr.port, network); }; diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index e1e10411..19c67779 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -207,11 +207,11 @@ TX.prototype.hash = function _hash(enc) { */ TX.prototype.witnessHash = function witnessHash(enc) { - let hash = this._whash; - if (!this.hasWitness()) return this.hash(enc); + let hash = this._whash; + if (!hash) { hash = digest.hash256(this.toRaw()); if (!this.mutable) @@ -287,8 +287,6 @@ TX.prototype.toNormalWriter = function toNormalWriter(bw) { */ TX.prototype.frame = function frame() { - let raw; - if (this.mutable) { assert(!this._raw); if (this.hasWitness()) @@ -299,11 +297,13 @@ TX.prototype.frame = function frame() { if (this._raw) { assert(this._size >= 0); assert(this._witness >= 0); - raw = new RawTX(this._size, this._witness); + const raw = new RawTX(this._size, this._witness); raw.data = this._raw; return raw; } + let raw; + if (this.hasWitness()) raw = this.frameWitness(); else @@ -445,8 +445,6 @@ TX.prototype.signatureHash = function signatureHash(index, prev, value, type, ve */ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) { - let size, bw; - if ((type & 0x1f) === hashType.SINGLE) { // Bitcoind used to return 1 as an error code: // it ended up being treated like a hash. @@ -458,9 +456,8 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) { prev = prev.removeSeparators(); // Calculate buffer size. - size = this.hashSize(index, prev, type); - - bw = new StaticWriter(size); + const size = this.hashSize(index, prev, type); + const bw = new StaticWriter(size); bw.writeU32(this.version); @@ -615,11 +612,10 @@ TX.prototype.hashSize = function hashSize(index, prev, type) { */ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type) { + const input = this.inputs[index]; let prevouts = encoding.ZERO_HASH; let sequences = encoding.ZERO_HASH; let outputs = encoding.ZERO_HASH; - const input = this.inputs[index]; - let bw, size; if (!(type & hashType.ANYONECANPAY)) { if (this._hashPrevouts) { @@ -661,12 +657,11 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type outputs = this._hashOutputs; } else { let size = 0; - let bw; for (const output of this.outputs) size += output.getSize(); - bw = new StaticWriter(size); + const bw = new StaticWriter(size); for (const output of this.outputs) output.toWriter(bw); @@ -681,8 +676,8 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type outputs = digest.hash256(output.toRaw()); } - size = 156 + prev.getVarSize(); - bw = new StaticWriter(size); + const size = 156 + prev.getVarSize(); + const bw = new StaticWriter(size); bw.writeU32(this.version); bw.writeBytes(prevouts); @@ -711,13 +706,11 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type */ TX.prototype.checksig = function checksig(index, prev, value, sig, key, version) { - let type, hash; - if (sig.length === 0) return false; - type = sig[sig.length - 1]; - hash = this.signatureHash(index, prev, value, type, version); + const type = sig[sig.length - 1]; + const hash = this.signatureHash(index, prev, value, type, version); return secp256k1.verify(hash, sig.slice(0, -1), key); }; @@ -736,18 +729,15 @@ TX.prototype.checksig = function checksig(index, prev, value, sig, key, version) */ TX.prototype.signature = function signature(index, prev, value, key, type, version) { - let hash, sig, bw; - if (type == null) type = hashType.ALL; if (version == null) version = 0; - hash = this.signatureHash(index, prev, value, type, version); - - sig = secp256k1.sign(hash, key); - bw = new StaticWriter(sig.length + 1); + const hash = this.signatureHash(index, prev, value, type, version); + const sig = secp256k1.sign(hash, key); + const bw = new StaticWriter(sig.length + 1); bw.writeBytes(sig); bw.writeU8(type); @@ -1022,12 +1012,11 @@ TX.prototype._getInputAddresses = function getInputAddresses(view) { for (const input of this.inputs) { const coin = view ? view.getOutputFor(input) : null; const addr = input.getAddress(coin); - let hash; if (!addr) continue; - hash = addr.getHash('hex'); + const hash = addr.getHash('hex'); if (!table[hash]) { table[hash] = true; @@ -1050,12 +1039,11 @@ TX.prototype._getOutputAddresses = function getOutputAddresses() { for (const output of this.outputs) { const addr = output.getAddress(); - let hash; if (!addr) continue; - hash = addr.getHash('hex'); + const hash = addr.getHash('hex'); if (!table[hash]) { table[hash] = true; @@ -1129,14 +1117,13 @@ TX.prototype.getAddresses = function getAddresses(view) { TX.prototype.getInputHashes = function getInputHashes(view, enc) { const hashes = []; - let addrs; if (enc === 'hex') { const [, table] = this._getInputAddresses(view); return Object.keys(table); } - addrs = this.getInputAddresses(view); + const addrs = this.getInputAddresses(view); for (const addr of addrs) hashes.push(addr.getHash()); @@ -1151,14 +1138,13 @@ TX.prototype.getInputHashes = function getInputHashes(view, enc) { TX.prototype.getOutputHashes = function getOutputHashes(enc) { const hashes = []; - let addrs; if (enc === 'hex') { const [, table] = this._getOutputAddresses(); return Object.keys(table); } - addrs = this.getOutputAddresses(); + const addrs = this.getOutputAddresses(); for (const addr of addrs) hashes.push(addr.getHash()); @@ -1174,14 +1160,13 @@ TX.prototype.getOutputHashes = function getOutputHashes(enc) { TX.prototype.getHashes = function getHashes(view, enc) { const hashes = []; - let addrs; if (enc === 'hex') { const [, table] = this._getAddresses(view); return Object.keys(table); } - addrs = this.getAddresses(view); + const addrs = this.getAddresses(view); for (const addr of addrs) hashes.push(addr.getHash()); @@ -1283,7 +1268,6 @@ TX.prototype.verifySequence = function verifySequence(index, locktime) { const TYPE_FLAG = consensus.SEQUENCE_TYPE_FLAG; const SEQUENCE_MASK = consensus.SEQUENCE_MASK; const input = this.inputs[index]; - let mask, sequence, predicate; assert(input, 'Input does not exist.'); assert(locktime >= 0, 'Locktime must be non-negative.'); @@ -1297,9 +1281,9 @@ TX.prototype.verifySequence = function verifySequence(index, locktime) { if ((input.sequence & DISABLE_FLAG) !== 0) return false; - mask = TYPE_FLAG | SEQUENCE_MASK; - sequence = input.sequence & mask; - predicate = locktime & mask; + const mask = TYPE_FLAG | SEQUENCE_MASK; + const sequence = input.sequence & mask; + const predicate = locktime & mask; if (!((sequence < TYPE_FLAG && predicate < TYPE_FLAG) || (sequence >= TYPE_FLAG && predicate >= TYPE_FLAG))) { @@ -1588,7 +1572,6 @@ TX.prototype.hasStandardWitness = function hasStandardWitness(view) { for (const input of this.inputs) { const witness = input.witness; const coin = view.getOutputFor(input); - let prev; if (!coin) continue; @@ -1596,7 +1579,7 @@ TX.prototype.hasStandardWitness = function hasStandardWitness(view) { if (witness.items.length === 0) continue; - prev = coin.script; + let prev = coin.script; if (prev.isScripthash()) { prev = input.script.getRedeem(); @@ -1621,8 +1604,6 @@ TX.prototype.hasStandardWitness = function hasStandardWitness(view) { } if (prev.isWitnessScripthash()) { - let redeem; - if (witness.items.length - 1 > policy.MAX_P2WSH_STACK) return false; @@ -1632,7 +1613,7 @@ TX.prototype.hasStandardWitness = function hasStandardWitness(view) { return false; } - redeem = witness.items[witness.items.length - 1]; + const redeem = witness.items[witness.items.length - 1]; if (redeem.length > policy.MAX_P2WSH_SIZE) return false; @@ -1726,7 +1707,6 @@ TX.prototype.verifyInputs = function verifyInputs(view, height) { TX.prototype.checkInputs = function checkInputs(view, height) { let total = 0; - let fee, value; assert(typeof height === 'number'); @@ -1754,12 +1734,12 @@ TX.prototype.checkInputs = function checkInputs(view, height) { } // Overflows already checked in `isSane()`. - value = this.getOutputValue(); + const value = this.getOutputValue(); if (total < value) return [-1, 'bad-txns-in-belowout', 100]; - fee = total - value; + const fee = total - value; if (fee < 0) return [-1, 'bad-txns-fee-negative', 100]; @@ -1779,13 +1759,11 @@ TX.prototype.checkInputs = function checkInputs(view, height) { */ TX.prototype.getModifiedSize = function getModifiedSize(size) { - let offset; - if (size == null) size = this.getVirtualSize(); for (const input of this.inputs) { - offset = 41 + Math.min(110, input.script.getSize()); + const offset = 41 + Math.min(110, input.script.getSize()); if (size > offset) size -= offset; } @@ -1815,12 +1793,11 @@ TX.prototype.getPriority = function getPriority(view, height, size) { for (const {prevout} of this.inputs) { const coin = view.getOutput(prevout); - let coinHeight; if (!coin) continue; - coinHeight = view.getHeight(prevout); + const coinHeight = view.getHeight(prevout); if (coinHeight === -1) continue; @@ -1848,12 +1825,11 @@ TX.prototype.getChainValue = function getChainValue(view) { for (const {prevout} of this.inputs) { const coin = view.getOutput(prevout); - let coinHeight; if (!coin) continue; - coinHeight = view.getHeight(prevout); + const coinHeight = view.getHeight(prevout); if (coinHeight === -1) continue; @@ -2272,8 +2248,6 @@ TX.prototype.fromRaw = function fromRaw(data) { */ TX.prototype.fromReader = function fromReader(br) { - let count; - if (TX.isWitness(br)) return this.fromWitnessReader(br); @@ -2281,14 +2255,14 @@ TX.prototype.fromReader = function fromReader(br) { this.version = br.readU32(); - count = br.readVarint(); + const inCount = br.readVarint(); - for (let i = 0; i < count; i++) + for (let i = 0; i < inCount; i++) this.inputs.push(Input.fromReader(br)); - count = br.readVarint(); + const outCount = br.readVarint(); - for (let i = 0; i < count; i++) + for (let i = 0; i < outCount; i++) this.outputs.push(Output.fromReader(br)); this.locktime = br.readU32(); @@ -2312,33 +2286,31 @@ TX.prototype.fromReader = function fromReader(br) { */ TX.prototype.fromWitnessReader = function fromWitnessReader(br) { - let flag = 0; - let witness = 0; - let hasWitness = false; - let count; - br.start(); this.version = br.readU32(); assert(br.readU8() === 0, 'Non-zero marker.'); - flag = br.readU8(); + let flag = br.readU8(); assert(flag !== 0, 'Flag byte is zero.'); this.flag = flag; - count = br.readVarint(); + const inCount = br.readVarint(); - for (let i = 0; i < count; i++) + for (let i = 0; i < inCount; i++) this.inputs.push(Input.fromReader(br)); - count = br.readVarint(); + const outCount = br.readVarint(); - for (let i = 0; i < count; i++) + for (let i = 0; i < outCount; i++) this.outputs.push(Output.fromReader(br)); + let witness = 0; + let hasWitness = false; + if (flag & 1) { flag ^= 1; @@ -2441,8 +2413,6 @@ TX.prototype.writeNormal = function writeNormal(bw) { */ TX.prototype.writeWitness = function writeWitness(bw) { - let witness; - if (this.inputs.length === 0 && this.outputs.length !== 0) throw new Error('Cannot serialize zero-input tx.'); @@ -2460,7 +2430,7 @@ TX.prototype.writeWitness = function writeWitness(bw) { for (const output of this.outputs) output.toWriter(bw); - witness = bw.written; + let witness = bw.written; for (const input of this.inputs) input.witness.toWriter(bw); diff --git a/lib/protocol/network.js b/lib/protocol/network.js index c68fbd83..7330299e 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -146,8 +146,6 @@ Network.prototype.ms = function ms() { */ Network.create = function create(options) { - let network; - if (typeof options === 'string') options = networks[options]; @@ -156,7 +154,7 @@ Network.create = function create(options) { if (Network[options.type]) return Network[options.type]; - network = new Network(options); + const network = new Network(options); Network[network.type] = network; diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index f08b89b2..93f64b35 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -14,7 +14,6 @@ const BN = require('../crypto/bn'); const network = exports; -let main, testnet, regtest, simnet; /** * Network type list. @@ -32,7 +31,7 @@ network.types = ['main', 'testnet', 'regtest', 'simnet']; * @type {Object} */ -main = network.main = {}; +const main = {}; /** * Symbolic network type. @@ -478,7 +477,7 @@ main.requestMempool = false; * https://en.bitcoin.it/wiki/Testnet */ -testnet = network.testnet = {}; +const testnet = {}; testnet.type = 'testnet'; @@ -659,7 +658,7 @@ testnet.requestMempool = false; * Regtest */ -regtest = network.regtest = {}; +const regtest = {}; regtest.type = 'regtest'; @@ -819,7 +818,7 @@ regtest.requestMempool = true; * Simnet (btcd) */ -simnet = network.simnet = {}; +const simnet = {}; simnet.type = 'simnet'; @@ -976,3 +975,12 @@ simnet.maxFeeRate = 60000; simnet.selfConnect = false; simnet.requestMempool = false; + +/* + * Expose + */ + +network.main = main; +network.testnet = testnet; +network.regtest = regtest; +network.simnet = simnet; diff --git a/lib/script/common.js b/lib/script/common.js index 1cf1ace1..4a51265b 100644 --- a/lib/script/common.js +++ b/lib/script/common.js @@ -322,14 +322,12 @@ exports.STACK_NEGATE = Buffer.from([0x81]); */ exports.isHashType = function isHashType(sig) { - let type; - assert(Buffer.isBuffer(sig)); if (sig.length === 0) return false; - type = sig[sig.length - 1] & ~exports.hashType.ANYONECANPAY; + const type = sig[sig.length - 1] & ~exports.hashType.ANYONECANPAY; if (!(type >= exports.hashType.ALL && type <= exports.hashType.SINGLE)) return false; @@ -451,8 +449,6 @@ exports.isCompressedEncoding = function isCompressedEncoding(key) { */ exports.isSignatureEncoding = function isSignatureEncoding(sig) { - let lenR, lenS; - assert(Buffer.isBuffer(sig)); // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] @@ -483,14 +479,14 @@ exports.isSignatureEncoding = function isSignatureEncoding(sig) { return false; // Extract the length of the R element. - lenR = sig[3]; + const lenR = sig[3]; // Make sure the length of the S element is still inside the signature. if (5 + lenR >= sig.length) return false; // Extract the length of the S element. - lenS = sig[5 + lenR]; + const lenS = sig[5 + lenR]; // Verify that the length of the signature matches the sum of the length // of the elements. @@ -706,8 +702,6 @@ exports.formatStackASM = function formatStackASM(items, decode) { */ exports.num = function num(value, minimal, size) { - let result; - assert(Buffer.isBuffer(value)); if (size == null) @@ -737,7 +731,7 @@ exports.num = function num(value, minimal, size) { if (value.length === 0) return new BN(0); - result = new BN(value, 'le'); + const result = new BN(value, 'le'); // If the input vector's most significant byte is // 0x80, remove it from the result's msb and return @@ -764,8 +758,6 @@ exports.num = function num(value, minimal, size) { */ exports.array = function array(value) { - let neg, result; - if (util.isNumber(value)) value = new BN(value); @@ -790,8 +782,8 @@ exports.array = function array(value) { // interpreted as a negative when // converting to an integral. - neg = value.cmpn(0) < 0; - result = value.toArray('le'); + const neg = value.cmpn(0) < 0; + const result = value.toArray('le'); if (result[result.length - 1] & 0x80) result.push(neg ? 0x80 : 0); diff --git a/lib/script/opcode.js b/lib/script/opcode.js index a5ab8e90..49481f30 100644 --- a/lib/script/opcode.js +++ b/lib/script/opcode.js @@ -407,8 +407,6 @@ Opcode.from = function from(data) { */ Opcode.fromSymbol = function fromSymbol(name) { - let op; - assert(typeof name === 'string'); assert(name.length > 0); @@ -418,7 +416,7 @@ Opcode.fromSymbol = function fromSymbol(name) { if (!util.startsWith(name, 'OP_')) name = `OP_${name}`; - op = common.opcodes[name]; + const op = common.opcodes[name]; assert(op != null, 'Unknown opcode.'); return Opcode.fromOp(op); @@ -431,12 +429,11 @@ Opcode.fromSymbol = function fromSymbol(name) { Opcode.prototype.toSymbol = function toSymbol() { let op = this.value; - let symbol; if (op === -1) op = 0xff; - symbol = common.opcodesByVal[op]; + let symbol = common.opcodesByVal[op]; if (symbol == null) symbol = util.hex8(op); diff --git a/lib/script/script.js b/lib/script/script.js index 527d5371..c82d5b2b 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -438,7 +438,6 @@ Script.prototype.getSubscript = function getSubscript(lastSep) { Script.prototype.removeSeparators = function removeSeparators() { let found = false; - let code; // Optimizing for the common case: // Check for any separators first. @@ -458,7 +457,7 @@ Script.prototype.removeSeparators = function removeSeparators() { // Uncommon case: someone actually // has a code separator. Go through // and remove them all. - code = []; + const code = []; for (const op of this.code) { if (op.value === -1) @@ -484,12 +483,12 @@ 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; - const state = []; - const alt = []; if (flags == null) flags = Script.flags.STANDARD_VERIFY_FLAGS; @@ -566,8 +565,6 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers break; } case opcodes.OP_CHECKLOCKTIMEVERIFY: { - let locktime; - // OP_CHECKLOCKTIMEVERIFY = OP_NOP2 if (!(flags & Script.flags.VERIFY_CHECKLOCKTIMEVERIFY)) { if (flags & Script.flags.VERIFY_DISCOURAGE_UPGRADABLE_NOPS) @@ -581,7 +578,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers if (stack.length === 0) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - locktime = Script.num(stack.top(-1), minimal, 5); + let locktime = Script.num(stack.top(-1), minimal, 5); if (locktime.cmpn(0) < 0) throw new ScriptError('NEGATIVE_LOCKTIME', op, ip); @@ -594,8 +591,6 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers break; } case opcodes.OP_CHECKSEQUENCEVERIFY: { - let locktime; - // OP_CHECKSEQUENCEVERIFY = OP_NOP3 if (!(flags & Script.flags.VERIFY_CHECKSEQUENCEVERIFY)) { if (flags & Script.flags.VERIFY_DISCOURAGE_UPGRADABLE_NOPS) @@ -609,7 +604,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers if (stack.length === 0) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - locktime = Script.num(stack.top(-1), minimal, 5); + let locktime = Script.num(stack.top(-1), minimal, 5); if (locktime.cmpn(0) < 0) throw new ScriptError('NEGATIVE_LOCKTIME', op, ip); @@ -725,27 +720,23 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers break; } case opcodes.OP_2DUP: { - let v1, v2; - if (stack.length < 2) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - v1 = stack.top(-2); - v2 = stack.top(-1); + const v1 = stack.top(-2); + const v2 = stack.top(-1); stack.push(v1); stack.push(v2); break; } case opcodes.OP_3DUP: { - let v1, v2, v3; - if (stack.length < 3) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - v1 = stack.top(-3); - v2 = stack.top(-2); - v3 = stack.top(-1); + const v1 = stack.top(-3); + const v2 = stack.top(-2); + const v3 = stack.top(-1); stack.push(v1); stack.push(v2); @@ -753,26 +744,22 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers break; } case opcodes.OP_2OVER: { - let v1, v2; - if (stack.length < 4) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - v1 = stack.top(-4); - v2 = stack.top(-3); + const v1 = stack.top(-4); + const v2 = stack.top(-3); stack.push(v1); stack.push(v2); break; } case opcodes.OP_2ROT: { - let v1, v2; - if (stack.length < 6) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - v1 = stack.top(-6); - v2 = stack.top(-5); + const v1 = stack.top(-6); + const v2 = stack.top(-5); stack.erase(-6, -4); stack.push(v1); @@ -788,12 +775,10 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers break; } case opcodes.OP_IFDUP: { - let val; - if (stack.length === 0) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - val = stack.top(-1); + const val = stack.top(-1); if (Script.bool(val)) stack.push(val); @@ -833,18 +818,16 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers } case opcodes.OP_PICK: case opcodes.OP_ROLL: { - let num, val; - if (stack.length < 2) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - num = Script.num(stack.top(-1), minimal).toNumber(); + const num = Script.num(stack.top(-1), minimal).toNumber(); stack.pop(); if (num < 0 || num >= stack.length) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - val = stack.top(-num - 1); + const val = stack.top(-num - 1); if (op.value === opcodes.OP_ROLL) stack.remove(-num - 1); @@ -883,15 +866,13 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers } case opcodes.OP_EQUAL: case opcodes.OP_EQUALVERIFY: { - let v1, v2, res; - if (stack.length < 2) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - v1 = stack.top(-2); - v2 = stack.top(-1); + const v1 = stack.top(-2); + const v2 = stack.top(-1); - res = v1.equals(v2); + const res = v1.equals(v2); stack.pop(); stack.pop(); @@ -912,12 +893,10 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers case opcodes.OP_ABS: case opcodes.OP_NOT: case opcodes.OP_0NOTEQUAL: { - let num; - if (stack.length < 1) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - num = Script.num(stack.top(-1), minimal); + let num = Script.num(stack.top(-1), minimal); switch (op.value) { case opcodes.OP_1ADD: @@ -963,13 +942,12 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers case opcodes.OP_GREATERTHANOREQUAL: case opcodes.OP_MIN: case opcodes.OP_MAX: { - let n1, n2, num; - if (stack.length < 2) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - n1 = Script.num(stack.top(-2), minimal); - n2 = Script.num(stack.top(-1), minimal); + const n1 = Script.num(stack.top(-2), minimal); + const n2 = Script.num(stack.top(-1), minimal); + let num; switch (op.value) { case opcodes.OP_ADD: @@ -1038,16 +1016,14 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers break; } case opcodes.OP_WITHIN: { - let val, n1, n2, n3; - if (stack.length < 3) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - n1 = Script.num(stack.top(-3), minimal); - n2 = Script.num(stack.top(-2), minimal); - n3 = Script.num(stack.top(-1), minimal); + const n1 = Script.num(stack.top(-3), minimal); + const n2 = Script.num(stack.top(-2), minimal); + const n3 = Script.num(stack.top(-1), minimal); - val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0; + const val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0; stack.pop(); stack.pop(); @@ -1097,19 +1073,16 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers } case opcodes.OP_CHECKSIG: case opcodes.OP_CHECKSIGVERIFY: { - let sig, key, res, subscript; - if (!tx) throw new ScriptError('UNKNOWN_ERROR', 'No TX passed in.'); if (stack.length < 2) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - sig = stack.top(-2); - key = stack.top(-1); - res = false; + const sig = stack.top(-2); + const key = stack.top(-1); - subscript = this.getSubscript(lastSep); + const subscript = this.getSubscript(lastSep); if (version === 0) subscript.removeData(sig); @@ -1117,6 +1090,8 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers validateSignature(sig, flags); validateKey(key, flags, version); + let res = false; + if (sig.length > 0) { const type = sig[sig.length - 1]; const hash = tx.signatureHash(index, subscript, value, type, version); @@ -1143,17 +1118,15 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers } case opcodes.OP_CHECKMULTISIG: case opcodes.OP_CHECKMULTISIGVERIFY: { - let i, m, n, isig, ikey, ikey2, subscript, res; - if (!tx) throw new ScriptError('UNKNOWN_ERROR', 'No TX passed in.'); - i = 1; + let i = 1; if (stack.length < i) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - n = Script.num(stack.top(-i), minimal).toNumber(); - ikey2 = n + 2; + let n = Script.num(stack.top(-i), minimal).toNumber(); + let ikey2 = n + 2; if (!(n >= 0 && n <= consensus.MAX_MULTISIG_PUBKEYS)) throw new ScriptError('PUBKEY_COUNT', op, ip); @@ -1164,25 +1137,25 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers throw new ScriptError('OP_COUNT', op, ip); i++; - ikey = i; + let ikey = i; i += n; if (stack.length < i) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - m = Script.num(stack.top(-i), minimal).toNumber(); + let m = Script.num(stack.top(-i), minimal).toNumber(); if (!(m >= 0 && m <= n)) throw new ScriptError('SIG_COUNT', op, ip); i++; - isig = i; + let isig = i; i += m; if (stack.length < i) throw new ScriptError('INVALID_STACK_OPERATION', op, ip); - subscript = this.getSubscript(lastSep); + const subscript = this.getSubscript(lastSep); for (let j = 0; j < m; j++) { const sig = stack.top(-isig - j); @@ -1190,7 +1163,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers subscript.removeData(sig); } - res = true; + let res = true; while (res && m > 0) { const sig = stack.top(-isig); const key = stack.top(-ikey); @@ -1589,12 +1562,10 @@ Script.fromNulldata = function fromNulldata(flags) { */ Script.prototype.fromProgram = function fromProgram(version, data) { - let op; - assert(util.isNumber(version) && version >= 0 && version <= 16); assert(Buffer.isBuffer(data) && data.length >= 2 && data.length <= 40); - op = Opcode.fromSmall(version); + const op = Opcode.fromSmall(version); this.raw = Buffer.allocUnsafe(2 + data.length); this.raw[0] = op.value; @@ -1695,15 +1666,13 @@ Script.fromCommitment = function fromCommitment(hash, flags) { */ Script.prototype.getRedeem = function getRedeem() { - let redeem; - if (this.code.length === 0) return; if (!this.isPushOnly()) return; - redeem = this.code[this.code.length - 1]; + const redeem = this.code[this.code.length - 1]; if (!redeem.data) return; @@ -1903,20 +1872,18 @@ Script.prototype.isPubkeyhash = function isPubkeyhash(minimal) { */ Script.prototype.isMultisig = function isMultisig(minimal) { - let m, n; - if (this.raw.length < 41) return false; if (this.raw[this.raw.length - 1] !== opcodes.OP_CHECKMULTISIG) return false; - n = common.getSmall(this.raw[this.raw.length - 2]); + const n = common.getSmall(this.raw[this.raw.length - 2]); if (n < 1) return false; - m = common.getSmall(this.raw[0]); + const m = common.getSmall(this.raw[0]); if (!(m >= 1 && m <= n)) return false; @@ -2053,13 +2020,11 @@ Script.prototype.isProgram = function isProgram() { */ Script.prototype.toProgram = function toProgram() { - let version, data; - if (!this.isProgram()) return; - version = common.getSmall(this.raw[0]); - data = this.raw.slice(2); + const version = common.getSmall(this.raw[0]); + const data = this.raw.slice(2); return new Program(version, data); }; @@ -2253,13 +2218,11 @@ Script.prototype.isMultisigInput = function isMultisigInput() { */ Script.prototype.isScripthashInput = function isScripthashInput() { - let op, redeem; - if (this.raw.length < 2) return false; // Grab the raw redeem script. - op = this.code[this.code.length - 1]; + const op = this.code[this.code.length - 1]; // Last data element should be an array // for the redeem script. @@ -2284,7 +2247,7 @@ Script.prototype.isScripthashInput = function isScripthashInput() { if (common.isKeyEncoding(op.data)) return false; - redeem = Script.fromRaw(op.data); + const redeem = Script.fromRaw(op.data); if (!redeem.isCode()) return false; @@ -2308,16 +2271,14 @@ Script.prototype.getCoinbaseHeight = function getCoinbaseHeight() { */ Script.getCoinbaseHeight = function getCoinbaseHeight(raw) { - let data, height, op; - if (raw.length === 0) return -1; // Small ints are allowed. - height = common.getSmall(raw[0]); + const smi = common.getSmall(raw[0]); - if (height !== -1) - return height; + if (smi !== -1) + return smi; // No more than 6 bytes (we can't // handle 7 byte JS numbers and @@ -2329,9 +2290,10 @@ Script.getCoinbaseHeight = function getCoinbaseHeight(raw) { if (raw.length < 1 + raw[0]) return -1; - data = raw.slice(1, 1 + raw[0]); + const data = raw.slice(1, 1 + raw[0]); // Deserialize the height. + let height; try { height = Script.num(data, true, 6); } catch (e) { @@ -2339,7 +2301,7 @@ Script.getCoinbaseHeight = function getCoinbaseHeight(raw) { } // Reserialize the height. - op = Opcode.fromNumber(height); + const op = Opcode.fromNumber(height); // Should have been OP_0-OP_16. if (!op.data) @@ -2619,14 +2581,14 @@ Script.prototype.getSigops = function getSigops(accurate) { */ Script.prototype.getScripthashSigops = function getScripthashSigops(input) { - let op, redeem; - if (!this.isScripthash()) return this.getSigops(true); if (input.code.length === 0) return 0; + let op; + for (op of input.code) { if (op.data) continue; @@ -2641,7 +2603,7 @@ Script.prototype.getScripthashSigops = function getScripthashSigops(input) { if (!op.data) return 0; - redeem = new Script(op.data); + const redeem = new Script(op.data); return redeem.getSigops(true); }; @@ -2702,8 +2664,6 @@ Script.prototype.getWitnessSigops = function getWitnessSigops(input, witness) { */ Script.prototype.fromString = function fromString(code) { - let bw; - assert(typeof code === 'string'); code = code.trim(); @@ -2712,7 +2672,8 @@ Script.prototype.fromString = function fromString(code) { return this; code = code.split(/\s+/); - bw = new BufferWriter(); + + const bw = new BufferWriter(); for (let op of code) { let symbol = op; @@ -2777,7 +2738,7 @@ Script.fromString = function fromString(code) { */ Script.verify = function verify(input, witness, output, tx, i, value, flags) { - let stack, copy, raw, redeem, hadWitness; + let hadWitness = false; if (flags == null) flags = Script.flags.STANDARD_VERIFY_FLAGS; @@ -2788,12 +2749,13 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) { } // Setup a stack. - stack = new Stack(); + let stack = new Stack(); // Execute the input script input.execute(stack, flags, tx, i, value, 0); // Copy the stack for P2SH + let copy; if (flags & Script.flags.VERIFY_P2SH) copy = stack.clone(); @@ -2832,8 +2794,8 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) { throw new ScriptError('EVAL_FALSE'); // Grab the real redeem script - raw = stack.pop(); - redeem = new Script(raw); + const raw = stack.pop(); + const redeem = new Script(raw); // Execute the redeem script. redeem.execute(stack, flags, tx, i, value, 0); @@ -2891,7 +2853,7 @@ 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 witnessScript, redeem; + let redeem; assert(program, 'verifyProgram called on non-witness-program.'); assert((flags & Script.flags.VERIFY_WITNESS) !== 0); @@ -2901,7 +2863,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val if (stack.length === 0) throw new ScriptError('WITNESS_PROGRAM_WITNESS_EMPTY'); - witnessScript = stack.pop(); + const witnessScript = stack.pop(); if (!digest.sha256(witnessScript).equals(program.data)) throw new ScriptError('WITNESS_PROGRAM_MISMATCH'); @@ -2963,10 +2925,8 @@ 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(); - const scripts = new BufferWriter(); + let scripts = new BufferWriter(); let version = 0; - let pathdata, depth, path, posdata, pos; - let metadata, subscripts, ops, script; assert(program.version === 1); assert((flags & Script.flags.VERIFY_MAST) !== 0); @@ -2974,15 +2934,15 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va if (stack.length < 4) throw new ScriptError('INVALID_MAST_STACK'); - metadata = stack.top(-1); + const metadata = stack.top(-1); if (metadata.length < 1 || metadata.length > 5) throw new ScriptError('INVALID_MAST_STACK'); - subscripts = metadata[0]; + const subscripts = metadata[0]; if (subscripts === 0 || stack.length < subscripts + 3) throw new ScriptError('INVALID_MAST_STACK'); - ops = subscripts; + let ops = subscripts; scriptRoot.writeU8(subscripts); if (metadata[metadata.length - 1] === 0x00) @@ -3001,12 +2961,12 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va mastRoot.writeU32(version); - pathdata = stack.top(-2); + const pathdata = stack.top(-2); if (pathdata.length & 0x1f) throw new ScriptError('INVALID_MAST_STACK'); - depth = pathdata.length >>> 5; + const depth = pathdata.length >>> 5; if (depth > 32) throw new ScriptError('INVALID_MAST_STACK'); @@ -3017,17 +2977,17 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va throw new ScriptError('OP_COUNT'); } - path = []; + const path = []; for (let j = 0; j < depth; j++) path.push(pathdata.slice(j * 32, j * 32 + 32)); - posdata = stack.top(-3); + const posdata = stack.top(-3); if (posdata.length > 4) throw new ScriptError('INVALID_MAST_STACK'); - pos = 0; + let pos = 0; if (posdata.length > 0) { if (posdata[posdata.length - 1] === 0x00) throw new ScriptError('INVALID_MAST_STACK'); @@ -3047,7 +3007,7 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va scripts.writeBytes(output.raw); for (let j = 0; j < subscripts; j++) { - script = stack.top(-(4 + j)); + const script = stack.top(-(4 + j)); if (version === 0) { if ((scripts.written + script.length) > consensus.MAX_SCRIPT_SIZE) throw new ScriptError('SCRIPT_SIZE'); @@ -3073,7 +3033,8 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va throw new ScriptError('PUSH_SIZE'); } - output = new Script(scripts.render()); + scripts = scripts.render(); + output = new Script(scripts); output.execute(stack, flags, tx, i, value, 1); if (stack.length !== 0) diff --git a/lib/script/scriptnum.js b/lib/script/scriptnum.js index f4c8278e..32cdcef8 100644 --- a/lib/script/scriptnum.js +++ b/lib/script/scriptnum.js @@ -321,7 +321,7 @@ ScriptNum.fromRaw = function fromRaw(data, minimal, limit) { ScriptNum.prototype.toRaw = function toRaw() { let value = this.value; let negative = false; - let data, offset, size; + let offset, size; // Zeroes are always empty arrays. if (value === 0) @@ -357,7 +357,7 @@ ScriptNum.prototype.toRaw = function toRaw() { } // Write number. - data = Buffer.allocUnsafe(size + offset); + const data = Buffer.allocUnsafe(size + offset); switch (size) { case 6: diff --git a/lib/script/sigcache.js b/lib/script/sigcache.js index dce50075..05f90af1 100644 --- a/lib/script/sigcache.js +++ b/lib/script/sigcache.js @@ -100,17 +100,15 @@ SigCache.prototype.has = function has(hash, sig, key) { */ SigCache.prototype.verify = function verify(msg, sig, key) { - let hash, result; - if (this.size === 0) return secp256k1.verify(msg, sig, key); - hash = msg.toString('hex'); + const hash = msg.toString('hex'); if (this.has(hash, sig, key)) return true; - result = secp256k1.verify(msg, sig, key); + const result = secp256k1.verify(msg, sig, key); if (!result) return false; diff --git a/lib/script/stack.js b/lib/script/stack.js index 5a5b9c72..0cfddacf 100644 --- a/lib/script/stack.js +++ b/lib/script/stack.js @@ -260,16 +260,14 @@ Stack.prototype.set = function set(i, value) { */ Stack.prototype.swap = function swap(i1, i2) { - let v1, v2; - if (i1 < 0) i1 = this.items.length + i1; if (i2 < 0) i2 = this.items.length + i2; - v1 = this.items[i1]; - v2 = this.items[i2]; + const v1 = this.items[i1]; + const v2 = this.items[i2]; this.items[i1] = v2; this.items[i2] = v1; diff --git a/lib/script/witness.js b/lib/script/witness.js index 44b329d8..7af3aa64 100644 --- a/lib/script/witness.js +++ b/lib/script/witness.js @@ -76,11 +76,9 @@ Witness.prototype.__defineSetter__('length', function(length) { */ Witness.prototype.fromOptions = function fromOptions(options) { - let items; - assert(options, 'Witness data is required.'); - items = options.items; + let items = options.items; if (!items) items = options; @@ -295,12 +293,10 @@ Witness.prototype.test = function test(filter) { */ Witness.prototype.getRedeem = function getRedeem() { - let redeem; - if (this.items.length === 0) return; - redeem = this.items[this.items.length - 1]; + const redeem = this.items[this.items.length - 1]; if (!redeem) return; diff --git a/lib/utils/asn1.js b/lib/utils/asn1.js index 6936be9b..26841774 100644 --- a/lib/utils/asn1.js +++ b/lib/utils/asn1.js @@ -46,10 +46,9 @@ const ASN1 = exports; ASN1.readTag = function readTag(br) { let type = br.readU8(); const primitive = (type & 0x20) === 0; - let oct; if ((type & 0x1f) === 0x1f) { - oct = type; + let oct = type; type = 0; while ((oct & 0x80) === 0x80) { oct = br.readU8(); @@ -77,7 +76,6 @@ ASN1.readTag = function readTag(br) { ASN1.readSize = function readSize(br, primitive) { let size = br.readU8(); - let bytes, i, j; // Indefinite form if (!primitive && size === 0x80) @@ -90,16 +88,15 @@ ASN1.readSize = function readSize(br, primitive) { } // Long form - bytes = size & 0x7f; + const bytes = size & 0x7f; if (bytes > 3) throw new Error('Length octet is too long.'); size = 0; - for (i = 0; i < bytes; i++) { + for (let i = 0; i < bytes; i++) { size <<= 8; - j = br.readU8(); - size |= j; + size |= br.readU8(); } return size; @@ -209,12 +206,12 @@ ASN1.readBitstr = function readBitstr(br) { ASN1.readString = function readString(br) { const tag = ASN1.readTag(br); - let str; switch (tag.type) { - case 0x03: // bitstr - str = br.readBytes(tag.size); + case 0x03: { // bitstr + const str = br.readBytes(tag.size); return ASN1.alignBitstr(str); + } // Note: // Fuck all these. case 0x04: // octstr @@ -229,10 +226,12 @@ ASN1.readString = function readString(br) { case 0x1b: // genstr case 0x1c: // unistr case 0x1d: // charstr - case 0x1e: // bmpstr + case 0x1e: { // bmpstr return br.readString('utf8', tag.size); - default: + } + default: { throw new Error(`Unexpected tag: ${tag.type}.`); + } } }; @@ -247,15 +246,14 @@ ASN1.alignBitstr = function alignBitstr(data) { const bits = (data.length - 1) * 8 - padding; const buf = data.slice(1); const shift = 8 - (bits % 8); - let i, out; if (shift === 8 || buf.length === 0) return buf; - out = Buffer.allocUnsafe(buf.length); + const out = Buffer.allocUnsafe(buf.length); out[0] = buf[0] >>> shift; - for (i = 1; i < buf.length; i++) { + for (let i = 1; i < buf.length; i++) { out[i] = buf[i - 1] << (8 - shift); out[i] |= buf[i] >>> shift; } @@ -422,7 +420,6 @@ ASN1.formatOID = function formatOID(data) { const ids = []; let ident = 0; let subident = 0; - let result, first, second; while (br.left()) { subident = br.readU8(); @@ -437,9 +434,9 @@ ASN1.formatOID = function formatOID(data) { if (subident & 0x80) ids.push(ident); - first = (ids[0] / 40) | 0; - second = ids[0] % 40; - result = [first, second].concat(ids.slice(1)); + const first = (ids[0] / 40) | 0; + const second = ids[0] % 40; + const result = [first, second].concat(ids.slice(1)); return result.join('.'); }; @@ -452,14 +449,13 @@ ASN1.formatOID = function formatOID(data) { ASN1.readAlgIdent = function readAlgIdent(br) { let params = null; - let alg, tag; br = ASN1.seq(br); - alg = ASN1.readOID(br); + const alg = ASN1.readOID(br); if (br.left() > 0) { - tag = ASN1.readTag(br); + const tag = ASN1.readTag(br); params = br.readBytes(tag.size); if (params.length === 0) params = null; diff --git a/lib/utils/asyncemitter.js b/lib/utils/asyncemitter.js index 7b16eac5..78e99a9c 100644 --- a/lib/utils/asyncemitter.js +++ b/lib/utils/asyncemitter.js @@ -116,18 +116,17 @@ AsyncEmitter.prototype._unshift = function _unshift(type, handler, once) { */ AsyncEmitter.prototype.removeListener = function removeListener(type, handler) { - let i, listeners, listener; - let index = -1; - assert(typeof type === 'string', '`type` must be a string.'); - listeners = this._events[type]; + const listeners = this._events[type]; if (!listeners) return; - for (i = 0; i < listeners.length; i++) { - listener = listeners[i]; + let index = -1; + + for (let i = 0; i < listeners.length; i++) { + const listener = listeners[i]; if (listener.handler === handler) { index = i; break; @@ -179,17 +178,16 @@ AsyncEmitter.prototype.removeAllListeners = function removeAllListeners(type) { */ AsyncEmitter.prototype.listeners = function listeners(type) { - let listeners, listener; - const result = []; - assert(typeof type === 'string', '`type` must be a string.'); - listeners = this._events[type]; + const listeners = this._events[type]; if (!listeners) return result; - for (listener of listeners) + const result = []; + + for (const listener of listeners) result.push(listener.handler); return result; @@ -201,11 +199,9 @@ AsyncEmitter.prototype.listeners = function listeners(type) { */ AsyncEmitter.prototype.listenerCount = function listenerCount(type) { - let listeners; - assert(typeof type === 'string', '`type` must be a string.'); - listeners = this._events[type]; + const listeners = this._events[type]; if (!listeners) return 0; @@ -222,29 +218,29 @@ AsyncEmitter.prototype.listenerCount = function listenerCount(type) { */ AsyncEmitter.prototype.emit = function emit(type) { - let i, j, listeners, error, err, args, listener, handler; - assert(typeof type === 'string', '`type` must be a string.'); - listeners = this._events[type]; + const listeners = this._events[type]; if (!listeners || listeners.length === 0) { if (type === 'error') { - error = arguments[1]; + const error = arguments[1]; if (error instanceof Error) throw error; - err = new Error(`Uncaught, unspecified "error" event. (${error})`); + const err = new Error(`Uncaught, unspecified "error" event. (${error})`); err.context = error; throw err; } return; } - for (i = 0; i < listeners.length; i++) { - listener = listeners[i]; - handler = listener.handler; + let args = null; + + for (let i = 0; i < listeners.length; i++) { + const listener = listeners[i]; + const handler = listener.handler; if (listener.once) { listeners.splice(i, 1); @@ -267,7 +263,7 @@ AsyncEmitter.prototype.emit = function emit(type) { default: if (!args) { args = new Array(arguments.length - 1); - for (j = 1; j < arguments.length; j++) + for (let j = 1; j < arguments.length; j++) args[j - 1] = arguments[j]; } handler.apply(null, args); @@ -285,29 +281,29 @@ AsyncEmitter.prototype.emit = function emit(type) { */ AsyncEmitter.prototype.fire = async function fire(type) { - let i, j, listeners, error, err, args, listener, handler; - assert(typeof type === 'string', '`type` must be a string.'); - listeners = this._events[type]; + const listeners = this._events[type]; if (!listeners || listeners.length === 0) { if (type === 'error') { - error = arguments[1]; + const error = arguments[1]; if (error instanceof Error) throw error; - err = new Error(`Uncaught, unspecified "error" event. (${error})`); + const err = new Error(`Uncaught, unspecified "error" event. (${error})`); err.context = error; throw err; } return; } - for (i = 0; i < listeners.length; i++) { - listener = listeners[i]; - handler = listener.handler; + let args = null; + + for (let i = 0; i < listeners.length; i++) { + const listener = listeners[i]; + const handler = listener.handler; if (listener.once) { listeners.splice(i, 1); @@ -330,7 +326,7 @@ AsyncEmitter.prototype.fire = async function fire(type) { default: if (!args) { args = new Array(arguments.length - 1); - for (j = 1; j < arguments.length; j++) + for (let j = 1; j < arguments.length; j++) args[j - 1] = arguments[j]; } await handler.apply(null, args); diff --git a/lib/utils/asyncobject.js b/lib/utils/asyncobject.js index d66229f3..86089291 100644 --- a/lib/utils/asyncobject.js +++ b/lib/utils/asyncobject.js @@ -190,15 +190,15 @@ AsyncObject.prototype.fire = async function fire() { */ AsyncObject.prototype.fireHook = async function fireHook(type) { - let listeners, args; - assert(typeof type === 'string', '`type` must be a string.'); - listeners = this._hooks[type]; + const listeners = this._hooks[type]; if (!listeners || listeners.length === 0) return; + let args = null; + for (const handler of listeners) { switch (arguments.length) { case 1: diff --git a/lib/utils/base58.js b/lib/utils/base58.js index 235d3690..5ef9baf2 100644 --- a/lib/utils/base58.js +++ b/lib/utils/base58.js @@ -37,24 +37,24 @@ for (let i = 0; i < base58.length; i++) exports.encode = function encode(data) { let zeroes = 0; - let length = 0; - let str = ''; - let i, b58, carry, j, k; + let i = 0; - for (i = 0; i < data.length; i++) { + for (; i < data.length; i++) { if (data[i] !== 0) break; zeroes++; } - b58 = Buffer.allocUnsafe(((data.length * 138 / 100) | 0) + 1); + const b58 = Buffer.allocUnsafe(((data.length * 138 / 100) | 0) + 1); b58.fill(0); - for (; i < data.length; i++) { - carry = data[i]; - j = 0; + let length = 0; - for (k = b58.length - 1; k >= 0; k--, j++) { + for (; i < data.length; i++) { + let carry = data[i]; + let j = 0; + + for (let k = b58.length - 1; k >= 0; k--, j++) { if (carry === 0 && j >= length) break; carry += 256 * b58[k]; @@ -70,7 +70,9 @@ exports.encode = function encode(data) { while (i < b58.length && b58[i] === 0) i++; - for (j = 0; j < zeroes; j++) + let str = ''; + + for (let j = 0; j < zeroes; j++) str += '1'; for (; i < b58.length; i++) @@ -92,28 +94,29 @@ if (native) exports.decode = function decode(str) { let zeroes = 0; - let length = 0; let i = 0; - let b256, ch, carry, j, k, out; - for (i = 0; i < str.length; i++) { + for (; i < str.length; i++) { if (str[i] !== '1') break; zeroes++; } - b256 = Buffer.allocUnsafe(((str.length * 733) / 1000 | 0) + 1); + const b256 = Buffer.allocUnsafe(((str.length * 733) / 1000 | 0) + 1); b256.fill(0); + let length = 0; + for (; i < str.length; i++) { - ch = unbase58[str[i]]; + const ch = unbase58[str[i]]; + if (ch == null) throw new Error('Non-base58 character.'); - carry = ch; - j = 0; + let carry = ch; + let j = 0; - for (k = b256.length - 1; k >= 0; k--, j++) { + for (let k = b256.length - 1; k >= 0; k--, j++) { if (carry === 0 && j >= length) break; carry += 58 * b256[k]; @@ -129,8 +132,9 @@ exports.decode = function decode(str) { while (i < b256.length && b256[i] === 0) i++; - out = Buffer.allocUnsafe(zeroes + (b256.length - i)); + const out = Buffer.allocUnsafe(zeroes + (b256.length - i)); + let j; for (j = 0; j < zeroes; j++) out[j] = 0; diff --git a/lib/utils/bech32.js b/lib/utils/bech32.js index 5258741f..82c87799 100644 --- a/lib/utils/bech32.js +++ b/lib/utils/bech32.js @@ -76,10 +76,10 @@ function polymod(pre) { function serialize(hrp, data) { let str = ''; let chk = 1; - let i, ch; + let i; for (i = 0; i < hrp.length; i++) { - ch = hrp.charCodeAt(i); + const ch = hrp.charCodeAt(i); if ((ch >> 5) === 0) throw new Error('Invalid bech32 character.'); @@ -92,16 +92,16 @@ function serialize(hrp, data) { chk = polymod(chk); - for (i = 0; i < hrp.length; i++) { - ch = hrp.charCodeAt(i); + for (let i = 0; i < hrp.length; i++) { + const ch = hrp.charCodeAt(i); chk = polymod(chk) ^ (ch & 0x1f); str += hrp[i]; } str += '1'; - for (i = 0; i < data.length; i++) { - ch = data[i]; + for (let i = 0; i < data.length; i++) { + const ch = data[i]; if ((ch >> 5) !== 0) throw new Error('Invalid bech32 value.'); @@ -110,12 +110,12 @@ function serialize(hrp, data) { str += CHARSET[ch]; } - for (i = 0; i < 6; i++) + for (let i = 0; i < 6; i++) chk = polymod(chk); chk ^= 1; - for (i = 0; i < 6; i++) + for (let i = 0; i < 6; i++) str += CHARSET[(chk >>> ((5 - i) * 5)) & 0x1f]; return str; @@ -128,12 +128,7 @@ function serialize(hrp, data) { */ function deserialize(str) { - let chk = 1; - let lower = false; - let upper = false; - let hrp = ''; let dlen = 0; - let i, hlen, ch, v, data; if (str.length < 8 || str.length > 90) throw new Error('Invalid bech32 string length.'); @@ -141,16 +136,22 @@ function deserialize(str) { while (dlen < str.length && str[(str.length - 1) - dlen] !== '1') dlen++; - hlen = str.length - (1 + dlen); + const hlen = str.length - (1 + dlen); if (hlen < 1 || dlen < 6) throw new Error('Invalid bech32 data length.'); dlen -= 6; - data = Buffer.allocUnsafe(dlen); - for (i = 0; i < hlen; i++) { - ch = str.charCodeAt(i); + const data = Buffer.allocUnsafe(dlen); + + let chk = 1; + let lower = false; + let upper = false; + let hrp = ''; + + for (let i = 0; i < hlen; i++) { + let ch = str.charCodeAt(i); if (ch < 0x21 || ch > 0x7e) throw new Error('Invalid bech32 character.'); @@ -168,14 +169,15 @@ function deserialize(str) { chk = polymod(chk); + let i; for (i = 0; i < hlen; i++) chk = polymod(chk) ^ (str.charCodeAt(i) & 0x1f); i++; while (i < str.length) { - ch = str.charCodeAt(i); - v = (ch & 0x80) ? -1 : TABLE[ch]; + const ch = str.charCodeAt(i); + const v = (ch & 0x80) ? -1 : TABLE[ch]; if (ch >= 0x61 && ch <= 0x7a) lower = true; @@ -215,17 +217,16 @@ function deserialize(str) { */ function convert(data, output, frombits, tobits, pad, off) { + const maxv = (1 << tobits) - 1; let acc = 0; let bits = 0; - const maxv = (1 << tobits) - 1; let j = 0; - let i, value; if (pad !== -1) output[j++] = pad; - for (i = off; i < data.length; i++) { - value = data[i]; + for (let i = off; i < data.length; i++) { + const value = data[i]; if ((value >> frombits) !== 0) throw new Error('Invalid bech32 bits.'); @@ -260,7 +261,6 @@ function convert(data, output, frombits, tobits, pad, off) { function encode(hrp, version, hash) { const output = POOL65; - let data; if (version < 0 || version > 16) throw new Error('Invalid bech32 version.'); @@ -268,7 +268,7 @@ function encode(hrp, version, hash) { if (hash.length < 2 || hash.length > 40) throw new Error('Invalid bech32 data length.'); - data = convert(hash, output, 8, 5, version, 0); + const data = convert(hash, output, 8, 5, version, 0); return serialize(hrp, data); } @@ -284,7 +284,6 @@ if (native) function decode(str) { const [hrp, data] = deserialize(str); - let version, hash, output; if (data.length === 0 || data.length > 65) throw new Error('Invalid bech32 data length.'); @@ -292,9 +291,9 @@ function decode(str) { if (data[0] > 16) throw new Error('Invalid bech32 version.'); - version = data[0]; - output = data; - hash = convert(data, output, 5, 8, -1, 1); + const version = data[0]; + const output = data; + const hash = convert(data, output, 5, 8, -1, 1); if (hash.length < 2 || hash.length > 40) throw new Error('Invalid bech32 data length.'); diff --git a/lib/utils/bloom.js b/lib/utils/bloom.js index 752a2fb0..936d7d33 100644 --- a/lib/utils/bloom.js +++ b/lib/utils/bloom.js @@ -117,15 +117,13 @@ Bloom.flagsByVal = { */ Bloom.prototype.fromOptions = function fromOptions(size, n, tweak, update) { - let filter; - assert(typeof size === 'number', '`size` must be a number.'); assert(size > 0, '`size` must be greater than zero.'); assert(size % 1 === 0, '`size` must be an integer.'); size -= size % 8; - filter = Buffer.allocUnsafe(size / 8); + const filter = Buffer.allocUnsafe(size / 8); filter.fill(0); if (tweak == null || tweak === -1) @@ -258,15 +256,13 @@ Bloom.prototype.added = function added(val, enc) { */ Bloom.fromRate = function fromRate(items, rate, update) { - let size, n; - assert(typeof items === 'number', '`items` must be a number.'); assert(items > 0, '`items` must be greater than zero.'); assert(items % 1 === 0, '`items` must be an integer.'); assert(typeof rate === 'number', '`rate` must be a number.'); assert(rate >= 0 && rate <= 1, '`rate` must be between 0.0 and 1.0.'); - size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0; + let size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0; size = Math.max(8, size); if (update !== -1) { @@ -274,7 +270,7 @@ Bloom.fromRate = function fromRate(items, rate, update) { 'Bloom filter size violates policy limits!'); } - n = Math.max(1, (size / items * LN2) | 0); + const n = Math.max(1, (size / items * LN2) | 0); if (update !== -1) { assert(n <= Bloom.MAX_HASH_FUNCS, diff --git a/lib/utils/co.js b/lib/utils/co.js index 55d4fbd2..9fad1b29 100644 --- a/lib/utils/co.js +++ b/lib/utils/co.js @@ -47,11 +47,11 @@ function exec(gen) { next.value.then(succeed, fail); }; - let succeed = (value) => { + const succeed = (value) => { step(value, false); }; - let fail = (value) => { + const fail = (value) => { step(value, true); }; @@ -161,14 +161,12 @@ function promisify(func) { function callbackify(func) { return function(...args) { - let callback; - if (args.length === 0 || typeof args[args.length - 1] !== 'function') { throw new Error(`${func.name || 'Function'} requires a callback.`); } - callback = args.pop(); + const callback = args.pop(); func.call(this, ...args).then((value) => { setImmediate(() => callback(null, value)); diff --git a/lib/utils/encoding.js b/lib/utils/encoding.js index a248addf..245b096e 100644 --- a/lib/utils/encoding.js +++ b/lib/utils/encoding.js @@ -346,7 +346,6 @@ encoding.read53BE = function read53BE(data, off) { encoding._write64 = function _write64(dst, num, off, be) { const negative = num < 0; - let hi, lo; if (negative) { num = -num; @@ -355,8 +354,8 @@ encoding._write64 = function _write64(dst, num, off, be) { enforce(num <= MAX_SAFE_INTEGER, off, 'Number exceeds 2^53-1'); - hi = (num * (1 / 0x100000000)) | 0; - lo = num | 0; + let hi = (num * (1 / 0x100000000)) | 0; + let lo = num | 0; if (negative) { hi = ~hi; @@ -697,21 +696,21 @@ encoding.sizeVarint = function sizeVarint(num) { */ encoding.readVarintBN = function readVarintBN(data, off) { - let result, value, size; - assert(off < data.length, off); switch (data[off]) { - case 0xff: - size = 9; + case 0xff: { + const size = 9; assert(off + size <= data.length, off); - value = encoding.readU64BN(data, off + 1); + const value = encoding.readU64BN(data, off + 1); enforce(value.bitLength() > 32, off, 'Non-canonical varint'); return new Varint(size, value); - default: - result = encoding.readVarint(data, off); + } + default: { + const result = encoding.readVarint(data, off); result.value = new BN(result.value); return result; + } } }; @@ -756,12 +755,11 @@ encoding.sizeVarintBN = function sizeVarintBN(num) { encoding.readVarint2 = function readVarint2(data, off) { let num = 0; let size = 0; - let ch; for (;;) { assert(off < data.length, off); - ch = data[off++]; + const ch = data[off++]; size++; enforce(num < 0x3fffffffffff, off, 'Number exceeds 2^53-1'); @@ -815,11 +813,10 @@ encoding.writeVarint2 = function writeVarint2(dst, num, off) { encoding.skipVarint2 = function skipVarint2(data, off) { let size = 0; - let ch; for (;;) { assert(off < data.length, off); - ch = data[off++]; + const ch = data[off++]; size++; if ((ch & 0x80) === 0) break; @@ -857,12 +854,11 @@ encoding.sizeVarint2 = function sizeVarint2(num) { encoding.readVarint2BN = function readVarint2BN(data, off) { let num = 0; let size = 0; - let ch; while (num < 0x3fffffffffff) { assert(off < data.length, off); - ch = data[off++]; + const ch = data[off++]; size++; num = (num * 0x80) + (ch & 0x7f); @@ -878,7 +874,7 @@ encoding.readVarint2BN = function readVarint2BN(data, off) { for (;;) { assert(off < data.length, off); - ch = data[off++]; + const ch = data[off++]; size++; enforce(num.bitLength() <= 64, off, 'Number exceeds 64 bits'); @@ -1013,12 +1009,10 @@ encoding.sizeVarlen = function sizeVarlen(len) { */ encoding.sizeVarString = function sizeVarString(str, enc) { - let len; - if (typeof str !== 'string') return encoding.sizeVarBytes(str); - len = Buffer.byteLength(str, enc); + const len = Buffer.byteLength(str, enc); return encoding.sizeVarint(len) + len; }; diff --git a/lib/utils/fs.js b/lib/utils/fs.js index b696f2cd..bc0c02c8 100644 --- a/lib/utils/fs.js +++ b/lib/utils/fs.js @@ -133,13 +133,12 @@ exports.mkdirp = async function mkdirp(dir, mode) { }; function getParts(path) { - let root = ''; - let parts; - path = path.replace(/\\/g, '/'); path = path.replace(/(^|\/)\.\//, '$1'); path = path.replace(/\/+\.?$/, ''); - parts = path.split(/\/+/); + + const parts = path.split(/\/+/); + let root = ''; if (process.platform === 'win32') { if (parts[0].indexOf(':') !== -1) diff --git a/lib/utils/gcs.js b/lib/utils/gcs.js index 1e98a610..bb1f0f71 100644 --- a/lib/utils/gcs.js +++ b/lib/utils/gcs.js @@ -82,7 +82,6 @@ GCSFilter.prototype.matchAny = function matchAny(key, items) { for (;;) { const cmp = last1.cmp(last2); - let value; if (cmp === 0) break; @@ -96,7 +95,7 @@ GCSFilter.prototype.matchAny = function matchAny(key, items) { return false; } - value = this.readU64(br); + const value = this.readU64(br); if (value === EOF) return false; @@ -119,13 +118,12 @@ GCSFilter.prototype.readU64 = function readU64(br) { GCSFilter.prototype._readU64 = function _readU64(br) { const num = new Int64(0); - let rem; // Unary while (br.readBit()) num.iaddn(1); - rem = br.readBits64(this.p); + const rem = br.readBits64(this.p); return num.ishln(this.p).ior(rem); }; @@ -224,37 +222,31 @@ GCSFilter.prototype.fromBytes = function fromBytes(N, P, data) { }; GCSFilter.prototype.fromNBytes = function fromNBytes(P, data) { - let N; - assert(typeof P === 'number' && isFinite(P)); assert(Buffer.isBuffer(data)); assert(data.length >= 4); - N = data.readUInt32BE(0, true); + const N = data.readUInt32BE(0, true); return this.fromBytes(N, P, data.slice(4)); }; GCSFilter.prototype.fromPBytes = function fromPBytes(N, data) { - let P; - assert(typeof N === 'number' && isFinite(N)); assert(Buffer.isBuffer(data)); assert(data.length >= 1); - P = data.readUInt8(0, true); + const P = data.readUInt8(0, true); return this.fromBytes(N, P, data.slice(1)); }; GCSFilter.prototype.fromNPBytes = function fromNPBytes(data) { - let N, P; - assert(Buffer.isBuffer(data)); assert(data.length >= 5); - N = data.readUInt32BE(0, true); - P = data.readUInt8(4, true); + const N = data.readUInt32BE(0, true); + const P = data.readUInt8(4, true); return this.fromBytes(N, P, data.slice(5)); }; @@ -348,15 +340,13 @@ function BitWriter() { } BitWriter.prototype.writeBit = function writeBit(bit) { - let index; - if (this.remain === 0) { this.stream.push(0); this.remain = 8; } if (bit) { - index = this.stream.length - 1; + const index = this.stream.length - 1; this.stream[index] |= 1 << (this.remain - 1); } @@ -364,14 +354,12 @@ BitWriter.prototype.writeBit = function writeBit(bit) { }; BitWriter.prototype.writeByte = function writeByte(ch) { - let index; - if (this.remain === 0) { this.stream.push(0); this.remain = 8; } - index = this.stream.length - 1; + const index = this.stream.length - 1; this.stream[index] |= (ch >> (8 - this.remain)) & 0xff; this.stream.push(0); diff --git a/lib/utils/heap.js b/lib/utils/heap.js index 37fab199..a09e9f3e 100644 --- a/lib/utils/heap.js +++ b/lib/utils/heap.js @@ -32,12 +32,11 @@ function Heap(compare) { Heap.prototype.init = function init() { const n = this.items.length; - let i; if (n <= 1) return; - for (i = (n / 2 | 0) - 1; i >= 0; i--) + for (let i = (n / 2 | 0) - 1; i >= 0; i--) this.down(i, n); }; @@ -80,12 +79,10 @@ Heap.prototype.insert = function insert(item) { */ Heap.prototype.shift = function shift() { - let n; - if (this.items.length === 0) return; - n = this.items.length - 1; + const n = this.items.length - 1; this.swap(0, n); this.down(0, n); @@ -100,12 +97,10 @@ Heap.prototype.shift = function shift() { */ Heap.prototype.remove = function remove(i) { - let n; - if (this.items.length === 0) return; - n = this.items.length - 1; + const n = this.items.length - 1; if (i < 0 || i > n) return; @@ -153,18 +148,16 @@ Heap.prototype.less = function less(i, j) { */ Heap.prototype.down = function down(i, n) { - let j, l, r; - for (;;) { - l = 2 * i + 1; + const l = 2 * i + 1; assert(l >= 0); if (l < 0 || l >= n) break; - j = l; - r = l + 1; + let j = l; + const r = l + 1; if (r < n && !this.less(l, r)) j = r; @@ -184,10 +177,8 @@ Heap.prototype.down = function down(i, n) { */ Heap.prototype.up = function up(i) { - let j; - for (;;) { - j = (i - 1) / 2 | 0; + const j = (i - 1) / 2 | 0; assert(j >= 0); diff --git a/lib/utils/ip.js b/lib/utils/ip.js index 946e5e85..50384343 100644 --- a/lib/utils/ip.js +++ b/lib/utils/ip.js @@ -65,12 +65,10 @@ IP.types = { */ IP.fromHostname = function fromHostname(addr, fallback) { - let parts, host, port, type, hostname, raw; - assert(typeof addr === 'string'); - assert(addr.length > 0, 'Bad address.'); + let host, port; if (addr[0] === '[') { if (addr[addr.length - 1] === ']') { // Case: @@ -81,13 +79,13 @@ IP.fromHostname = function fromHostname(addr, fallback) { // Case: // [::1]:80 addr = addr.slice(1); - parts = addr.split(']:'); + const parts = addr.split(']:'); assert(parts.length === 2, 'Bad IPv6 address.'); host = parts[0]; port = parts[1]; } } else { - parts = addr.split(':'); + const parts = addr.split(':'); switch (parts.length) { case 2: // Cases: @@ -124,13 +122,15 @@ IP.fromHostname = function fromHostname(addr, fallback) { port = fallback || 0; } - type = IP.getStringType(host); + const type = IP.getStringType(host); + let raw; if (type !== IP.types.DNS) { raw = IP.toBuffer(host); host = IP.toString(raw); } + let hostname; if (type === IP.types.IPV6) hostname = `[${host}]:${port}`; else @@ -147,8 +147,6 @@ IP.fromHostname = function fromHostname(addr, fallback) { */ IP.toHostname = function toHostname(host, port) { - let type; - assert(typeof host === 'string'); assert(host.length > 0); assert(typeof port === 'number'); @@ -156,7 +154,7 @@ IP.toHostname = function toHostname(host, port) { assert(!/[\[\]]/.test(host), 'Bad host.'); - type = IP.getStringType(host); + const type = IP.getStringType(host); if (host.indexOf(':') !== -1) assert(type === IP.types.IPV6, 'Bad host.'); @@ -283,9 +281,9 @@ IP.toBuffer = function toBuffer(str) { } if (IP.isOnionString(str)) { - let data = TOR_ONION; - data.copy(raw, 0); - data = base32.decode(str.slice(0, -6)); + const prefix = TOR_ONION; + prefix.copy(raw, 0); + const data = base32.decode(str.slice(0, -6)); assert(data.length === 10, 'Invalid onion address.'); data.copy(raw, 6); return raw; @@ -988,7 +986,6 @@ IP.getInterfaces = function _getInterfaces(name, family) { for (const details of items) { const type = details.family.toLowerCase(); - let raw; if (family && type !== family) continue; @@ -996,6 +993,8 @@ IP.getInterfaces = function _getInterfaces(name, family) { if (details.internal) continue; + let raw; + try { raw = IP.toBuffer(details.address); } catch (e) { diff --git a/lib/utils/lock.js b/lib/utils/lock.js index 977e1cfa..3e341cb1 100644 --- a/lib/utils/lock.js +++ b/lib/utils/lock.js @@ -54,14 +54,12 @@ Lock.create = function create(named) { */ Lock.prototype.has = function has(name) { - let count; - assert(this.named, 'Must use named jobs.'); if (this.current === name) return true; - count = this.map.get(name); + const count = this.map.get(name); if (count == null) return false; @@ -77,11 +75,9 @@ Lock.prototype.has = function has(name) { */ Lock.prototype.hasPending = function hasPending(name) { - let count; - assert(this.named, 'Must use named jobs.'); - count = this.map.get(name); + const count = this.map.get(name); if (count == null) return false; @@ -142,8 +138,6 @@ Lock.prototype.lock = function lock(arg1, arg2) { */ Lock.prototype.unlock = function unlock() { - let job; - assert(this.destroyed || this.busy); this.busy = false; @@ -154,7 +148,7 @@ Lock.prototype.unlock = function unlock() { assert(!this.destroyed); - job = this.jobs.shift(); + const job = this.jobs.shift(); if (job.name) { let count = this.map.get(job.name); @@ -176,13 +170,11 @@ Lock.prototype.unlock = function unlock() { */ Lock.prototype.destroy = function destroy() { - let jobs; - assert(!this.destroyed, 'Lock is already destroyed.'); this.destroyed = true; - jobs = this.jobs.slice(); + const jobs = this.jobs.slice(); this.busy = false; this.jobs.length = 0; diff --git a/lib/utils/lru.js b/lib/utils/lru.js index 0342ec9f..43f5dd51 100644 --- a/lib/utils/lru.js +++ b/lib/utils/lru.js @@ -44,10 +44,8 @@ function LRU(capacity, getSize) { */ LRU.prototype._getSize = function _getSize(item) { - let keySize; - if (this.getSize) { - keySize = Math.floor(item.key.length * 1.375); + const keySize = Math.floor(item.key.length * 1.375); return 120 + keySize + this.getSize(item.value); } @@ -60,11 +58,11 @@ LRU.prototype._getSize = function _getSize(item) { */ LRU.prototype._compact = function _compact() { - let item, next; - if (this.size <= this.capacity) return; + let item, next; + for (item = this.head; item; item = next) { if (this.size <= this.capacity) break; @@ -115,14 +113,12 @@ LRU.prototype.reset = function reset() { */ LRU.prototype.set = function set(key, value) { - let item; - if (this.capacity === 0) return; key = key + ''; - item = this.map.get(key); + let item = this.map.get(key); if (item) { this.size -= this._getSize(item); @@ -153,14 +149,12 @@ LRU.prototype.set = function set(key, value) { */ LRU.prototype.get = function get(key) { - let item; - if (this.capacity === 0) return; key = key + ''; - item = this.map.get(key); + const item = this.map.get(key); if (!item) return; @@ -190,14 +184,12 @@ LRU.prototype.has = function get(key) { */ LRU.prototype.remove = function remove(key) { - let item; - if (this.capacity === 0) return; key = key + ''; - item = this.map.get(key); + const item = this.map.get(key); if (!item) return false; diff --git a/lib/utils/mappedlock.js b/lib/utils/mappedlock.js index 723c6fa3..b15fd63e 100644 --- a/lib/utils/mappedlock.js +++ b/lib/utils/mappedlock.js @@ -106,7 +106,6 @@ MappedLock.prototype.unlock = function unlock(key) { const self = this; return function unlocker() { const jobs = self.jobs.get(key); - let job; assert(self.destroyed || self.busy.has(key)); self.busy.delete(key); @@ -116,7 +115,7 @@ MappedLock.prototype.unlock = function unlock(key) { assert(!self.destroyed); - job = jobs.shift(); + const job = jobs.shift(); assert(job); if (jobs.length === 0) diff --git a/lib/utils/protoreader.js b/lib/utils/protoreader.js index 50557585..6dd66bf2 100644 --- a/lib/utils/protoreader.js +++ b/lib/utils/protoreader.js @@ -85,12 +85,10 @@ ProtoReader.prototype.readFieldString = function readFieldString(tag, opt, enc) }; ProtoReader.prototype.nextTag = function nextTag() { - let field; - if (this.left() === 0) return -1; - field = this.readField(); + const field = this.readField(); this.seek(-field.size); @@ -101,7 +99,6 @@ ProtoReader.prototype.readField = function readField(tag, opt) { const offset = this.offset; const header = this.readVarint(); const field = new Field(header); - let inner; if (tag != null && field.tag !== tag) { assert(opt, 'Non-optional field not present.'); @@ -122,7 +119,7 @@ ProtoReader.prototype.readField = function readField(tag, opt) { case wireType.START_GROUP: field.group = []; for (;;) { - inner = this.readField(); + const inner = this.readField(); if (inner.type === wireType.END_GROUP) break; field.group.push(inner); diff --git a/lib/utils/rbt.js b/lib/utils/rbt.js index 11c9549f..6b16cd39 100644 --- a/lib/utils/rbt.js +++ b/lib/utils/rbt.js @@ -69,7 +69,7 @@ RBT.prototype.search = function search(key) { RBT.prototype.insert = function insert(key, value) { let current = this.root; let left = false; - let parent, node; + let parent; while (!current.isNull()) { const cmp = this.compare(key, current.key); @@ -91,7 +91,7 @@ RBT.prototype.insert = function insert(key, value) { } } - node = new RBTNode(key, value); + const node = new RBTNode(key, value); if (!parent) { this.root = node; @@ -193,12 +193,11 @@ RBT.prototype.remove = function remove(key) { RBT.prototype.removeNode = function removeNode(z) { let y = z; - let x; if (!z.left.isNull() && !z.right.isNull()) y = this.successor(z); - x = y.left.isNull() ? y.right : y.left; + const x = y.left.isNull() ? y.right : y.left; x.parent = y.parent; if (y.parent.isNull()) { diff --git a/lib/utils/reader.js b/lib/utils/reader.js index 2c181fd2..d6c534b6 100644 --- a/lib/utils/reader.js +++ b/lib/utils/reader.js @@ -102,12 +102,10 @@ BufferReader.prototype.start = function start() { */ BufferReader.prototype.end = function _end() { - let start, end; - assert(this.stack.length > 0); - start = this.stack.pop(); - end = this.offset; + const start = this.stack.pop(); + const end = this.offset; return end - start; }; @@ -123,14 +121,12 @@ BufferReader.prototype.end = function _end() { */ BufferReader.prototype.endData = function endData(zeroCopy) { - let ret, start, end, size, data; - assert(this.stack.length > 0); - start = this.stack.pop(); - end = this.offset; - size = end - start; - data = this.data; + const start = this.stack.pop(); + const end = this.offset; + const size = end - start; + const data = this.data; if (size === data.length) return data; @@ -138,7 +134,7 @@ BufferReader.prototype.endData = function endData(zeroCopy) { if (this.zeroCopy || zeroCopy) return data.slice(start, end); - ret = Buffer.allocUnsafe(size); + const ret = Buffer.allocUnsafe(size); data.copy(ret, 0, start, end); return ret; @@ -160,9 +156,8 @@ BufferReader.prototype.destroy = function destroy() { */ BufferReader.prototype.readU8 = function readU8() { - let ret; this.assert(this.offset + 1 <= this.data.length); - ret = this.data[this.offset]; + const ret = this.data[this.offset]; this.offset += 1; return ret; }; @@ -173,9 +168,8 @@ BufferReader.prototype.readU8 = function readU8() { */ BufferReader.prototype.readU16 = function readU16() { - let ret; this.assert(this.offset + 2 <= this.data.length); - ret = this.data.readUInt16LE(this.offset, true); + const ret = this.data.readUInt16LE(this.offset, true); this.offset += 2; return ret; }; @@ -186,9 +180,8 @@ BufferReader.prototype.readU16 = function readU16() { */ BufferReader.prototype.readU16BE = function readU16BE() { - let ret; this.assert(this.offset + 2 <= this.data.length); - ret = this.data.readUInt16BE(this.offset, true); + const ret = this.data.readUInt16BE(this.offset, true); this.offset += 2; return ret; }; @@ -199,9 +192,8 @@ BufferReader.prototype.readU16BE = function readU16BE() { */ BufferReader.prototype.readU32 = function readU32() { - let ret; this.assert(this.offset + 4 <= this.data.length); - ret = this.data.readUInt32LE(this.offset, true); + const ret = this.data.readUInt32LE(this.offset, true); this.offset += 4; return ret; }; @@ -212,9 +204,8 @@ BufferReader.prototype.readU32 = function readU32() { */ BufferReader.prototype.readU32BE = function readU32BE() { - let ret; this.assert(this.offset + 4 <= this.data.length); - ret = this.data.readUInt32BE(this.offset, true); + const ret = this.data.readUInt32BE(this.offset, true); this.offset += 4; return ret; }; @@ -226,9 +217,8 @@ BufferReader.prototype.readU32BE = function readU32BE() { */ BufferReader.prototype.readU64 = function readU64() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.readU64(this.data, this.offset); + const ret = encoding.readU64(this.data, this.offset); this.offset += 8; return ret; }; @@ -240,9 +230,8 @@ BufferReader.prototype.readU64 = function readU64() { */ BufferReader.prototype.readU64BE = function readU64BE() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.readU64BE(this.data, this.offset); + const ret = encoding.readU64BE(this.data, this.offset); this.offset += 8; return ret; }; @@ -254,9 +243,8 @@ BufferReader.prototype.readU64BE = function readU64BE() { */ BufferReader.prototype.readU53 = function readU53() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.readU53(this.data, this.offset); + const ret = encoding.readU53(this.data, this.offset); this.offset += 8; return ret; }; @@ -268,9 +256,8 @@ BufferReader.prototype.readU53 = function readU53() { */ BufferReader.prototype.readU53BE = function readU53BE() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.readU53BE(this.data, this.offset); + const ret = encoding.readU53BE(this.data, this.offset); this.offset += 8; return ret; }; @@ -281,9 +268,8 @@ BufferReader.prototype.readU53BE = function readU53BE() { */ BufferReader.prototype.read8 = function read8() { - let ret; this.assert(this.offset + 1 <= this.data.length); - ret = this.data.readInt8(this.offset, true); + const ret = this.data.readInt8(this.offset, true); this.offset += 1; return ret; }; @@ -294,9 +280,8 @@ BufferReader.prototype.read8 = function read8() { */ BufferReader.prototype.read16 = function read16() { - let ret; this.assert(this.offset + 2 <= this.data.length); - ret = this.data.readInt16LE(this.offset, true); + const ret = this.data.readInt16LE(this.offset, true); this.offset += 2; return ret; }; @@ -307,9 +292,8 @@ BufferReader.prototype.read16 = function read16() { */ BufferReader.prototype.read16BE = function read16BE() { - let ret; this.assert(this.offset + 2 <= this.data.length); - ret = this.data.readInt16BE(this.offset, true); + const ret = this.data.readInt16BE(this.offset, true); this.offset += 2; return ret; }; @@ -320,9 +304,8 @@ BufferReader.prototype.read16BE = function read16BE() { */ BufferReader.prototype.read32 = function read32() { - let ret; this.assert(this.offset + 4 <= this.data.length); - ret = this.data.readInt32LE(this.offset, true); + const ret = this.data.readInt32LE(this.offset, true); this.offset += 4; return ret; }; @@ -333,9 +316,8 @@ BufferReader.prototype.read32 = function read32() { */ BufferReader.prototype.read32BE = function read32BE() { - let ret; this.assert(this.offset + 4 <= this.data.length); - ret = this.data.readInt32BE(this.offset, true); + const ret = this.data.readInt32BE(this.offset, true); this.offset += 4; return ret; }; @@ -347,9 +329,8 @@ BufferReader.prototype.read32BE = function read32BE() { */ BufferReader.prototype.read64 = function read64() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.read64(this.data, this.offset); + const ret = encoding.read64(this.data, this.offset); this.offset += 8; return ret; }; @@ -361,9 +342,8 @@ BufferReader.prototype.read64 = function read64() { */ BufferReader.prototype.read64BE = function read64BE() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.read64BE(this.data, this.offset); + const ret = encoding.read64BE(this.data, this.offset); this.offset += 8; return ret; }; @@ -375,9 +355,8 @@ BufferReader.prototype.read64BE = function read64BE() { */ BufferReader.prototype.read53 = function read53() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.read53(this.data, this.offset); + const ret = encoding.read53(this.data, this.offset); this.offset += 8; return ret; }; @@ -389,9 +368,8 @@ BufferReader.prototype.read53 = function read53() { */ BufferReader.prototype.read53BE = function read53BE() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.read53BE(this.data, this.offset); + const ret = encoding.read53BE(this.data, this.offset); this.offset += 8; return ret; }; @@ -402,9 +380,8 @@ BufferReader.prototype.read53BE = function read53BE() { */ BufferReader.prototype.readU64BN = function readU64BN() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.readU64BN(this.data, this.offset); + const ret = encoding.readU64BN(this.data, this.offset); this.offset += 8; return ret; }; @@ -415,9 +392,8 @@ BufferReader.prototype.readU64BN = function readU64BN() { */ BufferReader.prototype.readU64BEBN = function readU64BEBN() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.readU64BEBN(this.data, this.offset); + const ret = encoding.readU64BEBN(this.data, this.offset); this.offset += 8; return ret; }; @@ -428,9 +404,8 @@ BufferReader.prototype.readU64BEBN = function readU64BEBN() { */ BufferReader.prototype.read64BN = function read64BN() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.read64BN(this.data, this.offset); + const ret = encoding.read64BN(this.data, this.offset); this.offset += 8; return ret; }; @@ -441,9 +416,8 @@ BufferReader.prototype.read64BN = function read64BN() { */ BufferReader.prototype.read64BEBN = function read64BEBN() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = encoding.read64BEBN(this.data, this.offset); + const ret = encoding.read64BEBN(this.data, this.offset); this.offset += 8; return ret; }; @@ -454,9 +428,8 @@ BufferReader.prototype.read64BEBN = function read64BEBN() { */ BufferReader.prototype.readFloat = function readFloat() { - let ret; this.assert(this.offset + 4 <= this.data.length); - ret = this.data.readFloatLE(this.offset, true); + const ret = this.data.readFloatLE(this.offset, true); this.offset += 4; return ret; }; @@ -467,9 +440,8 @@ BufferReader.prototype.readFloat = function readFloat() { */ BufferReader.prototype.readFloatBE = function readFloatBE() { - let ret; this.assert(this.offset + 4 <= this.data.length); - ret = this.data.readFloatBE(this.offset, true); + const ret = this.data.readFloatBE(this.offset, true); this.offset += 4; return ret; }; @@ -480,9 +452,8 @@ BufferReader.prototype.readFloatBE = function readFloatBE() { */ BufferReader.prototype.readDouble = function readDouble() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = this.data.readDoubleLE(this.offset, true); + const ret = this.data.readDoubleLE(this.offset, true); this.offset += 8; return ret; }; @@ -493,9 +464,8 @@ BufferReader.prototype.readDouble = function readDouble() { */ BufferReader.prototype.readDoubleBE = function readDoubleBE() { - let ret; this.assert(this.offset + 8 <= this.data.length); - ret = this.data.readDoubleBE(this.offset, true); + const ret = this.data.readDoubleBE(this.offset, true); this.offset += 8; return ret; }; @@ -576,11 +546,10 @@ BufferReader.prototype.readVarint2BN = function readVarint2BN() { */ BufferReader.prototype.readBytes = function readBytes(size, zeroCopy) { - let ret; - assert(size >= 0); this.assert(this.offset + size <= this.data.length); + let ret; if (this.zeroCopy || zeroCopy) { ret = this.data.slice(this.offset, this.offset + size); } else { @@ -613,10 +582,9 @@ BufferReader.prototype.readVarBytes = function readVarBytes(zeroCopy) { */ BufferReader.prototype.readString = function readString(enc, size) { - let ret; assert(size >= 0); this.assert(this.offset + size <= this.data.length); - ret = this.data.toString(enc, this.offset, this.offset + size); + const ret = this.data.toString(enc, this.offset, this.offset + size); this.offset += size; return ret; }; @@ -653,15 +621,20 @@ BufferReader.prototype.readVarString = function readVarString(enc, limit) { */ BufferReader.prototype.readNullString = function readNullString(enc) { - let i, ret; this.assert(this.offset + 1 <= this.data.length); - for (i = this.offset; i < this.data.length; i++) { + + let i = this.offset; + for (; i < this.data.length; i++) { if (this.data[i] === 0) break; } + this.assert(i !== this.data.length); - ret = this.readString(enc, i - this.offset); + + const ret = this.readString(enc, i - this.offset); + this.offset = i + 1; + return ret; }; @@ -672,12 +645,11 @@ BufferReader.prototype.readNullString = function readNullString(enc) { BufferReader.prototype.createChecksum = function createChecksum() { let start = 0; - let data; if (this.stack.length > 0) start = this.stack[this.stack.length - 1]; - data = this.data.slice(start, this.offset); + const data = this.data.slice(start, this.offset); return digest.hash256(data).readUInt32LE(0, true); }; diff --git a/lib/utils/rollingfilter.js b/lib/utils/rollingfilter.js index c4ab5598..d79f545e 100644 --- a/lib/utils/rollingfilter.js +++ b/lib/utils/rollingfilter.js @@ -48,30 +48,28 @@ function RollingFilter(items, rate) { */ RollingFilter.prototype.fromRate = function fromRate(items, rate) { - let logRate, max, n, limit, size, tweak, filter; - assert(typeof items === 'number', '`items` must be a number.'); assert(items > 0, '`items` must be greater than zero.'); assert(items % 1 === 0, '`items` must be an integer.'); assert(typeof rate === 'number', '`rate` must be a number.'); assert(rate >= 0 && rate <= 1, '`rate` must be between 0.0 and 1.0.'); - logRate = Math.log(rate); + const logRate = Math.log(rate); - n = Math.max(1, Math.min(Math.round(logRate / Math.log(0.5)), 50)); - limit = (items + 1) / 2 | 0; + const n = Math.max(1, Math.min(Math.round(logRate / Math.log(0.5)), 50)); + const limit = (items + 1) / 2 | 0; - max = limit * 3; - size = -1 * n * max / Math.log(1.0 - Math.exp(logRate / n)); + const max = limit * 3; + let size = -1 * n * max / Math.log(1.0 - Math.exp(logRate / n)); size = Math.ceil(size); items = ((size + 63) / 64 | 0) << 1; items >>>= 0; items = Math.max(1, items); - tweak = (Math.random() * 0x100000000) >>> 0; + const tweak = (Math.random() * 0x100000000) >>> 0; - filter = Buffer.allocUnsafe(items * 8); + const filter = Buffer.allocUnsafe(items * 8); filter.fill(0); this.n = n; @@ -130,16 +128,14 @@ RollingFilter.prototype.add = function add(val, enc) { val = Buffer.from(val, enc); if (this.entries === this.limit) { - let m1, m2; - this.entries = 0; this.generation += 1; if (this.generation === 4) this.generation = 1; - m1 = (this.generation & 1) * 0xffffffff; - m2 = (this.generation >>> 1) * 0xffffffff; + const m1 = (this.generation & 1) * 0xffffffff; + const m2 = (this.generation >>> 1) * 0xffffffff; for (let i = 0; i < this.items; i += 2) { const pos1 = i * 8; diff --git a/lib/utils/staticwriter.js b/lib/utils/staticwriter.js index 3d9dfe89..2cd37156 100644 --- a/lib/utils/staticwriter.js +++ b/lib/utils/staticwriter.js @@ -351,12 +351,10 @@ StaticWriter.prototype.copy = function copy(value, start, end) { */ StaticWriter.prototype.writeString = function writeString(value, enc) { - let size; - if (value.length === 0) return; - size = Buffer.byteLength(value, enc); + const size = Buffer.byteLength(value, enc); this.data.write(value, this.written, enc); @@ -385,14 +383,12 @@ StaticWriter.prototype.writeHash = function writeHash(value) { */ StaticWriter.prototype.writeVarString = function writeVarString(value, enc) { - let size; - if (value.length === 0) { this.writeVarint(0); return; } - size = Buffer.byteLength(value, enc); + const size = Buffer.byteLength(value, enc); this.writeVarint(size); this.data.write(value, this.written, enc); diff --git a/lib/utils/util.js b/lib/utils/util.js index cd745130..ef725bff 100644 --- a/lib/utils/util.js +++ b/lib/utils/util.js @@ -39,7 +39,6 @@ const inspectOptions = { util.hrtime = function hrtime(time) { if (!process.hrtime) { let now = util.ms(); - let ms, sec; if (time) { time = time[0] * 1000 + time[1] / 1e6; @@ -47,8 +46,9 @@ util.hrtime = function hrtime(time) { return now; } - ms = now % 1000; - sec = (now - ms) / 1000; + const ms = now % 1000; + const sec = (now - ms) / 1000; + return [sec, ms * 1e6]; } @@ -93,12 +93,12 @@ util.isHex = function isHex(obj) { */ util.revHex = function revHex(data) { - let out = ''; - assert(typeof data === 'string'); assert(data.length > 0); assert(data.length % 2 === 0); + let out = ''; + for (let i = 0; i < data.length; i += 2) out = data.slice(i, i + 2) + out; @@ -123,9 +123,6 @@ util.isSafeInteger = function isSafeInteger(value) { */ util.isSafeAddition = function isSafeAddition(a, b) { - let hi, lo, ahi, alo, bhi, blo; - let as, bs, s, c; - // We only work on positive numbers. assert(a >= 0); assert(b >= 0); @@ -135,22 +132,22 @@ util.isSafeAddition = function isSafeAddition(a, b) { return true; // Do a 64 bit addition and check the top 11 bits. - ahi = (a * (1 / 0x100000000)) | 0; - alo = a | 0; + let ahi = (a * (1 / 0x100000000)) | 0; + const alo = a | 0; - bhi = (b * (1 / 0x100000000)) | 0; - blo = b | 0; + let bhi = (b * (1 / 0x100000000)) | 0; + const blo = b | 0; // Credit to @indutny for this method. - lo = (alo + blo) | 0; + const lo = (alo + blo) | 0; - s = lo >> 31; - as = alo >> 31; - bs = blo >> 31; + const s = lo >> 31; + const as = alo >> 31; + const bs = blo >> 31; - c = ((as & bs) | (~s & (as ^ bs))) & 1; + const c = ((as & bs) | (~s & (as ^ bs))) & 1; - hi = (((ahi + bhi) | 0) + c) | 0; + let hi = (((ahi + bhi) | 0) + c) | 0; hi >>>= 0; ahi >>>= 0; @@ -331,9 +328,8 @@ util.format = function format(args, color) { */ util.log = function log(...args) { - let msg; - if (!process.stdout) { + let msg; if (args.length > 0) { msg = typeof args[0] !== 'object' ? util.fmt(...args) @@ -343,7 +339,7 @@ util.log = function log(...args) { return; } - msg = util.format(args); + const msg = util.format(args); process.stdout.write(msg + '\n'); }; @@ -355,9 +351,8 @@ util.log = function log(...args) { */ util.error = function error(...args) { - let msg; - if (!process.stderr) { + let msg; if (args.length > 0) { msg = typeof args[0] !== 'object' ? util.fmt(...args) @@ -367,7 +362,7 @@ util.error = function error(...args) { return; } - msg = util.format(args); + const msg = util.format(args); process.stderr.write(msg + '\n'); }; @@ -772,8 +767,6 @@ if (!''.startsWith) { */ util.memoryUsage = function memoryUsage() { - let mem; - if (!process.memoryUsage) { return { total: 0, @@ -784,7 +777,7 @@ util.memoryUsage = function memoryUsage() { }; } - mem = process.memoryUsage(); + const mem = process.memoryUsage(); return { total: util.mb(mem.rss), diff --git a/lib/utils/validator.js b/lib/utils/validator.js index 28ed2f27..caeee155 100644 --- a/lib/utils/validator.js +++ b/lib/utils/validator.js @@ -84,12 +84,10 @@ Validator.prototype.get = function get(key, fallback) { 'Key must be a string.'); for (const map of this.data) { - let value; - if (!map || typeof map !== 'object') throw new ValidationError('data', 'object'); - value = map[key]; + const value = map[key]; if (value != null) return value; @@ -345,7 +343,6 @@ Validator.prototype.btc = function btc(key, fallback) { Validator.prototype.hash = function hash(key, fallback) { const value = this.get(key); - let out = ''; if (fallback === undefined) fallback = null; @@ -369,6 +366,8 @@ Validator.prototype.hash = function hash(key, fallback) { if (!/^[0-9a-f]+$/i.test(value)) throw new ValidationError(key, 'hex string'); + let out = ''; + for (let i = 0; i < value.length; i += 2) out = value.slice(i, i + 2) + out; @@ -403,7 +402,6 @@ Validator.prototype.numhash = function numhash(key, fallback) { Validator.prototype.numstr = function numstr(key, fallback) { const value = this.get(key); - let num; if (fallback === undefined) fallback = null; @@ -417,7 +415,7 @@ Validator.prototype.numstr = function numstr(key, fallback) { return value; } - num = parseInt(value, 10); + const num = parseInt(value, 10); if (!isFinite(num)) return value; @@ -474,7 +472,6 @@ Validator.prototype.bool = function bool(key, fallback) { Validator.prototype.buf = function buf(key, fallback, enc) { const value = this.get(key); - let data; if (!enc) enc = 'hex'; @@ -491,7 +488,7 @@ Validator.prototype.buf = function buf(key, fallback, enc) { return value; } - data = Buffer.from(value, enc); + const data = Buffer.from(value, enc); if (data.length !== Buffer.byteLength(value, enc)) throw new ValidationError(key, `${enc} string`); @@ -508,7 +505,6 @@ Validator.prototype.buf = function buf(key, fallback, enc) { Validator.prototype.array = function array(key, fallback) { const value = this.get(key); - let result, parts; if (fallback === undefined) fallback = null; @@ -522,8 +518,8 @@ Validator.prototype.array = function array(key, fallback) { return value; } - parts = value.trim().split(/\s*,\s*/); - result = []; + const parts = value.trim().split(/\s*,\s*/); + const result = []; for (const part of parts) { if (part.length === 0) diff --git a/lib/utils/writer.js b/lib/utils/writer.js index 3f9d7f70..e8d9c0f6 100644 --- a/lib/utils/writer.js +++ b/lib/utils/writer.js @@ -479,14 +479,12 @@ BufferWriter.prototype.writeHash = function writeHash(value) { */ BufferWriter.prototype.writeVarString = function writeVarString(value, enc) { - let size; - if (value.length === 0) { this.ops.push(new WriteOp(VARINT, 0)); return; } - size = Buffer.byteLength(value, enc); + const size = Buffer.byteLength(value, enc); this.written += encoding.sizeVarint(size); this.written += size; diff --git a/lib/wallet/account.js b/lib/wallet/account.js index 1c2cb2f3..b43e4439 100644 --- a/lib/wallet/account.js +++ b/lib/wallet/account.js @@ -274,8 +274,6 @@ Account.prototype.open = function open() { */ Account.prototype.pushKey = function pushKey(key) { - let index; - if (typeof key === 'string') key = HD.PublicKey.fromBase58(key, this.network); @@ -294,7 +292,7 @@ Account.prototype.pushKey = function pushKey(key) { if (key.equal(this.accountKey)) throw new Error('Cannot add own key.'); - index = util.binaryInsert(this.keys, key, cmp, true); + const index = util.binaryInsert(this.keys, key, cmp, true); if (index === -1) return false; @@ -366,13 +364,11 @@ Account.prototype.addSharedKey = async function addSharedKey(key) { */ Account.prototype._hasDuplicate = function _hasDuplicate() { - let ring, hash; - if (this.keys.length !== this.n - 1) return false; - ring = this.deriveReceive(0); - hash = ring.getScriptHash('hex'); + const ring = this.deriveReceive(0); + const hash = ring.getScriptHash('hex'); return this.wallet.hasAddress(hash); }; @@ -503,28 +499,31 @@ Account.prototype.deriveNested = function deriveNested(index, master) { */ Account.prototype.derivePath = function derivePath(path, master) { - let data = path.data; - let ring; - switch (path.keyType) { - case Path.types.HD: + case Path.types.HD: { return this.deriveKey(path.branch, path.index, master); - case Path.types.KEY: + } + case Path.types.KEY: { assert(this.type === Account.types.PUBKEYHASH); + let data = path.data; + if (path.encrypted) { data = master.decipher(data, path.hash); if (!data) return; } - ring = WalletKey.fromImport(this, data); + const ring = WalletKey.fromImport(this, data); return ring; - case Path.types.ADDRESS: + } + case Path.types.ADDRESS: { return; - default: + } + default: { assert(false, 'Bad key type.'); + } } }; @@ -536,11 +535,11 @@ Account.prototype.derivePath = function derivePath(path, master) { */ Account.prototype.deriveKey = function deriveKey(branch, index, master) { - const keys = []; - let key, ring; - assert(typeof branch === 'number'); + const keys = []; + let key; + if (master && master.key && !this.watchOnly) { key = master.key.deriveBIP44(this.accountIndex); key = key.derive(branch).derive(index); @@ -548,7 +547,7 @@ Account.prototype.deriveKey = function deriveKey(branch, index, master) { key = this.accountKey.derive(branch).derive(index); } - ring = WalletKey.fromHD(this, key, branch, index); + const ring = WalletKey.fromHD(this, key, branch, index); switch (this.type) { case Account.types.PUBKEYHASH: @@ -721,8 +720,6 @@ Account.prototype.syncDepth = async function syncDepth(receive, change, nested) */ Account.prototype.setLookahead = async function setLookahead(lookahead) { - let depth, target; - if (lookahead === this.lookahead) { this.db.logger.warning( 'Lookahead is not changing for: %s/%s.', @@ -751,20 +748,24 @@ Account.prototype.setLookahead = async function setLookahead(lookahead) { return; } - depth = this.receiveDepth + this.lookahead; - target = this.receiveDepth + lookahead; + { + const depth = this.receiveDepth + this.lookahead; + const target = this.receiveDepth + lookahead; - for (let i = depth; i < target; i++) { - const key = this.deriveReceive(i); - await this.saveKey(key); + for (let i = depth; i < target; i++) { + const key = this.deriveReceive(i); + await this.saveKey(key); + } } - depth = this.changeDepth + this.lookahead; - target = this.changeDepth + lookahead; + { + const depth = this.changeDepth + this.lookahead; + const target = this.changeDepth + lookahead; - for (let i = depth; i < target; i++) { - const key = this.deriveChange(i); - await this.saveKey(key); + for (let i = depth; i < target; i++) { + const key = this.deriveChange(i); + await this.saveKey(key); + } } if (this.witness) { @@ -950,7 +951,6 @@ Account.prototype.toRaw = function toRaw() { Account.prototype.fromRaw = function fromRaw(data) { const br = new BufferReader(data); - let count; this.name = br.readVarString('ascii'); this.initialized = br.readU8() === 1; @@ -967,7 +967,7 @@ Account.prototype.fromRaw = function fromRaw(data) { assert(Account.typesByVal[this.type]); - count = br.readU8(); + const count = br.readU8(); for (let i = 0; i < count; i++) { const key = HD.PublicKey.fromRaw(br.readBytes(82)); diff --git a/lib/wallet/client.js b/lib/wallet/client.js index 6921d39c..6bb25f86 100644 --- a/lib/wallet/client.js +++ b/lib/wallet/client.js @@ -309,17 +309,16 @@ WalletClient.prototype.rescan = function rescan(start) { */ function parseEntry(data, enc) { - let br, block, hash, height; - if (typeof data === 'string') data = Buffer.from(data, 'hex'); - block = Headers.fromHead(data); + const block = Headers.fromHead(data); - br = new BufferReader(data); + const br = new BufferReader(data); br.seek(80); - height = br.readU32(); - hash = block.hash('hex'); + + const height = br.readU32(); + const hash = block.hash('hex'); return new BlockMeta(hash, height, block.time); } @@ -328,8 +327,8 @@ function parseBlock(entry, txs) { const block = parseEntry(entry); const out = []; - for (let tx of txs) { - tx = parseTX(tx); + for (const raw of txs) { + const tx = parseTX(raw); out.push(tx); } diff --git a/lib/wallet/common.js b/lib/wallet/common.js index 4cfd5845..8527bd9b 100644 --- a/lib/wallet/common.js +++ b/lib/wallet/common.js @@ -99,12 +99,11 @@ common.sortDeps = function sortDeps(txs) { for (const input of tx.inputs) { const prev = input.prevout.hash; - let count; if (!map.has(prev)) continue; - count = depCount.get(hash); + const count = depCount.get(hash); depCount.set(hash, count + 1); hasDeps = true; diff --git a/lib/wallet/http.js b/lib/wallet/http.js index 79c47cfd..91a282ce 100644 --- a/lib/wallet/http.js +++ b/lib/wallet/http.js @@ -108,7 +108,6 @@ HTTPServer.prototype.initRouter = function initRouter() { this.hook(async (req, res) => { const valid = req.valid(); - let id, token, wallet; if (req.path.length === 0) return; @@ -119,11 +118,11 @@ HTTPServer.prototype.initRouter = function initRouter() { if (req.method === 'PUT' && req.path.length === 1) return; - id = valid.str('id'); - token = valid.buf('token'); + const id = valid.str('id'); + const token = valid.buf('token'); if (!this.options.walletAuth) { - wallet = await this.walletdb.get(id); + const wallet = await this.walletdb.get(id); if (!wallet) { res.send(404); @@ -135,6 +134,8 @@ HTTPServer.prototype.initRouter = function initRouter() { return; } + let wallet = null; + try { wallet = await this.walletdb.auth(id, token); } catch (err) { @@ -200,9 +201,8 @@ HTTPServer.prototype.initRouter = function initRouter() { // Create wallet (compat) this.post('/', async (req, res) => { const valid = req.valid(); - let wallet; - wallet = await this.walletdb.create({ + const wallet = await this.walletdb.create({ id: valid.str('id'), type: valid.str('type'), m: valid.u32('m'), @@ -221,9 +221,8 @@ HTTPServer.prototype.initRouter = function initRouter() { // Create wallet this.put('/:id', async (req, res) => { const valid = req.valid(); - let wallet; - wallet = await this.walletdb.create({ + const wallet = await this.walletdb.create({ id: valid.str('id'), type: valid.str('type'), m: valid.u32('m'), @@ -263,9 +262,8 @@ HTTPServer.prototype.initRouter = function initRouter() { this.post('/:id/account', async (req, res) => { const valid = req.valid(); const passphrase = valid.str('passphrase'); - let options, account; - options = { + const options = { name: valid.str(['account', 'name']), witness: valid.bool('witness'), watchOnly: valid.bool('watchOnly'), @@ -276,7 +274,7 @@ HTTPServer.prototype.initRouter = function initRouter() { lookahead: valid.u32('lookahead') }; - account = await req.wallet.createAccount(options, passphrase); + const account = await req.wallet.createAccount(options, passphrase); if (!account) { res.send(404); @@ -290,9 +288,8 @@ HTTPServer.prototype.initRouter = function initRouter() { this.put('/:id/account/:account', async (req, res) => { const valid = req.valid(); const passphrase = valid.str('passphrase'); - let options, account; - options = { + const options = { name: valid.str('account'), witness: valid.bool('witness'), watchOnly: valid.bool('watchOnly'), @@ -303,7 +300,7 @@ HTTPServer.prototype.initRouter = function initRouter() { lookahead: valid.u32('lookahead') }; - account = await req.wallet.createAccount(options, passphrase); + const account = await req.wallet.createAccount(options, passphrase); if (!account) { res.send(404); @@ -381,9 +378,8 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const passphrase = valid.str('passphrase'); const outputs = valid.array('outputs'); - let options, tx, details; - options = { + const options = { rate: valid.u64('rate'), blocks: valid.u32('blocks'), maxFee: valid.u64('maxFee'), @@ -410,9 +406,9 @@ HTTPServer.prototype.initRouter = function initRouter() { }); } - tx = await req.wallet.send(options, passphrase); + const tx = await req.wallet.send(options, passphrase); - details = await req.wallet.getDetails(tx.hash('hex')); + const details = await req.wallet.getDetails(tx.hash('hex')); res.send(200, details.toJSON()); }); @@ -422,9 +418,8 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const passphrase = valid.str('passphrase'); const outputs = valid.array('outputs'); - let options, tx; - options = { + const options = { rate: valid.u64('rate'), maxFee: valid.u64('maxFee'), selection: valid.str('selection'), @@ -450,7 +445,8 @@ HTTPServer.prototype.initRouter = function initRouter() { }); } - tx = await req.wallet.createTX(options); + const tx = await req.wallet.createTX(options); + await req.wallet.sign(tx, passphrase); res.send(200, tx.getJSON(this.network)); }); @@ -460,11 +456,10 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const passphrase = valid.str('passphrase'); const raw = valid.buf('tx'); - let tx; enforce(raw, 'TX is required.'); - tx = MTX.fromRaw(raw); + const tx = MTX.fromRaw(raw); await req.wallet.sign(tx, passphrase); @@ -500,11 +495,10 @@ HTTPServer.prototype.initRouter = function initRouter() { this.get('/:id/block/:height', async (req, res) => { const valid = req.valid(); const height = valid.u32('height'); - let block; enforce(height != null, 'Height is required.'); - block = await req.wallet.getBlock(height); + const block = await req.wallet.getBlock(height); if (!block) { res.send(404); @@ -538,11 +532,10 @@ HTTPServer.prototype.initRouter = function initRouter() { this.get('/:id/key/:address', async (req, res) => { const valid = req.valid(); const address = valid.str('address'); - let key; enforce(address, 'Address is required.'); - key = await req.wallet.getKey(address); + const key = await req.wallet.getKey(address); if (!key) { res.send(404); @@ -557,11 +550,10 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const address = valid.str('address'); const passphrase = valid.str('passphrase'); - let key; enforce(address, 'Address is required.'); - key = await req.wallet.getPrivateKey(address, passphrase); + const key = await req.wallet.getPrivateKey(address, passphrase); if (!key) { res.send(404); @@ -640,12 +632,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const hash = valid.hash('hash'); const index = valid.u32('index'); - let outpoint; enforce(hash, 'Hash is required.'); enforce(index != null, 'Index is required.'); - outpoint = new Outpoint(hash, index); + const outpoint = new Outpoint(hash, index); this.wallet.lockCoin(outpoint); }); @@ -655,12 +646,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const hash = valid.hash('hash'); const index = valid.u32('index'); - let outpoint; enforce(hash, 'Hash is required.'); enforce(index != null, 'Index is required.'); - outpoint = new Outpoint(hash, index); + const outpoint = new Outpoint(hash, index); this.wallet.unlockCoin(outpoint); }); @@ -670,12 +660,11 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const hash = valid.hash('hash'); const index = valid.u32('index'); - let coin; enforce(hash, 'Hash is required.'); enforce(index != null, 'Index is required.'); - coin = await req.wallet.getCoin(hash, index); + const coin = await req.wallet.getCoin(hash, index); if (!coin) { res.send(404); @@ -691,11 +680,10 @@ HTTPServer.prototype.initRouter = function initRouter() { const acct = valid.str('account'); const txs = await req.wallet.getHistory(acct); const result = []; - let details; common.sortTX(txs); - details = await req.wallet.toDetails(txs); + const details = await req.wallet.toDetails(txs); for (const item of details) result.push(item.toJSON()); @@ -709,11 +697,10 @@ HTTPServer.prototype.initRouter = function initRouter() { const acct = valid.str('account'); const txs = await req.wallet.getPending(acct); const result = []; - let details; common.sortTX(txs); - details = await req.wallet.toDetails(txs); + const details = await req.wallet.toDetails(txs); for (const item of details) result.push(item.toJSON()); @@ -726,18 +713,17 @@ HTTPServer.prototype.initRouter = function initRouter() { const valid = req.valid(); const acct = valid.str('account'); const result = []; - let options, txs, details; - options = { + const options = { start: valid.u32('start'), end: valid.u32('end'), limit: valid.u32('limit'), reverse: valid.bool('reverse') }; - txs = await req.wallet.getRange(acct, options); + const txs = await req.wallet.getRange(acct, options); - details = await req.wallet.toDetails(txs); + const details = await req.wallet.toDetails(txs); for (const item of details) result.push(item.toJSON()); @@ -764,18 +750,17 @@ HTTPServer.prototype.initRouter = function initRouter() { this.get('/:id/tx/:hash', async (req, res) => { const valid = req.valid(); const hash = valid.hash('hash'); - let tx, details; enforce(hash, 'Hash is required.'); - tx = await req.wallet.getTX(hash); + const tx = await req.wallet.getTX(hash); if (!tx) { res.send(404); return; } - details = await req.wallet.toDetails(tx); + const details = await req.wallet.toDetails(tx); res.send(200, details.toJSON()); }); @@ -857,13 +842,12 @@ HTTPServer.prototype.handleSocket = function handleSocket(socket) { socket.hook('wallet auth', (args) => { const valid = new Validator([args]); const key = valid.str(0); - let hash; if (socket.auth) throw new Error('Already authed.'); if (!this.options.noAuth) { - hash = hash256(key); + const hash = hash256(key); if (!ccmp(hash, this.options.apiHash)) throw new Error('Bad key.'); } @@ -890,7 +874,6 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) { const id = valid.str(0, ''); const token = valid.buf(1); const channel = 'w:' + id; - let wallet; if (!id) throw new Error('Invalid parameter.'); @@ -903,6 +886,8 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) { if (!token) throw new Error('Invalid parameter.'); + let wallet = null; + try { wallet = await this.walletdb.auth(id, token); } catch (e) { diff --git a/lib/wallet/masterkey.js b/lib/wallet/masterkey.js index 869fc1e5..fce5cfaf 100644 --- a/lib/wallet/masterkey.js +++ b/lib/wallet/masterkey.js @@ -187,8 +187,6 @@ MasterKey.prototype.unlock = async function _unlock(passphrase, timeout) { */ MasterKey.prototype._unlock = async function _unlock(passphrase, timeout) { - let data, key; - if (this.key) { if (this.encrypted) { assert(this.timer != null); @@ -202,8 +200,8 @@ MasterKey.prototype._unlock = async function _unlock(passphrase, timeout) { assert(this.encrypted); - key = await this.derive(passphrase); - data = aes.decipher(this.ciphertext, key, this.iv); + const key = await this.derive(passphrase); + const data = aes.decipher(this.ciphertext, key, this.iv); this.fromKeyRaw(data); @@ -379,8 +377,6 @@ MasterKey.prototype.decrypt = async function decrypt(passphrase, clean) { */ MasterKey.prototype._decrypt = async function decrypt(passphrase, clean) { - let key, data; - if (!this.encrypted) throw new Error('Master key is not encrypted.'); @@ -389,8 +385,8 @@ MasterKey.prototype._decrypt = async function decrypt(passphrase, clean) { this._lock(); - key = await this.derive(passphrase); - data = aes.decipher(this.ciphertext, key, this.iv); + const key = await this.derive(passphrase); + const data = aes.decipher(this.ciphertext, key, this.iv); this.fromKeyRaw(data); this.encrypted = false; @@ -428,21 +424,19 @@ MasterKey.prototype.encrypt = async function encrypt(passphrase, clean) { */ MasterKey.prototype._encrypt = async function encrypt(passphrase, clean) { - let key, data, iv; - if (this.encrypted) throw new Error('Master key is already encrypted.'); if (!passphrase) throw new Error('No passphrase provided.'); - data = this.toKeyRaw(); - iv = random.randomBytes(16); + const raw = this.toKeyRaw(); + const iv = random.randomBytes(16); this.stop(); - key = await this.derive(passphrase); - data = aes.encipher(data, key, iv); + const key = await this.derive(passphrase); + const data = aes.encipher(raw, key, iv); this.key = null; this.mnemonic = null; @@ -540,8 +534,7 @@ MasterKey.prototype.getSize = function getSize() { */ MasterKey.prototype.toRaw = function toRaw() { - let size = this.getSize(); - const bw = new StaticWriter(size); + const bw = new StaticWriter(this.getSize()); if (this.encrypted) { bw.writeU8(1); @@ -559,7 +552,7 @@ MasterKey.prototype.toRaw = function toRaw() { bw.writeU8(0); // NOTE: useless varint - size = this.getKeySize(); + const size = this.getKeySize(); bw.writeVarint(size); bw.writeBytes(this.key.toRaw()); diff --git a/lib/wallet/plugin.js b/lib/wallet/plugin.js index e924a861..8681e8ef 100644 --- a/lib/wallet/plugin.js +++ b/lib/wallet/plugin.js @@ -31,9 +31,8 @@ plugin.id = 'walletdb'; plugin.init = function init(node) { const config = node.config; const client = new NodeClient(node); - let wdb; - wdb = new WalletDB({ + const wdb = new WalletDB({ network: node.network, logger: node.logger, workers: node.workers, diff --git a/lib/wallet/rpc.js b/lib/wallet/rpc.js index 14b0dc45..a67255a4 100644 --- a/lib/wallet/rpc.js +++ b/lib/wallet/rpc.js @@ -111,12 +111,10 @@ RPC.prototype.init = function init() { }; RPC.prototype.help = async function _help(args, help) { - let json; - if (args.length === 0) return 'Select a command.'; - json = { + const json = { method: args[0], params: [] }; @@ -134,12 +132,10 @@ RPC.prototype.stop = async function stop(args, help) { }; RPC.prototype.fundRawTransaction = async function fundRawTransaction(args, help) { - let valid = new Validator([args]); + const valid = new Validator([args]); const data = valid.buf(0); - let options = valid.obj(1); + const options = valid.obj(1); const wallet = this.wallet; - let rate = this.feeRate; - let change, tx; if (help || args.length < 1 || args.length > 2) { throw new RPCError(errs.MISC_ERROR, @@ -149,15 +145,19 @@ RPC.prototype.fundRawTransaction = async function fundRawTransaction(args, help) if (!data) throw new RPCError(errs.TYPE_ERROR, 'Invalid hex string.'); - tx = MTX.fromRaw(data); + const tx = MTX.fromRaw(data); if (tx.outputs.length === 0) { throw new RPCError(errs.INVALID_PARAMETER, 'TX must have at least one output.'); } + let rate = this.feeRate; + let change = null; + if (options) { - valid = new Validator([options]); + const valid = new Validator([options]); + change = valid.str('changeAddress'); rate = valid.btc('feeRate'); @@ -165,12 +165,10 @@ RPC.prototype.fundRawTransaction = async function fundRawTransaction(args, help) change = parseAddress(change, this.network); } - options = { + await wallet.fund(tx, { rate: rate, changeAddress: change - }; - - await wallet.fund(tx, options); + }); return { hex: tx.toRaw().toString('hex'), @@ -186,12 +184,11 @@ RPC.prototype.fundRawTransaction = async function fundRawTransaction(args, help) RPC.prototype.resendWalletTransactions = async function resendWalletTransactions(args, help) { const wallet = this.wallet; const hashes = []; - let txs; if (help || args.length !== 0) throw new RPCError(errs.MISC_ERROR, 'resendwallettransactions'); - txs = await wallet.resend(); + const txs = await wallet.resend(); for (const tx of txs) hashes.push(tx.txid()); @@ -233,13 +230,12 @@ RPC.prototype.dumpPrivKey = async function dumpPrivKey(args, help) { const wallet = this.wallet; const valid = new Validator([args]); const addr = valid.str(0, ''); - let hash, ring; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'dumpprivkey "bitcoinaddress"'); - hash = parseHash(addr, this.network); - ring = await wallet.getPrivateKey(hash); + const hash = parseHash(addr, this.network); + const ring = await wallet.getPrivateKey(hash); if (!ring) throw new RPCError(errs.MISC_ERROR, 'Key not found.'); @@ -252,7 +248,6 @@ RPC.prototype.dumpWallet = async function dumpWallet(args, help) { const valid = new Validator([args]); const file = valid.str(0); const time = util.date(); - let tip, out, hashes; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'dumpwallet "filename"'); @@ -260,9 +255,9 @@ RPC.prototype.dumpWallet = async function dumpWallet(args, help) { if (!file) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - tip = await this.wdb.getTip(); + const tip = await this.wdb.getTip(); - out = [ + const out = [ util.fmt('# Wallet Dump created by Bcoin %s', pkg.version), util.fmt('# * Created on %s', time), util.fmt('# * Best block at time of backup was %d (%s).', @@ -271,22 +266,22 @@ RPC.prototype.dumpWallet = async function dumpWallet(args, help) { '' ]; - hashes = await wallet.getAddressHashes(); + const hashes = await wallet.getAddressHashes(); for (const hash of hashes) { const ring = await wallet.getPrivateKey(hash); - let addr, fmt, str; if (!ring) continue; - addr = ring.getAddress('string'); - fmt = '%s %s label= addr=%s'; + const addr = ring.getAddress('string'); + + let fmt = '%s %s label= addr=%s'; if (ring.branch === 1) fmt = '%s %s change=1 addr=%s'; - str = util.fmt(fmt, ring.toSecret(), time, addr); + const str = util.fmt(fmt, ring.toSecret(), time, addr); out.push(str); } @@ -295,12 +290,12 @@ RPC.prototype.dumpWallet = async function dumpWallet(args, help) { out.push('# End of dump'); out.push(''); - out = out.join('\n'); + const dump = out.join('\n'); if (fs.unsupported) - return out; + return dump; - await fs.writeFile(file, out, 'utf8'); + await fs.writeFile(file, dump, 'utf8'); return null; }; @@ -334,7 +329,6 @@ RPC.prototype.getAccountAddress = async function getAccountAddress(args, help) { const valid = new Validator([args]); const wallet = this.wallet; let name = valid.str(0, ''); - let account; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'getaccountaddress "account"'); @@ -342,7 +336,7 @@ RPC.prototype.getAccountAddress = async function getAccountAddress(args, help) { if (!name) name = 'default'; - account = await wallet.getAccount(name); + const account = await wallet.getAccount(name); if (!account) return ''; @@ -354,13 +348,12 @@ RPC.prototype.getAccount = async function getAccount(args, help) { const wallet = this.wallet; const valid = new Validator([args]); const addr = valid.str(0, ''); - let hash, path; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'getaccount "bitcoinaddress"'); - hash = parseHash(addr, this.network); - path = await wallet.getPath(hash); + const hash = parseHash(addr, this.network); + const path = await wallet.getPath(hash); if (!path) return ''; @@ -373,7 +366,6 @@ RPC.prototype.getAddressesByAccount = async function getAddressesByAccount(args, const valid = new Validator([args]); let name = valid.str(0, ''); const addrs = []; - let paths; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'getaddressesbyaccount "account"'); @@ -381,7 +373,7 @@ RPC.prototype.getAddressesByAccount = async function getAddressesByAccount(args, if (name === '') name = 'default'; - paths = await wallet.getPaths(name); + const paths = await wallet.getPaths(name); for (const path of paths) { const addr = path.toAddress(); @@ -397,7 +389,6 @@ RPC.prototype.getBalance = async function getBalance(args, help) { let name = valid.str(0); const minconf = valid.u32(1, 0); const watchOnly = valid.bool(2, false); - let value, balance; if (help || args.length > 3) { throw new RPCError(errs.MISC_ERROR, @@ -413,7 +404,8 @@ RPC.prototype.getBalance = async function getBalance(args, help) { if (wallet.watchOnly !== watchOnly) return 0; - balance = await wallet.getBalance(name); + const balance = await wallet.getBalance(name); + let value; if (minconf > 0) value = balance.confirmed; @@ -427,7 +419,6 @@ RPC.prototype.getNewAddress = async function getNewAddress(args, help) { const wallet = this.wallet; const valid = new Validator([args]); let name = valid.str(0); - let addr; if (help || args.length > 1) throw new RPCError(errs.MISC_ERROR, 'getnewaddress ( "account" )'); @@ -435,19 +426,18 @@ RPC.prototype.getNewAddress = async function getNewAddress(args, help) { if (name === '') name = 'default'; - addr = await wallet.createReceive(name); + const addr = await wallet.createReceive(name); return addr.getAddress('string'); }; RPC.prototype.getRawChangeAddress = async function getRawChangeAddress(args, help) { const wallet = this.wallet; - let addr; if (help || args.length > 1) throw new RPCError(errs.MISC_ERROR, 'getrawchangeaddress'); - addr = await wallet.createChange(); + const addr = await wallet.createChange(); return addr.getAddress('string'); }; @@ -461,7 +451,6 @@ RPC.prototype.getReceivedByAccount = async function getReceivedByAccount(args, h const filter = new Set(); let total = 0; let lastConf = -1; - let paths, txs; if (help || args.length < 1 || args.length > 2) { throw new RPCError(errs.MISC_ERROR, @@ -471,12 +460,12 @@ RPC.prototype.getReceivedByAccount = async function getReceivedByAccount(args, h if (name === '') name = 'default'; - paths = await wallet.getPaths(name); + const paths = await wallet.getPaths(name); for (const path of paths) filter.add(path.hash); - txs = await wallet.getHistory(name); + const txs = await wallet.getHistory(name); for (const wtx of txs) { const conf = wtx.getDepth(height); @@ -504,15 +493,14 @@ RPC.prototype.getReceivedByAddress = async function getReceivedByAddress(args, h const minconf = valid.u32(1, 0); const height = this.wdb.state.height; let total = 0; - let hash, txs; if (help || args.length < 1 || args.length > 2) { throw new RPCError(errs.MISC_ERROR, 'getreceivedbyaddress "bitcoinaddress" ( minconf )'); } - hash = parseHash(addr, this.network); - txs = await wallet.getHistory(); + const hash = parseHash(addr, this.network); + const txs = await wallet.getHistory(); for (const wtx of txs) { if (wtx.getDepth(height) < minconf) @@ -604,7 +592,6 @@ RPC.prototype.getTransaction = async function getTransaction(args, help) { const valid = new Validator([args]); const hash = valid.hash(0); const watchOnly = valid.bool(1, false); - let wtx; if (help || args.length < 1 || args.length > 2) { throw new RPCError(errs.MISC_ERROR, @@ -614,7 +601,7 @@ RPC.prototype.getTransaction = async function getTransaction(args, help) { if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter'); - wtx = await wallet.getTX(hash); + const wtx = await wallet.getTX(hash); if (!wtx) throw new RPCError(errs.WALLET_ERROR, 'TX not found.'); @@ -626,7 +613,6 @@ RPC.prototype.abandonTransaction = async function abandonTransaction(args, help) const wallet = this.wallet; const valid = new Validator([args]); const hash = valid.hash(0); - let result; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'abandontransaction "txid"'); @@ -634,7 +620,7 @@ RPC.prototype.abandonTransaction = async function abandonTransaction(args, help) if (!hash) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - result = await wallet.abandon(hash); + const result = await wallet.abandon(hash); if (!result) throw new RPCError(errs.WALLET_ERROR, 'Transaction not in wallet.'); @@ -644,24 +630,22 @@ RPC.prototype.abandonTransaction = async function abandonTransaction(args, help) RPC.prototype.getUnconfirmedBalance = async function getUnconfirmedBalance(args, help) { const wallet = this.wallet; - let balance; if (help || args.length > 0) throw new RPCError(errs.MISC_ERROR, 'getunconfirmedbalance'); - balance = await wallet.getBalance(); + const balance = await wallet.getBalance(); return Amount.btc(balance.unconfirmed, true); }; RPC.prototype.getWalletInfo = async function getWalletInfo(args, help) { const wallet = this.wallet; - let balance; if (help || args.length !== 0) throw new RPCError(errs.MISC_ERROR, 'getwalletinfo'); - balance = await wallet.getBalance(); + const balance = await wallet.getBalance(); return { walletid: wallet.id, @@ -683,14 +667,13 @@ RPC.prototype.importPrivKey = async function importPrivKey(args, help) { const valid = new Validator([args]); const secret = valid.str(0); const rescan = valid.bool(2, false); - let key; if (help || args.length < 1 || args.length > 3) { throw new RPCError(errs.MISC_ERROR, 'importprivkey "bitcoinprivkey" ( "label" rescan )'); } - key = parseSecret(secret, this.network); + const key = parseSecret(secret, this.network); await wallet.importKey(0, key); @@ -706,7 +689,6 @@ RPC.prototype.importWallet = async function importWallet(args, help) { const file = valid.str(0); const rescan = valid.bool(1, false); const keys = []; - let data, lines; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'importwallet "filename" ( rescan )'); @@ -714,13 +696,11 @@ RPC.prototype.importWallet = async function importWallet(args, help) { if (fs.unsupported) throw new RPCError(errs.INTERNAL_ERROR, 'FS not available.'); - data = await fs.readFile(file, 'utf8'); + const data = await fs.readFile(file, 'utf8'); - lines = data.split(/\n+/); + const lines = data.split(/\n+/); for (let line of lines) { - let parts, secret; - line = line.trim(); if (line.length === 0) @@ -729,12 +709,12 @@ RPC.prototype.importWallet = async function importWallet(args, help) { if (/^\s*#/.test(line)) continue; - parts = line.split(/\s+/); + const parts = line.split(/\s+/); if (parts.length < 4) throw new RPCError(errs.DESERIALIZATION_ERROR, 'Malformed wallet.'); - secret = parseSecret(parts[0], this.network); + const secret = parseSecret(parts[0], this.network); keys.push(secret); } @@ -754,7 +734,6 @@ RPC.prototype.importAddress = async function importAddress(args, help) { let addr = valid.str(0, ''); const rescan = valid.bool(2, false); const p2sh = valid.bool(3, false); - let script; if (help || args.length < 1 || args.length > 4) { throw new RPCError(errs.MISC_ERROR, @@ -762,7 +741,7 @@ RPC.prototype.importAddress = async function importAddress(args, help) { } if (p2sh) { - script = valid.buf(0); + let script = valid.buf(0); if (!script) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameters.'); @@ -788,7 +767,6 @@ RPC.prototype.importPubkey = async function importPubkey(args, help) { const valid = new Validator([args]); const data = valid.buf(0); const rescan = valid.bool(2, false); - let key; if (help || args.length < 1 || args.length > 4) { throw new RPCError(errs.MISC_ERROR, @@ -798,7 +776,7 @@ RPC.prototype.importPubkey = async function importPubkey(args, help) { if (!data) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - key = KeyRing.fromPublic(data, this.network); + const key = KeyRing.fromPublic(data, this.network); await wallet.importKey(0, key); @@ -820,14 +798,13 @@ RPC.prototype.listAccounts = async function listAccounts(args, help) { const minconf = valid.u32(0, 0); const watchOnly = valid.bool(1, false); const map = {}; - let accounts; if (help || args.length > 2) { throw new RPCError(errs.MISC_ERROR, 'listaccounts ( minconf includeWatchonly)'); } - accounts = await wallet.getAccounts(); + const accounts = await wallet.getAccounts(); for (const account of accounts) { const balance = await wallet.getBalance(account); @@ -854,12 +831,11 @@ RPC.prototype.listAddressGroupings = async function listAddressGroupings(args, h RPC.prototype.listLockUnspent = async function listLockUnspent(args, help) { const wallet = this.wallet; const out = []; - let outpoints; if (help || args.length > 0) throw new RPCError(errs.MISC_ERROR, 'listlockunspent'); - outpoints = wallet.getLocked(); + const outpoints = wallet.getLocked(); for (const outpoint of outpoints) { out.push({ @@ -906,7 +882,6 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch const map = new Map(); let out = []; const result = []; - let txs; for (const path of paths) { const addr = path.toAddress(); @@ -920,7 +895,7 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch }); } - txs = await wallet.getHistory(); + const txs = await wallet.getHistory(); for (const wtx of txs) { const conf = wtx.getDepth(height); @@ -930,13 +905,12 @@ RPC.prototype._listReceived = async function _listReceived(minconf, empty, watch for (const output of wtx.tx.outputs) { const addr = output.getAddress(); - let hash, entry; if (!addr) continue; - hash = addr.getHash('hex'); - entry = map.get(hash); + const hash = addr.getHash('hex'); + const entry = map.get(hash); if (entry) { if (entry.confirmations === -1 || conf < entry.confirmations) @@ -992,7 +966,7 @@ RPC.prototype.listSinceBlock = async function listSinceBlock(args, help) { const watchOnly = valid.bool(2, false); let height = -1; const out = []; - let txs, highest; + let highest; if (help) { throw new RPCError(errs.MISC_ERROR, @@ -1011,11 +985,9 @@ RPC.prototype.listSinceBlock = async function listSinceBlock(args, help) { if (height === -1) height = this.chain.height; - txs = await wallet.getHistory(); + const txs = await wallet.getHistory(); for (const wtx of txs) { - let json; - if (wtx.height < height) continue; @@ -1025,7 +997,7 @@ RPC.prototype.listSinceBlock = async function listSinceBlock(args, help) { if (!highest || wtx.height > highest) highest = wtx; - json = await this._toListTX(wtx); + const json = await this._toListTX(wtx); out.push(json); } @@ -1045,7 +1017,6 @@ RPC.prototype._toListTX = async function _toListTX(wtx) { let received = 0; let receive = true; let sendMember, recMember, sendIndex, recIndex; - let member, index; if (!details) throw new RPCError(errs.WALLET_ERROR, 'TX not found.'); @@ -1074,6 +1045,8 @@ RPC.prototype._toListTX = async function _toListTX(wtx) { sendIndex = i; } + let member, index; + if (receive) { member = recMember; index = recIndex; @@ -1119,7 +1092,6 @@ RPC.prototype.listTransactions = async function listTransactions(args, help) { const watchOnly = valid.bool(3, false); let end = from + count; const out = []; - let txs; if (help || args.length > 4) { throw new RPCError(errs.MISC_ERROR, @@ -1132,7 +1104,7 @@ RPC.prototype.listTransactions = async function listTransactions(args, help) { if (name === '') name = 'default'; - txs = await wallet.getHistory(); + const txs = await wallet.getHistory(); common.sortTX(txs); @@ -1156,7 +1128,6 @@ RPC.prototype.listUnspent = async function listUnspent(args, help) { const height = this.wdb.state.height; const map = new Set(); const out = []; - let coins; if (help || args.length > 3) { throw new RPCError(errs.MISC_ERROR, @@ -1176,30 +1147,29 @@ RPC.prototype.listUnspent = async function listUnspent(args, help) { } } - coins = await wallet.getCoins(); + const coins = await wallet.getCoins(); common.sortCoins(coins); for (const coin of coins) { const depth = coin.getDepth(height); - let addr, hash, ring; if (!(depth >= minDepth && depth <= maxDepth)) continue; - addr = coin.getAddress(); + const addr = coin.getAddress(); if (!addr) continue; - hash = coin.getHash('hex'); + const hash = coin.getHash('hex'); if (addrs) { if (!hash || !map.has(hash)) continue; } - ring = await wallet.getKey(hash); + const ring = await wallet.getKey(hash); out.push({ txid: coin.txid(), @@ -1244,12 +1214,11 @@ RPC.prototype.lockUnspent = async function lockUnspent(args, help) { const valid = new Validator([output]); const hash = valid.hash('txid'); const index = valid.u32('vout'); - let outpoint; if (hash == null || index == null) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.'); - outpoint = new Outpoint(); + const outpoint = new Outpoint(); outpoint.hash = hash; outpoint.index = index; @@ -1273,10 +1242,9 @@ RPC.prototype.sendFrom = async function sendFrom(args, help) { const wallet = this.wallet; const valid = new Validator([args]); let name = valid.str(0); - let addr = valid.str(1); + const str = valid.str(1); const value = valid.btc(2); const minconf = valid.u32(3, 0); - let options, tx; if (help || args.length < 3 || args.length > 6) { throw new RPCError(errs.MISC_ERROR, @@ -1287,12 +1255,12 @@ RPC.prototype.sendFrom = async function sendFrom(args, help) { if (!addr || value == null) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - addr = parseAddress(addr, this.network); + const addr = parseAddress(str, this.network); if (name === '') name = 'default'; - options = { + const options = { account: name, subtractFee: false, rate: this.feeRate, @@ -1303,21 +1271,20 @@ RPC.prototype.sendFrom = async function sendFrom(args, help) { }] }; - tx = await wallet.send(options); + const tx = await wallet.send(options); return tx.txid(); }; RPC.prototype.sendMany = async function sendMany(args, help) { const wallet = this.wallet; - let valid = new Validator([args]); + const valid = new Validator([args]); let name = valid.str(0); const sendTo = valid.obj(1); const minconf = valid.u32(2, 1); const subtractFee = valid.bool(4, false); const uniq = new Set(); const outputs = []; - let options, tx; if (help || args.length < 2 || args.length > 5) { throw new RPCError(errs.MISC_ERROR, @@ -1331,13 +1298,12 @@ RPC.prototype.sendMany = async function sendMany(args, help) { if (!sendTo) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - valid = new Validator([sendTo]); + const to = new Validator([sendTo]); for (const key of Object.keys(sendTo)) { - const value = valid.btc(key); + const value = to.btc(key); const addr = parseAddress(key, this.network); const hash = addr.getHash('hex'); - let output; if (value == null) throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.'); @@ -1347,20 +1313,20 @@ RPC.prototype.sendMany = async function sendMany(args, help) { uniq.add(hash); - output = new Output(); + const output = new Output(); output.value = value; output.script.fromAddress(addr); outputs.push(output); } - options = { + const options = { outputs: outputs, subtractFee: subtractFee, account: name, depth: minconf }; - tx = await wallet.send(options); + const tx = await wallet.send(options); return tx.txid(); }; @@ -1368,10 +1334,9 @@ RPC.prototype.sendMany = async function sendMany(args, help) { RPC.prototype.sendToAddress = async function sendToAddress(args, help) { const wallet = this.wallet; const valid = new Validator([args]); - let addr = valid.str(0); + const str = valid.str(0); const value = valid.btc(1); const subtractFee = valid.bool(4, false); - let options, tx; if (help || args.length < 2 || args.length > 5) { throw new RPCError(errs.MISC_ERROR, @@ -1379,12 +1344,12 @@ RPC.prototype.sendToAddress = async function sendToAddress(args, help) { + ' ( "comment" "comment-to" subtractfeefromamount )'); } - addr = parseAddress(addr, this.network); + const addr = parseAddress(str, this.network); if (!addr || value == null) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - options = { + const options = { subtractFee: subtractFee, rate: this.feeRate, outputs: [{ @@ -1393,7 +1358,7 @@ RPC.prototype.sendToAddress = async function sendToAddress(args, help) { }] }; - tx = await wallet.send(options); + const tx = await wallet.send(options); return tx.txid(); }; @@ -1426,18 +1391,17 @@ RPC.prototype.setTXFee = async function setTXFee(args, help) { RPC.prototype.signMessage = async function signMessage(args, help) { const wallet = this.wallet; const valid = new Validator([args]); - let addr = valid.str(0, ''); - let msg = valid.str(1, ''); - let sig, ring; + const b58 = valid.str(0, ''); + const str = valid.str(1, ''); if (help || args.length !== 2) { throw new RPCError(errs.MISC_ERROR, 'signmessage "bitcoinaddress" "message"'); } - addr = parseHash(addr, this.network); + const addr = parseHash(b58, this.network); - ring = await wallet.getKey(addr); + const ring = await wallet.getKey(addr); if (!ring) throw new RPCError(errs.WALLET_ERROR, 'Address not found.'); @@ -1445,10 +1409,10 @@ RPC.prototype.signMessage = async function signMessage(args, help) { if (!wallet.master.key) throw new RPCError(errs.WALLET_UNLOCK_NEEDED, 'Wallet is locked.'); - msg = Buffer.from(MAGIC_STRING + msg, 'utf8'); - msg = digest.hash256(msg); + const msg = Buffer.from(MAGIC_STRING + str, 'utf8'); + const hash = digest.hash256(msg); - sig = ring.sign(msg); + const sig = ring.sign(hash); return sig.toString('base64'); }; @@ -1516,21 +1480,20 @@ RPC.prototype.walletPassphrase = async function walletPassphrase(args, help) { RPC.prototype.importPrunedFunds = async function importPrunedFunds(args, help) { const valid = new Validator([args]); - let tx = valid.buf(0); - let block = valid.buf(1); - let hash, height; + const txRaw = valid.buf(0); + const blockRaw = valid.buf(1); if (help || args.length < 2 || args.length > 3) { throw new RPCError(errs.MISC_ERROR, 'importprunedfunds "rawtransaction" "txoutproof" ( "label" )'); } - if (!tx || !block) + if (!txRaw || !blockRaw) throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.'); - tx = TX.fromRaw(tx); - block = MerkleBlock.fromRaw(block); - hash = block.hash('hex'); + const tx = TX.fromRaw(txRaw); + const block = MerkleBlock.fromRaw(blockRaw); + const hash = block.hash('hex'); if (!block.verify()) throw new RPCError(errs.VERIFY_ERROR, 'Invalid proof.'); @@ -1538,18 +1501,18 @@ RPC.prototype.importPrunedFunds = async function importPrunedFunds(args, help) { if (!block.hasTX(tx.hash('hex'))) throw new RPCError(errs.VERIFY_ERROR, 'Invalid proof.'); - height = await this.client.getEntry(hash); + const height = await this.client.getEntry(hash); if (height === -1) throw new RPCError(errs.VERIFY_ERROR, 'Invalid proof.'); - block = { + const entry = { hash: hash, time: block.time, height: height }; - if (!(await this.wdb.addTX(tx, block))) + if (!(await this.wdb.addTX(tx, entry))) throw new RPCError(errs.WALLET_ERROR, 'No tracked address for TX.'); return null; @@ -1575,12 +1538,11 @@ RPC.prototype.removePrunedFunds = async function removePrunedFunds(args, help) { RPC.prototype.selectWallet = async function selectWallet(args, help) { const valid = new Validator([args]); const id = valid.str(0); - let wallet; if (help || args.length !== 1) throw new RPCError(errs.MISC_ERROR, 'selectwallet "id"'); - wallet = await this.wdb.get(id); + const wallet = await this.wdb.get(id); if (!wallet) throw new RPCError(errs.WALLET_ERROR, 'Wallet not found.'); diff --git a/lib/wallet/server.js b/lib/wallet/server.js index 3d331dbb..ae941049 100644 --- a/lib/wallet/server.js +++ b/lib/wallet/server.js @@ -27,7 +27,6 @@ const server = exports; server.create = function create(options) { const config = new Config('bcoin'); let logger = new Logger('debug'); - let client, wdb, workers; config.inject(options); config.load(options); @@ -38,7 +37,7 @@ server.create = function create(options) { if (config.has('logger')) logger = config.obj('logger'); - client = new Client({ + const client = new Client({ network: config.network, uri: config.str('node-uri'), apiKey: config.str('node-api-key') @@ -53,7 +52,7 @@ server.create = function create(options) { shrink: config.bool('log-shrink') }); - workers = new WorkerPool({ + const workers = new WorkerPool({ enabled: config.str('workers-enabled'), size: config.num('workers-size'), timeout: config.num('workers-timeout') @@ -80,7 +79,7 @@ server.create = function create(options) { wdb.emit('error', err); }); - wdb = new WalletDB({ + const wdb = new WalletDB({ network: config.network, logger: logger, workers: workers, diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index 7acc1fca..aa936ccd 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -383,7 +383,6 @@ TXDB.prototype.removeInput = function removeInput(tx, index) { TXDB.prototype.resolveInput = async function resolveInput(tx, index, height, path, own) { const hash = tx.hash('hex'); const spent = await this.getSpent(hash, index); - let stx, credit; if (!spent) return false; @@ -395,11 +394,11 @@ TXDB.prototype.resolveInput = async function resolveInput(tx, index, height, pat // Get the spending transaction so // we can properly add the undo coin. - stx = await this.getTX(spent.hash); + const stx = await this.getTX(spent.hash); assert(stx); // Crete the credit and add the undo coin. - credit = Credit.fromTX(tx, index, height); + const credit = Credit.fromTX(tx, index, height); credit.own = own; this.spendCredit(credit, stx.tx, spent.index); @@ -609,7 +608,7 @@ TXDB.prototype.getBlock = async function getBlock(height) { TXDB.prototype.addBlock = async function addBlock(hash, meta) { const key = layout.b(meta.height); let data = await this.get(key); - let block, size; + let block; if (!data) { block = BlockRecord.fromMeta(meta); @@ -619,7 +618,7 @@ TXDB.prototype.addBlock = async function addBlock(hash, meta) { block = Buffer.allocUnsafe(data.length + 32); data.copy(block, 0); - size = block.readUInt32LE(40, true); + const size = block.readUInt32LE(40, true); block.writeUInt32LE(size + 1, 40, true); hash.copy(block, data.length); @@ -636,12 +635,11 @@ TXDB.prototype.addBlock = async function addBlock(hash, meta) { TXDB.prototype.removeBlock = async function removeBlock(hash, height) { const key = layout.b(height); const data = await this.get(key); - let block, size; if (!data) return; - size = data.readUInt32LE(40, true); + const size = data.readUInt32LE(40, true); assert(size > 0); assert(data.slice(-32).equals(hash)); @@ -651,7 +649,7 @@ TXDB.prototype.removeBlock = async function removeBlock(hash, height) { return; } - block = data.slice(0, -32); + const block = data.slice(0, -32); block.writeUInt32LE(size - 1, 40, true); this.put(key, block); @@ -709,10 +707,10 @@ TXDB.prototype.removeBlockSlow = async function removeBlockSlow(hash, height) { */ TXDB.prototype.add = async function add(tx, block) { - let result; - this.start(); + let result; + try { result = await this._add(tx, block); } catch (e) { @@ -735,7 +733,6 @@ TXDB.prototype.add = async function add(tx, block) { TXDB.prototype._add = async function add(tx, block) { const hash = tx.hash('hex'); const existing = await this.getTX(hash); - let wtx; assert(!tx.mutable, 'Cannot add mutable TX to wallet.'); @@ -753,7 +750,7 @@ TXDB.prototype._add = async function add(tx, block) { return await this._confirm(existing, block); } - wtx = TXRecord.fromTX(tx, block); + const wtx = TXRecord.fromTX(tx, block); if (!block) { // We ignore any unconfirmed txs @@ -805,7 +802,6 @@ TXDB.prototype.insert = async function insert(wtx, block) { const input = tx.inputs[i]; const prevout = input.prevout; const credit = await this.getCredit(prevout.hash, prevout.index); - let coin, path; if (!credit) { // Maintain an stxo list for every @@ -823,7 +819,7 @@ TXDB.prototype.insert = async function insert(wtx, block) { continue; } - coin = credit.coin; + const coin = credit.coin; // Do some verification. if (!block) { @@ -833,7 +829,7 @@ TXDB.prototype.insert = async function insert(wtx, block) { } } - path = await this.getPath(coin); + const path = await this.getPath(coin); assert(path); // Build the tx details object @@ -882,7 +878,6 @@ TXDB.prototype.insert = async function insert(wtx, block) { for (let i = 0; i < tx.outputs.length; i++) { const output = tx.outputs[i]; const path = await this.getPath(output); - let credit; if (!path) continue; @@ -897,7 +892,7 @@ TXDB.prototype.insert = async function insert(wtx, block) { continue; } - credit = Credit.fromTX(tx, i, height); + const credit = Credit.fromTX(tx, i, height); credit.own = own; this.pending.coin++; @@ -979,7 +974,6 @@ TXDB.prototype.insert = async function insert(wtx, block) { TXDB.prototype.confirm = async function confirm(hash, block) { const wtx = await this.getTX(hash); - let details; if (!wtx) return; @@ -991,6 +985,8 @@ TXDB.prototype.confirm = async function confirm(hash, block) { this.start(); + let details; + try { details = await this._confirm(wtx, block); } catch (e) { @@ -1030,7 +1026,6 @@ TXDB.prototype._confirm = async function confirm(wtx, block) { const input = tx.inputs[i]; const prevout = input.prevout; let credit = credits[i]; - let coin, path; // There may be new credits available // that we haven't seen yet. @@ -1051,11 +1046,11 @@ TXDB.prototype._confirm = async function confirm(wtx, block) { this.pending.unconfirmed -= credit.coin.value; } - coin = credit.coin; + const coin = credit.coin; assert(coin.height !== -1); - path = await this.getPath(coin); + const path = await this.getPath(coin); assert(path); details.setInput(i, path, coin); @@ -1074,7 +1069,6 @@ TXDB.prototype._confirm = async function confirm(wtx, block) { for (let i = 0; i < tx.outputs.length; i++) { const output = tx.outputs[i]; const path = await this.getPath(output); - let credit, coin; if (!path) continue; @@ -1082,7 +1076,7 @@ TXDB.prototype._confirm = async function confirm(wtx, block) { details.setOutput(i, path); accounts.add(path.account); - credit = await this.getCredit(hash, i); + const credit = await this.getCredit(hash, i); assert(credit); // Credits spent in the mempool add an @@ -1094,7 +1088,7 @@ TXDB.prototype._confirm = async function confirm(wtx, block) { // Update coin height and confirmed // balance. Save once again. - coin = credit.coin; + const coin = credit.coin; coin.height = height; this.pending.confirmed += output.value; @@ -1173,7 +1167,6 @@ TXDB.prototype.erase = async function erase(wtx, block) { for (let i = 0; i < tx.inputs.length; i++) { const credit = credits[i]; - let coin, path; if (!credit) { // This input never had an undo @@ -1183,8 +1176,8 @@ TXDB.prototype.erase = async function erase(wtx, block) { continue; } - coin = credit.coin; - path = await this.getPath(coin); + const coin = credit.coin; + const path = await this.getPath(coin); assert(path); details.setInput(i, path, coin); @@ -1209,7 +1202,6 @@ TXDB.prototype.erase = async function erase(wtx, block) { for (let i = 0; i < tx.outputs.length; i++) { const output = tx.outputs[i]; const path = await this.getPath(output); - let credit; if (!path) continue; @@ -1217,7 +1209,7 @@ TXDB.prototype.erase = async function erase(wtx, block) { details.setOutput(i, path); accounts.add(path.account); - credit = Credit.fromTX(tx, i, height); + const credit = Credit.fromTX(tx, i, height); this.pending.coin--; this.pending.unconfirmed -= output.value; @@ -1281,17 +1273,15 @@ TXDB.prototype.erase = async function erase(wtx, block) { TXDB.prototype.removeRecursive = async function removeRecursive(wtx) { const tx = wtx.tx; const hash = wtx.hash; - let details; for (let i = 0; i < tx.outputs.length; i++) { const spent = await this.getSpent(hash, i); - let stx; if (!spent) continue; // Remove all of the spender's spenders first. - stx = await this.getTX(spent.hash); + const stx = await this.getTX(spent.hash); assert(stx); @@ -1301,7 +1291,7 @@ TXDB.prototype.removeRecursive = async function removeRecursive(wtx) { this.start(); // Remove the spender. - details = await this.erase(wtx, wtx.getBlock()); + const details = await this.erase(wtx, wtx.getBlock()); assert(details); @@ -1317,10 +1307,10 @@ TXDB.prototype.removeRecursive = async function removeRecursive(wtx) { */ TXDB.prototype.unconfirm = async function unconfirm(hash) { - let details; - this.start(); + let details; + try { details = await this._unconfirm(hash); } catch (e) { @@ -1377,16 +1367,15 @@ TXDB.prototype.disconnect = async function disconnect(wtx, block) { for (let i = 0; i < tx.inputs.length; i++) { const credit = credits[i]; - let path, coin; if (!credit) continue; - coin = credit.coin; + const coin = credit.coin; assert(coin.height !== -1); - path = await this.getPath(coin); + const path = await this.getPath(coin); assert(path); details.setInput(i, path, coin); @@ -1406,12 +1395,11 @@ TXDB.prototype.disconnect = async function disconnect(wtx, block) { for (let i = 0; i < tx.outputs.length; i++) { const output = tx.outputs[i]; const path = await this.getPath(output); - let credit, coin; if (!path) continue; - credit = await this.getCredit(hash, i); + const credit = await this.getCredit(hash, i); // Potentially update undo coin height. if (!credit) { @@ -1427,7 +1415,7 @@ TXDB.prototype.disconnect = async function disconnect(wtx, block) { // Update coin height and confirmed // balance. Save once again. - coin = credit.coin; + const coin = credit.coin; coin.height = -1; this.pending.confirmed -= output.value; @@ -1475,13 +1463,12 @@ TXDB.prototype.disconnect = async function disconnect(wtx, block) { TXDB.prototype.removeConflict = async function removeConflict(wtx) { const tx = wtx.tx; - let details; this.logger.warning('Handling conflicting tx: %s.', tx.txid()); this.drop(); - details = await this.removeRecursive(wtx); + const details = await this.removeRecursive(wtx); this.start(); @@ -1512,10 +1499,9 @@ TXDB.prototype.removeConflicts = async function removeConflicts(tx, conf) { for (let i = 0; i < tx.inputs.length; i++) { const input = tx.inputs[i]; const prevout = input.prevout; - let spent, spender, block; // Is it already spent? - spent = await this.getSpent(prevout.hash, prevout.index); + const spent = await this.getSpent(prevout.hash, prevout.index); if (!spent) continue; @@ -1524,9 +1510,10 @@ TXDB.prototype.removeConflicts = async function removeConflicts(tx, conf) { if (spent.hash === hash) continue; - spender = await this.getTX(spent.hash); + const spender = await this.getTX(spent.hash); assert(spender); - block = spender.getBlock(); + + const block = spender.getBlock(); if (conf && block) return false; @@ -1796,8 +1783,6 @@ TXDB.prototype.getAccountHeightRangeHashes = function getAccountHeightRangeHashe */ TXDB.prototype.getHeightRangeHashes = function getHeightRangeHashes(account, options) { - let start, end; - if (account && typeof account === 'object') { options = account; account = null; @@ -1806,8 +1791,8 @@ TXDB.prototype.getHeightRangeHashes = function getHeightRangeHashes(account, opt if (account != null) return this.getAccountHeightRangeHashes(account, options); - start = options.start || 0; - end = options.end || 0xffffffff; + const start = options.start || 0; + const end = options.end || 0xffffffff; return this.keys({ gte: layout.h(start, encoding.NULL_HASH), @@ -1870,8 +1855,6 @@ TXDB.prototype.getAccountRangeHashes = function getAccountRangeHashes(account, o */ TXDB.prototype.getRangeHashes = function getRangeHashes(account, options) { - let start, end; - if (account && typeof account === 'object') { options = account; account = null; @@ -1880,8 +1863,8 @@ TXDB.prototype.getRangeHashes = function getRangeHashes(account, options) { if (account != null) return this.getAccountRangeHashes(account, options); - start = options.start || 0; - end = options.end || 0xffffffff; + const start = options.start || 0; + const end = options.end || 0xffffffff; return this.keys({ gte: layout.m(start, encoding.NULL_HASH), @@ -1908,14 +1891,13 @@ TXDB.prototype.getRangeHashes = function getRangeHashes(account, options) { TXDB.prototype.getRange = async function getRange(account, options) { const txs = []; - let hashes; if (account && typeof account === 'object') { options = account; account = null; } - hashes = await this.getRangeHashes(account, options); + const hashes = await this.getRangeHashes(account, options); for (const hash of hashes) { const tx = await this.getTX(hash); @@ -2053,7 +2035,6 @@ TXDB.prototype.getAccountCredits = async function getAccountCredits(account) { TXDB.prototype.getSpentCredits = async function getSpentCredits(tx) { const credits = []; - let hash; for (let i = 0; i < tx.inputs.length; i++) credits.push(null); @@ -2061,7 +2042,7 @@ TXDB.prototype.getSpentCredits = async function getSpentCredits(tx) { if (tx.isCoinbase()) return credits; - hash = tx.hash('hex'); + const hash = tx.hash('hex'); await this.range({ gte: layout.d(hash, 0x00000000), @@ -2128,12 +2109,11 @@ TXDB.prototype.getAccountCoins = async function getAccountCoins(account) { TXDB.prototype.getSpentCoins = async function getSpentCoins(tx) { const coins = []; - let credits; if (tx.isCoinbase()) return coins; - credits = await this.getSpentCredits(tx); + const credits = await this.getSpentCredits(tx); for (const credit of credits) { if (!credit) { @@ -2180,12 +2160,11 @@ TXDB.prototype.getCoinView = async function getCoinView(tx) { TXDB.prototype.getSpentView = async function getSpentView(tx) { const view = new CoinView(); - let coins; if (tx.isCoinbase()) return view; - coins = await this.getSpentCoins(tx); + const coins = await this.getSpentCoins(tx); for (const coin of coins) { if (!coin) @@ -2334,10 +2313,9 @@ TXDB.prototype.getCredit = async function getCredit(hash, index) { const state = this.state; const key = Outpoint.toKey(hash, index); let data = this.coinCache.get(key); - let credit; if (data) { - credit = Credit.fromRaw(data); + const credit = Credit.fromRaw(data); credit.coin.hash = hash; credit.coin.index = index; return credit; @@ -2348,7 +2326,7 @@ TXDB.prototype.getCredit = async function getCredit(hash, index) { if (!data) return; - credit = Credit.fromRaw(data); + const credit = Credit.fromRaw(data); credit.coin.hash = hash; credit.coin.index = index; @@ -2367,12 +2345,11 @@ TXDB.prototype.getCredit = async function getCredit(hash, index) { TXDB.prototype.getSpentCoin = async function getSpentCoin(spent, prevout) { const data = await this.get(layout.d(spent.hash, spent.index)); - let coin; if (!data) return; - coin = Coin.fromRaw(data); + const coin = Coin.fromRaw(data); coin.hash = prevout.hash; coin.index = prevout.index; @@ -2400,12 +2377,11 @@ TXDB.prototype.hasSpentCoin = function hasSpentCoin(spent) { TXDB.prototype.updateSpentCoin = async function updateSpentCoin(tx, index, height) { const prevout = Outpoint.fromTX(tx, index); const spent = await this.getSpent(prevout.hash, prevout.index); - let coin; if (!spent) return; - coin = await this.getSpentCoin(spent, prevout); + const coin = await this.getSpentCoin(spent, prevout); if (!coin) return; @@ -2501,11 +2477,10 @@ TXDB.prototype.getAccountBalance = async function getAccountBalance(account) { TXDB.prototype.zap = async function zap(account, age) { const hashes = []; const now = util.now(); - let txs; assert(util.isUInt32(age)); - txs = await this.getRange(account, { + const txs = await this.getRange(account, { start: 0, end: now - age }); @@ -2929,12 +2904,10 @@ Details.prototype.setOutput = function setOutput(i, path) { */ Details.prototype.getDepth = function getDepth() { - let depth; - if (this.height === -1) return 0; - depth = this.chainHeight - this.height; + const depth = this.chainHeight - this.height; if (depth < 0) return 0; @@ -3101,8 +3074,6 @@ BlockRecord.prototype.add = function add(hash) { */ BlockRecord.prototype.remove = function remove(hash) { - let index; - if (!this.index.has(hash)) return false; @@ -3114,7 +3085,7 @@ BlockRecord.prototype.remove = function remove(hash) { return true; } - index = this.hashes.indexOf(hash); + const index = this.hashes.indexOf(hash); assert(index !== -1); @@ -3131,13 +3102,12 @@ BlockRecord.prototype.remove = function remove(hash) { BlockRecord.prototype.fromRaw = function fromRaw(data) { const br = new BufferReader(data); - let count; this.hash = br.readHash('hex'); this.height = br.readU32(); this.time = br.readU32(); - count = br.readU32(); + const count = br.readU32(); for (let i = 0; i < count; i++) { const hash = br.readHash('hex'); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 43af2746..a64856f9 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -192,7 +192,6 @@ Wallet.fromOptions = function fromOptions(db, options) { Wallet.prototype.init = async function init(options) { const passphrase = options.passphrase; - let account; assert(!this.initialized); this.initialized = true; @@ -200,7 +199,7 @@ Wallet.prototype.init = async function init(options) { if (passphrase) await this.master.encrypt(passphrase); - account = await this._createAccount(options, passphrase); + const account = await this._createAccount(options, passphrase); assert(account); this.account = account; @@ -216,11 +215,9 @@ Wallet.prototype.init = async function init(options) { */ Wallet.prototype.open = async function open() { - let account; - assert(this.initialized); - account = await this.getAccount(0); + const account = await this.getAccount(0); if (!account) throw new Error('Default account not found.'); @@ -278,8 +275,6 @@ Wallet.prototype.addSharedKey = async function addSharedKey(acct, key) { */ Wallet.prototype._addSharedKey = async function addSharedKey(acct, key) { - let account, result; - if (!key) { key = acct; acct = null; @@ -288,13 +283,15 @@ Wallet.prototype._addSharedKey = async function addSharedKey(acct, key) { if (acct == null) acct = 0; - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); this.start(); + let result; + try { result = await account.addSharedKey(key); } catch (e) { @@ -332,8 +329,6 @@ Wallet.prototype.removeSharedKey = async function removeSharedKey(acct, key) { */ Wallet.prototype._removeSharedKey = async function removeSharedKey(acct, key) { - let account, result; - if (!key) { key = acct; acct = null; @@ -342,13 +337,15 @@ Wallet.prototype._removeSharedKey = async function removeSharedKey(acct, key) { if (acct == null) acct = 0; - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); this.start(); + let result; + try { result = await account.removeSharedKey(key); } catch (e) { @@ -541,12 +538,10 @@ Wallet.prototype.renameAccount = async function renameAccount(acct, name) { */ Wallet.prototype._renameAccount = async function _renameAccount(acct, name) { - let account, old, paths; - if (!common.isName(name)) throw new Error('Bad account name.'); - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); @@ -557,7 +552,7 @@ Wallet.prototype._renameAccount = async function _renameAccount(acct, name) { if (await this.hasAccount(name)) throw new Error('Account name not available.'); - old = account.name; + const old = account.name; this.start(); @@ -567,7 +562,7 @@ Wallet.prototype._renameAccount = async function _renameAccount(acct, name) { this.indexCache.remove(old); - paths = this.pathCache.values(); + const paths = this.pathCache.values(); for (const path of paths) { if (path.account !== account.accountIndex) @@ -612,17 +607,15 @@ Wallet.prototype.unlock = function unlock(passphrase, timeout) { */ Wallet.prototype.getID = function getID() { - let bw, key, hash; - assert(this.master.key, 'Cannot derive id.'); - key = this.master.key.derive(44); + const key = this.master.key.derive(44); - bw = new StaticWriter(37); + let bw = new StaticWriter(37); bw.writeBytes(key.publicKey); bw.writeU32(this.network.magic); - hash = digest.hash160(bw.render()); + const hash = digest.hash160(bw.render()); bw = new StaticWriter(27); bw.writeU8(0x03); @@ -644,13 +637,11 @@ Wallet.prototype.getID = function getID() { */ Wallet.prototype.getToken = function getToken(nonce) { - let bw, key; - assert(this.master.key, 'Cannot derive token.'); - key = this.master.key.derive(44, true); + const key = this.master.key.derive(44, true); - bw = new StaticWriter(36); + const bw = new StaticWriter(36); bw.writeBytes(key.privateKey); bw.writeU32(nonce); @@ -680,18 +671,17 @@ Wallet.prototype.createAccount = async function createAccount(options, passphras Wallet.prototype._createAccount = async function createAccount(options, passphrase) { let name = options.name; - let key, account, exists; if (!name) name = this.accountDepth + ''; - exists = await this.hasAccount(name); - - if (exists) + if (await this.hasAccount(name)) throw new Error('Account already exists.'); await this.unlock(passphrase); + let key; + if (this.watchOnly && options.accountKey) { key = options.accountKey; @@ -725,6 +715,8 @@ Wallet.prototype._createAccount = async function createAccount(options, passphra this.start(); + let account; + try { account = Account.fromOptions(this.db, options); account.wallet = this; @@ -802,19 +794,17 @@ Wallet.prototype.getAccountHashes = async function getAccountHashes(acct) { */ Wallet.prototype.getAccount = async function getAccount(acct) { - let index, unlock; - if (this.account) { if (acct === 0 || acct === 'default') return this.account; } - index = await this.getAccountIndex(acct); + const index = await this.getAccountIndex(acct); if (index === -1) return; - unlock = await this.readLock.lock(index); + const unlock = await this.readLock.lock(index); try { return await this._getAccount(index); @@ -860,15 +850,13 @@ Wallet.prototype._getAccount = async function getAccount(index) { */ Wallet.prototype.getAccountIndex = async function getAccountIndex(name) { - let index; - if (name == null) return -1; if (typeof name === 'number') return name; - index = this.indexCache.get(name); + let index = this.indexCache.get(name); if (index != null) return index; @@ -891,12 +879,10 @@ Wallet.prototype.getAccountIndex = async function getAccountIndex(name) { */ Wallet.prototype.getAccountName = async function getAccountName(index) { - let account; - if (typeof index === 'string') return index; - account = this.accountCache.get(index); + const account = this.accountCache.get(index); if (account) return account.name; @@ -977,8 +963,6 @@ Wallet.prototype.createKey = async function createKey(acct, branch) { */ Wallet.prototype._createKey = async function createKey(acct, branch) { - let account, result; - if (branch == null) { branch = acct; acct = null; @@ -987,13 +971,15 @@ Wallet.prototype._createKey = async function createKey(acct, branch) { if (acct == null) acct = 0; - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); this.start(); + let result; + try { result = await account.createKey(branch); } catch (e) { @@ -1131,13 +1117,11 @@ Wallet.prototype.hasPath = async function hasPath(address) { */ Wallet.prototype.getPaths = async function getPaths(acct) { - let paths, result; - if (acct != null) return await this.getAccountPaths(acct); - paths = await this.db.getWalletPaths(this.wid); - result = []; + const paths = await this.db.getWalletPaths(this.wid); + const result = []; for (const path of paths) { path.id = this.id; @@ -1211,8 +1195,6 @@ Wallet.prototype.importKey = async function importKey(acct, ring, passphrase) { */ Wallet.prototype._importKey = async function importKey(acct, ring, passphrase) { - let account, exists, path; - if (acct && typeof acct === 'object') { passphrase = ring; ring = acct; @@ -1233,12 +1215,12 @@ Wallet.prototype._importKey = async function importKey(acct, ring, passphrase) { throw new Error('Cannot import privkey into watch-only wallet.'); } - exists = await this.getPath(ring.getHash('hex')); + const hash = ring.getHash('hex'); - if (exists) + if (await this.getPath(hash)) throw new Error('Key already exists.'); - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); @@ -1249,7 +1231,8 @@ Wallet.prototype._importKey = async function importKey(acct, ring, passphrase) { await this.unlock(passphrase); ring = WalletKey.fromRing(account, ring); - path = ring.toPath(); + + const path = ring.toPath(); if (this.master.encrypted) { path.data = this.master.encipher(path.data, path.hash); @@ -1297,8 +1280,6 @@ Wallet.prototype.importAddress = async function importAddress(acct, address) { */ Wallet.prototype._importAddress = async function importAddress(acct, address) { - let account, exists, path; - if (!address) { address = acct; acct = null; @@ -1313,12 +1294,10 @@ Wallet.prototype._importAddress = async function importAddress(acct, address) { if (!this.watchOnly) throw new Error('Cannot import address into non watch-only wallet.'); - exists = await this.getPath(address); - - if (exists) + if (await this.getPath(address)) throw new Error('Address already exists.'); - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); @@ -1326,7 +1305,7 @@ Wallet.prototype._importAddress = async function importAddress(acct, address) { if (account.type !== Account.types.PUBKEYHASH) throw new Error('Cannot import into non-pkh account.'); - path = Path.fromAddress(account, address); + const path = Path.fromAddress(account, address); this.start(); @@ -1381,8 +1360,6 @@ Wallet.prototype.fund = async function fund(mtx, options, force) { */ Wallet.prototype._fund = async function fund(mtx, options) { - let rate, account, coins; - if (!options) options = {}; @@ -1392,6 +1369,8 @@ Wallet.prototype._fund = async function fund(mtx, options) { if (this.watchOnly) throw new Error('Cannot fund from watch-only wallet.'); + let account; + if (options.account != null) { account = await this.getAccount(options.account); if (!account) @@ -1403,11 +1382,13 @@ Wallet.prototype._fund = async function fund(mtx, options) { if (!account.initialized) throw new Error('Account is not initialized.'); - rate = options.rate; + let rate = options.rate; if (rate == null) rate = await this.db.estimateFee(options.blocks); + let coins; + if (options.smart) { coins = await this.getSmartCoins(options.account); } else { @@ -1456,17 +1437,17 @@ Wallet.prototype.getAccountByAddress = async function getAccountByAddress(addres Wallet.prototype.estimateSize = async function estimateSize(prev) { const scale = consensus.WITNESS_SCALE_FACTOR; const address = prev.getAddress(); - let size = 0; - let account; if (!address) return -1; - account = await this.getAccountByAddress(address); + const account = await this.getAccountByAddress(address); if (!account) return -1; + let size = 0; + if (prev.isScripthash()) { // Nested bullshit. if (account.witness) { @@ -1537,15 +1518,14 @@ Wallet.prototype.estimateSize = async function estimateSize(prev) { Wallet.prototype.createTX = async function createTX(options, force) { const outputs = options.outputs; const mtx = new MTX(); - let addr, total; assert(Array.isArray(outputs), 'Outputs must be an array.'); assert(outputs.length > 0, 'No outputs available.'); // Add the outputs - for (let output of outputs) { - output = new Output(output); - addr = output.getAddress(); + for (const obj of outputs) { + const output = new Output(obj); + const addr = output.getAddress(); if (output.isDust()) throw new Error('Output is dust.'); @@ -1576,7 +1556,7 @@ Wallet.prototype.createTX = async function createTX(options, force) { assert(mtx.isSane(), 'TX failed sanity check.'); assert(mtx.verifyInputs(this.db.state.height + 1), 'TX failed context check.'); - total = await this.template(mtx); + const total = await this.template(mtx); if (total === 0) throw new Error('Templating failed.'); @@ -1613,14 +1593,13 @@ Wallet.prototype.send = async function send(options, passphrase) { Wallet.prototype._send = async function send(options, passphrase) { const mtx = await this.createTX(options, true); - let tx; await this.sign(mtx, passphrase); if (!mtx.isSigned()) throw new Error('TX could not be fully signed.'); - tx = mtx.toTX(); + const tx = mtx.toTX(); // Policy sanity checks. if (tx.getSigopsCost(mtx.view) > policy.MAX_TX_SIGOPS_COST) @@ -1649,7 +1628,6 @@ Wallet.prototype._send = async function send(options, passphrase) { Wallet.prototype.increaseFee = async function increaseFee(hash, rate, passphrase) { const wtx = await this.getTX(hash); - let tx, mtx, view, oldFee, fee, change; assert(util.isUInt32(rate), 'Rate must be a number.'); @@ -1659,18 +1637,18 @@ Wallet.prototype.increaseFee = async function increaseFee(hash, rate, passphrase if (wtx.height !== -1) throw new Error('Transaction is confirmed.'); - tx = wtx.tx; + const tx = wtx.tx; if (tx.isCoinbase()) throw new Error('Transaction is a coinbase.'); - view = await this.getSpentView(tx); + const view = await this.getSpentView(tx); if (!tx.hasCoins(view)) throw new Error('Not all coins available.'); - oldFee = tx.getFee(view); - fee = tx.getMinFee(null, rate); + const oldFee = tx.getFee(view); + let fee = tx.getMinFee(null, rate); if (fee > MTX.Selector.MAX_FEE) fee = MTX.Selector.MAX_FEE; @@ -1678,7 +1656,7 @@ Wallet.prototype.increaseFee = async function increaseFee(hash, rate, passphrase if (oldFee >= fee) throw new Error('Fee is not increasing.'); - mtx = MTX.fromTX(tx); + const mtx = MTX.fromTX(tx); mtx.view = view; for (const input of mtx.inputs) { @@ -1688,15 +1666,15 @@ Wallet.prototype.increaseFee = async function increaseFee(hash, rate, passphrase input.witness.compile(); } + let change; for (let i = 0; i < mtx.outputs.length; i++) { const output = mtx.outputs[i]; const addr = output.getAddress(); - let path; if (!addr) continue; - path = await this.getPath(addr); + const path = await this.getPath(addr); if (!path) continue; @@ -1731,16 +1709,16 @@ Wallet.prototype.increaseFee = async function increaseFee(hash, rate, passphrase if (!mtx.isSigned()) throw new Error('TX could not be fully signed.'); - tx = mtx.toTX(); + const ntx = mtx.toTX(); this.logger.debug( 'Increasing fee for wallet tx (%s): %s', - this.id, tx.txid()); + this.id, ntx.txid()); - await this.db.addTX(tx); - await this.db.send(tx); + await this.db.addTX(ntx); + await this.db.send(ntx); - return tx; + return ntx; }; /** @@ -1750,7 +1728,7 @@ Wallet.prototype.increaseFee = async function increaseFee(hash, rate, passphrase Wallet.prototype.resend = async function resend() { const wtxs = await this.getPending(); - let txs = []; + const txs = []; if (wtxs.length > 0) this.logger.info('Rebroadcasting %d transactions.', wtxs.length); @@ -1758,9 +1736,9 @@ Wallet.prototype.resend = async function resend() { for (const wtx of wtxs) txs.push(wtx.tx); - txs = common.sortDeps(txs); + const sorted = common.sortDeps(txs); - for (const tx of txs) + for (const tx of sorted) await this.db.send(tx); return txs; @@ -1774,21 +1752,18 @@ Wallet.prototype.resend = async function resend() { */ Wallet.prototype.deriveInputs = async function deriveInputs(mtx) { - const rings = []; - let paths; - assert(mtx.mutable); - paths = await this.getInputPaths(mtx); + const paths = await this.getInputPaths(mtx); + const rings = []; for (const path of paths) { const account = await this.getAccount(path.account); - let ring; if (!account) continue; - ring = account.derivePath(path, this.master); + const ring = account.derivePath(path, this.master); if (ring) rings.push(ring); @@ -1806,12 +1781,11 @@ Wallet.prototype.deriveInputs = async function deriveInputs(mtx) { Wallet.prototype.getKey = async function getKey(address) { const hash = Address.getHash(address, 'hex'); const path = await this.getPath(hash); - let account; if (!path) return; - account = await this.getAccount(path.account); + const account = await this.getAccount(path.account); if (!account) return; @@ -1830,19 +1804,18 @@ Wallet.prototype.getKey = async function getKey(address) { Wallet.prototype.getPrivateKey = async function getPrivateKey(address, passphrase) { const hash = Address.getHash(address, 'hex'); const path = await this.getPath(hash); - let account, key; if (!path) return; - account = await this.getAccount(path.account); + const account = await this.getAccount(path.account); if (!account) return; await this.unlock(passphrase); - key = account.derivePath(path, this.master); + const key = account.derivePath(path, this.master); if (!key.privateKey) return; @@ -1858,14 +1831,13 @@ Wallet.prototype.getPrivateKey = async function getPrivateKey(address, passphras Wallet.prototype.getInputPaths = async function getInputPaths(mtx) { const paths = []; - let hashes; assert(mtx.mutable); if (!mtx.hasCoins()) throw new Error('Not all coins available.'); - hashes = mtx.getInputHashes('hex'); + const hashes = mtx.getInputHashes('hex'); for (const hash of hashes) { const path = await this.getPath(hash); @@ -1920,8 +1892,6 @@ Wallet.prototype.setLookahead = async function setLookahead(acct, lookahead) { */ Wallet.prototype._setLookahead = async function setLookahead(acct, lookahead) { - let account; - if (lookahead == null) { lookahead = acct; acct = null; @@ -1930,7 +1900,7 @@ Wallet.prototype._setLookahead = async function setLookahead(acct, lookahead) { if (acct == null) acct = 0; - account = await this.getAccount(acct); + const account = await this.getAccount(acct); if (!account) throw new Error('Account not found.'); @@ -1981,7 +1951,6 @@ Wallet.prototype.syncOutputDepth = async function syncOutputDepth(details) { let receive = -1; let change = -1; let nested = -1; - let account, ring; for (const path of paths) { switch (path.branch) { @@ -2004,10 +1973,10 @@ Wallet.prototype.syncOutputDepth = async function syncOutputDepth(details) { change += 2; nested += 2; - account = await this.getAccount(acct); + const account = await this.getAccount(acct); assert(account); - ring = await account.syncDepth(receive, change, nested); + const ring = await account.syncDepth(receive, change, nested); if (ring) derived.push(ring); @@ -2023,12 +1992,10 @@ Wallet.prototype.syncOutputDepth = async function syncOutputDepth(details) { */ Wallet.prototype.getRedeem = async function getRedeem(hash) { - let ring; - if (typeof hash === 'string') hash = Buffer.from(hash, 'hex'); - ring = await this.getKey(hash.toString('hex')); + const ring = await this.getKey(hash.toString('hex')); if (!ring) return; @@ -2060,14 +2027,12 @@ Wallet.prototype.template = async function template(mtx) { */ Wallet.prototype.sign = async function sign(mtx, passphrase) { - let rings; - if (this.watchOnly) throw new Error('Cannot sign from a watch-only wallet.'); await this.unlock(passphrase); - rings = await this.deriveInputs(mtx); + const rings = await this.deriveInputs(mtx); return await mtx.signAsync(rings, Script.hashType.ALL, this.db.workers); }; @@ -2176,10 +2141,9 @@ Wallet.prototype.add = async function add(tx, block) { */ Wallet.prototype._add = async function add(tx, block) { - let details, derived; - this.txdb.start(); + let details, derived; try { details = await this.txdb._add(tx, block); derived = await this.syncOutputDepth(details); @@ -2423,12 +2387,11 @@ Wallet.prototype.getBalance = async function getBalance(acct) { */ Wallet.prototype.getRange = async function getRange(acct, options) { - let account; if (acct && typeof acct === 'object') { options = acct; acct = null; } - account = await this.ensureIndex(acct); + const account = await this.ensureIndex(acct); return await this.txdb.getRange(account, options); }; @@ -2453,15 +2416,13 @@ Wallet.prototype.getLast = async function getLast(acct, limit) { */ Wallet.prototype.ensureIndex = async function ensureIndex(acct, enforce) { - let index; - if (acct == null) { if (enforce) throw new Error('No account provided.'); return null; } - index = await this.getAccountIndex(acct); + const index = await this.getAccountIndex(acct); if (index === -1) throw new Error('Account not found.'); diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index 456b3a4c..131fa3b7 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -139,8 +139,6 @@ WalletDB.prototype._init = function _init() { */ WalletDB.prototype._open = async function open() { - let wallet; - if (this.options.listen) await this.logger.open(); @@ -160,7 +158,7 @@ WalletDB.prototype._open = async function open() { this.state.height, this.state.startHeight); - wallet = await this.ensure({ + const wallet = await this.ensure({ id: 'primary' }); @@ -308,13 +306,14 @@ WalletDB.prototype.disconnect = async function disconnect() { WalletDB.prototype.init = async function init() { const state = await this.getState(); const startHeight = this.options.startHeight; - let tip; if (state) { this.state = state; return; } + let tip; + if (this.client) { if (startHeight != null) { tip = await this.client.getEntry(startHeight); @@ -342,15 +341,14 @@ WalletDB.prototype.init = async function init() { */ WalletDB.prototype.watch = async function watch() { - let hashes = 0; - let outpoints = 0; - let iter; - - iter = this.db.iterator({ + let iter = this.db.iterator({ gte: layout.p(encoding.NULL_HASH), lte: layout.p(encoding.HIGH_HASH) }); + let hashes = 0; + let outpoints = 0; + for (;;) { const item = await iter.next(); @@ -444,8 +442,6 @@ WalletDB.prototype.sync = async function sync() { */ WalletDB.prototype.scan = async function scan(height) { - let tip; - if (!this.client) return; @@ -460,7 +456,7 @@ WalletDB.prototype.scan = async function scan(height) { 'WalletDB is scanning %d blocks.', this.state.height - height + 1); - tip = await this.getTip(); + const tip = await this.getTip(); try { this.rescanning = true; @@ -518,12 +514,10 @@ WalletDB.prototype.send = async function send(tx) { */ WalletDB.prototype.estimateFee = async function estimateFee(blocks) { - let rate; - if (!this.client) return this.network.feeRate; - rate = await this.client.estimateFee(blocks); + const rate = await this.client.estimateFee(blocks); if (rate < this.network.feeRate) return this.network.feeRate; @@ -597,17 +591,17 @@ WalletDB.prototype.backup = function backup(path) { WalletDB.prototype.wipe = async function wipe() { const batch = this.db.batch(); - let total = 0; - let iter; this.logger.warning('Wiping WalletDB TXDB...'); this.logger.warning('I hope you know what you\'re doing.'); - iter = this.db.iterator({ + const iter = this.db.iterator({ gte: Buffer.from([0x00]), lte: Buffer.from([0xff]) }); + let total = 0; + for (;;) { const item = await iter.next(); @@ -645,8 +639,6 @@ WalletDB.prototype.wipe = async function wipe() { */ WalletDB.prototype.getDepth = async function getDepth() { - let iter, item, depth; - // This may seem like a strange way to do // this, but updating a global state when // creating a new wallet is actually pretty @@ -656,21 +648,21 @@ WalletDB.prototype.getDepth = async function getDepth() { // nonsense of adding a global lock to // walletdb.create by simply seeking to the // highest wallet wid. - iter = this.db.iterator({ + const iter = this.db.iterator({ gte: layout.w(0x00000000), lte: layout.w(0xffffffff), reverse: true, limit: 1 }); - item = await iter.next(); + const item = await iter.next(); if (!item) return 1; await iter.end(); - depth = layout.ww(item.key); + const depth = layout.ww(item.key); return depth + 1; }; @@ -823,20 +815,18 @@ WalletDB.prototype.unregister = function unregister(wallet) { */ WalletDB.prototype.getWalletID = async function getWalletID(id) { - let wid, data; - if (!id) return; if (typeof id === 'number') return id; - wid = this.widCache.get(id); + let wid = this.widCache.get(id); if (wid) return wid; - data = await this.db.get(layout.l(id)); + const data = await this.db.get(layout.l(id)); if (!data) return; @@ -856,12 +846,11 @@ WalletDB.prototype.getWalletID = async function getWalletID(id) { WalletDB.prototype.get = async function get(id) { const wid = await this.getWalletID(id); - let unlock; if (!wid) return; - unlock = await this.readLock.lock(wid); + const unlock = await this.readLock.lock(wid); try { return await this._get(wid); @@ -879,12 +868,11 @@ WalletDB.prototype.get = async function get(id) { WalletDB.prototype._get = async function get(wid) { let wallet = this.wallets.get(wid); - let data; if (wallet) return wallet; - data = await this.db.get(layout.w(wid)); + const data = await this.db.get(layout.w(wid)); if (!data) return; @@ -940,7 +928,6 @@ WalletDB.prototype.rename = async function rename(wallet, id) { WalletDB.prototype._rename = async function _rename(wallet, id) { const old = wallet.id; - let paths, batch; if (!common.isName(id)) throw new Error('WDB: Bad wallet ID.'); @@ -948,7 +935,7 @@ WalletDB.prototype._rename = async function _rename(wallet, id) { if (await this.has(id)) throw new Error('WDB: ID not available.'); - batch = this.start(wallet); + const batch = this.start(wallet); batch.del(layout.l(old)); wallet.id = id; @@ -959,7 +946,7 @@ WalletDB.prototype._rename = async function _rename(wallet, id) { this.widCache.remove(old); - paths = wallet.pathCache.values(); + const paths = wallet.pathCache.values(); for (const path of paths) path.id = id; @@ -1037,12 +1024,11 @@ WalletDB.prototype.create = async function create(options) { WalletDB.prototype._create = async function create(options) { const exists = await this.has(options.id); - let wallet; if (exists) throw new Error('WDB: Wallet already exists.'); - wallet = Wallet.fromOptions(this, options); + const wallet = Wallet.fromOptions(this, options); wallet.wid = this.depth++; await wallet.init(options); @@ -1186,12 +1172,11 @@ WalletDB.prototype.hasAccount = function hasAccount(wid, index) { WalletDB.prototype.getPathMap = async function getPathMap(hash) { let map = this.pathMapCache.get(hash); - let data; if (map) return map; - data = await this.db.get(layout.p(hash)); + const data = await this.db.get(layout.p(hash)); if (!data) return; @@ -1231,11 +1216,10 @@ WalletDB.prototype.savePath = async function savePath(wallet, path) { const wid = wallet.wid; const hash = path.hash; const batch = this.batch(wallet); - let map; await this.addHash(hash); - map = await this.getPathMap(hash); + let map = await this.getPathMap(hash); if (!map) map = new PathMapRecord(hash); @@ -1265,12 +1249,11 @@ WalletDB.prototype.savePath = async function savePath(wallet, path) { WalletDB.prototype.getPath = async function getPath(wid, hash) { const data = await this.db.get(layout.P(wid, hash)); - let path; if (!data) return; - path = Path.fromRaw(data); + const path = Path.fromRaw(data); path.wid = wid; path.hash = hash; @@ -1399,15 +1382,13 @@ WalletDB.prototype.encryptKeys = async function encryptKeys(wallet, key) { const batch = this.batch(wallet); for (let path of paths) { - let iv; - if (!path.data) continue; assert(!path.encrypted); - iv = Buffer.from(path.hash, 'hex'); - iv = iv.slice(0, 16); + const hash = Buffer.from(path.hash, 'hex'); + const iv = hash.slice(0, 16); path = path.clone(); path.data = aes.encipher(path.data, key, iv); @@ -1432,15 +1413,13 @@ WalletDB.prototype.decryptKeys = async function decryptKeys(wallet, key) { const batch = this.batch(wallet); for (let path of paths) { - let iv; - if (!path.data) continue; assert(path.encrypted); - iv = Buffer.from(path.hash, 'hex'); - iv = iv.slice(0, 16); + const hash = Buffer.from(path.hash, 'hex'); + const iv = hash.slice(0, 16); path = path.clone(); path.data = aes.decipher(path.data, key, iv); @@ -1478,10 +1457,8 @@ WalletDB.prototype.resend = async function resend() { WalletDB.prototype.resendPending = async function resendPending(wid) { const layout = layouts.txdb; - let txs = []; - let keys; - keys = await this.db.keys({ + const keys = await this.db.keys({ gte: layout.prefix(wid, layout.p(encoding.NULL_HASH)), lte: layout.prefix(wid, layout.p(encoding.HIGH_HASH)) }); @@ -1494,16 +1471,17 @@ WalletDB.prototype.resendPending = async function resendPending(wid) { keys.length, wid); + const txs = []; + for (const key of keys) { const hash = layout.pp(key); const tkey = layout.prefix(wid, layout.t(hash)); const data = await this.db.get(tkey); - let wtx; if (!data) continue; - wtx = TXRecord.fromRaw(data); + const wtx = TXRecord.fromRaw(data); if (wtx.tx.isCoinbase()) continue; @@ -1511,9 +1489,9 @@ WalletDB.prototype.resendPending = async function resendPending(wid) { txs.push(wtx.tx); } - txs = common.sortDeps(txs); + const sorted = common.sortDeps(txs); - for (const tx of txs) + for (const tx of sorted) await this.send(tx); }; @@ -1530,12 +1508,11 @@ WalletDB.prototype.getWalletsByTX = async function getWalletsByTX(tx) { if (!tx.isCoinbase()) { for (const input of tx.inputs) { const prevout = input.prevout; - let map; if (!this.testFilter(prevout.toRaw())) continue; - map = await this.getOutpointMap(prevout.hash, prevout.index); + const map = await this.getOutpointMap(prevout.hash, prevout.index); if (!map) continue; @@ -1546,12 +1523,10 @@ WalletDB.prototype.getWalletsByTX = async function getWalletsByTX(tx) { } for (const hash of hashes) { - let map; - if (!this.testFilter(hash)) continue; - map = await this.getPathMap(hash); + const map = await this.getPathMap(hash); if (!map) continue; @@ -1589,9 +1564,8 @@ WalletDB.prototype.getState = async function getState() { WalletDB.prototype.resetState = async function resetState(tip, marked) { const batch = this.db.batch(); const state = this.state.clone(); - let iter; - iter = this.db.iterator({ + const iter = this.db.iterator({ gte: layout.h(0), lte: layout.h(0xffffffff), values: false @@ -1774,12 +1748,11 @@ WalletDB.prototype.unwriteOutpointMap = function unwriteOutpointMap(wallet, hash WalletDB.prototype.getBlock = async function getBlock(height) { const data = await this.db.get(layout.h(height)); - let block; if (!data) return; - block = new BlockMeta(); + const block = new BlockMeta(); block.hash = data.toString('hex'); block.height = height; @@ -1808,8 +1781,6 @@ WalletDB.prototype.getTip = async function getTip() { */ WalletDB.prototype.rollback = async function rollback(height) { - let tip, marked; - if (height > this.state.height) throw new Error('WDB: Cannot rollback to the future.'); @@ -1822,7 +1793,8 @@ WalletDB.prototype.rollback = async function rollback(height) { 'Rolling back %d WalletDB blocks to height %d.', this.state.height - height, height); - tip = await this.getBlock(height); + let tip = await this.getBlock(height); + let marked = false; if (tip) { await this.revert(tip.height); @@ -1861,16 +1833,15 @@ WalletDB.prototype.rollback = async function rollback(height) { */ WalletDB.prototype.revert = async function revert(target) { - let total = 0; - let iter; - - iter = this.db.iterator({ + const iter = this.db.iterator({ gte: layout.b(target + 1), lte: layout.b(0xffffffff), reverse: true, values: true }); + let total = 0; + for (;;) { const item = await iter.next(); @@ -1989,7 +1960,6 @@ WalletDB.prototype.removeBlock = async function removeBlock(entry) { WalletDB.prototype._removeBlock = async function removeBlock(entry) { const tip = BlockMeta.fromEntry(entry); - let prev, block, txs; if (tip.height > this.state.height) { this.logger.warning( @@ -2001,20 +1971,20 @@ WalletDB.prototype._removeBlock = async function removeBlock(entry) { if (tip.height !== this.state.height) throw new Error('WDB: Bad disconnection (height mismatch).'); - prev = await this.getBlock(tip.height - 1); + const prev = await this.getBlock(tip.height - 1); if (!prev) throw new Error('WDB: Bad disconnection (no previous block).'); // Get the map of txids->wids. - block = await this.getBlockMap(tip.height); + const block = await this.getBlockMap(tip.height); if (!block) { await this.syncState(prev); return 0; } - txs = block.toArray(); + const txs = block.toArray(); for (let i = txs.length - 1; i >= 0; i--) { const tx = txs[i]; diff --git a/lib/workers/framer.js b/lib/workers/framer.js index 6b3d01d0..914b07a3 100644 --- a/lib/workers/framer.js +++ b/lib/workers/framer.js @@ -23,7 +23,6 @@ function Framer() { Framer.prototype.packet = function _packet(packet) { const size = 10 + packet.getSize(); const bw = new StaticWriter(size); - let data; bw.writeU32(packet.id); bw.writeU8(packet.cmd); @@ -33,7 +32,7 @@ Framer.prototype.packet = function _packet(packet) { bw.writeU8(0x0a); - data = bw.render(); + const data = bw.render(); data.writeUInt32LE(data.length - 10, 5, true); return data; diff --git a/lib/workers/packets.js b/lib/workers/packets.js index cf22ab63..99f29d3c 100644 --- a/lib/workers/packets.js +++ b/lib/workers/packets.js @@ -345,12 +345,11 @@ CheckResultPacket.prototype.toWriter = function toWriter(bw) { CheckResultPacket.fromRaw = function fromRaw(data) { const br = new BufferReader(data, true); const packet = new CheckResultPacket(); - let err; if (br.readU8() === 0) return packet; - err = new ScriptError(''); + const err = new ScriptError(''); err.code = br.readVarString('utf8'); err.message = br.readVarString('utf8'); err.stack = br.readVarString('utf8'); @@ -414,12 +413,11 @@ SignPacket.prototype.toWriter = function toWriter(bw) { SignPacket.fromRaw = function fromRaw(data) { const br = new BufferReader(data, true); const packet = new SignPacket(); - let count; packet.tx = MTX.fromReader(br); packet.tx.view.fromReader(br, packet.tx); - count = br.readVarint(); + const count = br.readVarint(); for (let i = 0; i < count; i++) { const ring = KeyRing.fromReader(br); @@ -500,11 +498,10 @@ SignResultPacket.prototype.inject = function inject(tx) { SignResultPacket.fromRaw = function fromRaw(data) { const br = new BufferReader(data, true); const packet = new SignResultPacket(); - let count; packet.total = br.readVarint(); - count = br.readVarint(); + const count = br.readVarint(); for (let i = 0; i < count; i++) { packet.script.push(Script.fromReader(br)); diff --git a/lib/workers/workerpool.js b/lib/workers/workerpool.js index 9bdddb7d..697f7074 100644 --- a/lib/workers/workerpool.js +++ b/lib/workers/workerpool.js @@ -187,8 +187,6 @@ WorkerPool.prototype.destroy = function destroy() { */ WorkerPool.prototype.execute = function execute(packet, timeout) { - let child; - if (!this.enabled || !Child.hasSupport()) { return new Promise((resolve, reject) => { setImmediate(() => { @@ -207,7 +205,7 @@ WorkerPool.prototype.execute = function execute(packet, timeout) { if (!timeout) timeout = this.timeout; - child = this.alloc(); + const child = this.alloc(); return child.execute(packet, timeout); }; @@ -242,13 +240,12 @@ WorkerPool.prototype.check = async function check(tx, view, flags) { WorkerPool.prototype.sign = async function sign(tx, ring, type) { let rings = ring; - let packet, result; if (!Array.isArray(rings)) rings = [rings]; - packet = new packets.SignPacket(tx, rings, type); - result = await this.execute(packet, -1); + const packet = new packets.SignPacket(tx, rings, type); + const result = await this.execute(packet, -1); result.inject(tx); diff --git a/migrate/chaindb0to1.js b/migrate/chaindb0to1.js index 4d610013..375363c6 100644 --- a/migrate/chaindb0to1.js +++ b/migrate/chaindb0to1.js @@ -27,45 +27,41 @@ function makeKey(data) { } async function checkVersion() { - let data, ver; - console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); if (!data) return; - ver = data.readUInt32LE(0, true); + const ver = data.readUInt32LE(0, true); if (ver !== 0) throw Error(`DB is version ${ver}.`); } async function updateState() { - let data, hash, batch, ver, p; - console.log('Updating chain state.'); - data = await db.get('R'); + const data = await db.get('R'); if (!data || data.length < 32) throw new Error('No chain state.'); - hash = data.slice(0, 32); + const hash = data.slice(0, 32); - p = new BufferWriter(); + let p = new BufferWriter(); p.writeHash(hash); p.writeU64(0); p.writeU64(0); p.writeU64(0); p = p.render(); - batch = db.batch(); + const batch = db.batch(); batch.put('R', p); - ver = Buffer.allocUnsafe(4); + const ver = Buffer.allocUnsafe(4); ver.writeUInt32LE(1, 0, true); batch.put('V', ver); @@ -77,19 +73,18 @@ async function updateState() { async function updateEndian() { const batch = db.batch(); let total = 0; - let iter, item; console.log('Updating endianness.'); console.log('Iterating...'); - iter = db.iterator({ + const iter = db.iterator({ gte: Buffer.from('4800000000', 'hex'), lte: Buffer.from('48ffffffff', 'hex'), values: true }); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; diff --git a/migrate/chaindb1to2.js b/migrate/chaindb1to2.js index 4cb1d48e..2f1e1560 100644 --- a/migrate/chaindb1to2.js +++ b/migrate/chaindb1to2.js @@ -13,14 +13,13 @@ const Coin = require('../lib/primitives/coin'); const Output = require('../lib/primitives/output'); const LDB = require('../lib/db/ldb'); let file = process.argv[2]; -let options = {}; -let db, batch, index; +let batch; assert(typeof file === 'string', 'Please pass in a database path.'); file = file.replace(/\.ldb\/?$/, ''); -db = LDB({ +const db = LDB({ location: file, db: 'leveldb', compression: true, @@ -29,14 +28,14 @@ db = LDB({ bufferKeys: true }); -options = {}; +const options = {}; options.spv = process.argv.indexOf('--spv') !== -1; options.prune = process.argv.indexOf('--prune') !== -1; options.indexTX = process.argv.indexOf('--index-tx') !== -1; options.indexAddress = process.argv.indexOf('--index-address') !== -1; options.network = networks.main; -index = process.argv.indexOf('--network'); +const index = process.argv.indexOf('--network'); if (index !== -1) { options.network = networks[process.argv[index + 1]]; @@ -44,16 +43,14 @@ if (index !== -1) { } async function updateVersion() { - let data, ver; - console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); if (!data) throw new Error('No DB version found!'); - ver = data.readUInt32LE(0, true); + let ver = data.readUInt32LE(0, true); if (ver !== 1) throw Error(`DB is version ${ver}.`); @@ -116,38 +113,37 @@ async function updateDeployments() { async function reserializeCoins() { let total = 0; - let i, iter, item, hash, old, coins, coin, output; - iter = db.iterator({ + const iter = db.iterator({ gte: pair('c', encoding.ZERO_HASH), lte: pair('c', encoding.MAX_HASH), values: true }); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; - hash = item.key.toString('hex', 1, 33); - old = OldCoins.fromRaw(item.value, hash); + const hash = item.key.toString('hex', 1, 33); + const old = OldCoins.fromRaw(item.value, hash); - coins = new Coins(); + const coins = new Coins(); coins.version = old.version; coins.hash = old.hash; coins.height = old.height; coins.coinbase = old.coinbase; - for (i = 0; i < old.outputs.length; i++) { - coin = old.get(i); + for (let i = 0; i < old.outputs.length; i++) { + const coin = old.get(i); if (!coin) { coins.outputs.push(null); continue; } - output = new Output(); + const output = new Output(); output.script = coin.script; output.value = coin.value; @@ -168,22 +164,21 @@ async function reserializeCoins() { async function reserializeUndo() { let total = 0; - let iter, item, br, undo; - iter = db.iterator({ + const iter = db.iterator({ gte: pair('u', encoding.ZERO_HASH), lte: pair('u', encoding.MAX_HASH), values: true }); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; - br = new BufferReader(item.value); - undo = new UndoCoins(); + const br = new BufferReader(item.value); + const undo = new UndoCoins(); while (br.left()) { undo.push(null); @@ -253,12 +248,11 @@ function defaultOptions() { function defaultDeployments() { const bw = new BufferWriter(); - let i, deployment; bw.writeU8(options.network.deploys.length); - for (i = 0; i < options.network.deploys.length; i++) { - deployment = options.network.deploys[i]; + for (let i = 0; i < options.network.deploys.length; i++) { + const deployment = options.network.deploys[i]; bw.writeU8(deployment.bit); bw.writeU32(deployment.startTime); bw.writeU32(deployment.timeout); diff --git a/migrate/chaindb2to3.js b/migrate/chaindb2to3.js index dac3e508..e9405923 100644 --- a/migrate/chaindb2to3.js +++ b/migrate/chaindb2to3.js @@ -70,7 +70,6 @@ function writeJournal(batch, state, hash) { async function readJournal() { const data = await db.get(JOURNAL_KEY); - let state, hash; if (!data) return [STATE_VERSION, encoding.NULL_HASH]; @@ -81,8 +80,8 @@ async function readJournal() { if (data.length !== 34) throw new Error('Bad migration length.'); - state = data.readUInt8(1, true); - hash = data.toString('hex', 2, 34); + const state = data.readUInt8(1, true); + const hash = data.toString('hex', 2, 34); console.log('Reading journal.'); console.log('Recovering from state %d.', state); @@ -92,16 +91,15 @@ async function readJournal() { async function updateVersion() { const batch = db.batch(); - let data, version; console.log('Checking version.'); - data = await db.get('V'); + let data = await db.get('V'); if (!data) throw new Error('No DB version found!'); - version = data.readUInt32LE(0, true); + const version = data.readUInt32LE(0, true); if (version !== 2) throw Error(`DB is version ${version}.`); @@ -136,8 +134,6 @@ async function reserializeUndo(hash) { console.log('Reserializing undo coins from tip %s.', util.revHex(tip.hash)); while (tip.height !== 0) { - let undoData, blockData, block, old, undo; - if (shouldPrune) { if (tip.height < height - 288) { batch.del(pair('u', tip.hash)); @@ -156,8 +152,8 @@ async function reserializeUndo(hash) { } } - undoData = await db.get(pair('u', tip.hash)); - blockData = await db.get(pair('b', tip.hash)); + const undoData = await db.get(pair('u', tip.hash)); + const blockData = await db.get(pair('b', tip.hash)); if (!undoData) { tip = await getEntry(tip.prevBlock); @@ -171,9 +167,9 @@ async function reserializeUndo(hash) { break; } - block = Block.fromRaw(blockData); - old = OldUndoCoins.fromRaw(undoData); - undo = new UndoCoins(); + const block = Block.fromRaw(blockData); + const old = OldUndoCoins.fromRaw(undoData); + const undo = new UndoCoins(); for (let i = block.txs.length - 1; i >= 1; i--) { const tx = block.txs[i]; @@ -181,13 +177,12 @@ async function reserializeUndo(hash) { const {prevout} = tx.inputs[j]; const coin = old.items.pop(); const output = coin.toOutput(); - let version, height, write, item; assert(coin); - [version, height, write] = await getMeta(coin, prevout); + const [version, height, write] = await getMeta(coin, prevout); - item = new CoinEntry(); + const item = new CoinEntry(); item.version = version; item.height = height; item.coinbase = coin.coinbase; @@ -294,7 +289,6 @@ async function reserializeCoins(hash) { while (start) { const item = await iter.next(); let update = false; - let hash, old; if (!item) break; @@ -302,17 +296,16 @@ async function reserializeCoins(hash) { if (item.key.length !== 33) continue; - hash = item.key.toString('hex', 1, 33); - old = OldCoins.fromRaw(item.value, hash); + const hash = item.key.toString('hex', 1, 33); + const old = OldCoins.fromRaw(item.value, hash); for (let i = 0; i < old.outputs.length; i++) { const coin = old.getCoin(i); - let item; if (!coin) continue; - item = new CoinEntry(); + const item = new CoinEntry(); item.version = coin.version; item.height = coin.height; item.coinbase = coin.coinbase; @@ -369,13 +362,12 @@ async function reserializeEntries(hash) { while (start) { const item = await iter.next(); - let entry, main; if (!item) break; - entry = entryFromRaw(item.value); - main = await isMainChain(entry, tip); + const entry = entryFromRaw(item.value); + const main = await isMainChain(entry, tip); batch.put(item.key, entryToRaw(entry, main)); @@ -409,11 +401,10 @@ async function finalize() { if (shouldPrune) { const data = await db.get('O'); - let flags; assert(data); - flags = data.readUInt32LE(4, true); + let flags = data.readUInt32LE(4, true); flags |= 1 << 2; data.writeUInt32LE(flags, 4, true); @@ -433,8 +424,6 @@ async function finalize() { } async function getMeta(coin, prevout) { - let item, data, br, version, height; - // Case 1: Undo coin is the last spend. if (coin.height !== -1) { assert(coin.version !== -1); @@ -444,7 +433,7 @@ async function getMeta(coin, prevout) { // Case 2: We have previously cached // this coin's metadata, but it's not // written yet. - item = metaCache.get(prevout.hash); + const item = metaCache.get(prevout.hash); if (item) { const [version, height] = item; @@ -454,7 +443,7 @@ async function getMeta(coin, prevout) { // Case 3: We have previously cached // this coin's metadata, and it is // written. - data = await db.get(pair(0x01, prevout.hash)); + let data = await db.get(pair(0x01, prevout.hash)); if (data) { const version = data.readUInt32LE(0, true); @@ -467,9 +456,9 @@ async function getMeta(coin, prevout) { data = await db.get(pair('c', prevout.hash)); assert(data); - br = new BufferReader(data); - version = br.readVarint(); - height = br.readU32(); + const br = new BufferReader(data); + const version = br.readVarint(); + const height = br.readU32(); return [version, height, true]; } @@ -575,8 +564,6 @@ function bpair(prefix, hash, index) { } (async () => { - let state, hash; - await db.open(); console.log('Opened %s.', file); @@ -592,7 +579,7 @@ function bpair(prefix, hash, index) { await co.timeout(3000); - [state, hash] = await readJournal(); + let [state, hash] = await readJournal(); if (state === STATE_VERSION) [state, hash] = await updateVersion(); diff --git a/migrate/coins-old.js b/migrate/coins-old.js index d58e47d6..a5b436c9 100644 --- a/migrate/coins-old.js +++ b/migrate/coins-old.js @@ -131,12 +131,10 @@ Coins.prototype.has = function has(index) { */ Coins.prototype.get = function get(index) { - let coin; - if (index >= this.outputs.length) return; - coin = this.outputs[index]; + const coin = this.outputs[index]; if (!coin) return; @@ -168,10 +166,9 @@ Coins.prototype.spend = function spend(index) { Coins.prototype.size = function size() { let index = -1; - let i, output; - for (i = this.outputs.length - 1; i >= 0; i--) { - output = this.outputs[i]; + for (let i = this.outputs.length - 1; i >= 0; i--) { + const output = this.outputs[i]; if (output) { index = i; break; @@ -224,7 +221,6 @@ Coins.prototype.toRaw = function toRaw() { const bw = new BufferWriter(); const length = this.size(); const len = Math.ceil(length / 8); - let i, output, bits, start, bit, oct, data; // Return nothing if we're fully spent. if (length === 0) @@ -236,7 +232,7 @@ Coins.prototype.toRaw = function toRaw() { // Create the `bits` value: // (height | coinbase-flag). - bits = this.height << 1; + let bits = this.height << 1; // Append the coinbase bit. if (this.coinbase) @@ -259,12 +255,12 @@ Coins.prototype.toRaw = function toRaw() { // allocating a buffer. We mark the spents // after rendering the final buffer. bw.writeVarint(len); - start = bw.written; + const start = bw.written; bw.fill(0, len); // Write the compressed outputs. - for (i = 0; i < length; i++) { - output = this.outputs[i]; + for (let i = 0; i < length; i++) { + const output = this.outputs[i]; if (!output) continue; @@ -274,18 +270,18 @@ Coins.prototype.toRaw = function toRaw() { // Render the buffer with all // zeroes in the spent field. - data = bw.render(); + const data = bw.render(); // Mark the spents in the spent field. // This is essentially a NOP for new coins. - for (i = 0; i < length; i++) { - output = this.outputs[i]; + for (let i = 0; i < length; i++) { + const output = this.outputs[i]; if (output) continue; - bit = i % 8; - oct = (i - bit) / 8; + const bit = i % 8; + let oct = (i - bit) / 8; oct += start; data[oct] |= 1 << (7 - bit); @@ -304,11 +300,10 @@ Coins.prototype.toRaw = function toRaw() { Coins.prototype.fromRaw = function fromRaw(data, hash, index) { const br = new BufferReader(data); let pos = 0; - let bits, len, start, bit, oct, spent, coin; this.version = br.readVarint(); - bits = br.readU32(); + const bits = br.readU32(); this.height = bits >>> 1; this.hash = hash; @@ -316,17 +311,17 @@ Coins.prototype.fromRaw = function fromRaw(data, hash, index) { // Mark the start of the spent field and // seek past it to avoid reading a buffer. - len = br.readVarint(); - start = br.offset; + const len = br.readVarint(); + const start = br.offset; br.seek(len); while (br.left()) { - bit = pos % 8; - oct = (pos - bit) / 8; + const bit = pos % 8; + let oct = (pos - bit) / 8; oct += start; // Read a single bit out of the spent field. - spent = data[oct] >>> (7 - bit); + let spent = data[oct] >>> (7 - bit); spent &= 1; // Already spent. @@ -338,7 +333,7 @@ Coins.prototype.fromRaw = function fromRaw(data, hash, index) { // Store the offset and size // in the compressed coin object. - coin = CoinEntry.fromReader(br); + const coin = CoinEntry.fromReader(br); this.outputs.push(coin); pos++; @@ -359,11 +354,10 @@ Coins.parseCoin = function parseCoin(data, hash, index) { const br = new BufferReader(data); const coin = new Coin(); let pos = 0; - let bits, len, start, bit, oct, spent; coin.version = br.readVarint(); - bits = br.readU32(); + const bits = br.readU32(); coin.hash = hash; coin.index = index; @@ -373,17 +367,17 @@ Coins.parseCoin = function parseCoin(data, hash, index) { // Mark the start of the spent field and // seek past it to avoid reading a buffer. - len = br.readVarint(); - start = br.offset; + const len = br.readVarint(); + const start = br.offset; br.seek(len); while (br.left()) { - bit = pos % 8; - oct = (pos - bit) / 8; + const bit = pos % 8; + let oct = (pos - bit) / 8; oct += start; // Read a single bit out of the spent field. - spent = data[oct] >>> (7 - bit); + let spent = data[oct] >>> (7 - bit); spent &= 1; // We found our coin. @@ -425,15 +419,13 @@ Coins.fromRaw = function fromRaw(data, hash) { */ Coins.prototype.fromTX = function fromTX(tx) { - let i, output; - this.version = tx.version; this.hash = tx.hash('hex'); this.height = tx.height; this.coinbase = tx.isCoinbase(); - for (i = 0; i < tx.outputs.length; i++) { - output = tx.outputs[i]; + for (let i = 0; i < tx.outputs.length; i++) { + const output = tx.outputs[i]; if (output.script.isUnspendable()) { this.outputs.push(null); @@ -491,7 +483,6 @@ function CoinEntry() { CoinEntry.prototype.toCoin = function toCoin(coins, index) { const coin = new Coin(); - let br; // Load in all necessary properties // from the parent Coins object. @@ -507,7 +498,7 @@ CoinEntry.prototype.toCoin = function toCoin(coins, index) { return coin; } - br = new BufferReader(this.raw); + const br = new BufferReader(this.raw); // Seek to the coin's offset. br.seek(this.offset); @@ -525,8 +516,6 @@ CoinEntry.prototype.toCoin = function toCoin(coins, index) { */ CoinEntry.prototype.toWriter = function toWriter(bw) { - let raw; - if (this.output) { compress.script(this.output.script, bw); bw.writeVarint(this.output.value); @@ -539,7 +528,7 @@ CoinEntry.prototype.toWriter = function toWriter(bw) { // didn't use it, it's still in its // compressed form. Just write it back // as a buffer for speed. - raw = this.raw.slice(this.offset, this.offset + this.size); + const raw = this.raw.slice(this.offset, this.offset + this.size); bw.writeBytes(raw); }; diff --git a/migrate/coins/coins.js b/migrate/coins/coins.js index aef8edd0..c4c74c72 100644 --- a/migrate/coins/coins.js +++ b/migrate/coins/coins.js @@ -149,12 +149,10 @@ Coins.prototype.has = function has(index) { */ Coins.prototype.isUnspent = function isUnspent(index) { - let output; - if (index >= this.outputs.length) return false; - output = this.outputs[index]; + const output = this.outputs[index]; if (!output || output.spent) return false; @@ -317,7 +315,6 @@ Coins.prototype.header = function header(len, size) { const first = this.isUnspent(0); const second = this.isUnspent(1); let offset = 0; - let code; // Throw if we're fully spent. assert(len !== 0, 'Cannot serialize fully-spent coins.'); @@ -330,7 +327,7 @@ Coins.prototype.header = function header(len, size) { } // Calculate header code. - code = 8 * (size - offset); + let code = 8 * (size - offset); if (this.coinbase) code += 1; @@ -425,7 +422,6 @@ Coins.prototype.fromRaw = function fromRaw(data, hash) { const br = new BufferReader(data); let first = null; let second = null; - let code, size, offset; // Inject hash (passed by caller). this.hash = hash; @@ -433,17 +429,17 @@ Coins.prototype.fromRaw = function fromRaw(data, hash) { // Read headers. this.version = br.readVarint(); this.height = br.readU32(); - code = br.readVarint(); + const code = br.readVarint(); this.coinbase = (code & 1) !== 0; // Recalculate size. - size = code / 8 | 0; + let size = code / 8 | 0; if ((code & 6) === 0) size += 1; // Setup spent field. - offset = br.offset; + let offset = br.offset; br.seek(size); // Read first two outputs. @@ -484,7 +480,6 @@ Coins.prototype.fromRaw = function fromRaw(data, hash) { Coins.parseCoin = function parseCoin(data, hash, index) { const br = new BufferReader(data); const coin = new Coin(); - let code, size, offset; // Inject outpoint (passed by caller). coin.hash = hash; @@ -493,11 +488,11 @@ Coins.parseCoin = function parseCoin(data, hash, index) { // Read headers. coin.version = br.readVarint(); coin.height = br.readU32(); - code = br.readVarint(); + const code = br.readVarint(); coin.coinbase = (code & 1) !== 0; // Recalculate size. - size = code / 8 | 0; + let size = code / 8 | 0; if ((code & 6) === 0) size += 1; @@ -506,7 +501,7 @@ Coins.parseCoin = function parseCoin(data, hash, index) { return; // Setup spent field. - offset = br.offset; + let offset = br.offset; br.seek(size); // Read first two outputs. @@ -562,8 +557,6 @@ Coins.fromRaw = function fromRaw(data, hash) { */ Coins.prototype.fromTX = function fromTX(tx, height) { - let output; - assert(typeof height === 'number'); this.version = tx.version; @@ -571,7 +564,7 @@ Coins.prototype.fromTX = function fromTX(tx, height) { this.height = height; this.coinbase = tx.isCoinbase(); - for (output of tx.outputs) { + for (const output of tx.outputs) { if (output.script.isUnspendable()) { this.outputs.push(null); continue; @@ -631,11 +624,9 @@ function CoinEntry() { */ CoinEntry.prototype.reader = function reader() { - let br; - assert(this.raw); - br = new BufferReader(this.raw); + const br = new BufferReader(this.raw); br.offset = this.offset; return br; diff --git a/migrate/coins/coinview.js b/migrate/coins/coinview.js index f3dcb941..659fe93b 100644 --- a/migrate/coins/coinview.js +++ b/migrate/coins/coinview.js @@ -185,7 +185,6 @@ CoinView.prototype.removeOutput = function removeOutput(hash, index) { CoinView.prototype.spendFrom = function spendFrom(coins, index) { const entry = coins.spend(index); - let undo; if (!entry) return false; @@ -193,7 +192,7 @@ CoinView.prototype.spendFrom = function spendFrom(coins, index) { this.undo.push(entry); if (coins.isEmpty()) { - undo = this.undo.top(); + const undo = this.undo.top(); undo.height = coins.height; undo.coinbase = coins.coinbase; undo.version = coins.version; @@ -405,14 +404,13 @@ CoinView.prototype.toWriter = function toWriter(bw, tx) { for (const input of tx.inputs) { const prevout = input.prevout; const coins = this.get(prevout.hash); - let entry; if (!coins) { bw.writeU8(0); continue; } - entry = coins.get(prevout.index); + const entry = coins.get(prevout.index); if (!entry) { bw.writeU8(0); @@ -437,12 +435,11 @@ CoinView.prototype.toWriter = function toWriter(bw, tx) { CoinView.prototype.fromReader = function fromReader(br, tx) { for (const input of tx.inputs) { const prevout = input.prevout; - let coins, entry; if (br.readU8() === 0) continue; - coins = this.get(prevout.hash); + let coins = this.get(prevout.hash); if (!coins) { coins = new Coins(); @@ -451,7 +448,7 @@ CoinView.prototype.fromReader = function fromReader(br, tx) { this.add(coins); } - entry = CoinEntry.fromReader(br); + const entry = CoinEntry.fromReader(br); coins.add(prevout.index, entry); } diff --git a/migrate/coins/compress.js b/migrate/coins/compress.js index e50be0e3..d890455a 100644 --- a/migrate/coins/compress.js +++ b/migrate/coins/compress.js @@ -30,8 +30,6 @@ const EMPTY_BUFFER = Buffer.alloc(0); */ function compressScript(script, bw) { - let data; - // Attempt to compress the output scripts. // We can _only_ ever compress them if // they are serialized as minimaldata, as @@ -41,7 +39,7 @@ function compressScript(script, bw) { // P2PKH -> 0 | key-hash // Saves 5 bytes. if (script.isPubkeyhash(true)) { - data = script.code[2].data; + const data = script.code[2].data; bw.writeU8(0); bw.writeBytes(data); return bw; @@ -50,7 +48,7 @@ function compressScript(script, bw) { // P2SH -> 1 | script-hash // Saves 3 bytes. if (script.isScripthash()) { - data = script.code[1].data; + const data = script.code[1].data; bw.writeU8(1); bw.writeBytes(data); return bw; @@ -60,7 +58,7 @@ function compressScript(script, bw) { // Only works if the key is valid. // Saves up to 35 bytes. if (script.isPubkey(true)) { - data = script.code[0].data; + let data = script.code[0].data; if (publicKeyVerify(data)) { data = compressKey(data); bw.writeBytes(data); @@ -129,8 +127,6 @@ function decompressScript(script, br) { */ function sizeScript(script) { - let size, data; - if (script.isPubkeyhash(true)) return 21; @@ -138,12 +134,12 @@ function sizeScript(script) { return 21; if (script.isPubkey(true)) { - data = script.code[0].data; + const data = script.code[0].data; if (publicKeyVerify(data)) return 33; } - size = 0; + let size = 0; size += encoding.sizeVarint(script.raw.length + COMPRESS_TYPES); size += script.raw.length; @@ -252,19 +248,17 @@ function skipOutput(br) { */ function compressValue(value) { - let exp, last; - if (value === 0) return 0; - exp = 0; + let exp = 0; while (value % 10 === 0 && exp < 9) { value /= 10; exp++; } if (exp < 9) { - last = value % 10; + const last = value % 10; value = (value - last) / 10; return 1 + 10 * (9 * value + last - 1) + exp; } @@ -279,18 +273,17 @@ function compressValue(value) { */ function decompressValue(value) { - let exp, n, last; - if (value === 0) return 0; value--; - exp = value % 10; + let exp = value % 10; value = (value - exp) / 10; + let n; if (exp < 9) { - last = value % 9; + const last = value % 9; value = (value - last) / 9; n = value * 10 + last + 1; } else { @@ -368,7 +361,6 @@ function compressKey(key) { function decompressKey(key) { const format = key[0]; - let out; assert(key.length === 33); @@ -387,7 +379,7 @@ function decompressKey(key) { } // Decompress the key. - out = secp256k1.publicKeyConvert(key, false); + const out = secp256k1.publicKeyConvert(key, false); // Reset the first byte so as not to // mutate the original buffer. diff --git a/migrate/compress-old.js b/migrate/compress-old.js index 1ba95c15..bceac2f1 100644 --- a/migrate/compress-old.js +++ b/migrate/compress-old.js @@ -20,8 +20,6 @@ const secp256k1 = require('../lib/crypto/secp256k1'); */ function compressScript(script, bw) { - let data; - // Attempt to compress the output scripts. // We can _only_ ever compress them if // they are serialized as minimaldata, as @@ -31,7 +29,7 @@ function compressScript(script, bw) { // P2PKH -> 1 | key-hash // Saves 5 bytes. if (script.isPubkeyhash(true)) { - data = script.code[2].data; + const data = script.code[2].data; bw.writeU8(1); bw.writeBytes(data); return bw; @@ -40,7 +38,7 @@ function compressScript(script, bw) { // P2SH -> 2 | script-hash // Saves 3 bytes. if (script.isScripthash()) { - data = script.code[1].data; + const data = script.code[1].data; bw.writeU8(2); bw.writeBytes(data); return bw; @@ -50,7 +48,7 @@ function compressScript(script, bw) { // Only works if the key is valid. // Saves up to 34 bytes. if (script.isPubkey(true)) { - data = script.code[0].data; + let data = script.code[0].data; if (secp256k1.publicKeyVerify(data)) { data = compressKey(data); bw.writeU8(3); @@ -112,19 +110,17 @@ function decompressScript(script, br) { */ function compressValue(value) { - let exp, last; - if (value === 0) return 0; - exp = 0; + let exp = 0; while (value % 10 === 0 && exp < 9) { value /= 10; exp++; } if (exp < 9) { - last = value % 10; + const last = value % 10; value = (value - last) / 10; return 1 + 10 * (9 * value + last - 1) + exp; } @@ -139,18 +135,17 @@ function compressValue(value) { */ function decompressValue(value) { - let exp, n, last; - if (value === 0) return 0; value--; - exp = value % 10; + let exp = value % 10; value = (value - exp) / 10; + let n; if (exp < 9) { - last = value % 9; + const last = value % 9; value = (value - last) / 9; n = value * 10 + last + 1; } else { @@ -210,7 +205,6 @@ function compressKey(key) { function decompressKey(key) { const format = key[0] >>> 2; - let out; assert(key.length === 33); @@ -223,7 +217,7 @@ function decompressKey(key) { // low bits so publicKeyConvert // actually understands it. key[0] &= 0x03; - out = secp256k1.publicKeyConvert(key, false); + const out = secp256k1.publicKeyConvert(key, false); // Reset the hi bits so as not to // mutate the original buffer. diff --git a/migrate/ensure-tip-index.js b/migrate/ensure-tip-index.js index af7355d5..2fa074ee 100644 --- a/migrate/ensure-tip-index.js +++ b/migrate/ensure-tip-index.js @@ -9,13 +9,13 @@ const LDB = require('../lib/db/ldb'); const BN = require('../lib/crypto/bn'); const DUMMY = Buffer.from([0]); let file = process.argv[2]; -let db, batch; +let batch; assert(typeof file === 'string', 'Please pass in a database path.'); file = file.replace(/\.ldb\/?$/, ''); -db = LDB({ +const db = LDB({ location: file, db: 'leveldb', compression: true, @@ -25,16 +25,14 @@ db = LDB({ }); async function checkVersion() { - let data, ver; - console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); if (!data) return; - ver = data.readUInt32LE(0, true); + const ver = data.readUInt32LE(0, true); if (ver !== 1) throw Error(`DB is version ${ver}.`); @@ -91,31 +89,30 @@ async function isMainChain(entry, tip) { // be indexing tips in the first place! async function indexTips() { const entries = await getEntries(); - let tip = await getTip(); + const tip = await getTip(); const tips = []; const orphans = []; const prevs = {}; - let i, orphan, entry, main; - for (i = 0; i < entries.length; i++) { - entry = entries[i]; - main = await isMainChain(entry, tip.hash); + for (let i = 0; i < entries.length; i++) { + const entry = entries[i]; + const main = await isMainChain(entry, tip.hash); if (!main) { orphans.push(entry); prevs[entry.prevBlock] = true; } } - for (i = 0; i < orphans.length; i++) { - orphan = orphans[i]; + for (let i = 0; i < orphans.length; i++) { + const orphan = orphans[i]; if (!prevs[orphan.hash]) tips.push(orphan.hash); } tips.push(tip.hash); - for (i = 0; i < tips.length; i++) { - tip = tips[i]; + for (let i = 0; i < tips.length; i++) { + const tip = tips[i]; console.log('Indexing chain tip: %s.', util.revHex(tip)); batch.put(pair('p', tip), DUMMY); } diff --git a/migrate/walletdb2to3.js b/migrate/walletdb2to3.js index 8b65c07d..b9f06c03 100644 --- a/migrate/walletdb2to3.js +++ b/migrate/walletdb2to3.js @@ -12,13 +12,13 @@ const BufferReader = require('../lib/utils/reader'); const BufferWriter = require('../lib/utils/writer'); const layout = walletdb.layout; let file = process.argv[2]; -let db, batch; +let batch; assert(typeof file === 'string', 'Please pass in a database path.'); file = file.replace(/\.ldb\/?$/, ''); -db = bcoin.ldb({ +const db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, @@ -29,14 +29,13 @@ db = bcoin.ldb({ async function updateVersion() { const bak = `${process.env.HOME}/walletdb-bak-${Date.now()}.ldb`; - let data, ver; console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); assert(data, 'No version.'); - ver = data.readUInt32LE(0, true); + let ver = data.readUInt32LE(0, true); if (ver !== 2) throw Error(`DB is version ${ver}.`); @@ -52,10 +51,8 @@ async function updateVersion() { async function updatePathMap() { let total = 0; - let i, iter, item, oldPaths, oldPath; - let hash, path, keys, key, ring; - iter = db.iterator({ + const iter = db.iterator({ gte: layout.p(encoding.NULL_HASH), lte: layout.p(encoding.HIGH_HASH), values: true @@ -64,21 +61,21 @@ async function updatePathMap() { console.log('Migrating path map.'); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; total++; - hash = layout.pp(item.key); - oldPaths = parsePaths(item.value, hash); - keys = Object.keys(oldPaths); + const hash = layout.pp(item.key); + const oldPaths = parsePaths(item.value, hash); + const keys = Object.keys(oldPaths); - for (i = 0; i < keys.length; i++) { + for (let i = 0; i < keys.length; i++) { keys[i] = +keys[i]; - key = keys[i]; - oldPath = oldPaths[key]; - path = new Path(oldPath); + const key = keys[i]; + const oldPath = oldPaths[key]; + const path = new Path(oldPath); if (path.data) { if (path.encrypted) { console.log( @@ -87,7 +84,7 @@ async function updatePathMap() { path.toAddress().toBase58()); continue; } - ring = keyFromRaw(path.data); + const ring = keyFromRaw(path.data); path.data = new bcoin.keyring(ring).toRaw(); } batch.put(layout.P(key, hash), path.toRaw()); @@ -101,9 +98,8 @@ async function updatePathMap() { async function updateAccounts() { let total = 0; - let iter, item, account, buf; - iter = db.iterator({ + const iter = db.iterator({ gte: layout.a(0, 0), lte: layout.a(0xffffffff, 0xffffffff), values: true @@ -112,19 +108,19 @@ async function updateAccounts() { console.log('Migrating accounts.'); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; total++; - account = accountFromRaw(item.value, item.key); + let account = accountFromRaw(item.value, item.key); account = new Account({ network: account.network, options: {} }, account); batch.put(item.key, account.toRaw()); if (account._old) { batch.del(layout.i(account.wid, account._old)); - buf = Buffer.allocUnsafe(4); + const buf = Buffer.allocUnsafe(4); buf.writeUInt32LE(account.accountIndex, 0, true); batch.put(layout.i(account.wid, account.name), buf); } @@ -135,9 +131,8 @@ async function updateAccounts() { async function updateWallets() { let total = 0; - let iter, item, wallet, buf; - iter = db.iterator({ + const iter = db.iterator({ gte: layout.w(0), lte: layout.w(0xffffffff), values: true @@ -146,19 +141,19 @@ async function updateWallets() { console.log('Migrating wallets.'); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; total++; - wallet = walletFromRaw(item.value); + let wallet = walletFromRaw(item.value); wallet = new Wallet({ network: wallet.network }, wallet); batch.put(item.key, wallet.toRaw()); if (wallet._old) { batch.del(layout.l(wallet._old)); - buf = Buffer.allocUnsafe(4); + const buf = Buffer.allocUnsafe(4); buf.writeUInt32LE(wallet.wid, 0, true); batch.put(layout.l(wallet.id), buf); } @@ -169,9 +164,8 @@ async function updateWallets() { async function updateTXMap() { let total = 0; - let iter, item, wallets; - iter = db.iterator({ + const iter = db.iterator({ gte: layout.e(encoding.NULL_HASH), lte: layout.e(encoding.HIGH_HASH), values: true @@ -180,13 +174,13 @@ async function updateTXMap() { console.log('Migrating tx map.'); for (;;) { - item = await iter.next(); + const item = await iter.next(); if (!item) break; total++; - wallets = parseWallets(item.value); + const wallets = parseWallets(item.value); batch.put(item.key, serializeWallets(wallets.sort())); } @@ -230,10 +224,9 @@ function pathFromRaw(data) { function parsePaths(data, hash) { const p = new BufferReader(data); const out = {}; - let path; while (p.left()) { - path = pathFromRaw(p); + const path = pathFromRaw(p); out[path.wid] = path; if (hash) path.hash = hash; @@ -252,10 +245,9 @@ function parseWallets(data) { function serializeWallets(wallets) { const p = new BufferWriter(); - let i, wid; - for (i = 0; i < wallets.length; i++) { - wid = wallets[i]; + for (let i = 0; i < wallets.length; i++) { + const wid = wallets[i]; p.writeU32(wid); } @@ -272,7 +264,6 @@ function readAccountKey(key) { function accountFromRaw(data, dbkey) { const account = {}; const p = new BufferReader(data); - let i, count, key, name; dbkey = readAccountKey(dbkey); account.wid = dbkey.wid; @@ -292,7 +283,7 @@ function accountFromRaw(data, dbkey) { account.watchOnly = false; account.nestedDepth = 0; - name = account.name.replace(/[^\-\._0-9A-Za-z]+/g, ''); + const name = account.name.replace(/[^\-\._0-9A-Za-z]+/g, ''); if (name !== account.name) { console.log('Account name changed: %s -> %s.', account.name, name); @@ -300,10 +291,10 @@ function accountFromRaw(data, dbkey) { account.name = name; } - count = p.readU8(); + const count = p.readU8(); - for (i = 0; i < count; i++) { - key = bcoin.hd.fromRaw(p.readBytes(82)); + for (let i = 0; i < count; i++) { + const key = bcoin.hd.fromRaw(p.readBytes(82)); account.keys.push(key); } @@ -313,7 +304,6 @@ function accountFromRaw(data, dbkey) { function walletFromRaw(data) { const wallet = {}; const p = new BufferReader(data); - let id; wallet.network = bcoin.network.fromMagic(p.readU32()); wallet.wid = p.readU32(); @@ -325,7 +315,7 @@ function walletFromRaw(data) { wallet.master = MasterKey.fromRaw(p.readVarBytes()); wallet.watchOnly = false; - id = wallet.id.replace(/[^\-\._0-9A-Za-z]+/g, ''); + const id = wallet.id.replace(/[^\-\._0-9A-Za-z]+/g, ''); if (id !== wallet.id) { console.log('Wallet ID changed: %s -> %s.', wallet.id, id); @@ -339,12 +329,11 @@ function walletFromRaw(data) { function keyFromRaw(data, network) { const ring = {}; const p = new BufferReader(data); - let key, script; ring.network = bcoin.network.get(network); ring.witness = p.readU8() === 1; - key = p.readVarBytes(); + const key = p.readVarBytes(); if (key.length === 32) { ring.privateKey = key; @@ -353,7 +342,7 @@ function keyFromRaw(data, network) { ring.publicKey = key; } - script = p.readVarBytes(); + const script = p.readVarBytes(); if (script.length > 0) ring.script = bcoin.script.fromRaw(script); diff --git a/migrate/walletdb3to4.js b/migrate/walletdb3to4.js index 135d0892..b00d84ad 100644 --- a/migrate/walletdb3to4.js +++ b/migrate/walletdb3to4.js @@ -8,13 +8,13 @@ const BufferReader = require('../lib/utils/reader'); const TX = require('../lib/primitives/tx'); const Coin = require('../lib/primitives/coin'); let file = process.argv[2]; -let db, batch; +let batch; assert(typeof file === 'string', 'Please pass in a database path.'); file = file.replace(/\.ldb\/?$/, ''); -db = bcoin.ldb({ +const db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, @@ -25,14 +25,13 @@ db = bcoin.ldb({ async function updateVersion() { const bak = `${process.env.HOME}/walletdb-bak-${Date.now()}.ldb`; - let data, ver; console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); assert(data, 'No version.'); - ver = data.readUInt32LE(0, true); + let ver = data.readUInt32LE(0, true); if (ver !== 3) throw Error(`DB is version ${ver}.`); @@ -48,19 +47,18 @@ async function updateVersion() { async function updateTXDB() { let txs = {}; - let i, keys, key, hash, tx, walletdb; - keys = await db.keys({ + const keys = await db.keys({ gte: Buffer.from([0x00]), lte: Buffer.from([0xff]) }); - for (i = 0; i < keys.length; i++) { - key = keys[i]; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; if (key[0] === 0x74 && key[5] === 0x74) { - tx = await db.get(key); + let tx = await db.get(key); tx = fromExtended(tx); - hash = tx.hash('hex'); + const hash = tx.hash('hex'); txs[hash] = tx; } if (key[0] === 0x74) @@ -72,7 +70,7 @@ async function updateTXDB() { await batch.write(); await db.close(); - walletdb = new WalletDB({ + const walletdb = new WalletDB({ location: file, db: 'leveldb', resolution: true, @@ -82,8 +80,8 @@ async function updateTXDB() { await walletdb.open(); - for (i = 0; i < txs.length; i++) { - tx = txs[i]; + for (let i = 0; i < txs.length; i++) { + const tx = txs[i]; await walletdb.addTX(tx); } @@ -93,7 +91,6 @@ async function updateTXDB() { function fromExtended(data, saveCoins) { const tx = new TX(); const p = BufferReader(data); - let i, coinCount, coin; tx.fromRaw(p); @@ -113,9 +110,9 @@ function fromExtended(data, saveCoins) { tx.index = -1; if (saveCoins) { - coinCount = p.readVarint(); - for (i = 0; i < coinCount; i++) { - coin = p.readVarBytes(); + const coinCount = p.readVarint(); + for (let i = 0; i < coinCount; i++) { + let coin = p.readVarBytes(); if (coin.length === 0) continue; coin = Coin.fromRaw(coin); diff --git a/migrate/walletdb4to5.js b/migrate/walletdb4to5.js index 242f3132..eb0e58f6 100644 --- a/migrate/walletdb4to5.js +++ b/migrate/walletdb4to5.js @@ -3,13 +3,13 @@ const assert = require('assert'); const bcoin = require('../'); let file = process.argv[2]; -let db, batch; +let batch; assert(typeof file === 'string', 'Please pass in a database path.'); file = file.replace(/\.ldb\/?$/, ''); -db = bcoin.ldb({ +const db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, @@ -20,11 +20,10 @@ db = bcoin.ldb({ async function updateVersion() { const bak = `${process.env.HOME}/walletdb-bak-${Date.now()}.ldb`; - let data, ver; console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); assert(data, 'No version.'); ver = data.readUInt32LE(0, true); @@ -36,21 +35,19 @@ async function updateVersion() { await db.backup(bak); - ver = Buffer.allocUnsafe(4); + let ver = Buffer.allocUnsafe(4); ver.writeUInt32LE(5, 0, true); batch.put('V', ver); } async function updateTXDB() { - let i, keys, key; - - keys = await db.keys({ + const keys = await db.keys({ gte: Buffer.from([0x00]), lte: Buffer.from([0xff]) }); - for (i = 0; i < keys.length; i++) { - key = keys[i]; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; switch (key[0]) { case 0x62: // b case 0x63: // c diff --git a/migrate/walletdb5to6.js b/migrate/walletdb5to6.js index b074b39a..656a0675 100644 --- a/migrate/walletdb5to6.js +++ b/migrate/walletdb5to6.js @@ -6,13 +6,13 @@ const encoding = require('../lib/utils/encoding'); const BufferWriter = require('../lib/utils/writer'); const BufferReader = require('../lib/utils/reader'); let file = process.argv[2]; -let db, batch; +let batch; assert(typeof file === 'string', 'Please pass in a database path.'); file = file.replace(/\.ldb\/?$/, ''); -db = bcoin.ldb({ +const db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, @@ -23,11 +23,10 @@ db = bcoin.ldb({ async function updateVersion() { const bak = `${process.env.HOME}/walletdb-bak-${Date.now()}.ldb`; - let data, ver; console.log('Checking version.'); - data = await db.get('V'); + const data = await db.get('V'); assert(data, 'No version.'); ver = data.readUInt32LE(0, true); @@ -39,22 +38,21 @@ async function updateVersion() { await db.backup(bak); - ver = Buffer.allocUnsafe(4); + let ver = Buffer.allocUnsafe(4); ver.writeUInt32LE(6, 0, true); batch.put('V', ver); } async function wipeTXDB() { let total = 0; - let i, keys, key; - keys = await db.keys({ + const keys = await db.keys({ gte: Buffer.from([0x00]), lte: Buffer.from([0xff]) }); - for (i = 0; i < keys.length; i++) { - key = keys[i]; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; switch (key[0]) { case 0x62: // b case 0x63: // c @@ -74,18 +72,16 @@ async function wipeTXDB() { } async function patchAccounts() { - let i, items, item, wid, index, account; - - items = await db.range({ + const items = await db.range({ gte: Buffer.from('610000000000000000', 'hex'), // a lte: Buffer.from('61ffffffffffffffff', 'hex') // a }); - for (i = 0; i < items.length; i++) { - item = items[i]; - wid = item.key.readUInt32BE(1, true); - index = item.key.readUInt32BE(5, true); - account = accountFromRaw(item.value); + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const wid = item.key.readUInt32BE(1, true); + const index = item.key.readUInt32BE(5, true); + const account = accountFromRaw(item.value); console.log('a[%d][%d] -> lookahead=%d', wid, index, account.lookahead); batch.put(item.key, accountToRaw(account)); console.log('n[%d][%d] -> %s', wid, index, account.name); @@ -94,35 +90,31 @@ async function patchAccounts() { } async function indexPaths() { - let i, items, item, wid, index, hash; - - items = await db.range({ + const items = await db.range({ gte: Buffer.from('5000000000' + encoding.NULL_HASH, 'hex'), // P lte: Buffer.from('50ffffffff' + encoding.HIGH_HASH, 'hex') // P }); - for (i = 0; i < items.length; i++) { - item = items[i]; - wid = item.key.readUInt32BE(1, true); - hash = item.key.toString('hex', 5); - index = item.value.readUInt32LE(0, true); + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const wid = item.key.readUInt32BE(1, true); + const hash = item.key.toString('hex', 5); + const index = item.value.readUInt32LE(0, true); console.log('r[%d][%d][%s] -> NUL', wid, index, hash); batch.put(r(wid, index, hash), Buffer.from([0])); } } async function patchPathMaps() { - let i, items, item, hash, wids; - - items = await db.range({ + const items = await db.range({ gte: Buffer.from('70' + encoding.NULL_HASH, 'hex'), // p lte: Buffer.from('70' + encoding.HIGH_HASH, 'hex') // p }); - for (i = 0; i < items.length; i++) { - item = items[i]; - hash = item.key.toString('hex', 1); - wids = parseWallets(item.value); + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const hash = item.key.toString('hex', 1); + const wids = parseWallets(item.value); console.log('p[%s] -> u32(%d)', hash, wids.length); batch.put(item.key, serializeWallets(wids)); } @@ -140,12 +132,11 @@ function parseWallets(data) { function serializeWallets(wids) { const p = new BufferWriter(); - let i, wid; p.writeU32(wids.length); - for (i = 0; i < wids.length; i++) { - wid = wids[i]; + for (let i = 0; i < wids.length; i++) { + const wid = wids[i]; p.writeU32(wid); } @@ -154,7 +145,6 @@ function serializeWallets(wids) { function accountToRaw(account) { const p = new BufferWriter(); - let i, key; p.writeVarString(account.name, 'ascii'); p.writeU8(account.initialized ? 1 : 0); @@ -170,8 +160,8 @@ function accountToRaw(account) { p.writeBytes(account.accountKey); p.writeU8(account.keys.length); - for (i = 0; i < account.keys.length; i++) { - key = account.keys[i]; + for (let i = 0; i < account.keys.length; i++) { + const key = account.keys[i]; p.writeBytes(key); } @@ -181,7 +171,6 @@ function accountToRaw(account) { function accountFromRaw(data) { const account = {}; const p = new BufferReader(data); - let i, count, key; account.name = p.readVarString('ascii'); account.initialized = p.readU8() === 1; @@ -197,10 +186,10 @@ function accountFromRaw(data) { account.accountKey = p.readBytes(82); account.keys = []; - count = p.readU8(); + const count = p.readU8(); - for (i = 0; i < count; i++) { - key = p.readBytes(82); + for (let i = 0; i < count; i++) { + const key = p.readBytes(82); account.keys.push(key); } @@ -226,9 +215,8 @@ function r(wid, index, hash) { async function updateLookahead() { const WalletDB = require('../lib/wallet/walletdb'); - let i, j, db, wallet; - db = new WalletDB({ + const db = new WalletDB({ network: process.argv[3], db: 'leveldb', location: file, @@ -241,11 +229,11 @@ async function updateLookahead() { await db.open(); - for (i = 1; i < db.depth; i++) { - wallet = await db.get(i); + for (let i = 1; i < db.depth; i++) { + const wallet = await db.get(i); assert(wallet); console.log('Updating wallet lookahead: %s', wallet.id); - for (j = 0; j < wallet.accountDepth; j++) + for (let j = 0; j < wallet.accountDepth; j++) await wallet.setLookahead(j, 20); } diff --git a/scripts/dump.js b/scripts/dump.js index 70acc5a6..fd5faa11 100644 --- a/scripts/dump.js +++ b/scripts/dump.js @@ -9,7 +9,6 @@ const CoinView = require('../lib/coins/coinview'); const SNAPSHOT = `${__dirname}/../dump.heapsnapshot`; const tx = parseTX('../test/data/tx4.hex'); -let raw, coins, entry; function parseTX(file) { const data = fs.readFileSync(`${__dirname}/${file}`, 'utf8'); @@ -28,9 +27,9 @@ function parseTX(file) { return { tx: tx, view: view }; } -raw = Coins.fromTX(tx.tx, 0).toRaw(); -coins = Coins.fromRaw(raw, tx.tx.hash('hex')); -entry = MempoolEntry.fromTX(tx.tx, tx.view, 1000000); +const raw = Coins.fromTX(tx.tx, 0).toRaw(); +const coins = Coins.fromRaw(raw, tx.tx.hash('hex')); +const entry = MempoolEntry.fromTX(tx.tx, tx.view, 1000000); setInterval(() => { console.log(tx.hash('hex')); diff --git a/scripts/gen.js b/scripts/gen.js index ad0928df..00e94d9e 100644 --- a/scripts/gen.js +++ b/scripts/gen.js @@ -10,13 +10,10 @@ const Script = require('../lib/script/script'); const Opcode = require('../lib/script/opcode'); const opcodes = Script.opcodes; -let main, testnet, regtest, segnet3, segnet4, btcd; - function createGenesisBlock(options) { let flags = options.flags; let script = options.script; let reward = options.reward; - let tx, block; if (!flags) { flags = Buffer.from( @@ -36,7 +33,7 @@ function createGenesisBlock(options) { if (!reward) reward = 50 * consensus.COIN; - tx = new TX({ + const tx = new TX({ version: 1, flag: 1, inputs: [{ @@ -58,7 +55,7 @@ function createGenesisBlock(options) { locktime: 0 }); - block = new Block({ + const block = new Block({ version: options.version, prevBlock: encoding.NULL_HASH, merkleRoot: tx.hash('hex'), @@ -73,42 +70,42 @@ function createGenesisBlock(options) { return block; } -main = createGenesisBlock({ +const main = createGenesisBlock({ version: 1, time: 1231006505, bits: 486604799, nonce: 2083236893 }); -testnet = createGenesisBlock({ +const testnet = createGenesisBlock({ version: 1, time: 1296688602, bits: 486604799, nonce: 414098458 }); -regtest = createGenesisBlock({ +const regtest = createGenesisBlock({ version: 1, time: 1296688602, bits: 545259519, nonce: 2 }); -segnet3 = createGenesisBlock({ +const segnet3 = createGenesisBlock({ version: 1, time: 1452831101, bits: 486604799, nonce: 0 }); -segnet4 = createGenesisBlock({ +const segnet4 = createGenesisBlock({ version: 1, time: 1452831101, bits: 503447551, nonce: 0 }); -btcd = createGenesisBlock({ +const btcd = createGenesisBlock({ version: 1, time: 1401292357, bits: 545259519, diff --git a/test/aes-test.js b/test/aes-test.js index ebbfd451..867187c1 100644 --- a/test/aes-test.js +++ b/test/aes-test.js @@ -16,8 +16,6 @@ describe('AES', function() { } function nencrypt(data, passphrase) { - let key, cipher; - assert(nativeCrypto, 'No crypto module available.'); assert(passphrase, 'No passphrase.'); @@ -27,8 +25,8 @@ describe('AES', function() { if (typeof passphrase === 'string') passphrase = Buffer.from(passphrase, 'utf8'); - key = pbkdf2key(passphrase, 2048, 32, 16); - cipher = nativeCrypto.createCipheriv('aes-256-cbc', key.key, key.iv); + const key = pbkdf2key(passphrase, 2048, 32, 16); + const cipher = nativeCrypto.createCipheriv('aes-256-cbc', key.key, key.iv); return Buffer.concat([ cipher.update(data), @@ -37,8 +35,6 @@ describe('AES', function() { } function ndecrypt(data, passphrase) { - let key, decipher; - assert(nativeCrypto, 'No crypto module available.'); assert(passphrase, 'No passphrase.'); @@ -48,8 +44,8 @@ describe('AES', function() { if (typeof passphrase === 'string') passphrase = Buffer.from(passphrase, 'utf8'); - key = pbkdf2key(passphrase, 2048, 32, 16); - decipher = nativeCrypto.createDecipheriv('aes-256-cbc', key.key, key.iv); + const key = pbkdf2key(passphrase, 2048, 32, 16); + const decipher = nativeCrypto.createDecipheriv('aes-256-cbc', key.key, key.iv); return Buffer.concat([ decipher.update(data), @@ -58,8 +54,6 @@ describe('AES', function() { } function bencrypt(data, passphrase) { - let key; - assert(nativeCrypto, 'No crypto module available.'); assert(passphrase, 'No passphrase.'); @@ -69,13 +63,11 @@ describe('AES', function() { if (typeof passphrase === 'string') passphrase = Buffer.from(passphrase, 'utf8'); - key = pbkdf2key(passphrase, 2048, 32, 16); + const key = pbkdf2key(passphrase, 2048, 32, 16); return aes.encipher(data, key.key, key.iv); } function bdecrypt(data, passphrase) { - let key; - assert(nativeCrypto, 'No crypto module available.'); assert(passphrase, 'No passphrase.'); @@ -85,13 +77,11 @@ describe('AES', function() { if (typeof passphrase === 'string') passphrase = Buffer.from(passphrase, 'utf8'); - key = pbkdf2key(passphrase, 2048, 32, 16); + const key = pbkdf2key(passphrase, 2048, 32, 16); return aes.decipher(data, key.key, key.iv); } function encrypt(data, passphrase) { - let key; - assert(nativeCrypto, 'No crypto module available.'); assert(passphrase, 'No passphrase.'); @@ -101,14 +91,12 @@ describe('AES', function() { if (typeof passphrase === 'string') passphrase = Buffer.from(passphrase, 'utf8'); - key = pbkdf2key(passphrase, 2048, 32, 16); + const key = pbkdf2key(passphrase, 2048, 32, 16); return aes.encipher(data, key.key, key.iv); } function decrypt(data, passphrase) { - let key; - assert(nativeCrypto, 'No crypto module available.'); assert(passphrase, 'No passphrase.'); @@ -118,7 +106,7 @@ describe('AES', function() { if (typeof passphrase === 'string') passphrase = Buffer.from(passphrase, 'utf8'); - key = pbkdf2key(passphrase, 2048, 32, 16); + const key = pbkdf2key(passphrase, 2048, 32, 16); return aes.decipher(data, key.key, key.iv); } diff --git a/test/bech32-test.js b/test/bech32-test.js index bceebabb..c79e7a69 100644 --- a/test/bech32-test.js +++ b/test/bech32-test.js @@ -173,7 +173,7 @@ describe('Bech32', function() { INVALID_ADDRESS.forEach((test) => { it(`should have invalid address for ${test}`, () => { - let ok1, ok2, ok; + let ok1, ok2; try { ok1 = fromAddress('bc', test); @@ -187,7 +187,7 @@ describe('Bech32', function() { ok2 = null; } - ok = ok1 === null && ok2 === null; + const ok = ok1 === null && ok2 === null; assert(ok); }); }); diff --git a/test/bip150-test.js b/test/bip150-test.js index ba5fc0a9..018a528e 100644 --- a/test/bip150-test.js +++ b/test/bip150-test.js @@ -24,11 +24,11 @@ describe('BIP150', function() { } it('should do encinit', () => { - let init = server.toEncinit(); + const init = server.toEncinit(); client.encinit(init.publicKey, init.cipher); - init = client.toEncinit(); - server.encinit(init.publicKey, init.cipher); + const init2 = client.toEncinit(); + server.encinit(init2.publicKey, init2.cipher); assert(!client.handshake); assert(!server.handshake); @@ -49,14 +49,12 @@ describe('BIP150', function() { }); it('should do BIP150 handshake', () => { - let challenge, reply, propose, result; - - challenge = client.bip150.toChallenge(); - reply = server.bip150.challenge(challenge.hash); - propose = client.bip150.reply(reply); - challenge = server.bip150.propose(propose); - reply = client.bip150.challenge(challenge); - result = server.bip150.reply(reply); + const challenge = client.bip150.toChallenge(); + const reply = server.bip150.challenge(challenge.hash); + const propose = client.bip150.reply(reply); + const challenge2 = server.bip150.propose(propose); + const reply2 = client.bip150.challenge(challenge2); + const result = server.bip150.reply(reply2); assert(!result); assert(client.bip150.auth); diff --git a/test/bip70-test.js b/test/bip70-test.js index 19d785b7..2f9ab66b 100644 --- a/test/bip70-test.js +++ b/test/bip70-test.js @@ -24,7 +24,6 @@ x509.trusted.clear(); describe('BIP70', function() { function testRequest(data) { const request = bip70.PaymentRequest.fromRaw(data); - let ser; assert.equal(request.pkiType, 'x509+sha256'); assert(request.pkiData); @@ -33,7 +32,7 @@ describe('BIP70', function() { assert(request.paymentDetails.memo.length !== 0); assert(request.paymentDetails.paymentUrl.length !== 0); - ser = request.toRaw(); + const ser = request.toRaw(); assert.equal(ser.toString('hex'), data.toString('hex')); assert(request.verify()); } @@ -47,7 +46,7 @@ describe('BIP70', function() { }); it('should verify cert chain', () => { - let request = bip70.PaymentRequest.fromRaw(tests.valid); + const request = bip70.PaymentRequest.fromRaw(tests.valid); assert.equal(request.version, 1); assert.equal(request.getChain().length, 4); @@ -62,67 +61,65 @@ describe('BIP70', function() { assert(request.verifyChain()); - request = bip70.PaymentRequest.fromRaw(tests.invalid); + const request2 = bip70.PaymentRequest.fromRaw(tests.invalid); - assert.equal(request.version, 1); - assert.equal(request.getChain().length, 3); - assert.equal(request.paymentDetails.paymentUrl, + assert.equal(request2.version, 1); + assert.equal(request2.getChain().length, 3); + assert.equal(request2.paymentDetails.paymentUrl, 'https://bitpay.com/i/PAQtNxX7KL8BtJBnfXyTaH'); - assert.equal(request.paymentDetails.network, 'main'); - assert.equal(request.paymentDetails.time, 1442409238); - assert.equal(request.paymentDetails.expires, 1442410138); - assert.equal(request.paymentDetails.outputs.length, 1); - assert.equal(request.paymentDetails.merchantData.length, 76); - assert(request.paymentDetails.getData('json')); - assert(request.paymentDetails.isExpired()); + assert.equal(request2.paymentDetails.network, 'main'); + assert.equal(request2.paymentDetails.time, 1442409238); + assert.equal(request2.paymentDetails.expires, 1442410138); + assert.equal(request2.paymentDetails.outputs.length, 1); + assert.equal(request2.paymentDetails.merchantData.length, 76); + assert(request2.paymentDetails.getData('json')); + assert(request2.paymentDetails.isExpired()); - assert(request.verifyChain()); + assert(request2.verifyChain()); - request.paymentDetails.setData({foo:1}, 'json'); - assert.equal(request.paymentDetails.merchantData.length, 9); - assert.deepStrictEqual(request.paymentDetails.getData('json'), {foo:1}); - assert(!request.verify()); + request2.paymentDetails.setData({foo:1}, 'json'); + assert.equal(request2.paymentDetails.merchantData.length, 9); + assert.deepStrictEqual(request2.paymentDetails.getData('json'), {foo:1}); + assert(!request2.verify()); - request = bip70.PaymentRequest.fromRaw(tests.untrusted); + const request3 = bip70.PaymentRequest.fromRaw(tests.untrusted); - assert.equal(request.version, -1); - assert.equal(request.getChain().length, 2); - assert.equal(request.paymentDetails.paymentUrl, + assert.equal(request3.version, -1); + assert.equal(request3.getChain().length, 2); + assert.equal(request3.paymentDetails.paymentUrl, 'https://www.coinbase.com/rp/55f9ca703d5d80008c0001f4'); - assert.equal(request.paymentDetails.network, null); - assert.equal(request.paymentDetails.time, 1442433682); - assert.equal(request.paymentDetails.expires, 1442434548); - assert.equal(request.paymentDetails.outputs.length, 1); - assert.equal(request.paymentDetails.merchantData.length, 32); - assert.equal(request.paymentDetails.getData('utf8'), + assert.equal(request3.paymentDetails.network, null); + assert.equal(request3.paymentDetails.time, 1442433682); + assert.equal(request3.paymentDetails.expires, 1442434548); + assert.equal(request3.paymentDetails.outputs.length, 1); + assert.equal(request3.paymentDetails.merchantData.length, 32); + assert.equal(request3.paymentDetails.getData('utf8'), 'bb79b6f2310e321bd3b1d929edbeb358'); - assert(request.paymentDetails.isExpired()); + assert(request3.paymentDetails.isExpired()); - assert(request.verifyChain()); + assert(request3.verifyChain()); }); it('should fail to verify cert signatures when enforcing trust', () => { - let request; - x509.allowUntrusted = false; - request = bip70.PaymentRequest.fromRaw(tests.valid); + const request = bip70.PaymentRequest.fromRaw(tests.valid); assert(!request.verifyChain()); - request = bip70.PaymentRequest.fromRaw(tests.invalid); - assert(!request.verifyChain()); + const request2 = bip70.PaymentRequest.fromRaw(tests.invalid); + assert(!request2.verifyChain()); - request = bip70.PaymentRequest.fromRaw(tests.untrusted); - assert(!request.verifyChain()); + const request3 = bip70.PaymentRequest.fromRaw(tests.untrusted); + assert(!request3.verifyChain()); }); it('should verify cert signatures once root cert is added', () => { - let request = bip70.PaymentRequest.fromRaw(tests.valid); + const request = bip70.PaymentRequest.fromRaw(tests.valid); x509.setTrust([request.getChain().pop()]); assert(request.verifyChain()); - request = bip70.PaymentRequest.fromRaw(tests.untrusted); - assert(!request.verifyChain()); + const request2 = bip70.PaymentRequest.fromRaw(tests.untrusted); + assert(!request2.verifyChain()); }); it('should still fail to verify cert signatures for invalid', () => { @@ -138,12 +135,12 @@ describe('BIP70', function() { }); it('should validate untrusted once again', () => { - let request = bip70.PaymentRequest.fromRaw(tests.untrusted); + const request = bip70.PaymentRequest.fromRaw(tests.untrusted); x509.setTrust([request.getChain().pop()]); - request = bip70.PaymentRequest.fromRaw(tests.untrusted); - assert(request.verifyChain()); - assert.equal(request.getCA().name, + const request2 = bip70.PaymentRequest.fromRaw(tests.untrusted); + assert(request2.verifyChain()); + assert.equal(request2.getCA().name, 'DigiCert SHA2 Extended Validation Server CA'); }); diff --git a/test/block-test.js b/test/block-test.js index b0b841bc..a4cafe8d 100644 --- a/test/block-test.js +++ b/test/block-test.js @@ -54,9 +54,7 @@ function applyUndo(block, undo) { } describe('Block', function() { - let mblock, raw, block, raw2; - - mblock = new MerkleBlock({ + let mblock = new MerkleBlock({ version: 2, prevBlock: 'd1831d4411bdfda89d9d8c842b541beafd1437fc560dbe5c0000000000000000', merkleRoot: '28bec1d35af480ba3884553d72694f6ba6c163a5c081d7e6edaec15f373f19af', @@ -78,9 +76,10 @@ describe('Block', function() { ], flags: Buffer.from([245, 122, 0]) }); - raw = mblock.toRaw().toString('hex'); - raw2 = '02000000d1831d4411bdfda89d9d8c842b541beafd1437fc560dbe5c0' + const raw = mblock.toRaw().toString('hex'); + + const raw2 = '02000000d1831d4411bdfda89d9d8c842b541beafd1437fc560dbe5c0' + '00000000000000028bec1d35af480ba3884553d72694f6ba6c163a5c081d7e6edaec' + '15f373f19af62ef6d536c890019d0b4bf46cd0100000a7d22e53bce1bbb3294d1a39' + '6c5acc45bdcc8f192cb492f0d9f55421fd4c62de19d6d585fdaf3737b9a54aaee1dd' @@ -96,16 +95,16 @@ describe('Block', function() { mblock = MerkleBlock.fromRaw(raw2, 'hex'); + const block = Block.fromJSON(block300025); + this.timeout(10000); it('should parse partial merkle tree', () => { - let tree; - assert(mblock.verifyPOW()); assert(mblock.verifyBody()); assert(mblock.verify()); - tree = mblock.getTree(); + const tree = mblock.getTree(); assert.equal(tree.matches.length, 2); assert.equal(mblock.hash('hex'), @@ -163,7 +162,7 @@ describe('Block', function() { }); it('should parse JSON', () => { - block = Block.fromJSON(block300025); + const block = Block.fromJSON(block300025); assert.equal(block.hash('hex'), '8cc72c02a958de5a8b35a23bb7e3bced8bf840cc0a4e1c820000000000000000'); assert.equal(block.rhash(), @@ -172,19 +171,17 @@ describe('Block', function() { }); it('should create a merkle block', () => { - let filter, item1, item2, mblock2; + const filter = Bloom.fromRate(1000, 0.01, Bloom.flags.NONE); - filter = Bloom.fromRate(1000, 0.01, Bloom.flags.NONE); - - item1 = '8e7445bbb8abd4b3174d80fa4c409fea6b94d96b'; - item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10' + const item1 = '8e7445bbb8abd4b3174d80fa4c409fea6b94d96b'; + const item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10' + 'e763272c6c9ca052972c69e3884a9022084215e2eef' + '0e6f781656b5d5a87231cd4349e534b6dea55ad4ff55e'; filter.add(item1, 'hex'); filter.add(item2, 'hex'); - mblock2 = MerkleBlock.fromBlock(block, filter); + const mblock2 = MerkleBlock.fromBlock(block, filter); assert(mblock2.verifyBody()); assert.deepEqual(mblock2.toRaw(), mblock.toRaw()); @@ -195,7 +192,6 @@ describe('Block', function() { const height = block300025.height; let sigops = 0; let reward = 0; - let flags; for (let i = 1; i < block300025.txs.length; i++) { const tx = block300025.txs[i]; @@ -212,7 +208,7 @@ describe('Block', function() { assert(!block.hasWitness()); assert.equal(block.getWeight(), 1136924); - flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_DERSIG; + const flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_DERSIG; for (let i = 1; i < block.txs.length; i++) { const tx = block.txs[i]; @@ -234,11 +230,10 @@ describe('Block', function() { it('should fail with a bad merkle root', () => { const block2 = new Block(block); - let reason; block2.merkleRoot = encoding.NULL_HASH; block2.refresh(); assert(!block2.verifyPOW()); - [, reason] = block2.checkBody(); + const [, reason] = block2.checkBody(); assert.equal(reason, 'bad-txnmrklroot'); assert(!block2.verify()); block2.merkleRoot = block.merkleRoot; @@ -248,11 +243,10 @@ describe('Block', function() { it('should fail on merkle block with a bad merkle root', () => { const mblock2 = new MerkleBlock(mblock); - let reason; mblock2.merkleRoot = encoding.NULL_HASH; mblock2.refresh(); assert(!mblock2.verifyPOW()); - [, reason] = mblock2.checkBody(); + const [, reason] = mblock2.checkBody(); assert.equal(reason, 'bad-txnmrklroot'); assert(!mblock2.verify()); mblock2.merkleRoot = mblock.merkleRoot; @@ -274,10 +268,9 @@ describe('Block', function() { it('should fail on duplicate txs', () => { const block2 = new Block(block); - let reason; block2.txs.push(block2.txs[block2.txs.length - 1]); block2.refresh(); - [, reason] = block2.checkBody(); + const [, reason] = block2.checkBody(); assert.equal(reason, 'bad-txns-duplicate'); }); @@ -293,28 +286,27 @@ describe('Block', function() { const cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex'); const cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); const map = new Map(); - let i, tx, mempool, result; assert(cblock1.init()); assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]); assert.equal(cblock2.toRaw().toString('hex'), cmpct1[0]); - for (i = 0; i < block.txs.length; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length; i++) { + const tx = block.txs[i]; map.set(tx.hash('hex'), { tx: tx }); } - mempool = { + const mempool = { map: map }; assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291); - result = cblock1.fillMempool(false, mempool); + const result = cblock1.fillMempool(false, mempool); assert(result); - for (i = 0; i < cblock1.available.length; i++) + for (let i = 0; i < cblock1.available.length; i++) assert(cblock1.available[i]); assert.equal( @@ -327,28 +319,27 @@ describe('Block', function() { const cblock1 = bip152.CompactBlock.fromRaw(cmpct1[0], 'hex'); const cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); const map = new Map(); - let i, tx, mempool, result, req, res; assert(cblock1.init()); assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]); assert.equal(cblock2.toRaw().toString('hex'), cmpct1[0]); - for (i = 0; i < block.txs.length >>> 1; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length >>> 1; i++) { + const tx = block.txs[i]; map.set(tx.hash('hex'), { tx: tx }); } - mempool = { + const mempool = { map: map }; assert.equal(cblock1.sid(block.txs[1].hash()), 125673511480291); - result = cblock1.fillMempool(false, mempool); + let result = cblock1.fillMempool(false, mempool); assert(!result); - req = cblock1.toRequest(); + let req = cblock1.toRequest(); assert.equal(req.hash, cblock1.hash('hex')); assert.deepEqual(req.indexes, [5, 6, 7, 8, 9]); @@ -356,13 +347,13 @@ describe('Block', function() { assert.equal(req.hash, cblock1.hash('hex')); assert.deepEqual(req.indexes, [5, 6, 7, 8, 9]); - res = bip152.TXResponse.fromBlock(block, req); + let res = bip152.TXResponse.fromBlock(block, req); res = bip152.TXResponse.fromRaw(res.toRaw()); result = cblock1.fillMissing(res); assert(result); - for (i = 0; i < cblock1.available.length; i++) + for (let i = 0; i < cblock1.available.length; i++) assert(cblock1.available[i]); assert.equal( @@ -375,26 +366,25 @@ describe('Block', function() { const cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex'); const cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); const map = new Map(); - let i, tx, result, mempool; assert(cblock1.init()); assert.equal(cblock1.toRaw().toString('hex'), cmpct2); assert.equal(cblock2.toRaw().toString('hex'), cmpct2); - for (i = 0; i < block.txs.length; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length; i++) { + const tx = block.txs[i]; map.set(tx.hash('hex'), { tx: tx }); } - mempool = { + const mempool = { map: map }; - result = cblock1.fillMempool(false, mempool); + const result = cblock1.fillMempool(false, mempool); assert(result); - for (i = 0; i < cblock1.available.length; i++) + for (let i = 0; i < cblock1.available.length; i++) assert(cblock1.available[i]); assert.equal( @@ -407,38 +397,37 @@ describe('Block', function() { const cblock1 = bip152.CompactBlock.fromRaw(cmpct2, 'hex'); const cblock2 = bip152.CompactBlock.fromBlock(block, false, cblock1.keyNonce); const map = new Map(); - let i, tx, mempool, result, req, res; assert(cblock1.init()); assert.equal(cblock1.toRaw().toString('hex'), cmpct2); assert.equal(cblock2.toRaw().toString('hex'), cmpct2); - for (i = 0; i < block.txs.length >>> 1; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length >>> 1; i++) { + const tx = block.txs[i]; map.set(tx.hash('hex'), { tx: tx }); } - mempool = { + const mempool = { map: map }; - result = cblock1.fillMempool(false, mempool); + let result = cblock1.fillMempool(false, mempool); assert(!result); - req = cblock1.toRequest(); + let req = cblock1.toRequest(); assert.equal(req.hash, cblock1.hash('hex')); req = bip152.TXRequest.fromRaw(req.toRaw()); assert.equal(req.hash, cblock1.hash('hex')); - res = bip152.TXResponse.fromBlock(block, req); + let res = bip152.TXResponse.fromBlock(block, req); res = bip152.TXResponse.fromRaw(res.toRaw()); result = cblock1.fillMissing(res); assert(result); - for (i = 0; i < cblock1.available.length; i++) + for (let i = 0; i < cblock1.available.length; i++) assert(cblock1.available[i]); assert.equal( @@ -454,10 +443,9 @@ describe('Block', function() { const view = applyUndo(block, undo); let sigops = 0; const flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_WITNESS; - let i, tx; - for (i = 0; i < block.txs.length; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length; i++) { + const tx = block.txs[i]; sigops += tx.getSigopsCost(view, flags); } @@ -473,10 +461,9 @@ describe('Block', function() { const view = applyUndo(block, undo); let sigops = 0; const flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_WITNESS; - let i, tx; - for (i = 0; i < block.txs.length; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length; i++) { + const tx = block.txs[i]; sigops += tx.getSigopsCost(view, flags); } @@ -492,10 +479,9 @@ describe('Block', function() { const view = applyUndo(block, undo); let sigops = 0; const flags = Script.flags.VERIFY_P2SH | Script.flags.VERIFY_WITNESS; - let i, tx; - for (i = 0; i < block.txs.length; i++) { - tx = block.txs[i]; + for (let i = 0; i < block.txs.length; i++) { + const tx = block.txs[i]; sigops += tx.getSigopsCost(view, flags); } diff --git a/test/chachapoly-test.js b/test/chachapoly-test.js index 2072056a..bbc8d822 100644 --- a/test/chachapoly-test.js +++ b/test/chachapoly-test.js @@ -12,16 +12,15 @@ describe('ChaCha20 / Poly1305 / AEAD', function() { let plain = options.plain; let ciphertext = options.ciphertext; const counter = options.counter; - let chacha, plainenc; key = Buffer.from(key, 'hex'); nonce = Buffer.from(nonce, 'hex'); plain = Buffer.from(plain, 'hex'); ciphertext = Buffer.from(ciphertext, 'hex'); - chacha = new ChaCha20(); + let chacha = new ChaCha20(); chacha.init(key, nonce, counter); - plainenc = Buffer.from(plain); + const plainenc = Buffer.from(plain); chacha.encrypt(plainenc); assert.deepEqual(plainenc, ciphertext); @@ -39,7 +38,6 @@ describe('ChaCha20 / Poly1305 / AEAD', function() { let pk = options.pk; let ciphertext = options.ciphertext; let tag = options.tag; - let aead, plainenc; plain = Buffer.from(plain, 'hex'); aad = Buffer.from(aad, 'hex'); @@ -49,12 +47,12 @@ describe('ChaCha20 / Poly1305 / AEAD', function() { ciphertext = Buffer.from(ciphertext, 'hex'); tag = Buffer.from(tag, 'hex'); - aead = new AEAD(); + let aead = new AEAD(); aead.init(key, nonce); assert.equal(aead.chacha20.getCounter(), 1); assert.deepEqual(aead.polyKey, pk); aead.aad(aad); - plainenc = Buffer.from(plain); + const plainenc = Buffer.from(plain); aead.encrypt(plainenc); assert.deepEqual(plainenc, ciphertext); assert.deepEqual(aead.finish(), tag); @@ -162,16 +160,14 @@ describe('ChaCha20 / Poly1305 / AEAD', function() { const expected = Buffer.from('ddb9da7ddd5e52792730ed5cda5f90a4', 'hex'); const key = Buffer.allocUnsafe(32); const msg = Buffer.allocUnsafe(73); - let mac; - let i; - for (i = 0; i < key.length; i++) + for (let i = 0; i < key.length; i++) key[i] = i + 221; - for (i = 0; i < msg.length; i++) + for (let i = 0; i < msg.length; i++) msg[i] = i + 121; - mac = Poly1305.auth(msg, key); + const mac = Poly1305.auth(msg, key); assert(Poly1305.verify(mac, expected)); assert.deepEqual(mac, expected); }); @@ -180,13 +176,12 @@ describe('ChaCha20 / Poly1305 / AEAD', function() { let key = '85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b'; let msg = 'Cryptographic Forum Research Group'; let tag = 'a8061dc1305136c6c22b8baf0c0127a9'; - let mac; key = Buffer.from(key, 'hex'); msg = Buffer.from(msg, 'ascii'); tag = Buffer.from(tag, 'hex'); - mac = Poly1305.auth(msg, key); + const mac = Poly1305.auth(msg, key); assert(Poly1305.verify(mac, tag)); }); diff --git a/test/chain-test.js b/test/chain-test.js index 27a41f09..d1903d40 100644 --- a/test/chain-test.js +++ b/test/chain-test.js @@ -49,9 +49,7 @@ describe('Chain', function() { async function mineCSV(tx) { const job = await cpu.createJob(); - let rtx; - - rtx = new MTX(); + const rtx = new MTX(); rtx.addOutput({ script: [ @@ -92,10 +90,8 @@ describe('Chain', function() { }); it('should mine 200 blocks', async () => { - let i, block; - - for (i = 0; i < 200; i++) { - block = await cpu.mineBlock(); + for (let i = 0; i < 200; i++) { + const block = await cpu.mineBlock(); assert(block); assert(await chain.add(block)); } @@ -104,13 +100,11 @@ describe('Chain', function() { }); it('should mine competing chains', async () => { - let i, mtx, job1, job2, blk1, blk2, hash1, hash2; + for (let i = 0; i < 10; i++) { + const job1 = await cpu.createJob(tip1); + const job2 = await cpu.createJob(tip2); - for (i = 0; i < 10; i++) { - job1 = await cpu.createJob(tip1); - job2 = await cpu.createJob(tip2); - - mtx = await wallet.create({ + const mtx = await wallet.create({ outputs: [{ address: wallet.getAddress(), value: 10 * 1e8 @@ -123,11 +117,11 @@ describe('Chain', function() { job1.refresh(); job2.refresh(); - blk1 = await job1.mineAsync(); - blk2 = await job2.mineAsync(); + const blk1 = await job1.mineAsync(); + const blk2 = await job2.mineAsync(); - hash1 = blk1.hash('hex'); - hash2 = blk2.hash('hex'); + const hash1 = blk1.hash('hex'); + const hash2 = blk2.hash('hex'); assert(await chain.add(blk1)); assert(await chain.add(blk2)); @@ -156,15 +150,14 @@ describe('Chain', function() { it('should handle a reorg', async () => { let forked = false; - let entry, block; assert.equal(chain.height, 210); - entry = await chain.db.getEntry(tip2.hash); + const entry = await chain.db.getEntry(tip2.hash); assert(entry); assert(chain.height === entry.height); - block = await cpu.mineBlock(entry); + const block = await cpu.mineBlock(entry); assert(block); chain.once('reorganize', () => { @@ -195,25 +188,23 @@ describe('Chain', function() { it('should mine a block after a reorg', async () => { const block = await cpu.mineBlock(); - let hash, entry, result; assert(await chain.add(block)); - hash = block.hash('hex'); - entry = await chain.db.getEntry(hash); + const hash = block.hash('hex'); + const entry = await chain.db.getEntry(hash); assert(entry); assert(chain.tip.hash === entry.hash); - result = await entry.isMainChain(); + const result = await entry.isMainChain(); assert(result); }); it('should prevent double spend on new chain', async () => { let job = await cpu.createJob(); - let mtx, block; - mtx = await wallet.create({ + const mtx = await wallet.create({ outputs: [{ address: wallet.getAddress(), value: 10 * 1e8 @@ -223,7 +214,7 @@ describe('Chain', function() { job.addTX(mtx.toTX(), mtx.view); job.refresh(); - block = await job.mineAsync(); + const block = await job.mineAsync(); assert(await chain.add(block)); @@ -242,14 +233,13 @@ describe('Chain', function() { const block = await chain.db.getBlock(tip1.hash); const cb = block.txs[0]; const mtx = new MTX(); - let job; mtx.addTX(cb, 0); mtx.addOutput(wallet.getAddress(), 10 * 1e8); wallet.sign(mtx); - job = await cpu.createJob(); + const job = await cpu.createJob(); job.addTX(mtx.toTX(), mtx.view); job.refresh(); @@ -263,9 +253,7 @@ describe('Chain', function() { }); it('should get coin', async () => { - let mtx, job, block, tx, output, coin; - - mtx = await wallet.send({ + const mtx = await wallet.send({ outputs: [ { address: wallet.getAddress(), @@ -282,17 +270,17 @@ describe('Chain', function() { ] }); - job = await cpu.createJob(); + const job = await cpu.createJob(); job.addTX(mtx.toTX(), mtx.view); job.refresh(); - block = await job.mineAsync(); + const block = await job.mineAsync(); assert(await chain.add(block)); - tx = block.txs[1]; - output = Coin.fromTX(tx, 2, chain.height); + const tx = block.txs[1]; + const output = Coin.fromTX(tx, 2, chain.height); - coin = await chain.db.getCoin(tx.hash('hex'), 2); + const coin = await chain.db.getCoin(tx.hash('hex'), 2); assert.deepEqual(coin.toRaw(), output.toRaw()); }); @@ -321,9 +309,8 @@ describe('Chain', function() { it('should rescan for transactions', async () => { let total = 0; - await chain.db.scan(0, wallet.filter, (block, txs) => { + await chain.db.scan(0, wallet.filter, async (block, txs) => { total += txs.length; - return Promise.resolve(); }); assert.equal(total, 226); @@ -331,35 +318,37 @@ describe('Chain', function() { it('should activate csv', async () => { const deployments = network.deployments; - let i, block, prev, state, cache; miner.options.version = -1; assert.equal(chain.height, 214); - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert.equal(state, 1); - for (i = 0; i < 417; i++) { - block = await cpu.mineBlock(); + for (let i = 0; i < 417; i++) { + const block = await cpu.mineBlock(); assert(await chain.add(block)); switch (chain.height) { - case 288: - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + case 288: { + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert.equal(state, 1); break; - case 432: - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + } + case 432: { + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert.equal(state, 2); break; - case 576: - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + } + case 576: { + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert.equal(state, 3); break; + } } } @@ -367,7 +356,7 @@ describe('Chain', function() { assert(chain.state.hasCSV()); assert(chain.state.hasWitness()); - cache = await chain.db.getStateCache(); + const cache = await chain.db.getStateCache(); assert.deepEqual(cache, chain.db.stateCache); assert.equal(chain.db.stateCache.updates.length, 0); assert(await chain.db.verifyDeployments()); @@ -383,13 +372,12 @@ describe('Chain', function() { it('should test csv', async () => { const tx = (await chain.db.getBlock(chain.height - 100)).txs[0]; let block = await mineCSV(tx); - let csv, job, rtx; assert(await chain.add(block)); - csv = block.txs[1]; + const csv = block.txs[1]; - rtx = new MTX(); + const rtx = new MTX(); rtx.addOutput({ script: [ @@ -402,7 +390,7 @@ describe('Chain', function() { rtx.addTX(csv, 0); rtx.setSequence(0, 1, false); - job = await cpu.createJob(); + const job = await cpu.createJob(); job.addTX(rtx.toTX(), rtx.view); job.refresh(); @@ -415,7 +403,6 @@ describe('Chain', function() { it('should fail csv with bad sequence', async () => { const csv = (await chain.db.getBlock(chain.height - 100)).txs[0]; const rtx = new MTX(); - let job; rtx.addOutput({ script: [ @@ -428,7 +415,7 @@ describe('Chain', function() { rtx.addTX(csv, 0); rtx.setSequence(0, 1, false); - job = await cpu.createJob(); + const job = await cpu.createJob(); job.addTX(rtx.toTX(), rtx.view); job.refresh(); @@ -444,13 +431,12 @@ describe('Chain', function() { it('should fail csv lock checks', async () => { const tx = (await chain.db.getBlock(chain.height - 100)).txs[0]; const block = await mineCSV(tx); - let csv, job, rtx; assert(await chain.add(block)); - csv = block.txs[1]; + const csv = block.txs[1]; - rtx = new MTX(); + const rtx = new MTX(); rtx.addOutput({ script: [ @@ -463,7 +449,7 @@ describe('Chain', function() { rtx.addTX(csv, 0); rtx.setSequence(0, 2, false); - job = await cpu.createJob(); + const job = await cpu.createJob(); job.addTX(rtx.toTX(), rtx.view); job.refresh(); @@ -542,11 +528,10 @@ describe('Chain', function() { const block = await cpu.mineBlock(); const tx = block.txs[0]; const output = tx.outputs[1]; - let commit; assert(output.script.isCommitment()); - commit = Buffer.from(output.script.get(1)); + const commit = Buffer.from(output.script.get(1)); commit.fill(0, 10); output.script.set(1, commit); output.script.compile(); @@ -580,10 +565,8 @@ describe('Chain', function() { }); it('should mine 2000 witness blocks', async () => { - let i, block; - - for (i = 0; i < 2001; i++) { - block = await cpu.mineBlock(); + for (let i = 0; i < 2001; i++) { + const block = await cpu.mineBlock(); assert(block); assert(await chain.add(block)); } @@ -595,14 +578,13 @@ describe('Chain', function() { let block = await chain.db.getBlock(chain.height - 2000); const cb = block.txs[0]; const mtx = new MTX(); - let job; mtx.addTX(cb, 0); mtx.addOutput(wwallet.getAddress(), 1000); wwallet.sign(mtx); - job = await cpu.createJob(); + const job = await cpu.createJob(); job.addTX(mtx.toTX(), mtx.view); job.refresh(); @@ -615,17 +597,15 @@ describe('Chain', function() { const start = chain.height - 2000; const end = chain.height - 200; const job = await cpu.createJob(); - let mtx = new MTX(); - let i, j, block, cb; - for (i = start; i <= end; i++) { - block = await chain.db.getBlock(i); - cb = block.txs[0]; + for (let i = start; i <= end; i++) { + const block = await chain.db.getBlock(i); + const cb = block.txs[0]; - mtx = new MTX(); + const mtx = new MTX(); mtx.addTX(cb, 0); - for (j = 0; j < 16; j++) + for (let j = 0; j < 16; j++) mtx.addOutput(wwallet.getAddress(), 1); wwallet.sign(mtx); @@ -642,17 +622,15 @@ describe('Chain', function() { const start = chain.height - 2000; const end = chain.height - 200; const job = await cpu.createJob(); - let mtx = new MTX(); - let i, j, block, cb; - for (i = start; i <= end; i++) { - block = await chain.db.getBlock(i); - cb = block.txs[0]; + for (let i = start; i <= end; i++) { + const block = await chain.db.getBlock(i); + const cb = block.txs[0]; - mtx = new MTX(); + const mtx = new MTX(); mtx.addTX(cb, 0); - for (j = 0; j < 20; j++) + for (let j = 0; j < 20; j++) mtx.addOutput(wwallet.getAddress(), 1); wwallet.sign(mtx); @@ -669,17 +647,15 @@ describe('Chain', function() { const start = chain.height - 2000; const end = chain.height - 200; const job = await cpu.createJob(); - let mtx = new MTX(); - let i, j, block, cb; - for (i = start; i <= end; i++) { - block = await chain.db.getBlock(i); - cb = block.txs[0]; + for (let i = start; i <= end; i++) { + const block = await chain.db.getBlock(i); + const cb = block.txs[0]; - mtx = new MTX(); + const mtx = new MTX(); mtx.addTX(cb, 0); - for (j = 0; j < 15; j++) + for (let j = 0; j < 15; j++) mtx.addOutput(wwallet.getAddress(), 1); wwallet.sign(mtx); @@ -693,10 +669,8 @@ describe('Chain', function() { }); it('should fail to connect bad versions', async () => { - let i, job; - - for (i = 0; i <= 3; i++) { - job = await cpu.createJob(); + for (let i = 0; i <= 3; i++) { + const job = await cpu.createJob(); job.attempt.version = i; assert.equal(await mineBlock(job), 'bad-version'); } @@ -768,12 +742,11 @@ describe('Chain', function() { it('should mine 111 multisig blocks', async () => { const flags = common.flags.DEFAULT_FLAGS & ~common.flags.VERIFY_POW; - let i, j, script, cb, output, val, block; - script = new Script(); + let script = new Script(); script.push(new BN(20)); - for (i = 0; i < 20; i++) + for (let i = 0; i < 20; i++) script.push(encoding.ZERO_KEY); script.push(new BN(20)); @@ -782,15 +755,15 @@ describe('Chain', function() { script = Script.fromScripthash(script.hash160()); - for (i = 0; i < 111; i++) { - block = await cpu.mineBlock(); - cb = block.txs[0]; - val = cb.outputs[0].value; + for (let i = 0; i < 111; i++) { + const block = await cpu.mineBlock(); + const cb = block.txs[0]; + const val = cb.outputs[0].value; cb.outputs[0].value = 0; - for (j = 0; j < Math.min(100, val); j++) { - output = new Output(); + for (let j = 0; j < Math.min(100, val); j++) { + const output = new Output(); output.script = script.clone(); output.value = 1; @@ -810,28 +783,27 @@ describe('Chain', function() { const start = chain.height - 110; const end = chain.height - 100; const job = await cpu.createJob(); - let i, j, mtx, script, block, cb; - script = new Script(); + const script = new Script(); script.push(new BN(20)); - for (i = 0; i < 20; i++) + for (let i = 0; i < 20; i++) script.push(encoding.ZERO_KEY); script.push(new BN(20)); script.push(opcodes.OP_CHECKMULTISIG); script.compile(); - for (i = start; i <= end; i++) { - block = await chain.db.getBlock(i); - cb = block.txs[0]; + for (let i = start; i <= end; i++) { + const block = await chain.db.getBlock(i); + const cb = block.txs[0]; if (cb.outputs.length === 2) continue; - mtx = new MTX(); + const mtx = new MTX(); - for (j = 2; j < cb.outputs.length; j++) { + for (let j = 2; j < cb.outputs.length; j++) { mtx.addTX(cb, j); mtx.inputs[j - 2].script = new Script([script.toRaw()]); } diff --git a/test/coins-test.js b/test/coins-test.js index 0d74fca0..6409813f 100644 --- a/test/coins-test.js +++ b/test/coins-test.js @@ -33,14 +33,13 @@ describe('Coins', function() { const view = new CoinView(); const prevout = new Outpoint(hash, 0); const input = Input.fromOutpoint(prevout); - let coins, entry, output; view.addTX(tx1, 1); - coins = view.get(hash); + const coins = view.get(hash); assert.equal(coins.outputs.size, tx1.outputs.length); - entry = coins.get(0); + const entry = coins.get(0); assert(entry); assert(!entry.spent); @@ -51,7 +50,7 @@ describe('Coins', function() { assert(entry.output instanceof Output); assert.equal(entry.spent, false); - output = view.getOutputFor(input); + const output = view.getOutputFor(input); assert(output); deepCoinsEqual(entry, reserialize(entry)); @@ -60,20 +59,19 @@ describe('Coins', function() { it('should spend an output', () => { const hash = tx1.hash('hex'); const view = new CoinView(); - let coins, entry, length; view.addTX(tx1, 1); - coins = view.get(hash); + let coins = view.get(hash); assert(coins); - length = coins.outputs.size; + const length = coins.outputs.size; view.spendEntry(new Outpoint(hash, 0)); coins = view.get(hash); assert(coins); - entry = coins.get(0); + const entry = coins.get(0); assert(entry); assert(entry.spent); @@ -85,22 +83,20 @@ describe('Coins', function() { it('should handle coin view', () => { const view = new CoinView(); - let i, tx, size, bw, br; - let raw, res, prev, coins; - for (i = 1; i < data.txs.length; i++) { - tx = data.txs[i]; + for (let i = 1; i < data.txs.length; i++) { + const tx = data.txs[i]; view.addTX(tx, 1); } - size = view.getSize(tx1); - bw = new StaticWriter(size); - raw = view.toWriter(bw, tx1).render(); - br = new BufferReader(raw); - res = CoinView.fromReader(br, tx1); + const size = view.getSize(tx1); + const bw = new StaticWriter(size); + const raw = view.toWriter(bw, tx1).render(); + const br = new BufferReader(raw); + const res = CoinView.fromReader(br, tx1); - prev = tx1.inputs[0].prevout; - coins = res.get(prev.hash); + const prev = tx1.inputs[0].prevout; + const coins = res.get(prev.hash); assert.strictEqual(coins.outputs.size, 1); assert.strictEqual(coins.get(0), null); diff --git a/test/gcs-test.js b/test/gcs-test.js index ee408f74..3dcd083d 100644 --- a/test/gcs-test.js +++ b/test/gcs-test.js @@ -15,11 +15,8 @@ describe('GCS', function() { const key = random.randomBytes(16); const P = 20; let filter1, filter2, filter3, filter4, filter5; - let contents1, contents2; - let op1, op2, op3, op4; - let addr1, addr2; - contents1 = [ + const contents1 = [ Buffer.from('Alex', 'ascii'), Buffer.from('Bob', 'ascii'), Buffer.from('Charlie', 'ascii'), @@ -39,7 +36,7 @@ describe('GCS', function() { Buffer.from('Quentin', 'ascii') ]; - contents2 = [ + const contents2 = [ Buffer.from('Alice', 'ascii'), Buffer.from('Betty', 'ascii'), Buffer.from('Charmaine', 'ascii'), @@ -59,24 +56,24 @@ describe('GCS', function() { Buffer.from('Queenie', 'ascii') ]; - op1 = new Outpoint( + const op1 = new Outpoint( '4cba1d1753ed19dbeafffb1a6c805d20e4af00b194a8f85353163cef83319c2c', 4); - op2 = new Outpoint( + const op2 = new Outpoint( 'b7c3c4bce1a23baef2da05f9b7e4bff813449ec7e80f980ec7e4cacfadcd3314', 3); - op3 = new Outpoint( + const op3 = new Outpoint( '4cba1d1753ed19dbeafffb1a6c805d20e4af00b194a8f85353163cef83319c2c', 400); - op4 = new Outpoint( + const op4 = new Outpoint( 'b7c3c4bce1a23baef2da05f9b7e4bff813449ec7e80f980ec7e4cacfadcd3314', 300); - addr1 = new Address('bc1qmyrddmxglk49ye2wd29wefaavw7es8k5d555lx'); - addr2 = new Address('bc1q4645ycu0l9pnvxaxnhemushv0w4cd9flkqh95j'); + const addr1 = new Address('bc1qmyrddmxglk49ye2wd29wefaavw7es8k5d555lx'); + const addr2 = new Address('bc1q4645ycu0l9pnvxaxnhemushv0w4cd9flkqh95j'); it('should test GCS filter build', () => { filter1 = GCSFilter.fromItems(P, key, contents1); @@ -132,14 +129,12 @@ describe('GCS', function() { }); it('should test GCS filter matchAny', () => { - let c, match; - - match = filter1.matchAny(key, contents2); + let match = filter1.matchAny(key, contents2); assert(!match); match = filter2.matchAny(key, contents2); assert(!match); - c = contents2.slice(); + const c = contents2.slice(); c.push(Buffer.from('Nate')); match = filter1.matchAny(key, c); diff --git a/test/hd-test.js b/test/hd-test.js index 22ee3a0d..ba1d87df 100644 --- a/test/hd-test.js +++ b/test/hd-test.js @@ -68,12 +68,11 @@ describe('HD', function() { it('should derive correctly when private key has leading zeros', () => { const key = HD.PrivateKey.fromBase58(vectors.zero_priv); - let child; assert.equal(key.privateKey.toString('hex'), '00000055378cf5fafb56c711c674143f9b0ee82ab0ba2924f19b64f5ae7cdbfd'); - child = key.derivePath('m/44\'/0\'/0\'/0/0\''); + const child = key.derivePath('m/44\'/0\'/0\'/0/0\''); assert.equal(child.privateKey.toString('hex'), '3348069561d2a0fb925e74bf198762acc47dce7db27372257d2d959a9e6f8aeb'); }); diff --git a/test/http-test.js b/test/http-test.js index f0237c86..89b7b267 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -13,9 +13,9 @@ const FullNode = require('../lib/node/fullnode'); const pkg = require('../lib/pkg'); describe('HTTP', function() { - let node, wallet, wdb, addr, hash; + let addr, hash; - node = new FullNode({ + const node = new FullNode({ network: 'regtest', apiKey: 'foo', walletAuth: true, @@ -23,12 +23,12 @@ describe('HTTP', function() { plugins: [require('../lib/wallet/plugin')] }); - wallet = new HTTP.Wallet({ + const wallet = new HTTP.Wallet({ network: 'regtest', apiKey: 'foo' }); - wdb = node.require('walletdb'); + const wdb = node.require('walletdb'); this.timeout(15000); @@ -105,9 +105,8 @@ describe('HTTP', function() { it('should send a tx', async () => { let value = 0; - let options, tx; - options = { + const options = { rate: 10000, outputs: [{ value: 10000, @@ -115,7 +114,7 @@ describe('HTTP', function() { }] }; - tx = await wallet.send(options); + const tx = await wallet.send(options); assert(tx); assert.equal(tx.inputs.length, 1); diff --git a/test/mempool-test.js b/test/mempool-test.js index 83cdb0dd..f3fcefb5 100644 --- a/test/mempool-test.js +++ b/test/mempool-test.js @@ -24,23 +24,21 @@ describe('Mempool', function() { this.timeout(5000); function dummy(prev, prevHash) { - let fund, coin, entry; - if (!prevHash) prevHash = encoding.ONE_HASH.toString('hex'); - coin = new Coin(); + const coin = new Coin(); coin.height = 0; coin.value = 0; coin.script = prev; coin.hash = prevHash; coin.index = 0; - fund = new MTX(); + const fund = new MTX(); fund.addCoin(coin); fund.addOutput(prev, 70000); - entry = MempoolEntry.fromTX(fund.toTX(), fund.view, 0); + const entry = MempoolEntry.fromTX(fund.toTX(), fund.view, 0); mempool.trackEntry(entry, fund.view); @@ -55,22 +53,21 @@ describe('Mempool', function() { it('should handle incoming orphans and TXs', async () => { const kp = KeyRing.generate(); const w = wallet; - let t1, t2, t3, t4, f1, fake, prev, sig, balance, txs; - t1 = new MTX(); + let t1 = new MTX(); t1.addOutput(w.getAddress(), 50000); t1.addOutput(w.getAddress(), 10000); - prev = Script.fromPubkey(kp.publicKey); + const prev = Script.fromPubkey(kp.publicKey); t1.addCoin(dummy(prev)); - sig = t1.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); + const sig = t1.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); t1.inputs[0].script = new Script([sig]); // balance: 51000 w.sign(t1); t1 = t1.toTX(); - t2 = new MTX(); + let t2 = new MTX(); t2.addTX(t1, 0); // 50000 t2.addOutput(w.getAddress(), 20000); t2.addOutput(w.getAddress(), 20000); @@ -79,7 +76,7 @@ describe('Mempool', function() { w.sign(t2); t2 = t2.toTX(); - t3 = new MTX(); + let t3 = new MTX(); t3.addTX(t1, 1); // 10000 t3.addTX(t2, 0); // 20000 t3.addOutput(w.getAddress(), 23000); @@ -88,7 +85,7 @@ describe('Mempool', function() { w.sign(t3); t3 = t3.toTX(); - t4 = new MTX(); + let t4 = new MTX(); t4.addTX(t2, 1); // 24000 t4.addTX(t3, 0); // 23000 t4.addOutput(w.getAddress(), 11000); @@ -98,7 +95,7 @@ describe('Mempool', function() { w.sign(t4); t4 = t4.toTX(); - f1 = new MTX(); + let f1 = new MTX(); f1.addTX(t4, 1); // 11000 f1.addOutput(new Address(), 9000); @@ -106,7 +103,7 @@ describe('Mempool', function() { w.sign(f1); f1 = f1.toTX(); - fake = new MTX(); + let fake = new MTX(); fake.addTX(t1, 1); // 1000 (already redeemed) fake.addOutput(w.getAddress(), 6000); // 6000 instead of 500 @@ -122,7 +119,7 @@ describe('Mempool', function() { await mempool.addTX(fake); await mempool.addTX(t4); - balance = mempool.getBalance(); + let balance = mempool.getBalance(); assert.equal(balance, 70000); // note: funding balance await mempool.addTX(t1); @@ -145,7 +142,7 @@ describe('Mempool', function() { balance = mempool.getBalance(); assert.equal(balance, 20000); - txs = mempool.getHistory(); + const txs = mempool.getHistory(); assert(txs.some((tx) => { return tx.hash('hex') === f1.hash('hex'); })); @@ -154,21 +151,20 @@ describe('Mempool', function() { it('should handle locktime', async () => { const w = wallet; const kp = KeyRing.generate(); - let tx, prev, prevHash, sig; - tx = new MTX(); + let tx = new MTX(); tx.addOutput(w.getAddress(), 50000); tx.addOutput(w.getAddress(), 10000); - prev = Script.fromPubkey(kp.publicKey); - prevHash = random.randomBytes(32).toString('hex'); + const prev = Script.fromPubkey(kp.publicKey); + const prevHash = random.randomBytes(32).toString('hex'); tx.addCoin(dummy(prev, prevHash)); tx.setLocktime(200); chain.tip.height = 200; - sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); + const sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); tx.inputs[0].script = new Script([sig]); tx = tx.toTX(); @@ -180,23 +176,23 @@ describe('Mempool', function() { it('should handle invalid locktime', async () => { const w = wallet; const kp = KeyRing.generate(); - let tx, prev, prevHash, sig, err; - tx = new MTX(); + let tx = new MTX(); tx.addOutput(w.getAddress(), 50000); tx.addOutput(w.getAddress(), 10000); - prev = Script.fromPubkey(kp.publicKey); - prevHash = random.randomBytes(32).toString('hex'); + const prev = Script.fromPubkey(kp.publicKey); + const prevHash = random.randomBytes(32).toString('hex'); tx.addCoin(dummy(prev, prevHash)); tx.setLocktime(200); chain.tip.height = 200 - 1; - sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); + const sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); tx.inputs[0].script = new Script([sig]); tx = tx.toTX(); + let err; try { await mempool.addTX(tx); } catch (e) { @@ -211,27 +207,27 @@ describe('Mempool', function() { it('should not cache a malleated wtx with mutated sig', async () => { const w = wallet; const kp = KeyRing.generate(); - let tx, prev, prevHash, prevs, sig, err; kp.witness = true; - tx = new MTX(); + let tx = new MTX(); tx.addOutput(w.getAddress(), 50000); tx.addOutput(w.getAddress(), 10000); - prev = Script.fromProgram(0, kp.getKeyHash()); - prevHash = random.randomBytes(32).toString('hex'); + const prev = Script.fromProgram(0, kp.getKeyHash()); + const prevHash = random.randomBytes(32).toString('hex'); tx.addCoin(dummy(prev, prevHash)); - prevs = Script.fromPubkeyhash(kp.getKeyHash()); + const prevs = Script.fromPubkeyhash(kp.getKeyHash()); - sig = tx.signature(0, prevs, 70000, kp.privateKey, Script.hashType.ALL, 1); + const sig = tx.signature(0, prevs, 70000, kp.privateKey, Script.hashType.ALL, 1); sig[sig.length - 1] = 0; tx.inputs[0].witness = new Witness([sig, kp.publicKey]); tx = tx.toTX(); + let err; try { await mempool.addTX(tx); } catch (e) { @@ -245,22 +241,22 @@ describe('Mempool', function() { it('should not cache a malleated tx with unnecessary witness', async () => { const w = wallet; const kp = KeyRing.generate(); - let tx, prev, prevHash, sig, err; - tx = new MTX(); + let tx = new MTX(); tx.addOutput(w.getAddress(), 50000); tx.addOutput(w.getAddress(), 10000); - prev = Script.fromPubkey(kp.publicKey); - prevHash = random.randomBytes(32).toString('hex'); + const prev = Script.fromPubkey(kp.publicKey); + const prevHash = random.randomBytes(32).toString('hex'); tx.addCoin(dummy(prev, prevHash)); - sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); + const sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0); tx.inputs[0].script = new Script([sig]); tx.inputs[0].witness.push(Buffer.alloc(0)); tx = tx.toTX(); + let err; try { await mempool.addTX(tx); } catch (e) { @@ -274,21 +270,21 @@ describe('Mempool', function() { it('should not cache a malleated wtx with wit removed', async () => { const w = wallet; const kp = KeyRing.generate(); - let tx, prev, prevHash, err; kp.witness = true; - tx = new MTX(); + let tx = new MTX(); tx.addOutput(w.getAddress(), 50000); tx.addOutput(w.getAddress(), 10000); - prev = Script.fromProgram(0, kp.getKeyHash()); - prevHash = random.randomBytes(32).toString('hex'); + const prev = Script.fromProgram(0, kp.getKeyHash()); + const prevHash = random.randomBytes(32).toString('hex'); tx.addCoin(dummy(prev, prevHash)); tx = tx.toTX(); + let err; try { await mempool.addTX(tx); } catch (e) { @@ -303,19 +299,19 @@ describe('Mempool', function() { it('should cache non-malleated tx without sig', async () => { const w = wallet; const kp = KeyRing.generate(); - let tx, prev, prevHash, err; - tx = new MTX(); + let tx = new MTX(); tx.addOutput(w.getAddress(), 50000); tx.addOutput(w.getAddress(), 10000); - prev = Script.fromPubkey(kp.publicKey); - prevHash = random.randomBytes(32).toString('hex'); + const prev = Script.fromPubkey(kp.publicKey); + const prevHash = random.randomBytes(32).toString('hex'); tx.addCoin(dummy(prev, prevHash)); tx = tx.toTX(); + let err; try { await mempool.addTX(tx); } catch (e) { @@ -330,9 +326,8 @@ describe('Mempool', function() { it('should clear reject cache', async () => { const w = wallet; - let tx; - tx = new MTX(); + let tx = new MTX(); tx.addOutpoint(new Outpoint()); tx.addOutput(w.getAddress(), 50000); tx = tx.toTX(); diff --git a/test/mnemonic-test.js b/test/mnemonic-test.js index f9cc1243..4c606b60 100644 --- a/test/mnemonic-test.js +++ b/test/mnemonic-test.js @@ -13,9 +13,7 @@ describe('Mnemonic', function() { const seed = Buffer.from(data[2], 'hex'); const xpriv = data[3]; it(`should create an english mnemonic (${i})`, () => { - let mnemonic, key; - - mnemonic = new HD.Mnemonic({ + const mnemonic = new HD.Mnemonic({ language: 'english', entropy: entropy, passphrase: 'TREZOR' @@ -24,7 +22,7 @@ describe('Mnemonic', function() { assert.equal(mnemonic.getPhrase(), phrase); assert.equal(mnemonic.toSeed().toString('hex'), seed.toString('hex')); - key = HD.fromMnemonic(mnemonic); + const key = HD.fromMnemonic(mnemonic); assert.equal(key.toBase58(), xpriv); }); }); @@ -36,9 +34,7 @@ describe('Mnemonic', function() { const passphrase = data.passphrase; const xpriv = data.bip32_xprv; it(`should create a japanese mnemonic (${i})`, () => { - let mnemonic, key; - - mnemonic = new HD.Mnemonic({ + const mnemonic = new HD.Mnemonic({ language: 'japanese', entropy: entropy, passphrase: passphrase @@ -47,7 +43,7 @@ describe('Mnemonic', function() { assert.equal(mnemonic.getPhrase(), phrase); assert.equal(mnemonic.toSeed().toString('hex'), seed.toString('hex')); - key = HD.fromMnemonic(mnemonic); + const key = HD.fromMnemonic(mnemonic); assert.equal(key.toBase58(), xpriv); }); }); diff --git a/test/node-test.js b/test/node-test.js index 2fddcff6..310d4cba 100644 --- a/test/node-test.js +++ b/test/node-test.js @@ -12,11 +12,10 @@ const TX = require('../lib/primitives/tx'); const Address = require('../lib/primitives/address'); describe('Node', function() { - let node, chain, wdb, miner; let wallet, tip1, tip2, cb1, cb2; let tx1, tx2; - node = new FullNode({ + const node = new FullNode({ db: 'memory', apiKey: 'foo', network: 'regtest', @@ -24,20 +23,19 @@ describe('Node', function() { plugins: [require('../lib/wallet/plugin')] }); - chain = node.chain; - miner = node.miner; - wdb = node.require('walletdb'); + const chain = node.chain; + const miner = node.miner; + const wdb = node.require('walletdb'); this.timeout(5000); async function mineBlock(tip, tx) { const job = await miner.createJob(tip); - let rtx; if (!tx) return await job.mineAsync(); - rtx = new MTX(); + const rtx = new MTX(); rtx.addTX(tx, 0); @@ -73,13 +71,11 @@ describe('Node', function() { }); it('should mine competing chains', async () => { - let i, block1, block2; - - for (i = 0; i < 10; i++) { - block1 = await mineBlock(tip1, cb1); + for (let i = 0; i < 10; i++) { + const block1 = await mineBlock(tip1, cb1); cb1 = block1.txs[0]; - block2 = await mineBlock(tip2, cb2); + const block2 = await mineBlock(tip2, cb2); cb2 = block2.txs[0]; await chain.add(block1); @@ -107,29 +103,25 @@ describe('Node', function() { }); it('should have correct balance', async () => { - let balance; - await co.timeout(100); - balance = await wallet.getBalance(); + const balance = await wallet.getBalance(); assert.equal(balance.unconfirmed, 550 * 1e8); assert.equal(balance.confirmed, 550 * 1e8); }); it('should handle a reorg', async () => { - let entry, block, forked; - assert.equal(wdb.state.height, chain.height); assert.equal(chain.height, 11); - entry = await chain.db.getEntry(tip2.hash); + const entry = await chain.db.getEntry(tip2.hash); assert(entry); assert(chain.height === entry.height); - block = await miner.mineBlock(entry); + const block = await miner.mineBlock(entry); assert(block); - forked = false; + let forked = false; chain.once('reorganize', () => { forked = true; }); @@ -148,11 +140,9 @@ describe('Node', function() { }); it('should have correct balance', async () => { - let balance; - await co.timeout(100); - balance = await wallet.getBalance(); + const balance = await wallet.getBalance(); assert.equal(balance.unconfirmed, 1100 * 1e8); assert.equal(balance.confirmed, 600 * 1e8); }); @@ -164,15 +154,14 @@ describe('Node', function() { it('should mine a block after a reorg', async () => { const block = await mineBlock(null, cb2); - let entry, result; await chain.add(block); - entry = await chain.db.getEntry(block.hash('hex')); + const entry = await chain.db.getEntry(block.hash('hex')); assert(entry); assert(chain.tip.hash === entry.hash); - result = await entry.isMainChain(); + const result = await entry.isMainChain(); assert(result); }); @@ -215,28 +204,24 @@ describe('Node', function() { }); it('should get coin', async () => { - let block, tx, output, coin; - - block = await mineBlock(); + let block = await mineBlock(); await chain.add(block); block = await mineBlock(null, block.txs[0]); await chain.add(block); - tx = block.txs[1]; - output = Coin.fromTX(tx, 1, chain.height); + const tx = block.txs[1]; + const output = Coin.fromTX(tx, 1, chain.height); - coin = await chain.db.getCoin(tx.hash('hex'), 1); + const coin = await chain.db.getCoin(tx.hash('hex'), 1); assert.deepEqual(coin.toRaw(), output.toRaw()); }); it('should get balance', async () => { - let balance, txs; - await co.timeout(100); - balance = await wallet.getBalance(); + const balance = await wallet.getBalance(); assert.equal(balance.unconfirmed, 1250 * 1e8); assert.equal(balance.confirmed, 750 * 1e8); @@ -245,7 +230,7 @@ describe('Node', function() { assert.equal(wdb.state.height, chain.height); - txs = await wallet.getHistory(); + const txs = await wallet.getHistory(); assert.equal(txs.length, 45); }); @@ -266,9 +251,8 @@ describe('Node', function() { it('should rescan for transactions', async () => { let total = 0; - await chain.db.scan(0, wdb.filter, (block, txs) => { + await chain.db.scan(0, wdb.filter, async (block, txs) => { total += txs.length; - return Promise.resolve(); }); assert.equal(total, 26); @@ -276,38 +260,40 @@ describe('Node', function() { it('should activate csv', async () => { const deployments = chain.network.deployments; - let i, block, prev, state, cache; - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert(state === 0); - for (i = 0; i < 417; i++) { - block = await miner.mineBlock(); + for (let i = 0; i < 417; i++) { + const block = await miner.mineBlock(); await chain.add(block); switch (chain.height) { - case 144: - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + case 144: { + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert(state === 1); break; - case 288: - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + } + case 288: { + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert(state === 2); break; - case 432: - prev = await chain.tip.getPrevious(); - state = await chain.getState(prev, deployments.csv); + } + case 432: { + const prev = await chain.tip.getPrevious(); + const state = await chain.getState(prev, deployments.csv); assert(state === 3); break; + } } } assert(chain.height === 432); assert(chain.state.hasCSV()); - cache = await chain.db.getStateCache(); + const cache = await chain.db.getStateCache(); assert.deepEqual(cache, chain.db.stateCache); assert.equal(chain.db.stateCache.updates.length, 0); assert(await chain.db.verifyDeployments()); @@ -315,9 +301,7 @@ describe('Node', function() { async function mineCSV(tx) { const job = await miner.createJob(); - let redeemer; - - redeemer = new MTX(); + const redeemer = new MTX(); redeemer.addOutput({ script: [ @@ -342,13 +326,12 @@ describe('Node', function() { it('should test csv', async () => { const tx = (await chain.db.getBlock(chain.height)).txs[0]; let block = await mineCSV(tx); - let csv, job, redeemer; await chain.add(block); - csv = block.txs[1]; + const csv = block.txs[1]; - redeemer = new MTX(); + const redeemer = new MTX(); redeemer.addOutput({ script: [ @@ -361,7 +344,7 @@ describe('Node', function() { redeemer.addTX(csv, 0); redeemer.setSequence(0, 1, false); - job = await miner.createJob(); + const job = await miner.createJob(); job.addTX(redeemer.toTX(), redeemer.view); job.refresh(); @@ -373,9 +356,7 @@ describe('Node', function() { it('should fail csv with bad sequence', async () => { const csv = (await chain.db.getBlock(chain.height)).txs[1]; - let block, job, redeemer, err; - - redeemer = new MTX(); + const redeemer = new MTX(); redeemer.addOutput({ script: [ @@ -388,13 +369,14 @@ describe('Node', function() { redeemer.addTX(csv, 0); redeemer.setSequence(0, 1, false); - job = await miner.createJob(); + const job = await miner.createJob(); job.addTX(redeemer.toTX(), redeemer.view); job.refresh(); - block = await job.mineAsync(); + const block = await job.mineAsync(); + let err; try { await chain.add(block); } catch (e) { @@ -414,13 +396,12 @@ describe('Node', function() { it('should fail csv lock checks', async () => { const tx = (await chain.db.getBlock(chain.height)).txs[0]; let block = await mineCSV(tx); - let csv, job, redeemer, err; await chain.add(block); - csv = block.txs[1]; + const csv = block.txs[1]; - redeemer = new MTX(); + const redeemer = new MTX(); redeemer.addOutput({ script: [ @@ -433,13 +414,14 @@ describe('Node', function() { redeemer.addTX(csv, 0); redeemer.setSequence(0, 2, false); - job = await miner.createJob(); + const job = await miner.createJob(); job.addTX(redeemer.toTX(), redeemer.view); job.refresh(); block = await job.mineAsync(); + let err; try { await chain.add(block); } catch (e) { @@ -468,9 +450,7 @@ describe('Node', function() { }); it('should get a block template', async () => { - let json; - - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'getblocktemplate', params: [ {rules: ['segwit']} @@ -518,15 +498,14 @@ describe('Node', function() { it('should send a block template proposal', async () => { const attempt = await node.miner.createBlock(); - let block, hex, json; attempt.refresh(); - block = attempt.toBlock(); + const block = attempt.toBlock(); - hex = block.toRaw().toString('hex'); + const hex = block.toRaw().toString('hex'); - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'getblocktemplate', params: [{ mode: 'proposal', @@ -541,9 +520,8 @@ describe('Node', function() { it('should submit a block', async () => { const block = await node.miner.mineBlock(); const hex = block.toRaw().toString('hex'); - let json; - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'submitblock', params: [hex] }, {}); @@ -555,11 +533,10 @@ describe('Node', function() { it('should validate an address', async () => { const addr = new Address(); - let json; addr.network = node.network; - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'validateaddress', params: [addr.toString()] }, {}); @@ -574,9 +551,7 @@ describe('Node', function() { }); it('should add transaction to mempool', async () => { - let mtx, tx, missing; - - mtx = await wallet.createTX({ + const mtx = await wallet.createTX({ rate: 100000, outputs: [{ value: 100000, @@ -589,20 +564,18 @@ describe('Node', function() { assert(mtx.isSigned()); tx1 = mtx; - tx = mtx.toTX(); + const tx = mtx.toTX(); await wallet.db.addTX(tx); - missing = await node.mempool.addTX(tx); + const missing = await node.mempool.addTX(tx); assert(!missing || missing.length === 0); assert.equal(node.mempool.map.size, 1); }); it('should add lesser transaction to mempool', async () => { - let mtx, tx, missing; - - mtx = await wallet.createTX({ + const mtx = await wallet.createTX({ rate: 1000, outputs: [{ value: 50000, @@ -615,11 +588,11 @@ describe('Node', function() { assert(mtx.isSigned()); tx2 = mtx; - tx = mtx.toTX(); + const tx = mtx.toTX(); await wallet.db.addTX(tx); - missing = await node.mempool.addTX(tx); + const missing = await node.mempool.addTX(tx); assert(!missing || missing.length === 0); assert.equal(node.mempool.map.size, 2); @@ -628,11 +601,10 @@ describe('Node', function() { it('should get a block template', async () => { let fees = 0; let weight = 0; - let i, item, json, result; node.rpc.refreshBlock(); - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'getblocktemplate', params: [ {rules: ['segwit']} @@ -643,10 +615,10 @@ describe('Node', function() { assert(!json.error); assert(json.result); - result = json.result; + const result = json.result; - for (i = 0; i < result.transactions.length; i++) { - item = result.transactions[i]; + for (let i = 0; i < result.transactions.length; i++) { + const item = result.transactions[i]; fees += item.fee; weight += item.weight; } @@ -660,23 +632,19 @@ describe('Node', function() { }); it('should get raw transaction', async () => { - let json, tx; - - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'getrawtransaction', params: [tx2.txid()], id: '1' }, {}); assert(!json.error); - tx = TX.fromRaw(json.result, 'hex'); + const tx = TX.fromRaw(json.result, 'hex'); assert.equal(tx.txid(), tx2.txid()); }); it('should prioritise transaction', async () => { - let json; - - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'prioritisetransaction', params: [tx2.txid(), 0, 10000000], id: '1' @@ -689,11 +657,10 @@ describe('Node', function() { it('should get a block template', async () => { let fees = 0; let weight = 0; - let i, item, json, result; node.rpc.refreshBlock(); - json = await node.rpc.call({ + const json = await node.rpc.call({ method: 'getblocktemplate', params: [ {rules: ['segwit']} @@ -704,10 +671,10 @@ describe('Node', function() { assert(!json.error); assert(json.result); - result = json.result; + const result = json.result; - for (i = 0; i < result.transactions.length; i++) { - item = result.transactions[i]; + for (let i = 0; i < result.transactions.length; i++) { + const item = result.transactions[i]; fees += item.fee; weight += item.weight; } diff --git a/test/protocol-test.js b/test/protocol-test.js index b70b61bc..ff3dc7c1 100644 --- a/test/protocol-test.js +++ b/test/protocol-test.js @@ -13,7 +13,7 @@ const network = Network.get('main'); describe('Protocol', function() { const pkg = require('../lib/pkg'); const agent = `/bcoin:${pkg.version}/`; - let parser, framer, v1, v2, hosts; + let parser, framer; beforeEach(() => { parser = new Parser(); @@ -32,7 +32,7 @@ describe('Protocol', function() { }); } - v1 = packets.VersionPacket.fromOptions({ + const v1 = packets.VersionPacket.fromOptions({ version: 300, services: 1, time: network.now(), @@ -51,7 +51,7 @@ describe('Protocol', function() { assert.equal(payload.noRelay, false); }); - v2 = packets.VersionPacket.fromOptions({ + const v2 = packets.VersionPacket.fromOptions({ version: 300, services: 1, time: network.now(), @@ -74,7 +74,7 @@ describe('Protocol', function() { }); /* eslint indent: 0 */ - hosts = [ + const hosts = [ new NetAddress({ services: 1, host: '127.0.0.1', @@ -106,9 +106,7 @@ describe('Protocol', function() { it('should include the raw data of only one transaction in a ' + 'parsed transaction', () => { - let tx, rawTwoTxs, rawFirstTx; - - rawTwoTxs = Buffer.from( + const rawTwoTxs = Buffer.from( '0100000004b124cca7e9686375380c845d0fd002ed704aef4472f4cc193' + 'fca4aa1b3404da400000000b400493046022100d3c9ba786488323c975f' + 'e61593df6a8041c5442736f361887abfe5c97175c72b022100ca61688f4' + @@ -160,7 +158,7 @@ describe('Protocol', function() { 'dc5c0500000017a9149eb21980dc9d413d8eac27314938b9da920ee53e8' + '700000000', 'hex'); - rawFirstTx = Buffer.from( + const rawFirstTx = Buffer.from( '0100000004b124cca7e9686375380c845d0fd002ed704aef4472f4cc193' + 'fca4aa1b3404da400000000b400493046022100d3c9ba786488323c975f' + 'e61593df6a8041c5442736f361887abfe5c97175c72b022100ca61688f4' + @@ -202,7 +200,7 @@ describe('Protocol', function() { 'de5c0500000017a9141d9ca71efa36d814424ea6ca1437e67287aebe348' + '700000000', 'hex'); - tx = TX.fromRaw(rawTwoTxs); + const tx = TX.fromRaw(rawTwoTxs); tx._raw = null; assert.deepEqual(tx.toRaw(), rawFirstTx); diff --git a/test/script-test.js b/test/script-test.js index ff051937..4a1a43ec 100644 --- a/test/script-test.js +++ b/test/script-test.js @@ -25,15 +25,13 @@ function success(res, stack) { describe('Script', function() { it('should encode/decode script', () => { - let src, decoded, dst; - - src = '20' + const src = '20' + '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' + '20' + '101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f' + 'ac'; - decoded = Script.fromRaw(src, 'hex'); + const decoded = Script.fromRaw(src, 'hex'); assert.equal(decoded.code.length, 3); assert.equal(decoded.code[0].data.toString('hex'), '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'); @@ -41,7 +39,7 @@ describe('Script', function() { '101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f'); assert.equal(decoded.code[2].value, opcodes.OP_CHECKSIG); - dst = decoded.toRaw(); + const dst = decoded.toRaw(); assert.equal(dst.toString('hex'), src); }); @@ -66,11 +64,9 @@ describe('Script', function() { }); it('should handle if statements correctly', () => { - let input, output, stack, res; + let input = new Script([opcodes.OP_1, opcodes.OP_2]); - input = new Script([opcodes.OP_1, opcodes.OP_2]); - - output = new Script([ + let output = new Script([ opcodes.OP_2, opcodes.OP_EQUAL, opcodes.OP_IF, @@ -81,11 +77,11 @@ describe('Script', function() { opcodes.OP_5 ]); - stack = new Stack(); + let stack = new Stack(); input.execute(stack); - res = output.execute(stack); + let res = output.execute(stack); assert(res); assert.deepEqual(stack.items, [[1], [3], [5]]); @@ -162,57 +158,51 @@ describe('Script', function() { }); it('should handle CScriptNums correctly', () => { - let input, output, stack; - - input = new Script([ + const input = new Script([ Buffer.from('ffffff7f', 'hex'), opcodes.OP_NEGATE, opcodes.OP_DUP, opcodes.OP_ADD ]); - output = new Script([ + const output = new Script([ Buffer.from('feffffff80', 'hex'), opcodes.OP_EQUAL ]); - stack = new Stack(); + const stack = new Stack(); assert(input.execute(stack)); assert(success(output.execute(stack), stack)); }); it('should handle CScriptNums correctly', () => { - let input, output, stack; - - input = new Script([ + const input = new Script([ opcodes.OP_11, opcodes.OP_10, opcodes.OP_1, opcodes.OP_ADD ]); - output = new Script([ + const output = new Script([ opcodes.OP_NUMNOTEQUAL, opcodes.OP_NOT ]); - stack = new Stack(); + const stack = new Stack(); assert(input.execute(stack)); assert(success(output.execute(stack), stack)); }); it('should handle OP_ROLL correctly', () => { - let input, output, stack; - - input = new Script([ + const input = new Script([ Buffer.from([0x16]), Buffer.from([0x15]), Buffer.from([0x14]) ]); - output = new Script([ + const output = new Script([ opcodes.OP_0, opcodes.OP_ROLL, Buffer.from([0x14]), @@ -222,7 +212,7 @@ describe('Script', function() { opcodes.OP_EQUAL ]); - stack = new Stack(); + const stack = new Stack(); assert(input.execute(stack)); assert(success(output.execute(stack), stack)); @@ -262,10 +252,8 @@ describe('Script', function() { [false, true].forEach((noCache) => { const suffix = noCache ? 'without cache' : 'with cache'; it(`should handle script test ${suffix}:${comments}`, () => { - let prev, tx, err, res; - // Funding transaction. - prev = new TX({ + const prev = new TX({ version: 1, flag: 1, inputs: [{ @@ -285,7 +273,7 @@ describe('Script', function() { }); // Spending transaction. - tx = new TX({ + const tx = new TX({ version: 1, flag: 1, inputs: [{ @@ -309,6 +297,8 @@ describe('Script', function() { tx.refresh(); } + let err; + let res; try { res = Script.verify(input, witness, output, tx, 0, amount, flags); } catch (e) { diff --git a/test/scrypt-test.js b/test/scrypt-test.js index e8a1e6ad..c50bd536 100644 --- a/test/scrypt-test.js +++ b/test/scrypt-test.js @@ -4,6 +4,8 @@ const assert = require('assert'); const scrypt = require('../lib/crypto/scrypt'); describe('Scrypt', function() { + this.timeout(20000); + it('should perform scrypt with N=16', () => { const pass = Buffer.from(''); const salt = Buffer.from(''); diff --git a/test/tx-test.js b/test/tx-test.js index 886b8dc6..42e199a9 100644 --- a/test/tx-test.js +++ b/test/tx-test.js @@ -42,7 +42,6 @@ function parseTest(data) { let [coins, tx, names] = data; const view = new CoinView(); let flags = 0; - let coin; if (!names) names = ''; @@ -64,7 +63,7 @@ function parseTest(data) { if (index === -1) continue; - coin = new Coin({ + const coin = new Coin({ version: 1, height: -1, coinbase: false, @@ -77,7 +76,7 @@ function parseTest(data) { view.addCoin(coin); } - coin = view.getOutputFor(tx.inputs[0]); + const coin = view.getOutputFor(tx.inputs[0]); return { tx: tx, @@ -92,14 +91,13 @@ function parseTest(data) { function sigopContext(scriptSig, witness, scriptPubkey) { const view = new CoinView(); - let input, output, fund, spend; - input = new Input(); - output = new Output(); + let input = new Input(); + let output = new Output(); output.value = 1; output.script = scriptPubkey; - fund = new TX(); + const fund = new TX(); fund.version = 1; fund.inputs.push(input); fund.outputs.push(output); @@ -114,7 +112,7 @@ function sigopContext(scriptSig, witness, scriptPubkey) { output = new Output(); output.value = 1; - spend = new TX(); + const spend = new TX(); spend.version = 1; spend.inputs.push(input); spend.outputs.push(output); @@ -216,8 +214,6 @@ describe('TX', function() { }); it(`should parse witness tx properly ${suffix}`, () => { - let raw1, raw2, wtx2; - clearCache(wtx.tx, noCache); assert.equal(wtx.tx.inputs.length, 5); @@ -230,13 +226,13 @@ describe('TX', function() { assert.equal(wtx.tx.getVirtualSize(), 61813); assert.equal(wtx.tx.getWeight(), 247250); - raw1 = wtx.tx.toRaw(); + const raw1 = wtx.tx.toRaw(); clearCache(wtx.tx, true); - raw2 = wtx.tx.toRaw(); + const raw2 = wtx.tx.toRaw(); assert.deepEqual(raw1, raw2); - wtx2 = TX.fromRaw(raw2); + const wtx2 = TX.fromRaw(raw2); clearCache(wtx2, noCache); assert.equal(wtx.tx.hash('hex'), wtx2.hash('hex')); @@ -248,24 +244,22 @@ describe('TX', function() { let comment = ''; arr.forEach((json, i) => { - let data, tx, view, flags, comments; - if (json.length === 1) { comment += ' ' + json[0]; return; } - data = parseTest(json); + const data = parseTest(json); if (!data) { comment = ''; return; } - tx = data.tx; - view = data.view; - flags = data.flags; - comments = comment.trim(); + const tx = data.tx; + const view = data.view; + const flags = data.flags; + let comments = comment.trim(); if (!comments) comments = data.comments; @@ -318,15 +312,15 @@ describe('TX', function() { sighash.forEach((data) => { let [tx, script, index, type, hash] = data; - let expected, hex; if (data.length === 1) return; tx = TX.fromRaw(tx, 'hex'); script = Script.fromRaw(script, 'hex'); - expected = util.revHex(hash); - hex = type & 3; + + const expected = util.revHex(hash); + let hex = type & 3; if (type & 0x80) hex |= 0x80; @@ -507,9 +501,8 @@ describe('TX', function() { it('should fail to parse >53 bit values', () => { const view = new CoinView(); - let tx, raw; - tx = new TX({ + const tx = new TX({ version: 1, flag: 1, inputs: [ @@ -522,7 +515,7 @@ describe('TX', function() { locktime: 0 }); - raw = tx.toRaw(); + let raw = tx.toRaw(); assert(encoding.readU64(raw, 47) === 0xdeadbeef); raw[54] = 0x7f; @@ -661,18 +654,17 @@ describe('TX', function() { const flags = Script.flags.VERIFY_WITNESS | Script.flags.VERIFY_P2SH; const key = KeyRing.generate(); const pub = key.publicKey; - let ctx, output, input, witness; - output = Script.fromMultisig(1, 2, [pub, pub]); + const output = Script.fromMultisig(1, 2, [pub, pub]); - input = new Script([ + const input = new Script([ opcodes.OP_0, opcodes.OP_0 ]); - witness = new Witness(); + const witness = new Witness(); - ctx = sigopContext(input, witness, output); + const ctx = sigopContext(input, witness, output); assert.equal(ctx.spend.getSigopsCost(ctx.view, flags), 0); assert.equal(ctx.fund.getSigopsCost(ctx.view, flags), @@ -683,20 +675,19 @@ describe('TX', function() { const flags = Script.flags.VERIFY_WITNESS | Script.flags.VERIFY_P2SH; const key = KeyRing.generate(); const pub = key.publicKey; - let ctx, redeem, output, input, witness; - redeem = Script.fromMultisig(1, 2, [pub, pub]); - output = Script.fromScripthash(redeem.hash160()); + const redeem = Script.fromMultisig(1, 2, [pub, pub]); + const output = Script.fromScripthash(redeem.hash160()); - input = new Script([ + const input = new Script([ opcodes.OP_0, opcodes.OP_0, redeem.toRaw() ]); - witness = new Witness(); + const witness = new Witness(); - ctx = sigopContext(input, witness, output); + const ctx = sigopContext(input, witness, output); assert.equal(ctx.spend.getSigopsCost(ctx.view, flags), 2 * consensus.WITNESS_SCALE_FACTOR); @@ -705,18 +696,17 @@ describe('TX', function() { it('should count sigops for p2wpkh', () => { const flags = Script.flags.VERIFY_WITNESS | Script.flags.VERIFY_P2SH; const key = KeyRing.generate(); - let ctx, output, input, witness; - output = Script.fromProgram(0, key.getKeyHash()); + let output = Script.fromProgram(0, key.getKeyHash()); - input = new Script(); + const input = new Script(); - witness = new Witness([ + const witness = new Witness([ Buffer.from([0]), Buffer.from([0]) ]); - ctx = sigopContext(input, witness, output); + let ctx = sigopContext(input, witness, output); assert.equal(ctx.spend.getSigopsCost(ctx.view, flags), 1); assert.equal( @@ -741,21 +731,20 @@ describe('TX', function() { it('should count sigops for nested p2wpkh', () => { const flags = Script.flags.VERIFY_WITNESS | Script.flags.VERIFY_P2SH; const key = KeyRing.generate(); - let ctx, redeem, output, input, witness; - redeem = Script.fromProgram(0, key.getKeyHash()); - output = Script.fromScripthash(redeem.hash160()); + const redeem = Script.fromProgram(0, key.getKeyHash()); + const output = Script.fromScripthash(redeem.hash160()); - input = new Script([ + const input = new Script([ redeem.toRaw() ]); - witness = new Witness([ + const witness = new Witness([ Buffer.from([0]), Buffer.from([0]) ]); - ctx = sigopContext(input, witness, output); + const ctx = sigopContext(input, witness, output); assert.equal(ctx.spend.getSigopsCost(ctx.view, flags), 1); }); @@ -764,20 +753,19 @@ describe('TX', function() { const flags = Script.flags.VERIFY_WITNESS | Script.flags.VERIFY_P2SH; const key = KeyRing.generate(); const pub = key.publicKey; - let ctx, redeem, output, input, witness; - redeem = Script.fromMultisig(1, 2, [pub, pub]); - output = Script.fromProgram(0, redeem.sha256()); + const redeem = Script.fromMultisig(1, 2, [pub, pub]); + const output = Script.fromProgram(0, redeem.sha256()); - input = new Script(); + const input = new Script(); - witness = new Witness([ + const witness = new Witness([ Buffer.from([0]), Buffer.from([0]), redeem.toRaw() ]); - ctx = sigopContext(input, witness, output); + const ctx = sigopContext(input, witness, output); assert.equal(ctx.spend.getSigopsCost(ctx.view, flags), 2); assert.equal( @@ -789,23 +777,22 @@ describe('TX', function() { const flags = Script.flags.VERIFY_WITNESS | Script.flags.VERIFY_P2SH; const key = KeyRing.generate(); const pub = key.publicKey; - let ctx, wscript, redeem, output, input, witness; - wscript = Script.fromMultisig(1, 2, [pub, pub]); - redeem = Script.fromProgram(0, wscript.sha256()); - output = Script.fromScripthash(redeem.hash160()); + const wscript = Script.fromMultisig(1, 2, [pub, pub]); + const redeem = Script.fromProgram(0, wscript.sha256()); + const output = Script.fromScripthash(redeem.hash160()); - input = new Script([ + const input = new Script([ redeem.toRaw() ]); - witness = new Witness([ + const witness = new Witness([ Buffer.from([0]), Buffer.from([0]), wscript.toRaw() ]); - ctx = sigopContext(input, witness, output); + const ctx = sigopContext(input, witness, output); assert.equal(ctx.spend.getSigopsCost(ctx.view, flags), 2); }); diff --git a/test/utils-test.js b/test/utils-test.js index 6187f022..ba2d4f55 100644 --- a/test/utils-test.js +++ b/test/utils-test.js @@ -13,9 +13,7 @@ const consensus = require('../lib/protocol/consensus'); const Validator = require('../lib/utils/validator'); describe('Utils', function() { - let vectors, signed, unsigned; - - vectors = [ + const vectors = [ ['', ''], ['61', '2g'], ['626262', 'a3gV'], @@ -38,15 +36,14 @@ describe('Utils', function() { it('should encode/decode base58', () => { const buf = Buffer.from('000000deadbeef', 'hex'); - let b = base58.encode(buf); - let i, r; + const b = base58.encode(buf); assert.equal(b, '1116h8cQN'); assert.deepEqual(base58.decode(b), buf); - for (i = 0; i < vectors.length; i++) { - r = Buffer.from(vectors[i][0], 'hex'); - b = vectors[i][1]; + for (let i = 0; i < vectors.length; i++) { + const r = Buffer.from(vectors[i][0], 'hex'); + const b = vectors[i][1]; assert.equal(base58.encode(r), b); assert.deepEqual(base58.decode(b), r); } @@ -54,9 +51,8 @@ describe('Utils', function() { it('should verify proof-of-work', () => { const bits = 0x1900896c; - let hash; - hash = Buffer.from( + const hash = Buffer.from( '672b3f1bb11a994267ea4171069ba0aa4448a840f38e8f340000000000000000', 'hex' ); @@ -105,8 +101,6 @@ describe('Utils', function() { }); it('should write/read new varints', () => { - let b; - /* * 0: [0x00] 256: [0x81 0x00] * 1: [0x01] 16383: [0xFE 0x7F] @@ -116,7 +110,7 @@ describe('Utils', function() { * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] */ - b = Buffer.allocUnsafe(1); + let b = Buffer.allocUnsafe(1); b.fill(0x00); encoding.writeVarint2(b, 0, 0); assert.equal(encoding.readVarint2(b, 0).value, 0); @@ -179,7 +173,7 @@ describe('Utils', function() { assert.deepEqual(b, [0x8e, 0xfe, 0xfe, 0xff, 0x00]); }); - unsigned = [ + const unsigned = [ new BN('ffeeffee'), new BN('001fffeeffeeffee'), new BN('eeffeeff'), @@ -188,7 +182,7 @@ describe('Utils', function() { new BN(1) ]; - signed = [ + const signed = [ new BN('ffeeffee'), new BN('001fffeeffeeffee'), new BN('eeffeeff'), @@ -209,14 +203,12 @@ describe('Utils', function() { const bits = num.bitLength(); it(`should write+read a ${bits} bit unsigned int`, () => { - let n1, n2; - encoding.writeU64BN(buf1, num, 0); encoding.writeU64(buf2, num.toNumber(), 0); assert.deepEqual(buf1, buf2); - n1 = encoding.readU64BN(buf1, 0); - n2 = encoding.readU64(buf2, 0); + const n1 = encoding.readU64BN(buf1, 0); + const n2 = encoding.readU64(buf2, 0); assert.equal(n1.toNumber(), n2); }); }); @@ -228,29 +220,25 @@ describe('Utils', function() { const sign = num.isNeg() ? 'negative' : 'positive'; it(`should write+read a ${bits} bit ${sign} int`, () => { - let n1, n2; - encoding.write64BN(buf1, num, 0); encoding.write64(buf2, num.toNumber(), 0); assert.deepEqual(buf1, buf2); - n1 = encoding.read64BN(buf1, 0); - n2 = encoding.read64(buf2, 0); + const n1 = encoding.read64BN(buf1, 0); + const n2 = encoding.read64(buf2, 0); assert.equal(n1.toNumber(), n2); }); it(`should write+read a ${bits} bit ${sign} int as unsigned`, () => { - let n1, n2; - encoding.writeU64BN(buf1, num, 0); encoding.writeU64(buf2, num.toNumber(), 0); assert.deepEqual(buf1, buf2); - n1 = encoding.readU64BN(buf1, 0); + const n1 = encoding.readU64BN(buf1, 0); if (num.isNeg()) { assert.throws(() => encoding.readU64(buf2, 0)); } else { - n2 = encoding.readU64(buf2, 0); + const n2 = encoding.readU64(buf2, 0); assert.equal(n1.toNumber(), n2); } }); @@ -263,18 +251,17 @@ describe('Utils', function() { let salt = '000102030405060708090a0b0c'; let info = 'f0f1f2f3f4f5f6f7f8f9'; let len = 42; - let prkE, okmE, prk, okm; - prkE = '077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5'; - okmE = '3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1' + let prkE = '077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5'; + let okmE = '3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1' + 'a5a4c5db02d56ecc4c5bf34007208d5b887185865'; ikm = Buffer.from(ikm, 'hex'); salt = Buffer.from(salt, 'hex'); info = Buffer.from(info, 'hex'); - prk = hkdf.extract(ikm, salt, alg); - okm = hkdf.expand(prk, info, len, alg); + let prk = hkdf.extract(ikm, salt, alg); + let okm = hkdf.expand(prk, info, len, alg); assert.equal(prk.toString('hex'), prkE); assert.equal(okm.toString('hex'), okmE); diff --git a/test/wallet-test.js b/test/wallet-test.js index 8c58acef..747c0c69 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -26,13 +26,11 @@ let globalHeight = 1; const globalTime = util.now(); function nextBlock(height) { - let hash, prev; - if (height == null) height = globalHeight++; - hash = digest.hash256(encoding.U32(height)).toString('hex'); - prev = digest.hash256(encoding.U32(height - 1)).toString('hex'); + const hash = digest.hash256(encoding.U32(height)).toString('hex'); + const prev = digest.hash256(encoding.U32(height - 1)).toString('hex'); return { hash: hash, @@ -53,10 +51,10 @@ function dummy(hash) { } describe('Wallet', function() { - let wdb, wallet, ewallet, ekey; + let wallet, ewallet, ekey; let doubleSpendWallet, doubleSpend; - wdb = new WalletDB({ + const wdb = new WalletDB({ name: 'wallet-test', db: 'memory', verify: true @@ -87,12 +85,10 @@ describe('Wallet', function() { }); it('should create and get wallet', async () => { - let w1, w2; - - w1 = await wdb.create(); + const w1 = await wdb.create(); await w1.destroy(); - w2 = await wdb.get(w1.id); + const w2 = await wdb.get(w1.id); assert(w1 !== w2); assert(w1.master !== w2.master); @@ -104,24 +100,23 @@ describe('Wallet', function() { async function testP2PKH(witness, bullshitNesting) { const flags = Script.flags.STANDARD_VERIFY_FLAGS; - let w, addr, src, tx; - w = await wdb.create({ witness: witness }); + const w = await wdb.create({ witness: witness }); - addr = Address.fromString(w.getAddress('string')); + const addr = Address.fromString(w.getAddress('string')); if (witness) assert.equal(addr.type, Address.types.WITNESS); else assert.equal(addr.type, Address.types.PUBKEYHASH); - src = new MTX(); + let src = new MTX(); src.addInput(dummy()); src.addOutput(bullshitNesting ? w.getNested() : w.getAddress(), 5460 * 2); src.addOutput(new Address(), 2 * 5460); src = src.toTX(); - tx = new MTX(); + const tx = new MTX(); tx.addTX(src, 0); tx.addOutput(w.getAddress(), 5460); @@ -143,35 +138,33 @@ describe('Wallet', function() { }); it('should multisign/verify TX', async () => { - let w, k, script, src, tx, maxSize; - - w = await wdb.create({ + const w = await wdb.create({ type: 'multisig', m: 1, n: 2 }); - k = HD.generate().deriveBIP44(0).toPublic(); + const k = HD.generate().deriveBIP44(0).toPublic(); await w.addSharedKey(k); - script = Script.fromMultisig(1, 2, [ + const script = Script.fromMultisig(1, 2, [ w.account.receive.getPublicKey(), k.derivePath('m/0/0').publicKey ]); // Input transaction (bare 1-of-2 multisig) - src = new MTX(); + let src = new MTX(); src.addInput(dummy()); src.addOutput(script, 5460 * 2); src.addOutput(new Address(), 5460 * 2); src = src.toTX(); - tx = new MTX(); + const tx = new MTX(); tx.addTX(src, 0); tx.addOutput(w.getAddress(), 5460); - maxSize = await tx.estimateSize(); + const maxSize = await tx.estimateSize(); await w.sign(tx); @@ -182,17 +175,16 @@ describe('Wallet', function() { it('should handle missed and invalid txs', async () => { const w = await wdb.create(); const f = await wdb.create(); - let t1, t2, t3, t4, f1, fake, balance, txs; // Coinbase // balance: 51000 - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w.getAddress(), 50000); t1.addOutput(w.getAddress(), 1000); t1 = t1.toTX(); - t2 = new MTX(); + let t2 = new MTX(); t2.addTX(t1, 0); // 50000 t2.addOutput(w.getAddress(), 24000); t2.addOutput(w.getAddress(), 24000); @@ -204,7 +196,7 @@ describe('Wallet', function() { // balance: 49000 await w.sign(t2); t2 = t2.toTX(); - t3 = new MTX(); + let t3 = new MTX(); t3.addTX(t1, 1); // 1000 t3.addTX(t2, 0); // 24000 t3.addOutput(w.getAddress(), 23000); @@ -212,7 +204,7 @@ describe('Wallet', function() { // balance: 47000 await w.sign(t3); t3 = t3.toTX(); - t4 = new MTX(); + let t4 = new MTX(); t4.addTX(t2, 1); // 24000 t4.addTX(t3, 0); // 23000 t4.addOutput(w.getAddress(), 11000); @@ -221,7 +213,7 @@ describe('Wallet', function() { // balance: 22000 await w.sign(t4); t4 = t4.toTX(); - f1 = new MTX(); + let f1 = new MTX(); f1.addTX(t4, 1); // 11000 f1.addOutput(f.getAddress(), 10000); @@ -229,7 +221,7 @@ describe('Wallet', function() { await w.sign(f1); f1 = f1.toTX(); - fake = new MTX(); + let fake = new MTX(); fake.addTX(t1, 1); // 1000 (already redeemed) fake.addOutput(w.getAddress(), 500); @@ -246,7 +238,7 @@ describe('Wallet', function() { await wdb.addTX(t4); - balance = await w.getBalance(); + let balance = await w.getBalance(); assert.equal(balance.unconfirmed, 22500); await wdb.addTX(t1); @@ -269,7 +261,7 @@ describe('Wallet', function() { balance = await w.getBalance(); assert.equal(balance.unconfirmed, 11000); - txs = await w.getHistory(); + let txs = await w.getHistory(); assert(txs.some((wtx) => { return wtx.hash === f1.hash('hex'); })); @@ -285,15 +277,14 @@ describe('Wallet', function() { it('should cleanup spenders after double-spend', async () => { const w = doubleSpendWallet; - let tx, txs, total, balance; - tx = new MTX(); + let tx = new MTX(); tx.addCoin(doubleSpend); tx.addOutput(w.getAddress(), 5000); - txs = await w.getHistory(); + let txs = await w.getHistory(); assert.equal(txs.length, 5); - total = txs.reduce((t, wtx) => { + let total = txs.reduce((t, wtx) => { return t + wtx.tx.getOutputValue(); }, 0); @@ -302,7 +293,7 @@ describe('Wallet', function() { await w.sign(tx); tx = tx.toTX(); - balance = await w.getBalance(); + let balance = await w.getBalance(); assert.equal(balance.unconfirmed, 11000); await wdb.addTX(tx); @@ -320,9 +311,7 @@ describe('Wallet', function() { }); it('should handle missed txs without resolution', async () => { - let wdb, w, f, t1, t2, t3, t4, f1, balance, txs; - - wdb = new WalletDB({ + const wdb = new WalletDB({ name: 'wallet-test', db: 'memory', verify: false @@ -330,11 +319,11 @@ describe('Wallet', function() { await wdb.open(); - w = await wdb.create(); - f = await wdb.create(); + const w = await wdb.create(); + const f = await wdb.create(); // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w.getAddress(), 50000); t1.addOutput(w.getAddress(), 1000); @@ -343,7 +332,7 @@ describe('Wallet', function() { // await w.sign(t1); t1 = t1.toTX(); - t2 = new MTX(); + let t2 = new MTX(); t2.addTX(t1, 0); // 50000 t2.addOutput(w.getAddress(), 24000); t2.addOutput(w.getAddress(), 24000); @@ -351,7 +340,7 @@ describe('Wallet', function() { // balance: 49000 await w.sign(t2); t2 = t2.toTX(); - t3 = new MTX(); + let t3 = new MTX(); t3.addTX(t1, 1); // 1000 t3.addTX(t2, 0); // 24000 t3.addOutput(w.getAddress(), 23000); @@ -359,7 +348,7 @@ describe('Wallet', function() { // balance: 47000 await w.sign(t3); t3 = t3.toTX(); - t4 = new MTX(); + let t4 = new MTX(); t4.addTX(t2, 1); // 24000 t4.addTX(t3, 0); // 23000 t4.addOutput(w.getAddress(), 11000); @@ -368,7 +357,7 @@ describe('Wallet', function() { // balance: 22000 await w.sign(t4); t4 = t4.toTX(); - f1 = new MTX(); + let f1 = new MTX(); f1.addTX(t4, 1); // 11000 f1.addOutput(f.getAddress(), 10000); @@ -393,7 +382,7 @@ describe('Wallet', function() { await wdb.addTX(t4); - balance = await w.getBalance(); + let balance = await w.getBalance(); assert.equal(balance.unconfirmed, 22000); await wdb.addTX(t1); @@ -416,7 +405,7 @@ describe('Wallet', function() { balance = await w.getBalance(); assert.equal(balance.unconfirmed, 11000); - txs = await w.getHistory(); + let txs = await w.getHistory(); assert(txs.some((wtx) => { return wtx.tx.hash('hex') === f1.hash('hex'); })); @@ -447,10 +436,9 @@ describe('Wallet', function() { it('should fill tx with inputs', async () => { const w1 = await wdb.create(); const w2 = await wdb.create(); - let view, t1, t2, t3, err; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w1.getAddress(), 5460); t1.addOutput(w1.getAddress(), 5460); @@ -462,11 +450,11 @@ describe('Wallet', function() { await wdb.addTX(t1); // Create new transaction - t2 = new MTX(); + let t2 = new MTX(); t2.addOutput(w2.getAddress(), 5460); await w1.fund(t2, { rate: 10000, round: true }); await w1.sign(t2); - view = t2.view; + const view = t2.view; t2 = t2.toTX(); assert(t2.verify(view)); @@ -476,9 +464,10 @@ describe('Wallet', function() { assert.equal(t2.getFee(view), 10000); // Create new transaction - t3 = new MTX(); + const t3 = new MTX(); t3.addOutput(w2.getAddress(), 15000); + let err; try { await w1.fund(t3, { rate: 10000, round: true }); } catch (e) { @@ -492,10 +481,10 @@ describe('Wallet', function() { it('should fill tx with inputs with accurate fee', async () => { const w1 = await wdb.create({ master: KEY1 }); const w2 = await wdb.create({ master: KEY2 }); - let view, t1, t2, t3, balance, err; + let balance; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy(encoding.NULL_HASH)); t1.addOutput(w1.getAddress(), 5460); t1.addOutput(w1.getAddress(), 5460); @@ -506,12 +495,12 @@ describe('Wallet', function() { await wdb.addTX(t1); // Create new transaction - t2 = new MTX(); + let t2 = new MTX(); t2.addOutput(w2.getAddress(), 5460); await w1.fund(t2, { rate: 10000 }); await w1.sign(t2); - view = t2.view; + const view = t2.view; t2 = t2.toTX(); assert(t2.verify(view)); @@ -534,9 +523,10 @@ describe('Wallet', function() { await wdb.addTX(t2); // Create new transaction - t3 = new MTX(); + const t3 = new MTX(); t3.addOutput(w2.getAddress(), 15000); + let err; try { await w1.fund(t3, { rate: 10000 }); } catch (e) { @@ -552,10 +542,9 @@ describe('Wallet', function() { const w1 = await wdb.create(); const w2 = await wdb.create(); const to = await wdb.create(); - let t1, t2, tx, cost, total, coins1, coins2; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w1.getAddress(), 5460); t1.addOutput(w1.getAddress(), 5460); @@ -564,7 +553,7 @@ describe('Wallet', function() { t1 = t1.toTX(); // Coinbase - t2 = new MTX(); + let t2 = new MTX(); t2.addInput(dummy()); t2.addOutput(w2.getAddress(), 5460); t2.addOutput(w2.getAddress(), 5460); @@ -576,14 +565,14 @@ describe('Wallet', function() { await wdb.addTX(t2); // Create our tx with an output - tx = new MTX(); + const tx = new MTX(); tx.addOutput(to.getAddress(), 5460); - cost = tx.getOutputValue(); - total = cost * 10000; + const cost = tx.getOutputValue(); + let total = cost * 10000; - coins1 = await w1.getCoins(); - coins2 = await w2.getCoins(); + const coins1 = await w1.getCoins(); + const coins2 = await w2.getCoins(); // Add our unspent inputs to sign tx.addCoin(coins1[0]); @@ -619,22 +608,19 @@ describe('Wallet', function() { const flags = Script.flags.STANDARD_VERIFY_FLAGS; const rec = bullshitNesting ? 'nested' : 'receive'; const depth = bullshitNesting ? 'nestedDepth' : 'receiveDepth'; - let options, w1, w2, w3, receive, b58; - let addr, paddr, utx, send, change; - let view, block; // Create 3 2-of-3 wallets with our pubkeys as "shared keys" - options = { + const options = { witness: witness, type: 'multisig', m: 2, n: 3 }; - w1 = await wdb.create(options); - w2 = await wdb.create(options); - w3 = await wdb.create(options); - receive = await wdb.create(); + const w1 = await wdb.create(options); + const w2 = await wdb.create(options); + const w3 = await wdb.create(options); + const receive = await wdb.create(); await w1.addSharedKey(w2.account.accountKey); await w1.addSharedKey(w3.account.accountKey); @@ -644,8 +630,8 @@ describe('Wallet', function() { await w3.addSharedKey(w2.account.accountKey); // Our p2sh address - b58 = w1.account[rec].getAddress('string'); - addr = Address.fromString(b58); + let b58 = w1.account[rec].getAddress('string'); + const addr = Address.fromString(b58); if (witness) { if (bullshitNesting) @@ -660,7 +646,7 @@ describe('Wallet', function() { assert.equal(w2.account[rec].getAddress('string'), b58); assert.equal(w3.account[rec].getAddress('string'), b58); - paddr = w1.getNested(); + const paddr = w1.getNested(); if (witness) { assert(paddr); @@ -670,13 +656,13 @@ describe('Wallet', function() { } // Add a shared unspent transaction to our wallets - utx = new MTX(); + let utx = new MTX(); utx.addInput(dummy()); utx.addOutput(bullshitNesting ? paddr : addr, 5460 * 10); utx = utx.toTX(); // Simulate a confirmation - block = nextBlock(); + let block = nextBlock(); assert.equal(w1.account[depth], 1); @@ -693,7 +679,7 @@ describe('Wallet', function() { assert.equal(w3.account[rec].getAddress('string'), b58); // Create a tx requiring 2 signatures - send = new MTX(); + let send = new MTX(); send.addOutput(receive.getAddress(), 5460); assert(!send.verify(flags)); await w1.fund(send, { rate: 10000, round: true }); @@ -704,13 +690,13 @@ describe('Wallet', function() { await w2.sign(send); - view = send.view; + const view = send.view; send = send.toTX(); assert(send.verify(view, flags)); assert.equal(w1.account.changeDepth, 1); - change = w1.account.change.getAddress('string'); + let change = w1.account.change.getAddress('string'); assert.equal(w1.account.change.getAddress('string'), change); assert.equal(w2.account.change.getAddress('string'), change); assert.equal(w3.account.change.getAddress('string'), change); @@ -757,19 +743,18 @@ describe('Wallet', function() { it('should fill tx with account 1', async () => { const w1 = await wdb.create(); const w2 = await wdb.create(); - let account, accounts, rec, t1, t2, t3, err; - account = await w1.createAccount({ name: 'foo' }); + let account = await w1.createAccount({ name: 'foo' }); assert.equal(account.name, 'foo'); assert.equal(account.accountIndex, 1); account = await w1.getAccount('foo'); assert.equal(account.name, 'foo'); assert.equal(account.accountIndex, 1); - rec = account.receive; + const rec = account.receive; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addOutput(rec.getAddress(), 5460); t1.addOutput(rec.getAddress(), 5460); t1.addOutput(rec.getAddress(), 5460); @@ -781,7 +766,7 @@ describe('Wallet', function() { await wdb.addTX(t1); // Create new transaction - t2 = new MTX(); + const t2 = new MTX(); t2.addOutput(w2.getAddress(), 5460); await w1.fund(t2, { rate: 10000, round: true }); await w1.sign(t2); @@ -793,9 +778,10 @@ describe('Wallet', function() { assert.equal(t2.getFee(), 10000); // Create new transaction - t3 = new MTX(); + const t3 = new MTX(); t3.addOutput(w2.getAddress(), 15000); + let err; try { await w1.fund(t3, { rate: 10000, round: true }); } catch (e) { @@ -805,21 +791,20 @@ describe('Wallet', function() { assert(err); assert.equal(err.requiredFunds, 25000); - accounts = await w1.getAccounts(); + const accounts = await w1.getAccounts(); assert.deepEqual(accounts, ['default', 'foo']); }); it('should fail to fill tx with account 1', async () => { const w = await wdb.create(); - let acc, account, t1, t2, err; wallet = w; - acc = await w.createAccount({ name: 'foo' }); + const acc = await w.createAccount({ name: 'foo' }); assert.equal(acc.name, 'foo'); assert.equal(acc.accountIndex, 1); - account = await w.getAccount('foo'); + const account = await w.getAccount('foo'); assert.equal(account.name, 'foo'); assert.equal(account.accountIndex, 1); assert(account.accountKey.toBase58() === acc.accountKey.toBase58()); @@ -833,7 +818,7 @@ describe('Wallet', function() { w.account.receive.getAddress('string')); // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addOutput(w.getAddress(), 5460); t1.addOutput(w.getAddress(), 5460); t1.addOutput(w.getAddress(), 5460); @@ -845,8 +830,9 @@ describe('Wallet', function() { await wdb.addTX(t1); // Should fill from `foo` and fail - t2 = new MTX(); + let t2 = new MTX(); t2.addOutput(w.getAddress(), 5460); + let err; try { await w.fund(t2, { rate: 10000, round: true, account: 'foo' }); } catch (e) { @@ -877,13 +863,12 @@ describe('Wallet', function() { it('should create two accounts (multiple encryption)', async () => { let w = await wdb.create({ id: 'foobar', passphrase: 'foo' }); - let account; await w.destroy(); w = await wdb.get('foobar'); - account = await w.createAccount({ name: 'foo1' }, 'foo'); + const account = await w.createAccount({ name: 'foo1' }, 'foo'); assert(account); await w.lock(); @@ -891,13 +876,12 @@ describe('Wallet', function() { it('should fill tx with inputs when encrypted', async () => { const w = await wdb.create({ passphrase: 'foo' }); - let t1, t2, err; w.master.stop(); w.master.key = null; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w.getAddress(), 5460); t1.addOutput(w.getAddress(), 5460); @@ -908,11 +892,12 @@ describe('Wallet', function() { await wdb.addTX(t1); // Create new transaction - t2 = new MTX(); + const t2 = new MTX(); t2.addOutput(w.getAddress(), 5460); await w.fund(t2, { rate: 10000, round: true }); // Should fail + let err; try { await w.sign(t2, 'bar'); } catch (e) { @@ -930,10 +915,9 @@ describe('Wallet', function() { it('should fill tx with inputs with subtract fee (1)', async () => { const w1 = await wdb.create(); const w2 = await wdb.create(); - let t1, t2; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w1.getAddress(), 5460); t1.addOutput(w1.getAddress(), 5460); @@ -944,7 +928,7 @@ describe('Wallet', function() { await wdb.addTX(t1); // Create new transaction - t2 = new MTX(); + const t2 = new MTX(); t2.addOutput(w2.getAddress(), 21840); await w1.fund(t2, { rate: 10000, round: true, subtractFee: true }); await w1.sign(t2); @@ -959,10 +943,9 @@ describe('Wallet', function() { it('should fill tx with inputs with subtract fee (2)', async () => { const w1 = await wdb.create(); const w2 = await wdb.create(); - let options, t1, t2; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w1.getAddress(), 5460); t1.addOutput(w1.getAddress(), 5460); @@ -972,7 +955,7 @@ describe('Wallet', function() { await wdb.addTX(t1); - options = { + const options = { subtractFee: true, rate: 10000, round: true, @@ -980,7 +963,7 @@ describe('Wallet', function() { }; // Create new transaction - t2 = await w1.createTX(options); + const t2 = await w1.createTX(options); await w1.sign(t2); assert(t2.verify()); @@ -995,10 +978,9 @@ describe('Wallet', function() { const w2 = await wdb.create(); let found = false; let total = 0; - let i, options, t1, t2, t3, block, coins, coin; // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(w1.getAddress(), 5460); t1.addOutput(w1.getAddress(), 5460); @@ -1009,7 +991,7 @@ describe('Wallet', function() { await wdb.addTX(t1); // Coinbase - t2 = new MTX(); + let t2 = new MTX(); t2.addInput(dummy()); t2.addOutput(w1.getAddress(), 5460); t2.addOutput(w1.getAddress(), 5460); @@ -1017,15 +999,15 @@ describe('Wallet', function() { t2.addOutput(w1.getAddress(), 5460); t2 = t2.toTX(); - block = nextBlock(); + const block = nextBlock(); await wdb.addBlock(block, [t2]); - coins = await w1.getSmartCoins(); + let coins = await w1.getSmartCoins(); assert.equal(coins.length, 4); - for (i = 0; i < coins.length; i++) { - coin = coins[i]; + for (let i = 0; i < coins.length; i++) { + const coin = coins[i]; assert.equal(coin.height, block.height); } @@ -1040,8 +1022,8 @@ describe('Wallet', function() { coins = await w1.getSmartCoins(); assert.equal(coins.length, 4); - for (i = 0; i < coins.length; i++) { - coin = coins[i]; + for (let i = 0; i < coins.length; i++) { + const coin = coins[i]; if (coin.height === -1) { assert(!found); assert(coin.value < 5460); @@ -1055,19 +1037,19 @@ describe('Wallet', function() { assert(found); // Use smart selection - options = { + const options = { subtractFee: true, smart: true, rate: 10000, outputs: [{ address: w2.getAddress(), value: total }] }; - t3 = await w1.createTX(options); + const t3 = await w1.createTX(options); assert.equal(t3.inputs.length, 4); found = false; - for (i = 0; i < t3.inputs.length; i++) { - coin = t3.view.getCoinFor(t3.inputs[i]); + for (let i = 0; i < t3.inputs.length; i++) { + const coin = t3.view.getCoinFor(t3.inputs[i]); if (coin.height === -1) { assert(!found); assert(coin.value < 5460); @@ -1120,16 +1102,15 @@ describe('Wallet', function() { it('should import privkey', async () => { const key = KeyRing.generate(); const w = await wdb.create({ passphrase: 'test' }); - let options, k, t1, t2, wtx; await w.importKey('default', key, 'test'); - k = await w.getKey(key.getHash('hex')); + const k = await w.getKey(key.getHash('hex')); assert.equal(k.getHash('hex'), key.getHash('hex')); // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addOutput(key.getAddress(), 5460); t1.addOutput(key.getAddress(), 5460); t1.addOutput(key.getAddress(), 5460); @@ -1140,18 +1121,18 @@ describe('Wallet', function() { await wdb.addTX(t1); - wtx = await w.getTX(t1.hash('hex')); + const wtx = await w.getTX(t1.hash('hex')); assert(wtx); assert.equal(t1.hash('hex'), wtx.hash); - options = { + const options = { rate: 10000, round: true, outputs: [{ address: w.getAddress(), value: 7000 }] }; // Create new transaction - t2 = await w.createTX(options); + const t2 = await w.createTX(options); await w.sign(t2); assert(t2.verify()); assert(t2.inputs[0].prevout.hash === wtx.hash); @@ -1164,11 +1145,10 @@ describe('Wallet', function() { const priv = KeyRing.generate(); const key = new KeyRing(priv.publicKey); const w = await wdb.create({ watchOnly: true }); - let k; await w.importKey('default', key); - k = await w.getPath(key.getHash('hex')); + let k = await w.getPath(key.getHash('hex')); assert.equal(k.hash, key.getHash('hex')); @@ -1179,11 +1159,10 @@ describe('Wallet', function() { it('should import address', async () => { const key = KeyRing.generate(); const w = await wdb.create({ watchOnly: true }); - let k; await w.importAddress('default', key.getAddress()); - k = await w.getPath(key.getHash('hex')); + let k = await w.getPath(key.getHash('hex')); assert.equal(k.hash, key.getHash('hex')); @@ -1211,14 +1190,13 @@ describe('Wallet', function() { it('should change passphrase with encrypted imports', async () => { const w = ewallet; const addr = ekey.getAddress(); - let path, d1, d2, k; assert(w.master.encrypted); - path = await w.getPath(addr); + let path = await w.getPath(addr); assert(path); assert(path.data && path.encrypted); - d1 = path.data; + const d1 = path.data; await w.decrypt('test'); @@ -1226,7 +1204,7 @@ describe('Wallet', function() { assert(path); assert(path.data && !path.encrypted); - k = await w.getKey(addr); + let k = await w.getKey(addr); assert(k); await w.encrypt('foo'); @@ -1234,7 +1212,7 @@ describe('Wallet', function() { path = await w.getPath(addr); assert(path); assert(path.data && path.encrypted); - d2 = path.data; + const d2 = path.data; assert(!d1.equals(d2)); @@ -1248,9 +1226,7 @@ describe('Wallet', function() { }); it('should recover from a missed tx', async () => { - let wdb, alice, addr, bob, t1, t2, t3; - - wdb = new WalletDB({ + const wdb = new WalletDB({ name: 'wallet-test', db: 'memory', verify: false @@ -1258,12 +1234,12 @@ describe('Wallet', function() { await wdb.open(); - alice = await wdb.create({ master: KEY1 }); - bob = await wdb.create({ master: KEY1 }); - addr = alice.getAddress(); + const alice = await wdb.create({ master: KEY1 }); + const bob = await wdb.create({ master: KEY1 }); + const addr = alice.getAddress(); // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(addr, 50000); t1 = t1.toTX(); @@ -1272,7 +1248,7 @@ describe('Wallet', function() { await bob.add(t1); // Bob misses this tx! - t2 = new MTX(); + let t2 = new MTX(); t2.addTX(t1, 0); t2.addOutput(addr, 24000); t2.addOutput(addr, 24000); @@ -1287,7 +1263,7 @@ describe('Wallet', function() { (await bob.getBalance()).unconfirmed); // Bob sees this one. - t3 = new MTX(); + let t3 = new MTX(); t3.addTX(t2, 0); t3.addTX(t2, 1); t3.addOutput(addr, 30000); @@ -1312,9 +1288,7 @@ describe('Wallet', function() { }); it('should recover from a missed tx and double spend', async () => { - let wdb, alice, addr, bob, t1, t2, t3, t2a; - - wdb = new WalletDB({ + const wdb = new WalletDB({ name: 'wallet-test', db: 'memory', verify: false @@ -1322,12 +1296,12 @@ describe('Wallet', function() { await wdb.open(); - alice = await wdb.create({ master: KEY1 }); - bob = await wdb.create({ master: KEY1 }); - addr = alice.getAddress(); + const alice = await wdb.create({ master: KEY1 }); + const bob = await wdb.create({ master: KEY1 }); + const addr = alice.getAddress(); // Coinbase - t1 = new MTX(); + let t1 = new MTX(); t1.addInput(dummy()); t1.addOutput(addr, 50000); t1 = t1.toTX(); @@ -1336,7 +1310,7 @@ describe('Wallet', function() { await bob.add(t1); // Bob misses this tx! - t2 = new MTX(); + let t2 = new MTX(); t2.addTX(t1, 0); t2.addOutput(addr, 24000); t2.addOutput(addr, 24000); @@ -1351,7 +1325,7 @@ describe('Wallet', function() { (await bob.getBalance()).unconfirmed); // Bob doublespends. - t2a = new MTX(); + let t2a = new MTX(); t2a.addTX(t1, 0); t2a.addOutput(addr, 10000); t2a.addOutput(addr, 10000); @@ -1362,7 +1336,7 @@ describe('Wallet', function() { await bob.add(t2a); // Bob sees this one. - t3 = new MTX(); + let t3 = new MTX(); t3.addTX(t2, 0); t3.addTX(t2, 1); t3.addOutput(addr, 30000);