From 063ce75db689214e7f5b193a8abfc376c3b5f852 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 15 May 2017 01:34:01 +0000 Subject: [PATCH 001/540] Test that transactions are being processed --- lib/full_node.js | 12 ++++++++++ lib/index.js | 11 ++-------- lib/trust_is_risk.js | 26 ++++++++++++++++++++++ package.json | 6 +++-- src/full_node.js | 12 ++++++++++ src/index.js | 11 ++-------- src/trust_is_risk.js | 26 ++++++++++++++++++++++ test/full_node.js | 50 ++++++++++++++++++++++++++++++++++++++++++ test/helpers.js | 52 ++++++++++++++++++++++++++++++++++++++++++++ test/test.js | 10 --------- 10 files changed, 186 insertions(+), 30 deletions(-) create mode 100644 lib/full_node.js create mode 100644 lib/trust_is_risk.js create mode 100644 src/full_node.js create mode 100644 src/trust_is_risk.js create mode 100644 test/full_node.js create mode 100644 test/helpers.js delete mode 100644 test/test.js diff --git a/lib/full_node.js b/lib/full_node.js new file mode 100644 index 0000000..947cc83 --- /dev/null +++ b/lib/full_node.js @@ -0,0 +1,12 @@ +// +var bcoin = require('bcoin'); +var TrustIsRisk = require('./trust_is_risk'); + +class FullNode extends bcoin.fullnode { + constructor(options ) { + super(options); + this.trust = new TrustIsRisk(this); + } +} + +module.exports = FullNode; diff --git a/lib/index.js b/lib/index.js index 2b229a1..01c118a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,12 +1,5 @@ // -var bcoin = require('bcoin'); - -class fullnode extends bcoin.fullnode { - constructor(options ) { - super(options); - } -} - module.exports = { - fullnode + FullNode: require('./full_node'), + TrustIsRisk: require('./trust_is_risk') } diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js new file mode 100644 index 0000000..ed2e4e1 --- /dev/null +++ b/lib/trust_is_risk.js @@ -0,0 +1,26 @@ +// +var bcoin = require('bcoin'); + +class TrustIsRisk { + + + constructor(node ) { + this.node = node; + + this.node.on('tx', this.addTX.bind(this)); + } + + addTX(tx ) { + if (!this.isTrustTX(tx)) return false; + // TODO + return true; + } + + isTrustTX(tx ) { + return true; // TODO + } + +} + + +module.exports = TrustIsRisk; diff --git a/package.json b/package.json index 681643a..af50d22 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha", + "test": "npm run build && mocha -t 5000", "prepublish": "npm run build", "typecheck": "flow check" }, @@ -27,7 +27,9 @@ "devDependencies": { "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.0", - "should": "^11.2.1" + "should": "^11.2.1", + "should-sinon": "0.0.5", + "sinon": "^2.2.0" }, "dependencies": { "bcoin": "^1.0.0-beta.12" diff --git a/src/full_node.js b/src/full_node.js new file mode 100644 index 0000000..2798307 --- /dev/null +++ b/src/full_node.js @@ -0,0 +1,12 @@ +// @flow +var bcoin = require('bcoin'); +var TrustIsRisk = require('./trust_is_risk'); + +class FullNode extends bcoin.fullnode { + constructor(options : Object) { + super(options); + this.trust = new TrustIsRisk(this); + } +} + +module.exports = FullNode; diff --git a/src/index.js b/src/index.js index 2db0e64..f21fb90 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,5 @@ // @flow -var bcoin = require('bcoin'); - -class fullnode extends bcoin.fullnode { - constructor(options : Object) { - super(options); - } -} - module.exports = { - fullnode + FullNode: require('./full_node'), + TrustIsRisk: require('./trust_is_risk') } diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js new file mode 100644 index 0000000..8be984d --- /dev/null +++ b/src/trust_is_risk.js @@ -0,0 +1,26 @@ +// @flow +var bcoin = require('bcoin'); + +class TrustIsRisk { + node : bcoin.fullnode + + constructor(node : bcoin.fullnode) { + this.node = node; + + this.node.on('tx', this.addTX.bind(this)); + } + + addTX(tx : bcoin.TX) : boolean { + if (!this.isTrustTX(tx)) return false; + // TODO + return true; + } + + isTrustTX(tx : bcoin.TX) : boolean { + return true; // TODO + } + +} + + +module.exports = TrustIsRisk; diff --git a/test/full_node.js b/test/full_node.js new file mode 100644 index 0000000..64ad3b5 --- /dev/null +++ b/test/full_node.js @@ -0,0 +1,50 @@ +var Trust = require('../'); +var bcoin = require('bcoin'); +var testHelpers = require('./helpers'); +var consensus = require('bcoin/lib/protocol/consensus'); +var sinon = require('sinon'); +var should = require('should'); +require('should-sinon'); + +describe('TrustIsRisk.FullNode', () => { + var node = null; + var walletDB = null; + sinon.spy(Trust.TrustIsRisk.prototype, 'addTX'); + + beforeEach(() => testHelpers.getNode().then((n) => { + node = n; + })); + + beforeEach(() => testHelpers.getWalletDB(node).then((w) => { + walletDB = w; + })); + + afterEach(() => walletDB.close()); + afterEach(() => node.close()); + + it('should be a bcoin instance', () => { + should(node).be.an.instanceof(bcoin.fullnode); + }); + + it('should call trust.addTX() on every transaction', async function() { + var sender = await testHelpers.getWallet(walletDB, 'sender'); + var receiver = await testHelpers.getWallet(walletDB, 'receiver'); + + // Produce a block and reward the sender, so that we have a coin to spend. + await testHelpers.mineBlock(node, sender.getAddress('base58')); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + + await testHelpers.time(100); + await sender.send({ + outputs: [{ + value: 10 * consensus.COIN, + address: receiver.getAddress('base58') + }] + }); + + await testHelpers.time(100); + node.trust.addTX.should.be.calledOnce(); + }); +}); diff --git a/test/helpers.js b/test/helpers.js new file mode 100644 index 0000000..0b2c7fc --- /dev/null +++ b/test/helpers.js @@ -0,0 +1,52 @@ +var TrustIsRisk = require('../'); +var WalletDB = require('bcoin/lib/wallet/walletdb'); +var bcoin = require('bcoin'); + +var testHelpers = { + getNode: async () => { + var node = new TrustIsRisk.FullNode({network: 'regtest', passphrase: 'secret'}); + + await node.open(); + await node.connect(); + node.startSync(); + + return node; + }, + + getWalletDB: async (node) => { + var walletDB = new WalletDB({ + network: 'regtest', + db: 'memory', + client: new bcoin.node.NodeClient(node) + }); + + await walletDB.open(); + await walletDB.connect(); + + return walletDB; + }, + + getWallet: async (walletDB, id) => { + var options = { + id, + passphrase: 'secret', + witness: false, + type: 'pubkeyhash' + }; + + return walletDB.create(options); + }, + + mineBlock: async (node, rewardAddress) => { + var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); + await node.chain.add(block); + }, + + time: async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); + } +} + +module.exports = testHelpers; diff --git a/test/test.js b/test/test.js deleted file mode 100644 index cd34a7d..0000000 --- a/test/test.js +++ /dev/null @@ -1,10 +0,0 @@ -var TrustIsRisk = require('../'); -var bcoin = require('bcoin'); -var should = require('should'); - -describe('new TrustIsRisk.fullnode', () => { - it('should be a bcoin instance', () => { - var node = new TrustIsRisk.fullnode({}); - should(node).be.an.instanceof(bcoin.fullnode); - }); -}); From c1cce130f2d03eff351f4d83b5f4c0fcc95a6c02 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 15 May 2017 14:19:09 +0000 Subject: [PATCH 002/540] Implement trust-increasing transaction parsing --- flow-typed/npm/bcoin_vx.x.x.js | 1688 +------------------------------- lib/full_node.js | 2 + lib/trust_is_risk.js | 75 +- src/full_node.js | 2 + src/trust_is_risk.js | 81 +- test/full_node.js | 2 +- test/trust_is_risk.js | 115 +++ 7 files changed, 297 insertions(+), 1668 deletions(-) create mode 100644 test/trust_is_risk.js diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index cd32081..e1db501 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -1,1670 +1,50 @@ -// flow-typed signature: 52ec7d952e23091ff45f80adada48ac0 -// flow-typed version: <>/bcoin_v^1.0.0-beta.12/flow_v0.45.0 +// This is a work-in-progress attempt to type the bcoin library. -/** - * This is an autogenerated libdef stub for: - * - * 'bcoin' - * - * Fill this stub out by replacing all the `any` types. - * - * Once filled out, we encourage you to share your work with the - * community by sending a pull request to: - * https://github.com/flowtype/flow-typed - */ - -declare module 'bcoin' { - declare module.exports: any; -} - -/** - * We include stubs for each file inside this npm package in case you need to - * require those files directly. Feel free to delete any files that aren't - * needed. - */ -declare module 'bcoin/browser/empty' { - declare module.exports: any; -} - -declare module 'bcoin/browser/index' { - declare module.exports: any; -} - -declare module 'bcoin/browser/server' { - declare module.exports: any; -} - -declare module 'bcoin/browser/transform' { - declare module.exports: any; -} - -declare module 'bcoin/browser/wsproxy' { - declare module.exports: any; -} - -declare module 'bcoin/examples/chain' { - declare module.exports: any; -} - -declare module 'bcoin/examples/client' { - declare module.exports: any; -} - -declare module 'bcoin/examples/miner' { - declare module.exports: any; -} - -declare module 'bcoin/examples/node' { - declare module.exports: any; -} - -declare module 'bcoin/examples/peer' { - declare module.exports: any; -} - -declare module 'bcoin/examples/plugin' { - declare module.exports: any; -} - -declare module 'bcoin/examples/tx' { - declare module.exports: any; -} - -declare module 'bcoin/examples/wallet' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bcoin' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/certs' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/payment' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/paymentack' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/paymentdetails' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/paymentrequest' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/pk' { - declare module.exports: any; -} - -declare module 'bcoin/lib/bip70/x509' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/chain' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/chaindb' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/chainentry' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/common' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/layout-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/blockchain/layout' { - declare module.exports: any; -} - -declare module 'bcoin/lib/btc/amount' { - declare module.exports: any; -} - -declare module 'bcoin/lib/btc/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/btc/uri' { - declare module.exports: any; -} - -declare module 'bcoin/lib/coins/coins' { - declare module.exports: any; -} - -declare module 'bcoin/lib/coins/coinview' { - declare module.exports: any; -} - -declare module 'bcoin/lib/coins/compress' { - declare module.exports: any; -} - -declare module 'bcoin/lib/coins/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/coins/undocoins' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/aes' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/backend-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/backend' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/chachapoly' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/crypto' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/ec-elliptic' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/ec-secp256k1' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/ec' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/pk-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/pk' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/schnorr' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/scrypt' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/sha256' { - declare module.exports: any; -} - -declare module 'bcoin/lib/crypto/siphash' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/backends-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/backends' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/ldb' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/level' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/lowlevelup' { - declare module.exports: any; -} - -declare module 'bcoin/lib/db/memdb' { - declare module.exports: any; -} - -declare module 'bcoin/lib/env' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/common' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/hd' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/mnemonic' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/private' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/public' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/wordlist-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/wordlist' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/chinese-simplified' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/chinese-traditional' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/english' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/french' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/italian' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/japanese' { - declare module.exports: any; -} - -declare module 'bcoin/lib/hd/words/spanish' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/base' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/client' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/request' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/rpc' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/rpcbase' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/rpcclient' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/server' { - declare module.exports: any; -} - -declare module 'bcoin/lib/http/wallet' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mempool/fees' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mempool/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mempool/layout-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mempool/layout' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mempool/mempool' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mempool/mempoolentry' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mining/common' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mining/cpuminer' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mining/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mining/mine' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mining/miner' { - declare module.exports: any; -} - -declare module 'bcoin/lib/mining/template' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/bip150' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/bip151' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/bip152' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/common' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/dns-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/dns' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/framer' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/hostlist' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/packets' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/parser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/peer' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/pool' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/proxysocket' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/seeds/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/seeds/main' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/seeds/testnet' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/socks' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/tcp-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/tcp' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/upnp-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/net/upnp' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/config' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/fullnode' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/logger' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/node' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/nodeclient' { - declare module.exports: any; -} - -declare module 'bcoin/lib/node/spvnode' { - declare module.exports: any; -} - -declare module 'bcoin/lib/pkg' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/abstractblock' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/address' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/block' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/coin' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/headers' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/input' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/invitem' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/keyring' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/memblock' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/merkleblock' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/mtx' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/netaddress' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/outpoint' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/output' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/tx' { - declare module.exports: any; -} - -declare module 'bcoin/lib/primitives/txmeta' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/consensus' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/errors' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/network' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/networks' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/policy' { - declare module.exports: any; -} - -declare module 'bcoin/lib/protocol/timedata' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/common' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/opcode' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/program' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/script' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/scriptnum' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/sigcache' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/stack' { - declare module.exports: any; -} - -declare module 'bcoin/lib/script/witness' { - declare module.exports: any; -} - -declare module 'bcoin/lib/types' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/asn1' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/asyncemitter' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/asyncobject' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/base32' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/base58' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/bloom' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/co' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/encoding' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/fs' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/heap' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/ip' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/lazy-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/lazy' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/list' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/lock' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/lru' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/map' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/murmur3' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/native' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/nexttick-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/nexttick' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/nfkd-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/nfkd' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/pem' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/protobuf' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/rbt' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/reader' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/staticwriter' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/util' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/validator' { - declare module.exports: any; -} - -declare module 'bcoin/lib/utils/writer' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/account' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/client' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/common' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/http' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/layout-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/layout' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/masterkey' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/path' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/plugin' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/records' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/rpc' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/server' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/txdb' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/wallet' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/walletdb' { - declare module.exports: any; -} - -declare module 'bcoin/lib/wallet/walletkey' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/framer' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/index' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/jobs' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/master' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/packets' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/parser-client' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/parser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/worker-browser' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/worker' { - declare module.exports: any; -} - -declare module 'bcoin/lib/workers/workerpool' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/chaindb0to1' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/chaindb1to2' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/coins-old' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/coinview-old' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/compress-old' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/ensure-tip-index' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/walletdb2to3' { - declare module.exports: any; -} - -declare module 'bcoin/migrate/walletdb3to4' { - declare module.exports: any; +declare class bcoin$FullNode { + on(eventName : string, eventHandler : Function) : void; } -declare module 'bcoin/migrate/walletdb4to5' { - declare module.exports: any; +declare class bcoin$Address { + toBase58() : string; + static fromHash(string|Buffer) : bcoin$Address; } -declare module 'bcoin/migrate/walletdb5to6' { - declare module.exports: any; +declare class bcoin$TX { + inputs : bcoin$Input[]; + outputs : bcoin$Output[]; } -declare module 'bcoin/scripts/dump' { - declare module.exports: any; -} +declare class bcoin$Output { + script : bcoin$Script; + value : number; -declare module 'bcoin/scripts/fuzz' { - declare module.exports: any; + getType() : ('pubkeyhash' | 'multisig'); + getAddress() : bcoin$Address; } -declare module 'bcoin/scripts/gen' { - declare module.exports: any; +declare class bcoin$Input { + script : bcoin$Script; + getType() : ('pubkeyhash' | 'multisig'); + getAddress() : bcoin$Address; } -declare module 'bcoin/vendor/setimmediate' { - declare module.exports: any; +declare class bcoin$Script { + get(n : number) : (Buffer); } -declare module 'bcoin/vendor/unorm' { - declare module.exports: any; +declare module 'bcoin' { + declare module.exports: { + fullnode : Class, + script : Class, + primitives : { + Address : Class, + TX : Class, + Output : Class, + Input : Class + }, + crypto : { + hash160(str : (string | Buffer)) : (string | Buffer) + } + } } -// Filename aliases -declare module 'bcoin/browser/empty.js' { - declare module.exports: $Exports<'bcoin/browser/empty'>; -} -declare module 'bcoin/browser/index.js' { - declare module.exports: $Exports<'bcoin/browser/index'>; -} -declare module 'bcoin/browser/server.js' { - declare module.exports: $Exports<'bcoin/browser/server'>; -} -declare module 'bcoin/browser/transform.js' { - declare module.exports: $Exports<'bcoin/browser/transform'>; -} -declare module 'bcoin/browser/wsproxy.js' { - declare module.exports: $Exports<'bcoin/browser/wsproxy'>; -} -declare module 'bcoin/examples/chain.js' { - declare module.exports: $Exports<'bcoin/examples/chain'>; -} -declare module 'bcoin/examples/client.js' { - declare module.exports: $Exports<'bcoin/examples/client'>; -} -declare module 'bcoin/examples/miner.js' { - declare module.exports: $Exports<'bcoin/examples/miner'>; -} -declare module 'bcoin/examples/node.js' { - declare module.exports: $Exports<'bcoin/examples/node'>; -} -declare module 'bcoin/examples/peer.js' { - declare module.exports: $Exports<'bcoin/examples/peer'>; -} -declare module 'bcoin/examples/plugin.js' { - declare module.exports: $Exports<'bcoin/examples/plugin'>; -} -declare module 'bcoin/examples/tx.js' { - declare module.exports: $Exports<'bcoin/examples/tx'>; -} -declare module 'bcoin/examples/wallet.js' { - declare module.exports: $Exports<'bcoin/examples/wallet'>; -} -declare module 'bcoin/lib/bcoin.js' { - declare module.exports: $Exports<'bcoin/lib/bcoin'>; -} -declare module 'bcoin/lib/bip70/certs.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/certs'>; -} -declare module 'bcoin/lib/bip70/index.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/index'>; -} -declare module 'bcoin/lib/bip70/payment.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/payment'>; -} -declare module 'bcoin/lib/bip70/paymentack.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/paymentack'>; -} -declare module 'bcoin/lib/bip70/paymentdetails.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/paymentdetails'>; -} -declare module 'bcoin/lib/bip70/paymentrequest.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/paymentrequest'>; -} -declare module 'bcoin/lib/bip70/pk.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/pk'>; -} -declare module 'bcoin/lib/bip70/x509.js' { - declare module.exports: $Exports<'bcoin/lib/bip70/x509'>; -} -declare module 'bcoin/lib/blockchain/chain.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/chain'>; -} -declare module 'bcoin/lib/blockchain/chaindb.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/chaindb'>; -} -declare module 'bcoin/lib/blockchain/chainentry.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/chainentry'>; -} -declare module 'bcoin/lib/blockchain/common.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/common'>; -} -declare module 'bcoin/lib/blockchain/index.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/index'>; -} -declare module 'bcoin/lib/blockchain/layout-browser.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/layout-browser'>; -} -declare module 'bcoin/lib/blockchain/layout.js' { - declare module.exports: $Exports<'bcoin/lib/blockchain/layout'>; -} -declare module 'bcoin/lib/btc/amount.js' { - declare module.exports: $Exports<'bcoin/lib/btc/amount'>; -} -declare module 'bcoin/lib/btc/index.js' { - declare module.exports: $Exports<'bcoin/lib/btc/index'>; -} -declare module 'bcoin/lib/btc/uri.js' { - declare module.exports: $Exports<'bcoin/lib/btc/uri'>; -} -declare module 'bcoin/lib/coins/coins.js' { - declare module.exports: $Exports<'bcoin/lib/coins/coins'>; -} -declare module 'bcoin/lib/coins/coinview.js' { - declare module.exports: $Exports<'bcoin/lib/coins/coinview'>; -} -declare module 'bcoin/lib/coins/compress.js' { - declare module.exports: $Exports<'bcoin/lib/coins/compress'>; -} -declare module 'bcoin/lib/coins/index.js' { - declare module.exports: $Exports<'bcoin/lib/coins/index'>; -} -declare module 'bcoin/lib/coins/undocoins.js' { - declare module.exports: $Exports<'bcoin/lib/coins/undocoins'>; -} -declare module 'bcoin/lib/crypto/aes.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/aes'>; -} -declare module 'bcoin/lib/crypto/backend-browser.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/backend-browser'>; -} -declare module 'bcoin/lib/crypto/backend.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/backend'>; -} -declare module 'bcoin/lib/crypto/chachapoly.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/chachapoly'>; -} -declare module 'bcoin/lib/crypto/crypto.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/crypto'>; -} -declare module 'bcoin/lib/crypto/ec-elliptic.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/ec-elliptic'>; -} -declare module 'bcoin/lib/crypto/ec-secp256k1.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/ec-secp256k1'>; -} -declare module 'bcoin/lib/crypto/ec.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/ec'>; -} -declare module 'bcoin/lib/crypto/index.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/index'>; -} -declare module 'bcoin/lib/crypto/pk-browser.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/pk-browser'>; -} -declare module 'bcoin/lib/crypto/pk.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/pk'>; -} -declare module 'bcoin/lib/crypto/schnorr.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/schnorr'>; -} -declare module 'bcoin/lib/crypto/scrypt.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/scrypt'>; -} -declare module 'bcoin/lib/crypto/sha256.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/sha256'>; -} -declare module 'bcoin/lib/crypto/siphash.js' { - declare module.exports: $Exports<'bcoin/lib/crypto/siphash'>; -} -declare module 'bcoin/lib/db/backends-browser.js' { - declare module.exports: $Exports<'bcoin/lib/db/backends-browser'>; -} -declare module 'bcoin/lib/db/backends.js' { - declare module.exports: $Exports<'bcoin/lib/db/backends'>; -} -declare module 'bcoin/lib/db/index.js' { - declare module.exports: $Exports<'bcoin/lib/db/index'>; -} -declare module 'bcoin/lib/db/ldb.js' { - declare module.exports: $Exports<'bcoin/lib/db/ldb'>; -} -declare module 'bcoin/lib/db/level.js' { - declare module.exports: $Exports<'bcoin/lib/db/level'>; -} -declare module 'bcoin/lib/db/lowlevelup.js' { - declare module.exports: $Exports<'bcoin/lib/db/lowlevelup'>; -} -declare module 'bcoin/lib/db/memdb.js' { - declare module.exports: $Exports<'bcoin/lib/db/memdb'>; -} -declare module 'bcoin/lib/env.js' { - declare module.exports: $Exports<'bcoin/lib/env'>; -} -declare module 'bcoin/lib/hd/common.js' { - declare module.exports: $Exports<'bcoin/lib/hd/common'>; -} -declare module 'bcoin/lib/hd/hd.js' { - declare module.exports: $Exports<'bcoin/lib/hd/hd'>; -} -declare module 'bcoin/lib/hd/index.js' { - declare module.exports: $Exports<'bcoin/lib/hd/index'>; -} -declare module 'bcoin/lib/hd/mnemonic.js' { - declare module.exports: $Exports<'bcoin/lib/hd/mnemonic'>; -} -declare module 'bcoin/lib/hd/private.js' { - declare module.exports: $Exports<'bcoin/lib/hd/private'>; -} -declare module 'bcoin/lib/hd/public.js' { - declare module.exports: $Exports<'bcoin/lib/hd/public'>; -} -declare module 'bcoin/lib/hd/wordlist-browser.js' { - declare module.exports: $Exports<'bcoin/lib/hd/wordlist-browser'>; -} -declare module 'bcoin/lib/hd/wordlist.js' { - declare module.exports: $Exports<'bcoin/lib/hd/wordlist'>; -} -declare module 'bcoin/lib/hd/words/chinese-simplified.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/chinese-simplified'>; -} -declare module 'bcoin/lib/hd/words/chinese-traditional.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/chinese-traditional'>; -} -declare module 'bcoin/lib/hd/words/english.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/english'>; -} -declare module 'bcoin/lib/hd/words/french.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/french'>; -} -declare module 'bcoin/lib/hd/words/index.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/index'>; -} -declare module 'bcoin/lib/hd/words/italian.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/italian'>; -} -declare module 'bcoin/lib/hd/words/japanese.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/japanese'>; -} -declare module 'bcoin/lib/hd/words/spanish.js' { - declare module.exports: $Exports<'bcoin/lib/hd/words/spanish'>; -} -declare module 'bcoin/lib/http/base.js' { - declare module.exports: $Exports<'bcoin/lib/http/base'>; -} -declare module 'bcoin/lib/http/client.js' { - declare module.exports: $Exports<'bcoin/lib/http/client'>; -} -declare module 'bcoin/lib/http/index.js' { - declare module.exports: $Exports<'bcoin/lib/http/index'>; -} -declare module 'bcoin/lib/http/request.js' { - declare module.exports: $Exports<'bcoin/lib/http/request'>; -} -declare module 'bcoin/lib/http/rpc.js' { - declare module.exports: $Exports<'bcoin/lib/http/rpc'>; -} -declare module 'bcoin/lib/http/rpcbase.js' { - declare module.exports: $Exports<'bcoin/lib/http/rpcbase'>; -} -declare module 'bcoin/lib/http/rpcclient.js' { - declare module.exports: $Exports<'bcoin/lib/http/rpcclient'>; -} -declare module 'bcoin/lib/http/server.js' { - declare module.exports: $Exports<'bcoin/lib/http/server'>; -} -declare module 'bcoin/lib/http/wallet.js' { - declare module.exports: $Exports<'bcoin/lib/http/wallet'>; -} -declare module 'bcoin/lib/mempool/fees.js' { - declare module.exports: $Exports<'bcoin/lib/mempool/fees'>; -} -declare module 'bcoin/lib/mempool/index.js' { - declare module.exports: $Exports<'bcoin/lib/mempool/index'>; -} -declare module 'bcoin/lib/mempool/layout-browser.js' { - declare module.exports: $Exports<'bcoin/lib/mempool/layout-browser'>; -} -declare module 'bcoin/lib/mempool/layout.js' { - declare module.exports: $Exports<'bcoin/lib/mempool/layout'>; -} -declare module 'bcoin/lib/mempool/mempool.js' { - declare module.exports: $Exports<'bcoin/lib/mempool/mempool'>; -} -declare module 'bcoin/lib/mempool/mempoolentry.js' { - declare module.exports: $Exports<'bcoin/lib/mempool/mempoolentry'>; -} -declare module 'bcoin/lib/mining/common.js' { - declare module.exports: $Exports<'bcoin/lib/mining/common'>; -} -declare module 'bcoin/lib/mining/cpuminer.js' { - declare module.exports: $Exports<'bcoin/lib/mining/cpuminer'>; -} -declare module 'bcoin/lib/mining/index.js' { - declare module.exports: $Exports<'bcoin/lib/mining/index'>; -} -declare module 'bcoin/lib/mining/mine.js' { - declare module.exports: $Exports<'bcoin/lib/mining/mine'>; -} -declare module 'bcoin/lib/mining/miner.js' { - declare module.exports: $Exports<'bcoin/lib/mining/miner'>; -} -declare module 'bcoin/lib/mining/template.js' { - declare module.exports: $Exports<'bcoin/lib/mining/template'>; -} -declare module 'bcoin/lib/net/bip150.js' { - declare module.exports: $Exports<'bcoin/lib/net/bip150'>; -} -declare module 'bcoin/lib/net/bip151.js' { - declare module.exports: $Exports<'bcoin/lib/net/bip151'>; -} -declare module 'bcoin/lib/net/bip152.js' { - declare module.exports: $Exports<'bcoin/lib/net/bip152'>; -} -declare module 'bcoin/lib/net/common.js' { - declare module.exports: $Exports<'bcoin/lib/net/common'>; -} -declare module 'bcoin/lib/net/dns-browser.js' { - declare module.exports: $Exports<'bcoin/lib/net/dns-browser'>; -} -declare module 'bcoin/lib/net/dns.js' { - declare module.exports: $Exports<'bcoin/lib/net/dns'>; -} -declare module 'bcoin/lib/net/framer.js' { - declare module.exports: $Exports<'bcoin/lib/net/framer'>; -} -declare module 'bcoin/lib/net/hostlist.js' { - declare module.exports: $Exports<'bcoin/lib/net/hostlist'>; -} -declare module 'bcoin/lib/net/index.js' { - declare module.exports: $Exports<'bcoin/lib/net/index'>; -} -declare module 'bcoin/lib/net/packets.js' { - declare module.exports: $Exports<'bcoin/lib/net/packets'>; -} -declare module 'bcoin/lib/net/parser.js' { - declare module.exports: $Exports<'bcoin/lib/net/parser'>; -} -declare module 'bcoin/lib/net/peer.js' { - declare module.exports: $Exports<'bcoin/lib/net/peer'>; -} -declare module 'bcoin/lib/net/pool.js' { - declare module.exports: $Exports<'bcoin/lib/net/pool'>; -} -declare module 'bcoin/lib/net/proxysocket.js' { - declare module.exports: $Exports<'bcoin/lib/net/proxysocket'>; -} -declare module 'bcoin/lib/net/seeds/index.js' { - declare module.exports: $Exports<'bcoin/lib/net/seeds/index'>; -} -declare module 'bcoin/lib/net/seeds/main.js' { - declare module.exports: $Exports<'bcoin/lib/net/seeds/main'>; -} -declare module 'bcoin/lib/net/seeds/testnet.js' { - declare module.exports: $Exports<'bcoin/lib/net/seeds/testnet'>; -} -declare module 'bcoin/lib/net/socks.js' { - declare module.exports: $Exports<'bcoin/lib/net/socks'>; -} -declare module 'bcoin/lib/net/tcp-browser.js' { - declare module.exports: $Exports<'bcoin/lib/net/tcp-browser'>; -} -declare module 'bcoin/lib/net/tcp.js' { - declare module.exports: $Exports<'bcoin/lib/net/tcp'>; -} -declare module 'bcoin/lib/net/upnp-browser.js' { - declare module.exports: $Exports<'bcoin/lib/net/upnp-browser'>; -} -declare module 'bcoin/lib/net/upnp.js' { - declare module.exports: $Exports<'bcoin/lib/net/upnp'>; -} -declare module 'bcoin/lib/node/config.js' { - declare module.exports: $Exports<'bcoin/lib/node/config'>; -} -declare module 'bcoin/lib/node/fullnode.js' { - declare module.exports: $Exports<'bcoin/lib/node/fullnode'>; -} -declare module 'bcoin/lib/node/index.js' { - declare module.exports: $Exports<'bcoin/lib/node/index'>; -} -declare module 'bcoin/lib/node/logger.js' { - declare module.exports: $Exports<'bcoin/lib/node/logger'>; -} -declare module 'bcoin/lib/node/node.js' { - declare module.exports: $Exports<'bcoin/lib/node/node'>; -} -declare module 'bcoin/lib/node/nodeclient.js' { - declare module.exports: $Exports<'bcoin/lib/node/nodeclient'>; -} -declare module 'bcoin/lib/node/spvnode.js' { - declare module.exports: $Exports<'bcoin/lib/node/spvnode'>; -} -declare module 'bcoin/lib/pkg.js' { - declare module.exports: $Exports<'bcoin/lib/pkg'>; -} -declare module 'bcoin/lib/primitives/abstractblock.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/abstractblock'>; -} -declare module 'bcoin/lib/primitives/address.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/address'>; -} -declare module 'bcoin/lib/primitives/block.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/block'>; -} -declare module 'bcoin/lib/primitives/coin.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/coin'>; -} -declare module 'bcoin/lib/primitives/headers.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/headers'>; -} -declare module 'bcoin/lib/primitives/index.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/index'>; -} -declare module 'bcoin/lib/primitives/input.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/input'>; -} -declare module 'bcoin/lib/primitives/invitem.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/invitem'>; -} -declare module 'bcoin/lib/primitives/keyring.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/keyring'>; -} -declare module 'bcoin/lib/primitives/memblock.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/memblock'>; -} -declare module 'bcoin/lib/primitives/merkleblock.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/merkleblock'>; -} -declare module 'bcoin/lib/primitives/mtx.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/mtx'>; -} -declare module 'bcoin/lib/primitives/netaddress.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/netaddress'>; -} -declare module 'bcoin/lib/primitives/outpoint.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/outpoint'>; -} -declare module 'bcoin/lib/primitives/output.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/output'>; -} -declare module 'bcoin/lib/primitives/tx.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/tx'>; -} -declare module 'bcoin/lib/primitives/txmeta.js' { - declare module.exports: $Exports<'bcoin/lib/primitives/txmeta'>; -} -declare module 'bcoin/lib/protocol/consensus.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/consensus'>; -} -declare module 'bcoin/lib/protocol/errors.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/errors'>; -} -declare module 'bcoin/lib/protocol/index.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/index'>; -} -declare module 'bcoin/lib/protocol/network.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/network'>; -} -declare module 'bcoin/lib/protocol/networks.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/networks'>; -} -declare module 'bcoin/lib/protocol/policy.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/policy'>; -} -declare module 'bcoin/lib/protocol/timedata.js' { - declare module.exports: $Exports<'bcoin/lib/protocol/timedata'>; -} -declare module 'bcoin/lib/script/common.js' { - declare module.exports: $Exports<'bcoin/lib/script/common'>; -} -declare module 'bcoin/lib/script/index.js' { - declare module.exports: $Exports<'bcoin/lib/script/index'>; -} -declare module 'bcoin/lib/script/opcode.js' { - declare module.exports: $Exports<'bcoin/lib/script/opcode'>; -} -declare module 'bcoin/lib/script/program.js' { - declare module.exports: $Exports<'bcoin/lib/script/program'>; -} -declare module 'bcoin/lib/script/script.js' { - declare module.exports: $Exports<'bcoin/lib/script/script'>; -} -declare module 'bcoin/lib/script/scriptnum.js' { - declare module.exports: $Exports<'bcoin/lib/script/scriptnum'>; -} -declare module 'bcoin/lib/script/sigcache.js' { - declare module.exports: $Exports<'bcoin/lib/script/sigcache'>; -} -declare module 'bcoin/lib/script/stack.js' { - declare module.exports: $Exports<'bcoin/lib/script/stack'>; -} -declare module 'bcoin/lib/script/witness.js' { - declare module.exports: $Exports<'bcoin/lib/script/witness'>; -} -declare module 'bcoin/lib/types.js' { - declare module.exports: $Exports<'bcoin/lib/types'>; -} -declare module 'bcoin/lib/utils/asn1.js' { - declare module.exports: $Exports<'bcoin/lib/utils/asn1'>; -} -declare module 'bcoin/lib/utils/asyncemitter.js' { - declare module.exports: $Exports<'bcoin/lib/utils/asyncemitter'>; -} -declare module 'bcoin/lib/utils/asyncobject.js' { - declare module.exports: $Exports<'bcoin/lib/utils/asyncobject'>; -} -declare module 'bcoin/lib/utils/base32.js' { - declare module.exports: $Exports<'bcoin/lib/utils/base32'>; -} -declare module 'bcoin/lib/utils/base58.js' { - declare module.exports: $Exports<'bcoin/lib/utils/base58'>; -} -declare module 'bcoin/lib/utils/bloom.js' { - declare module.exports: $Exports<'bcoin/lib/utils/bloom'>; -} -declare module 'bcoin/lib/utils/co.js' { - declare module.exports: $Exports<'bcoin/lib/utils/co'>; -} -declare module 'bcoin/lib/utils/encoding.js' { - declare module.exports: $Exports<'bcoin/lib/utils/encoding'>; -} -declare module 'bcoin/lib/utils/fs.js' { - declare module.exports: $Exports<'bcoin/lib/utils/fs'>; -} -declare module 'bcoin/lib/utils/heap.js' { - declare module.exports: $Exports<'bcoin/lib/utils/heap'>; -} -declare module 'bcoin/lib/utils/index.js' { - declare module.exports: $Exports<'bcoin/lib/utils/index'>; -} -declare module 'bcoin/lib/utils/ip.js' { - declare module.exports: $Exports<'bcoin/lib/utils/ip'>; -} -declare module 'bcoin/lib/utils/lazy-browser.js' { - declare module.exports: $Exports<'bcoin/lib/utils/lazy-browser'>; -} -declare module 'bcoin/lib/utils/lazy.js' { - declare module.exports: $Exports<'bcoin/lib/utils/lazy'>; -} -declare module 'bcoin/lib/utils/list.js' { - declare module.exports: $Exports<'bcoin/lib/utils/list'>; -} -declare module 'bcoin/lib/utils/lock.js' { - declare module.exports: $Exports<'bcoin/lib/utils/lock'>; -} -declare module 'bcoin/lib/utils/lru.js' { - declare module.exports: $Exports<'bcoin/lib/utils/lru'>; -} -declare module 'bcoin/lib/utils/map.js' { - declare module.exports: $Exports<'bcoin/lib/utils/map'>; -} -declare module 'bcoin/lib/utils/murmur3.js' { - declare module.exports: $Exports<'bcoin/lib/utils/murmur3'>; -} -declare module 'bcoin/lib/utils/native.js' { - declare module.exports: $Exports<'bcoin/lib/utils/native'>; -} -declare module 'bcoin/lib/utils/nexttick-browser.js' { - declare module.exports: $Exports<'bcoin/lib/utils/nexttick-browser'>; -} -declare module 'bcoin/lib/utils/nexttick.js' { - declare module.exports: $Exports<'bcoin/lib/utils/nexttick'>; -} -declare module 'bcoin/lib/utils/nfkd-browser.js' { - declare module.exports: $Exports<'bcoin/lib/utils/nfkd-browser'>; -} -declare module 'bcoin/lib/utils/nfkd.js' { - declare module.exports: $Exports<'bcoin/lib/utils/nfkd'>; -} -declare module 'bcoin/lib/utils/pem.js' { - declare module.exports: $Exports<'bcoin/lib/utils/pem'>; -} -declare module 'bcoin/lib/utils/protobuf.js' { - declare module.exports: $Exports<'bcoin/lib/utils/protobuf'>; -} -declare module 'bcoin/lib/utils/rbt.js' { - declare module.exports: $Exports<'bcoin/lib/utils/rbt'>; -} -declare module 'bcoin/lib/utils/reader.js' { - declare module.exports: $Exports<'bcoin/lib/utils/reader'>; -} -declare module 'bcoin/lib/utils/staticwriter.js' { - declare module.exports: $Exports<'bcoin/lib/utils/staticwriter'>; -} -declare module 'bcoin/lib/utils/util.js' { - declare module.exports: $Exports<'bcoin/lib/utils/util'>; -} -declare module 'bcoin/lib/utils/validator.js' { - declare module.exports: $Exports<'bcoin/lib/utils/validator'>; -} -declare module 'bcoin/lib/utils/writer.js' { - declare module.exports: $Exports<'bcoin/lib/utils/writer'>; -} -declare module 'bcoin/lib/wallet/account.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/account'>; -} -declare module 'bcoin/lib/wallet/client.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/client'>; -} -declare module 'bcoin/lib/wallet/common.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/common'>; -} -declare module 'bcoin/lib/wallet/http.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/http'>; -} -declare module 'bcoin/lib/wallet/index.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/index'>; -} -declare module 'bcoin/lib/wallet/layout-browser.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/layout-browser'>; -} -declare module 'bcoin/lib/wallet/layout.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/layout'>; -} -declare module 'bcoin/lib/wallet/masterkey.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/masterkey'>; -} -declare module 'bcoin/lib/wallet/path.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/path'>; -} -declare module 'bcoin/lib/wallet/plugin.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/plugin'>; -} -declare module 'bcoin/lib/wallet/records.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/records'>; -} -declare module 'bcoin/lib/wallet/rpc.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/rpc'>; -} -declare module 'bcoin/lib/wallet/server.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/server'>; -} -declare module 'bcoin/lib/wallet/txdb.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/txdb'>; -} -declare module 'bcoin/lib/wallet/wallet.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/wallet'>; -} -declare module 'bcoin/lib/wallet/walletdb.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/walletdb'>; -} -declare module 'bcoin/lib/wallet/walletkey.js' { - declare module.exports: $Exports<'bcoin/lib/wallet/walletkey'>; -} -declare module 'bcoin/lib/workers/framer.js' { - declare module.exports: $Exports<'bcoin/lib/workers/framer'>; -} -declare module 'bcoin/lib/workers/index.js' { - declare module.exports: $Exports<'bcoin/lib/workers/index'>; -} -declare module 'bcoin/lib/workers/jobs.js' { - declare module.exports: $Exports<'bcoin/lib/workers/jobs'>; -} -declare module 'bcoin/lib/workers/master.js' { - declare module.exports: $Exports<'bcoin/lib/workers/master'>; -} -declare module 'bcoin/lib/workers/packets.js' { - declare module.exports: $Exports<'bcoin/lib/workers/packets'>; -} -declare module 'bcoin/lib/workers/parser-client.js' { - declare module.exports: $Exports<'bcoin/lib/workers/parser-client'>; -} -declare module 'bcoin/lib/workers/parser.js' { - declare module.exports: $Exports<'bcoin/lib/workers/parser'>; -} -declare module 'bcoin/lib/workers/worker-browser.js' { - declare module.exports: $Exports<'bcoin/lib/workers/worker-browser'>; -} -declare module 'bcoin/lib/workers/worker.js' { - declare module.exports: $Exports<'bcoin/lib/workers/worker'>; -} -declare module 'bcoin/lib/workers/workerpool.js' { - declare module.exports: $Exports<'bcoin/lib/workers/workerpool'>; -} -declare module 'bcoin/migrate/chaindb0to1.js' { - declare module.exports: $Exports<'bcoin/migrate/chaindb0to1'>; -} -declare module 'bcoin/migrate/chaindb1to2.js' { - declare module.exports: $Exports<'bcoin/migrate/chaindb1to2'>; -} -declare module 'bcoin/migrate/coins-old.js' { - declare module.exports: $Exports<'bcoin/migrate/coins-old'>; -} -declare module 'bcoin/migrate/coinview-old.js' { - declare module.exports: $Exports<'bcoin/migrate/coinview-old'>; -} -declare module 'bcoin/migrate/compress-old.js' { - declare module.exports: $Exports<'bcoin/migrate/compress-old'>; -} -declare module 'bcoin/migrate/ensure-tip-index.js' { - declare module.exports: $Exports<'bcoin/migrate/ensure-tip-index'>; -} -declare module 'bcoin/migrate/walletdb2to3.js' { - declare module.exports: $Exports<'bcoin/migrate/walletdb2to3'>; -} -declare module 'bcoin/migrate/walletdb3to4.js' { - declare module.exports: $Exports<'bcoin/migrate/walletdb3to4'>; -} -declare module 'bcoin/migrate/walletdb4to5.js' { - declare module.exports: $Exports<'bcoin/migrate/walletdb4to5'>; -} -declare module 'bcoin/migrate/walletdb5to6.js' { - declare module.exports: $Exports<'bcoin/migrate/walletdb5to6'>; -} -declare module 'bcoin/scripts/dump.js' { - declare module.exports: $Exports<'bcoin/scripts/dump'>; -} -declare module 'bcoin/scripts/fuzz.js' { - declare module.exports: $Exports<'bcoin/scripts/fuzz'>; -} -declare module 'bcoin/scripts/gen.js' { - declare module.exports: $Exports<'bcoin/scripts/gen'>; -} -declare module 'bcoin/vendor/setimmediate.js' { - declare module.exports: $Exports<'bcoin/vendor/setimmediate'>; -} -declare module 'bcoin/vendor/unorm.js' { - declare module.exports: $Exports<'bcoin/vendor/unorm'>; -} diff --git a/lib/full_node.js b/lib/full_node.js index 947cc83..79b1948 100644 --- a/lib/full_node.js +++ b/lib/full_node.js @@ -3,6 +3,8 @@ var bcoin = require('bcoin'); var TrustIsRisk = require('./trust_is_risk'); class FullNode extends bcoin.fullnode { + + constructor(options ) { super(options); this.trust = new TrustIsRisk(this); diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index ed2e4e1..336a6be 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -1,5 +1,14 @@ // var bcoin = require('bcoin'); +var Address = bcoin.primitives.Address; + + // base58 bitcoin address + + + + + + class TrustIsRisk { @@ -11,16 +20,72 @@ class TrustIsRisk { } addTX(tx ) { - if (!this.isTrustTX(tx)) return false; - // TODO + var trustChange = this.parseTXAsTrustChange(tx); + if (trustChange === null) return false; + return true; } - isTrustTX(tx ) { - return true; // TODO + // Parses a transaction as a trust change, or returns null if the + // transaction is not a TIR transaction. + parseTXAsTrustChange(tx ) { + var trustChange = this.parseTXAsTrustIncrease(tx); + if (trustChange === null) { + trustChange = this.parseTXAsTrustDecrease(tx); + } + + return trustChange; } -} + parseTXAsTrustIncrease(tx ) { + if (tx.inputs.length !== 1) return null; + if (tx.inputs[0].getType() !== 'pubkeyhash') return null; + var sender = tx.inputs[0].getAddress(); + + if (tx.outputs.length == 0 || tx.outputs.length > 2) return null; + + var trustChanges = []; + for (var i = 0; i < tx.outputs.length; i++) { + if (this.isChangeOutput(tx.outputs[i], sender)) continue; + + var trustChange = this.parseOutputAsDirectTrust(tx.outputs[i], sender.toBase58()); + if (trustChange === null) return null; + trustChanges.push(trustChange); + } + if (trustChanges.length !== 1) return null; + + return trustChanges[0]; + } + + parseTXAsTrustDecrease(tx ) { + return null; + } + + isChangeOutput(output , sender ) { + return (output.getType() === 'pubkeyhash') + && (output.getAddress().toBase58() === sender.toBase58()); + } + + parseOutputAsDirectTrust(output , sender ) { + if (output.getType() !== 'multisig') return null; + + var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58() + var addressB = Address.fromHash(bcoin.crypto.hash160(output.script.get(2))).toBase58(); + + if (addressA === addressB) return null; + var receiver; + if (addressA === sender) receiver = addressB; + else if (addressB === sender) receiver = addressA; + else return null; + + return { + from: sender, + to: receiver, + amount: Number(output.value) + }; + } + +} module.exports = TrustIsRisk; diff --git a/src/full_node.js b/src/full_node.js index 2798307..f6b31f8 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -3,6 +3,8 @@ var bcoin = require('bcoin'); var TrustIsRisk = require('./trust_is_risk'); class FullNode extends bcoin.fullnode { + trust : TrustIsRisk + constructor(options : Object) { super(options); this.trust = new TrustIsRisk(this); diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 8be984d..43d13b2 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,26 +1,91 @@ // @flow var bcoin = require('bcoin'); +var Address = bcoin.primitives.Address; + +type Entity = string; // base58 bitcoin address +type DirectTrust = { + from : Entity, + to: Entity, + amount: number +} +type TrustChange = DirectTrust; class TrustIsRisk { - node : bcoin.fullnode + node : bcoin$FullNode - constructor(node : bcoin.fullnode) { + constructor(node : bcoin$FullNode) { this.node = node; this.node.on('tx', this.addTX.bind(this)); } - addTX(tx : bcoin.TX) : boolean { - if (!this.isTrustTX(tx)) return false; - // TODO + addTX(tx : bcoin$TX) : boolean { + var trustChange = this.parseTXAsTrustChange(tx); + if (trustChange === null) return false; + return true; } - isTrustTX(tx : bcoin.TX) : boolean { - return true; // TODO + // Parses a transaction as a trust change, or returns null if the + // transaction is not a TIR transaction. + parseTXAsTrustChange(tx : bcoin$TX) : ?TrustChange { + var trustChange = this.parseTXAsTrustIncrease(tx); + if (trustChange === null) { + trustChange = this.parseTXAsTrustDecrease(tx); + } + + return trustChange; } -} + parseTXAsTrustIncrease(tx : bcoin$TX) : ?TrustChange { + if (tx.inputs.length !== 1) return null; + if (tx.inputs[0].getType() !== 'pubkeyhash') return null; + var sender = tx.inputs[0].getAddress(); + + if (tx.outputs.length == 0 || tx.outputs.length > 2) return null; + var trustChanges = []; + for (var i = 0; i < tx.outputs.length; i++) { + if (this.isChangeOutput(tx.outputs[i], sender)) continue; + + var trustChange = this.parseOutputAsDirectTrust(tx.outputs[i], sender.toBase58()); + if (trustChange === null) return null; + trustChanges.push(trustChange); + } + if (trustChanges.length !== 1) return null; + + return trustChanges[0]; + } + + parseTXAsTrustDecrease(tx : bcoin$TX) : ?TrustChange { + return null; + } + + isChangeOutput(output : bcoin$Output, sender : bcoin$Address) : boolean { + return (output.getType() === 'pubkeyhash') + && (output.getAddress().toBase58() === sender.toBase58()); + } + + parseOutputAsDirectTrust(output : bcoin$Output, sender : Entity) : ?DirectTrust { + if (output.getType() !== 'multisig') return null; + + var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58() + var addressB = Address.fromHash(bcoin.crypto.hash160(output.script.get(2))).toBase58(); + + if (addressA === addressB) return null; + + var receiver; + if (addressA === sender) receiver = addressB; + else if (addressB === sender) receiver = addressA; + else return null; + + return { + from: sender, + to: receiver, + amount: Number(output.value) + }; + } + +} module.exports = TrustIsRisk; diff --git a/test/full_node.js b/test/full_node.js index 64ad3b5..d6308a8 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -6,7 +6,7 @@ var sinon = require('sinon'); var should = require('should'); require('should-sinon'); -describe('TrustIsRisk.FullNode', () => { +describe('FullNode', () => { var node = null; var walletDB = null; sinon.spy(Trust.TrustIsRisk.prototype, 'addTX'); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js new file mode 100644 index 0000000..5c6e95a --- /dev/null +++ b/test/trust_is_risk.js @@ -0,0 +1,115 @@ +var Trust = require('../'); +var bcoin = require('bcoin'); +var testHelpers = require('./helpers'); +var consensus = require('bcoin/lib/protocol/consensus'); +var sinon = require('sinon'); +var should = require('should'); +require('should-sinon'); + +describe('TrustIsRisk', () => { + var inputP2PKH = new bcoin.primitives.Input({ + prevout: { + hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', + index: 0xfffffffa + }, script: bcoin.script.fromString( + // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE + "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") + }); + + var outputOneOfTwoMultsig = new bcoin.primitives.Output({ + script: bcoin.script.fromString( + // 1/{17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE, 1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx} + "OP_1 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083 0x28 0x2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b OP_2 OP_CHECKMULTISIG"), + value: 42 + }); + + var tir = null, mtx = null, changeScript = null; + beforeEach(() => { + tir = new Trust.TrustIsRisk(new bcoin.fullnode({})); + + mtx = new bcoin.primitives.MTX({ + inputs: [ + inputP2PKH + ], + outputs: [ + outputOneOfTwoMultsig + ] + }); + + changeScript = bcoin.script.fromString( + // Pays to 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE + "OP_DUP OP_HASH160 0x14 0x46005EF459C9E7C37AF8871D25BC39D0EA0534D1 OP_EQUALVERIFY OP_CHECKSIG"); + }); + + describe('.parseTXAsTrustIncrease', () => { + it('correctly parses trust increasing transactions', () => { + var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + + should(trustChange).deepEqual({ + from: "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE", + to: "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx", + amount: 42 + }); + }); + + it('rejects transactions with more than one input', () => { + mtx.inputs.push(inputP2PKH); + var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + + should(trustChange).equal(null); + }); + + it('correctly parses trust increasing transactions with change outputs', () => { + mtx.outputs[0].value -= 10; + mtx.outputs.push(new bcoin.primitives.Output({ + script: changeScript, + value: 10 + })); + var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + + should(trustChange).deepEqual({ + from: "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE", + to: "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx", + amount: 32 + }); + }); + + it('rejects transactions with two change outputs', () => { + mtx.outputs[0].value -= 10; + for (var i = 0; i < 2; i++) { + mtx.outputs.push(new bcoin.primitives.Output({ + script: changeScript, + value: 5 + })); + } + var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + + should(trustChange).equal(null); + }); + + it('rejects transactions with a second output that\'s not a change output', () => { + mtx.outputs[0].value -= 10; + mtx.outputs.push(new bcoin.primitives.Output({ + script: bcoin.script.fromString( + // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND + "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), + value: 10 + })); + var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + + should(trustChange).equal(null); + }); + + it('rejects transactions with no trust outputs', () => { + mtx.outputs[0] = new bcoin.primitives.Output({ + script: bcoin.script.fromString( + // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND + "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), + value: 10 + }); + var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + + should(trustChange).equal(null); + }); + }); +}); From 00e4c469e76deb37d4faa191f6c1b601bc1edee3 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Wed, 17 May 2017 19:10:52 +0000 Subject: [PATCH 003/540] Implement TrustIsRisk.prototype.getDirect() --- lib/trust_is_risk.js | 22 +++++++++++++++++++++- src/trust_is_risk.js | 22 +++++++++++++++++++++- test/trust_is_risk.js | 42 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 336a6be..496d37a 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -12,16 +12,36 @@ var Address = bcoin.primitives.Address; class TrustIsRisk { + + // Direct trust map + + + + + constructor(node ) { this.node = node; + this.trust = {}; this.node.on('tx', this.addTX.bind(this)); } + getDirect(from , to ) { + if (!this.trust.hasOwnProperty(from)) return 0; + if (!this.trust[from].hasOwnProperty(to)) return 0; + return this.trust[from][to]; + } + addTX(tx ) { var trustChange = this.parseTXAsTrustChange(tx); - if (trustChange === null) return false; + if (!trustChange) return false; + + if (!this.trust.hasOwnProperty(trustChange.from)) this.trust[trustChange.from] = {} + if (!this.trust[trustChange.from].hasOwnProperty(trustChange.to)) { + this.trust[trustChange.from][trustChange.to] = 0 + } + this.trust[trustChange.from][trustChange.to] += trustChange.amount; return true; } diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 43d13b2..be4c8af 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -12,16 +12,36 @@ type TrustChange = DirectTrust; class TrustIsRisk { node : bcoin$FullNode + + // Direct trust map + trust : { + [from : Entity] : ({ + [to : Entity] : number + }) + }; constructor(node : bcoin$FullNode) { this.node = node; + this.trust = {}; this.node.on('tx', this.addTX.bind(this)); } + getDirect(from : Entity, to : Entity) : number { + if (!this.trust.hasOwnProperty(from)) return 0; + if (!this.trust[from].hasOwnProperty(to)) return 0; + return this.trust[from][to]; + } + addTX(tx : bcoin$TX) : boolean { var trustChange = this.parseTXAsTrustChange(tx); - if (trustChange === null) return false; + if (!trustChange) return false; + + if (!this.trust.hasOwnProperty(trustChange.from)) this.trust[trustChange.from] = {} + if (!this.trust[trustChange.from].hasOwnProperty(trustChange.to)) { + this.trust[trustChange.from][trustChange.to] = 0 + } + this.trust[trustChange.from][trustChange.to] += trustChange.amount; return true; } diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 5c6e95a..a03ef5f 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -7,18 +7,21 @@ var should = require('should'); require('should-sinon'); describe('TrustIsRisk', () => { + var sender = "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE"; + var receiver = "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx"; + var inputP2PKH = new bcoin.primitives.Input({ prevout: { hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', index: 0xfffffffa }, script: bcoin.script.fromString( - // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE + // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (sender) "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") }); var outputOneOfTwoMultsig = new bcoin.primitives.Output({ script: bcoin.script.fromString( - // 1/{17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE, 1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx} + // 1/{17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (sender), 1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx (receiver)} "OP_1 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083 0x28 0x2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b OP_2 OP_CHECKMULTISIG"), value: 42 }); @@ -46,8 +49,8 @@ describe('TrustIsRisk', () => { var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); should(trustChange).deepEqual({ - from: "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE", - to: "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx", + from: sender, + to: receiver, amount: 42 }); }); @@ -68,8 +71,8 @@ describe('TrustIsRisk', () => { var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); should(trustChange).deepEqual({ - from: "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE", - to: "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx", + from: sender, + to: receiver, amount: 32 }); }); @@ -91,7 +94,7 @@ describe('TrustIsRisk', () => { mtx.outputs[0].value -= 10; mtx.outputs.push(new bcoin.primitives.Output({ script: bcoin.script.fromString( - // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND + // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND (neither sender or receiver) "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), value: 10 })); @@ -103,7 +106,7 @@ describe('TrustIsRisk', () => { it('rejects transactions with no trust outputs', () => { mtx.outputs[0] = new bcoin.primitives.Output({ script: bcoin.script.fromString( - // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND + // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND (neither sender or receiver) "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), value: 10 }); @@ -112,4 +115,27 @@ describe('TrustIsRisk', () => { should(trustChange).equal(null); }); }); + + describe('.getDirect()', () => { + it('returns zero for two arbitary parties that do not trust each other', () => { + should(tir.getDirect(sender, receiver)).equal(0); + should(tir.getDirect(receiver, sender)).equal(0); + should(tir.getDirect("1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND", sender)).equal(0); + should(tir.getDirect(sender, "1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND")).equal(0); + }); + }); + + describe('.addTX()', () => { + it('correctly increases direct trust when adding a trust-increasing transaction', () => { + mtx.outputs[0].value -= 10; + mtx.outputs.push(new bcoin.primitives.Output({ + script: changeScript, + value: 10 + })); + tir.addTX(mtx.toTX()); + + should(tir.getDirect(sender, receiver)).equal(32); + should(tir.getDirect(receiver, sender)).equal(0); // Trust is not bi-directional + }); + }); }); From 913fd8d3761dc55499ceca6fd6d1ae6c0c12d14c Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Thu, 18 May 2017 18:29:52 +0000 Subject: [PATCH 004/540] Implement trust decreasing transaction parsing --- flow-typed/npm/bcoin_vx.x.x.js | 11 +- lib/trust_is_risk.js | 185 ++++++++++++++++++++------- package.json | 1 + src/trust_is_risk.js | 185 ++++++++++++++++++++------- test/helpers.js | 9 ++ test/trust_is_risk.js | 222 ++++++++++++++++++--------------- 6 files changed, 417 insertions(+), 196 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index e1db501..d07ac45 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -12,6 +12,8 @@ declare class bcoin$Address { declare class bcoin$TX { inputs : bcoin$Input[]; outputs : bcoin$Output[]; + + hash(enc : ?'hex') : Buffer; } declare class bcoin$Output { @@ -24,6 +26,7 @@ declare class bcoin$Output { declare class bcoin$Input { script : bcoin$Script; + prevout : bcoin$Outpoint; getType() : ('pubkeyhash' | 'multisig'); getAddress() : bcoin$Address; } @@ -32,6 +35,11 @@ declare class bcoin$Script { get(n : number) : (Buffer); } +declare class bcoin$Outpoint { + hash : Buffer; + index : number; +} + declare module 'bcoin' { declare module.exports: { fullnode : Class, @@ -40,7 +48,8 @@ declare module 'bcoin' { Address : Class, TX : Class, Output : Class, - Input : Class + Input : Class, + Outpoint : Class }, crypto : { hash160(str : (string | Buffer)) : (string | Buffer) diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 496d37a..60a5ac2 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -1,92 +1,181 @@ // var bcoin = require('bcoin'); +var assert = require('assert'); var Address = bcoin.primitives.Address; // base58 bitcoin address - + + + + class TrustIsRisk { - // Direct trust map - + - + + + + + constructor(node ) { this.node = node; - this.trust = {}; + this.directTrust = {}; + this.TXToTrust = {}; this.node.on('tx', this.addTX.bind(this)); } - getDirect(from , to ) { - if (!this.trust.hasOwnProperty(from)) return 0; - if (!this.trust[from].hasOwnProperty(to)) return 0; - return this.trust[from][to]; + getDirectTrust(from , to ) { + if (!this.directTrust.hasOwnProperty(from)) return 0; + if (!this.directTrust[from].hasOwnProperty(to)) return 0; + return this.directTrust[from][to]; } + // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network + // if successful. + // Returns true if the transaction is a TIR transaction and was successfully added to the + // network, false otherwise. + // Throws an error if the transaction was processed earlier. addTX(tx ) { - var trustChange = this.parseTXAsTrustChange(tx); - if (!trustChange) return false; + var txHash = tx.hash().toString('hex'); + if (this.TXToTrust.hasOwnProperty(txHash)) { + throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen again.'); + } - if (!this.trust.hasOwnProperty(trustChange.from)) this.trust[trustChange.from] = {} - if (!this.trust[trustChange.from].hasOwnProperty(trustChange.to)) { - this.trust[trustChange.from][trustChange.to] = 0 + var trustChanges = this.getTrustChanges(tx); + if (trustChanges.length === 0) return false; + else { + trustChanges.map(this.applyTrustChange.bind(this)); + return true; + } + } + + // Returns a list of trust changes that a transaction causes, which will be one of the following: + // * An empty list (for non-TIR transactions). + // * A list containing a single trust increase (for trust-increasing transactions). + // * A list containing one or more trust decreases (for trust-decreasing transactions). + getTrustChanges(tx ) { + var trustIncrease = this.parseTXAsTrustIncrease(tx); + if (trustIncrease !== null) { + return [trustIncrease]; + } else { + return this.getTrustDecreases(tx); } - this.trust[trustChange.from][trustChange.to] += trustChange.amount; - - return true; } - // Parses a transaction as a trust change, or returns null if the - // transaction is not a TIR transaction. - parseTXAsTrustChange(tx ) { - var trustChange = this.parseTXAsTrustIncrease(tx); - if (trustChange === null) { - trustChange = this.parseTXAsTrustDecrease(tx); + applyTrustChange(trustChange ) { + if (!this.directTrust.hasOwnProperty(trustChange.from)) this.directTrust[trustChange.from] = {}; + if (!this.directTrust[trustChange.from].hasOwnProperty(trustChange.to)) { + this.directTrust[trustChange.from][trustChange.to] = 0 } - return trustChange; + this.directTrust[trustChange.from][trustChange.to] += trustChange.amount; + + if (this.directTrust[trustChange.from][trustChange.to] > 0) { + this.TXToTrust[trustChange.txHash] = { + from: trustChange.from, + to: trustChange.to, + amount: this.directTrust[trustChange.from][trustChange.to], + txHash: trustChange.txHash, + outputIndex: trustChange.outputIndex + }; + } } - parseTXAsTrustIncrease(tx ) { + parseTXAsTrustIncrease(tx ) { if (tx.inputs.length !== 1) return null; - if (tx.inputs[0].getType() !== 'pubkeyhash') return null; - var sender = tx.inputs[0].getAddress(); + if (tx.inputs[0].getType() !== 'pubkeyhash') return null; // TODO: This is unreliable + if (this.TXToTrust[tx.inputs[0].prevout.hash.toString('hex')]) return null; + var sender = tx.inputs[0].getAddress().toBase58(); - if (tx.outputs.length == 0 || tx.outputs.length > 2) return null; + if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; - var trustChanges = []; - for (var i = 0; i < tx.outputs.length; i++) { - if (this.isChangeOutput(tx.outputs[i], sender)) continue; + var trustOutputs = this.searchForDirectTrustOutputs(tx, sender); + if (trustOutputs.length !== 1) return null; - var trustChange = this.parseOutputAsDirectTrust(tx.outputs[i], sender.toBase58()); - if (trustChange === null) return null; - trustChanges.push(trustChange); - } - if (trustChanges.length !== 1) return null; + var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length + if (changeOutputCount + 1 !== tx.outputs.length) return null; - return trustChanges[0]; + return trustOutputs[0]; } - parseTXAsTrustDecrease(tx ) { - return null; + getTrustDecreases(tx ) { + var inputTrusts = this.getInputTrusts(tx.inputs); + return inputTrusts.map(this.getTrustDecrease.bind(this, tx)); + } + + getInputTrusts(inputs ) { + return inputs.map((input) => { + var trust = this.TXToTrust[input.prevout.hash.toString('hex')] + if (trust && trust.outputIndex === input.prevout.index) return trust; + else return null; + }).filter(Boolean); + } + + getTrustDecrease(tx , prevTrust ) { + var txHash = tx.hash().toString('hex'); + var nullifyTrust = { + from: prevTrust.from, + to: prevTrust.to, + amount: -prevTrust.amount, + txHash, + outputIndex: null + }; + + if (tx.inputs.length !== 1) return nullifyTrust; + + var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.from, prevTrust.to); + if (trustOutputs.length != 1) return nullifyTrust; + var nextTrust = trustOutputs[0]; + + assert(nextTrust.from === prevTrust.from); + assert(nextTrust.to === prevTrust.to); + + var trustAmountChange = nextTrust.amount - prevTrust.amount; + assert(trustAmountChange <= 0); + return { + from: nextTrust.from, + to: nextTrust.to, + amount: trustAmountChange, + txHash, + outputIndex: nextTrust.outputIndex + } + } + + // Looks for direct trust outputs that originate from a sender in an array of bitcoin outputs. + // If the recipient parameter is set, it will limit the results only to the outputs being sent to + // the recipient. + searchForDirectTrustOutputs(tx , sender , recipient ) { + var directTrusts = tx.outputs.map((output, outputIndex) => + this.parseOutputAsDirectTrust(tx, outputIndex, sender) + ).filter(Boolean); + + if (recipient) { + directTrusts.filter((trust) => trust.to === recipient); + } + + return directTrusts; } - isChangeOutput(output , sender ) { + isChangeOutput(output , sender ) { return (output.getType() === 'pubkeyhash') - && (output.getAddress().toBase58() === sender.toBase58()); + && (output.getAddress().toBase58() === sender); } - parseOutputAsDirectTrust(output , sender ) { + parseOutputAsDirectTrust(tx , outputIndex , sender ) + { + var txHash = tx.hash().toString('hex'); + var output = tx.outputs[outputIndex]; if (output.getType() !== 'multisig') return null; var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58() @@ -94,15 +183,17 @@ class TrustIsRisk { if (addressA === addressB) return null; - var receiver; - if (addressA === sender) receiver = addressB; - else if (addressB === sender) receiver = addressA; + var recipient; + if (addressA === sender) recipient = addressB; + else if (addressB === sender) recipient = addressA; else return null; return { from: sender, - to: receiver, - amount: Number(output.value) + to: recipient, + amount: Number(output.value), + txHash, + outputIndex }; } diff --git a/package.json b/package.json index af50d22..9928a84 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "devDependencies": { "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.0", + "mocha": "^3.4.2", "should": "^11.2.1", "should-sinon": "0.0.5", "sinon": "^2.2.0" diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index be4c8af..0babc19 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,92 +1,181 @@ // @flow var bcoin = require('bcoin'); +var assert = require('assert'); var Address = bcoin.primitives.Address; type Entity = string; // base58 bitcoin address type DirectTrust = { from : Entity, to: Entity, - amount: number + amount: number, + txHash: string, + outputIndex: ?number, // Not set for nullifying trust changes } type TrustChange = DirectTrust; +type TXHash = string; class TrustIsRisk { node : bcoin$FullNode - // Direct trust map - trust : { + directTrust : { [from : Entity] : ({ [to : Entity] : number }) - }; + } + + TXToTrust : { + [hash : TXHash] : DirectTrust + } constructor(node : bcoin$FullNode) { this.node = node; - this.trust = {}; + this.directTrust = {}; + this.TXToTrust = {}; this.node.on('tx', this.addTX.bind(this)); } - getDirect(from : Entity, to : Entity) : number { - if (!this.trust.hasOwnProperty(from)) return 0; - if (!this.trust[from].hasOwnProperty(to)) return 0; - return this.trust[from][to]; + getDirectTrust(from : Entity, to : Entity) : number { + if (!this.directTrust.hasOwnProperty(from)) return 0; + if (!this.directTrust[from].hasOwnProperty(to)) return 0; + return this.directTrust[from][to]; } + // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network + // if successful. + // Returns true if the transaction is a TIR transaction and was successfully added to the + // network, false otherwise. + // Throws an error if the transaction was processed earlier. addTX(tx : bcoin$TX) : boolean { - var trustChange = this.parseTXAsTrustChange(tx); - if (!trustChange) return false; + var txHash = tx.hash().toString('hex'); + if (this.TXToTrust.hasOwnProperty(txHash)) { + throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen again.'); + } - if (!this.trust.hasOwnProperty(trustChange.from)) this.trust[trustChange.from] = {} - if (!this.trust[trustChange.from].hasOwnProperty(trustChange.to)) { - this.trust[trustChange.from][trustChange.to] = 0 + var trustChanges = this.getTrustChanges(tx); + if (trustChanges.length === 0) return false; + else { + trustChanges.map(this.applyTrustChange.bind(this)); + return true; + } + } + + // Returns a list of trust changes that a transaction causes, which will be one of the following: + // * An empty list (for non-TIR transactions). + // * A list containing a single trust increase (for trust-increasing transactions). + // * A list containing one or more trust decreases (for trust-decreasing transactions). + getTrustChanges(tx : bcoin$TX) : TrustChange[] { + var trustIncrease = this.parseTXAsTrustIncrease(tx); + if (trustIncrease !== null) { + return [trustIncrease]; + } else { + return this.getTrustDecreases(tx); } - this.trust[trustChange.from][trustChange.to] += trustChange.amount; - - return true; } - // Parses a transaction as a trust change, or returns null if the - // transaction is not a TIR transaction. - parseTXAsTrustChange(tx : bcoin$TX) : ?TrustChange { - var trustChange = this.parseTXAsTrustIncrease(tx); - if (trustChange === null) { - trustChange = this.parseTXAsTrustDecrease(tx); + applyTrustChange(trustChange : TrustChange) { + if (!this.directTrust.hasOwnProperty(trustChange.from)) this.directTrust[trustChange.from] = {}; + if (!this.directTrust[trustChange.from].hasOwnProperty(trustChange.to)) { + this.directTrust[trustChange.from][trustChange.to] = 0 } - return trustChange; + this.directTrust[trustChange.from][trustChange.to] += trustChange.amount; + + if (this.directTrust[trustChange.from][trustChange.to] > 0) { + this.TXToTrust[trustChange.txHash] = { + from: trustChange.from, + to: trustChange.to, + amount: this.directTrust[trustChange.from][trustChange.to], + txHash: trustChange.txHash, + outputIndex: trustChange.outputIndex + }; + } } - parseTXAsTrustIncrease(tx : bcoin$TX) : ?TrustChange { + parseTXAsTrustIncrease(tx : bcoin$TX) : (TrustChange | null) { if (tx.inputs.length !== 1) return null; - if (tx.inputs[0].getType() !== 'pubkeyhash') return null; - var sender = tx.inputs[0].getAddress(); + if (tx.inputs[0].getType() !== 'pubkeyhash') return null; // TODO: This is unreliable + if (this.TXToTrust[tx.inputs[0].prevout.hash.toString('hex')]) return null; + var sender = tx.inputs[0].getAddress().toBase58(); - if (tx.outputs.length == 0 || tx.outputs.length > 2) return null; + if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; - var trustChanges = []; - for (var i = 0; i < tx.outputs.length; i++) { - if (this.isChangeOutput(tx.outputs[i], sender)) continue; + var trustOutputs = this.searchForDirectTrustOutputs(tx, sender); + if (trustOutputs.length !== 1) return null; - var trustChange = this.parseOutputAsDirectTrust(tx.outputs[i], sender.toBase58()); - if (trustChange === null) return null; - trustChanges.push(trustChange); - } - if (trustChanges.length !== 1) return null; + var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length + if (changeOutputCount + 1 !== tx.outputs.length) return null; - return trustChanges[0]; + return trustOutputs[0]; } - parseTXAsTrustDecrease(tx : bcoin$TX) : ?TrustChange { - return null; + getTrustDecreases(tx : bcoin$TX) : TrustChange[] { + var inputTrusts = this.getInputTrusts(tx.inputs); + return inputTrusts.map(this.getTrustDecrease.bind(this, tx)); + } + + getInputTrusts(inputs : bcoin$Input[]) : DirectTrust[] { + return inputs.map((input) => { + var trust = this.TXToTrust[input.prevout.hash.toString('hex')] + if (trust && trust.outputIndex === input.prevout.index) return trust; + else return null; + }).filter(Boolean); + } + + getTrustDecrease(tx : bcoin$TX, prevTrust : DirectTrust) : TrustChange { + var txHash = tx.hash().toString('hex'); + var nullifyTrust = { + from: prevTrust.from, + to: prevTrust.to, + amount: -prevTrust.amount, + txHash, + outputIndex: null + }; + + if (tx.inputs.length !== 1) return nullifyTrust; + + var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.from, prevTrust.to); + if (trustOutputs.length != 1) return nullifyTrust; + var nextTrust = trustOutputs[0]; + + assert(nextTrust.from === prevTrust.from); + assert(nextTrust.to === prevTrust.to); + + var trustAmountChange = nextTrust.amount - prevTrust.amount; + assert(trustAmountChange <= 0); + return { + from: nextTrust.from, + to: nextTrust.to, + amount: trustAmountChange, + txHash, + outputIndex: nextTrust.outputIndex + } + } + + // Looks for direct trust outputs that originate from a sender in an array of bitcoin outputs. + // If the recipient parameter is set, it will limit the results only to the outputs being sent to + // the recipient. + searchForDirectTrustOutputs(tx : bcoin$TX, sender : Entity, recipient : ?Entity) : DirectTrust[] { + var directTrusts = tx.outputs.map((output, outputIndex) => + this.parseOutputAsDirectTrust(tx, outputIndex, sender) + ).filter(Boolean); + + if (recipient) { + directTrusts.filter((trust) => trust.to === recipient); + } + + return directTrusts; } - isChangeOutput(output : bcoin$Output, sender : bcoin$Address) : boolean { + isChangeOutput(output : bcoin$Output, sender : Entity) : boolean { return (output.getType() === 'pubkeyhash') - && (output.getAddress().toBase58() === sender.toBase58()); + && (output.getAddress().toBase58() === sender); } - parseOutputAsDirectTrust(output : bcoin$Output, sender : Entity) : ?DirectTrust { + parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, sender : Entity) + : (DirectTrust | null) { + var txHash = tx.hash().toString('hex'); + var output = tx.outputs[outputIndex]; if (output.getType() !== 'multisig') return null; var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58() @@ -94,15 +183,17 @@ class TrustIsRisk { if (addressA === addressB) return null; - var receiver; - if (addressA === sender) receiver = addressB; - else if (addressB === sender) receiver = addressA; + var recipient; + if (addressA === sender) recipient = addressB; + else if (addressB === sender) recipient = addressA; else return null; return { from: sender, - to: receiver, - amount: Number(output.value) + to: recipient, + amount: Number(output.value), + txHash, + outputIndex }; } diff --git a/test/helpers.js b/test/helpers.js index 0b2c7fc..2cd68ec 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -46,6 +46,15 @@ var testHelpers = { return new Promise((resolve, reject) => { setTimeout(resolve, milliseconds); }); + }, + + P2PKHOutput: (to, value) => { + var address = bcoin.primitives.Address.fromBase58(to); + var script = bcoin.script.fromString( + `OP_DUP OP_HASH160 0x${Number(address.hash.length).toString(16)} ` + + `0x${address.hash.toString('hex')} OP_EQUALVERIFY OP_CHECKSIG`); + + return new bcoin.primitives.Output({script, value}); } } diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index a03ef5f..a959f53 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -7,135 +7,155 @@ var should = require('should'); require('should-sinon'); describe('TrustIsRisk', () => { - var sender = "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE"; - var receiver = "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx"; - - var inputP2PKH = new bcoin.primitives.Input({ - prevout: { - hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', - index: 0xfffffffa - }, script: bcoin.script.fromString( - // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (sender) - "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") - }); - - var outputOneOfTwoMultsig = new bcoin.primitives.Output({ - script: bcoin.script.fromString( - // 1/{17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (sender), 1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx (receiver)} - "OP_1 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083 0x28 0x2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b OP_2 OP_CHECKMULTISIG"), - value: 42 - }); + var alice = "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE"; + var bob = "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx"; + var charlie = "1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND"; - var tir = null, mtx = null, changeScript = null; + var inputP2PKH, outputOneOfTwoMultisig, inputOneOfTwoMultisig; + var tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; beforeEach(() => { tir = new Trust.TrustIsRisk(new bcoin.fullnode({})); - mtx = new bcoin.primitives.MTX({ + inputP2PKH = new bcoin.primitives.Input({ + prevout: { + hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', + index: 2 + }, + script: bcoin.script.fromString( + // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (alice) + "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") + }); + + outputOneOfTwoMultisig = new bcoin.primitives.Output({ + script: bcoin.script.fromString( + // 1/{17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (alice), 1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx (bob)} + "OP_1 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083 0x28 0x2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b OP_2 OP_CHECKMULTISIG"), + value: 42 + }); + + trustIncreasingMTX = new bcoin.primitives.MTX({ inputs: [ inputP2PKH ], outputs: [ - outputOneOfTwoMultsig + outputOneOfTwoMultisig + ] + }); + + trustIncreasingTX = trustIncreasingMTX.toTX(); + inputOneOfTwoMultisig = new bcoin.primitives.Input({ + prevout: { + hash: trustIncreasingTX.hash().toString('hex'), + index: 0 + }, + script: bcoin.script.fromString( + // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE + "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") + }); + + trustDecreasingMTX = new bcoin.primitives.MTX({ + inputs: [ + inputOneOfTwoMultisig + ], + outputs: [ + Object.assign(outputOneOfTwoMultisig.clone(), {value: 20}), + testHelpers.P2PKHOutput(alice, 22) ] }); - changeScript = bcoin.script.fromString( - // Pays to 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE - "OP_DUP OP_HASH160 0x14 0x46005EF459C9E7C37AF8871D25BC39D0EA0534D1 OP_EQUALVERIFY OP_CHECKSIG"); }); - describe('.parseTXAsTrustIncrease', () => { - it('correctly parses trust increasing transactions', () => { - var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + describe('.getDirectTrust()', () => { + it('returns zero for two arbitary parties that do not trust each other', () => { + should(tir.getDirectTrust(alice, bob)).equal(0); + should(tir.getDirectTrust(bob, alice)).equal(0); + should(tir.getDirectTrust(charlie, alice)).equal(0); + should(tir.getDirectTrust(alice, charlie)).equal(0); + }); + }); - should(trustChange).deepEqual({ - from: sender, - to: receiver, - amount: 42 + describe('.addTX()', () => { + describe('with a non-TIR transaction', () => { + it('does not change trust', () => { + trustIncreasingMTX.outputs[0] = new bcoin.primitives.Output({ + script: bcoin.script.fromString( + // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND (neither alice or bob) + "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), + value: 10 + }); + tir.parseTXAsTrustIncrease(trustIncreasingMTX.toTX()); + + should(tir.getDirectTrust(alice, bob)).equal(0); }); }); - it('rejects transactions with more than one input', () => { - mtx.inputs.push(inputP2PKH); - var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); + describe('with a trust increasing transaction', () => { + it('correctly increases trust', () => { + tir.addTX(trustIncreasingTX); - should(trustChange).equal(null); - }); + should(tir.getDirectTrust(alice, bob)).equal(42); + should(tir.getDirectTrust(bob, alice)).equal(0); + }); + + it('which has more than one input does not change trust', () => { + trustIncreasingMTX.inputs.push(inputP2PKH); + tir.addTX(trustIncreasingMTX.toTX()); - it('correctly parses trust increasing transactions with change outputs', () => { - mtx.outputs[0].value -= 10; - mtx.outputs.push(new bcoin.primitives.Output({ - script: changeScript, - value: 10 - })); - var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); - - should(trustChange).deepEqual({ - from: sender, - to: receiver, - amount: 32 + should(tir.getDirectTrust(alice, bob)).equal(0); }); - }); - it('rejects transactions with two change outputs', () => { - mtx.outputs[0].value -= 10; - for (var i = 0; i < 2; i++) { - mtx.outputs.push(new bcoin.primitives.Output({ - script: changeScript, - value: 5 - })); - } - var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); - - should(trustChange).equal(null); - }); + it('which has a change output correctly increases trust', () => { + trustIncreasingMTX.outputs[0].value -= 10; + trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(alice, 10)); + tir.addTX(trustIncreasingMTX.toTX()); - it('rejects transactions with a second output that\'s not a change output', () => { - mtx.outputs[0].value -= 10; - mtx.outputs.push(new bcoin.primitives.Output({ - script: bcoin.script.fromString( - // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND (neither sender or receiver) - "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), - value: 10 - })); - var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); - - should(trustChange).equal(null); - }); + should(tir.getDirectTrust(alice, bob)).equal(32); + }); + + it('which has two change outputs does not change trust', () => { + trustIncreasingMTX.outputs[0].value -= 10; + for (var i = 0; i < 2; i++) { + trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(alice, 5)); + } + tir.addTX(trustIncreasingMTX.toTX()); - it('rejects transactions with no trust outputs', () => { - mtx.outputs[0] = new bcoin.primitives.Output({ - script: bcoin.script.fromString( - // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND (neither sender or receiver) - "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), - value: 10 + should(tir.getDirectTrust(alice, bob)).equal(0); }); - var trustChange = tir.parseTXAsTrustIncrease(mtx.toTX()); - should(trustChange).equal(null); - }); - }); + it('which has a second output that is not a change output does not change trust', () => { + trustIncreasingMTX.outputs[0].value -= 10; + trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(charlie, 5)); + tir.addTX(trustIncreasingMTX.toTX()); + + should(tir.getDirectTrust(alice, bob)).equal(0); + }); - describe('.getDirect()', () => { - it('returns zero for two arbitary parties that do not trust each other', () => { - should(tir.getDirect(sender, receiver)).equal(0); - should(tir.getDirect(receiver, sender)).equal(0); - should(tir.getDirect("1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND", sender)).equal(0); - should(tir.getDirect(sender, "1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND")).equal(0); }); - }); - describe('.addTX()', () => { - it('correctly increases direct trust when adding a trust-increasing transaction', () => { - mtx.outputs[0].value -= 10; - mtx.outputs.push(new bcoin.primitives.Output({ - script: changeScript, - value: 10 - })); - tir.addTX(mtx.toTX()); - - should(tir.getDirect(sender, receiver)).equal(32); - should(tir.getDirect(receiver, sender)).equal(0); // Trust is not bi-directional + describe('with a trust decreasing transaction', () => { + beforeEach(() => { + tir.addTX(trustIncreasingTX); + }); + + it('correctly decreases trust', () => { + tir.addTX(trustDecreasingMTX.toTX()); + should(tir.getDirectTrust(alice, bob)).equal(20); + }); + + it('which has a second input decreases trust to zero', () => { + trustDecreasingMTX.inputs.push(inputP2PKH); + tir.addTX(trustDecreasingMTX.toTX()); + + should(tir.getDirectTrust(alice, bob)).equal(0); + }); + + it('which has more than one trust outputs decreases trust to zero', () => { + trustDecreasingMTX.outputs[0].value -= 15; + trustDecreasingMTX.outputs.push(Object.assign(outputOneOfTwoMultisig.clone(), {value: 5})); + tir.addTX(trustDecreasingMTX.toTX()); + + should(tir.getDirectTrust(alice, bob)).equal(0); + }); }); }); }); From 14b48e5b2591a951d1d10b2b2885cb06d020002c Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 22 May 2017 23:32:53 +0000 Subject: [PATCH 005/540] Implement MaxFlow-based indirect trust inference --- .../npm/graph-theory-ford-fulkerson_vx.x.x.js | 45 +++ flow-typed/npm/should-sinon_vx.x.x.js | 39 ++ flow-typed/npm/sinon_vx.x.x.js | 375 ++++++++++++++++++ flow-typed/npm/sorted-set_vx.x.x.js | 87 ++++ lib/trust_is_risk.js | 34 +- package.json | 4 +- src/trust_is_risk.js | 34 +- test/graphs/nobodyLikesFrank.json | 24 ++ test/graphs/topcoder.json | 19 + test/helpers.js | 89 ++++- test/trust_is_risk.js | 160 +++++--- 11 files changed, 856 insertions(+), 54 deletions(-) create mode 100644 flow-typed/npm/graph-theory-ford-fulkerson_vx.x.x.js create mode 100644 flow-typed/npm/should-sinon_vx.x.x.js create mode 100644 flow-typed/npm/sinon_vx.x.x.js create mode 100644 flow-typed/npm/sorted-set_vx.x.x.js create mode 100644 test/graphs/nobodyLikesFrank.json create mode 100644 test/graphs/topcoder.json diff --git a/flow-typed/npm/graph-theory-ford-fulkerson_vx.x.x.js b/flow-typed/npm/graph-theory-ford-fulkerson_vx.x.x.js new file mode 100644 index 0000000..983c36c --- /dev/null +++ b/flow-typed/npm/graph-theory-ford-fulkerson_vx.x.x.js @@ -0,0 +1,45 @@ +// flow-typed signature: 2849579ad8dda7785593fce35e7021fd +// flow-typed version: <>/graph-theory-ford-fulkerson_v^1.0.0/flow_v0.45.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'graph-theory-ford-fulkerson' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'graph-theory-ford-fulkerson' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'graph-theory-ford-fulkerson/example/example' { + declare module.exports: any; +} + +declare module 'graph-theory-ford-fulkerson/test/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'graph-theory-ford-fulkerson/example/example.js' { + declare module.exports: $Exports<'graph-theory-ford-fulkerson/example/example'>; +} +declare module 'graph-theory-ford-fulkerson/index' { + declare module.exports: $Exports<'graph-theory-ford-fulkerson'>; +} +declare module 'graph-theory-ford-fulkerson/index.js' { + declare module.exports: $Exports<'graph-theory-ford-fulkerson'>; +} +declare module 'graph-theory-ford-fulkerson/test/index.js' { + declare module.exports: $Exports<'graph-theory-ford-fulkerson/test/index'>; +} diff --git a/flow-typed/npm/should-sinon_vx.x.x.js b/flow-typed/npm/should-sinon_vx.x.x.js new file mode 100644 index 0000000..6de6924 --- /dev/null +++ b/flow-typed/npm/should-sinon_vx.x.x.js @@ -0,0 +1,39 @@ +// flow-typed signature: 45843e3ce6bf3afc28721ddbe8e0ce2f +// flow-typed version: <>/should-sinon_v0.0.5/flow_v0.45.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'should-sinon' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'should-sinon' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'should-sinon/should-sinon' { + declare module.exports: any; +} + +declare module 'should-sinon/test' { + declare module.exports: any; +} + +// Filename aliases +declare module 'should-sinon/should-sinon.js' { + declare module.exports: $Exports<'should-sinon/should-sinon'>; +} +declare module 'should-sinon/test.js' { + declare module.exports: $Exports<'should-sinon/test'>; +} diff --git a/flow-typed/npm/sinon_vx.x.x.js b/flow-typed/npm/sinon_vx.x.x.js new file mode 100644 index 0000000..c75f639 --- /dev/null +++ b/flow-typed/npm/sinon_vx.x.x.js @@ -0,0 +1,375 @@ +// flow-typed signature: 49be0b929be2f6361f541fdb8e279527 +// flow-typed version: <>/sinon_v^2.2.0/flow_v0.45.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'sinon' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'sinon' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'sinon/lib/sinon' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/assert' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/behavior' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/blob' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/call' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/collect-own-methods' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/collection' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/color' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/default-behaviors' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/match' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/mock-expectation' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/mock' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/sandbox' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/spy-formatters' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/spy' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/stub-descriptor' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/stub-entire-object' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/stub-non-function-property' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/stub' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/throw-on-falsy-object' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/called-in-order' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/deep-equal' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/default-config' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/deprecated' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/every' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/extend' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/format' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/function-name' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/function-to-string' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/get-config' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/get-property-descriptor' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/index' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/iterable-to-string' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/log_error' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/order-by-first-call' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/restore' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/times-in-words' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/typeOf' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/value-to-string' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/walk' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/core/wrap-method' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/event' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/fake_server_with_clock' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/fake_server' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/fake_timers' { + declare module.exports: any; +} + +declare module 'sinon/lib/sinon/util/fake_xml_http_request' { + declare module.exports: any; +} + +declare module 'sinon/pkg/sinon-2.2.0' { + declare module.exports: any; +} + +declare module 'sinon/pkg/sinon-no-sourcemaps-2.2.0' { + declare module.exports: any; +} + +declare module 'sinon/pkg/sinon-no-sourcemaps' { + declare module.exports: any; +} + +declare module 'sinon/pkg/sinon' { + declare module.exports: any; +} + +// Filename aliases +declare module 'sinon/lib/sinon.js' { + declare module.exports: $Exports<'sinon/lib/sinon'>; +} +declare module 'sinon/lib/sinon/assert.js' { + declare module.exports: $Exports<'sinon/lib/sinon/assert'>; +} +declare module 'sinon/lib/sinon/behavior.js' { + declare module.exports: $Exports<'sinon/lib/sinon/behavior'>; +} +declare module 'sinon/lib/sinon/blob.js' { + declare module.exports: $Exports<'sinon/lib/sinon/blob'>; +} +declare module 'sinon/lib/sinon/call.js' { + declare module.exports: $Exports<'sinon/lib/sinon/call'>; +} +declare module 'sinon/lib/sinon/collect-own-methods.js' { + declare module.exports: $Exports<'sinon/lib/sinon/collect-own-methods'>; +} +declare module 'sinon/lib/sinon/collection.js' { + declare module.exports: $Exports<'sinon/lib/sinon/collection'>; +} +declare module 'sinon/lib/sinon/color.js' { + declare module.exports: $Exports<'sinon/lib/sinon/color'>; +} +declare module 'sinon/lib/sinon/default-behaviors.js' { + declare module.exports: $Exports<'sinon/lib/sinon/default-behaviors'>; +} +declare module 'sinon/lib/sinon/match.js' { + declare module.exports: $Exports<'sinon/lib/sinon/match'>; +} +declare module 'sinon/lib/sinon/mock-expectation.js' { + declare module.exports: $Exports<'sinon/lib/sinon/mock-expectation'>; +} +declare module 'sinon/lib/sinon/mock.js' { + declare module.exports: $Exports<'sinon/lib/sinon/mock'>; +} +declare module 'sinon/lib/sinon/sandbox.js' { + declare module.exports: $Exports<'sinon/lib/sinon/sandbox'>; +} +declare module 'sinon/lib/sinon/spy-formatters.js' { + declare module.exports: $Exports<'sinon/lib/sinon/spy-formatters'>; +} +declare module 'sinon/lib/sinon/spy.js' { + declare module.exports: $Exports<'sinon/lib/sinon/spy'>; +} +declare module 'sinon/lib/sinon/stub-descriptor.js' { + declare module.exports: $Exports<'sinon/lib/sinon/stub-descriptor'>; +} +declare module 'sinon/lib/sinon/stub-entire-object.js' { + declare module.exports: $Exports<'sinon/lib/sinon/stub-entire-object'>; +} +declare module 'sinon/lib/sinon/stub-non-function-property.js' { + declare module.exports: $Exports<'sinon/lib/sinon/stub-non-function-property'>; +} +declare module 'sinon/lib/sinon/stub.js' { + declare module.exports: $Exports<'sinon/lib/sinon/stub'>; +} +declare module 'sinon/lib/sinon/throw-on-falsy-object.js' { + declare module.exports: $Exports<'sinon/lib/sinon/throw-on-falsy-object'>; +} +declare module 'sinon/lib/sinon/util/core/called-in-order.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/called-in-order'>; +} +declare module 'sinon/lib/sinon/util/core/deep-equal.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/deep-equal'>; +} +declare module 'sinon/lib/sinon/util/core/default-config.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/default-config'>; +} +declare module 'sinon/lib/sinon/util/core/deprecated.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/deprecated'>; +} +declare module 'sinon/lib/sinon/util/core/every.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/every'>; +} +declare module 'sinon/lib/sinon/util/core/extend.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/extend'>; +} +declare module 'sinon/lib/sinon/util/core/format.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/format'>; +} +declare module 'sinon/lib/sinon/util/core/function-name.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/function-name'>; +} +declare module 'sinon/lib/sinon/util/core/function-to-string.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/function-to-string'>; +} +declare module 'sinon/lib/sinon/util/core/get-config.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/get-config'>; +} +declare module 'sinon/lib/sinon/util/core/get-property-descriptor.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/get-property-descriptor'>; +} +declare module 'sinon/lib/sinon/util/core/index.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/index'>; +} +declare module 'sinon/lib/sinon/util/core/iterable-to-string.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/iterable-to-string'>; +} +declare module 'sinon/lib/sinon/util/core/log_error.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/log_error'>; +} +declare module 'sinon/lib/sinon/util/core/order-by-first-call.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/order-by-first-call'>; +} +declare module 'sinon/lib/sinon/util/core/restore.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/restore'>; +} +declare module 'sinon/lib/sinon/util/core/times-in-words.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/times-in-words'>; +} +declare module 'sinon/lib/sinon/util/core/typeOf.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/typeOf'>; +} +declare module 'sinon/lib/sinon/util/core/value-to-string.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/value-to-string'>; +} +declare module 'sinon/lib/sinon/util/core/walk.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/walk'>; +} +declare module 'sinon/lib/sinon/util/core/wrap-method.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/core/wrap-method'>; +} +declare module 'sinon/lib/sinon/util/event.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/event'>; +} +declare module 'sinon/lib/sinon/util/fake_server_with_clock.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/fake_server_with_clock'>; +} +declare module 'sinon/lib/sinon/util/fake_server.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/fake_server'>; +} +declare module 'sinon/lib/sinon/util/fake_timers.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/fake_timers'>; +} +declare module 'sinon/lib/sinon/util/fake_xml_http_request.js' { + declare module.exports: $Exports<'sinon/lib/sinon/util/fake_xml_http_request'>; +} +declare module 'sinon/pkg/sinon-2.2.0.js' { + declare module.exports: $Exports<'sinon/pkg/sinon-2.2.0'>; +} +declare module 'sinon/pkg/sinon-no-sourcemaps-2.2.0.js' { + declare module.exports: $Exports<'sinon/pkg/sinon-no-sourcemaps-2.2.0'>; +} +declare module 'sinon/pkg/sinon-no-sourcemaps.js' { + declare module.exports: $Exports<'sinon/pkg/sinon-no-sourcemaps'>; +} +declare module 'sinon/pkg/sinon.js' { + declare module.exports: $Exports<'sinon/pkg/sinon'>; +} diff --git a/flow-typed/npm/sorted-set_vx.x.x.js b/flow-typed/npm/sorted-set_vx.x.x.js new file mode 100644 index 0000000..be9ce1e --- /dev/null +++ b/flow-typed/npm/sorted-set_vx.x.x.js @@ -0,0 +1,87 @@ +// flow-typed signature: 49b561be32534814522dc2da04fa8dea +// flow-typed version: <>/sorted-set_v1.x.x/flow_v0.45.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'sorted-set' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'sorted-set' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'sorted-set/examples/distance' { + declare module.exports: any; +} + +declare module 'sorted-set/examples/kademlia' { + declare module.exports: any; +} + +declare module 'sorted-set/examples/ttl' { + declare module.exports: any; +} + +declare module 'sorted-set/lib/intersect-sorted' { + declare module.exports: any; +} + +declare module 'sorted-set/lib/intersect-unique' { + declare module.exports: any; +} + +declare module 'sorted-set/lib/set' { + declare module.exports: any; +} + +declare module 'sorted-set/test/index' { + declare module.exports: any; +} + +declare module 'sorted-set/test/set' { + declare module.exports: any; +} + +// Filename aliases +declare module 'sorted-set/examples/distance.js' { + declare module.exports: $Exports<'sorted-set/examples/distance'>; +} +declare module 'sorted-set/examples/kademlia.js' { + declare module.exports: $Exports<'sorted-set/examples/kademlia'>; +} +declare module 'sorted-set/examples/ttl.js' { + declare module.exports: $Exports<'sorted-set/examples/ttl'>; +} +declare module 'sorted-set/index' { + declare module.exports: $Exports<'sorted-set'>; +} +declare module 'sorted-set/index.js' { + declare module.exports: $Exports<'sorted-set'>; +} +declare module 'sorted-set/lib/intersect-sorted.js' { + declare module.exports: $Exports<'sorted-set/lib/intersect-sorted'>; +} +declare module 'sorted-set/lib/intersect-unique.js' { + declare module.exports: $Exports<'sorted-set/lib/intersect-unique'>; +} +declare module 'sorted-set/lib/set.js' { + declare module.exports: $Exports<'sorted-set/lib/set'>; +} +declare module 'sorted-set/test/index.js' { + declare module.exports: $Exports<'sorted-set/test/index'>; +} +declare module 'sorted-set/test/set.js' { + declare module.exports: $Exports<'sorted-set/test/set'>; +} diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 60a5ac2..2d810c7 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -2,6 +2,9 @@ var bcoin = require('bcoin'); var assert = require('assert'); var Address = bcoin.primitives.Address; +var SortedSet = require('sorted-set'); +var maxFlow = require('graph-theory-ford-fulkerson'); + // base58 bitcoin address @@ -27,15 +30,31 @@ class TrustIsRisk { + + constructor(node ) { this.node = node; this.directTrust = {}; this.TXToTrust = {}; + this.entities = new SortedSet(); this.node.on('tx', this.addTX.bind(this)); } + getTrust(from , to ) { + if (from === to) return Infinity; + + // TODO: Optimize + var graph = this.getGraphWeightMatrix(); + var fromIndex = this.getGraphWeightMatrixIndex(from); + var toIndex = this.getGraphWeightMatrixIndex(to); + + if (fromIndex === -1 || toIndex === -1) return 0; + else return maxFlow(graph, fromIndex, toIndex); + } + getDirectTrust(from , to ) { + if (from === to) return Infinity; if (!this.directTrust.hasOwnProperty(from)) return 0; if (!this.directTrust[from].hasOwnProperty(to)) return 0; return this.directTrust[from][to]; @@ -49,7 +68,7 @@ class TrustIsRisk { addTX(tx ) { var txHash = tx.hash().toString('hex'); if (this.TXToTrust.hasOwnProperty(txHash)) { - throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen again.'); + throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen before.'); } var trustChanges = this.getTrustChanges(tx); @@ -90,6 +109,9 @@ class TrustIsRisk { outputIndex: trustChange.outputIndex }; } + + this.entities.add(trustChange.from); + this.entities.add(trustChange.to); } parseTXAsTrustIncrease(tx ) { @@ -197,6 +219,16 @@ class TrustIsRisk { }; } + getGraphWeightMatrix() { + var entitiesArr = this.entities.slice(0, this.entities.length); + return entitiesArr.map((from) => { + return entitiesArr.map((to) => this.getDirectTrust(from, to)); + }); + } + + getGraphWeightMatrixIndex(entity ) { + return this.entities.rank(entity); + } } module.exports = TrustIsRisk; diff --git a/package.json b/package.json index 9928a84..e5bc1ef 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,8 @@ "sinon": "^2.2.0" }, "dependencies": { - "bcoin": "^1.0.0-beta.12" + "bcoin": "^1.0.0-beta.12", + "graph-theory-ford-fulkerson": "^1.0.0", + "sorted-set": "^0.3.0" } } diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0babc19..c74fde1 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -2,6 +2,9 @@ var bcoin = require('bcoin'); var assert = require('assert'); var Address = bcoin.primitives.Address; +var SortedSet = require('sorted-set'); +var maxFlow = require('graph-theory-ford-fulkerson'); + type Entity = string; // base58 bitcoin address type DirectTrust = { @@ -27,15 +30,31 @@ class TrustIsRisk { [hash : TXHash] : DirectTrust } + entities : SortedSet + constructor(node : bcoin$FullNode) { this.node = node; this.directTrust = {}; this.TXToTrust = {}; + this.entities = new SortedSet(); this.node.on('tx', this.addTX.bind(this)); } + getTrust(from : Entity, to : Entity) : number { + if (from === to) return Infinity; + + // TODO: Optimize + var graph = this.getGraphWeightMatrix(); + var fromIndex = this.getGraphWeightMatrixIndex(from); + var toIndex = this.getGraphWeightMatrixIndex(to); + + if (fromIndex === -1 || toIndex === -1) return 0; + else return maxFlow(graph, fromIndex, toIndex); + } + getDirectTrust(from : Entity, to : Entity) : number { + if (from === to) return Infinity; if (!this.directTrust.hasOwnProperty(from)) return 0; if (!this.directTrust[from].hasOwnProperty(to)) return 0; return this.directTrust[from][to]; @@ -49,7 +68,7 @@ class TrustIsRisk { addTX(tx : bcoin$TX) : boolean { var txHash = tx.hash().toString('hex'); if (this.TXToTrust.hasOwnProperty(txHash)) { - throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen again.'); + throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen before.'); } var trustChanges = this.getTrustChanges(tx); @@ -90,6 +109,9 @@ class TrustIsRisk { outputIndex: trustChange.outputIndex }; } + + this.entities.add(trustChange.from); + this.entities.add(trustChange.to); } parseTXAsTrustIncrease(tx : bcoin$TX) : (TrustChange | null) { @@ -197,6 +219,16 @@ class TrustIsRisk { }; } + getGraphWeightMatrix() : number[][] { + var entitiesArr = this.entities.slice(0, this.entities.length); + return entitiesArr.map((from) => { + return entitiesArr.map((to) => this.getDirectTrust(from, to)); + }); + } + + getGraphWeightMatrixIndex(entity : Entity) : number { + return this.entities.rank(entity); + } } module.exports = TrustIsRisk; diff --git a/test/graphs/nobodyLikesFrank.json b/test/graphs/nobodyLikesFrank.json new file mode 100644 index 0000000..09865cc --- /dev/null +++ b/test/graphs/nobodyLikesFrank.json @@ -0,0 +1,24 @@ +{ + "alice": { + "bob": 10, + "dave": 3 + }, + "bob": { + "charlie": 1, + "eve": 2, + "dave": 1, + "george": 1 + }, + "charlie": { + "george": 3 + }, + "dave": { + "eve": 10, + "alice": 2 + }, + "eve": {}, + "frank": { + "charlie": 100 + }, + "george": {} +} diff --git a/test/graphs/topcoder.json b/test/graphs/topcoder.json new file mode 100644 index 0000000..f051965 --- /dev/null +++ b/test/graphs/topcoder.json @@ -0,0 +1,19 @@ +{ + "alice": { + "bob": 3, + "dave": 1 + }, + "bob": { + "charlie": 3 + }, + "charlie": { + "frank": 2 + }, + "dave": { + "charlie": 5, + "eve": 4 + }, + "eve": { + "frank": 2 + } +} diff --git a/test/helpers.js b/test/helpers.js index 2cd68ec..40df046 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,8 +1,33 @@ var TrustIsRisk = require('../'); var WalletDB = require('bcoin/lib/wallet/walletdb'); var bcoin = require('bcoin'); +var assert = require('assert'); var testHelpers = { + getAddressFixtures: () => { + var names = ['alice', 'bob', 'charlie', 'dave', 'eve', 'frank', 'george']; + var pubkeys = [ + '02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083', + '2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b', + '3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD782', + '19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F351', + '0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A84', + '878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D4516', + '1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A93' + ]; + assert(pubkeys.length === names.length); + + var addr = {}; + for (var i = 0; i < names.length; i++) { + var name = names[i]; + addr[name] = {}; + addr[name].pubkey = Buffer.from(pubkeys[i], 'hex'); + addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(addr[name].pubkey)).toString(); + } + + return addr; + }, + getNode: async () => { var node = new TrustIsRisk.FullNode({network: 'regtest', passphrase: 'secret'}); @@ -48,14 +73,70 @@ var testHelpers = { }); }, - P2PKHOutput: (to, value) => { + bufferToScript: (data) => { + return `0x${Number(data.length).toString(16)} 0x${data.toString('hex')}`; + }, + + getP2PKHOutput: (to, value) => { var address = bcoin.primitives.Address.fromBase58(to); var script = bcoin.script.fromString( - `OP_DUP OP_HASH160 0x${Number(address.hash.length).toString(16)} ` - + `0x${address.hash.toString('hex')} OP_EQUALVERIFY OP_CHECKSIG`); + `OP_DUP OP_HASH160 ${testHelpers.bufferToScript(address.hash)} OP_EQUALVERIFY OP_CHECKSIG`); return new bcoin.primitives.Output({script, value}); + }, + + getP2PKHInput: (pubKey, prevout) => { + if (!prevout) { + prevout = { // Don't care + hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', + index: 2 + }; + } + + return new bcoin.primitives.Input({ + prevout, + script: bcoin.script.fromString( + // Don't care about the signature + "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 " + + testHelpers.bufferToScript(pubKey)) + }); + }, + + getOneOfTwoMultisigOutput: (pubKeyFrom, pubKeyTo, value) => { + return new bcoin.primitives.Output({ + value, + script: bcoin.script.fromString( + "OP_1 " + + testHelpers.bufferToScript(pubKeyFrom) + " " + + testHelpers.bufferToScript(pubKeyTo) + " " + + "OP_2 OP_CHECKMULTISIG") + }); + }, + + getTrustIncreasingMTX: (pubKeyFrom, pubKeyTo, value) => { + return new bcoin.primitives.MTX({ + inputs: [ + testHelpers.getP2PKHInput(pubKeyFrom) + ], + outputs: [ + testHelpers.getOneOfTwoMultisigOutput(pubKeyFrom, pubKeyTo, value) + ] + }); + }, + + applyGraph: (tir, fileName, addr) => { + var graph = require(fileName); + + for (var from in graph) { + var neighbours = graph[from]; + for (var to in neighbours) { + var value = neighbours[to]; + tir.addTX(testHelpers.getTrustIncreasingMTX(addr[from].pubkey, addr[to].pubkey, value).toTX()); + } + } } -} +}; + + module.exports = testHelpers; diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index a959f53..cc7cf3b 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -7,43 +7,20 @@ var should = require('should'); require('should-sinon'); describe('TrustIsRisk', () => { - var alice = "17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE"; - var bob = "1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx"; - var charlie = "1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND"; + var addr = testHelpers.getAddressFixtures(); + // Add base58 address variables to scope. + for (name in addr) { + eval(`var ${name} = "${addr[name].base58}";`); + } - var inputP2PKH, outputOneOfTwoMultisig, inputOneOfTwoMultisig; var tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; beforeEach(() => { tir = new Trust.TrustIsRisk(new bcoin.fullnode({})); - inputP2PKH = new bcoin.primitives.Input({ - prevout: { - hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', - index: 2 - }, - script: bcoin.script.fromString( - // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (alice) - "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") - }); - - outputOneOfTwoMultisig = new bcoin.primitives.Output({ - script: bcoin.script.fromString( - // 1/{17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE (alice), 1P6NdQWeZTLrYCpQNbYeXsLeaEjn8h6UFx (bob)} - "OP_1 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083 0x28 0x2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b OP_2 OP_CHECKMULTISIG"), - value: 42 - }); - - trustIncreasingMTX = new bcoin.primitives.MTX({ - inputs: [ - inputP2PKH - ], - outputs: [ - outputOneOfTwoMultisig - ] - }); - + trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubkey, addr.bob.pubkey, 42); trustIncreasingTX = trustIncreasingMTX.toTX(); - inputOneOfTwoMultisig = new bcoin.primitives.Input({ + + var inputOneOfTwoMultisig = new bcoin.primitives.Input({ prevout: { hash: trustIncreasingTX.hash().toString('hex'), index: 0 @@ -58,31 +35,31 @@ describe('TrustIsRisk', () => { inputOneOfTwoMultisig ], outputs: [ - Object.assign(outputOneOfTwoMultisig.clone(), {value: 20}), - testHelpers.P2PKHOutput(alice, 22) + testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubkey, addr.bob.pubkey, 20), + testHelpers.getP2PKHOutput(addr.alice.base58, 22) ] }); - }); describe('.getDirectTrust()', () => { it('returns zero for two arbitary parties that do not trust each other', () => { - should(tir.getDirectTrust(alice, bob)).equal(0); + should(tir.getDirectTrust(addr.alice.base58, bob)).equal(0); should(tir.getDirectTrust(bob, alice)).equal(0); should(tir.getDirectTrust(charlie, alice)).equal(0); should(tir.getDirectTrust(alice, charlie)).equal(0); + should(tir.getDirectTrust(charlie, frank)).equal(0); + }); + + it('returns Infinity for one\'s direct trust to themselves', () => { + should(tir.getDirectTrust(alice, alice)).equal(Infinity); + should(tir.getDirectTrust(bob, bob)).equal(Infinity); }); }); describe('.addTX()', () => { describe('with a non-TIR transaction', () => { it('does not change trust', () => { - trustIncreasingMTX.outputs[0] = new bcoin.primitives.Output({ - script: bcoin.script.fromString( - // Pays to 1JDfVQkZxMvRwM3Lc6LkDrpX55Ldk3JqND (neither alice or bob) - "OP_DUP OP_HASH160 0x14 0xBCDF4271C6600E7D02E60F9206A9AD862FFBD4F0 OP_EQUALVERIFY OP_CHECKSIG"), - value: 10 - }); + trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50); tir.parseTXAsTrustIncrease(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -98,7 +75,7 @@ describe('TrustIsRisk', () => { }); it('which has more than one input does not change trust', () => { - trustIncreasingMTX.inputs.push(inputP2PKH); + trustIncreasingMTX.inputs.push(trustIncreasingMTX.inputs[0].clone()); tir.addTX(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -106,7 +83,7 @@ describe('TrustIsRisk', () => { it('which has a change output correctly increases trust', () => { trustIncreasingMTX.outputs[0].value -= 10; - trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(alice, 10)); + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 10)); tir.addTX(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(32); @@ -115,7 +92,7 @@ describe('TrustIsRisk', () => { it('which has two change outputs does not change trust', () => { trustIncreasingMTX.outputs[0].value -= 10; for (var i = 0; i < 2; i++) { - trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(alice, 5)); + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 5)); } tir.addTX(trustIncreasingMTX.toTX()); @@ -124,7 +101,7 @@ describe('TrustIsRisk', () => { it('which has a second output that is not a change output does not change trust', () => { trustIncreasingMTX.outputs[0].value -= 10; - trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(charlie, 5)); + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(charlie, 5)); tir.addTX(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -143,7 +120,7 @@ describe('TrustIsRisk', () => { }); it('which has a second input decreases trust to zero', () => { - trustDecreasingMTX.inputs.push(inputP2PKH); + trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubkey)); tir.addTX(trustDecreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -151,11 +128,100 @@ describe('TrustIsRisk', () => { it('which has more than one trust outputs decreases trust to zero', () => { trustDecreasingMTX.outputs[0].value -= 15; - trustDecreasingMTX.outputs.push(Object.assign(outputOneOfTwoMultisig.clone(), {value: 5})); + trustDecreasingMTX.outputs.push( + testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubkey, addr.bob.pubkey, 5)); tir.addTX(trustDecreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); }); }); + + describe('.getTrust()', () => { + it('returns zero for two arbitary parties that do not trust each other', () => { + should(tir.getTrust(alice, bob)).equal(0); + should(tir.getTrust(bob, alice)).equal(0); + should(tir.getTrust(charlie, alice)).equal(0); + should(tir.getTrust(alice, charlie)).equal(0); + }); + + it('returns Infinity for one\'s trust to themselves', () => { + should(tir.getTrust(alice, alice)).equal(Infinity); + should(tir.getTrust(bob, bob)).equal(Infinity); + }); + + describe('after applying the Nobody Likes Frank graph example', () => { + beforeEach(() => { + testHelpers.applyGraph(tir, './graphs/nobodyLikesFrank.json', addr); + }); + + it('correctly computes trusts', () => { + should(tir.getTrust(alice, alice)).equal(Infinity); + should(tir.getTrust(alice, bob)).equal(10); + should(tir.getTrust(alice, charlie)).equal(1); + should(tir.getTrust(alice, dave)).equal(4); + should(tir.getTrust(alice, eve)).equal(6); + should(tir.getTrust(alice, frank)).equal(0); + should(tir.getTrust(alice, george)).equal(2); + + should(tir.getTrust(bob, alice)).equal(1); + should(tir.getTrust(bob, bob)).equal(Infinity); + should(tir.getTrust(bob, charlie)).equal(1); + should(tir.getTrust(bob, dave)).equal(1); + should(tir.getTrust(bob, eve)).equal(3); + should(tir.getTrust(bob, frank)).equal(0); + should(tir.getTrust(bob, george)).equal(2); + + should(tir.getTrust(charlie, alice)).equal(0); + should(tir.getTrust(charlie, bob)).equal(0); + should(tir.getTrust(charlie, charlie)).equal(Infinity); + should(tir.getTrust(charlie, dave)).equal(0); + should(tir.getTrust(charlie, eve)).equal(0); + should(tir.getTrust(charlie, frank)).equal(0); + should(tir.getTrust(charlie, george)).equal(3); + + should(tir.getTrust(dave, alice)).equal(2); + should(tir.getTrust(dave, bob)).equal(2); + should(tir.getTrust(dave, charlie)).equal(1); + should(tir.getTrust(dave, dave)).equal(Infinity); + should(tir.getTrust(dave, eve)).equal(12); + should(tir.getTrust(dave, frank)).equal(0); + should(tir.getTrust(dave, george)).equal(2); + + should(tir.getTrust(eve, alice)).equal(0); + should(tir.getTrust(eve, bob)).equal(0); + should(tir.getTrust(eve, charlie)).equal(0); + should(tir.getTrust(eve, dave)).equal(0); + should(tir.getTrust(eve, eve)).equal(Infinity); + should(tir.getTrust(eve, frank)).equal(0); + should(tir.getTrust(eve, george)).equal(0); + + should(tir.getTrust(frank, alice)).equal(0); + should(tir.getTrust(frank, bob)).equal(0); + should(tir.getTrust(frank, charlie)).equal(100); + should(tir.getTrust(frank, dave)).equal(0); + should(tir.getTrust(frank, eve)).equal(0); + should(tir.getTrust(frank, frank)).equal(Infinity); + should(tir.getTrust(frank, george)).equal(3); + + should(tir.getTrust(george, alice)).equal(0); + should(tir.getTrust(george, bob)).equal(0); + should(tir.getTrust(george, charlie)).equal(0); + should(tir.getTrust(george, dave)).equal(0); + should(tir.getTrust(george, eve)).equal(0); + should(tir.getTrust(george, frank)).equal(0); + should(tir.getTrust(george, george)).equal(Infinity); + }); + + it('correctly computes trusts when bob trusts frank', () => { + tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubkey, addr.frank.pubkey, 8).toTX()); + should(tir.getTrust(george, frank)).equal(0); + should(tir.getTrust(alice, frank)).equal(8); + should(tir.getTrust(dave, frank)).equal(2); + should(tir.getTrust(bob, frank)).equal(8); + }); + + // TODO: Decrement direct trusts and test that indirect trusts update correctly + }); + }); }); }); From e7e4f8460489bdbd5241bbfdc7db44f663e5a321 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Fri, 26 May 2017 00:02:51 +0000 Subject: [PATCH 006/540] Implement .getTrustIncreasingMTX() --- flow-typed/npm/bcoin_vx.x.x.js | 34 +++++++++++++++++++++-- lib/trust_is_risk.js | 37 ++++++++++++++++++++++-- src/trust_is_risk.js | 37 ++++++++++++++++++++++-- test/trust_is_risk.js | 51 ++++++++++++++++++++++++++++++++-- 4 files changed, 150 insertions(+), 9 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index d07ac45..504682f 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -1,12 +1,16 @@ // This is a work-in-progress attempt to type the bcoin library. +type Hash = (string | Buffer); +type Network = any; + declare class bcoin$FullNode { on(eventName : string, eventHandler : Function) : void; + getTX(hash : Hash) : Promise; } declare class bcoin$Address { toBase58() : string; - static fromHash(string|Buffer) : bcoin$Address; + static fromHash(Hash) : bcoin$Address; } declare class bcoin$TX { @@ -16,6 +20,17 @@ declare class bcoin$TX { hash(enc : ?'hex') : Buffer; } + +declare class bcoin$MTX { + inputs : bcoin$Input[]; + outputs : bcoin$Output[]; + + toTX : bcoin$TX; + template(ring : bcoin$KeyRing) : number; + scriptVector(outputScript : bcoin$Script, inputScript : bcoin$Script, ring : bcoin$KeyRing) : boolean; +} + + declare class bcoin$Output { script : bcoin$Script; value : number; @@ -25,13 +40,19 @@ declare class bcoin$Output { } declare class bcoin$Input { + static fromOutpoint(outpoint : bcoin$Outpoint) : bcoin$Input; + script : bcoin$Script; prevout : bcoin$Outpoint; + getType() : ('pubkeyhash' | 'multisig'); getAddress() : bcoin$Address; } declare class bcoin$Script { + static fromMultisig(m : number, n : number, keys : Buffer[]) : bcoin$Script; + static fromPubkeyhash(hash : Hash) : bcoin$Script; + get(n : number) : (Buffer); } @@ -40,6 +61,11 @@ declare class bcoin$Outpoint { index : number; } +declare class bcoin$KeyRing { + static fromPrivate(key : Buffer, compressed : ?boolean, network : ?Network) : bcoin$KeyRing; + static fromPublic(key : Buffer, network : ?Network) : bcoin$KeyRing; +} + declare module 'bcoin' { declare module.exports: { fullnode : Class, @@ -47,12 +73,14 @@ declare module 'bcoin' { primitives : { Address : Class, TX : Class, + MTX : Class, Output : Class, Input : Class, - Outpoint : Class + Outpoint : Class, + KeyRing: Class }, crypto : { - hash160(str : (string | Buffer)) : (string | Buffer) + hash160(str : (string | Buffer)) : Hash } } } diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 2d810c7..2b2a5b6 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -1,7 +1,12 @@ // var bcoin = require('bcoin'); -var assert = require('assert'); var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var assert = require('assert'); var SortedSet = require('sorted-set'); var maxFlow = require('graph-theory-ford-fulkerson'); @@ -16,6 +21,7 @@ var maxFlow = require('graph-theory-ford-fulkerson'); + class TrustIsRisk { @@ -41,6 +47,33 @@ class TrustIsRisk { this.node.on('tx', this.addTX.bind(this)); } + async getTrustIncreasingMTX(from , to , outpoint , trustAmount ) + { + var prevTX = await this.node.getTX(outpoint.hash); + var prevOutput = prevTX.outputs[outpoint.index]; + + var mtx = new MTX({ + inputs: [ + Input.fromOutpoint(outpoint) + ], + outputs: [ + new Output({ // Trust output + script: bcoin.script.fromMultisig(1, 2, [from, to]), + value: trustAmount + }), + new Output({ // Change output + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), + value: prevOutput.value - trustAmount + }) + ] + }); + + var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); + assert(success); + + return mtx; + } + getTrust(from , to ) { if (from === to) return Infinity; @@ -200,7 +233,7 @@ class TrustIsRisk { var output = tx.outputs[outputIndex]; if (output.getType() !== 'multisig') return null; - var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58() + var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58(); var addressB = Address.fromHash(bcoin.crypto.hash160(output.script.get(2))).toBase58(); if (addressA === addressB) return null; diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index c74fde1..42dce05 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,7 +1,12 @@ // @flow var bcoin = require('bcoin'); -var assert = require('assert'); var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var assert = require('assert'); var SortedSet = require('sorted-set'); var maxFlow = require('graph-theory-ford-fulkerson'); @@ -16,6 +21,7 @@ type DirectTrust = { } type TrustChange = DirectTrust; type TXHash = string; +type PubKey = Buffer; class TrustIsRisk { node : bcoin$FullNode @@ -41,6 +47,33 @@ class TrustIsRisk { this.node.on('tx', this.addTX.bind(this)); } + async getTrustIncreasingMTX(from : PubKey, to : PubKey, outpoint : bcoin$Outpoint, trustAmount : number) + : Promise { + var prevTX = await this.node.getTX(outpoint.hash); + var prevOutput = prevTX.outputs[outpoint.index]; + + var mtx = new MTX({ + inputs: [ + Input.fromOutpoint(outpoint) + ], + outputs: [ + new Output({ // Trust output + script: bcoin.script.fromMultisig(1, 2, [from, to]), + value: trustAmount + }), + new Output({ // Change output + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), + value: prevOutput.value - trustAmount + }) + ] + }); + + var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); + assert(success); + + return mtx; + } + getTrust(from : Entity, to : Entity) : number { if (from === to) return Infinity; @@ -200,7 +233,7 @@ class TrustIsRisk { var output = tx.outputs[outputIndex]; if (output.getType() !== 'multisig') return null; - var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58() + var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58(); var addressB = Address.fromHash(bcoin.crypto.hash160(output.script.get(2))).toBase58(); if (addressA === addressB) return null; diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index cc7cf3b..88c1d26 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -6,6 +6,8 @@ var sinon = require('sinon'); var should = require('should'); require('should-sinon'); +var Address = bcoin.primitives.Address; + describe('TrustIsRisk', () => { var addr = testHelpers.getAddressFixtures(); // Add base58 address variables to scope. @@ -13,9 +15,10 @@ describe('TrustIsRisk', () => { eval(`var ${name} = "${addr[name].base58}";`); } - var tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; + var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; beforeEach(() => { - tir = new Trust.TrustIsRisk(new bcoin.fullnode({})); + node = new bcoin.fullnode({}); + tir = new Trust.TrustIsRisk(node); trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubkey, addr.bob.pubkey, 42); trustIncreasingTX = trustIncreasingMTX.toTX(); @@ -136,6 +139,50 @@ describe('TrustIsRisk', () => { }); }); + describe('.getTrustIncreasingMTX()', () => { + it('creates valid trust-increasing transactions', async () => { + var getTXStub = sinon.stub(node, 'getTX'); + + var prevOutput = { + hash: 'v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', + index: 1 + }; + + getTXStub.withArgs(prevOutput.hash).returns(new bcoin.primitives.MTX({ + inputs: [ + testHelpers.getP2PKHInput(addr.alice.pubkey) + ], + outputs: [ + testHelpers.getOneOfTwoMultisigOutput(addr.charlie.pubkey, addr.bob.pubkey, 40), + testHelpers.getP2PKHOutput(alice, 1000), // This is the P2PKH being used + testHelpers.getP2PKHOutput(dave, 200) + ] + }).toTX()); + + var mtx = await tir.getTrustIncreasingMTX(addr.alice.pubkey, addr.bob.pubkey, prevOutput, 100); + + mtx.inputs.length.should.equal(1); + var input = mtx.inputs[0]; + input.script.get(0).should.equal(0); // OP_0, because this is an unsigned bcoin input template. + input.script.get(1).should.equal(addr.alice.pubkey); + + mtx.outputs.length.should.equal(2); + + var trustOutput = mtx.outputs[0]; + trustOutput.getType().should.equal('multisig'); + var addressA = Address.fromHash(bcoin.crypto.hash160(trustOutput.script.get(1))).toBase58(); + var addressB = Address.fromHash(bcoin.crypto.hash160(trustOutput.script.get(2))).toBase58(); + addressA.should.equal(alice); + addressB.should.equal(bob); + trustOutput.value.should.equal(100); + + var changeOutput = mtx.outputs[1]; + changeOutput.getType().should.equal('pubkeyhash'); + changeOutput.getAddress().toBase58().should.equal(alice); + changeOutput.value.should.equal(900); + }); + }); + describe('.getTrust()', () => { it('returns zero for two arbitary parties that do not trust each other', () => { should(tir.getTrust(alice, bob)).equal(0); From 7d44250656d8cb15c4323514029fcb5e9833ad5b Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Fri, 26 May 2017 01:11:54 +0000 Subject: [PATCH 007/540] Use conscise should syntax --- test/full_node.js | 2 +- test/trust_is_risk.js | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index d6308a8..7ade3fb 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -23,7 +23,7 @@ describe('FullNode', () => { afterEach(() => node.close()); it('should be a bcoin instance', () => { - should(node).be.an.instanceof(bcoin.fullnode); + node.should.be.an.instanceof(bcoin.fullnode); }); it('should call trust.addTX() on every transaction', async function() { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index a959f53..885ae45 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -67,10 +67,10 @@ describe('TrustIsRisk', () => { describe('.getDirectTrust()', () => { it('returns zero for two arbitary parties that do not trust each other', () => { - should(tir.getDirectTrust(alice, bob)).equal(0); - should(tir.getDirectTrust(bob, alice)).equal(0); - should(tir.getDirectTrust(charlie, alice)).equal(0); - should(tir.getDirectTrust(alice, charlie)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); + tir.getDirectTrust(bob, alice).should.equal(0); + tir.getDirectTrust(charlie, alice).should.equal(0); + tir.getDirectTrust(alice, charlie).should.equal(0); }); }); @@ -85,7 +85,7 @@ describe('TrustIsRisk', () => { }); tir.parseTXAsTrustIncrease(trustIncreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); }); }); @@ -93,15 +93,15 @@ describe('TrustIsRisk', () => { it('correctly increases trust', () => { tir.addTX(trustIncreasingTX); - should(tir.getDirectTrust(alice, bob)).equal(42); - should(tir.getDirectTrust(bob, alice)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(42); + tir.getDirectTrust(bob, alice).should.equal(0); }); it('which has more than one input does not change trust', () => { trustIncreasingMTX.inputs.push(inputP2PKH); tir.addTX(trustIncreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); }); it('which has a change output correctly increases trust', () => { @@ -109,7 +109,7 @@ describe('TrustIsRisk', () => { trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(alice, 10)); tir.addTX(trustIncreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(32); + tir.getDirectTrust(alice, bob).should.equal(32); }); it('which has two change outputs does not change trust', () => { @@ -119,7 +119,7 @@ describe('TrustIsRisk', () => { } tir.addTX(trustIncreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); }); it('which has a second output that is not a change output does not change trust', () => { @@ -127,7 +127,7 @@ describe('TrustIsRisk', () => { trustIncreasingMTX.outputs.push(testHelpers.P2PKHOutput(charlie, 5)); tir.addTX(trustIncreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); }); }); @@ -139,14 +139,14 @@ describe('TrustIsRisk', () => { it('correctly decreases trust', () => { tir.addTX(trustDecreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(20); + tir.getDirectTrust(alice, bob).should.equal(20); }); it('which has a second input decreases trust to zero', () => { trustDecreasingMTX.inputs.push(inputP2PKH); tir.addTX(trustDecreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); }); it('which has more than one trust outputs decreases trust to zero', () => { @@ -154,7 +154,7 @@ describe('TrustIsRisk', () => { trustDecreasingMTX.outputs.push(Object.assign(outputOneOfTwoMultisig.clone(), {value: 5})); tir.addTX(trustDecreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(0); + tir.getDirectTrust(alice, bob).should.equal(0); }); }); }); From 23d9a4b3cbe59a9d5da919c0551585e0d8563295 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Sat, 27 May 2017 19:02:24 +0000 Subject: [PATCH 008/540] Implement .getTrustDecreasingMTXs() --- flow-typed/npm/bcoin_vx.x.x.js | 1 + lib/direct_trust.js | 106 +++++++++++++ lib/helpers.js | 12 ++ lib/trust_db.js | 115 ++++++++++++++ lib/trust_is_risk.js | 258 +++++++++++++++----------------- lib/types.js | 8 + src/direct_trust.js | 106 +++++++++++++ src/helpers.js | 12 ++ src/trust_db.js | 115 ++++++++++++++ src/trust_is_risk.js | 264 +++++++++++++++------------------ src/types.js | 8 + test/trust_is_risk.js | 65 ++++++++ 12 files changed, 787 insertions(+), 283 deletions(-) create mode 100644 lib/direct_trust.js create mode 100644 lib/helpers.js create mode 100644 lib/trust_db.js create mode 100644 lib/types.js create mode 100644 src/direct_trust.js create mode 100644 src/helpers.js create mode 100644 src/trust_db.js create mode 100644 src/types.js diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 504682f..74a3e2e 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -28,6 +28,7 @@ declare class bcoin$MTX { toTX : bcoin$TX; template(ring : bcoin$KeyRing) : number; scriptVector(outputScript : bcoin$Script, inputScript : bcoin$Script, ring : bcoin$KeyRing) : boolean; + addOutput(output : bcoin$Output) : void; } diff --git a/lib/direct_trust.js b/lib/direct_trust.js new file mode 100644 index 0000000..6545c0b --- /dev/null +++ b/lib/direct_trust.js @@ -0,0 +1,106 @@ +// + +var bcoin = require('bcoin'); +var assert = require('assert'); +var helpers = require('./helpers'); + + + + + + + + + + + + + + +class DirectTrust { + + + + + // Every DT is associated with a transaction output, except for non-standard trust decreasing + // transactions, which reduce trust to zero and are related to a whole transaction and not + // a specific output. + + + + + + + + constructor(options ) { + this.outputIndex = null; + this.script = null; + this.prev = null; + this.next = null; + Object.assign(this, options); + } + + isNull() { + return this.amount === 0; + } + + isIncrease() { + return this.prev === null; + } + + isDecrease() { + return !this.isIncrease(); + } + + isSpent() { + return this.next !== null; + } + + isSpendable() { + return !this.isSpent() && !this.isNull(); + } + + isValid() { + // TODO: Consider removing this function and ensure validity at build time by using the flow + // type system, possibly by creating sub-types like "IncreasingDirectTrust" etc. + var valid = true; + + if ((this.outputIndex === null) !== (this.script === null)) valid = false; + if (this.outputIndex === null && this.isIncrease()) valid = false; + if (this.outputIndex === null && this.amount > 0) valid = false; + if (this.isIncrease() && this.isNull()) valid = false; + if (this.isSpent() && this.isNull()) valid = false; + + return valid; + } + + getFromEntity() { + return helpers.pubKeyToEntity(this.from); + } + + getToEntity() { + return helpers.pubKeyToEntity(this.to); + } + + spend(next ) { + assert(!this.isSpent()); + assert(this.from.equals(next.from) && this.to.equals(next.to)); + assert(next.amount <= this.amount); + + this.next = next; + next.prev = this; + } + + getNullifying(txHash ) { + return new DirectTrust({ + from: this.from, + to: this.to, + amount: 0, + + prev: this, + txHash, + }); + } +} + +module.exports = DirectTrust; diff --git a/lib/helpers.js b/lib/helpers.js new file mode 100644 index 0000000..f7c1443 --- /dev/null +++ b/lib/helpers.js @@ -0,0 +1,12 @@ +// + +var bcoin = require('bcoin'); +var Address = bcoin.primitives.Address; + +var helpers = { + pubKeyToEntity: (key ) => { + return Address.fromHash(bcoin.crypto.hash160(key)).toBase58() + } +}; + +module.exports = helpers; diff --git a/lib/trust_db.js b/lib/trust_db.js new file mode 100644 index 0000000..ccd282b --- /dev/null +++ b/lib/trust_db.js @@ -0,0 +1,115 @@ +// + +var assert = require('assert'); +var SortedSet = require('sorted-set'); +var maxFlow = require('graph-theory-ford-fulkerson'); +var bcoin = require('bcoin'); +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var DirectTrust = require('./direct_trust'); + +class TrustDB { + + + + + constructor() { + this.directTrusts = new Map(); + this.txToDirectTrust = new Map(); + this.entities = new SortedSet(); + } + + getDirectTrustByTX(txHash ) { + if (!this.isTrustTX(txHash)) return null; + return ((this.txToDirectTrust.get(txHash) ) ); + } + + getDirectTrustByOutpoint(outpoint ) { + var trust = this.txToDirectTrust.get(outpoint.hash.toString('hex')); + if (!trust) return null; + if (trust.outputIndex !== outpoint.index) return null; + return trust; + } + + getDirectTrustAmount(from , to ) { + if (from === to) return Infinity; + + var trusts = this.getSpendableDirectTrusts(from, to); + return trusts.reduce((sum, t) => sum + t.amount, 0); + } + + getSpendableDirectTrusts(from , to ) { + return this.getDirectTrusts(from, to).filter((t) => t.isSpendable()); + } + + getDirectTrusts(from , to ) { + var fromMap = this.directTrusts.get(from); + if (!fromMap) return []; + + var trusts = fromMap.get(to); + if (!trusts) return []; + + return trusts; + } + + getGraphWeightMatrix() { + var entitiesArr = this.getEntities(); + return entitiesArr.map((from) => { + return entitiesArr.map((to) => this.getDirectTrustAmount(from, to)); + }); + } + + getTrustAmount(from , to ) { + // TODO: Optimize + if (from === to) return Infinity; + + var graph = this.getGraphWeightMatrix(); + var fromIndex = this.getEntityIndex(from); + var toIndex = this.getEntityIndex(to); + + if (fromIndex === -1 || toIndex === -1) return 0; + else return maxFlow(graph, fromIndex, toIndex); + } + + getEntities() { + return this.entities.slice(0, this.entities.length); + } + + getEntityIndex(entity ) { + return this.entities.rank(entity); + } + + isTrustTX(txHash ) { + return this.txToDirectTrust.has(txHash); + } + + add(trust ) { + var from = trust.getFromEntity(); + var to = trust.getToEntity(); + assert(from !== to); + + if (!this.directTrusts.has(from)) this.directTrusts.set(from, new Map()); + var fromMap = ((this.directTrusts.get(from) ) ); + + if (!fromMap.has(to)) fromMap.set(to, []); + var trusts = ((fromMap.get(to) ) ); + + if (trust.prev !== null) { + trust.prev.spend(trust); + assert(trust.prev && trust.prev.isValid() && !trust.prev.isSpendable()); + } + + assert(trust.isValid()); + trusts.push(trust); + this.txToDirectTrust.set(trust.txHash, trust); + + this.entities.add(from); + this.entities.add(to); + } +} + +module.exports = TrustDB; diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 2b2a5b6..278f64a 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -1,4 +1,5 @@ // + var bcoin = require('bcoin'); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -7,90 +8,27 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var assert = require('assert'); -var SortedSet = require('sorted-set'); -var maxFlow = require('graph-theory-ford-fulkerson'); - - - // base58 bitcoin address - - - - - - - - - - +var helpers = require('./helpers'); +var TrustDB = require('./trust_db'); +var DirectTrust = require('./direct_trust'); class TrustIsRisk { - - - - - - - - - - - - + constructor(node ) { this.node = node; - this.directTrust = {}; - this.TXToTrust = {}; - this.entities = new SortedSet(); + this.trustDB = new TrustDB(); this.node.on('tx', this.addTX.bind(this)); } - async getTrustIncreasingMTX(from , to , outpoint , trustAmount ) - { - var prevTX = await this.node.getTX(outpoint.hash); - var prevOutput = prevTX.outputs[outpoint.index]; - - var mtx = new MTX({ - inputs: [ - Input.fromOutpoint(outpoint) - ], - outputs: [ - new Output({ // Trust output - script: bcoin.script.fromMultisig(1, 2, [from, to]), - value: trustAmount - }), - new Output({ // Change output - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), - value: prevOutput.value - trustAmount - }) - ] - }); - - var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); - assert(success); - - return mtx; - } - - getTrust(from , to ) { - if (from === to) return Infinity; - - // TODO: Optimize - var graph = this.getGraphWeightMatrix(); - var fromIndex = this.getGraphWeightMatrixIndex(from); - var toIndex = this.getGraphWeightMatrixIndex(to); - - if (fromIndex === -1 || toIndex === -1) return 0; - else return maxFlow(graph, fromIndex, toIndex); + getTrust(from , to ) { + return this.trustDB.getTrustAmount(from, to); } - getDirectTrust(from , to ) { - if (from === to) return Infinity; - if (!this.directTrust.hasOwnProperty(from)) return 0; - if (!this.directTrust[from].hasOwnProperty(to)) return 0; - return this.directTrust[from][to]; + getDirectTrust(from , to ) { + return this.trustDB.getDirectTrustAmount(from, to); } // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network @@ -100,23 +38,23 @@ class TrustIsRisk { // Throws an error if the transaction was processed earlier. addTX(tx ) { var txHash = tx.hash().toString('hex'); - if (this.TXToTrust.hasOwnProperty(txHash)) { - throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen before.'); + if (this.trustDB.isTrustTX(txHash)) { + throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } - var trustChanges = this.getTrustChanges(tx); - if (trustChanges.length === 0) return false; + var directTrusts = this.getDirectTrusts(tx); + if (directTrusts.length === 0) return false; else { - trustChanges.map(this.applyTrustChange.bind(this)); + directTrusts.map(this.trustDB.add.bind(this.trustDB)); return true; } } - // Returns a list of trust changes that a transaction causes, which will be one of the following: + // Returns a list of trusts that a transaction contains, which will be one of the following: // * An empty list (for non-TIR transactions). // * A list containing a single trust increase (for trust-increasing transactions). // * A list containing one or more trust decreases (for trust-decreasing transactions). - getTrustChanges(tx ) { + getDirectTrusts(tx ) { var trustIncrease = this.parseTXAsTrustIncrease(tx); if (trustIncrease !== null) { return [trustIncrease]; @@ -125,32 +63,89 @@ class TrustIsRisk { } } - applyTrustChange(trustChange ) { - if (!this.directTrust.hasOwnProperty(trustChange.from)) this.directTrust[trustChange.from] = {}; - if (!this.directTrust[trustChange.from].hasOwnProperty(trustChange.to)) { - this.directTrust[trustChange.from][trustChange.to] = 0 + async getTrustIncreasingMTX(from , to , outpoint , trustAmount ) + { + var prevTX = await this.node.getTX(outpoint.hash); + if (!prevTX) throw new Error('Could not find transaction'); + + var prevOutput = prevTX.outputs[outpoint.index]; + if (!prevOutput) throw new Error('Could not find transaction output'); + + var mtx = new MTX({ + inputs: [ + Input.fromOutpoint(outpoint) + ], + outputs: [ + new Output({ + script: bcoin.script.fromMultisig(1, 2, [from, to]), + value: trustAmount + }) + ] + }); + + var changeAmount = prevOutput.value - trustAmount; + if (changeAmount) { + mtx.addOutput(new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), + value: changeAmount + })); } - this.directTrust[trustChange.from][trustChange.to] += trustChange.amount; + var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); + assert(success); + + return mtx; + } + + getTrustDecreasingMTXs(from , to , trustDecreaseAmount ) + { + var fromAddress = Address.fromHash(bcoin.crypto.hash160(from)).toBase58(); + var toAddress = Address.fromHash(bcoin.crypto.hash160(to)).toBase58(); + if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); + + var existingTrustAmount = this.trustDB.getDirectTrustAmount(fromAddress, toAddress); + if (existingTrustAmount < trustDecreaseAmount) throw new Error('Insufficient trust'); + + var directTrusts = this.trustDB.getSpendableDirectTrusts(fromAddress, toAddress); + return directTrusts.map((directTrust) => { + var decrease = Math.min(trustDecreaseAmount, directTrust.amount); + if (decrease === 0) return null; + trustDecreaseAmount -= decrease; + return this.getTrustDecreasingMTX(directTrust, decrease); + }).filter(Boolean); + } + + getTrustDecreasingMTX(directTrust , decreaseAmount ) { + var remainingTrustAmount = directTrust.amount - decreaseAmount; + + var mtx = new MTX({ + inputs: [ + Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) + ], + outputs: [new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(directTrust.from)), + value: decreaseAmount + })] + }); - if (this.directTrust[trustChange.from][trustChange.to] > 0) { - this.TXToTrust[trustChange.txHash] = { - from: trustChange.from, - to: trustChange.to, - amount: this.directTrust[trustChange.from][trustChange.to], - txHash: trustChange.txHash, - outputIndex: trustChange.outputIndex - }; + if (remainingTrustAmount > 0) { + mtx.addOutput(new Output({ + script: bcoin.script.fromMultisig(1, 2, [directTrust.from, directTrust.to]), + value: remainingTrustAmount + })); } - this.entities.add(trustChange.from); - this.entities.add(trustChange.to); + var success = mtx.scriptVector(((directTrust.script ) ), + mtx.inputs[0].script, KeyRing.fromPublic(directTrust.from)); + assert(success); + + return mtx; } parseTXAsTrustIncrease(tx ) { if (tx.inputs.length !== 1) return null; if (tx.inputs[0].getType() !== 'pubkeyhash') return null; // TODO: This is unreliable - if (this.TXToTrust[tx.inputs[0].prevout.hash.toString('hex')]) return null; + if (this.trustDB.isTrustTX(tx.inputs[0].prevout.hash.toString('hex'))) return null; var sender = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -171,7 +166,7 @@ class TrustIsRisk { getInputTrusts(inputs ) { return inputs.map((input) => { - var trust = this.TXToTrust[input.prevout.hash.toString('hex')] + var trust = this.trustDB.getDirectTrustByOutpoint(input.prevout); if (trust && trust.outputIndex === input.prevout.index) return trust; else return null; }).filter(Boolean); @@ -179,35 +174,23 @@ class TrustIsRisk { getTrustDecrease(tx , prevTrust ) { var txHash = tx.hash().toString('hex'); - var nullifyTrust = { - from: prevTrust.from, - to: prevTrust.to, - amount: -prevTrust.amount, - txHash, - outputIndex: null - }; + var nullTrust = prevTrust.getNullifying(txHash); - if (tx.inputs.length !== 1) return nullifyTrust; + if (tx.inputs.length !== 1) return nullTrust; - var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.from, prevTrust.to); - if (trustOutputs.length != 1) return nullifyTrust; + var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getFromEntity(), + prevTrust.getToEntity()); + if (trustOutputs.length != 1) return nullTrust; var nextTrust = trustOutputs[0]; - assert(nextTrust.from === prevTrust.from); - assert(nextTrust.to === prevTrust.to); + nextTrust.prev = prevTrust; - var trustAmountChange = nextTrust.amount - prevTrust.amount; - assert(trustAmountChange <= 0); - return { - from: nextTrust.from, - to: nextTrust.to, - amount: trustAmountChange, - txHash, - outputIndex: nextTrust.outputIndex - } + assert(nextTrust.amount - prevTrust.amount <= 0); + return nextTrust; } - + // Looks for direct trust outputs that originate from a sender in an array of bitcoin outputs. + // Returns a list of the corresponding DirectTrust objects. // If the recipient parameter is set, it will limit the results only to the outputs being sent to // the recipient. searchForDirectTrustOutputs(tx , sender , recipient ) { @@ -233,35 +216,30 @@ class TrustIsRisk { var output = tx.outputs[outputIndex]; if (output.getType() !== 'multisig') return null; - var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58(); - var addressB = Address.fromHash(bcoin.crypto.hash160(output.script.get(2))).toBase58(); - - if (addressA === addressB) return null; + var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); + if (entities[0] === entities[1]) return null; - var recipient; - if (addressA === sender) recipient = addressB; - else if (addressB === sender) recipient = addressA; + var from, to; + if (entities[0] === sender) { + from = output.script.get(1); + to = output.script.get(2); + } + else if (entities[1] === sender) { + from = output.script.get(2); + to = output.script.get(1); + } else return null; - return { - from: sender, - to: recipient, + return new DirectTrust({ + from, + to, amount: Number(output.value), - txHash, - outputIndex - }; - } - getGraphWeightMatrix() { - var entitiesArr = this.entities.slice(0, this.entities.length); - return entitiesArr.map((from) => { - return entitiesArr.map((to) => this.getDirectTrust(from, to)); + txHash, + outputIndex, + script: output.script }); } - - getGraphWeightMatrixIndex(entity ) { - return this.entities.rank(entity); - } } module.exports = TrustIsRisk; diff --git a/lib/types.js b/lib/types.js new file mode 100644 index 0000000..44ee569 --- /dev/null +++ b/lib/types.js @@ -0,0 +1,8 @@ +// + +// base58 bitcoin address: + + + + + diff --git a/src/direct_trust.js b/src/direct_trust.js new file mode 100644 index 0000000..fe3e687 --- /dev/null +++ b/src/direct_trust.js @@ -0,0 +1,106 @@ +// @flow +import type {Entity, TXHash, PubKey} from "./types" +var bcoin = require('bcoin'); +var assert = require('assert'); +var helpers = require('./helpers'); + +type DirectTrustOptions = { + from : PubKey, + to : PubKey, + amount : number, + + txHash : string, + outputIndex? : number, + script? : bcoin$Script, + + prev? : DirectTrust, + next? :DirectTrust +} + +class DirectTrust { + from : PubKey + to : PubKey + amount : number + + // Every DT is associated with a transaction output, except for non-standard trust decreasing + // transactions, which reduce trust to zero and are related to a whole transaction and not + // a specific output. + txHash : string + outputIndex : (number | null) + script : (bcoin$Script | null) + + prev : (DirectTrust | null) + next : (DirectTrust | null) + + constructor(options : DirectTrustOptions) { + this.outputIndex = null; + this.script = null; + this.prev = null; + this.next = null; + Object.assign(this, options); + } + + isNull() { + return this.amount === 0; + } + + isIncrease() : boolean { + return this.prev === null; + } + + isDecrease() : boolean { + return !this.isIncrease(); + } + + isSpent() : boolean { + return this.next !== null; + } + + isSpendable() : boolean { + return !this.isSpent() && !this.isNull(); + } + + isValid() : boolean { + // TODO: Consider removing this function and ensure validity at build time by using the flow + // type system, possibly by creating sub-types like "IncreasingDirectTrust" etc. + var valid = true; + + if ((this.outputIndex === null) !== (this.script === null)) valid = false; + if (this.outputIndex === null && this.isIncrease()) valid = false; + if (this.outputIndex === null && this.amount > 0) valid = false; + if (this.isIncrease() && this.isNull()) valid = false; + if (this.isSpent() && this.isNull()) valid = false; + + return valid; + } + + getFromEntity() : Entity { + return helpers.pubKeyToEntity(this.from); + } + + getToEntity() : Entity { + return helpers.pubKeyToEntity(this.to); + } + + spend(next : DirectTrust) : void { + assert(!this.isSpent()); + assert(this.from.equals(next.from) && this.to.equals(next.to)); + assert(next.amount <= this.amount); + + this.next = next; + next.prev = this; + } + + getNullifying(txHash : string) : DirectTrust { + return new DirectTrust({ + from: this.from, + to: this.to, + amount: 0, + + prev: this, + txHash, + }); + } +} + +module.exports = DirectTrust; diff --git a/src/helpers.js b/src/helpers.js new file mode 100644 index 0000000..fcf67bc --- /dev/null +++ b/src/helpers.js @@ -0,0 +1,12 @@ +// @flow +import type {Entity, TXHash, PubKey} from "./types" +var bcoin = require('bcoin'); +var Address = bcoin.primitives.Address; + +var helpers = { + pubKeyToEntity: (key : PubKey) : Entity => { + return Address.fromHash(bcoin.crypto.hash160(key)).toBase58() + } +}; + +module.exports = helpers; diff --git a/src/trust_db.js b/src/trust_db.js new file mode 100644 index 0000000..bca781c --- /dev/null +++ b/src/trust_db.js @@ -0,0 +1,115 @@ +// @flow +import type {Entity, TXHash, PubKey} from "./types" +var assert = require('assert'); +var SortedSet = require('sorted-set'); +var maxFlow = require('graph-theory-ford-fulkerson'); +var bcoin = require('bcoin'); +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var DirectTrust = require('./direct_trust'); + +class TrustDB { + directTrusts : Map>> + txToDirectTrust : Map + entities : SortedSet; + + constructor() { + this.directTrusts = new Map(); + this.txToDirectTrust = new Map(); + this.entities = new SortedSet(); + } + + getDirectTrustByTX(txHash : string) : (DirectTrust | null) { + if (!this.isTrustTX(txHash)) return null; + return ((this.txToDirectTrust.get(txHash) : any) : DirectTrust); + } + + getDirectTrustByOutpoint(outpoint : bcoin$Outpoint) : (DirectTrust | null) { + var trust = this.txToDirectTrust.get(outpoint.hash.toString('hex')); + if (!trust) return null; + if (trust.outputIndex !== outpoint.index) return null; + return trust; + } + + getDirectTrustAmount(from : Entity, to : Entity) : number { + if (from === to) return Infinity; + + var trusts = this.getSpendableDirectTrusts(from, to); + return trusts.reduce((sum, t) => sum + t.amount, 0); + } + + getSpendableDirectTrusts(from : Entity, to : Entity) : DirectTrust[] { + return this.getDirectTrusts(from, to).filter((t) => t.isSpendable()); + } + + getDirectTrusts(from : Entity, to : Entity) : DirectTrust[] { + var fromMap = this.directTrusts.get(from); + if (!fromMap) return []; + + var trusts = fromMap.get(to); + if (!trusts) return []; + + return trusts; + } + + getGraphWeightMatrix() : number[][] { + var entitiesArr = this.getEntities(); + return entitiesArr.map((from) => { + return entitiesArr.map((to) => this.getDirectTrustAmount(from, to)); + }); + } + + getTrustAmount(from : Entity, to : Entity) : number { + // TODO: Optimize + if (from === to) return Infinity; + + var graph = this.getGraphWeightMatrix(); + var fromIndex = this.getEntityIndex(from); + var toIndex = this.getEntityIndex(to); + + if (fromIndex === -1 || toIndex === -1) return 0; + else return maxFlow(graph, fromIndex, toIndex); + } + + getEntities() : Entity[] { + return this.entities.slice(0, this.entities.length); + } + + getEntityIndex(entity : Entity) : number { + return this.entities.rank(entity); + } + + isTrustTX(txHash : string) : boolean { + return this.txToDirectTrust.has(txHash); + } + + add(trust : DirectTrust) { + var from = trust.getFromEntity(); + var to = trust.getToEntity(); + assert(from !== to); + + if (!this.directTrusts.has(from)) this.directTrusts.set(from, new Map()); + var fromMap = ((this.directTrusts.get(from) : any) : Map>); + + if (!fromMap.has(to)) fromMap.set(to, []); + var trusts = ((fromMap.get(to) : any) : Array); + + if (trust.prev !== null) { + trust.prev.spend(trust); + assert(trust.prev && trust.prev.isValid() && !trust.prev.isSpendable()); + } + + assert(trust.isValid()); + trusts.push(trust); + this.txToDirectTrust.set(trust.txHash, trust); + + this.entities.add(from); + this.entities.add(to); + } +} + +module.exports = TrustDB; diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 42dce05..3f35e59 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,4 +1,5 @@ // @flow +import type {Entity, TXHash, PubKey} from "./types" var bcoin = require('bcoin'); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -7,90 +8,27 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var assert = require('assert'); -var SortedSet = require('sorted-set'); -var maxFlow = require('graph-theory-ford-fulkerson'); - - -type Entity = string; // base58 bitcoin address -type DirectTrust = { - from : Entity, - to: Entity, - amount: number, - txHash: string, - outputIndex: ?number, // Not set for nullifying trust changes -} -type TrustChange = DirectTrust; -type TXHash = string; -type PubKey = Buffer; +var helpers = require('./helpers'); +var TrustDB = require('./trust_db'); +var DirectTrust = require('./direct_trust'); class TrustIsRisk { node : bcoin$FullNode - - directTrust : { - [from : Entity] : ({ - [to : Entity] : number - }) - } - - TXToTrust : { - [hash : TXHash] : DirectTrust - } - - entities : SortedSet + trustDB : TrustDB constructor(node : bcoin$FullNode) { this.node = node; - this.directTrust = {}; - this.TXToTrust = {}; - this.entities = new SortedSet(); + this.trustDB = new TrustDB(); this.node.on('tx', this.addTX.bind(this)); } - async getTrustIncreasingMTX(from : PubKey, to : PubKey, outpoint : bcoin$Outpoint, trustAmount : number) - : Promise { - var prevTX = await this.node.getTX(outpoint.hash); - var prevOutput = prevTX.outputs[outpoint.index]; - - var mtx = new MTX({ - inputs: [ - Input.fromOutpoint(outpoint) - ], - outputs: [ - new Output({ // Trust output - script: bcoin.script.fromMultisig(1, 2, [from, to]), - value: trustAmount - }), - new Output({ // Change output - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), - value: prevOutput.value - trustAmount - }) - ] - }); - - var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); - assert(success); - - return mtx; - } - - getTrust(from : Entity, to : Entity) : number { - if (from === to) return Infinity; - - // TODO: Optimize - var graph = this.getGraphWeightMatrix(); - var fromIndex = this.getGraphWeightMatrixIndex(from); - var toIndex = this.getGraphWeightMatrixIndex(to); - - if (fromIndex === -1 || toIndex === -1) return 0; - else return maxFlow(graph, fromIndex, toIndex); + getTrust(from : Entity, to : Entity) { + return this.trustDB.getTrustAmount(from, to); } - getDirectTrust(from : Entity, to : Entity) : number { - if (from === to) return Infinity; - if (!this.directTrust.hasOwnProperty(from)) return 0; - if (!this.directTrust[from].hasOwnProperty(to)) return 0; - return this.directTrust[from][to]; + getDirectTrust(from : Entity, to : Entity) { + return this.trustDB.getDirectTrustAmount(from, to); } // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network @@ -100,23 +38,23 @@ class TrustIsRisk { // Throws an error if the transaction was processed earlier. addTX(tx : bcoin$TX) : boolean { var txHash = tx.hash().toString('hex'); - if (this.TXToTrust.hasOwnProperty(txHash)) { - throw new Error('Duplicate TX: Transaction with hash ' + txHash + ' has been seen before.'); + if (this.trustDB.isTrustTX(txHash)) { + throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } - var trustChanges = this.getTrustChanges(tx); - if (trustChanges.length === 0) return false; + var directTrusts = this.getDirectTrusts(tx); + if (directTrusts.length === 0) return false; else { - trustChanges.map(this.applyTrustChange.bind(this)); + directTrusts.map(this.trustDB.add.bind(this.trustDB)); return true; } } - // Returns a list of trust changes that a transaction causes, which will be one of the following: + // Returns a list of trusts that a transaction contains, which will be one of the following: // * An empty list (for non-TIR transactions). // * A list containing a single trust increase (for trust-increasing transactions). // * A list containing one or more trust decreases (for trust-decreasing transactions). - getTrustChanges(tx : bcoin$TX) : TrustChange[] { + getDirectTrusts(tx : bcoin$TX) : DirectTrust[] { var trustIncrease = this.parseTXAsTrustIncrease(tx); if (trustIncrease !== null) { return [trustIncrease]; @@ -125,32 +63,89 @@ class TrustIsRisk { } } - applyTrustChange(trustChange : TrustChange) { - if (!this.directTrust.hasOwnProperty(trustChange.from)) this.directTrust[trustChange.from] = {}; - if (!this.directTrust[trustChange.from].hasOwnProperty(trustChange.to)) { - this.directTrust[trustChange.from][trustChange.to] = 0 + async getTrustIncreasingMTX(from : PubKey, to : PubKey, outpoint : bcoin$Outpoint, trustAmount : number) + : Promise { + var prevTX = await this.node.getTX(outpoint.hash); + if (!prevTX) throw new Error('Could not find transaction'); + + var prevOutput = prevTX.outputs[outpoint.index]; + if (!prevOutput) throw new Error('Could not find transaction output'); + + var mtx = new MTX({ + inputs: [ + Input.fromOutpoint(outpoint) + ], + outputs: [ + new Output({ + script: bcoin.script.fromMultisig(1, 2, [from, to]), + value: trustAmount + }) + ] + }); + + var changeAmount = prevOutput.value - trustAmount; + if (changeAmount) { + mtx.addOutput(new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), + value: changeAmount + })); } - this.directTrust[trustChange.from][trustChange.to] += trustChange.amount; + var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); + assert(success); + + return mtx; + } + + getTrustDecreasingMTXs(from : PubKey, to : PubKey, trustDecreaseAmount : number) + : bcoin$MTX[] { + var fromAddress = Address.fromHash(bcoin.crypto.hash160(from)).toBase58(); + var toAddress = Address.fromHash(bcoin.crypto.hash160(to)).toBase58(); + if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); + + var existingTrustAmount = this.trustDB.getDirectTrustAmount(fromAddress, toAddress); + if (existingTrustAmount < trustDecreaseAmount) throw new Error('Insufficient trust'); + + var directTrusts = this.trustDB.getSpendableDirectTrusts(fromAddress, toAddress); + return directTrusts.map((directTrust) => { + var decrease = Math.min(trustDecreaseAmount, directTrust.amount); + if (decrease === 0) return null; + trustDecreaseAmount -= decrease; + return this.getTrustDecreasingMTX(directTrust, decrease); + }).filter(Boolean); + } + + getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number) { + var remainingTrustAmount = directTrust.amount - decreaseAmount; + + var mtx = new MTX({ + inputs: [ + Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) + ], + outputs: [new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(directTrust.from)), + value: decreaseAmount + })] + }); - if (this.directTrust[trustChange.from][trustChange.to] > 0) { - this.TXToTrust[trustChange.txHash] = { - from: trustChange.from, - to: trustChange.to, - amount: this.directTrust[trustChange.from][trustChange.to], - txHash: trustChange.txHash, - outputIndex: trustChange.outputIndex - }; + if (remainingTrustAmount > 0) { + mtx.addOutput(new Output({ + script: bcoin.script.fromMultisig(1, 2, [directTrust.from, directTrust.to]), + value: remainingTrustAmount + })); } - this.entities.add(trustChange.from); - this.entities.add(trustChange.to); + var success = mtx.scriptVector(((directTrust.script : any) : bcoin$Script), + mtx.inputs[0].script, KeyRing.fromPublic(directTrust.from)); + assert(success); + + return mtx; } - parseTXAsTrustIncrease(tx : bcoin$TX) : (TrustChange | null) { + parseTXAsTrustIncrease(tx : bcoin$TX) : (DirectTrust | null) { if (tx.inputs.length !== 1) return null; if (tx.inputs[0].getType() !== 'pubkeyhash') return null; // TODO: This is unreliable - if (this.TXToTrust[tx.inputs[0].prevout.hash.toString('hex')]) return null; + if (this.trustDB.isTrustTX(tx.inputs[0].prevout.hash.toString('hex'))) return null; var sender = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -164,50 +159,38 @@ class TrustIsRisk { return trustOutputs[0]; } - getTrustDecreases(tx : bcoin$TX) : TrustChange[] { + getTrustDecreases(tx : bcoin$TX) : DirectTrust[] { var inputTrusts = this.getInputTrusts(tx.inputs); return inputTrusts.map(this.getTrustDecrease.bind(this, tx)); } getInputTrusts(inputs : bcoin$Input[]) : DirectTrust[] { return inputs.map((input) => { - var trust = this.TXToTrust[input.prevout.hash.toString('hex')] + var trust = this.trustDB.getDirectTrustByOutpoint(input.prevout); if (trust && trust.outputIndex === input.prevout.index) return trust; else return null; }).filter(Boolean); } - getTrustDecrease(tx : bcoin$TX, prevTrust : DirectTrust) : TrustChange { + getTrustDecrease(tx : bcoin$TX, prevTrust : DirectTrust) : DirectTrust { var txHash = tx.hash().toString('hex'); - var nullifyTrust = { - from: prevTrust.from, - to: prevTrust.to, - amount: -prevTrust.amount, - txHash, - outputIndex: null - }; + var nullTrust = prevTrust.getNullifying(txHash); - if (tx.inputs.length !== 1) return nullifyTrust; + if (tx.inputs.length !== 1) return nullTrust; - var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.from, prevTrust.to); - if (trustOutputs.length != 1) return nullifyTrust; + var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getFromEntity(), + prevTrust.getToEntity()); + if (trustOutputs.length != 1) return nullTrust; var nextTrust = trustOutputs[0]; - assert(nextTrust.from === prevTrust.from); - assert(nextTrust.to === prevTrust.to); + nextTrust.prev = prevTrust; - var trustAmountChange = nextTrust.amount - prevTrust.amount; - assert(trustAmountChange <= 0); - return { - from: nextTrust.from, - to: nextTrust.to, - amount: trustAmountChange, - txHash, - outputIndex: nextTrust.outputIndex - } + assert(nextTrust.amount - prevTrust.amount <= 0); + return nextTrust; } - + // Looks for direct trust outputs that originate from a sender in an array of bitcoin outputs. + // Returns a list of the corresponding DirectTrust objects. // If the recipient parameter is set, it will limit the results only to the outputs being sent to // the recipient. searchForDirectTrustOutputs(tx : bcoin$TX, sender : Entity, recipient : ?Entity) : DirectTrust[] { @@ -233,35 +216,30 @@ class TrustIsRisk { var output = tx.outputs[outputIndex]; if (output.getType() !== 'multisig') return null; - var addressA = Address.fromHash(bcoin.crypto.hash160(output.script.get(1))).toBase58(); - var addressB = Address.fromHash(bcoin.crypto.hash160(output.script.get(2))).toBase58(); - - if (addressA === addressB) return null; + var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); + if (entities[0] === entities[1]) return null; - var recipient; - if (addressA === sender) recipient = addressB; - else if (addressB === sender) recipient = addressA; + var from, to; + if (entities[0] === sender) { + from = output.script.get(1); + to = output.script.get(2); + } + else if (entities[1] === sender) { + from = output.script.get(2); + to = output.script.get(1); + } else return null; - return { - from: sender, - to: recipient, + return new DirectTrust({ + from, + to, amount: Number(output.value), - txHash, - outputIndex - }; - } - getGraphWeightMatrix() : number[][] { - var entitiesArr = this.entities.slice(0, this.entities.length); - return entitiesArr.map((from) => { - return entitiesArr.map((to) => this.getDirectTrust(from, to)); + txHash, + outputIndex, + script: output.script }); } - - getGraphWeightMatrixIndex(entity : Entity) : number { - return this.entities.rank(entity); - } } module.exports = TrustIsRisk; diff --git a/src/types.js b/src/types.js new file mode 100644 index 0000000..1dc9d64 --- /dev/null +++ b/src/types.js @@ -0,0 +1,8 @@ +//@flow + +// base58 bitcoin address: +export type Entity = string; + +export type TXHash = string; + +export type PubKey = Buffer; diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 88c1d26..bb2b11a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -110,6 +110,11 @@ describe('TrustIsRisk', () => { should(tir.getDirectTrust(alice, bob)).equal(0); }); + it('which has been processed before throws', () => { + var tx = trustIncreasingMTX.toTX(); + tir.addTX(tx); + should.throws(() => tir.addTX(tx), /already processed/i); + }); }); describe('with a trust decreasing transaction', () => { @@ -183,6 +188,66 @@ describe('TrustIsRisk', () => { }); }); + describe('.getTrustDecreasingMTX()', () => { + var trustTXs = []; + beforeEach(() => { + var tx; + + tx = trustIncreasingTX; + trustTXs.push(tx); + tir.addTX(tx); + + trustIncreasingMTX.outputs[0].value = 100; + tx = trustIncreasingMTX.toTX(); + trustTXs.push(tx); + tir.addTX(tx); + + trustIncreasingMTX.outputs[0].value = 500; + tx = trustIncreasingMTX.toTX(); + trustTXs.push(tx); + tir.addTX(tx); + + // Total trust 642 + }); + + it('creates correct trust decreasing transactions', () => { + // Should spend the entire first transaction and 40 from the second transaction + var mtxs = tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 82); + mtxs.length.should.equal(2); + var mtx = mtxs[0]; + + mtx.inputs.length.should.equal(1); + mtx.inputs[0].prevout.should.have.properties({ + hash: trustTXs[0].hash().toString('hex'), + index: 0 + }); + + mtx.outputs.length.should.equal(1); // Single P2PKH output + mtx.outputs[0].getType().should.equal('pubkeyhash'); + mtx.outputs[0].getAddress().toBase58().should.equal(alice); + mtx.outputs[0].value.should.equal(42); + + mtx = mtxs[1]; + mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output + mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); + mtx.outputs[1].value.should.equal(60); + mtx.outputs[0].getType().should.equal('pubkeyhash'); + mtx.outputs[0].getAddress().toBase58().should.equal(alice); + mtx.outputs[0].value.should.equal(40); + }); + + it('throws when trying to decrease self-trust', () => { + should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.alice.pubkey, 10) + , /self-trust/i); + }); + + it('throws when there is not enough trust', () => { + should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 700) + , /insufficient trust/i); + + }); + }); + describe('.getTrust()', () => { it('returns zero for two arbitary parties that do not trust each other', () => { should(tir.getTrust(alice, bob)).equal(0); From bdee7b066e4ba6a61ff152f1c3968b2488117d43 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Sat, 27 May 2017 20:04:55 +0000 Subject: [PATCH 009/540] Implement trust stealing --- lib/trust_is_risk.js | 14 ++++++++------ src/trust_is_risk.js | 14 ++++++++------ test/trust_is_risk.js | 33 +++++++++++++++++++++++++++------ 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 278f64a..963c337 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -97,10 +97,11 @@ class TrustIsRisk { return mtx; } - getTrustDecreasingMTXs(from , to , trustDecreaseAmount ) + getTrustDecreasingMTXs(from , to , trustDecreaseAmount , payTo ) { - var fromAddress = Address.fromHash(bcoin.crypto.hash160(from)).toBase58(); - var toAddress = Address.fromHash(bcoin.crypto.hash160(to)).toBase58(); + var fromAddress = helpers.pubKeyToEntity(from); + var toAddress = helpers.pubKeyToEntity(to); + if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); var existingTrustAmount = this.trustDB.getDirectTrustAmount(fromAddress, toAddress); @@ -111,11 +112,12 @@ class TrustIsRisk { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.getTrustDecreasingMTX(directTrust, decrease); + return this.getTrustDecreasingMTX(directTrust, decrease, payTo); }).filter(Boolean); } - getTrustDecreasingMTX(directTrust , decreaseAmount ) { + getTrustDecreasingMTX(directTrust , decreaseAmount , payTo ) { + if (!payTo) payTo = directTrust.getFromEntity(); var remainingTrustAmount = directTrust.amount - decreaseAmount; var mtx = new MTX({ @@ -123,7 +125,7 @@ class TrustIsRisk { Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) ], outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(directTrust.from)), + script: bcoin.script.fromPubkeyhash(Address.fromBase58(payTo).hash), value: decreaseAmount })] }); diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 3f35e59..ac9b1fd 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -97,10 +97,11 @@ class TrustIsRisk { return mtx; } - getTrustDecreasingMTXs(from : PubKey, to : PubKey, trustDecreaseAmount : number) + getTrustDecreasingMTXs(from : PubKey, to : PubKey, trustDecreaseAmount : number, payTo : ?Entity) : bcoin$MTX[] { - var fromAddress = Address.fromHash(bcoin.crypto.hash160(from)).toBase58(); - var toAddress = Address.fromHash(bcoin.crypto.hash160(to)).toBase58(); + var fromAddress = helpers.pubKeyToEntity(from); + var toAddress = helpers.pubKeyToEntity(to); + if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); var existingTrustAmount = this.trustDB.getDirectTrustAmount(fromAddress, toAddress); @@ -111,11 +112,12 @@ class TrustIsRisk { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.getTrustDecreasingMTX(directTrust, decrease); + return this.getTrustDecreasingMTX(directTrust, decrease, payTo); }).filter(Boolean); } - getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number) { + getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payTo : ?Entity) { + if (!payTo) payTo = directTrust.getFromEntity(); var remainingTrustAmount = directTrust.amount - decreaseAmount; var mtx = new MTX({ @@ -123,7 +125,7 @@ class TrustIsRisk { Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) ], outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(directTrust.from)), + script: bcoin.script.fromPubkeyhash(Address.fromBase58(payTo).hash), value: decreaseAmount })] }); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index bb2b11a..48a199d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -189,9 +189,10 @@ describe('TrustIsRisk', () => { }); describe('.getTrustDecreasingMTX()', () => { - var trustTXs = []; + var trustTXs; beforeEach(() => { var tx; + trustTXs = []; tx = trustIncreasingTX; trustTXs.push(tx); @@ -210,10 +211,13 @@ describe('TrustIsRisk', () => { // Total trust 642 }); - it('creates correct trust decreasing transactions', () => { - // Should spend the entire first transaction and 40 from the second transaction - var mtxs = tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 82); + // Helper specific to the next couple of tests: + // Checks that mtxs is a list of two trust decreasing transactions. The first one spends the + // entire first trust increasing transaction, and the second spends part of the second. + // Also checks that the reduced trust is sent via P2PKH outputs to the correct recipient. + var checkMTXs = (mtxs, recipient) => { mtxs.length.should.equal(2); + var mtx = mtxs[0]; mtx.inputs.length.should.equal(1); @@ -224,16 +228,33 @@ describe('TrustIsRisk', () => { mtx.outputs.length.should.equal(1); // Single P2PKH output mtx.outputs[0].getType().should.equal('pubkeyhash'); - mtx.outputs[0].getAddress().toBase58().should.equal(alice); + mtx.outputs[0].getAddress().toBase58().should.equal(recipient); mtx.outputs[0].value.should.equal(42); mtx = mtxs[1]; + + mtx.inputs.length.should.equal(1); + mtx.inputs[0].prevout.should.have.properties({ + hash: trustTXs[1].hash().toString('hex'), + index: 0 + }); + mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); mtx.outputs[1].value.should.equal(60); mtx.outputs[0].getType().should.equal('pubkeyhash'); - mtx.outputs[0].getAddress().toBase58().should.equal(alice); + mtx.outputs[0].getAddress().toBase58().should.equal(recipient); mtx.outputs[0].value.should.equal(40); + }; + + it('creates correct trust decreasing transactions', () => { + var mtxs = tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 82); + checkMTXs(mtxs, alice); + }); + + it('creates correct trust stealing transactions', () => { + var mtxs = tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 82, charlie); + checkMTXs(mtxs, charlie); }); it('throws when trying to decrease self-trust', () => { From 885d11fe2b64f73595f3ac2485d362b27a1976ea Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 29 May 2017 16:01:02 +0000 Subject: [PATCH 010/540] Implement a complete end to end regtest test --- flow-typed/npm/bcoin_vx.x.x.js | 18 +++- lib/direct_trust.js | 10 +- lib/helpers.js | 4 +- lib/trust_db.js | 7 +- lib/trust_is_risk.js | 99 +++++++++++++------ lib/types.js | 2 +- package.json | 2 +- src/direct_trust.js | 10 +- src/helpers.js | 4 +- src/trust_db.js | 7 +- src/trust_is_risk.js | 99 +++++++++++++------ src/types.js | 2 +- test/full_node.js | 156 ++++++++++++++++++++++++++++-- test/graphs/nobodyLikesFrank.json | 2 +- test/helpers.js | 52 +++++----- test/trust_is_risk.js | 101 +++++++++---------- 16 files changed, 401 insertions(+), 174 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 74a3e2e..87c534d 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -6,11 +6,14 @@ type Network = any; declare class bcoin$FullNode { on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; + getCoin(hash : Hash, index : number) : bcoin$Coin; } declare class bcoin$Address { toBase58() : string; + hash : Buffer; static fromHash(Hash) : bcoin$Address; + static fromBase58(string) : bcoin$Address; } declare class bcoin$TX { @@ -29,9 +32,11 @@ declare class bcoin$MTX { template(ring : bcoin$KeyRing) : number; scriptVector(outputScript : bcoin$Script, inputScript : bcoin$Script, ring : bcoin$KeyRing) : boolean; addOutput(output : bcoin$Output) : void; + addCoin(coin : bcoin$Coin) : void; + sign(ring : bcoin$KeyRing) : number; + signInput(index : number, coin : bcoin$Coin, keyRing : bcoin$KeyRing) : boolean; } - declare class bcoin$Output { script : bcoin$Script; value : number; @@ -65,6 +70,14 @@ declare class bcoin$Outpoint { declare class bcoin$KeyRing { static fromPrivate(key : Buffer, compressed : ?boolean, network : ?Network) : bcoin$KeyRing; static fromPublic(key : Buffer, network : ?Network) : bcoin$KeyRing; + + getPublicKey() : Buffer; + getPrivateKey() : Buffer; +} + +declare class bcoin$Coin extends bcoin$Output { + script : bcoin$Script; + value : number; } declare module 'bcoin' { @@ -78,7 +91,8 @@ declare module 'bcoin' { Output : Class, Input : Class, Outpoint : Class, - KeyRing: Class + KeyRing : Class, + Coin : Class }, crypto : { hash160(str : (string | Buffer)) : Hash diff --git a/lib/direct_trust.js b/lib/direct_trust.js index 6545c0b..ad676f4 100644 --- a/lib/direct_trust.js +++ b/lib/direct_trust.js @@ -1,12 +1,12 @@ // - + var bcoin = require('bcoin'); var assert = require('assert'); var helpers = require('./helpers'); - - + + @@ -18,8 +18,8 @@ var helpers = require('./helpers'); class DirectTrust { - - + + // Every DT is associated with a transaction output, except for non-standard trust decreasing diff --git a/lib/helpers.js b/lib/helpers.js index f7c1443..27f228c 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -1,10 +1,10 @@ // - + var bcoin = require('bcoin'); var Address = bcoin.primitives.Address; var helpers = { - pubKeyToEntity: (key ) => { + pubKeyToEntity: (key ) => { return Address.fromHash(bcoin.crypto.hash160(key)).toBase58() } }; diff --git a/lib/trust_db.js b/lib/trust_db.js index ccd282b..a19a92d 100644 --- a/lib/trust_db.js +++ b/lib/trust_db.js @@ -1,5 +1,5 @@ // - + var assert = require('assert'); var SortedSet = require('sorted-set'); var maxFlow = require('graph-theory-ford-fulkerson'); @@ -87,6 +87,11 @@ class TrustDB { return this.txToDirectTrust.has(txHash); } + isTrustOutput(txHash , outputIndex ) { + var trust = this.txToDirectTrust.get(txHash); + return trust !== undefined && trust.outputIndex === outputIndex; + } + add(trust ) { var from = trust.getFromEntity(); var to = trust.getToEntity(); diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 963c337..f994941 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -1,5 +1,5 @@ // - + var bcoin = require('bcoin'); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -7,6 +7,7 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; +var Coin = bcoin.primitives.Coin; var assert = require('assert'); var helpers = require('./helpers'); var TrustDB = require('./trust_db'); @@ -14,21 +15,21 @@ var DirectTrust = require('./direct_trust'); class TrustIsRisk { - + constructor(node ) { this.node = node; - this.trustDB = new TrustDB(); + this.db = new TrustDB(); this.node.on('tx', this.addTX.bind(this)); } getTrust(from , to ) { - return this.trustDB.getTrustAmount(from, to); + return this.db.getTrustAmount(from, to); } getDirectTrust(from , to ) { - return this.trustDB.getDirectTrustAmount(from, to); + return this.db.getDirectTrustAmount(from, to); } // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network @@ -38,14 +39,14 @@ class TrustIsRisk { // Throws an error if the transaction was processed earlier. addTX(tx ) { var txHash = tx.hash().toString('hex'); - if (this.trustDB.isTrustTX(txHash)) { + if (this.db.isTrustTX(txHash)) { throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } var directTrusts = this.getDirectTrusts(tx); if (directTrusts.length === 0) return false; else { - directTrusts.map(this.trustDB.add.bind(this.trustDB)); + directTrusts.map(this.db.add.bind(this.db)); return true; } } @@ -63,18 +64,21 @@ class TrustIsRisk { } } - async getTrustIncreasingMTX(from , to , outpoint , trustAmount ) + // Returns a promise resolving to a mutable transaction object, which increases a trust + // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output + // payable to the sender. + // Any satoshis not spent will be returned to the sender, minus the fees, via P2PKH. + async getTrustIncreasingMTX(fromPrivate , to , outpoint , + trustAmount , fee ) { - var prevTX = await this.node.getTX(outpoint.hash); - if (!prevTX) throw new Error('Could not find transaction'); + if (!fee) fee = 1000; // TODO: estimate this + var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + if (!coin) throw new Error('Could not find coin'); - var prevOutput = prevTX.outputs[outpoint.index]; - if (!prevOutput) throw new Error('Could not find transaction output'); + var fromKeyRing = KeyRing.fromPrivate(fromPrivate); + var from = fromKeyRing.getPublicKey(); var mtx = new MTX({ - inputs: [ - Input.fromOutpoint(outpoint) - ], outputs: [ new Output({ script: bcoin.script.fromMultisig(1, 2, [from, to]), @@ -83,7 +87,7 @@ class TrustIsRisk { ] }); - var changeAmount = prevOutput.value - trustAmount; + var changeAmount = coin.value - trustAmount - fee; if (changeAmount) { mtx.addOutput(new Output({ script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), @@ -91,45 +95,71 @@ class TrustIsRisk { })); } - var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); + mtx.addCoin(coin); + var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, fromKeyRing); assert(success); + var signedCount = mtx.sign(fromKeyRing); + assert(signedCount === 1); + return mtx; } - getTrustDecreasingMTXs(from , to , trustDecreaseAmount , payTo ) - { - var fromAddress = helpers.pubKeyToEntity(from); - var toAddress = helpers.pubKeyToEntity(to); + // Returns an array of trust-decreasing mutable transaction objects, which reduce a trust + // relationship by the amount specified. The payee will receive the amount deducted minus the + // transaction fees via P2PKH. + // If steal is undefined or set to false, then the `from` key is expected to be a private key and + // the `to` key is expected to be a public key. If steal is set to true, then `from` is expected + // to be a public key and `to` is expected to be a private key. The private key will be used to + // sign the transaction. + getTrustDecreasingMTXs(from , to , trustDecreaseAmount , payee , + steal , fee ) { + if (steal === undefined) steal = false; + + var signingKeyRing, fromKeyRing, toKeyRing; + if (!steal) { + signingKeyRing = KeyRing.fromPrivate(from); + fromKeyRing = KeyRing.fromPrivate(from); + toKeyRing = KeyRing.fromPublic(to); + } else { + signingKeyRing = KeyRing.fromPrivate(to); + fromKeyRing = KeyRing.fromPublic(from); + toKeyRing = KeyRing.fromPrivate(to); + } + + var fromAddress = helpers.pubKeyToEntity(fromKeyRing.getPublicKey()); + var toAddress = helpers.pubKeyToEntity(toKeyRing.getPublicKey()); if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); - var existingTrustAmount = this.trustDB.getDirectTrustAmount(fromAddress, toAddress); + var existingTrustAmount = this.db.getDirectTrustAmount(fromAddress, toAddress); if (existingTrustAmount < trustDecreaseAmount) throw new Error('Insufficient trust'); - var directTrusts = this.trustDB.getSpendableDirectTrusts(fromAddress, toAddress); + var directTrusts = this.db.getSpendableDirectTrusts(fromAddress, toAddress); return directTrusts.map((directTrust) => { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.getTrustDecreasingMTX(directTrust, decrease, payTo); + return this.getTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, fee); }).filter(Boolean); } - getTrustDecreasingMTX(directTrust , decreaseAmount , payTo ) { - if (!payTo) payTo = directTrust.getFromEntity(); - var remainingTrustAmount = directTrust.amount - decreaseAmount; + getTrustDecreasingMTX(directTrust , decreaseAmount , payee , + signingKeyRing , fee ) { + if (!payee) payee = directTrust.getFromEntity(); + if (!fee) fee = 1000; // TODO: estimate this var mtx = new MTX({ inputs: [ Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) ], outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(Address.fromBase58(payTo).hash), - value: decreaseAmount + script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), + value: decreaseAmount - fee })] }); + var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ script: bcoin.script.fromMultisig(1, 2, [directTrust.from, directTrust.to]), @@ -141,13 +171,18 @@ class TrustIsRisk { mtx.inputs[0].script, KeyRing.fromPublic(directTrust.from)); assert(success); + success = mtx.signInput(0, new Coin({script: directTrust.script, value: directTrust.amount}), + signingKeyRing); + assert(success); + return mtx; } parseTXAsTrustIncrease(tx ) { if (tx.inputs.length !== 1) return null; - if (tx.inputs[0].getType() !== 'pubkeyhash') return null; // TODO: This is unreliable - if (this.trustDB.isTrustTX(tx.inputs[0].prevout.hash.toString('hex'))) return null; + var input = tx.inputs[0]; + if (input.getType() !== 'pubkeyhash') return null; // TODO: This is unreliable + if (this.db.isTrustOutput(input.prevout.hash.toString('hex'), input.prevout.index)) return null; var sender = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -168,7 +203,7 @@ class TrustIsRisk { getInputTrusts(inputs ) { return inputs.map((input) => { - var trust = this.trustDB.getDirectTrustByOutpoint(input.prevout); + var trust = this.db.getDirectTrustByOutpoint(input.prevout); if (trust && trust.outputIndex === input.prevout.index) return trust; else return null; }).filter(Boolean); diff --git a/lib/types.js b/lib/types.js index 44ee569..79f17ec 100644 --- a/lib/types.js +++ b/lib/types.js @@ -5,4 +5,4 @@ - + diff --git a/package.json b/package.json index e5bc1ef..6691347 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 5000", + "test": "npm run build && mocha -t 10000", "prepublish": "npm run build", "typecheck": "flow check" }, diff --git a/src/direct_trust.js b/src/direct_trust.js index fe3e687..153cc83 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -1,12 +1,12 @@ // @flow -import type {Entity, TXHash, PubKey} from "./types" +import type {Entity, TXHash, Key} from "./types" var bcoin = require('bcoin'); var assert = require('assert'); var helpers = require('./helpers'); type DirectTrustOptions = { - from : PubKey, - to : PubKey, + from : Key, + to : Key, amount : number, txHash : string, @@ -18,8 +18,8 @@ type DirectTrustOptions = { } class DirectTrust { - from : PubKey - to : PubKey + from : Key + to : Key amount : number // Every DT is associated with a transaction output, except for non-standard trust decreasing diff --git a/src/helpers.js b/src/helpers.js index fcf67bc..7723bff 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,10 +1,10 @@ // @flow -import type {Entity, TXHash, PubKey} from "./types" +import type {Entity, TXHash, Key} from "./types" var bcoin = require('bcoin'); var Address = bcoin.primitives.Address; var helpers = { - pubKeyToEntity: (key : PubKey) : Entity => { + pubKeyToEntity: (key : Key) : Entity => { return Address.fromHash(bcoin.crypto.hash160(key)).toBase58() } }; diff --git a/src/trust_db.js b/src/trust_db.js index bca781c..bf610e5 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -1,5 +1,5 @@ // @flow -import type {Entity, TXHash, PubKey} from "./types" +import type {Entity, TXHash, Key} from "./types" var assert = require('assert'); var SortedSet = require('sorted-set'); var maxFlow = require('graph-theory-ford-fulkerson'); @@ -87,6 +87,11 @@ class TrustDB { return this.txToDirectTrust.has(txHash); } + isTrustOutput(txHash : string, outputIndex : number) : boolean { + var trust = this.txToDirectTrust.get(txHash); + return trust !== undefined && trust.outputIndex === outputIndex; + } + add(trust : DirectTrust) { var from = trust.getFromEntity(); var to = trust.getToEntity(); diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index ac9b1fd..3ce0959 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,5 +1,5 @@ // @flow -import type {Entity, TXHash, PubKey} from "./types" +import type {Entity, TXHash, Key} from "./types" var bcoin = require('bcoin'); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -7,6 +7,7 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; +var Coin = bcoin.primitives.Coin; var assert = require('assert'); var helpers = require('./helpers'); var TrustDB = require('./trust_db'); @@ -14,21 +15,21 @@ var DirectTrust = require('./direct_trust'); class TrustIsRisk { node : bcoin$FullNode - trustDB : TrustDB + db : TrustDB constructor(node : bcoin$FullNode) { this.node = node; - this.trustDB = new TrustDB(); + this.db = new TrustDB(); this.node.on('tx', this.addTX.bind(this)); } getTrust(from : Entity, to : Entity) { - return this.trustDB.getTrustAmount(from, to); + return this.db.getTrustAmount(from, to); } getDirectTrust(from : Entity, to : Entity) { - return this.trustDB.getDirectTrustAmount(from, to); + return this.db.getDirectTrustAmount(from, to); } // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network @@ -38,14 +39,14 @@ class TrustIsRisk { // Throws an error if the transaction was processed earlier. addTX(tx : bcoin$TX) : boolean { var txHash = tx.hash().toString('hex'); - if (this.trustDB.isTrustTX(txHash)) { + if (this.db.isTrustTX(txHash)) { throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } var directTrusts = this.getDirectTrusts(tx); if (directTrusts.length === 0) return false; else { - directTrusts.map(this.trustDB.add.bind(this.trustDB)); + directTrusts.map(this.db.add.bind(this.db)); return true; } } @@ -63,18 +64,21 @@ class TrustIsRisk { } } - async getTrustIncreasingMTX(from : PubKey, to : PubKey, outpoint : bcoin$Outpoint, trustAmount : number) + // Returns a promise resolving to a mutable transaction object, which increases a trust + // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output + // payable to the sender. + // Any satoshis not spent will be returned to the sender, minus the fees, via P2PKH. + async getTrustIncreasingMTX(fromPrivate : Key, to : Key, outpoint : bcoin$Outpoint, + trustAmount : number, fee : ?number) : Promise { - var prevTX = await this.node.getTX(outpoint.hash); - if (!prevTX) throw new Error('Could not find transaction'); + if (!fee) fee = 1000; // TODO: estimate this + var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + if (!coin) throw new Error('Could not find coin'); - var prevOutput = prevTX.outputs[outpoint.index]; - if (!prevOutput) throw new Error('Could not find transaction output'); + var fromKeyRing = KeyRing.fromPrivate(fromPrivate); + var from = fromKeyRing.getPublicKey(); var mtx = new MTX({ - inputs: [ - Input.fromOutpoint(outpoint) - ], outputs: [ new Output({ script: bcoin.script.fromMultisig(1, 2, [from, to]), @@ -83,7 +87,7 @@ class TrustIsRisk { ] }); - var changeAmount = prevOutput.value - trustAmount; + var changeAmount = coin.value - trustAmount - fee; if (changeAmount) { mtx.addOutput(new Output({ script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), @@ -91,45 +95,71 @@ class TrustIsRisk { })); } - var success = mtx.scriptVector(prevOutput.script, mtx.inputs[0].script, KeyRing.fromPublic(from)); + mtx.addCoin(coin); + var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, fromKeyRing); assert(success); + var signedCount = mtx.sign(fromKeyRing); + assert(signedCount === 1); + return mtx; } - getTrustDecreasingMTXs(from : PubKey, to : PubKey, trustDecreaseAmount : number, payTo : ?Entity) - : bcoin$MTX[] { - var fromAddress = helpers.pubKeyToEntity(from); - var toAddress = helpers.pubKeyToEntity(to); + // Returns an array of trust-decreasing mutable transaction objects, which reduce a trust + // relationship by the amount specified. The payee will receive the amount deducted minus the + // transaction fees via P2PKH. + // If steal is undefined or set to false, then the `from` key is expected to be a private key and + // the `to` key is expected to be a public key. If steal is set to true, then `from` is expected + // to be a public key and `to` is expected to be a private key. The private key will be used to + // sign the transaction. + getTrustDecreasingMTXs(from : Key, to : Key, trustDecreaseAmount : number, payee : ?Entity, + steal : ?boolean, fee : ?number) : bcoin$MTX[] { + if (steal === undefined) steal = false; + + var signingKeyRing, fromKeyRing, toKeyRing; + if (!steal) { + signingKeyRing = KeyRing.fromPrivate(from); + fromKeyRing = KeyRing.fromPrivate(from); + toKeyRing = KeyRing.fromPublic(to); + } else { + signingKeyRing = KeyRing.fromPrivate(to); + fromKeyRing = KeyRing.fromPublic(from); + toKeyRing = KeyRing.fromPrivate(to); + } + + var fromAddress = helpers.pubKeyToEntity(fromKeyRing.getPublicKey()); + var toAddress = helpers.pubKeyToEntity(toKeyRing.getPublicKey()); if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); - var existingTrustAmount = this.trustDB.getDirectTrustAmount(fromAddress, toAddress); + var existingTrustAmount = this.db.getDirectTrustAmount(fromAddress, toAddress); if (existingTrustAmount < trustDecreaseAmount) throw new Error('Insufficient trust'); - var directTrusts = this.trustDB.getSpendableDirectTrusts(fromAddress, toAddress); + var directTrusts = this.db.getSpendableDirectTrusts(fromAddress, toAddress); return directTrusts.map((directTrust) => { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.getTrustDecreasingMTX(directTrust, decrease, payTo); + return this.getTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, fee); }).filter(Boolean); } - getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payTo : ?Entity) { - if (!payTo) payTo = directTrust.getFromEntity(); - var remainingTrustAmount = directTrust.amount - decreaseAmount; + getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, + signingKeyRing : bcoin$KeyRing, fee : ?number) { + if (!payee) payee = directTrust.getFromEntity(); + if (!fee) fee = 1000; // TODO: estimate this var mtx = new MTX({ inputs: [ Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) ], outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(Address.fromBase58(payTo).hash), - value: decreaseAmount + script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), + value: decreaseAmount - fee })] }); + var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ script: bcoin.script.fromMultisig(1, 2, [directTrust.from, directTrust.to]), @@ -141,13 +171,18 @@ class TrustIsRisk { mtx.inputs[0].script, KeyRing.fromPublic(directTrust.from)); assert(success); + success = mtx.signInput(0, new Coin({script: directTrust.script, value: directTrust.amount}), + signingKeyRing); + assert(success); + return mtx; } parseTXAsTrustIncrease(tx : bcoin$TX) : (DirectTrust | null) { if (tx.inputs.length !== 1) return null; - if (tx.inputs[0].getType() !== 'pubkeyhash') return null; // TODO: This is unreliable - if (this.trustDB.isTrustTX(tx.inputs[0].prevout.hash.toString('hex'))) return null; + var input = tx.inputs[0]; + if (input.getType() !== 'pubkeyhash') return null; // TODO: This is unreliable + if (this.db.isTrustOutput(input.prevout.hash.toString('hex'), input.prevout.index)) return null; var sender = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -168,7 +203,7 @@ class TrustIsRisk { getInputTrusts(inputs : bcoin$Input[]) : DirectTrust[] { return inputs.map((input) => { - var trust = this.trustDB.getDirectTrustByOutpoint(input.prevout); + var trust = this.db.getDirectTrustByOutpoint(input.prevout); if (trust && trust.outputIndex === input.prevout.index) return trust; else return null; }).filter(Boolean); diff --git a/src/types.js b/src/types.js index 1dc9d64..1bb788b 100644 --- a/src/types.js +++ b/src/types.js @@ -5,4 +5,4 @@ export type Entity = string; export type TXHash = string; -export type PubKey = Buffer; +export type Key = Buffer; diff --git a/test/full_node.js b/test/full_node.js index d6308a8..f8792c5 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -1,30 +1,36 @@ var Trust = require('../'); +var helpers = require('../lib/helpers.js'); var bcoin = require('bcoin'); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; var testHelpers = require('./helpers'); var consensus = require('bcoin/lib/protocol/consensus'); var sinon = require('sinon'); var should = require('should'); require('should-sinon'); +const COIN = consensus.COIN; + describe('FullNode', () => { var node = null; var walletDB = null; sinon.spy(Trust.TrustIsRisk.prototype, 'addTX'); - beforeEach(() => testHelpers.getNode().then((n) => { + beforeEach('get node', () => testHelpers.getNode().then((n) => { node = n; })); - beforeEach(() => testHelpers.getWalletDB(node).then((w) => { + beforeEach('get walletDB', () => testHelpers.getWalletDB(node).then((w) => { walletDB = w; })); - afterEach(() => walletDB.close()); - afterEach(() => node.close()); - - it('should be a bcoin instance', () => { - should(node).be.an.instanceof(bcoin.fullnode); - }); + afterEach('close walletDB', async () => walletDB.close()); + afterEach('close node', async () => node.close()); it('should call trust.addTX() on every transaction', async function() { var sender = await testHelpers.getWallet(walletDB, 'sender'); @@ -39,7 +45,7 @@ describe('FullNode', () => { await testHelpers.time(100); await sender.send({ outputs: [{ - value: 10 * consensus.COIN, + value: 10 * COIN, address: receiver.getAddress('base58') }] }); @@ -47,4 +53,136 @@ describe('FullNode', () => { await testHelpers.time(100); node.trust.addTX.should.be.calledOnce(); }); + + describe('with the nobodyLikesFrank.json example', () => { + var addresses, rings = {}; + + beforeEach('apply graph transactions', async () => { + addresses = {}; + rings = {}; + + for (var i = 0; i < testHelpers.names.length; i++) { + var name = testHelpers.names[i]; + rings[name] = testHelpers.rings[i]; + addresses[name] = helpers.pubKeyToEntity(rings[name].getPublicKey()); + } + + // Alice mines three blocks, each rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var coinbaseCoinsCount = 3; + var coinbaseHashes = []; + for(var i = 0; i < coinbaseCoinsCount; i++) { + var block = await testHelpers.mineBlock(node, addresses.alice); + coinbaseHashes.push(block.txs[0].hash()); + await testHelpers.time(200); + } + + // Alice sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + var outputs = testHelpers.names.map((name) => { + return new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160(rings[name].getPublicKey())), + value: sendAmount * consensus.COIN + }); + }); + + // We have to use a change output, because transaction with too large a fee are considered + // invalid. + var fee = 0.01; + var changeAmount = 50 * coinbaseCoinsCount - sendAmount * testHelpers.names.length - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160(rings.alice.getPublicKey())), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { + return node.getCoin(hash.toString('hex'), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(rings.alice); + signedCount.should.equal(coinbaseCoinsCount); + should(await mtx.verify()); + + var tx = mtx.toTX(); + node.sendTX(tx); + prevout = {}; + testHelpers.names.forEach((name) => { + prevout[name] = { + hash: tx.hash().toString('hex'), + index: testHelpers.names.indexOf(name) + }; + }); + await testHelpers.time(500); + + // Alice mines another block + await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); + await testHelpers.time(500); + + var graph = require('./graphs/nobodyLikesFrank.json'); + var promises = []; + for (var from in graph) { + var neighbours = graph[from]; + for (var to in neighbours) { + var value = neighbours[to]; + if (!value || value < 1) continue; + + var outpoint = new Outpoint(prevout[from].hash, prevout[from].index); + + var mtx = await node.trust.getTrustIncreasingMTX(rings[from].getPrivateKey(), + rings[to].getPublicKey(), outpoint, value * consensus.COIN); + + should(await mtx.verify()); + + // The change output from this transaction will be used in other transactions from the + // same origin. We therefore need to sleep until the transaction is added to the pool. + var tx = mtx.toTX(); + node.sendTX(tx); + await testHelpers.time(250); + + prevout[from] = {hash: tx.hash().toString('hex'), index: 1}; + } + } + //mtxs.forEach((mtx) => node.sendTX(mtx.toTX())); + await testHelpers.time(500); + + // Alice mines yet another block + await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); + await testHelpers.time(500); + }); + + it('computes trusts correctly', () => { + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + should(node.trust.getTrust(alice, alice)).equal(Infinity); + should(node.trust.getTrust(alice, bob)).equal(10 * COIN); + should(node.trust.getTrust(alice, charlie)).equal(1 * COIN); + should(node.trust.getTrust(alice, frank)).equal(0); + should(node.trust.getTrust(alice, eve)).equal(6 * COIN); + + should(node.trust.getTrust(bob, alice)).equal(1 * COIN); + should(node.trust.getTrust(bob, eve)).equal(3 * COIN); + should(node.trust.getTrust(dave, eve)).equal(12 * COIN); + should(node.trust.getTrust(george, eve)).equal(0); + }); + + it('after decreasing some trusts computes trusts correctly', async () => { + var mtxs = node.trust.getTrustDecreasingMTXs(rings.alice.getPrivateKey(), + rings.bob.getPublicKey(), 3 * COIN); + mtxs.length.should.equal(1); + var mtx = mtxs[0]; + + should(await mtx.verify()); + node.sendTX(mtx.toTX()); + + await testHelpers.time(500); + should(node.trust.getTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + }); + }); }); diff --git a/test/graphs/nobodyLikesFrank.json b/test/graphs/nobodyLikesFrank.json index 09865cc..9c246bc 100644 --- a/test/graphs/nobodyLikesFrank.json +++ b/test/graphs/nobodyLikesFrank.json @@ -18,7 +18,7 @@ }, "eve": {}, "frank": { - "charlie": 100 + "charlie": 10 }, "george": {} } diff --git a/test/helpers.js b/test/helpers.js index 40df046..b16a0da 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,28 +1,34 @@ var TrustIsRisk = require('../'); var WalletDB = require('bcoin/lib/wallet/walletdb'); var bcoin = require('bcoin'); +var KeyRing = bcoin.primitives.KeyRing; var assert = require('assert'); var testHelpers = { + names: ['alice', 'bob', 'charlie', 'dave', 'eve', 'frank', 'george'], + rings: [ + '02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c0', + '2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ad', + '3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD7', + '19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F3', + '0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A', + '878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D45', + '1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A' + ].map((key) => KeyRing.fromPrivate(new Buffer(key, 'hex'))), + getAddressFixtures: () => { - var names = ['alice', 'bob', 'charlie', 'dave', 'eve', 'frank', 'george']; - var pubkeys = [ - '02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083', - '2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ada53054a3654e669b', - '3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD782', - '19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F351', - '0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A84', - '878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D4516', - '1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A93' - ]; - assert(pubkeys.length === names.length); + assert(testHelpers.rings.length === testHelpers.names.length); var addr = {}; - for (var i = 0; i < names.length; i++) { - var name = names[i]; + for (var i = 0; i < testHelpers.names.length; i++) { + var name = testHelpers.names[i]; + var pubKey = testHelpers.rings[i].getPublicKey(); + var privKey = testHelpers.rings[i].getPrivateKey(); + addr[name] = {}; - addr[name].pubkey = Buffer.from(pubkeys[i], 'hex'); - addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(addr[name].pubkey)).toString(); + addr[name].pubKey = pubKey; + addr[name].privKey = privKey; + addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(pubKey)).toString(); } return addr; @@ -65,6 +71,7 @@ var testHelpers = { mineBlock: async (node, rewardAddress) => { var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); await node.chain.add(block); + return node.getBlock(node.chain.tip.hash); }, time: async (milliseconds) => { @@ -79,8 +86,7 @@ var testHelpers = { getP2PKHOutput: (to, value) => { var address = bcoin.primitives.Address.fromBase58(to); - var script = bcoin.script.fromString( - `OP_DUP OP_HASH160 ${testHelpers.bufferToScript(address.hash)} OP_EQUALVERIFY OP_CHECKSIG`); + var script = bcoin.script.fromPubkeyhash(address.hash); return new bcoin.primitives.Output({script, value}); }, @@ -104,12 +110,8 @@ var testHelpers = { getOneOfTwoMultisigOutput: (pubKeyFrom, pubKeyTo, value) => { return new bcoin.primitives.Output({ - value, - script: bcoin.script.fromString( - "OP_1 " - + testHelpers.bufferToScript(pubKeyFrom) + " " - + testHelpers.bufferToScript(pubKeyTo) + " " - + "OP_2 OP_CHECKMULTISIG") + script: bcoin.script.fromMultisig(1, 2, [pubKeyFrom, pubKeyTo]), + value }); }, @@ -131,12 +133,10 @@ var testHelpers = { var neighbours = graph[from]; for (var to in neighbours) { var value = neighbours[to]; - tir.addTX(testHelpers.getTrustIncreasingMTX(addr[from].pubkey, addr[to].pubkey, value).toTX()); + tir.addTX(testHelpers.getTrustIncreasingMTX(addr[from].pubKey, addr[to].pubKey, value).toTX()); } } } }; - - module.exports = testHelpers; diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 48a199d..ddb3d36 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -1,12 +1,17 @@ var Trust = require('../'); +var helpers = require('../lib/helpers.js'); var bcoin = require('bcoin'); +var Coin = bcoin.primitives.Coin; +var Address = bcoin.primitives.Address; +var Input = bcoin.primitives.Input; +var MTX = bcoin.primitives.MTX; var testHelpers = require('./helpers'); var consensus = require('bcoin/lib/protocol/consensus'); var sinon = require('sinon'); var should = require('should'); require('should-sinon'); -var Address = bcoin.primitives.Address; +const COIN = bcoin.consensus.COIN; describe('TrustIsRisk', () => { var addr = testHelpers.getAddressFixtures(); @@ -20,10 +25,10 @@ describe('TrustIsRisk', () => { node = new bcoin.fullnode({}); tir = new Trust.TrustIsRisk(node); - trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubkey, addr.bob.pubkey, 42); + trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); trustIncreasingTX = trustIncreasingMTX.toTX(); - var inputOneOfTwoMultisig = new bcoin.primitives.Input({ + var inputOneOfTwoMultisig = new Input({ prevout: { hash: trustIncreasingTX.hash().toString('hex'), index: 0 @@ -33,13 +38,13 @@ describe('TrustIsRisk', () => { "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") }); - trustDecreasingMTX = new bcoin.primitives.MTX({ + trustDecreasingMTX = new MTX({ inputs: [ inputOneOfTwoMultisig ], outputs: [ - testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubkey, addr.bob.pubkey, 20), - testHelpers.getP2PKHOutput(addr.alice.base58, 22) + testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), + testHelpers.getP2PKHOutput(addr.alice.base58, 22 * COIN) ] }); }); @@ -62,7 +67,7 @@ describe('TrustIsRisk', () => { describe('.addTX()', () => { describe('with a non-TIR transaction', () => { it('does not change trust', () => { - trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50); + trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); tir.parseTXAsTrustIncrease(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -73,7 +78,7 @@ describe('TrustIsRisk', () => { it('correctly increases trust', () => { tir.addTX(trustIncreasingTX); - should(tir.getDirectTrust(alice, bob)).equal(42); + should(tir.getDirectTrust(alice, bob)).equal(42 * COIN); should(tir.getDirectTrust(bob, alice)).equal(0); }); @@ -85,17 +90,17 @@ describe('TrustIsRisk', () => { }); it('which has a change output correctly increases trust', () => { - trustIncreasingMTX.outputs[0].value -= 10; - trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 10)); + trustIncreasingMTX.outputs[0].value -= 10 * COIN; + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 10 * COIN)); tir.addTX(trustIncreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(32); + should(tir.getDirectTrust(alice, bob)).equal(32 * COIN); }); it('which has two change outputs does not change trust', () => { trustIncreasingMTX.outputs[0].value -= 10; for (var i = 0; i < 2; i++) { - trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 5)); + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 5 * COIN)); } tir.addTX(trustIncreasingMTX.toTX()); @@ -103,8 +108,8 @@ describe('TrustIsRisk', () => { }); it('which has a second output that is not a change output does not change trust', () => { - trustIncreasingMTX.outputs[0].value -= 10; - trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(charlie, 5)); + trustIncreasingMTX.outputs[0].value -= 10 * COIN; + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(charlie, 5 * COIN)); tir.addTX(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -112,7 +117,7 @@ describe('TrustIsRisk', () => { it('which has been processed before throws', () => { var tx = trustIncreasingMTX.toTX(); - tir.addTX(tx); + should(tir.addTX(tx)); should.throws(() => tir.addTX(tx), /already processed/i); }); }); @@ -124,20 +129,20 @@ describe('TrustIsRisk', () => { it('correctly decreases trust', () => { tir.addTX(trustDecreasingMTX.toTX()); - should(tir.getDirectTrust(alice, bob)).equal(20); + should(tir.getDirectTrust(alice, bob)).equal(20 * COIN); }); it('which has a second input decreases trust to zero', () => { - trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubkey)); + trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubKey)); tir.addTX(trustDecreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); }); it('which has more than one trust outputs decreases trust to zero', () => { - trustDecreasingMTX.outputs[0].value -= 15; + trustDecreasingMTX.outputs[0].value -= 15 * COIN; trustDecreasingMTX.outputs.push( - testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubkey, addr.bob.pubkey, 5)); + testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 5 * COIN)); tir.addTX(trustDecreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); @@ -146,45 +151,35 @@ describe('TrustIsRisk', () => { describe('.getTrustIncreasingMTX()', () => { it('creates valid trust-increasing transactions', async () => { - var getTXStub = sinon.stub(node, 'getTX'); + var getTXStub = sinon.stub(node, 'getCoin'); var prevOutput = { hash: 'v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', index: 1 }; - getTXStub.withArgs(prevOutput.hash).returns(new bcoin.primitives.MTX({ - inputs: [ - testHelpers.getP2PKHInput(addr.alice.pubkey) - ], - outputs: [ - testHelpers.getOneOfTwoMultisigOutput(addr.charlie.pubkey, addr.bob.pubkey, 40), - testHelpers.getP2PKHOutput(alice, 1000), // This is the P2PKH being used - testHelpers.getP2PKHOutput(dave, 200) - ] - }).toTX()); + getTXStub.withArgs(prevOutput.hash).returns(new Coin({ + script: testHelpers.getP2PKHOutput(alice, 1).script, + value: 1000 * COIN + })); - var mtx = await tir.getTrustIncreasingMTX(addr.alice.pubkey, addr.bob.pubkey, prevOutput, 100); + var mtx = await tir.getTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, + 100 * COIN); mtx.inputs.length.should.equal(1); - var input = mtx.inputs[0]; - input.script.get(0).should.equal(0); // OP_0, because this is an unsigned bcoin input template. - input.script.get(1).should.equal(addr.alice.pubkey); mtx.outputs.length.should.equal(2); var trustOutput = mtx.outputs[0]; trustOutput.getType().should.equal('multisig'); - var addressA = Address.fromHash(bcoin.crypto.hash160(trustOutput.script.get(1))).toBase58(); - var addressB = Address.fromHash(bcoin.crypto.hash160(trustOutput.script.get(2))).toBase58(); - addressA.should.equal(alice); - addressB.should.equal(bob); - trustOutput.value.should.equal(100); + [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() + .should.deepEqual([alice, bob].sort()); + trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; changeOutput.getType().should.equal('pubkeyhash'); changeOutput.getAddress().toBase58().should.equal(alice); - changeOutput.value.should.equal(900); + changeOutput.value.should.equal(900 * COIN - 1000); }); }); @@ -198,17 +193,17 @@ describe('TrustIsRisk', () => { trustTXs.push(tx); tir.addTX(tx); - trustIncreasingMTX.outputs[0].value = 100; + trustIncreasingMTX.outputs[0].value = 100 * COIN; tx = trustIncreasingMTX.toTX(); trustTXs.push(tx); tir.addTX(tx); - trustIncreasingMTX.outputs[0].value = 500; + trustIncreasingMTX.outputs[0].value = 500 * COIN; tx = trustIncreasingMTX.toTX(); trustTXs.push(tx); tir.addTX(tx); - // Total trust 642 + // Total trust 642 BTC }); // Helper specific to the next couple of tests: @@ -229,7 +224,7 @@ describe('TrustIsRisk', () => { mtx.outputs.length.should.equal(1); // Single P2PKH output mtx.outputs[0].getType().should.equal('pubkeyhash'); mtx.outputs[0].getAddress().toBase58().should.equal(recipient); - mtx.outputs[0].value.should.equal(42); + mtx.outputs[0].value.should.equal(42 * COIN - 1000); mtx = mtxs[1]; @@ -241,29 +236,29 @@ describe('TrustIsRisk', () => { mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); - mtx.outputs[1].value.should.equal(60); + mtx.outputs[1].value.should.equal(60 * COIN); mtx.outputs[0].getType().should.equal('pubkeyhash'); mtx.outputs[0].getAddress().toBase58().should.equal(recipient); - mtx.outputs[0].value.should.equal(40); + mtx.outputs[0].value.should.equal(40 * COIN - 1000); }; it('creates correct trust decreasing transactions', () => { - var mtxs = tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 82); + var mtxs = tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); checkMTXs(mtxs, alice); }); it('creates correct trust stealing transactions', () => { - var mtxs = tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 82, charlie); + var mtxs = tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); checkMTXs(mtxs, charlie); }); it('throws when trying to decrease self-trust', () => { - should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.alice.pubkey, 10) + should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) , /self-trust/i); }); it('throws when there is not enough trust', () => { - should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.pubkey, addr.bob.pubkey, 700) + should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) , /insufficient trust/i); }); @@ -330,7 +325,7 @@ describe('TrustIsRisk', () => { should(tir.getTrust(frank, alice)).equal(0); should(tir.getTrust(frank, bob)).equal(0); - should(tir.getTrust(frank, charlie)).equal(100); + should(tir.getTrust(frank, charlie)).equal(10); should(tir.getTrust(frank, dave)).equal(0); should(tir.getTrust(frank, eve)).equal(0); should(tir.getTrust(frank, frank)).equal(Infinity); @@ -346,13 +341,13 @@ describe('TrustIsRisk', () => { }); it('correctly computes trusts when bob trusts frank', () => { - tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubkey, addr.frank.pubkey, 8).toTX()); + tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); should(tir.getTrust(george, frank)).equal(0); should(tir.getTrust(alice, frank)).equal(8); should(tir.getTrust(dave, frank)).equal(2); should(tir.getTrust(bob, frank)).equal(8); }); - + // TODO: Decrement direct trusts and test that indirect trusts update correctly }); }); From eeff57abb107cd34bddc3ff6dbeded06df58856d Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 29 May 2017 16:49:00 +0000 Subject: [PATCH 011/540] Use ESLint, fix style issues --- .eslintrc.json | 40 +++++++++++++ flow-typed/npm/bcoin_vx.x.x.js | 1 + lib/direct_trust.js | 10 ++-- lib/full_node.js | 4 +- lib/helpers.js | 10 ++-- lib/index.js | 6 +- lib/trust_db.js | 20 +++---- lib/trust_is_risk.js | 44 +++++++------- package.json | 7 ++- src/direct_trust.js | 10 ++-- src/full_node.js | 4 +- src/helpers.js | 10 ++-- src/index.js | 6 +- src/trust_db.js | 20 +++---- src/trust_is_risk.js | 44 +++++++------- test/full_node.js | 102 ++++++++++++++++---------------- test/helpers.js | 40 ++++++------- test/trust_is_risk.js | 104 ++++++++++++++++----------------- 18 files changed, 264 insertions(+), 218 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..2597f3d --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "parser": "babel-eslint", + "plugins": [ + "eslint-plugin-flowtype" + ], + "env": { + "es6": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:flowtype/recommended" + ], + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ], + "flowtype/space-before-type-colon": 0, + "no-undef": 0, + "no-unused-vars": 0 + }, + "settings": { + "flowtype": { + "onlyFilesWithFlowAnnotation": true + } + } +} diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 87c534d..c6663cc 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -100,3 +100,4 @@ declare module 'bcoin' { } } + diff --git a/lib/direct_trust.js b/lib/direct_trust.js index ad676f4..d1da9c8 100644 --- a/lib/direct_trust.js +++ b/lib/direct_trust.js @@ -1,8 +1,8 @@ // - -var bcoin = require('bcoin'); -var assert = require('assert'); -var helpers = require('./helpers'); + + +var assert = require("assert"); +var helpers = require("./helpers"); @@ -14,7 +14,7 @@ var helpers = require('./helpers'); - + class DirectTrust { diff --git a/lib/full_node.js b/lib/full_node.js index 79b1948..3525254 100644 --- a/lib/full_node.js +++ b/lib/full_node.js @@ -1,6 +1,6 @@ // -var bcoin = require('bcoin'); -var TrustIsRisk = require('./trust_is_risk'); +var bcoin = require("bcoin"); +var TrustIsRisk = require("./trust_is_risk"); class FullNode extends bcoin.fullnode { diff --git a/lib/helpers.js b/lib/helpers.js index 27f228c..a345715 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -1,12 +1,12 @@ // - -var bcoin = require('bcoin'); + +var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var helpers = { - pubKeyToEntity: (key ) => { - return Address.fromHash(bcoin.crypto.hash160(key)).toBase58() - } + pubKeyToEntity: (key ) => { + return Address.fromHash(bcoin.crypto.hash160(key)).toBase58(); + } }; module.exports = helpers; diff --git a/lib/index.js b/lib/index.js index 01c118a..824eb06 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,5 @@ // module.exports = { - FullNode: require('./full_node'), - TrustIsRisk: require('./trust_is_risk') -} + FullNode: require("./full_node"), + TrustIsRisk: require("./trust_is_risk") +}; diff --git a/lib/trust_db.js b/lib/trust_db.js index a19a92d..fecf695 100644 --- a/lib/trust_db.js +++ b/lib/trust_db.js @@ -1,16 +1,16 @@ // - -var assert = require('assert'); -var SortedSet = require('sorted-set'); -var maxFlow = require('graph-theory-ford-fulkerson'); -var bcoin = require('bcoin'); + +var assert = require("assert"); +var SortedSet = require("sorted-set"); +var maxFlow = require("graph-theory-ford-fulkerson"); +var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var DirectTrust = require('./direct_trust'); +var DirectTrust = require("./direct_trust"); class TrustDB { @@ -29,7 +29,7 @@ class TrustDB { } getDirectTrustByOutpoint(outpoint ) { - var trust = this.txToDirectTrust.get(outpoint.hash.toString('hex')); + var trust = this.txToDirectTrust.get(outpoint.hash.toString("hex")); if (!trust) return null; if (trust.outputIndex !== outpoint.index) return null; return trust; @@ -87,9 +87,9 @@ class TrustDB { return this.txToDirectTrust.has(txHash); } - isTrustOutput(txHash , outputIndex ) { - var trust = this.txToDirectTrust.get(txHash); - return trust !== undefined && trust.outputIndex === outputIndex; + isTrustOutput(txHash , outputIndex ) { + var trust = this.txToDirectTrust.get(txHash); + return trust !== undefined && trust.outputIndex === outputIndex; } add(trust ) { diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index f994941..7e0b8cb 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -1,6 +1,6 @@ // - -var bcoin = require('bcoin'); + +var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; @@ -8,10 +8,10 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var Coin = bcoin.primitives.Coin; -var assert = require('assert'); -var helpers = require('./helpers'); -var TrustDB = require('./trust_db'); -var DirectTrust = require('./direct_trust'); +var assert = require("assert"); +var helpers = require("./helpers"); +var TrustDB = require("./trust_db"); +var DirectTrust = require("./direct_trust"); class TrustIsRisk { @@ -21,7 +21,7 @@ class TrustIsRisk { this.node = node; this.db = new TrustDB(); - this.node.on('tx', this.addTX.bind(this)); + this.node.on("tx", this.addTX.bind(this)); } getTrust(from , to ) { @@ -38,7 +38,7 @@ class TrustIsRisk { // network, false otherwise. // Throws an error if the transaction was processed earlier. addTX(tx ) { - var txHash = tx.hash().toString('hex'); + var txHash = tx.hash().toString("hex"); if (this.db.isTrustTX(txHash)) { throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } @@ -71,9 +71,9 @@ class TrustIsRisk { async getTrustIncreasingMTX(fromPrivate , to , outpoint , trustAmount , fee ) { - if (!fee) fee = 1000; // TODO: estimate this + if (!fee) fee = 1000; // TODO: estimate this var coin = await this.node.getCoin(outpoint.hash, outpoint.index); - if (!coin) throw new Error('Could not find coin'); + if (!coin) throw new Error("Could not find coin"); var fromKeyRing = KeyRing.fromPrivate(fromPrivate); var from = fromKeyRing.getPublicKey(); @@ -95,7 +95,7 @@ class TrustIsRisk { })); } - mtx.addCoin(coin); + mtx.addCoin(coin); var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, fromKeyRing); assert(success); @@ -130,10 +130,10 @@ class TrustIsRisk { var fromAddress = helpers.pubKeyToEntity(fromKeyRing.getPublicKey()); var toAddress = helpers.pubKeyToEntity(toKeyRing.getPublicKey()); - if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); + if (fromAddress === toAddress) throw new Error("Can't decrease self-trust"); var existingTrustAmount = this.db.getDirectTrustAmount(fromAddress, toAddress); - if (existingTrustAmount < trustDecreaseAmount) throw new Error('Insufficient trust'); + if (existingTrustAmount < trustDecreaseAmount) throw new Error("Insufficient trust"); var directTrusts = this.db.getSpendableDirectTrusts(fromAddress, toAddress); return directTrusts.map((directTrust) => { @@ -147,7 +147,7 @@ class TrustIsRisk { getTrustDecreasingMTX(directTrust , decreaseAmount , payee , signingKeyRing , fee ) { if (!payee) payee = directTrust.getFromEntity(); - if (!fee) fee = 1000; // TODO: estimate this + if (!fee) fee = 1000; // TODO: estimate this var mtx = new MTX({ inputs: [ @@ -180,9 +180,9 @@ class TrustIsRisk { parseTXAsTrustIncrease(tx ) { if (tx.inputs.length !== 1) return null; - var input = tx.inputs[0]; - if (input.getType() !== 'pubkeyhash') return null; // TODO: This is unreliable - if (this.db.isTrustOutput(input.prevout.hash.toString('hex'), input.prevout.index)) return null; + var input = tx.inputs[0]; + if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable + if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; var sender = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -190,7 +190,7 @@ class TrustIsRisk { var trustOutputs = this.searchForDirectTrustOutputs(tx, sender); if (trustOutputs.length !== 1) return null; - var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length + var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length; if (changeOutputCount + 1 !== tx.outputs.length) return null; return trustOutputs[0]; @@ -210,7 +210,7 @@ class TrustIsRisk { } getTrustDecrease(tx , prevTrust ) { - var txHash = tx.hash().toString('hex'); + var txHash = tx.hash().toString("hex"); var nullTrust = prevTrust.getNullifying(txHash); if (tx.inputs.length !== 1) return nullTrust; @@ -243,15 +243,15 @@ class TrustIsRisk { } isChangeOutput(output , sender ) { - return (output.getType() === 'pubkeyhash') + return (output.getType() === "pubkeyhash") && (output.getAddress().toBase58() === sender); } parseOutputAsDirectTrust(tx , outputIndex , sender ) { - var txHash = tx.hash().toString('hex'); + var txHash = tx.hash().toString("hex"); var output = tx.outputs[outputIndex]; - if (output.getType() !== 'multisig') return null; + if (output.getType() !== "multisig") return null; var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); if (entities[0] === entities[1]) return null; diff --git a/package.json b/package.json index 6691347..c08a511 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "build": "flow-remove-types -d lib/ src/", "test": "npm run build && mocha -t 10000", "prepublish": "npm run build", - "typecheck": "flow check" + "typecheck": "flow check", + "lint": "./node_modules/.bin/eslint --fix src/ test/", + "check": "npm run lint && npm run typecheck && npm run test" }, "repository": { "type": "git", @@ -25,6 +27,9 @@ }, "homepage": "https://github.com/decrypto-org/TrustIsRisk.js#readme", "devDependencies": { + "babel-eslint": "^7.2.3", + "eslint": "^3.19.0", + "eslint-plugin-flowtype": "^2.33.0", "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.0", "mocha": "^3.4.2", diff --git a/src/direct_trust.js b/src/direct_trust.js index 153cc83..70662ed 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -1,8 +1,8 @@ // @flow -import type {Entity, TXHash, Key} from "./types" -var bcoin = require('bcoin'); -var assert = require('assert'); -var helpers = require('./helpers'); +import type {Entity, Key} from "./types"; +import type {script} from "bcoin"; +var assert = require("assert"); +var helpers = require("./helpers"); type DirectTrustOptions = { from : Key, @@ -14,7 +14,7 @@ type DirectTrustOptions = { script? : bcoin$Script, prev? : DirectTrust, - next? :DirectTrust + next? : DirectTrust } class DirectTrust { diff --git a/src/full_node.js b/src/full_node.js index f6b31f8..93e664d 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -1,6 +1,6 @@ // @flow -var bcoin = require('bcoin'); -var TrustIsRisk = require('./trust_is_risk'); +var bcoin = require("bcoin"); +var TrustIsRisk = require("./trust_is_risk"); class FullNode extends bcoin.fullnode { trust : TrustIsRisk diff --git a/src/helpers.js b/src/helpers.js index 7723bff..6416a31 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,12 +1,12 @@ // @flow -import type {Entity, TXHash, Key} from "./types" -var bcoin = require('bcoin'); +import type {Entity, TXHash, Key} from "./types"; +var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var helpers = { - pubKeyToEntity: (key : Key) : Entity => { - return Address.fromHash(bcoin.crypto.hash160(key)).toBase58() - } + pubKeyToEntity: (key : Key) : Entity => { + return Address.fromHash(bcoin.crypto.hash160(key)).toBase58(); + } }; module.exports = helpers; diff --git a/src/index.js b/src/index.js index f21fb90..66a1290 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ // @flow module.exports = { - FullNode: require('./full_node'), - TrustIsRisk: require('./trust_is_risk') -} + FullNode: require("./full_node"), + TrustIsRisk: require("./trust_is_risk") +}; diff --git a/src/trust_db.js b/src/trust_db.js index bf610e5..449f50a 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -1,16 +1,16 @@ // @flow -import type {Entity, TXHash, Key} from "./types" -var assert = require('assert'); -var SortedSet = require('sorted-set'); -var maxFlow = require('graph-theory-ford-fulkerson'); -var bcoin = require('bcoin'); +import type {Entity, TXHash, Key} from "./types"; +var assert = require("assert"); +var SortedSet = require("sorted-set"); +var maxFlow = require("graph-theory-ford-fulkerson"); +var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var DirectTrust = require('./direct_trust'); +var DirectTrust = require("./direct_trust"); class TrustDB { directTrusts : Map>> @@ -29,7 +29,7 @@ class TrustDB { } getDirectTrustByOutpoint(outpoint : bcoin$Outpoint) : (DirectTrust | null) { - var trust = this.txToDirectTrust.get(outpoint.hash.toString('hex')); + var trust = this.txToDirectTrust.get(outpoint.hash.toString("hex")); if (!trust) return null; if (trust.outputIndex !== outpoint.index) return null; return trust; @@ -87,9 +87,9 @@ class TrustDB { return this.txToDirectTrust.has(txHash); } - isTrustOutput(txHash : string, outputIndex : number) : boolean { - var trust = this.txToDirectTrust.get(txHash); - return trust !== undefined && trust.outputIndex === outputIndex; + isTrustOutput(txHash : string, outputIndex : number) : boolean { + var trust = this.txToDirectTrust.get(txHash); + return trust !== undefined && trust.outputIndex === outputIndex; } add(trust : DirectTrust) { diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 3ce0959..db3ec16 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,6 +1,6 @@ // @flow -import type {Entity, TXHash, Key} from "./types" -var bcoin = require('bcoin'); +import type {Entity, TXHash, Key} from "./types"; +var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; @@ -8,10 +8,10 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var Coin = bcoin.primitives.Coin; -var assert = require('assert'); -var helpers = require('./helpers'); -var TrustDB = require('./trust_db'); -var DirectTrust = require('./direct_trust'); +var assert = require("assert"); +var helpers = require("./helpers"); +var TrustDB = require("./trust_db"); +var DirectTrust = require("./direct_trust"); class TrustIsRisk { node : bcoin$FullNode @@ -21,7 +21,7 @@ class TrustIsRisk { this.node = node; this.db = new TrustDB(); - this.node.on('tx', this.addTX.bind(this)); + this.node.on("tx", this.addTX.bind(this)); } getTrust(from : Entity, to : Entity) { @@ -38,7 +38,7 @@ class TrustIsRisk { // network, false otherwise. // Throws an error if the transaction was processed earlier. addTX(tx : bcoin$TX) : boolean { - var txHash = tx.hash().toString('hex'); + var txHash = tx.hash().toString("hex"); if (this.db.isTrustTX(txHash)) { throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } @@ -71,9 +71,9 @@ class TrustIsRisk { async getTrustIncreasingMTX(fromPrivate : Key, to : Key, outpoint : bcoin$Outpoint, trustAmount : number, fee : ?number) : Promise { - if (!fee) fee = 1000; // TODO: estimate this + if (!fee) fee = 1000; // TODO: estimate this var coin = await this.node.getCoin(outpoint.hash, outpoint.index); - if (!coin) throw new Error('Could not find coin'); + if (!coin) throw new Error("Could not find coin"); var fromKeyRing = KeyRing.fromPrivate(fromPrivate); var from = fromKeyRing.getPublicKey(); @@ -95,7 +95,7 @@ class TrustIsRisk { })); } - mtx.addCoin(coin); + mtx.addCoin(coin); var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, fromKeyRing); assert(success); @@ -130,10 +130,10 @@ class TrustIsRisk { var fromAddress = helpers.pubKeyToEntity(fromKeyRing.getPublicKey()); var toAddress = helpers.pubKeyToEntity(toKeyRing.getPublicKey()); - if (fromAddress === toAddress) throw new Error('Can\'t decrease self-trust'); + if (fromAddress === toAddress) throw new Error("Can't decrease self-trust"); var existingTrustAmount = this.db.getDirectTrustAmount(fromAddress, toAddress); - if (existingTrustAmount < trustDecreaseAmount) throw new Error('Insufficient trust'); + if (existingTrustAmount < trustDecreaseAmount) throw new Error("Insufficient trust"); var directTrusts = this.db.getSpendableDirectTrusts(fromAddress, toAddress); return directTrusts.map((directTrust) => { @@ -147,7 +147,7 @@ class TrustIsRisk { getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, signingKeyRing : bcoin$KeyRing, fee : ?number) { if (!payee) payee = directTrust.getFromEntity(); - if (!fee) fee = 1000; // TODO: estimate this + if (!fee) fee = 1000; // TODO: estimate this var mtx = new MTX({ inputs: [ @@ -180,9 +180,9 @@ class TrustIsRisk { parseTXAsTrustIncrease(tx : bcoin$TX) : (DirectTrust | null) { if (tx.inputs.length !== 1) return null; - var input = tx.inputs[0]; - if (input.getType() !== 'pubkeyhash') return null; // TODO: This is unreliable - if (this.db.isTrustOutput(input.prevout.hash.toString('hex'), input.prevout.index)) return null; + var input = tx.inputs[0]; + if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable + if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; var sender = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -190,7 +190,7 @@ class TrustIsRisk { var trustOutputs = this.searchForDirectTrustOutputs(tx, sender); if (trustOutputs.length !== 1) return null; - var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length + var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length; if (changeOutputCount + 1 !== tx.outputs.length) return null; return trustOutputs[0]; @@ -210,7 +210,7 @@ class TrustIsRisk { } getTrustDecrease(tx : bcoin$TX, prevTrust : DirectTrust) : DirectTrust { - var txHash = tx.hash().toString('hex'); + var txHash = tx.hash().toString("hex"); var nullTrust = prevTrust.getNullifying(txHash); if (tx.inputs.length !== 1) return nullTrust; @@ -243,15 +243,15 @@ class TrustIsRisk { } isChangeOutput(output : bcoin$Output, sender : Entity) : boolean { - return (output.getType() === 'pubkeyhash') + return (output.getType() === "pubkeyhash") && (output.getAddress().toBase58() === sender); } parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, sender : Entity) : (DirectTrust | null) { - var txHash = tx.hash().toString('hex'); + var txHash = tx.hash().toString("hex"); var output = tx.outputs[outputIndex]; - if (output.getType() !== 'multisig') return null; + if (output.getType() !== "multisig") return null; var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); if (entities[0] === entities[1]) return null; diff --git a/test/full_node.js b/test/full_node.js index f8792c5..9ca89a4 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -1,6 +1,6 @@ -var Trust = require('../'); -var helpers = require('../lib/helpers.js'); -var bcoin = require('bcoin'); +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -8,36 +8,36 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var testHelpers = require('./helpers'); -var consensus = require('bcoin/lib/protocol/consensus'); -var sinon = require('sinon'); -var should = require('should'); -require('should-sinon'); +var testHelpers = require("./helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +require("should-sinon"); const COIN = consensus.COIN; -describe('FullNode', () => { +describe("FullNode", () => { var node = null; var walletDB = null; - sinon.spy(Trust.TrustIsRisk.prototype, 'addTX'); + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); - beforeEach('get node', () => testHelpers.getNode().then((n) => { + beforeEach("get node", () => testHelpers.getNode().then((n) => { node = n; })); - beforeEach('get walletDB', () => testHelpers.getWalletDB(node).then((w) => { + beforeEach("get walletDB", () => testHelpers.getWalletDB(node).then((w) => { walletDB = w; })); - afterEach('close walletDB', async () => walletDB.close()); - afterEach('close node', async () => node.close()); + afterEach("close walletDB", async () => walletDB.close()); + afterEach("close node", async () => node.close()); - it('should call trust.addTX() on every transaction', async function() { - var sender = await testHelpers.getWallet(walletDB, 'sender'); - var receiver = await testHelpers.getWallet(walletDB, 'receiver'); + it("should call trust.addTX() on every transaction", async function() { + var sender = await testHelpers.getWallet(walletDB, "sender"); + var receiver = await testHelpers.getWallet(walletDB, "receiver"); // Produce a block and reward the sender, so that we have a coin to spend. - await testHelpers.mineBlock(node, sender.getAddress('base58')); + await testHelpers.mineBlock(node, sender.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; @@ -46,7 +46,7 @@ describe('FullNode', () => { await sender.send({ outputs: [{ value: 10 * COIN, - address: receiver.getAddress('base58') + address: receiver.getAddress("base58") }] }); @@ -54,14 +54,14 @@ describe('FullNode', () => { node.trust.addTX.should.be.calledOnce(); }); - describe('with the nobodyLikesFrank.json example', () => { + describe("with the nobodyLikesFrank.json example", () => { var addresses, rings = {}; - beforeEach('apply graph transactions', async () => { + beforeEach("apply graph transactions", async () => { addresses = {}; rings = {}; - for (var i = 0; i < testHelpers.names.length; i++) { + for (let i = 0; i < testHelpers.names.length; i++) { var name = testHelpers.names[i]; rings[name] = testHelpers.rings[i]; addresses[name] = helpers.pubKeyToEntity(rings[name].getPublicKey()); @@ -71,7 +71,7 @@ describe('FullNode', () => { consensus.COINBASE_MATURITY = 0; var coinbaseCoinsCount = 3; var coinbaseHashes = []; - for(var i = 0; i < coinbaseCoinsCount; i++) { + for(let i = 0; i < coinbaseCoinsCount; i++) { var block = await testHelpers.mineBlock(node, addresses.alice); coinbaseHashes.push(block.txs[0].hash()); await testHelpers.time(200); @@ -99,7 +99,7 @@ describe('FullNode', () => { // Use the coinbase coins as inputs var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { - return node.getCoin(hash.toString('hex'), 0); + return node.getCoin(hash.toString("hex"), 0); })); var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); @@ -110,41 +110,41 @@ describe('FullNode', () => { var tx = mtx.toTX(); node.sendTX(tx); - prevout = {}; - testHelpers.names.forEach((name) => { - prevout[name] = { - hash: tx.hash().toString('hex'), - index: testHelpers.names.indexOf(name) - }; - }); + prevout = {}; + testHelpers.names.forEach((name) => { + prevout[name] = { + hash: tx.hash().toString("hex"), + index: testHelpers.names.indexOf(name) + }; + }); await testHelpers.time(500); // Alice mines another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); await testHelpers.time(500); - var graph = require('./graphs/nobodyLikesFrank.json'); + var graph = require("./graphs/nobodyLikesFrank.json"); var promises = []; for (var from in graph) { var neighbours = graph[from]; for (var to in neighbours) { var value = neighbours[to]; - if (!value || value < 1) continue; + if (!value || value < 1) continue; - var outpoint = new Outpoint(prevout[from].hash, prevout[from].index); + let outpoint = new Outpoint(prevout[from].hash, prevout[from].index); - var mtx = await node.trust.getTrustIncreasingMTX(rings[from].getPrivateKey(), + let mtx = await node.trust.getTrustIncreasingMTX(rings[from].getPrivateKey(), rings[to].getPublicKey(), outpoint, value * consensus.COIN); - should(await mtx.verify()); + should(await mtx.verify()); // The change output from this transaction will be used in other transactions from the // same origin. We therefore need to sleep until the transaction is added to the pool. - var tx = mtx.toTX(); - node.sendTX(tx); - await testHelpers.time(250); + let tx = mtx.toTX(); + node.sendTX(tx); + await testHelpers.time(250); - prevout[from] = {hash: tx.hash().toString('hex'), index: 1}; + prevout[from] = {hash: tx.hash().toString("hex"), index: 1}; } } //mtxs.forEach((mtx) => node.sendTX(mtx.toTX())); @@ -155,24 +155,24 @@ describe('FullNode', () => { await testHelpers.time(500); }); - it('computes trusts correctly', () => { + it("computes trusts correctly", () => { for (name in addresses) { // Add addresses to scope eval(`var ${name} = "${addresses[name]}";`); } - should(node.trust.getTrust(alice, alice)).equal(Infinity); - should(node.trust.getTrust(alice, bob)).equal(10 * COIN); - should(node.trust.getTrust(alice, charlie)).equal(1 * COIN); - should(node.trust.getTrust(alice, frank)).equal(0); - should(node.trust.getTrust(alice, eve)).equal(6 * COIN); + should(node.trust.getTrust(alice, alice)).equal(Infinity); + should(node.trust.getTrust(alice, bob)).equal(10 * COIN); + should(node.trust.getTrust(alice, charlie)).equal(1 * COIN); + should(node.trust.getTrust(alice, frank)).equal(0); + should(node.trust.getTrust(alice, eve)).equal(6 * COIN); - should(node.trust.getTrust(bob, alice)).equal(1 * COIN); - should(node.trust.getTrust(bob, eve)).equal(3 * COIN); - should(node.trust.getTrust(dave, eve)).equal(12 * COIN); - should(node.trust.getTrust(george, eve)).equal(0); + should(node.trust.getTrust(bob, alice)).equal(1 * COIN); + should(node.trust.getTrust(bob, eve)).equal(3 * COIN); + should(node.trust.getTrust(dave, eve)).equal(12 * COIN); + should(node.trust.getTrust(george, eve)).equal(0); }); - it('after decreasing some trusts computes trusts correctly', async () => { + it("after decreasing some trusts computes trusts correctly", async () => { var mtxs = node.trust.getTrustDecreasingMTXs(rings.alice.getPrivateKey(), rings.bob.getPublicKey(), 3 * COIN); mtxs.length.should.equal(1); diff --git a/test/helpers.js b/test/helpers.js index b16a0da..98b906b 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,20 +1,20 @@ -var TrustIsRisk = require('../'); -var WalletDB = require('bcoin/lib/wallet/walletdb'); -var bcoin = require('bcoin'); +var TrustIsRisk = require("../"); +var WalletDB = require("bcoin/lib/wallet/walletdb"); +var bcoin = require("bcoin"); var KeyRing = bcoin.primitives.KeyRing; -var assert = require('assert'); +var assert = require("assert"); var testHelpers = { - names: ['alice', 'bob', 'charlie', 'dave', 'eve', 'frank', 'george'], + names: ["alice", "bob", "charlie", "dave", "eve", "frank", "george"], rings: [ - '02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c0', - '2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ad', - '3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD7', - '19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F3', - '0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A', - '878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D45', - '1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A' - ].map((key) => KeyRing.fromPrivate(new Buffer(key, 'hex'))), + "02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c0", + "2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ad", + "3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD7", + "19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F3", + "0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A", + "878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D45", + "1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A" + ].map((key) => KeyRing.fromPrivate(new Buffer(key, "hex"))), getAddressFixtures: () => { assert(testHelpers.rings.length === testHelpers.names.length); @@ -35,7 +35,7 @@ var testHelpers = { }, getNode: async () => { - var node = new TrustIsRisk.FullNode({network: 'regtest', passphrase: 'secret'}); + var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); await node.open(); await node.connect(); @@ -46,8 +46,8 @@ var testHelpers = { getWalletDB: async (node) => { var walletDB = new WalletDB({ - network: 'regtest', - db: 'memory', + network: "regtest", + db: "memory", client: new bcoin.node.NodeClient(node) }); @@ -60,9 +60,9 @@ var testHelpers = { getWallet: async (walletDB, id) => { var options = { id, - passphrase: 'secret', + passphrase: "secret", witness: false, - type: 'pubkeyhash' + type: "pubkeyhash" }; return walletDB.create(options); @@ -81,7 +81,7 @@ var testHelpers = { }, bufferToScript: (data) => { - return `0x${Number(data.length).toString(16)} 0x${data.toString('hex')}`; + return `0x${Number(data.length).toString(16)} 0x${data.toString("hex")}`; }, getP2PKHOutput: (to, value) => { @@ -94,7 +94,7 @@ var testHelpers = { getP2PKHInput: (pubKey, prevout) => { if (!prevout) { prevout = { // Don't care - hash: 'v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', + hash: "v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", index: 2 }; } diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index ddb3d36..7c4db6a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -1,19 +1,19 @@ -var Trust = require('../'); -var helpers = require('../lib/helpers.js'); -var bcoin = require('bcoin'); +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); var Coin = bcoin.primitives.Coin; var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; -var testHelpers = require('./helpers'); -var consensus = require('bcoin/lib/protocol/consensus'); -var sinon = require('sinon'); -var should = require('should'); -require('should-sinon'); +var testHelpers = require("./helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +require("should-sinon"); const COIN = bcoin.consensus.COIN; -describe('TrustIsRisk', () => { +describe("TrustIsRisk", () => { var addr = testHelpers.getAddressFixtures(); // Add base58 address variables to scope. for (name in addr) { @@ -30,7 +30,7 @@ describe('TrustIsRisk', () => { var inputOneOfTwoMultisig = new Input({ prevout: { - hash: trustIncreasingTX.hash().toString('hex'), + hash: trustIncreasingTX.hash().toString("hex"), index: 0 }, script: bcoin.script.fromString( @@ -49,8 +49,8 @@ describe('TrustIsRisk', () => { }); }); - describe('.getDirectTrust()', () => { - it('returns zero for two arbitary parties that do not trust each other', () => { + describe(".getDirectTrust()", () => { + it("returns zero for two arbitary parties that do not trust each other", () => { should(tir.getDirectTrust(addr.alice.base58, bob)).equal(0); should(tir.getDirectTrust(bob, alice)).equal(0); should(tir.getDirectTrust(charlie, alice)).equal(0); @@ -58,15 +58,15 @@ describe('TrustIsRisk', () => { should(tir.getDirectTrust(charlie, frank)).equal(0); }); - it('returns Infinity for one\'s direct trust to themselves', () => { + it("returns Infinity for one's direct trust to themselves", () => { should(tir.getDirectTrust(alice, alice)).equal(Infinity); should(tir.getDirectTrust(bob, bob)).equal(Infinity); }); }); - describe('.addTX()', () => { - describe('with a non-TIR transaction', () => { - it('does not change trust', () => { + describe(".addTX()", () => { + describe("with a non-TIR transaction", () => { + it("does not change trust", () => { trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); tir.parseTXAsTrustIncrease(trustIncreasingMTX.toTX()); @@ -74,22 +74,22 @@ describe('TrustIsRisk', () => { }); }); - describe('with a trust increasing transaction', () => { - it('correctly increases trust', () => { + describe("with a trust increasing transaction", () => { + it("correctly increases trust", () => { tir.addTX(trustIncreasingTX); should(tir.getDirectTrust(alice, bob)).equal(42 * COIN); should(tir.getDirectTrust(bob, alice)).equal(0); }); - it('which has more than one input does not change trust', () => { + it("which has more than one input does not change trust", () => { trustIncreasingMTX.inputs.push(trustIncreasingMTX.inputs[0].clone()); tir.addTX(trustIncreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); }); - it('which has a change output correctly increases trust', () => { + it("which has a change output correctly increases trust", () => { trustIncreasingMTX.outputs[0].value -= 10 * COIN; trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 10 * COIN)); tir.addTX(trustIncreasingMTX.toTX()); @@ -97,7 +97,7 @@ describe('TrustIsRisk', () => { should(tir.getDirectTrust(alice, bob)).equal(32 * COIN); }); - it('which has two change outputs does not change trust', () => { + it("which has two change outputs does not change trust", () => { trustIncreasingMTX.outputs[0].value -= 10; for (var i = 0; i < 2; i++) { trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 5 * COIN)); @@ -107,7 +107,7 @@ describe('TrustIsRisk', () => { should(tir.getDirectTrust(alice, bob)).equal(0); }); - it('which has a second output that is not a change output does not change trust', () => { + it("which has a second output that is not a change output does not change trust", () => { trustIncreasingMTX.outputs[0].value -= 10 * COIN; trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(charlie, 5 * COIN)); tir.addTX(trustIncreasingMTX.toTX()); @@ -115,31 +115,31 @@ describe('TrustIsRisk', () => { should(tir.getDirectTrust(alice, bob)).equal(0); }); - it('which has been processed before throws', () => { + it("which has been processed before throws", () => { var tx = trustIncreasingMTX.toTX(); should(tir.addTX(tx)); should.throws(() => tir.addTX(tx), /already processed/i); }); }); - describe('with a trust decreasing transaction', () => { + describe("with a trust decreasing transaction", () => { beforeEach(() => { tir.addTX(trustIncreasingTX); }); - it('correctly decreases trust', () => { + it("correctly decreases trust", () => { tir.addTX(trustDecreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(20 * COIN); }); - it('which has a second input decreases trust to zero', () => { + it("which has a second input decreases trust to zero", () => { trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubKey)); tir.addTX(trustDecreasingMTX.toTX()); should(tir.getDirectTrust(alice, bob)).equal(0); }); - it('which has more than one trust outputs decreases trust to zero', () => { + it("which has more than one trust outputs decreases trust to zero", () => { trustDecreasingMTX.outputs[0].value -= 15 * COIN; trustDecreasingMTX.outputs.push( testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 5 * COIN)); @@ -149,18 +149,18 @@ describe('TrustIsRisk', () => { }); }); - describe('.getTrustIncreasingMTX()', () => { - it('creates valid trust-increasing transactions', async () => { - var getTXStub = sinon.stub(node, 'getCoin'); + describe(".getTrustIncreasingMTX()", () => { + it("creates valid trust-increasing transactions", async () => { + var getTXStub = sinon.stub(node, "getCoin"); var prevOutput = { - hash: 'v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8', + hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", index: 1 }; getTXStub.withArgs(prevOutput.hash).returns(new Coin({ - script: testHelpers.getP2PKHOutput(alice, 1).script, - value: 1000 * COIN + script: testHelpers.getP2PKHOutput(alice, 1).script, + value: 1000 * COIN })); var mtx = await tir.getTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, @@ -171,19 +171,19 @@ describe('TrustIsRisk', () => { mtx.outputs.length.should.equal(2); var trustOutput = mtx.outputs[0]; - trustOutput.getType().should.equal('multisig'); + trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; - changeOutput.getType().should.equal('pubkeyhash'); + changeOutput.getType().should.equal("pubkeyhash"); changeOutput.getAddress().toBase58().should.equal(alice); changeOutput.value.should.equal(900 * COIN - 1000); }); }); - describe('.getTrustDecreasingMTX()', () => { + describe(".getTrustDecreasingMTX()", () => { var trustTXs; beforeEach(() => { var tx; @@ -217,12 +217,12 @@ describe('TrustIsRisk', () => { mtx.inputs.length.should.equal(1); mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[0].hash().toString('hex'), + hash: trustTXs[0].hash().toString("hex"), index: 0 }); mtx.outputs.length.should.equal(1); // Single P2PKH output - mtx.outputs[0].getType().should.equal('pubkeyhash'); + mtx.outputs[0].getType().should.equal("pubkeyhash"); mtx.outputs[0].getAddress().toBase58().should.equal(recipient); mtx.outputs[0].value.should.equal(42 * COIN - 1000); @@ -230,59 +230,59 @@ describe('TrustIsRisk', () => { mtx.inputs.length.should.equal(1); mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[1].hash().toString('hex'), + hash: trustTXs[1].hash().toString("hex"), index: 0 }); mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); mtx.outputs[1].value.should.equal(60 * COIN); - mtx.outputs[0].getType().should.equal('pubkeyhash'); + mtx.outputs[0].getType().should.equal("pubkeyhash"); mtx.outputs[0].getAddress().toBase58().should.equal(recipient); mtx.outputs[0].value.should.equal(40 * COIN - 1000); }; - it('creates correct trust decreasing transactions', () => { + it("creates correct trust decreasing transactions", () => { var mtxs = tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); checkMTXs(mtxs, alice); }); - it('creates correct trust stealing transactions', () => { + it("creates correct trust stealing transactions", () => { var mtxs = tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); checkMTXs(mtxs, charlie); }); - it('throws when trying to decrease self-trust', () => { + it("throws when trying to decrease self-trust", () => { should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) , /self-trust/i); }); - it('throws when there is not enough trust', () => { + it("throws when there is not enough trust", () => { should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) , /insufficient trust/i); }); - }); + }); - describe('.getTrust()', () => { - it('returns zero for two arbitary parties that do not trust each other', () => { + describe(".getTrust()", () => { + it("returns zero for two arbitary parties that do not trust each other", () => { should(tir.getTrust(alice, bob)).equal(0); should(tir.getTrust(bob, alice)).equal(0); should(tir.getTrust(charlie, alice)).equal(0); should(tir.getTrust(alice, charlie)).equal(0); }); - it('returns Infinity for one\'s trust to themselves', () => { + it("returns Infinity for one's trust to themselves", () => { should(tir.getTrust(alice, alice)).equal(Infinity); should(tir.getTrust(bob, bob)).equal(Infinity); }); - describe('after applying the Nobody Likes Frank graph example', () => { + describe("after applying the Nobody Likes Frank graph example", () => { beforeEach(() => { - testHelpers.applyGraph(tir, './graphs/nobodyLikesFrank.json', addr); + testHelpers.applyGraph(tir, "./graphs/nobodyLikesFrank.json", addr); }); - it('correctly computes trusts', () => { + it("correctly computes trusts", () => { should(tir.getTrust(alice, alice)).equal(Infinity); should(tir.getTrust(alice, bob)).equal(10); should(tir.getTrust(alice, charlie)).equal(1); @@ -340,7 +340,7 @@ describe('TrustIsRisk', () => { should(tir.getTrust(george, george)).equal(Infinity); }); - it('correctly computes trusts when bob trusts frank', () => { + it("correctly computes trusts when bob trusts frank", () => { tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); should(tir.getTrust(george, frank)).equal(0); should(tir.getTrust(alice, frank)).equal(8); From d28d1b66ccf351cb34d96b7e25e89575caacb5c2 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 29 May 2017 17:35:04 +0000 Subject: [PATCH 012/540] Refactor: use consistent variable names --- lib/direct_trust.js | 18 ++++---- lib/trust_db.js | 52 ++++++++++----------- lib/trust_is_risk.js | 108 +++++++++++++++++++++---------------------- src/direct_trust.js | 22 ++++----- src/trust_db.js | 52 ++++++++++----------- src/trust_is_risk.js | 108 +++++++++++++++++++++---------------------- test/full_node.js | 16 +++---- test/helpers.js | 24 +++++----- 8 files changed, 200 insertions(+), 200 deletions(-) diff --git a/lib/direct_trust.js b/lib/direct_trust.js index d1da9c8..0656934 100644 --- a/lib/direct_trust.js +++ b/lib/direct_trust.js @@ -5,8 +5,8 @@ var assert = require("assert"); var helpers = require("./helpers"); + - @@ -18,8 +18,8 @@ var helpers = require("./helpers"); class DirectTrust { + - // Every DT is associated with a transaction output, except for non-standard trust decreasing @@ -74,17 +74,17 @@ class DirectTrust { return valid; } - getFromEntity() { - return helpers.pubKeyToEntity(this.from); + getOriginEntity() { + return helpers.pubKeyToEntity(this.origin); } - getToEntity() { - return helpers.pubKeyToEntity(this.to); + getDestEntity() { + return helpers.pubKeyToEntity(this.dest); } spend(next ) { assert(!this.isSpent()); - assert(this.from.equals(next.from) && this.to.equals(next.to)); + assert(this.origin.equals(next.origin) && this.dest.equals(next.dest)); assert(next.amount <= this.amount); this.next = next; @@ -93,8 +93,8 @@ class DirectTrust { getNullifying(txHash ) { return new DirectTrust({ - from: this.from, - to: this.to, + origin: this.origin, + dest: this.dest, amount: 0, prev: this, diff --git a/lib/trust_db.js b/lib/trust_db.js index fecf695..d894ed1 100644 --- a/lib/trust_db.js +++ b/lib/trust_db.js @@ -35,22 +35,22 @@ class TrustDB { return trust; } - getDirectTrustAmount(from , to ) { - if (from === to) return Infinity; + getDirectTrustAmount(origin , dest ) { + if (origin === dest) return Infinity; - var trusts = this.getSpendableDirectTrusts(from, to); + var trusts = this.getSpendableDirectTrusts(origin, dest); return trusts.reduce((sum, t) => sum + t.amount, 0); } - getSpendableDirectTrusts(from , to ) { - return this.getDirectTrusts(from, to).filter((t) => t.isSpendable()); + getSpendableDirectTrusts(origin , dest ) { + return this.getDirectTrusts(origin, dest).filter((t) => t.isSpendable()); } - getDirectTrusts(from , to ) { - var fromMap = this.directTrusts.get(from); - if (!fromMap) return []; + getDirectTrusts(origin , dest ) { + var originMap = this.directTrusts.get(origin); + if (!originMap) return []; - var trusts = fromMap.get(to); + var trusts = originMap.get(dest); if (!trusts) return []; return trusts; @@ -58,21 +58,21 @@ class TrustDB { getGraphWeightMatrix() { var entitiesArr = this.getEntities(); - return entitiesArr.map((from) => { - return entitiesArr.map((to) => this.getDirectTrustAmount(from, to)); + return entitiesArr.map((origin) => { + return entitiesArr.map((dest) => this.getDirectTrustAmount(origin, dest)); }); } - getTrustAmount(from , to ) { + getTrustAmount(origin , dest ) { // TODO: Optimize - if (from === to) return Infinity; + if (origin === dest) return Infinity; var graph = this.getGraphWeightMatrix(); - var fromIndex = this.getEntityIndex(from); - var toIndex = this.getEntityIndex(to); + var originIndex = this.getEntityIndex(origin); + var destIndex = this.getEntityIndex(dest); - if (fromIndex === -1 || toIndex === -1) return 0; - else return maxFlow(graph, fromIndex, toIndex); + if (originIndex === -1 || destIndex === -1) return 0; + else return maxFlow(graph, originIndex, destIndex); } getEntities() { @@ -93,15 +93,15 @@ class TrustDB { } add(trust ) { - var from = trust.getFromEntity(); - var to = trust.getToEntity(); - assert(from !== to); + var origin = trust.getOriginEntity(); + var dest = trust.getDestEntity(); + assert(origin !== dest); - if (!this.directTrusts.has(from)) this.directTrusts.set(from, new Map()); - var fromMap = ((this.directTrusts.get(from) ) ); + if (!this.directTrusts.has(origin)) this.directTrusts.set(origin, new Map()); + var originMap = ((this.directTrusts.get(origin) ) ); - if (!fromMap.has(to)) fromMap.set(to, []); - var trusts = ((fromMap.get(to) ) ); + if (!originMap.has(dest)) originMap.set(dest, []); + var trusts = ((originMap.get(dest) ) ); if (trust.prev !== null) { trust.prev.spend(trust); @@ -112,8 +112,8 @@ class TrustDB { trusts.push(trust); this.txToDirectTrust.set(trust.txHash, trust); - this.entities.add(from); - this.entities.add(to); + this.entities.add(origin); + this.entities.add(dest); } } diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 7e0b8cb..d13fe7a 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -24,12 +24,12 @@ class TrustIsRisk { this.node.on("tx", this.addTX.bind(this)); } - getTrust(from , to ) { - return this.db.getTrustAmount(from, to); + getTrust(origin , dest ) { + return this.db.getTrustAmount(origin, dest); } - getDirectTrust(from , to ) { - return this.db.getDirectTrustAmount(from, to); + getDirectTrust(origin , dest ) { + return this.db.getDirectTrustAmount(origin, dest); } // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network @@ -66,22 +66,22 @@ class TrustIsRisk { // Returns a promise resolving to a mutable transaction object, which increases a trust // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output - // payable to the sender. - // Any satoshis not spent will be returned to the sender, minus the fees, via P2PKH. - async getTrustIncreasingMTX(fromPrivate , to , outpoint , + // payable to the sender. The origin key must be a private key. Any satoshis not spent will be + // returned to the sender, minus the fees, via P2PKH. + async getTrustIncreasingMTX(origin , dest , outpoint , trustAmount , fee ) { if (!fee) fee = 1000; // TODO: estimate this var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!coin) throw new Error("Could not find coin"); - var fromKeyRing = KeyRing.fromPrivate(fromPrivate); - var from = fromKeyRing.getPublicKey(); + var originKeyRing = KeyRing.fromPrivate(origin); + var originPubKey = originKeyRing.getPublicKey(); var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 2, [from, to]), + script: bcoin.script.fromMultisig(1, 2, [originPubKey, dest]), value: trustAmount }) ] @@ -90,16 +90,16 @@ class TrustIsRisk { var changeAmount = coin.value - trustAmount - fee; if (changeAmount) { mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), value: changeAmount })); } mtx.addCoin(coin); - var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, fromKeyRing); + var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); assert(success); - var signedCount = mtx.sign(fromKeyRing); + var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); return mtx; @@ -108,34 +108,34 @@ class TrustIsRisk { // Returns an array of trust-decreasing mutable transaction objects, which reduce a trust // relationship by the amount specified. The payee will receive the amount deducted minus the // transaction fees via P2PKH. - // If steal is undefined or set to false, then the `from` key is expected to be a private key and - // the `to` key is expected to be a public key. If steal is set to true, then `from` is expected - // to be a public key and `to` is expected to be a private key. The private key will be used to - // sign the transaction. - getTrustDecreasingMTXs(from , to , trustDecreaseAmount , payee , + // If steal is undefined or set to false, then the `origin` key is expected to be a private key + // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is + // expected to be a public key and `dest` is expected to be a private key. The private key will be + // used to sign the transaction. + getTrustDecreasingMTXs(origin , dest , trustDecreaseAmount , payee , steal , fee ) { if (steal === undefined) steal = false; - var signingKeyRing, fromKeyRing, toKeyRing; + var signingKeyRing, originKeyRing, destKeyRing; if (!steal) { - signingKeyRing = KeyRing.fromPrivate(from); - fromKeyRing = KeyRing.fromPrivate(from); - toKeyRing = KeyRing.fromPublic(to); + signingKeyRing = KeyRing.fromPrivate(origin); + originKeyRing = KeyRing.fromPrivate(origin); + destKeyRing = KeyRing.fromPublic(dest); } else { - signingKeyRing = KeyRing.fromPrivate(to); - fromKeyRing = KeyRing.fromPublic(from); - toKeyRing = KeyRing.fromPrivate(to); + signingKeyRing = KeyRing.fromPrivate(dest); + originKeyRing = KeyRing.fromPublic(origin); + destKeyRing = KeyRing.fromPrivate(dest); } - var fromAddress = helpers.pubKeyToEntity(fromKeyRing.getPublicKey()); - var toAddress = helpers.pubKeyToEntity(toKeyRing.getPublicKey()); + var originAddress = helpers.pubKeyToEntity(originKeyRing.getPublicKey()); + var destAddress = helpers.pubKeyToEntity(destKeyRing.getPublicKey()); - if (fromAddress === toAddress) throw new Error("Can't decrease self-trust"); + if (originAddress === destAddress) throw new Error("Can't decrease self-trust"); - var existingTrustAmount = this.db.getDirectTrustAmount(fromAddress, toAddress); + var existingTrustAmount = this.db.getDirectTrustAmount(originAddress, destAddress); if (existingTrustAmount < trustDecreaseAmount) throw new Error("Insufficient trust"); - var directTrusts = this.db.getSpendableDirectTrusts(fromAddress, toAddress); + var directTrusts = this.db.getSpendableDirectTrusts(originAddress, destAddress); return directTrusts.map((directTrust) => { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; @@ -146,7 +146,7 @@ class TrustIsRisk { getTrustDecreasingMTX(directTrust , decreaseAmount , payee , signingKeyRing , fee ) { - if (!payee) payee = directTrust.getFromEntity(); + if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this var mtx = new MTX({ @@ -162,13 +162,13 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 2, [directTrust.from, directTrust.to]), + script: bcoin.script.fromMultisig(1, 2, [directTrust.origin, directTrust.dest]), value: remainingTrustAmount })); } var success = mtx.scriptVector(((directTrust.script ) ), - mtx.inputs[0].script, KeyRing.fromPublic(directTrust.from)); + mtx.inputs[0].script, KeyRing.fromPublic(directTrust.origin)); assert(success); success = mtx.signInput(0, new Coin({script: directTrust.script, value: directTrust.amount}), @@ -183,14 +183,14 @@ class TrustIsRisk { var input = tx.inputs[0]; if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; - var sender = tx.inputs[0].getAddress().toBase58(); + var origin = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; - var trustOutputs = this.searchForDirectTrustOutputs(tx, sender); + var trustOutputs = this.searchForDirectTrustOutputs(tx, origin); if (trustOutputs.length !== 1) return null; - var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length; + var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, origin)).length; if (changeOutputCount + 1 !== tx.outputs.length) return null; return trustOutputs[0]; @@ -215,8 +215,8 @@ class TrustIsRisk { if (tx.inputs.length !== 1) return nullTrust; - var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getFromEntity(), - prevTrust.getToEntity()); + var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getOriginEntity(), + prevTrust.getDestEntity()); if (trustOutputs.length != 1) return nullTrust; var nextTrust = trustOutputs[0]; @@ -230,46 +230,46 @@ class TrustIsRisk { // Returns a list of the corresponding DirectTrust objects. // If the recipient parameter is set, it will limit the results only to the outputs being sent to // the recipient. - searchForDirectTrustOutputs(tx , sender , recipient ) { + searchForDirectTrustOutputs(tx , origin , recipient ) { var directTrusts = tx.outputs.map((output, outputIndex) => - this.parseOutputAsDirectTrust(tx, outputIndex, sender) + this.parseOutputAsDirectTrust(tx, outputIndex, origin) ).filter(Boolean); if (recipient) { - directTrusts.filter((trust) => trust.to === recipient); + directTrusts.filter((trust) => trust.dest === recipient); } return directTrusts; } - isChangeOutput(output , sender ) { + isChangeOutput(output , origin ) { return (output.getType() === "pubkeyhash") - && (output.getAddress().toBase58() === sender); + && (output.getAddress().toBase58() === origin); } - parseOutputAsDirectTrust(tx , outputIndex , sender ) + parseOutputAsDirectTrust(tx , outputIndex , origin ) { var txHash = tx.hash().toString("hex"); var output = tx.outputs[outputIndex]; if (output.getType() !== "multisig") return null; - + var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); if (entities[0] === entities[1]) return null; - var from, to; - if (entities[0] === sender) { - from = output.script.get(1); - to = output.script.get(2); + var originPubKey, destPubKey; + if (entities[0] === origin) { + originPubKey = output.script.get(1); + destPubKey = output.script.get(2); } - else if (entities[1] === sender) { - from = output.script.get(2); - to = output.script.get(1); + else if (entities[1] === origin) { + originPubKey = output.script.get(2); + destPubKey = output.script.get(1); } else return null; return new DirectTrust({ - from, - to, + origin: originPubKey, + dest: destPubKey, amount: Number(output.value), txHash, diff --git a/src/direct_trust.js b/src/direct_trust.js index 70662ed..15fbae6 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -5,8 +5,8 @@ var assert = require("assert"); var helpers = require("./helpers"); type DirectTrustOptions = { - from : Key, - to : Key, + origin : Key, + dest : Key, amount : number, txHash : string, @@ -18,8 +18,8 @@ type DirectTrustOptions = { } class DirectTrust { - from : Key - to : Key + origin : Key + dest : Key amount : number // Every DT is associated with a transaction output, except for non-standard trust decreasing @@ -74,17 +74,17 @@ class DirectTrust { return valid; } - getFromEntity() : Entity { - return helpers.pubKeyToEntity(this.from); + getOriginEntity() : Entity { + return helpers.pubKeyToEntity(this.origin); } - getToEntity() : Entity { - return helpers.pubKeyToEntity(this.to); + getDestEntity() : Entity { + return helpers.pubKeyToEntity(this.dest); } spend(next : DirectTrust) : void { assert(!this.isSpent()); - assert(this.from.equals(next.from) && this.to.equals(next.to)); + assert(this.origin.equals(next.origin) && this.dest.equals(next.dest)); assert(next.amount <= this.amount); this.next = next; @@ -93,8 +93,8 @@ class DirectTrust { getNullifying(txHash : string) : DirectTrust { return new DirectTrust({ - from: this.from, - to: this.to, + origin: this.origin, + dest: this.dest, amount: 0, prev: this, diff --git a/src/trust_db.js b/src/trust_db.js index 449f50a..650616b 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -35,22 +35,22 @@ class TrustDB { return trust; } - getDirectTrustAmount(from : Entity, to : Entity) : number { - if (from === to) return Infinity; + getDirectTrustAmount(origin : Entity, dest : Entity) : number { + if (origin === dest) return Infinity; - var trusts = this.getSpendableDirectTrusts(from, to); + var trusts = this.getSpendableDirectTrusts(origin, dest); return trusts.reduce((sum, t) => sum + t.amount, 0); } - getSpendableDirectTrusts(from : Entity, to : Entity) : DirectTrust[] { - return this.getDirectTrusts(from, to).filter((t) => t.isSpendable()); + getSpendableDirectTrusts(origin : Entity, dest : Entity) : DirectTrust[] { + return this.getDirectTrusts(origin, dest).filter((t) => t.isSpendable()); } - getDirectTrusts(from : Entity, to : Entity) : DirectTrust[] { - var fromMap = this.directTrusts.get(from); - if (!fromMap) return []; + getDirectTrusts(origin : Entity, dest : Entity) : DirectTrust[] { + var originMap = this.directTrusts.get(origin); + if (!originMap) return []; - var trusts = fromMap.get(to); + var trusts = originMap.get(dest); if (!trusts) return []; return trusts; @@ -58,21 +58,21 @@ class TrustDB { getGraphWeightMatrix() : number[][] { var entitiesArr = this.getEntities(); - return entitiesArr.map((from) => { - return entitiesArr.map((to) => this.getDirectTrustAmount(from, to)); + return entitiesArr.map((origin) => { + return entitiesArr.map((dest) => this.getDirectTrustAmount(origin, dest)); }); } - getTrustAmount(from : Entity, to : Entity) : number { + getTrustAmount(origin : Entity, dest : Entity) : number { // TODO: Optimize - if (from === to) return Infinity; + if (origin === dest) return Infinity; var graph = this.getGraphWeightMatrix(); - var fromIndex = this.getEntityIndex(from); - var toIndex = this.getEntityIndex(to); + var originIndex = this.getEntityIndex(origin); + var destIndex = this.getEntityIndex(dest); - if (fromIndex === -1 || toIndex === -1) return 0; - else return maxFlow(graph, fromIndex, toIndex); + if (originIndex === -1 || destIndex === -1) return 0; + else return maxFlow(graph, originIndex, destIndex); } getEntities() : Entity[] { @@ -93,15 +93,15 @@ class TrustDB { } add(trust : DirectTrust) { - var from = trust.getFromEntity(); - var to = trust.getToEntity(); - assert(from !== to); + var origin = trust.getOriginEntity(); + var dest = trust.getDestEntity(); + assert(origin !== dest); - if (!this.directTrusts.has(from)) this.directTrusts.set(from, new Map()); - var fromMap = ((this.directTrusts.get(from) : any) : Map>); + if (!this.directTrusts.has(origin)) this.directTrusts.set(origin, new Map()); + var originMap = ((this.directTrusts.get(origin) : any) : Map>); - if (!fromMap.has(to)) fromMap.set(to, []); - var trusts = ((fromMap.get(to) : any) : Array); + if (!originMap.has(dest)) originMap.set(dest, []); + var trusts = ((originMap.get(dest) : any) : Array); if (trust.prev !== null) { trust.prev.spend(trust); @@ -112,8 +112,8 @@ class TrustDB { trusts.push(trust); this.txToDirectTrust.set(trust.txHash, trust); - this.entities.add(from); - this.entities.add(to); + this.entities.add(origin); + this.entities.add(dest); } } diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index db3ec16..fc1f8ff 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -24,12 +24,12 @@ class TrustIsRisk { this.node.on("tx", this.addTX.bind(this)); } - getTrust(from : Entity, to : Entity) { - return this.db.getTrustAmount(from, to); + getTrust(origin : Entity, dest : Entity) { + return this.db.getTrustAmount(origin, dest); } - getDirectTrust(from : Entity, to : Entity) { - return this.db.getDirectTrustAmount(from, to); + getDirectTrust(origin : Entity, dest : Entity) { + return this.db.getDirectTrustAmount(origin, dest); } // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network @@ -66,22 +66,22 @@ class TrustIsRisk { // Returns a promise resolving to a mutable transaction object, which increases a trust // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output - // payable to the sender. - // Any satoshis not spent will be returned to the sender, minus the fees, via P2PKH. - async getTrustIncreasingMTX(fromPrivate : Key, to : Key, outpoint : bcoin$Outpoint, + // payable to the sender. The origin key must be a private key. Any satoshis not spent will be + // returned to the sender, minus the fees, via P2PKH. + async getTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, fee : ?number) : Promise { if (!fee) fee = 1000; // TODO: estimate this var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!coin) throw new Error("Could not find coin"); - var fromKeyRing = KeyRing.fromPrivate(fromPrivate); - var from = fromKeyRing.getPublicKey(); + var originKeyRing = KeyRing.fromPrivate(origin); + var originPubKey = originKeyRing.getPublicKey(); var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 2, [from, to]), + script: bcoin.script.fromMultisig(1, 2, [originPubKey, dest]), value: trustAmount }) ] @@ -90,16 +90,16 @@ class TrustIsRisk { var changeAmount = coin.value - trustAmount - fee; if (changeAmount) { mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(from)), + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), value: changeAmount })); } mtx.addCoin(coin); - var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, fromKeyRing); + var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); assert(success); - var signedCount = mtx.sign(fromKeyRing); + var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); return mtx; @@ -108,34 +108,34 @@ class TrustIsRisk { // Returns an array of trust-decreasing mutable transaction objects, which reduce a trust // relationship by the amount specified. The payee will receive the amount deducted minus the // transaction fees via P2PKH. - // If steal is undefined or set to false, then the `from` key is expected to be a private key and - // the `to` key is expected to be a public key. If steal is set to true, then `from` is expected - // to be a public key and `to` is expected to be a private key. The private key will be used to - // sign the transaction. - getTrustDecreasingMTXs(from : Key, to : Key, trustDecreaseAmount : number, payee : ?Entity, + // If steal is undefined or set to false, then the `origin` key is expected to be a private key + // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is + // expected to be a public key and `dest` is expected to be a private key. The private key will be + // used to sign the transaction. + getTrustDecreasingMTXs(origin : Key, dest : Key, trustDecreaseAmount : number, payee : ?Entity, steal : ?boolean, fee : ?number) : bcoin$MTX[] { if (steal === undefined) steal = false; - var signingKeyRing, fromKeyRing, toKeyRing; + var signingKeyRing, originKeyRing, destKeyRing; if (!steal) { - signingKeyRing = KeyRing.fromPrivate(from); - fromKeyRing = KeyRing.fromPrivate(from); - toKeyRing = KeyRing.fromPublic(to); + signingKeyRing = KeyRing.fromPrivate(origin); + originKeyRing = KeyRing.fromPrivate(origin); + destKeyRing = KeyRing.fromPublic(dest); } else { - signingKeyRing = KeyRing.fromPrivate(to); - fromKeyRing = KeyRing.fromPublic(from); - toKeyRing = KeyRing.fromPrivate(to); + signingKeyRing = KeyRing.fromPrivate(dest); + originKeyRing = KeyRing.fromPublic(origin); + destKeyRing = KeyRing.fromPrivate(dest); } - var fromAddress = helpers.pubKeyToEntity(fromKeyRing.getPublicKey()); - var toAddress = helpers.pubKeyToEntity(toKeyRing.getPublicKey()); + var originAddress = helpers.pubKeyToEntity(originKeyRing.getPublicKey()); + var destAddress = helpers.pubKeyToEntity(destKeyRing.getPublicKey()); - if (fromAddress === toAddress) throw new Error("Can't decrease self-trust"); + if (originAddress === destAddress) throw new Error("Can't decrease self-trust"); - var existingTrustAmount = this.db.getDirectTrustAmount(fromAddress, toAddress); + var existingTrustAmount = this.db.getDirectTrustAmount(originAddress, destAddress); if (existingTrustAmount < trustDecreaseAmount) throw new Error("Insufficient trust"); - var directTrusts = this.db.getSpendableDirectTrusts(fromAddress, toAddress); + var directTrusts = this.db.getSpendableDirectTrusts(originAddress, destAddress); return directTrusts.map((directTrust) => { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; @@ -146,7 +146,7 @@ class TrustIsRisk { getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, signingKeyRing : bcoin$KeyRing, fee : ?number) { - if (!payee) payee = directTrust.getFromEntity(); + if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this var mtx = new MTX({ @@ -162,13 +162,13 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 2, [directTrust.from, directTrust.to]), + script: bcoin.script.fromMultisig(1, 2, [directTrust.origin, directTrust.dest]), value: remainingTrustAmount })); } var success = mtx.scriptVector(((directTrust.script : any) : bcoin$Script), - mtx.inputs[0].script, KeyRing.fromPublic(directTrust.from)); + mtx.inputs[0].script, KeyRing.fromPublic(directTrust.origin)); assert(success); success = mtx.signInput(0, new Coin({script: directTrust.script, value: directTrust.amount}), @@ -183,14 +183,14 @@ class TrustIsRisk { var input = tx.inputs[0]; if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; - var sender = tx.inputs[0].getAddress().toBase58(); + var origin = tx.inputs[0].getAddress().toBase58(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; - var trustOutputs = this.searchForDirectTrustOutputs(tx, sender); + var trustOutputs = this.searchForDirectTrustOutputs(tx, origin); if (trustOutputs.length !== 1) return null; - var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, sender)).length; + var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, origin)).length; if (changeOutputCount + 1 !== tx.outputs.length) return null; return trustOutputs[0]; @@ -215,8 +215,8 @@ class TrustIsRisk { if (tx.inputs.length !== 1) return nullTrust; - var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getFromEntity(), - prevTrust.getToEntity()); + var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getOriginEntity(), + prevTrust.getDestEntity()); if (trustOutputs.length != 1) return nullTrust; var nextTrust = trustOutputs[0]; @@ -230,46 +230,46 @@ class TrustIsRisk { // Returns a list of the corresponding DirectTrust objects. // If the recipient parameter is set, it will limit the results only to the outputs being sent to // the recipient. - searchForDirectTrustOutputs(tx : bcoin$TX, sender : Entity, recipient : ?Entity) : DirectTrust[] { + searchForDirectTrustOutputs(tx : bcoin$TX, origin : Entity, recipient : ?Entity) : DirectTrust[] { var directTrusts = tx.outputs.map((output, outputIndex) => - this.parseOutputAsDirectTrust(tx, outputIndex, sender) + this.parseOutputAsDirectTrust(tx, outputIndex, origin) ).filter(Boolean); if (recipient) { - directTrusts.filter((trust) => trust.to === recipient); + directTrusts.filter((trust) => trust.dest === recipient); } return directTrusts; } - isChangeOutput(output : bcoin$Output, sender : Entity) : boolean { + isChangeOutput(output : bcoin$Output, origin : Entity) : boolean { return (output.getType() === "pubkeyhash") - && (output.getAddress().toBase58() === sender); + && (output.getAddress().toBase58() === origin); } - parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, sender : Entity) + parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, origin : Entity) : (DirectTrust | null) { var txHash = tx.hash().toString("hex"); var output = tx.outputs[outputIndex]; if (output.getType() !== "multisig") return null; - + var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); if (entities[0] === entities[1]) return null; - var from, to; - if (entities[0] === sender) { - from = output.script.get(1); - to = output.script.get(2); + var originPubKey, destPubKey; + if (entities[0] === origin) { + originPubKey = output.script.get(1); + destPubKey = output.script.get(2); } - else if (entities[1] === sender) { - from = output.script.get(2); - to = output.script.get(1); + else if (entities[1] === origin) { + originPubKey = output.script.get(2); + destPubKey = output.script.get(1); } else return null; return new DirectTrust({ - from, - to, + origin: originPubKey, + dest: destPubKey, amount: Number(output.value), txHash, diff --git a/test/full_node.js b/test/full_node.js index 9ca89a4..f7cdea8 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -125,16 +125,16 @@ describe("FullNode", () => { var graph = require("./graphs/nobodyLikesFrank.json"); var promises = []; - for (var from in graph) { - var neighbours = graph[from]; - for (var to in neighbours) { - var value = neighbours[to]; + for (var origin in graph) { + var neighbours = graph[origin]; + for (var dest in neighbours) { + var value = neighbours[dest]; if (!value || value < 1) continue; - let outpoint = new Outpoint(prevout[from].hash, prevout[from].index); + let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = await node.trust.getTrustIncreasingMTX(rings[from].getPrivateKey(), - rings[to].getPublicKey(), outpoint, value * consensus.COIN); + let mtx = await node.trust.getTrustIncreasingMTX(rings[origin].getPrivateKey(), + rings[dest].getPublicKey(), outpoint, value * consensus.COIN); should(await mtx.verify()); @@ -144,7 +144,7 @@ describe("FullNode", () => { node.sendTX(tx); await testHelpers.time(250); - prevout[from] = {hash: tx.hash().toString("hex"), index: 1}; + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } } //mtxs.forEach((mtx) => node.sendTX(mtx.toTX())); diff --git a/test/helpers.js b/test/helpers.js index 98b906b..ba54e80 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -84,8 +84,8 @@ var testHelpers = { return `0x${Number(data.length).toString(16)} 0x${data.toString("hex")}`; }, - getP2PKHOutput: (to, value) => { - var address = bcoin.primitives.Address.fromBase58(to); + getP2PKHOutput: (dest, value) => { + var address = bcoin.primitives.Address.fromBase58(dest); var script = bcoin.script.fromPubkeyhash(address.hash); return new bcoin.primitives.Output({script, value}); @@ -108,20 +108,20 @@ var testHelpers = { }); }, - getOneOfTwoMultisigOutput: (pubKeyFrom, pubKeyTo, value) => { + getOneOfTwoMultisigOutput: (originPubKey, destPubKey, value) => { return new bcoin.primitives.Output({ - script: bcoin.script.fromMultisig(1, 2, [pubKeyFrom, pubKeyTo]), + script: bcoin.script.fromMultisig(1, 2, [originPubKey, destPubKey]), value }); }, - getTrustIncreasingMTX: (pubKeyFrom, pubKeyTo, value) => { + getTrustIncreasingMTX: (originPubKey, destPubKey, value) => { return new bcoin.primitives.MTX({ inputs: [ - testHelpers.getP2PKHInput(pubKeyFrom) + testHelpers.getP2PKHInput(originPubKey) ], outputs: [ - testHelpers.getOneOfTwoMultisigOutput(pubKeyFrom, pubKeyTo, value) + testHelpers.getOneOfTwoMultisigOutput(originPubKey, destPubKey, value) ] }); }, @@ -129,11 +129,11 @@ var testHelpers = { applyGraph: (tir, fileName, addr) => { var graph = require(fileName); - for (var from in graph) { - var neighbours = graph[from]; - for (var to in neighbours) { - var value = neighbours[to]; - tir.addTX(testHelpers.getTrustIncreasingMTX(addr[from].pubKey, addr[to].pubKey, value).toTX()); + for (var origin in graph) { + var neighbours = graph[origin]; + for (var dest in neighbours) { + var value = neighbours[dest]; + tir.addTX(testHelpers.getTrustIncreasingMTX(addr[origin].pubKey, addr[dest].pubKey, value).toTX()); } } } From 22fa3c4882e31def8428597792317b38d273e513 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 29 May 2017 17:39:50 +0000 Subject: [PATCH 013/540] Add Travis CI --- .travis.yml | 10 ++++++++++ test/full_node.js | 20 +++++++++++--------- test/helpers.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..58524d2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - "7" + +install: + - npm install +script: + - npm run lint + - npm run typecheck + - npm test diff --git a/test/full_node.js b/test/full_node.js index f7cdea8..df82206 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -19,10 +19,12 @@ const COIN = consensus.COIN; describe("FullNode", () => { var node = null; var walletDB = null; + var NodeWatcher = null; sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); beforeEach("get node", () => testHelpers.getNode().then((n) => { node = n; + watcher = new testHelpers.NodeWatcher(node); })); beforeEach("get walletDB", () => testHelpers.getWalletDB(node).then((w) => { @@ -36,21 +38,22 @@ describe("FullNode", () => { var sender = await testHelpers.getWallet(walletDB, "sender"); var receiver = await testHelpers.getWallet(walletDB, "receiver"); + await testHelpers.time(1000); // Produce a block and reward the sender, so that we have a coin to spend. await testHelpers.mineBlock(node, sender.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; - await testHelpers.time(100); + await sender.send({ outputs: [{ value: 10 * COIN, address: receiver.getAddress("base58") }] }); - - await testHelpers.time(100); + await watcher.waitForTX(); + node.trust.addTX.should.be.calledOnce(); }); @@ -74,7 +77,7 @@ describe("FullNode", () => { for(let i = 0; i < coinbaseCoinsCount; i++) { var block = await testHelpers.mineBlock(node, addresses.alice); coinbaseHashes.push(block.txs[0].hash()); - await testHelpers.time(200); + await testHelpers.time(500); } // Alice sends 20 BTC to everyone (including herself) via P2PKH @@ -110,6 +113,8 @@ describe("FullNode", () => { var tx = mtx.toTX(); node.sendTX(tx); + await watcher.waitForTX(); + prevout = {}; testHelpers.names.forEach((name) => { prevout[name] = { @@ -117,7 +122,6 @@ describe("FullNode", () => { index: testHelpers.names.indexOf(name) }; }); - await testHelpers.time(500); // Alice mines another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); @@ -142,13 +146,11 @@ describe("FullNode", () => { // same origin. We therefore need to sleep until the transaction is added to the pool. let tx = mtx.toTX(); node.sendTX(tx); - await testHelpers.time(250); + await watcher.waitForTX(); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } } - //mtxs.forEach((mtx) => node.sendTX(mtx.toTX())); - await testHelpers.time(500); // Alice mines yet another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); @@ -181,7 +183,7 @@ describe("FullNode", () => { should(await mtx.verify()); node.sendTX(mtx.toTX()); - await testHelpers.time(500); + await testHelpers.time(750); should(node.trust.getTrust(addresses.alice, addresses.bob)).equal(7 * COIN); }); }); diff --git a/test/helpers.js b/test/helpers.js index ba54e80..cb19900 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -139,4 +139,48 @@ var testHelpers = { } }; +class NodeWatcher { + constructor(node) { + this.txCount = 0; + this.blockCount = 0; + this.node = node; + this.node.on("tx", this.onTX.bind(this)); + this.node.on("block", this.onBlock.bind(this)); + } + + onTX() { + this.txCount++; + } + + onBlock() { + this.blockCount++; + } + + async waitForBlock(initialCount) { + if (initialCount === undefined) initialCount = this.blockCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.blockCount > initialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } + + async waitForTX(initialCount) { + if (initialCount === undefined) initialCount = this.txCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } +} + +testHelpers.NodeWatcher = NodeWatcher; + module.exports = testHelpers; From 0c7d90d2181709320bcf2c8faf100af471557292 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 29 May 2017 20:42:26 +0100 Subject: [PATCH 014/540] Fix indentation in .eslintrc --- .eslintrc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2597f3d..f8d4494 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,9 +1,9 @@ { - "parser": "babel-eslint", + "parser": "babel-eslint", "plugins": [ "eslint-plugin-flowtype" ], - "env": { + "env": { "es6": true, "node": true }, From 9e2f03c9a90078ccebf915b051f3d536913d07b4 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Tue, 11 Jul 2017 19:13:48 +0000 Subject: [PATCH 015/540] Code review responses --- .eslintrc.json | 2 +- .travis.yml | 4 +- lib/trust_is_risk.js | 11 +- package.json | 2 +- src/trust_is_risk.js | 11 +- test/full_node.js | 76 +++++---- test/helpers.js | 14 +- test/trust_is_risk.js | 360 +++++++++++++++++++++--------------------- 8 files changed, 243 insertions(+), 237 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2597f3d..d39279a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,5 @@ { - "parser": "babel-eslint", + "parser": "babel-eslint", "plugins": [ "eslint-plugin-flowtype" ], diff --git a/.travis.yml b/.travis.yml index 58524d2..9af64ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,4 @@ node_js: install: - npm install script: - - npm run lint - - npm run typecheck - - npm test + - npm run check diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index d13fe7a..1210bd5 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -24,7 +24,7 @@ class TrustIsRisk { this.node.on("tx", this.addTX.bind(this)); } - getTrust(origin , dest ) { + getIndirectTrust(origin , dest ) { return this.db.getTrustAmount(origin, dest); } @@ -46,7 +46,7 @@ class TrustIsRisk { var directTrusts = this.getDirectTrusts(tx); if (directTrusts.length === 0) return false; else { - directTrusts.map(this.db.add.bind(this.db)); + directTrusts.forEach(this.db.add.bind(this.db)); return true; } } @@ -68,12 +68,13 @@ class TrustIsRisk { // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output // payable to the sender. The origin key must be a private key. Any satoshis not spent will be // returned to the sender, minus the fees, via P2PKH. - async getTrustIncreasingMTX(origin , dest , outpoint , + async createTrustIncreasingMTX(origin , dest , outpoint , trustAmount , fee ) { if (!fee) fee = 1000; // TODO: estimate this var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!coin) throw new Error("Could not find coin"); + if (origin === dest) throw new Error("Can not increase self-trust."); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); @@ -112,7 +113,7 @@ class TrustIsRisk { // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. - getTrustDecreasingMTXs(origin , dest , trustDecreaseAmount , payee , + createTrustDecreasingMTXs(origin , dest , trustDecreaseAmount , payee , steal , fee ) { if (steal === undefined) steal = false; @@ -155,7 +156,7 @@ class TrustIsRisk { ], outputs: [new Output({ script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), - value: decreaseAmount - fee + value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) })] }); diff --git a/package.json b/package.json index c08a511..3d8c39a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "blockchain" ], "author": "Decrypto-org", - "license": "ISC", + "license": "MIT", "bugs": { "url": "https://github.com/decrypto-org/TrustIsRisk.js/issues" }, diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index fc1f8ff..565b6f6 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -24,7 +24,7 @@ class TrustIsRisk { this.node.on("tx", this.addTX.bind(this)); } - getTrust(origin : Entity, dest : Entity) { + getIndirectTrust(origin : Entity, dest : Entity) { return this.db.getTrustAmount(origin, dest); } @@ -46,7 +46,7 @@ class TrustIsRisk { var directTrusts = this.getDirectTrusts(tx); if (directTrusts.length === 0) return false; else { - directTrusts.map(this.db.add.bind(this.db)); + directTrusts.forEach(this.db.add.bind(this.db)); return true; } } @@ -68,12 +68,13 @@ class TrustIsRisk { // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output // payable to the sender. The origin key must be a private key. Any satoshis not spent will be // returned to the sender, minus the fees, via P2PKH. - async getTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, + async createTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, fee : ?number) : Promise { if (!fee) fee = 1000; // TODO: estimate this var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!coin) throw new Error("Could not find coin"); + if (origin === dest) throw new Error("Can not increase self-trust."); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); @@ -112,7 +113,7 @@ class TrustIsRisk { // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. - getTrustDecreasingMTXs(origin : Key, dest : Key, trustDecreaseAmount : number, payee : ?Entity, + createTrustDecreasingMTXs(origin : Key, dest : Key, trustDecreaseAmount : number, payee : ?Entity, steal : ?boolean, fee : ?number) : bcoin$MTX[] { if (steal === undefined) steal = false; @@ -155,7 +156,7 @@ class TrustIsRisk { ], outputs: [new Output({ script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), - value: decreaseAmount - fee + value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) })] }); diff --git a/test/full_node.js b/test/full_node.js index df82206..1cb7245 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -12,6 +12,7 @@ var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); var should = require("should"); +var assert = require("assert"); require("should-sinon"); const COIN = consensus.COIN; @@ -20,31 +21,32 @@ describe("FullNode", () => { var node = null; var walletDB = null; var NodeWatcher = null; + var watcher = null; sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); - beforeEach("get node", () => testHelpers.getNode().then((n) => { - node = n; + beforeEach("get node", async () => { + node = await testHelpers.getNode(); watcher = new testHelpers.NodeWatcher(node); - })); + }); - beforeEach("get walletDB", () => testHelpers.getWalletDB(node).then((w) => { - walletDB = w; - })); + beforeEach("get walletDB", async () => { + walletDB = await testHelpers.getWalletDB(node); + }); afterEach("close walletDB", async () => walletDB.close()); afterEach("close node", async () => node.close()); it("should call trust.addTX() on every transaction", async function() { - var sender = await testHelpers.getWallet(walletDB, "sender"); - var receiver = await testHelpers.getWallet(walletDB, "receiver"); + var sender = await testHelpers.createWallet(walletDB, "sender"); + var receiver = await testHelpers.createWallet(walletDB, "receiver"); - await testHelpers.time(1000); + await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. await testHelpers.mineBlock(node, sender.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; - await testHelpers.time(100); + await testHelpers.delay(100); await sender.send({ outputs: [{ @@ -72,27 +74,26 @@ describe("FullNode", () => { // Alice mines three blocks, each rewards her with 50 spendable BTC consensus.COINBASE_MATURITY = 0; - var coinbaseCoinsCount = 3; + var blockCount = 3; var coinbaseHashes = []; - for(let i = 0; i < coinbaseCoinsCount; i++) { + for(let i = 0; i < blockCount; i++) { var block = await testHelpers.mineBlock(node, addresses.alice); coinbaseHashes.push(block.txs[0].hash()); - await testHelpers.time(500); + await testHelpers.delay(500); } // Alice sends 20 BTC to everyone (including herself) via P2PKH var sendAmount = 20; var outputs = testHelpers.names.map((name) => { - return new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160(rings[name].getPublicKey())), - value: sendAmount * consensus.COIN - }); + return testHelpers.getP2PKHOutput( + Address.fromHash(bcoin.crypto.hash160(rings[name].getPublicKey())).toBase58(), + sendAmount * consensus.COIN); }); // We have to use a change output, because transaction with too large a fee are considered // invalid. var fee = 0.01; - var changeAmount = 50 * coinbaseCoinsCount - sendAmount * testHelpers.names.length - fee; + var changeAmount = 50 * blockCount - sendAmount * testHelpers.names.length - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ script: Script.fromPubkeyhash(bcoin.crypto.hash160(rings.alice.getPublicKey())), @@ -108,8 +109,8 @@ describe("FullNode", () => { coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); var signedCount = mtx.sign(rings.alice); - signedCount.should.equal(coinbaseCoinsCount); - should(await mtx.verify()); + assert(signedCount === blockCount); + assert(await mtx.verify()); var tx = mtx.toTX(); node.sendTX(tx); @@ -125,10 +126,9 @@ describe("FullNode", () => { // Alice mines another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); - await testHelpers.time(500); + await testHelpers.delay(500); var graph = require("./graphs/nobodyLikesFrank.json"); - var promises = []; for (var origin in graph) { var neighbours = graph[origin]; for (var dest in neighbours) { @@ -137,13 +137,11 @@ describe("FullNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = await node.trust.getTrustIncreasingMTX(rings[origin].getPrivateKey(), + let mtx = await node.trust.createTrustIncreasingMTX(rings[origin].getPrivateKey(), rings[dest].getPublicKey(), outpoint, value * consensus.COIN); - should(await mtx.verify()); + assert(await mtx.verify()); - // The change output from this transaction will be used in other transactions from the - // same origin. We therefore need to sleep until the transaction is added to the pool. let tx = mtx.toTX(); node.sendTX(tx); await watcher.waitForTX(); @@ -154,7 +152,7 @@ describe("FullNode", () => { // Alice mines yet another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); - await testHelpers.time(500); + await testHelpers.delay(500); }); it("computes trusts correctly", () => { @@ -162,20 +160,20 @@ describe("FullNode", () => { eval(`var ${name} = "${addresses[name]}";`); } - should(node.trust.getTrust(alice, alice)).equal(Infinity); - should(node.trust.getTrust(alice, bob)).equal(10 * COIN); - should(node.trust.getTrust(alice, charlie)).equal(1 * COIN); - should(node.trust.getTrust(alice, frank)).equal(0); - should(node.trust.getTrust(alice, eve)).equal(6 * COIN); + should(node.trust.getIndirectTrust(alice, alice)).equal(Infinity); + should(node.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); + should(node.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); + should(node.trust.getIndirectTrust(alice, frank)).equal(0); + should(node.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); - should(node.trust.getTrust(bob, alice)).equal(1 * COIN); - should(node.trust.getTrust(bob, eve)).equal(3 * COIN); - should(node.trust.getTrust(dave, eve)).equal(12 * COIN); - should(node.trust.getTrust(george, eve)).equal(0); + should(node.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); + should(node.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); + should(node.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); + should(node.trust.getIndirectTrust(george, eve)).equal(0); }); it("after decreasing some trusts computes trusts correctly", async () => { - var mtxs = node.trust.getTrustDecreasingMTXs(rings.alice.getPrivateKey(), + var mtxs = node.trust.createTrustDecreasingMTXs(rings.alice.getPrivateKey(), rings.bob.getPublicKey(), 3 * COIN); mtxs.length.should.equal(1); var mtx = mtxs[0]; @@ -183,8 +181,8 @@ describe("FullNode", () => { should(await mtx.verify()); node.sendTX(mtx.toTX()); - await testHelpers.time(750); - should(node.trust.getTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + await testHelpers.delay(750); + should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); }); }); }); diff --git a/test/helpers.js b/test/helpers.js index cb19900..02bcd68 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,8 +7,8 @@ var assert = require("assert"); var testHelpers = { names: ["alice", "bob", "charlie", "dave", "eve", "frank", "george"], rings: [ - "02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c0", - "2437025954568a8273968aa7535dbfc444fd8f8d0f5237cd96ac7234c77810ad", + "02B8F07A401ECA4888039B1898F94DB44C43CCC6D3AA8B27E9B6ED7B377B24C0", + "2437025954568A8273968AA7535DBFC444FD8F8D0F5237CD96AC7234C77810AD", "3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD7", "19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F3", "0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A", @@ -57,7 +57,7 @@ var testHelpers = { return walletDB; }, - getWallet: async (walletDB, id) => { + createWallet: async (walletDB, id) => { var options = { id, passphrase: "secret", @@ -71,10 +71,12 @@ var testHelpers = { mineBlock: async (node, rewardAddress) => { var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); await node.chain.add(block); + // node.chain.tip does not contain all the properties we want, + // so we need to fetch it: return node.getBlock(node.chain.tip.hash); }, - time: async (milliseconds) => { + delay: async (milliseconds) => { return new Promise((resolve, reject) => { setTimeout(resolve, milliseconds); }); @@ -126,14 +128,14 @@ var testHelpers = { }); }, - applyGraph: (tir, fileName, addr) => { + applyGraph: (trust, fileName, addressBook) => { var graph = require(fileName); for (var origin in graph) { var neighbours = graph[origin]; for (var dest in neighbours) { var value = neighbours[dest]; - tir.addTX(testHelpers.getTrustIncreasingMTX(addr[origin].pubKey, addr[dest].pubKey, value).toTX()); + trust.addTX(testHelpers.getTrustIncreasingMTX(addressBook[origin].pubKey, addressBook[dest].pubKey, value).toTX()); } } } diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index ab2b12a..e0abb54 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -68,9 +68,13 @@ describe("TrustIsRisk", () => { describe("with a non-TIR transaction", () => { it("does not change trust", () => { trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); - tir.parseTXAsTrustIncrease(trustIncreasingMTX.toTX()); + tir.addTX(trustIncreasingMTX.toTX()); tir.getDirectTrust(alice, bob).should.equal(0); + tir.getDirectTrust(bob, alice).should.equal(0); + tir.getDirectTrust(alice, charlie).should.equal(0); + tir.getDirectTrust(charlie, alice).should.equal(0); + tir.getDirectTrust(charlie, dave).should.equal(0); }); }); @@ -80,6 +84,7 @@ describe("TrustIsRisk", () => { tir.getDirectTrust(alice, bob).should.equal(42 * COIN); tir.getDirectTrust(bob, alice).should.equal(0); + tir.getDirectTrust(charlie, dave).should.equal(0); }); it("which has more than one input does not change trust", () => { @@ -119,6 +124,7 @@ describe("TrustIsRisk", () => { var tx = trustIncreasingMTX.toTX(); should(tir.addTX(tx)); should.throws(() => tir.addTX(tx), /already processed/i); + tir.getDirectTrust(alice, bob).should.equal(42 * COIN); }); }); @@ -148,208 +154,208 @@ describe("TrustIsRisk", () => { tir.getDirectTrust(alice, bob).should.equal(0); }); }); + }); - describe(".getTrustIncreasingMTX()", () => { - it("creates valid trust-increasing transactions", async () => { - var getTXStub = sinon.stub(node, "getCoin"); + describe(".createTrustIncreasingMTX()", () => { + it("creates valid trust-increasing transactions", async () => { + var getTXStub = sinon.stub(node, "getCoin"); - var prevOutput = { - hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", - index: 1 - }; + var prevOutput = { + hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", + index: 1 + }; - getTXStub.withArgs(prevOutput.hash).returns(new Coin({ - script: testHelpers.getP2PKHOutput(alice, 1).script, - value: 1000 * COIN - })); + getTXStub.withArgs(prevOutput.hash).returns(new Coin({ + script: testHelpers.getP2PKHOutput(alice, 1).script, + value: 1000 * COIN + })); - var mtx = await tir.getTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, - 100 * COIN); + var mtx = await tir.createTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, + 100 * COIN); - mtx.inputs.length.should.equal(1); + mtx.inputs.length.should.equal(1); - mtx.outputs.length.should.equal(2); + mtx.outputs.length.should.equal(2); - var trustOutput = mtx.outputs[0]; - trustOutput.getType().should.equal("multisig"); - [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() - .should.deepEqual([alice, bob].sort()); - trustOutput.value.should.equal(100 * COIN); + var trustOutput = mtx.outputs[0]; + trustOutput.getType().should.equal("multisig"); + [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() + .should.deepEqual([alice, bob].sort()); + trustOutput.value.should.equal(100 * COIN); - var changeOutput = mtx.outputs[1]; - changeOutput.getType().should.equal("pubkeyhash"); - changeOutput.getAddress().toBase58().should.equal(alice); - changeOutput.value.should.equal(900 * COIN - 1000); - }); + var changeOutput = mtx.outputs[1]; + changeOutput.getType().should.equal("pubkeyhash"); + changeOutput.getAddress().toBase58().should.equal(alice); + changeOutput.value.should.equal(900 * COIN - 1000); }); + }); - describe(".getTrustDecreasingMTX()", () => { - var trustTXs; - beforeEach(() => { - var tx; - trustTXs = []; + describe(".getTrustDecreasingMTX()", () => { + var trustTXs; + beforeEach(() => { + var tx; + trustTXs = []; - tx = trustIncreasingTX; - trustTXs.push(tx); - tir.addTX(tx); + tx = trustIncreasingTX; + trustTXs.push(tx); + tir.addTX(tx); - trustIncreasingMTX.outputs[0].value = 100 * COIN; - tx = trustIncreasingMTX.toTX(); - trustTXs.push(tx); - tir.addTX(tx); + trustIncreasingMTX.outputs[0].value = 100 * COIN; + tx = trustIncreasingMTX.toTX(); + trustTXs.push(tx); + tir.addTX(tx); - trustIncreasingMTX.outputs[0].value = 500 * COIN; - tx = trustIncreasingMTX.toTX(); - trustTXs.push(tx); - tir.addTX(tx); + trustIncreasingMTX.outputs[0].value = 500 * COIN; + tx = trustIncreasingMTX.toTX(); + trustTXs.push(tx); + tir.addTX(tx); - // Total trust 642 BTC - }); + // Total trust 642 BTC + }); - // Helper specific to the next couple of tests: - // Checks that mtxs is a list of two trust decreasing transactions. The first one spends the - // entire first trust increasing transaction, and the second spends part of the second. - // Also checks that the reduced trust is sent via P2PKH outputs to the correct recipient. - var checkMTXs = (mtxs, recipient) => { - mtxs.length.should.equal(2); - - var mtx = mtxs[0]; - - mtx.inputs.length.should.equal(1); - mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[0].hash().toString("hex"), - index: 0 - }); - - mtx.outputs.length.should.equal(1); // Single P2PKH output - mtx.outputs[0].getType().should.equal("pubkeyhash"); - mtx.outputs[0].getAddress().toBase58().should.equal(recipient); - mtx.outputs[0].value.should.equal(42 * COIN - 1000); - - mtx = mtxs[1]; - - mtx.inputs.length.should.equal(1); - mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[1].hash().toString("hex"), - index: 0 - }); - - mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output - mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); - mtx.outputs[1].value.should.equal(60 * COIN); - mtx.outputs[0].getType().should.equal("pubkeyhash"); - mtx.outputs[0].getAddress().toBase58().should.equal(recipient); - mtx.outputs[0].value.should.equal(40 * COIN - 1000); - }; + // Helper specific to the next couple of tests: + // Checks that mtxs is a list of two trust decreasing transactions. The first one spends the + // entire first trust increasing transaction, and the second spends part of the second. + // Also checks that the reduced trust is sent via P2PKH outputs to the correct recipient. + var checkMTXs = (mtxs, recipient) => { + mtxs.length.should.equal(2); - it("creates correct trust decreasing transactions", () => { - var mtxs = tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); - checkMTXs(mtxs, alice); - }); + var mtx = mtxs[0]; - it("creates correct trust stealing transactions", () => { - var mtxs = tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); - checkMTXs(mtxs, charlie); + mtx.inputs.length.should.equal(1); + mtx.inputs[0].prevout.should.have.properties({ + hash: trustTXs[0].hash().toString("hex"), + index: 0 }); - it("throws when trying to decrease self-trust", () => { - should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) - , /self-trust/i); - }); + mtx.outputs.length.should.equal(1); // Single P2PKH output + mtx.outputs[0].getType().should.equal("pubkeyhash"); + mtx.outputs[0].getAddress().toBase58().should.equal(recipient); + mtx.outputs[0].value.should.equal(42 * COIN - 1000); - it("throws when there is not enough trust", () => { - should.throws(() => tir.getTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) - , /insufficient trust/i); - + mtx = mtxs[1]; + + mtx.inputs.length.should.equal(1); + mtx.inputs[0].prevout.should.have.properties({ + hash: trustTXs[1].hash().toString("hex"), + index: 0 }); + + mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output + mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); + mtx.outputs[1].value.should.equal(60 * COIN); + mtx.outputs[0].getType().should.equal("pubkeyhash"); + mtx.outputs[0].getAddress().toBase58().should.equal(recipient); + mtx.outputs[0].value.should.equal(40 * COIN - 1000); + }; + + it("creates correct trust decreasing transactions", () => { + var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); + checkMTXs(mtxs, alice); + }); + + it("creates correct trust stealing transactions", () => { + var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); + checkMTXs(mtxs, charlie); + }); + + it("throws when trying to decrease self-trust", () => { + should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) + , /self-trust/i); + }); + + it("throws when there is not enough trust", () => { + should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) + , /insufficient trust/i); + }); + }); - describe(".getTrust()", () => { - it("returns zero for two arbitary parties that do not trust each other", () => { - should(tir.getTrust(alice, bob)).equal(0); - should(tir.getTrust(bob, alice)).equal(0); - should(tir.getTrust(charlie, alice)).equal(0); - should(tir.getTrust(alice, charlie)).equal(0); - }); - - it("returns Infinity for one's trust to themselves", () => { - should(tir.getTrust(alice, alice)).equal(Infinity); - should(tir.getTrust(bob, bob)).equal(Infinity); + describe(".getIndirectTrust()", () => { + it("returns zero for two arbitary parties that do not trust each other", () => { + should(tir.getIndirectTrust(alice, bob)).equal(0); + should(tir.getIndirectTrust(bob, alice)).equal(0); + should(tir.getIndirectTrust(charlie, alice)).equal(0); + should(tir.getIndirectTrust(alice, charlie)).equal(0); + }); + + it("returns Infinity for one's trust to themselves", () => { + should(tir.getIndirectTrust(alice, alice)).equal(Infinity); + should(tir.getIndirectTrust(bob, bob)).equal(Infinity); + }); + + describe("after applying the Nobody Likes Frank graph example", () => { + beforeEach(() => { + testHelpers.applyGraph(tir, "./graphs/nobodyLikesFrank.json", addr); }); - describe("after applying the Nobody Likes Frank graph example", () => { - beforeEach(() => { - testHelpers.applyGraph(tir, "./graphs/nobodyLikesFrank.json", addr); - }); - - it("correctly computes trusts", () => { - should(tir.getTrust(alice, alice)).equal(Infinity); - should(tir.getTrust(alice, bob)).equal(10); - should(tir.getTrust(alice, charlie)).equal(1); - should(tir.getTrust(alice, dave)).equal(4); - should(tir.getTrust(alice, eve)).equal(6); - should(tir.getTrust(alice, frank)).equal(0); - should(tir.getTrust(alice, george)).equal(2); - - should(tir.getTrust(bob, alice)).equal(1); - should(tir.getTrust(bob, bob)).equal(Infinity); - should(tir.getTrust(bob, charlie)).equal(1); - should(tir.getTrust(bob, dave)).equal(1); - should(tir.getTrust(bob, eve)).equal(3); - should(tir.getTrust(bob, frank)).equal(0); - should(tir.getTrust(bob, george)).equal(2); - - should(tir.getTrust(charlie, alice)).equal(0); - should(tir.getTrust(charlie, bob)).equal(0); - should(tir.getTrust(charlie, charlie)).equal(Infinity); - should(tir.getTrust(charlie, dave)).equal(0); - should(tir.getTrust(charlie, eve)).equal(0); - should(tir.getTrust(charlie, frank)).equal(0); - should(tir.getTrust(charlie, george)).equal(3); - - should(tir.getTrust(dave, alice)).equal(2); - should(tir.getTrust(dave, bob)).equal(2); - should(tir.getTrust(dave, charlie)).equal(1); - should(tir.getTrust(dave, dave)).equal(Infinity); - should(tir.getTrust(dave, eve)).equal(12); - should(tir.getTrust(dave, frank)).equal(0); - should(tir.getTrust(dave, george)).equal(2); - - should(tir.getTrust(eve, alice)).equal(0); - should(tir.getTrust(eve, bob)).equal(0); - should(tir.getTrust(eve, charlie)).equal(0); - should(tir.getTrust(eve, dave)).equal(0); - should(tir.getTrust(eve, eve)).equal(Infinity); - should(tir.getTrust(eve, frank)).equal(0); - should(tir.getTrust(eve, george)).equal(0); - - should(tir.getTrust(frank, alice)).equal(0); - should(tir.getTrust(frank, bob)).equal(0); - should(tir.getTrust(frank, charlie)).equal(10); - should(tir.getTrust(frank, dave)).equal(0); - should(tir.getTrust(frank, eve)).equal(0); - should(tir.getTrust(frank, frank)).equal(Infinity); - should(tir.getTrust(frank, george)).equal(3); - - should(tir.getTrust(george, alice)).equal(0); - should(tir.getTrust(george, bob)).equal(0); - should(tir.getTrust(george, charlie)).equal(0); - should(tir.getTrust(george, dave)).equal(0); - should(tir.getTrust(george, eve)).equal(0); - should(tir.getTrust(george, frank)).equal(0); - should(tir.getTrust(george, george)).equal(Infinity); - }); - - it("correctly computes trusts when bob trusts frank", () => { - tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); - should(tir.getTrust(george, frank)).equal(0); - should(tir.getTrust(alice, frank)).equal(8); - should(tir.getTrust(dave, frank)).equal(2); - should(tir.getTrust(bob, frank)).equal(8); - }); - - // TODO: Decrement direct trusts and test that indirect trusts update correctly + it("correctly computes trusts", () => { + should(tir.getIndirectTrust(alice, alice)).equal(Infinity); + should(tir.getIndirectTrust(alice, bob)).equal(10); + should(tir.getIndirectTrust(alice, charlie)).equal(1); + should(tir.getIndirectTrust(alice, dave)).equal(4); + should(tir.getIndirectTrust(alice, eve)).equal(6); + should(tir.getIndirectTrust(alice, frank)).equal(0); + should(tir.getIndirectTrust(alice, george)).equal(2); + + should(tir.getIndirectTrust(bob, alice)).equal(1); + should(tir.getIndirectTrust(bob, bob)).equal(Infinity); + should(tir.getIndirectTrust(bob, charlie)).equal(1); + should(tir.getIndirectTrust(bob, dave)).equal(1); + should(tir.getIndirectTrust(bob, eve)).equal(3); + should(tir.getIndirectTrust(bob, frank)).equal(0); + should(tir.getIndirectTrust(bob, george)).equal(2); + + should(tir.getIndirectTrust(charlie, alice)).equal(0); + should(tir.getIndirectTrust(charlie, bob)).equal(0); + should(tir.getIndirectTrust(charlie, charlie)).equal(Infinity); + should(tir.getIndirectTrust(charlie, dave)).equal(0); + should(tir.getIndirectTrust(charlie, eve)).equal(0); + should(tir.getIndirectTrust(charlie, frank)).equal(0); + should(tir.getIndirectTrust(charlie, george)).equal(3); + + should(tir.getIndirectTrust(dave, alice)).equal(2); + should(tir.getIndirectTrust(dave, bob)).equal(2); + should(tir.getIndirectTrust(dave, charlie)).equal(1); + should(tir.getIndirectTrust(dave, dave)).equal(Infinity); + should(tir.getIndirectTrust(dave, eve)).equal(12); + should(tir.getIndirectTrust(dave, frank)).equal(0); + should(tir.getIndirectTrust(dave, george)).equal(2); + + should(tir.getIndirectTrust(eve, alice)).equal(0); + should(tir.getIndirectTrust(eve, bob)).equal(0); + should(tir.getIndirectTrust(eve, charlie)).equal(0); + should(tir.getIndirectTrust(eve, dave)).equal(0); + should(tir.getIndirectTrust(eve, eve)).equal(Infinity); + should(tir.getIndirectTrust(eve, frank)).equal(0); + should(tir.getIndirectTrust(eve, george)).equal(0); + + should(tir.getIndirectTrust(frank, alice)).equal(0); + should(tir.getIndirectTrust(frank, bob)).equal(0); + should(tir.getIndirectTrust(frank, charlie)).equal(10); + should(tir.getIndirectTrust(frank, dave)).equal(0); + should(tir.getIndirectTrust(frank, eve)).equal(0); + should(tir.getIndirectTrust(frank, frank)).equal(Infinity); + should(tir.getIndirectTrust(frank, george)).equal(3); + + should(tir.getIndirectTrust(george, alice)).equal(0); + should(tir.getIndirectTrust(george, bob)).equal(0); + should(tir.getIndirectTrust(george, charlie)).equal(0); + should(tir.getIndirectTrust(george, dave)).equal(0); + should(tir.getIndirectTrust(george, eve)).equal(0); + should(tir.getIndirectTrust(george, frank)).equal(0); + should(tir.getIndirectTrust(george, george)).equal(Infinity); }); + + it("correctly computes trusts when bob trusts frank", () => { + tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); + should(tir.getIndirectTrust(george, frank)).equal(0); + should(tir.getIndirectTrust(alice, frank)).equal(8); + should(tir.getIndirectTrust(dave, frank)).equal(2); + should(tir.getIndirectTrust(bob, frank)).equal(8); + }); + + // TODO: Decrement direct trusts and test that indirect trusts update correctly }); }); }); From d9d073a3f9d8ec0b43050c9fd70754120de01b40 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 11 Sep 2017 22:13:29 +0000 Subject: [PATCH 016/540] Move fixtures to separate fixtures file. --- lib/trust_is_risk.js | 1 + src/trust_is_risk.js | 1 + test/fixtures.js | 23 +++++++++++++++++++++++ test/full_node.js | 41 +++++++++++++++++++++++------------------ test/helpers.js | 30 +----------------------------- test/trust_is_risk.js | 18 +++++++++++++++--- 6 files changed, 64 insertions(+), 50 deletions(-) create mode 100644 test/fixtures.js diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js index 1210bd5..8bec28d 100644 --- a/lib/trust_is_risk.js +++ b/lib/trust_is_risk.js @@ -89,6 +89,7 @@ class TrustIsRisk { }); var changeAmount = coin.value - trustAmount - fee; + assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 565b6f6..07d79c8 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -89,6 +89,7 @@ class TrustIsRisk { }); var changeAmount = coin.value - trustAmount - fee; + assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), diff --git a/test/fixtures.js b/test/fixtures.js new file mode 100644 index 0000000..a11f021 --- /dev/null +++ b/test/fixtures.js @@ -0,0 +1,23 @@ +var bcoin = require("bcoin"); +var KeyRing = bcoin.primitives.KeyRing; + +var privateKeys = { + "alice": "02B8F07A401ECA4888039B1898F94DB44C43CCC6D3AA8B27E9B6ED7B377B24C0", + "bob": "2437025954568A8273968AA7535DBFC444FD8F8D0F5237CD96AC7234C77810AD", + "charlie": "3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD7", + "dave": "19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F3", + "eve": "0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A", + "frank": "878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D45", + "george": "1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A" +}; + +var keyRings = {}; +for (let name in privateKeys) { + let key = privateKeys[name]; + keyRings[name] = KeyRing.fromPrivate(new Buffer(key, "hex")); +} + +module.exports = { + keyRings, + names: Object.keys(keyRings) +}; diff --git a/test/full_node.js b/test/full_node.js index 1cb7245..051c371 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -13,6 +13,7 @@ var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); var should = require("should"); var assert = require("assert"); +var fixtures = require("./fixtures"); require("should-sinon"); const COIN = consensus.COIN; @@ -64,12 +65,9 @@ describe("FullNode", () => { beforeEach("apply graph transactions", async () => { addresses = {}; - rings = {}; - for (let i = 0; i < testHelpers.names.length; i++) { - var name = testHelpers.names[i]; - rings[name] = testHelpers.rings[i]; - addresses[name] = helpers.pubKeyToEntity(rings[name].getPublicKey()); + for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { + addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); } // Alice mines three blocks, each rewards her with 50 spendable BTC @@ -84,19 +82,21 @@ describe("FullNode", () => { // Alice sends 20 BTC to everyone (including herself) via P2PKH var sendAmount = 20; - var outputs = testHelpers.names.map((name) => { + var outputs = fixtures.names.map((name) => { return testHelpers.getP2PKHOutput( - Address.fromHash(bcoin.crypto.hash160(rings[name].getPublicKey())).toBase58(), + Address.fromHash(bcoin.crypto.hash160(fixtures.keyRings[name].getPublicKey())) + .toBase58(), sendAmount * consensus.COIN); }); // We have to use a change output, because transaction with too large a fee are considered // invalid. var fee = 0.01; - var changeAmount = 50 * blockCount - sendAmount * testHelpers.names.length - fee; + var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160(rings.alice.getPublicKey())), + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + fixtures.keyRings.alice.getPublicKey())), value: changeAmount * consensus.COIN })); } @@ -108,7 +108,7 @@ describe("FullNode", () => { var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); - var signedCount = mtx.sign(rings.alice); + var signedCount = mtx.sign(fixtures.keyRings.alice); assert(signedCount === blockCount); assert(await mtx.verify()); @@ -117,15 +117,16 @@ describe("FullNode", () => { await watcher.waitForTX(); prevout = {}; - testHelpers.names.forEach((name) => { + fixtures.names.forEach((name) => { prevout[name] = { hash: tx.hash().toString("hex"), - index: testHelpers.names.indexOf(name) + index: fixtures.names.indexOf(name) }; }); // Alice mines another block - await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); + await testHelpers.mineBlock(node, helpers.pubKeyToEntity( + fixtures.keyRings.alice.getPublicKey())); await testHelpers.delay(500); var graph = require("./graphs/nobodyLikesFrank.json"); @@ -137,8 +138,11 @@ describe("FullNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = await node.trust.createTrustIncreasingMTX(rings[origin].getPrivateKey(), - rings[dest].getPublicKey(), outpoint, value * consensus.COIN); + let mtx = await node.trust.createTrustIncreasingMTX( + fixtures.keyRings[origin].getPrivateKey(), + fixtures.keyRings[dest].getPublicKey(), + outpoint, + value * consensus.COIN); assert(await mtx.verify()); @@ -151,7 +155,8 @@ describe("FullNode", () => { } // Alice mines yet another block - await testHelpers.mineBlock(node, helpers.pubKeyToEntity(rings.alice.getPublicKey())); + await testHelpers.mineBlock(node, helpers.pubKeyToEntity( + fixtures.keyRings.alice.getPublicKey())); await testHelpers.delay(500); }); @@ -173,8 +178,8 @@ describe("FullNode", () => { }); it("after decreasing some trusts computes trusts correctly", async () => { - var mtxs = node.trust.createTrustDecreasingMTXs(rings.alice.getPrivateKey(), - rings.bob.getPublicKey(), 3 * COIN); + var mtxs = node.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), + fixtures.keyRings.bob.getPublicKey(), 3 * COIN); mtxs.length.should.equal(1); var mtx = mtxs[0]; diff --git a/test/helpers.js b/test/helpers.js index 02bcd68..855c1de 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,39 +1,11 @@ var TrustIsRisk = require("../"); var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); +var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); var testHelpers = { - names: ["alice", "bob", "charlie", "dave", "eve", "frank", "george"], - rings: [ - "02B8F07A401ECA4888039B1898F94DB44C43CCC6D3AA8B27E9B6ED7B377B24C0", - "2437025954568A8273968AA7535DBFC444FD8F8D0F5237CD96AC7234C77810AD", - "3BBA2AF9539D09B4FD2BDEA1D3A2CE4BF5D779831B8781EE2ACF9C03378B2AD7", - "19BD8D853FAEFDB9B01E4DE7F6096FF8F5F96D43E6564A5258307334A4AA59F3", - "0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A", - "878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D45", - "1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A" - ].map((key) => KeyRing.fromPrivate(new Buffer(key, "hex"))), - - getAddressFixtures: () => { - assert(testHelpers.rings.length === testHelpers.names.length); - - var addr = {}; - for (var i = 0; i < testHelpers.names.length; i++) { - var name = testHelpers.names[i]; - var pubKey = testHelpers.rings[i].getPublicKey(); - var privKey = testHelpers.rings[i].getPrivateKey(); - - addr[name] = {}; - addr[name].pubKey = pubKey; - addr[name].privKey = privKey; - addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(pubKey)).toString(); - } - - return addr; - }, - getNode: async () => { var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index e0abb54..a4085fa 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -9,15 +9,27 @@ var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); var should = require("should"); +var fixtures = require("./fixtures"); require("should-sinon"); const COIN = bcoin.consensus.COIN; describe("TrustIsRisk", () => { - var addr = testHelpers.getAddressFixtures(); + var addr = {}; + for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { + var pubKey = keyRing.getPublicKey(); + var privKey = keyRing.getPrivateKey(); + + addr[name] = {}; + addr[name].pubKey = pubKey; + addr[name].privKey = privKey; + addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(pubKey)).toString(); + } + // Add base58 address variables to scope. - for (name in addr) { - eval(`var ${name} = "${addr[name].base58}";`); + for (name in fixtures.keyRings) { + var keyRing = fixtures.keyRings[name]; + eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); } var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; From 8df2ff57eb88fc64c5421b739734acab72a79222 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 11 Sep 2017 22:30:32 +0000 Subject: [PATCH 017/540] Remove compiled files from repo; Minor code review fixes --- .gitignore | 1 + lib/direct_trust.js | 106 ---------------- lib/full_node.js | 14 --- lib/helpers.js | 12 -- lib/index.js | 5 - lib/trust_db.js | 120 ------------------ lib/trust_is_risk.js | 284 ------------------------------------------- lib/types.js | 8 -- src/trust_db.js | 5 - test/full_node.js | 4 + 10 files changed, 5 insertions(+), 554 deletions(-) delete mode 100644 lib/direct_trust.js delete mode 100644 lib/full_node.js delete mode 100644 lib/helpers.js delete mode 100644 lib/index.js delete mode 100644 lib/trust_db.js delete mode 100644 lib/trust_is_risk.js delete mode 100644 lib/types.js diff --git a/.gitignore b/.gitignore index a6ec74b..b4e253f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ +lib/ *.swp diff --git a/lib/direct_trust.js b/lib/direct_trust.js deleted file mode 100644 index 0656934..0000000 --- a/lib/direct_trust.js +++ /dev/null @@ -1,106 +0,0 @@ -// - - -var assert = require("assert"); -var helpers = require("./helpers"); - - - - - - - - - - - - - - -class DirectTrust { - - - - - // Every DT is associated with a transaction output, except for non-standard trust decreasing - // transactions, which reduce trust to zero and are related to a whole transaction and not - // a specific output. - - - - - - - - constructor(options ) { - this.outputIndex = null; - this.script = null; - this.prev = null; - this.next = null; - Object.assign(this, options); - } - - isNull() { - return this.amount === 0; - } - - isIncrease() { - return this.prev === null; - } - - isDecrease() { - return !this.isIncrease(); - } - - isSpent() { - return this.next !== null; - } - - isSpendable() { - return !this.isSpent() && !this.isNull(); - } - - isValid() { - // TODO: Consider removing this function and ensure validity at build time by using the flow - // type system, possibly by creating sub-types like "IncreasingDirectTrust" etc. - var valid = true; - - if ((this.outputIndex === null) !== (this.script === null)) valid = false; - if (this.outputIndex === null && this.isIncrease()) valid = false; - if (this.outputIndex === null && this.amount > 0) valid = false; - if (this.isIncrease() && this.isNull()) valid = false; - if (this.isSpent() && this.isNull()) valid = false; - - return valid; - } - - getOriginEntity() { - return helpers.pubKeyToEntity(this.origin); - } - - getDestEntity() { - return helpers.pubKeyToEntity(this.dest); - } - - spend(next ) { - assert(!this.isSpent()); - assert(this.origin.equals(next.origin) && this.dest.equals(next.dest)); - assert(next.amount <= this.amount); - - this.next = next; - next.prev = this; - } - - getNullifying(txHash ) { - return new DirectTrust({ - origin: this.origin, - dest: this.dest, - amount: 0, - - prev: this, - txHash, - }); - } -} - -module.exports = DirectTrust; diff --git a/lib/full_node.js b/lib/full_node.js deleted file mode 100644 index 3525254..0000000 --- a/lib/full_node.js +++ /dev/null @@ -1,14 +0,0 @@ -// -var bcoin = require("bcoin"); -var TrustIsRisk = require("./trust_is_risk"); - -class FullNode extends bcoin.fullnode { - - - constructor(options ) { - super(options); - this.trust = new TrustIsRisk(this); - } -} - -module.exports = FullNode; diff --git a/lib/helpers.js b/lib/helpers.js deleted file mode 100644 index a345715..0000000 --- a/lib/helpers.js +++ /dev/null @@ -1,12 +0,0 @@ -// - -var bcoin = require("bcoin"); -var Address = bcoin.primitives.Address; - -var helpers = { - pubKeyToEntity: (key ) => { - return Address.fromHash(bcoin.crypto.hash160(key)).toBase58(); - } -}; - -module.exports = helpers; diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 824eb06..0000000 --- a/lib/index.js +++ /dev/null @@ -1,5 +0,0 @@ -// -module.exports = { - FullNode: require("./full_node"), - TrustIsRisk: require("./trust_is_risk") -}; diff --git a/lib/trust_db.js b/lib/trust_db.js deleted file mode 100644 index d894ed1..0000000 --- a/lib/trust_db.js +++ /dev/null @@ -1,120 +0,0 @@ -// - -var assert = require("assert"); -var SortedSet = require("sorted-set"); -var maxFlow = require("graph-theory-ford-fulkerson"); -var bcoin = require("bcoin"); -var Address = bcoin.primitives.Address; -var KeyRing = bcoin.primitives.KeyRing; -var MTX = bcoin.primitives.MTX; -var Input = bcoin.primitives.Input; -var Output = bcoin.primitives.Output; -var Outpoint = bcoin.primitives.Outpoint; -var DirectTrust = require("./direct_trust"); - -class TrustDB { - - - - - constructor() { - this.directTrusts = new Map(); - this.txToDirectTrust = new Map(); - this.entities = new SortedSet(); - } - - getDirectTrustByTX(txHash ) { - if (!this.isTrustTX(txHash)) return null; - return ((this.txToDirectTrust.get(txHash) ) ); - } - - getDirectTrustByOutpoint(outpoint ) { - var trust = this.txToDirectTrust.get(outpoint.hash.toString("hex")); - if (!trust) return null; - if (trust.outputIndex !== outpoint.index) return null; - return trust; - } - - getDirectTrustAmount(origin , dest ) { - if (origin === dest) return Infinity; - - var trusts = this.getSpendableDirectTrusts(origin, dest); - return trusts.reduce((sum, t) => sum + t.amount, 0); - } - - getSpendableDirectTrusts(origin , dest ) { - return this.getDirectTrusts(origin, dest).filter((t) => t.isSpendable()); - } - - getDirectTrusts(origin , dest ) { - var originMap = this.directTrusts.get(origin); - if (!originMap) return []; - - var trusts = originMap.get(dest); - if (!trusts) return []; - - return trusts; - } - - getGraphWeightMatrix() { - var entitiesArr = this.getEntities(); - return entitiesArr.map((origin) => { - return entitiesArr.map((dest) => this.getDirectTrustAmount(origin, dest)); - }); - } - - getTrustAmount(origin , dest ) { - // TODO: Optimize - if (origin === dest) return Infinity; - - var graph = this.getGraphWeightMatrix(); - var originIndex = this.getEntityIndex(origin); - var destIndex = this.getEntityIndex(dest); - - if (originIndex === -1 || destIndex === -1) return 0; - else return maxFlow(graph, originIndex, destIndex); - } - - getEntities() { - return this.entities.slice(0, this.entities.length); - } - - getEntityIndex(entity ) { - return this.entities.rank(entity); - } - - isTrustTX(txHash ) { - return this.txToDirectTrust.has(txHash); - } - - isTrustOutput(txHash , outputIndex ) { - var trust = this.txToDirectTrust.get(txHash); - return trust !== undefined && trust.outputIndex === outputIndex; - } - - add(trust ) { - var origin = trust.getOriginEntity(); - var dest = trust.getDestEntity(); - assert(origin !== dest); - - if (!this.directTrusts.has(origin)) this.directTrusts.set(origin, new Map()); - var originMap = ((this.directTrusts.get(origin) ) ); - - if (!originMap.has(dest)) originMap.set(dest, []); - var trusts = ((originMap.get(dest) ) ); - - if (trust.prev !== null) { - trust.prev.spend(trust); - assert(trust.prev && trust.prev.isValid() && !trust.prev.isSpendable()); - } - - assert(trust.isValid()); - trusts.push(trust); - this.txToDirectTrust.set(trust.txHash, trust); - - this.entities.add(origin); - this.entities.add(dest); - } -} - -module.exports = TrustDB; diff --git a/lib/trust_is_risk.js b/lib/trust_is_risk.js deleted file mode 100644 index 8bec28d..0000000 --- a/lib/trust_is_risk.js +++ /dev/null @@ -1,284 +0,0 @@ -// - -var bcoin = require("bcoin"); -var Address = bcoin.primitives.Address; -var KeyRing = bcoin.primitives.KeyRing; -var MTX = bcoin.primitives.MTX; -var Input = bcoin.primitives.Input; -var Output = bcoin.primitives.Output; -var Outpoint = bcoin.primitives.Outpoint; -var Coin = bcoin.primitives.Coin; -var assert = require("assert"); -var helpers = require("./helpers"); -var TrustDB = require("./trust_db"); -var DirectTrust = require("./direct_trust"); - -class TrustIsRisk { - - - - constructor(node ) { - this.node = node; - this.db = new TrustDB(); - - this.node.on("tx", this.addTX.bind(this)); - } - - getIndirectTrust(origin , dest ) { - return this.db.getTrustAmount(origin, dest); - } - - getDirectTrust(origin , dest ) { - return this.db.getDirectTrustAmount(origin, dest); - } - - // Attempts to parse a bitcoin transaction as a trust change and adds it to the trust network - // if successful. - // Returns true if the transaction is a TIR transaction and was successfully added to the - // network, false otherwise. - // Throws an error if the transaction was processed earlier. - addTX(tx ) { - var txHash = tx.hash().toString("hex"); - if (this.db.isTrustTX(txHash)) { - throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); - } - - var directTrusts = this.getDirectTrusts(tx); - if (directTrusts.length === 0) return false; - else { - directTrusts.forEach(this.db.add.bind(this.db)); - return true; - } - } - - // Returns a list of trusts that a transaction contains, which will be one of the following: - // * An empty list (for non-TIR transactions). - // * A list containing a single trust increase (for trust-increasing transactions). - // * A list containing one or more trust decreases (for trust-decreasing transactions). - getDirectTrusts(tx ) { - var trustIncrease = this.parseTXAsTrustIncrease(tx); - if (trustIncrease !== null) { - return [trustIncrease]; - } else { - return this.getTrustDecreases(tx); - } - } - - // Returns a promise resolving to a mutable transaction object, which increases a trust - // relationship by some amount. It will spend the outpoint, which must reference a P2PKH output - // payable to the sender. The origin key must be a private key. Any satoshis not spent will be - // returned to the sender, minus the fees, via P2PKH. - async createTrustIncreasingMTX(origin , dest , outpoint , - trustAmount , fee ) - { - if (!fee) fee = 1000; // TODO: estimate this - var coin = await this.node.getCoin(outpoint.hash, outpoint.index); - if (!coin) throw new Error("Could not find coin"); - if (origin === dest) throw new Error("Can not increase self-trust."); - - var originKeyRing = KeyRing.fromPrivate(origin); - var originPubKey = originKeyRing.getPublicKey(); - - var mtx = new MTX({ - outputs: [ - new Output({ - script: bcoin.script.fromMultisig(1, 2, [originPubKey, dest]), - value: trustAmount - }) - ] - }); - - var changeAmount = coin.value - trustAmount - fee; - assert(changeAmount >= 0); - if (changeAmount) { - mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), - value: changeAmount - })); - } - - mtx.addCoin(coin); - var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); - assert(success); - - var signedCount = mtx.sign(originKeyRing); - assert(signedCount === 1); - - return mtx; - } - - // Returns an array of trust-decreasing mutable transaction objects, which reduce a trust - // relationship by the amount specified. The payee will receive the amount deducted minus the - // transaction fees via P2PKH. - // If steal is undefined or set to false, then the `origin` key is expected to be a private key - // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is - // expected to be a public key and `dest` is expected to be a private key. The private key will be - // used to sign the transaction. - createTrustDecreasingMTXs(origin , dest , trustDecreaseAmount , payee , - steal , fee ) { - if (steal === undefined) steal = false; - - var signingKeyRing, originKeyRing, destKeyRing; - if (!steal) { - signingKeyRing = KeyRing.fromPrivate(origin); - originKeyRing = KeyRing.fromPrivate(origin); - destKeyRing = KeyRing.fromPublic(dest); - } else { - signingKeyRing = KeyRing.fromPrivate(dest); - originKeyRing = KeyRing.fromPublic(origin); - destKeyRing = KeyRing.fromPrivate(dest); - } - - var originAddress = helpers.pubKeyToEntity(originKeyRing.getPublicKey()); - var destAddress = helpers.pubKeyToEntity(destKeyRing.getPublicKey()); - - if (originAddress === destAddress) throw new Error("Can't decrease self-trust"); - - var existingTrustAmount = this.db.getDirectTrustAmount(originAddress, destAddress); - if (existingTrustAmount < trustDecreaseAmount) throw new Error("Insufficient trust"); - - var directTrusts = this.db.getSpendableDirectTrusts(originAddress, destAddress); - return directTrusts.map((directTrust) => { - var decrease = Math.min(trustDecreaseAmount, directTrust.amount); - if (decrease === 0) return null; - trustDecreaseAmount -= decrease; - return this.getTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, fee); - }).filter(Boolean); - } - - getTrustDecreasingMTX(directTrust , decreaseAmount , payee , - signingKeyRing , fee ) { - if (!payee) payee = directTrust.getOriginEntity(); - if (!fee) fee = 1000; // TODO: estimate this - - var mtx = new MTX({ - inputs: [ - Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) - ], - outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), - value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) - })] - }); - - var remainingTrustAmount = directTrust.amount - decreaseAmount; - if (remainingTrustAmount > 0) { - mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 2, [directTrust.origin, directTrust.dest]), - value: remainingTrustAmount - })); - } - - var success = mtx.scriptVector(((directTrust.script ) ), - mtx.inputs[0].script, KeyRing.fromPublic(directTrust.origin)); - assert(success); - - success = mtx.signInput(0, new Coin({script: directTrust.script, value: directTrust.amount}), - signingKeyRing); - assert(success); - - return mtx; - } - - parseTXAsTrustIncrease(tx ) { - if (tx.inputs.length !== 1) return null; - var input = tx.inputs[0]; - if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable - if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; - var origin = tx.inputs[0].getAddress().toBase58(); - - if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; - - var trustOutputs = this.searchForDirectTrustOutputs(tx, origin); - if (trustOutputs.length !== 1) return null; - - var changeOutputCount = tx.outputs.filter((o) => this.isChangeOutput(o, origin)).length; - if (changeOutputCount + 1 !== tx.outputs.length) return null; - - return trustOutputs[0]; - } - - getTrustDecreases(tx ) { - var inputTrusts = this.getInputTrusts(tx.inputs); - return inputTrusts.map(this.getTrustDecrease.bind(this, tx)); - } - - getInputTrusts(inputs ) { - return inputs.map((input) => { - var trust = this.db.getDirectTrustByOutpoint(input.prevout); - if (trust && trust.outputIndex === input.prevout.index) return trust; - else return null; - }).filter(Boolean); - } - - getTrustDecrease(tx , prevTrust ) { - var txHash = tx.hash().toString("hex"); - var nullTrust = prevTrust.getNullifying(txHash); - - if (tx.inputs.length !== 1) return nullTrust; - - var trustOutputs = this.searchForDirectTrustOutputs(tx, prevTrust.getOriginEntity(), - prevTrust.getDestEntity()); - if (trustOutputs.length != 1) return nullTrust; - var nextTrust = trustOutputs[0]; - - nextTrust.prev = prevTrust; - - assert(nextTrust.amount - prevTrust.amount <= 0); - return nextTrust; - } - - // Looks for direct trust outputs that originate from a sender in an array of bitcoin outputs. - // Returns a list of the corresponding DirectTrust objects. - // If the recipient parameter is set, it will limit the results only to the outputs being sent to - // the recipient. - searchForDirectTrustOutputs(tx , origin , recipient ) { - var directTrusts = tx.outputs.map((output, outputIndex) => - this.parseOutputAsDirectTrust(tx, outputIndex, origin) - ).filter(Boolean); - - if (recipient) { - directTrusts.filter((trust) => trust.dest === recipient); - } - - return directTrusts; - } - - isChangeOutput(output , origin ) { - return (output.getType() === "pubkeyhash") - && (output.getAddress().toBase58() === origin); - } - - parseOutputAsDirectTrust(tx , outputIndex , origin ) - { - var txHash = tx.hash().toString("hex"); - var output = tx.outputs[outputIndex]; - if (output.getType() !== "multisig") return null; - - var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); - if (entities[0] === entities[1]) return null; - - var originPubKey, destPubKey; - if (entities[0] === origin) { - originPubKey = output.script.get(1); - destPubKey = output.script.get(2); - } - else if (entities[1] === origin) { - originPubKey = output.script.get(2); - destPubKey = output.script.get(1); - } - else return null; - - return new DirectTrust({ - origin: originPubKey, - dest: destPubKey, - amount: Number(output.value), - - txHash, - outputIndex, - script: output.script - }); - } -} - -module.exports = TrustIsRisk; diff --git a/lib/types.js b/lib/types.js deleted file mode 100644 index 79f17ec..0000000 --- a/lib/types.js +++ /dev/null @@ -1,8 +0,0 @@ -// - -// base58 bitcoin address: - - - - - diff --git a/src/trust_db.js b/src/trust_db.js index 650616b..0af2541 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -23,11 +23,6 @@ class TrustDB { this.entities = new SortedSet(); } - getDirectTrustByTX(txHash : string) : (DirectTrust | null) { - if (!this.isTrustTX(txHash)) return null; - return ((this.txToDirectTrust.get(txHash) : any) : DirectTrust); - } - getDirectTrustByOutpoint(outpoint : bcoin$Outpoint) : (DirectTrust | null) { var trust = this.txToDirectTrust.get(outpoint.hash.toString("hex")); if (!trust) return null; diff --git a/test/full_node.js b/test/full_node.js index 051c371..a3260ba 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -190,4 +190,8 @@ describe("FullNode", () => { should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); }); }); + + describe("with the topcoder.json example", () => { + //TODO: Write tests here. + }); }); From 86a512c50ed80f41872a5c91309c77fc1d92831e Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 11 Sep 2017 23:03:44 +0000 Subject: [PATCH 018/540] More CR responses. --- src/trust_is_risk.js | 9 +++++---- test/trust_is_risk.js | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 07d79c8..367bbee 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -228,17 +228,18 @@ class TrustIsRisk { return nextTrust; } - // Looks for direct trust outputs that originate from a sender in an array of bitcoin outputs. - // Returns a list of the corresponding DirectTrust objects. + // Looks for direct trust outputs that originate from a sender in a transaction. + // Returns an array of the corresponding DirectTrust objects. // If the recipient parameter is set, it will limit the results only to the outputs being sent to // the recipient. searchForDirectTrustOutputs(tx : bcoin$TX, origin : Entity, recipient : ?Entity) : DirectTrust[] { var directTrusts = tx.outputs.map((output, outputIndex) => this.parseOutputAsDirectTrust(tx, outputIndex, origin) - ).filter(Boolean); + ).filter(Boolean); // filter out nulls if (recipient) { - directTrusts.filter((trust) => trust.dest === recipient); + directTrusts = directTrusts.filter((trust) => + helpers.pubKeyToEntity(trust.dest) === recipient); } return directTrusts; diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index a4085fa..2040784 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -150,6 +150,16 @@ describe("TrustIsRisk", () => { tir.getDirectTrust(alice, bob).should.equal(20 * COIN); }); + it("decreases trust to zero for trust decreasing transactions with a wrong recipient", () => { + // By changing the trust recipient from bob to charlie, we make the transaction a + // nullifying trust transaction. + trustDecreasingMTX.outputs[0] = + testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.charlie.pubKey, 20 * COIN); + + tir.addTX(trustDecreasingMTX.toTX()); + tir.getDirectTrust(alice, bob).should.equal(0); + }); + it("which has a second input decreases trust to zero", () => { trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubKey)); tir.addTX(trustDecreasingMTX.toTX()); From 8f2511875f0bfe501091048e9edc1bed23b2e9ca Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 11 Sep 2017 23:17:29 +0000 Subject: [PATCH 019/540] More CR fixes. --- src/direct_trust.js | 15 ++++++--------- src/trust_db.js | 2 +- src/trust_is_risk.js | 6 ++---- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/direct_trust.js b/src/direct_trust.js index 15fbae6..3ed4fcf 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -63,15 +63,12 @@ class DirectTrust { isValid() : boolean { // TODO: Consider removing this function and ensure validity at build time by using the flow // type system, possibly by creating sub-types like "IncreasingDirectTrust" etc. - var valid = true; - - if ((this.outputIndex === null) !== (this.script === null)) valid = false; - if (this.outputIndex === null && this.isIncrease()) valid = false; - if (this.outputIndex === null && this.amount > 0) valid = false; - if (this.isIncrease() && this.isNull()) valid = false; - if (this.isSpent() && this.isNull()) valid = false; - - return valid; + if ((this.outputIndex === null) !== (this.script === null)) return false; + if (this.outputIndex === null && this.isIncrease()) return false; + if (this.outputIndex === null && this.amount > 0) return false; + if (this.isIncrease() && this.isNull()) return false; + if (this.isSpent() && this.isNull()) return false; + return true; } getOriginEntity() : Entity { diff --git a/src/trust_db.js b/src/trust_db.js index 0af2541..d41e680 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -71,7 +71,7 @@ class TrustDB { } getEntities() : Entity[] { - return this.entities.slice(0, this.entities.length); + return this.entities.slice(); } getEntityIndex(entity : Entity) : number { diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 367bbee..d92a947 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -205,9 +205,7 @@ class TrustIsRisk { getInputTrusts(inputs : bcoin$Input[]) : DirectTrust[] { return inputs.map((input) => { - var trust = this.db.getDirectTrustByOutpoint(input.prevout); - if (trust && trust.outputIndex === input.prevout.index) return trust; - else return null; + return this.db.getDirectTrustByOutpoint(input.prevout); }).filter(Boolean); } @@ -224,7 +222,7 @@ class TrustIsRisk { nextTrust.prev = prevTrust; - assert(nextTrust.amount - prevTrust.amount <= 0); + assert(nextTrust.amount <= prevTrust.amount); return nextTrust; } From ba908f5baa879d86871130dc92ecf8d887312f30 Mon Sep 17 00:00:00 2001 From: Christos Porios Date: Mon, 11 Sep 2017 23:26:40 +0000 Subject: [PATCH 020/540] Fix bcoin version 1.0.0-beta.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d8c39a..116b868 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "sinon": "^2.2.0" }, "dependencies": { - "bcoin": "^1.0.0-beta.12", + "bcoin": "1.0.0-beta.12", "graph-theory-ford-fulkerson": "^1.0.0", "sorted-set": "^0.3.0" } From 0927949460db091d28978d6ad8a02a289fa023eb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Sep 2017 12:23:01 +0100 Subject: [PATCH 021/540] Rename "OneOfTwo" to "OneOfThree" --- test/helpers.js | 4 ++-- test/trust_is_risk.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 855c1de..d38b350 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -82,7 +82,7 @@ var testHelpers = { }); }, - getOneOfTwoMultisigOutput: (originPubKey, destPubKey, value) => { + getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { return new bcoin.primitives.Output({ script: bcoin.script.fromMultisig(1, 2, [originPubKey, destPubKey]), value @@ -95,7 +95,7 @@ var testHelpers = { testHelpers.getP2PKHInput(originPubKey) ], outputs: [ - testHelpers.getOneOfTwoMultisigOutput(originPubKey, destPubKey, value) + testHelpers.getOneOfThreeMultisigOutput(originPubKey, destPubKey, value) ] }); }, diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 2040784..278ec1d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -40,7 +40,7 @@ describe("TrustIsRisk", () => { trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); trustIncreasingTX = trustIncreasingMTX.toTX(); - var inputOneOfTwoMultisig = new Input({ + var inputOneOfThreeMultisig = new Input({ prevout: { hash: trustIncreasingTX.hash().toString("hex"), index: 0 @@ -52,10 +52,10 @@ describe("TrustIsRisk", () => { trustDecreasingMTX = new MTX({ inputs: [ - inputOneOfTwoMultisig + inputOneOfThreeMultisig ], outputs: [ - testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), + testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), testHelpers.getP2PKHOutput(addr.alice.base58, 22 * COIN) ] }); @@ -170,7 +170,7 @@ describe("TrustIsRisk", () => { it("which has more than one trust outputs decreases trust to zero", () => { trustDecreasingMTX.outputs[0].value -= 15 * COIN; trustDecreasingMTX.outputs.push( - testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 5 * COIN)); + testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 5 * COIN)); tir.addTX(trustDecreasingMTX.toTX()); tir.getDirectTrust(alice, bob).should.equal(0); From 977df8dc7b40d487f101ea99c3598914bea3204e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Sep 2017 13:53:15 +0100 Subject: [PATCH 022/540] Add provisional tag --- test/trust_is_risk.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 278ec1d..e109536 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -13,6 +13,9 @@ var fixtures = require("./fixtures"); require("should-sinon"); const COIN = bcoin.consensus.COIN; +const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // +const ripemdTag1 = "1"; //TODO +const tag = "1111111111111111111111111111111111"; // describe("TrustIsRisk", () => { var addr = {}; From f815dc0e1393f5b1c500c0e70d83dac74d768c91 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Sep 2017 13:54:13 +0100 Subject: [PATCH 023/540] Check trustisrisk tag in trust increasing MTX --- test/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index e109536..a8a1693 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -206,6 +206,7 @@ describe("TrustIsRisk", () => { trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); + trustOutput.script.get(3).should.equal(tag); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From e36468c8dfa4d89d38b387fa33a17f77992630f7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Sep 2017 13:58:27 +0100 Subject: [PATCH 024/540] Add provisional tag --- src/trust_is_risk.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index d92a947..c8aef90 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,6 +13,10 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); +const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // +const ripemdTag1 = "1"; //TODO +const tag = "1111111111111111111111111111111111"; // + class TrustIsRisk { node : bcoin$FullNode db : TrustDB From 3a7eea6ab639cf7ed7b2b5ea5a1b57cf85960727 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Sep 2017 13:58:55 +0100 Subject: [PATCH 025/540] Add tag to trust increasing MTX --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index c8aef90..8939c47 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -86,7 +86,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 2, [originPubKey, dest]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, tag]), value: trustAmount }) ] From 6efd6fe1c5bc6d5e108c5e0a39874e03658a3da5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 12:08:19 +0100 Subject: [PATCH 026/540] Turn tag from String to Buffer --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 8939c47..50bf4f2 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -15,7 +15,7 @@ var DirectTrust = require("./direct_trust"); const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // const ripemdTag1 = "1"; //TODO -const tag = "1111111111111111111111111111111111"; // +const tag = Buffer.from("1111111111111111111111111111111111"); // class TrustIsRisk { node : bcoin$FullNode From f5682949a7504d3c8238fcdb0cf08a9e5f7989c1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 12:31:09 +0100 Subject: [PATCH 027/540] Comment out "trustisrisk" tag creation commands A provisional tag is currently used, the correct tag creation procedure will be implemented later. --- src/trust_is_risk.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 50bf4f2..fd730fd 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,9 +13,9 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // -const ripemdTag1 = "1"; //TODO -const tag = Buffer.from("1111111111111111111111111111111111"); // +//const ripemdTag = bcoin.crypto.hash160("trustisrisk"); +//const ripemdTag1 = "1"; TOFIX +const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { node : bcoin$FullNode From 89b25a0cc1a084496985dea19ef8d7a148087306 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 13:49:29 +0100 Subject: [PATCH 028/540] Random change Done to check if Travis CI sees the commented out lines --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index fd730fd..184cd9c 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,8 +13,8 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -//const ripemdTag = bcoin.crypto.hash160("trustisrisk"); -//const ripemdTag1 = "1"; TOFIX +// const ripemdTag = bcoin.crypto.hash160("trustisrisk"); +// const ripemdTag1 = "1"; TOFIX const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { From 81e7df46d4a0ca88f60161396dfeeadfc4f4af6e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 14:09:52 +0100 Subject: [PATCH 029/540] Comment out "trustisrisk" tag in test --- test/trust_is_risk.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index a8a1693..c52c132 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -13,9 +13,9 @@ var fixtures = require("./fixtures"); require("should-sinon"); const COIN = bcoin.consensus.COIN; -const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // -const ripemdTag1 = "1"; //TODO -const tag = "1111111111111111111111111111111111"; // +// const ripemdTag = bcoin.crypto.hash160("trustisrisk"); +// const ripemdTag1 = "1"; TOFIX +const tag = Buffer.from("1111111111111111111111111111111111"); describe("TrustIsRisk", () => { var addr = {}; From f0b1880ef1fb19bdc802b874ed2aafb3ed6c63bb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 14:32:13 +0100 Subject: [PATCH 030/540] Replace "equal" with "deepEqual" --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c52c132..0be50c3 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -206,7 +206,7 @@ describe("TrustIsRisk", () => { trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.equal(tag); + trustOutput.script.get(3).should.deepEqual(tag); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From 826cd8e20fa8dd4b44a39f629dcc1b8a41126ad6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 15:05:39 +0100 Subject: [PATCH 031/540] Add tag to getTrustDecreasingMTX() --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 184cd9c..f346e7e 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -168,7 +168,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 2, [directTrust.origin, directTrust.dest]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, tag]), value: remainingTrustAmount })); } From 8c369e5fd9f833e9e1039189510b69bb449cddce Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 15:27:06 +0100 Subject: [PATCH 032/540] Add provisional "trustisrisk" tag --- test/helpers.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index d38b350..349aa11 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,6 +5,10 @@ var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); +// const ripemdTag = bcoin.crypto.hash160("trustisrisk"); +// const ripemdTag1 = "1"; TOFIX +const tag = Buffer.from("1111111111111111111111111111111111"); + var testHelpers = { getNode: async () => { var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); From e6ec7f006678e2a02a6a730c166a539e0c0cc741 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 7 Sep 2017 15:27:27 +0100 Subject: [PATCH 033/540] Add tag to getOneOfThreeMultisigOutput() --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index 349aa11..4f33917 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -88,7 +88,7 @@ var testHelpers = { getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { return new bcoin.primitives.Output({ - script: bcoin.script.fromMultisig(1, 2, [originPubKey, destPubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value }); }, From 5d35bc8dbb09f3492f1f161d1e51ac28184694e3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 8 Sep 2017 15:35:47 +0100 Subject: [PATCH 034/540] Add publicKeyArray which contains "Trust is Risk" --- src/trust_is_risk.js | 1 + test/helpers.js | 1 + test/trust_is_risk.js | 1 + 3 files changed, 3 insertions(+) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index f346e7e..0f2c057 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -15,6 +15,7 @@ var DirectTrust = require("./direct_trust"); // const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // const ripemdTag1 = "1"; TOFIX +const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { diff --git a/test/helpers.js b/test/helpers.js index 4f33917..a32302a 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,6 +7,7 @@ var assert = require("assert"); // const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // const ripemdTag1 = "1"; TOFIX +const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const tag = Buffer.from("1111111111111111111111111111111111"); var testHelpers = { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 0be50c3..c1b04f8 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -15,6 +15,7 @@ require("should-sinon"); const COIN = bcoin.consensus.COIN; // const ripemdTag = bcoin.crypto.hash160("trustisrisk"); // const ripemdTag1 = "1"; TOFIX +const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const tag = Buffer.from("1111111111111111111111111111111111"); describe("TrustIsRisk", () => { From f498dd8d9383f6a771978c867d64dde9ac6eb1bb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 17:46:17 +0100 Subject: [PATCH 035/540] Add public key to addres conversion --- src/trust_is_risk.js | 13 ++++++++++--- test/helpers.js | 13 ++++++++++--- test/trust_is_risk.js | 13 ++++++++++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0f2c057..f712b69 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,10 +13,17 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -// const ripemdTag = bcoin.crypto.hash160("trustisrisk"); -// const ripemdTag1 = "1"; TOFIX const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const tag = Buffer.from("1111111111111111111111111111111111"); +const publicKey = Buffer.from(publicKeyArray); +const step2 = bcoin.crypto.sha256(publicKey); +const step3 = bcoin.crypto.ripemd160(step2); +const step4 = Buffer.concat([buffer.Buffer.alloc(1), step3]); +const step5 = bcoin.crypto.sha256(step4); +const step6 = bcoin.crypto.sha256(step5); +const step7 = step6.slice(0, 4); +const step8 = Buffer.concat([step4, step7]); +const tag = bcoin.base58.encode(step8); +// const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { node : bcoin$FullNode diff --git a/test/helpers.js b/test/helpers.js index a32302a..9a5c195 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,10 +5,17 @@ var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); -// const ripemdTag = bcoin.crypto.hash160("trustisrisk"); -// const ripemdTag1 = "1"; TOFIX const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const tag = Buffer.from("1111111111111111111111111111111111"); +const publicKey = Buffer.from(publicKeyArray); +const step2 = bcoin.crypto.sha256(publicKey); +const step3 = bcoin.crypto.ripemd160(step2); +const step4 = Buffer.concat([buffer.Buffer.alloc(1), step3]); +const step5 = bcoin.crypto.sha256(step4); +const step6 = bcoin.crypto.sha256(step5); +const step7 = step6.slice(0, 4); +const step8 = Buffer.concat([step4, step7]); +const tag = bcoin.base58.encode(step8); +// const tag = Buffer.from("1111111111111111111111111111111111"); var testHelpers = { getNode: async () => { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c1b04f8..1faf20a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -13,10 +13,17 @@ var fixtures = require("./fixtures"); require("should-sinon"); const COIN = bcoin.consensus.COIN; -// const ripemdTag = bcoin.crypto.hash160("trustisrisk"); -// const ripemdTag1 = "1"; TOFIX const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const tag = Buffer.from("1111111111111111111111111111111111"); +const publicKey = Buffer.from(publicKeyArray); +const step2 = bcoin.crypto.sha256(publicKey); +const step3 = bcoin.crypto.ripemd160(step2); +const step4 = Buffer.concat([buffer.Buffer.alloc(1), step3]); +const step5 = bcoin.crypto.sha256(step4); +const step6 = bcoin.crypto.sha256(step5); +const step7 = step6.slice(0, 4); +const step8 = Buffer.concat([step4, step7]); +const tag = bcoin.base58.encode(step8); +// const tag = Buffer.from("1111111111111111111111111111111111"); describe("TrustIsRisk", () => { var addr = {}; From ac64cfc44358ebb61b4ba1fea338dffa4ec64cb5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 17:59:08 +0100 Subject: [PATCH 036/540] Replace buffer.Buffer with Buffer --- src/trust_is_risk.js | 2 +- test/helpers.js | 2 +- test/trust_is_risk.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index f712b69..17f9534 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -17,9 +17,9 @@ const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x const publicKey = Buffer.from(publicKeyArray); const step2 = bcoin.crypto.sha256(publicKey); const step3 = bcoin.crypto.ripemd160(step2); -const step4 = Buffer.concat([buffer.Buffer.alloc(1), step3]); const step5 = bcoin.crypto.sha256(step4); const step6 = bcoin.crypto.sha256(step5); +const step4 = Buffer.concat([Buffer.alloc(1), step3]); const step7 = step6.slice(0, 4); const step8 = Buffer.concat([step4, step7]); const tag = bcoin.base58.encode(step8); diff --git a/test/helpers.js b/test/helpers.js index 9a5c195..e6b250f 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -9,9 +9,9 @@ const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x const publicKey = Buffer.from(publicKeyArray); const step2 = bcoin.crypto.sha256(publicKey); const step3 = bcoin.crypto.ripemd160(step2); -const step4 = Buffer.concat([buffer.Buffer.alloc(1), step3]); const step5 = bcoin.crypto.sha256(step4); const step6 = bcoin.crypto.sha256(step5); +const step4 = Buffer.concat([Buffer.alloc(1), step3]); const step7 = step6.slice(0, 4); const step8 = Buffer.concat([step4, step7]); const tag = bcoin.base58.encode(step8); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1faf20a..950ef38 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -17,9 +17,9 @@ const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x const publicKey = Buffer.from(publicKeyArray); const step2 = bcoin.crypto.sha256(publicKey); const step3 = bcoin.crypto.ripemd160(step2); -const step4 = Buffer.concat([buffer.Buffer.alloc(1), step3]); const step5 = bcoin.crypto.sha256(step4); const step6 = bcoin.crypto.sha256(step5); +const step4 = Buffer.concat([Buffer.alloc(1), step3]); const step7 = step6.slice(0, 4); const step8 = Buffer.concat([step4, step7]); const tag = bcoin.base58.encode(step8); From b2f2b315ede6f99d490183a727770daf905a9fe3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 17:59:50 +0100 Subject: [PATCH 037/540] Require crypto and base58 from bcoin --- src/trust_is_risk.js | 12 +- test/helpers.js | 12 +- test/trust_is_risk.js | 395 ------------------------------------------ 3 files changed, 14 insertions(+), 405 deletions(-) delete mode 100644 test/trust_is_risk.js diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 17f9534..10b77bf 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -12,17 +12,19 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); +var crypto = require("bcoin/lib/crypto"); +var base58 = require("bcoin/lib/utils/base58"); const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const publicKey = Buffer.from(publicKeyArray); -const step2 = bcoin.crypto.sha256(publicKey); -const step3 = bcoin.crypto.ripemd160(step2); -const step5 = bcoin.crypto.sha256(step4); -const step6 = bcoin.crypto.sha256(step5); +const step2 = crypto.sha256(publicKey); +const step3 = crypto.ripemd160(step2); const step4 = Buffer.concat([Buffer.alloc(1), step3]); +const step5 = crypto.sha256(step4); +const step6 = crypto.sha256(step5); const step7 = step6.slice(0, 4); const step8 = Buffer.concat([step4, step7]); -const tag = bcoin.base58.encode(step8); +const tag = base58.encode(step8); // const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { diff --git a/test/helpers.js b/test/helpers.js index e6b250f..688c329 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -4,17 +4,19 @@ var bcoin = require("bcoin"); var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); +var crypto = require("bcoin/lib/crypto"); +var base58 = require("bcoin/lib/utils/base58"); const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const publicKey = Buffer.from(publicKeyArray); -const step2 = bcoin.crypto.sha256(publicKey); -const step3 = bcoin.crypto.ripemd160(step2); -const step5 = bcoin.crypto.sha256(step4); -const step6 = bcoin.crypto.sha256(step5); +const step2 = crypto.sha256(publicKey); +const step3 = crypto.ripemd160(step2); const step4 = Buffer.concat([Buffer.alloc(1), step3]); +const step5 = crypto.sha256(step4); +const step6 = crypto.sha256(step5); const step7 = step6.slice(0, 4); const step8 = Buffer.concat([step4, step7]); -const tag = bcoin.base58.encode(step8); +const tag = base58.encode(step8); // const tag = Buffer.from("1111111111111111111111111111111111"); var testHelpers = { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js deleted file mode 100644 index 950ef38..0000000 --- a/test/trust_is_risk.js +++ /dev/null @@ -1,395 +0,0 @@ -var Trust = require("../"); -var helpers = require("../lib/helpers.js"); -var bcoin = require("bcoin"); -var Coin = bcoin.primitives.Coin; -var Address = bcoin.primitives.Address; -var Input = bcoin.primitives.Input; -var MTX = bcoin.primitives.MTX; -var testHelpers = require("./helpers"); -var consensus = require("bcoin/lib/protocol/consensus"); -var sinon = require("sinon"); -var should = require("should"); -var fixtures = require("./fixtures"); -require("should-sinon"); - -const COIN = bcoin.consensus.COIN; -const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const publicKey = Buffer.from(publicKeyArray); -const step2 = bcoin.crypto.sha256(publicKey); -const step3 = bcoin.crypto.ripemd160(step2); -const step5 = bcoin.crypto.sha256(step4); -const step6 = bcoin.crypto.sha256(step5); -const step4 = Buffer.concat([Buffer.alloc(1), step3]); -const step7 = step6.slice(0, 4); -const step8 = Buffer.concat([step4, step7]); -const tag = bcoin.base58.encode(step8); -// const tag = Buffer.from("1111111111111111111111111111111111"); - -describe("TrustIsRisk", () => { - var addr = {}; - for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { - var pubKey = keyRing.getPublicKey(); - var privKey = keyRing.getPrivateKey(); - - addr[name] = {}; - addr[name].pubKey = pubKey; - addr[name].privKey = privKey; - addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(pubKey)).toString(); - } - - // Add base58 address variables to scope. - for (name in fixtures.keyRings) { - var keyRing = fixtures.keyRings[name]; - eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); - } - - var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; - beforeEach(() => { - node = new bcoin.fullnode({}); - tir = new Trust.TrustIsRisk(node); - - trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); - trustIncreasingTX = trustIncreasingMTX.toTX(); - - var inputOneOfThreeMultisig = new Input({ - prevout: { - hash: trustIncreasingTX.hash().toString("hex"), - index: 0 - }, - script: bcoin.script.fromString( - // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE - "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") - }); - - trustDecreasingMTX = new MTX({ - inputs: [ - inputOneOfThreeMultisig - ], - outputs: [ - testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), - testHelpers.getP2PKHOutput(addr.alice.base58, 22 * COIN) - ] - }); - }); - - describe(".getDirectTrust()", () => { - it("returns zero for two arbitary parties that do not trust each other", () => { - tir.getDirectTrust(alice, bob).should.equal(0); - tir.getDirectTrust(bob, alice).should.equal(0); - tir.getDirectTrust(charlie, alice).should.equal(0); - tir.getDirectTrust(alice, charlie).should.equal(0); - tir.getDirectTrust(charlie, frank).should.equal(0); - }); - - it("returns Infinity for one's direct trust to themselves", () => { - tir.getDirectTrust(alice, alice).should.equal(Infinity); - tir.getDirectTrust(bob, bob).should.equal(Infinity); - }); - }); - - describe(".addTX()", () => { - describe("with a non-TIR transaction", () => { - it("does not change trust", () => { - trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); - tir.addTX(trustIncreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(0); - tir.getDirectTrust(bob, alice).should.equal(0); - tir.getDirectTrust(alice, charlie).should.equal(0); - tir.getDirectTrust(charlie, alice).should.equal(0); - tir.getDirectTrust(charlie, dave).should.equal(0); - }); - }); - - describe("with a trust increasing transaction", () => { - it("correctly increases trust", () => { - tir.addTX(trustIncreasingTX); - - tir.getDirectTrust(alice, bob).should.equal(42 * COIN); - tir.getDirectTrust(bob, alice).should.equal(0); - tir.getDirectTrust(charlie, dave).should.equal(0); - }); - - it("which has more than one input does not change trust", () => { - trustIncreasingMTX.inputs.push(trustIncreasingMTX.inputs[0].clone()); - tir.addTX(trustIncreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(0); - }); - - it("which has a change output correctly increases trust", () => { - trustIncreasingMTX.outputs[0].value -= 10 * COIN; - trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 10 * COIN)); - tir.addTX(trustIncreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(32 * COIN); - }); - - it("which has two change outputs does not change trust", () => { - trustIncreasingMTX.outputs[0].value -= 10; - for (var i = 0; i < 2; i++) { - trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 5 * COIN)); - } - tir.addTX(trustIncreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(0); - }); - - it("which has a second output that is not a change output does not change trust", () => { - trustIncreasingMTX.outputs[0].value -= 10 * COIN; - trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(charlie, 5 * COIN)); - tir.addTX(trustIncreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(0); - }); - - it("which has been processed before throws", () => { - var tx = trustIncreasingMTX.toTX(); - should(tir.addTX(tx)); - should.throws(() => tir.addTX(tx), /already processed/i); - tir.getDirectTrust(alice, bob).should.equal(42 * COIN); - }); - }); - - describe("with a trust decreasing transaction", () => { - beforeEach(() => { - tir.addTX(trustIncreasingTX); - }); - - it("correctly decreases trust", () => { - tir.addTX(trustDecreasingMTX.toTX()); - tir.getDirectTrust(alice, bob).should.equal(20 * COIN); - }); - - it("decreases trust to zero for trust decreasing transactions with a wrong recipient", () => { - // By changing the trust recipient from bob to charlie, we make the transaction a - // nullifying trust transaction. - trustDecreasingMTX.outputs[0] = - testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.charlie.pubKey, 20 * COIN); - - tir.addTX(trustDecreasingMTX.toTX()); - tir.getDirectTrust(alice, bob).should.equal(0); - }); - - it("which has a second input decreases trust to zero", () => { - trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubKey)); - tir.addTX(trustDecreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(0); - }); - - it("which has more than one trust outputs decreases trust to zero", () => { - trustDecreasingMTX.outputs[0].value -= 15 * COIN; - trustDecreasingMTX.outputs.push( - testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 5 * COIN)); - tir.addTX(trustDecreasingMTX.toTX()); - - tir.getDirectTrust(alice, bob).should.equal(0); - }); - }); - }); - - describe(".createTrustIncreasingMTX()", () => { - it("creates valid trust-increasing transactions", async () => { - var getTXStub = sinon.stub(node, "getCoin"); - - var prevOutput = { - hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", - index: 1 - }; - - getTXStub.withArgs(prevOutput.hash).returns(new Coin({ - script: testHelpers.getP2PKHOutput(alice, 1).script, - value: 1000 * COIN - })); - - var mtx = await tir.createTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, - 100 * COIN); - - mtx.inputs.length.should.equal(1); - - mtx.outputs.length.should.equal(2); - - var trustOutput = mtx.outputs[0]; - trustOutput.getType().should.equal("multisig"); - [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() - .should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.deepEqual(tag); - trustOutput.value.should.equal(100 * COIN); - - var changeOutput = mtx.outputs[1]; - changeOutput.getType().should.equal("pubkeyhash"); - changeOutput.getAddress().toBase58().should.equal(alice); - changeOutput.value.should.equal(900 * COIN - 1000); - }); - }); - - describe(".getTrustDecreasingMTX()", () => { - var trustTXs; - beforeEach(() => { - var tx; - trustTXs = []; - - tx = trustIncreasingTX; - trustTXs.push(tx); - tir.addTX(tx); - - trustIncreasingMTX.outputs[0].value = 100 * COIN; - tx = trustIncreasingMTX.toTX(); - trustTXs.push(tx); - tir.addTX(tx); - - trustIncreasingMTX.outputs[0].value = 500 * COIN; - tx = trustIncreasingMTX.toTX(); - trustTXs.push(tx); - tir.addTX(tx); - - // Total trust 642 BTC - }); - - // Helper specific to the next couple of tests: - // Checks that mtxs is a list of two trust decreasing transactions. The first one spends the - // entire first trust increasing transaction, and the second spends part of the second. - // Also checks that the reduced trust is sent via P2PKH outputs to the correct recipient. - var checkMTXs = (mtxs, recipient) => { - mtxs.length.should.equal(2); - - var mtx = mtxs[0]; - - mtx.inputs.length.should.equal(1); - mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[0].hash().toString("hex"), - index: 0 - }); - - mtx.outputs.length.should.equal(1); // Single P2PKH output - mtx.outputs[0].getType().should.equal("pubkeyhash"); - mtx.outputs[0].getAddress().toBase58().should.equal(recipient); - mtx.outputs[0].value.should.equal(42 * COIN - 1000); - - mtx = mtxs[1]; - - mtx.inputs.length.should.equal(1); - mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[1].hash().toString("hex"), - index: 0 - }); - - mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output - mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); - mtx.outputs[1].value.should.equal(60 * COIN); - mtx.outputs[0].getType().should.equal("pubkeyhash"); - mtx.outputs[0].getAddress().toBase58().should.equal(recipient); - mtx.outputs[0].value.should.equal(40 * COIN - 1000); - }; - - it("creates correct trust decreasing transactions", () => { - var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); - checkMTXs(mtxs, alice); - }); - - it("creates correct trust stealing transactions", () => { - var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); - checkMTXs(mtxs, charlie); - }); - - it("throws when trying to decrease self-trust", () => { - should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) - , /self-trust/i); - }); - - it("throws when there is not enough trust", () => { - should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) - , /insufficient trust/i); - - }); - }); - - describe(".getIndirectTrust()", () => { - it("returns zero for two arbitary parties that do not trust each other", () => { - should(tir.getIndirectTrust(alice, bob)).equal(0); - should(tir.getIndirectTrust(bob, alice)).equal(0); - should(tir.getIndirectTrust(charlie, alice)).equal(0); - should(tir.getIndirectTrust(alice, charlie)).equal(0); - }); - - it("returns Infinity for one's trust to themselves", () => { - should(tir.getIndirectTrust(alice, alice)).equal(Infinity); - should(tir.getIndirectTrust(bob, bob)).equal(Infinity); - }); - - describe("after applying the Nobody Likes Frank graph example", () => { - beforeEach(() => { - testHelpers.applyGraph(tir, "./graphs/nobodyLikesFrank.json", addr); - }); - - it("correctly computes trusts", () => { - should(tir.getIndirectTrust(alice, alice)).equal(Infinity); - should(tir.getIndirectTrust(alice, bob)).equal(10); - should(tir.getIndirectTrust(alice, charlie)).equal(1); - should(tir.getIndirectTrust(alice, dave)).equal(4); - should(tir.getIndirectTrust(alice, eve)).equal(6); - should(tir.getIndirectTrust(alice, frank)).equal(0); - should(tir.getIndirectTrust(alice, george)).equal(2); - - should(tir.getIndirectTrust(bob, alice)).equal(1); - should(tir.getIndirectTrust(bob, bob)).equal(Infinity); - should(tir.getIndirectTrust(bob, charlie)).equal(1); - should(tir.getIndirectTrust(bob, dave)).equal(1); - should(tir.getIndirectTrust(bob, eve)).equal(3); - should(tir.getIndirectTrust(bob, frank)).equal(0); - should(tir.getIndirectTrust(bob, george)).equal(2); - - should(tir.getIndirectTrust(charlie, alice)).equal(0); - should(tir.getIndirectTrust(charlie, bob)).equal(0); - should(tir.getIndirectTrust(charlie, charlie)).equal(Infinity); - should(tir.getIndirectTrust(charlie, dave)).equal(0); - should(tir.getIndirectTrust(charlie, eve)).equal(0); - should(tir.getIndirectTrust(charlie, frank)).equal(0); - should(tir.getIndirectTrust(charlie, george)).equal(3); - - should(tir.getIndirectTrust(dave, alice)).equal(2); - should(tir.getIndirectTrust(dave, bob)).equal(2); - should(tir.getIndirectTrust(dave, charlie)).equal(1); - should(tir.getIndirectTrust(dave, dave)).equal(Infinity); - should(tir.getIndirectTrust(dave, eve)).equal(12); - should(tir.getIndirectTrust(dave, frank)).equal(0); - should(tir.getIndirectTrust(dave, george)).equal(2); - - should(tir.getIndirectTrust(eve, alice)).equal(0); - should(tir.getIndirectTrust(eve, bob)).equal(0); - should(tir.getIndirectTrust(eve, charlie)).equal(0); - should(tir.getIndirectTrust(eve, dave)).equal(0); - should(tir.getIndirectTrust(eve, eve)).equal(Infinity); - should(tir.getIndirectTrust(eve, frank)).equal(0); - should(tir.getIndirectTrust(eve, george)).equal(0); - - should(tir.getIndirectTrust(frank, alice)).equal(0); - should(tir.getIndirectTrust(frank, bob)).equal(0); - should(tir.getIndirectTrust(frank, charlie)).equal(10); - should(tir.getIndirectTrust(frank, dave)).equal(0); - should(tir.getIndirectTrust(frank, eve)).equal(0); - should(tir.getIndirectTrust(frank, frank)).equal(Infinity); - should(tir.getIndirectTrust(frank, george)).equal(3); - - should(tir.getIndirectTrust(george, alice)).equal(0); - should(tir.getIndirectTrust(george, bob)).equal(0); - should(tir.getIndirectTrust(george, charlie)).equal(0); - should(tir.getIndirectTrust(george, dave)).equal(0); - should(tir.getIndirectTrust(george, eve)).equal(0); - should(tir.getIndirectTrust(george, frank)).equal(0); - should(tir.getIndirectTrust(george, george)).equal(Infinity); - }); - - it("correctly computes trusts when bob trusts frank", () => { - tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); - should(tir.getIndirectTrust(george, frank)).equal(0); - should(tir.getIndirectTrust(alice, frank)).equal(8); - should(tir.getIndirectTrust(dave, frank)).equal(2); - should(tir.getIndirectTrust(bob, frank)).equal(8); - }); - - // TODO: Decrement direct trusts and test that indirect trusts update correctly - }); - }); -}); From 247dc436b559fd1a96b469d447b280e53fa68385 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 18:05:02 +0100 Subject: [PATCH 038/540] Set i in {crypto,base58} as bcoin.$i --- src/trust_is_risk.js | 4 +- test/helpers.js | 4 +- test/trust_is_risk.js | 397 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 401 insertions(+), 4 deletions(-) create mode 100644 test/trust_is_risk.js diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 10b77bf..a2c7db7 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -12,8 +12,8 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -var crypto = require("bcoin/lib/crypto"); -var base58 = require("bcoin/lib/utils/base58"); +var crypto = bcoin.crypto; +var base58 = bcoin.base58; const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const publicKey = Buffer.from(publicKeyArray); diff --git a/test/helpers.js b/test/helpers.js index 688c329..bbf3864 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -4,8 +4,8 @@ var bcoin = require("bcoin"); var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); -var crypto = require("bcoin/lib/crypto"); -var base58 = require("bcoin/lib/utils/base58"); +var crypto = bcoin.crypto; +var base58 = bcoin.base58; const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const publicKey = Buffer.from(publicKeyArray); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js new file mode 100644 index 0000000..32c5bbf --- /dev/null +++ b/test/trust_is_risk.js @@ -0,0 +1,397 @@ +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); +var Coin = bcoin.primitives.Coin; +var Address = bcoin.primitives.Address; +var Input = bcoin.primitives.Input; +var MTX = bcoin.primitives.MTX; +var testHelpers = require("./helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +var fixtures = require("./fixtures"); +var crypto = require("bcoin/lib/crypto"); +var base58 = require("bcoin/lib/utils/base58"); +require("should-sinon"); + +const COIN = bcoin.consensus.COIN; +const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const publicKey = Buffer.from(publicKeyArray); +const step2 = crypto.sha256(publicKey); +const step3 = crypto.ripemd160(step2); +const step4 = Buffer.concat([Buffer.alloc(1), step3]); +const step5 = crypto.sha256(step4); +const step6 = crypto.sha256(step5); +const step7 = step6.slice(0, 4); +const step8 = Buffer.concat([step4, step7]); +const tag = base58.encode(step8); +// const tag = Buffer.from("1111111111111111111111111111111111"); + +describe("TrustIsRisk", () => { + var addr = {}; + for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { + var pubKey = keyRing.getPublicKey(); + var privKey = keyRing.getPrivateKey(); + + addr[name] = {}; + addr[name].pubKey = pubKey; + addr[name].privKey = privKey; + addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(pubKey)).toString(); + } + + // Add base58 address variables to scope. + for (name in fixtures.keyRings) { + var keyRing = fixtures.keyRings[name]; + eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); + } + + var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; + beforeEach(() => { + node = new bcoin.fullnode({}); + tir = new Trust.TrustIsRisk(node); + + trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); + trustIncreasingTX = trustIncreasingMTX.toTX(); + + var inputOneOfThreeMultisig = new Input({ + prevout: { + hash: trustIncreasingTX.hash().toString("hex"), + index: 0 + }, + script: bcoin.script.fromString( + // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE + "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") + }); + + trustDecreasingMTX = new MTX({ + inputs: [ + inputOneOfThreeMultisig + ], + outputs: [ + testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), + testHelpers.getP2PKHOutput(addr.alice.base58, 22 * COIN) + ] + }); + }); + + describe(".getDirectTrust()", () => { + it("returns zero for two arbitary parties that do not trust each other", () => { + tir.getDirectTrust(alice, bob).should.equal(0); + tir.getDirectTrust(bob, alice).should.equal(0); + tir.getDirectTrust(charlie, alice).should.equal(0); + tir.getDirectTrust(alice, charlie).should.equal(0); + tir.getDirectTrust(charlie, frank).should.equal(0); + }); + + it("returns Infinity for one's direct trust to themselves", () => { + tir.getDirectTrust(alice, alice).should.equal(Infinity); + tir.getDirectTrust(bob, bob).should.equal(Infinity); + }); + }); + + describe(".addTX()", () => { + describe("with a non-TIR transaction", () => { + it("does not change trust", () => { + trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); + tir.addTX(trustIncreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(0); + tir.getDirectTrust(bob, alice).should.equal(0); + tir.getDirectTrust(alice, charlie).should.equal(0); + tir.getDirectTrust(charlie, alice).should.equal(0); + tir.getDirectTrust(charlie, dave).should.equal(0); + }); + }); + + describe("with a trust increasing transaction", () => { + it("correctly increases trust", () => { + tir.addTX(trustIncreasingTX); + + tir.getDirectTrust(alice, bob).should.equal(42 * COIN); + tir.getDirectTrust(bob, alice).should.equal(0); + tir.getDirectTrust(charlie, dave).should.equal(0); + }); + + it("which has more than one input does not change trust", () => { + trustIncreasingMTX.inputs.push(trustIncreasingMTX.inputs[0].clone()); + tir.addTX(trustIncreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(0); + }); + + it("which has a change output correctly increases trust", () => { + trustIncreasingMTX.outputs[0].value -= 10 * COIN; + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 10 * COIN)); + tir.addTX(trustIncreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(32 * COIN); + }); + + it("which has two change outputs does not change trust", () => { + trustIncreasingMTX.outputs[0].value -= 10; + for (var i = 0; i < 2; i++) { + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(alice, 5 * COIN)); + } + tir.addTX(trustIncreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(0); + }); + + it("which has a second output that is not a change output does not change trust", () => { + trustIncreasingMTX.outputs[0].value -= 10 * COIN; + trustIncreasingMTX.outputs.push(testHelpers.getP2PKHOutput(charlie, 5 * COIN)); + tir.addTX(trustIncreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(0); + }); + + it("which has been processed before throws", () => { + var tx = trustIncreasingMTX.toTX(); + should(tir.addTX(tx)); + should.throws(() => tir.addTX(tx), /already processed/i); + tir.getDirectTrust(alice, bob).should.equal(42 * COIN); + }); + }); + + describe("with a trust decreasing transaction", () => { + beforeEach(() => { + tir.addTX(trustIncreasingTX); + }); + + it("correctly decreases trust", () => { + tir.addTX(trustDecreasingMTX.toTX()); + tir.getDirectTrust(alice, bob).should.equal(20 * COIN); + }); + + it("decreases trust to zero for trust decreasing transactions with a wrong recipient", () => { + // By changing the trust recipient from bob to charlie, we make the transaction a + // nullifying trust transaction. + trustDecreasingMTX.outputs[0] = + testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.charlie.pubKey, 20 * COIN); + + tir.addTX(trustDecreasingMTX.toTX()); + tir.getDirectTrust(alice, bob).should.equal(0); + }); + + it("which has a second input decreases trust to zero", () => { + trustDecreasingMTX.inputs.push(testHelpers.getP2PKHInput(addr.alice.pubKey)); + tir.addTX(trustDecreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(0); + }); + + it("which has more than one trust outputs decreases trust to zero", () => { + trustDecreasingMTX.outputs[0].value -= 15 * COIN; + trustDecreasingMTX.outputs.push( + testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 5 * COIN)); + tir.addTX(trustDecreasingMTX.toTX()); + + tir.getDirectTrust(alice, bob).should.equal(0); + }); + }); + }); + + describe(".createTrustIncreasingMTX()", () => { + it("creates valid trust-increasing transactions", async () => { + var getTXStub = sinon.stub(node, "getCoin"); + + var prevOutput = { + hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", + index: 1 + }; + + getTXStub.withArgs(prevOutput.hash).returns(new Coin({ + script: testHelpers.getP2PKHOutput(alice, 1).script, + value: 1000 * COIN + })); + + var mtx = await tir.createTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, + 100 * COIN); + + mtx.inputs.length.should.equal(1); + + mtx.outputs.length.should.equal(2); + + var trustOutput = mtx.outputs[0]; + trustOutput.getType().should.equal("multisig"); + [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() + .should.deepEqual([alice, bob].sort()); + trustOutput.script.get(3).should.deepEqual(tag); + trustOutput.value.should.equal(100 * COIN); + + var changeOutput = mtx.outputs[1]; + changeOutput.getType().should.equal("pubkeyhash"); + changeOutput.getAddress().toBase58().should.equal(alice); + changeOutput.value.should.equal(900 * COIN - 1000); + }); + }); + + describe(".getTrustDecreasingMTX()", () => { + var trustTXs; + beforeEach(() => { + var tx; + trustTXs = []; + + tx = trustIncreasingTX; + trustTXs.push(tx); + tir.addTX(tx); + + trustIncreasingMTX.outputs[0].value = 100 * COIN; + tx = trustIncreasingMTX.toTX(); + trustTXs.push(tx); + tir.addTX(tx); + + trustIncreasingMTX.outputs[0].value = 500 * COIN; + tx = trustIncreasingMTX.toTX(); + trustTXs.push(tx); + tir.addTX(tx); + + // Total trust 642 BTC + }); + + // Helper specific to the next couple of tests: + // Checks that mtxs is a list of two trust decreasing transactions. The first one spends the + // entire first trust increasing transaction, and the second spends part of the second. + // Also checks that the reduced trust is sent via P2PKH outputs to the correct recipient. + var checkMTXs = (mtxs, recipient) => { + mtxs.length.should.equal(2); + + var mtx = mtxs[0]; + + mtx.inputs.length.should.equal(1); + mtx.inputs[0].prevout.should.have.properties({ + hash: trustTXs[0].hash().toString("hex"), + index: 0 + }); + + mtx.outputs.length.should.equal(1); // Single P2PKH output + mtx.outputs[0].getType().should.equal("pubkeyhash"); + mtx.outputs[0].getAddress().toBase58().should.equal(recipient); + mtx.outputs[0].value.should.equal(42 * COIN - 1000); + + mtx = mtxs[1]; + + mtx.inputs.length.should.equal(1); + mtx.inputs[0].prevout.should.have.properties({ + hash: trustTXs[1].hash().toString("hex"), + index: 0 + }); + + mtx.outputs.length.should.equal(2); // One P2PKH output and one multisig trust output + mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); + mtx.outputs[1].value.should.equal(60 * COIN); + mtx.outputs[0].getType().should.equal("pubkeyhash"); + mtx.outputs[0].getAddress().toBase58().should.equal(recipient); + mtx.outputs[0].value.should.equal(40 * COIN - 1000); + }; + + it("creates correct trust decreasing transactions", () => { + var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); + checkMTXs(mtxs, alice); + }); + + it("creates correct trust stealing transactions", () => { + var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); + checkMTXs(mtxs, charlie); + }); + + it("throws when trying to decrease self-trust", () => { + should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) + , /self-trust/i); + }); + + it("throws when there is not enough trust", () => { + should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) + , /insufficient trust/i); + + }); + }); + + describe(".getIndirectTrust()", () => { + it("returns zero for two arbitary parties that do not trust each other", () => { + should(tir.getIndirectTrust(alice, bob)).equal(0); + should(tir.getIndirectTrust(bob, alice)).equal(0); + should(tir.getIndirectTrust(charlie, alice)).equal(0); + should(tir.getIndirectTrust(alice, charlie)).equal(0); + }); + + it("returns Infinity for one's trust to themselves", () => { + should(tir.getIndirectTrust(alice, alice)).equal(Infinity); + should(tir.getIndirectTrust(bob, bob)).equal(Infinity); + }); + + describe("after applying the Nobody Likes Frank graph example", () => { + beforeEach(() => { + testHelpers.applyGraph(tir, "./graphs/nobodyLikesFrank.json", addr); + }); + + it("correctly computes trusts", () => { + should(tir.getIndirectTrust(alice, alice)).equal(Infinity); + should(tir.getIndirectTrust(alice, bob)).equal(10); + should(tir.getIndirectTrust(alice, charlie)).equal(1); + should(tir.getIndirectTrust(alice, dave)).equal(4); + should(tir.getIndirectTrust(alice, eve)).equal(6); + should(tir.getIndirectTrust(alice, frank)).equal(0); + should(tir.getIndirectTrust(alice, george)).equal(2); + + should(tir.getIndirectTrust(bob, alice)).equal(1); + should(tir.getIndirectTrust(bob, bob)).equal(Infinity); + should(tir.getIndirectTrust(bob, charlie)).equal(1); + should(tir.getIndirectTrust(bob, dave)).equal(1); + should(tir.getIndirectTrust(bob, eve)).equal(3); + should(tir.getIndirectTrust(bob, frank)).equal(0); + should(tir.getIndirectTrust(bob, george)).equal(2); + + should(tir.getIndirectTrust(charlie, alice)).equal(0); + should(tir.getIndirectTrust(charlie, bob)).equal(0); + should(tir.getIndirectTrust(charlie, charlie)).equal(Infinity); + should(tir.getIndirectTrust(charlie, dave)).equal(0); + should(tir.getIndirectTrust(charlie, eve)).equal(0); + should(tir.getIndirectTrust(charlie, frank)).equal(0); + should(tir.getIndirectTrust(charlie, george)).equal(3); + + should(tir.getIndirectTrust(dave, alice)).equal(2); + should(tir.getIndirectTrust(dave, bob)).equal(2); + should(tir.getIndirectTrust(dave, charlie)).equal(1); + should(tir.getIndirectTrust(dave, dave)).equal(Infinity); + should(tir.getIndirectTrust(dave, eve)).equal(12); + should(tir.getIndirectTrust(dave, frank)).equal(0); + should(tir.getIndirectTrust(dave, george)).equal(2); + + should(tir.getIndirectTrust(eve, alice)).equal(0); + should(tir.getIndirectTrust(eve, bob)).equal(0); + should(tir.getIndirectTrust(eve, charlie)).equal(0); + should(tir.getIndirectTrust(eve, dave)).equal(0); + should(tir.getIndirectTrust(eve, eve)).equal(Infinity); + should(tir.getIndirectTrust(eve, frank)).equal(0); + should(tir.getIndirectTrust(eve, george)).equal(0); + + should(tir.getIndirectTrust(frank, alice)).equal(0); + should(tir.getIndirectTrust(frank, bob)).equal(0); + should(tir.getIndirectTrust(frank, charlie)).equal(10); + should(tir.getIndirectTrust(frank, dave)).equal(0); + should(tir.getIndirectTrust(frank, eve)).equal(0); + should(tir.getIndirectTrust(frank, frank)).equal(Infinity); + should(tir.getIndirectTrust(frank, george)).equal(3); + + should(tir.getIndirectTrust(george, alice)).equal(0); + should(tir.getIndirectTrust(george, bob)).equal(0); + should(tir.getIndirectTrust(george, charlie)).equal(0); + should(tir.getIndirectTrust(george, dave)).equal(0); + should(tir.getIndirectTrust(george, eve)).equal(0); + should(tir.getIndirectTrust(george, frank)).equal(0); + should(tir.getIndirectTrust(george, george)).equal(Infinity); + }); + + it("correctly computes trusts when bob trusts frank", () => { + tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); + should(tir.getIndirectTrust(george, frank)).equal(0); + should(tir.getIndirectTrust(alice, frank)).equal(8); + should(tir.getIndirectTrust(dave, frank)).equal(2); + should(tir.getIndirectTrust(bob, frank)).equal(8); + }); + + // TODO: Decrement direct trusts and test that indirect trusts update correctly + }); + }); +}); From 274ec2a3b3d20389811dc04370d56829b9fd278f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 18:26:44 +0100 Subject: [PATCH 039/540] Use hash160/256 instead of ripemd/sha --- src/trust_is_risk.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index a2c7db7..e874159 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -12,19 +12,17 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -var crypto = bcoin.crypto; -var base58 = bcoin.base58; - const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const publicKey = Buffer.from(publicKeyArray); -const step2 = crypto.sha256(publicKey); -const step3 = crypto.ripemd160(step2); -const step4 = Buffer.concat([Buffer.alloc(1), step3]); -const step5 = crypto.sha256(step4); -const step6 = crypto.sha256(step5); -const step7 = step6.slice(0, 4); -const step8 = Buffer.concat([step4, step7]); -const tag = base58.encode(step8); + +const step2 = bcoin.crypto.hash160(pubKey); +// const step3 = crypto.ripemd160(step2); +const step3 = Buffer.concat([Buffer.alloc(1), step2]); +const step4 = crypto.hash256(step3); +// const step6 = crypto.sha256(step5); +const step5 = step4.slice(0, 4); +const step6 = Buffer.concat([step3, step5]); +const tag = base58.encode(step6); // const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { From ca938c3f0d9649329f4af753bf00d675bb60baea Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 18:27:03 +0100 Subject: [PATCH 040/540] Rename publicKey to pubKey --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index e874159..4fc4853 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -12,9 +12,9 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const publicKey = Buffer.from(publicKeyArray); +const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const pubKey = Buffer.from(pubKeyArray); const step2 = bcoin.crypto.hash160(pubKey); // const step3 = crypto.ripemd160(step2); const step3 = Buffer.concat([Buffer.alloc(1), step2]); From f695312fb456b879f85ec382dcbbad6f175e1b5f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 9 Sep 2017 18:39:06 +0100 Subject: [PATCH 041/540] Convert step2 string to buffer --- src/trust_is_risk.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 4fc4853..0be1b38 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -17,12 +17,12 @@ const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, const pubKey = Buffer.from(pubKeyArray); const step2 = bcoin.crypto.hash160(pubKey); // const step3 = crypto.ripemd160(step2); -const step3 = Buffer.concat([Buffer.alloc(1), step2]); -const step4 = crypto.hash256(step3); +const step3 = Buffer.concat([Buffer.alloc(1), Buffer.from(step2)]); +const step4 = bcoin.crypto.hash256(step3); // const step6 = crypto.sha256(step5); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); -const tag = base58.encode(step6); +const tag = bcoin.base58.encode(step6); // const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { From bfba382caaec7401e795a6b2b478d2f12777df52 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:04:51 +0100 Subject: [PATCH 042/540] Replace hash256 with two sha256 --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0be1b38..47a5693 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -18,7 +18,7 @@ const pubKey = Buffer.from(pubKeyArray); const step2 = bcoin.crypto.hash160(pubKey); // const step3 = crypto.ripemd160(step2); const step3 = Buffer.concat([Buffer.alloc(1), Buffer.from(step2)]); -const step4 = bcoin.crypto.hash256(step3); +const step4 = bcoin.crypto.sha256(bcoin.crypto.sha256(step3)); // const step6 = crypto.sha256(step5); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); From e07ad9da16e33963b29b4217ca08fe51b30972f1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:07:07 +0100 Subject: [PATCH 043/540] Remove "bcoin." before "crypto" --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 47a5693..1aa868f 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -18,7 +18,7 @@ const pubKey = Buffer.from(pubKeyArray); const step2 = bcoin.crypto.hash160(pubKey); // const step3 = crypto.ripemd160(step2); const step3 = Buffer.concat([Buffer.alloc(1), Buffer.from(step2)]); -const step4 = bcoin.crypto.sha256(bcoin.crypto.sha256(step3)); +const step4 = crypto.sha256(crypto.sha256(step3)); // const step6 = crypto.sha256(step5); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); From 439581e6a86373d56d1d9b4c9853955e682054e0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:17:20 +0100 Subject: [PATCH 044/540] Use "bcoin.crypto.hash256()" --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 1aa868f..0be1b38 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -18,7 +18,7 @@ const pubKey = Buffer.from(pubKeyArray); const step2 = bcoin.crypto.hash160(pubKey); // const step3 = crypto.ripemd160(step2); const step3 = Buffer.concat([Buffer.alloc(1), Buffer.from(step2)]); -const step4 = crypto.sha256(crypto.sha256(step3)); +const step4 = bcoin.crypto.hash256(step3); // const step6 = crypto.sha256(step5); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); From d955c4fa5601ccacba6020a1c1bc807bf474c253 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:18:13 +0100 Subject: [PATCH 045/540] Add "hash256()" type --- flow-typed/npm/bcoin_vx.x.x.js | 1 + 1 file changed, 1 insertion(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index c6663cc..acfeeef 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -96,6 +96,7 @@ declare module 'bcoin' { }, crypto : { hash160(str : (string | Buffer)) : Hash + hash256(str : (string | Buffer)) : Hash } } } From 13bee497a4d31b80dd1604df3b4070b2d514ec90 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:21:29 +0100 Subject: [PATCH 046/540] Add missing comma (,) --- flow-typed/npm/bcoin_vx.x.x.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index acfeeef..36a355d 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -95,7 +95,7 @@ declare module 'bcoin' { Coin : Class }, crypto : { - hash160(str : (string | Buffer)) : Hash + hash160(str : (string | Buffer)) : Hash, hash256(str : (string | Buffer)) : Hash } } From 3b0a699124bf24b087b18c27002714854bb27a57 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:28:30 +0100 Subject: [PATCH 047/540] Add "base58()" type --- flow-typed/npm/bcoin_vx.x.x.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 36a355d..cf789da 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -97,6 +97,9 @@ declare module 'bcoin' { crypto : { hash160(str : (string | Buffer)) : Hash, hash256(str : (string | Buffer)) : Hash + }, + base58 : { + encode(str : (string | Buffer)) : Address } } } From 0f75dd2fb9877382346609d4e73f13f9abcba370 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:29:14 +0100 Subject: [PATCH 048/540] Make all steps' types buffers --- src/trust_is_risk.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0be1b38..34fc162 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -15,10 +15,10 @@ var DirectTrust = require("./direct_trust"); const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const pubKey = Buffer.from(pubKeyArray); -const step2 = bcoin.crypto.hash160(pubKey); +const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); // const step3 = crypto.ripemd160(step2); -const step3 = Buffer.concat([Buffer.alloc(1), Buffer.from(step2)]); -const step4 = bcoin.crypto.hash256(step3); +const step3 = Buffer.concat([Buffer.alloc(1), step2]); +const step4 = Buffer.from(bcoin.crypto.hash256(step3)); // const step6 = crypto.sha256(step5); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); From 3fc5f18f5f8f9ce1fd28d7450b5047edf3b63cab Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:32:55 +0100 Subject: [PATCH 049/540] Replace "Address" with "bcoin$Address" --- flow-typed/npm/bcoin_vx.x.x.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index cf789da..8a460f8 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -99,7 +99,7 @@ declare module 'bcoin' { hash256(str : (string | Buffer)) : Hash }, base58 : { - encode(str : (string | Buffer)) : Address + encode(str : (string | Buffer)) : bcoin$Address } } } From 58aa495b4a7063eee283ba407b907cc243a75588 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:36:22 +0100 Subject: [PATCH 050/540] Replace "bcoin$Address" with "Buffer" --- flow-typed/npm/bcoin_vx.x.x.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 8a460f8..676a00f 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -99,7 +99,7 @@ declare module 'bcoin' { hash256(str : (string | Buffer)) : Hash }, base58 : { - encode(str : (string | Buffer)) : bcoin$Address + encode(str : (string | Buffer)) : Buffer } } } From 6e925ef9872776ad39a0ed3f7feb2162ad14eff4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:41:07 +0100 Subject: [PATCH 051/540] Use tag creation from src/trust_is_risk.js --- test/helpers.js | 17 +++++++---------- test/trust_is_risk.js | 17 +++++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index bbf3864..f430979 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -8,16 +8,13 @@ var crypto = bcoin.crypto; var base58 = bcoin.base58; const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const publicKey = Buffer.from(publicKeyArray); -const step2 = crypto.sha256(publicKey); -const step3 = crypto.ripemd160(step2); -const step4 = Buffer.concat([Buffer.alloc(1), step3]); -const step5 = crypto.sha256(step4); -const step6 = crypto.sha256(step5); -const step7 = step6.slice(0, 4); -const step8 = Buffer.concat([step4, step7]); -const tag = base58.encode(step8); -// const tag = Buffer.from("1111111111111111111111111111111111"); +const pubKey = Buffer.from(pubKeyArray); +const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); +const step3 = Buffer.concat([Buffer.alloc(1), step2]); +const step4 = Buffer.from(bcoin.crypto.hash256(step3)); +const step5 = step4.slice(0, 4); +const step6 = Buffer.concat([step3, step5]); +const tag = bcoin.base58.encode(step6); var testHelpers = { getNode: async () => { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 32c5bbf..63a14b3 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -16,16 +16,13 @@ require("should-sinon"); const COIN = bcoin.consensus.COIN; const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const publicKey = Buffer.from(publicKeyArray); -const step2 = crypto.sha256(publicKey); -const step3 = crypto.ripemd160(step2); -const step4 = Buffer.concat([Buffer.alloc(1), step3]); -const step5 = crypto.sha256(step4); -const step6 = crypto.sha256(step5); -const step7 = step6.slice(0, 4); -const step8 = Buffer.concat([step4, step7]); -const tag = base58.encode(step8); -// const tag = Buffer.from("1111111111111111111111111111111111"); +const pubKey = Buffer.from(pubKeyArray); +const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); +const step3 = Buffer.concat([Buffer.alloc(1), step2]); +const step4 = Buffer.from(bcoin.crypto.hash256(step3)); +const step5 = step4.slice(0, 4); +const step6 = Buffer.concat([step3, step5]); +const tag = bcoin.base58.encode(step6); describe("TrustIsRisk", () => { var addr = {}; From 619274a912fa9f98b3221a71bb0d329181fcf4c2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:41:17 +0100 Subject: [PATCH 052/540] Remove commented out lines --- src/trust_is_risk.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 34fc162..0031826 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -16,14 +16,11 @@ var DirectTrust = require("./direct_trust"); const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const pubKey = Buffer.from(pubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); -// const step3 = crypto.ripemd160(step2); const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); -// const step6 = crypto.sha256(step5); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); const tag = bcoin.base58.encode(step6); -// const tag = Buffer.from("1111111111111111111111111111111111"); class TrustIsRisk { node : bcoin$FullNode From 821feaffc6cadef5f99334363092f2473a7b4a9d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:44:59 +0100 Subject: [PATCH 053/540] Rename "publicKeyArray" to "pubKeyArray" --- test/helpers.js | 2 +- test/trust_is_risk.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index f430979..3ba208c 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,7 +7,7 @@ var assert = require("assert"); var crypto = bcoin.crypto; var base58 = bcoin.base58; -const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const pubKey = Buffer.from(pubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 63a14b3..c9d505e 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -15,7 +15,7 @@ var base58 = require("bcoin/lib/utils/base58"); require("should-sinon"); const COIN = bcoin.consensus.COIN; -const publicKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; const pubKey = Buffer.from(pubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); From 73ec9ca22c0eee5e438e9c47797389fe8c331711 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:49:33 +0100 Subject: [PATCH 054/540] Rename "pubKey" to "fakePubKey" --- src/trust_is_risk.js | 6 +++--- test/helpers.js | 6 +++--- test/trust_is_risk.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0031826..a9a8c92 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,9 +13,9 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const pubKey = Buffer.from(pubKeyArray); -const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); +const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const fakePubKey = Buffer.from(fakePubKeyArray); +const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); const step5 = step4.slice(0, 4); diff --git a/test/helpers.js b/test/helpers.js index 3ba208c..41dda7e 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,9 +7,9 @@ var assert = require("assert"); var crypto = bcoin.crypto; var base58 = bcoin.base58; -const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const pubKey = Buffer.from(pubKeyArray); -const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); +const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const fakePubKey = Buffer.from(fakePubKeyArray); +const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); const step5 = step4.slice(0, 4); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c9d505e..7ea4f68 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -15,9 +15,9 @@ var base58 = require("bcoin/lib/utils/base58"); require("should-sinon"); const COIN = bcoin.consensus.COIN; -const pubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; -const pubKey = Buffer.from(pubKeyArray); -const step2 = Buffer.from(bcoin.crypto.hash160(pubKey)); +const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const fakePubKey = Buffer.from(fakePubKeyArray); +const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); const step5 = step4.slice(0, 4); From 9fb9eaaa1da4d3b4a683eded7653154f2a5b5461 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 22:53:29 +0100 Subject: [PATCH 055/540] Make fakePubKeyArray preetier --- src/trust_is_risk.js | 9 ++++++++- test/helpers.js | 9 ++++++++- test/trust_is_risk.js | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index a9a8c92..a9ee63f 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,7 +13,14 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/helpers.js b/test/helpers.js index 41dda7e..1e21169 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,7 +7,14 @@ var assert = require("assert"); var crypto = bcoin.crypto; var base58 = bcoin.base58; -const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 7ea4f68..1e894de 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -15,7 +15,14 @@ var base58 = require("bcoin/lib/utils/base58"); require("should-sinon"); const COIN = bcoin.consensus.COIN; -const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); From e4e9b9d712e2e77c89e3b51572b64fa62d67cbb9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Sep 2017 23:01:50 +0100 Subject: [PATCH 056/540] Add TODO comment to check tag --- test/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1e894de..4f4f544 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -51,6 +51,7 @@ describe("TrustIsRisk", () => { var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; beforeEach(() => { + // TODO: check that tag has correct type and format: Valid address, corresponding public key is "0x04Trust is Risk0x00..0x00" node = new bcoin.fullnode({}); tir = new Trust.TrustIsRisk(node); From 764dcc432b9c2187f6c84d57025d35b41dc3f058 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 11:36:16 +0100 Subject: [PATCH 057/540] Replace tabs with spaces --- src/trust_is_risk.js | 14 +++++++------- test/helpers.js | 14 +++++++------- test/trust_is_risk.js | 14 +++++++------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index a9ee63f..f98738d 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -14,13 +14,13 @@ var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/helpers.js b/test/helpers.js index 1e21169..839f1d7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -8,13 +8,13 @@ var crypto = bcoin.crypto; var base58 = bcoin.base58; const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 4f4f544..8e04431 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -16,13 +16,13 @@ require("should-sinon"); const COIN = bcoin.consensus.COIN; const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); From 33387a81226ebad5db1eb6f83c1824534884c8b6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 14:45:29 +0100 Subject: [PATCH 058/540] Turn tag from string to Buffer --- src/trust_is_risk.js | 2 +- test/helpers.js | 2 +- test/trust_is_risk.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index f98738d..50b07be 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -27,7 +27,7 @@ const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); -const tag = bcoin.base58.encode(step6); +const tag = Buffer.from(bcoin.base58.encode(step6)); class TrustIsRisk { node : bcoin$FullNode diff --git a/test/helpers.js b/test/helpers.js index 839f1d7..929bd1d 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -21,7 +21,7 @@ const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); -const tag = bcoin.base58.encode(step6); +const tag = Buffer.from(bcoin.base58.encode(step6)); var testHelpers = { getNode: async () => { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 8e04431..b4b0652 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -29,7 +29,7 @@ const step3 = Buffer.concat([Buffer.alloc(1), step2]); const step4 = Buffer.from(bcoin.crypto.hash256(step3)); const step5 = step4.slice(0, 4); const step6 = Buffer.concat([step3, step5]); -const tag = bcoin.base58.encode(step6); +const tag = Buffer.from(bcoin.base58.encode(step6)); describe("TrustIsRisk", () => { var addr = {}; From fa7d3b81451650ad4596731c6442d465d9444a04 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 17:42:57 +0100 Subject: [PATCH 059/540] Indent --- src/trust_is_risk.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 50b07be..14391ce 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -14,13 +14,13 @@ var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); From 95896bb5ded3eeb7594e8aca4cc84ea4a937fcdc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 17:43:26 +0100 Subject: [PATCH 060/540] Add tag validity and content tests --- test/trust_is_risk.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index b4b0652..bf86273 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -79,6 +79,24 @@ describe("TrustIsRisk", () => { }); }); + describe("tag", () => { + it("is a valid bitcoin address", () => { + assert(Address.fromString(tag.toString('ascii'))); + }); + + it("corresponds to a public key that contains \"Trust is Risk\"", () => { + const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; + bcoin.httpWallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + }); + }); + describe(".getDirectTrust()", () => { it("returns zero for two arbitary parties that do not trust each other", () => { tir.getDirectTrust(alice, bob).should.equal(0); From 152302d6ac7204daf69f354b4780e193c461543b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 17:47:50 +0100 Subject: [PATCH 061/540] Accept small identation --- src/trust_is_risk.js | 14 +++++++------- test/trust_is_risk.js | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 14391ce..50b07be 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -14,13 +14,13 @@ var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index bf86273..952e113 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -86,14 +86,14 @@ describe("TrustIsRisk", () => { it("corresponds to a public key that contains \"Trust is Risk\"", () => { const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; bcoin.httpWallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00]; }); }); From 1ffb083c432e17f1902cd6aa0f99568c899a0c7d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 17:49:12 +0100 Subject: [PATCH 062/540] Use should instead of assert() --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 952e113..0d3ffe2 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -81,7 +81,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("is a valid bitcoin address", () => { - assert(Address.fromString(tag.toString('ascii'))); + Address.fromString(tag.toString("ascii")).should.equal(1); }); it("corresponds to a public key that contains \"Trust is Risk\"", () => { From ba456d843934a5f6fce2576d406b6f7ec270e5e4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 17:49:41 +0100 Subject: [PATCH 063/540] Use wallet.getKey instead of httpWallet.getKey --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 0d3ffe2..4d61cc5 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -86,7 +86,6 @@ describe("TrustIsRisk", () => { it("corresponds to a public key that contains \"Trust is Risk\"", () => { const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - bcoin.httpWallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -94,6 +93,7 @@ describe("TrustIsRisk", () => { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + bcoin.wallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); }); }); From 7675547fa267938af5467755830c84a680ccb0f7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 17:53:16 +0100 Subject: [PATCH 064/540] Replace equal with exist --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 4d61cc5..e01aeb0 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -81,7 +81,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("is a valid bitcoin address", () => { - Address.fromString(tag.toString("ascii")).should.equal(1); + Address.fromString(tag.toString("ascii")).should.exist(1); }); it("corresponds to a public key that contains \"Trust is Risk\"", () => { From c5364583f79abb57a5e5b80009ded53a0ad8f7a1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 18:53:42 +0100 Subject: [PATCH 065/540] Make fake public key preetier --- src/trust_is_risk.js | 12 +++++------- test/helpers.js | 12 +++++------- test/trust_is_risk.js | 24 ++++++++++-------------- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 50b07be..023dcbe 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -14,13 +14,11 @@ var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/helpers.js b/test/helpers.js index 929bd1d..1ce9220 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -8,13 +8,11 @@ var crypto = bcoin.crypto; var base58 = bcoin.base58; const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index e01aeb0..d2d2847 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -16,13 +16,11 @@ require("should-sinon"); const COIN = bcoin.consensus.COIN; const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00]; const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); @@ -86,13 +84,11 @@ describe("TrustIsRisk", () => { it("corresponds to a public key that contains \"Trust is Risk\"", () => { const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00]; + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00]; bcoin.wallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); }); }); From d1a761a4145897888110e91e24de9ca7b90bc0f7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 19:30:20 +0100 Subject: [PATCH 066/540] Remove unneeded crypto and base58 vars --- test/helpers.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 1ce9220..7715c08 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -4,8 +4,6 @@ var bcoin = require("bcoin"); var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); -var crypto = bcoin.crypto; -var base58 = bcoin.base58; const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, From f0b0c69436969b99328ef5c1a4d29fe425658372 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 20:09:01 +0100 Subject: [PATCH 067/540] Add "HDPublicKey" type --- flow-typed/npm/bcoin_vx.x.x.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 676a00f..db7d461 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -100,6 +100,9 @@ declare module 'bcoin' { }, base58 : { encode(str : (string | Buffer)) : Buffer + }, + HDPublicKey : { + fromBase58(str : (string | Buffer)) : Buffer } } } From 15d2500523f88eab51e845521beaab17a550a813 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 20:09:39 +0100 Subject: [PATCH 068/540] Require "assert" --- test/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index d2d2847..d6fb21d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -12,6 +12,7 @@ var should = require("should"); var fixtures = require("./fixtures"); var crypto = require("bcoin/lib/crypto"); var base58 = require("bcoin/lib/utils/base58"); +var assert = require("assert"); require("should-sinon"); const COIN = bcoin.consensus.COIN; From a2680bb5abbc644364a979232aca17682d418167 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 20:10:30 +0100 Subject: [PATCH 069/540] Replace "should" with "assert" --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index d6fb21d..2009b6a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -80,7 +80,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("is a valid bitcoin address", () => { - Address.fromString(tag.toString("ascii")).should.exist(1); + assert.ok(Address.fromString(tag.toString("ascii"))); }); it("corresponds to a public key that contains \"Trust is Risk\"", () => { From 35ab49ad17c98e605c537666b4459fe4ee278b7a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Sep 2017 20:11:12 +0100 Subject: [PATCH 070/540] Play with Address to Public Key function --- test/trust_is_risk.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 2009b6a..82d8841 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -90,7 +90,8 @@ describe("TrustIsRisk", () => { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - bcoin.wallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + bcoin.prototype.HDPublicKey.fromBase58(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + bcoin.http.Wallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); }); }); From 8fbcd6f52848830a797df675ce51c3463c552e61 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 19:57:31 +0100 Subject: [PATCH 071/540] Add package-lock.json --- package-lock.json | 3062 +++++++++++++++++++++++++++++++++++++++++ test/trust_is_risk.js | 2 +- 2 files changed, 3063 insertions(+), 1 deletion(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d417c2e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3062 @@ +{ + "name": "trust-is-risk", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=" + }, + "abstract-leveldown": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "optional": true, + "requires": { + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "accepts": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", + "integrity": "sha1-1xyW99QdD+2iw4zRToonwEFY30o=", + "optional": true, + "requires": { + "mime-types": "2.0.14", + "negotiator": "0.4.9" + }, + "dependencies": { + "mime-db": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", + "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=", + "optional": true + }, + "mime-types": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", + "optional": true, + "requires": { + "mime-db": "1.12.0" + } + } + } + }, + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha1-kRy1PgNoB88Pp3jcXTcPvYZCRtc=", + "dev": true + }, + "acorn-jsx": { + "version": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz" + }, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "optional": true + }, + "ajv": { + "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" + } + }, + "ajv-keywords": { + "version": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" + }, + "ansi-escapes": { + "version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "aproba": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", + "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "requires": { + "delegates": "1.0.0", + "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz" + } + }, + "argparse": { + "version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + } + }, + "array-index": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz", + "integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=", + "optional": true, + "requires": { + "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" + } + }, + "array-union": { + "version": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + } + }, + "array-uniq": { + "version": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=" + }, + "arrify": { + "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "babel-code-frame": { + "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "js-tokens": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" + } + }, + "babel-eslint": { + "version": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "dev": true, + "requires": { + "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "babel-traverse": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "babel-types": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "babylon": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz" + } + }, + "babel-messages": { + "version": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" + } + }, + "babel-runtime": { + "version": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "regenerator-runtime": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz" + } + }, + "babel-traverse": { + "version": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "babel-messages": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "babel-types": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "babylon": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "globals": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "invariant": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" + } + }, + "babel-types": { + "version": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "to-fast-properties": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz" + } + }, + "babylon": { + "version": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha1-ry87iPpvXB5MY00aD46sT1WzleM=", + "dev": true + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "optional": true + }, + "balanced-match": { + "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-arraybuffer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz", + "integrity": "sha1-R030qfLaJOBd8xWMOx2zw81GoVQ=" + }, + "base64id": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz", + "integrity": "sha1-As4P3u4M709ACA4ec+g08LG/zj8=", + "optional": true + }, + "bcoin": { + "version": "1.0.0-beta.12", + "resolved": "https://registry.npmjs.org/bcoin/-/bcoin-1.0.0-beta.12.tgz", + "integrity": "sha1-hb+4F/VjDlnKsLeHv51DaPwSRsQ=", + "requires": { + "bcoin-native": "0.0.14", + "bn.js": "4.11.6", + "elliptic": "6.3.2", + "leveldown": "1.5.0", + "secp256k1": "3.2.5", + "socket.io": "1.4.8", + "socket.io-client": "1.4.8" + } + }, + "bcoin-native": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/bcoin-native/-/bcoin-native-0.0.14.tgz", + "integrity": "sha1-gRvFFbIJRlvnGESsPzo7kO+J9BE=", + "optional": true, + "requires": { + "bindings": "1.2.1", + "nan": "2.5.1" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "benchmark": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz", + "integrity": "sha1-Lx4vpMNZ8REiqhgwgiGOlX45DHM=" + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, + "bindings": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", + "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=", + "optional": true + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "optional": true, + "requires": { + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + }, + "bl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz", + "integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=", + "requires": { + "readable-stream": "2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "string_decoder": "0.10.31", + "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + } + }, + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-stdout": { + "version": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserify-aes": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz", + "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==", + "optional": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "optional": true + }, + "caller-path": { + "version": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, + "callsites": { + "version": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "has-ansi": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + } + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "optional": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + }, + "circular-json": { + "version": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", + "dev": true + }, + "cli-cursor": { + "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz" + } + }, + "cli-width": { + "version": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "optional": true + }, + "component-emitter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "optional": true + }, + "concat-map": { + "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "typedarray": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "core-js": { + "version": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", + "dev": true + }, + "core-util-is": { + "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "requires": { + "cipher-base": "1.0.4", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "ripemd160": "2.0.1", + "sha.js": "2.4.8" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "optional": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "ripemd160": "2.0.1", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "sha.js": "2.4.8" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.10.1" + } + }, + "d": { + "version": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "debug": { + "version": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "requires": { + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + } + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "optional": true + }, + "deep-is": { + "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "is-path-cwd": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "is-path-in-cwd": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "diff": { + "version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "doctrine": { + "version": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true, + "requires": { + "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "optional": true, + "requires": { + "browserify-aes": "1.0.8", + "create-hash": "1.1.3", + "create-hmac": "1.1.6" + } + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "elliptic": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.2.tgz", + "integrity": "sha1-5MgeCCnPCmWrcOmYuCMnI7XBvEg=", + "requires": { + "bn.js": "4.11.6", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + } + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "requires": { + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + } + }, + "engine.io": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.6.11.tgz", + "integrity": "sha1-JTOpemWHbED/z5U5e375tJXEI/4=", + "optional": true, + "requires": { + "accepts": "1.1.4", + "base64id": "0.1.0", + "debug": "2.2.0", + "engine.io-parser": "1.2.4", + "ws": "1.1.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "optional": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "optional": true + } + } + }, + "engine.io-client": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.6.11.tgz", + "integrity": "sha1-fSUNj6HCGBGezeUTkEWKV9UXE3Y=", + "optional": true, + "requires": { + "component-emitter": "1.1.2", + "component-inherit": "0.0.3", + "debug": "2.2.0", + "engine.io-parser": "1.2.4", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parsejson": "0.0.1", + "parseqs": "0.0.2", + "parseuri": "0.0.4", + "ws": "1.0.1", + "xmlhttprequest-ssl": "1.5.1", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "optional": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "optional": true + }, + "ws": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz", + "integrity": "sha1-fQsqLljN3YGQOcKcneZQReGzEOk=", + "optional": true, + "requires": { + "options": "0.0.6", + "ultron": "1.0.2" + } + } + } + }, + "engine.io-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.2.4.tgz", + "integrity": "sha1-4Il7C/FOeS1M0qWVBVORnFaUjEI=", + "requires": { + "after": "0.8.1", + "arraybuffer.slice": "0.0.6", + "base64-arraybuffer": "0.1.2", + "blob": "0.0.4", + "has-binary": "0.1.6", + "utf8": "2.1.0" + }, + "dependencies": { + "after": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.1.tgz", + "integrity": "sha1-q11PuIP1loFtNRX495HAr0ht1ic=" + }, + "has-binary": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.6.tgz", + "integrity": "sha1-JTJvOc+k9hath4eJTjryz7x7bhA=", + "requires": { + "isarray": "0.0.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "es5-ext": { + "version": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", + "requires": { + "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" + } + }, + "es6-iterator": { + "version": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "requires": { + "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" + } + }, + "es6-map": { + "version": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "es6-set": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "event-emitter": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz" + } + }, + "es6-set": { + "version": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "event-emitter": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz" + } + }, + "es6-symbol": { + "version": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz" + } + }, + "es6-weak-map": { + "version": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" + } + }, + "escape-string-regexp": { + "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escope": { + "version": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "es6-weak-map": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "esrecurse": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" + } + }, + "eslint": { + "version": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "concat-stream": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "doctrine": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "escope": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "espree": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", + "esquery": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "file-entry-cache": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "globals": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "ignore": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "imurmurhash": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "inquirer": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "is-my-json-valid": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "is-resolvable": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "js-yaml": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", + "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "levn": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "natural-compare": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "optionator": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "path-is-inside": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "pluralize": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "progress": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "require-uncached": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "shelljs": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "strip-bom": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "table": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "text-table": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "user-home": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz" + } + }, + "eslint-plugin-flowtype": { + "version": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.35.1.tgz", + "integrity": "sha1-mtmBgbRno2RfvSqNQwOTzBek6mM=", + "dev": true, + "requires": { + "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" + } + }, + "espree": { + "version": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", + "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=", + "dev": true, + "requires": { + "acorn": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "acorn-jsx": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz" + } + }, + "esprima": { + "version": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", + "dev": true + }, + "esquery": { + "version": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" + } + }, + "esrecurse": { + "version": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + } + }, + "estraverse": { + "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "optional": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + }, + "execspawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/execspawn/-/execspawn-1.0.1.tgz", + "integrity": "sha1-gob53efOzeeQX73ATiTzaPI/jaY=", + "optional": true, + "requires": { + "util-extend": "1.0.3" + } + }, + "exit-hook": { + "version": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz", + "integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==", + "optional": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-future": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", + "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=", + "optional": true + }, + "fast-levenshtein": { + "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + } + }, + "file-entry-cache": { + "version": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + } + }, + "flat-cache": { + "version": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "dev": true, + "requires": { + "circular-json": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "del": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "write": "https://registry.npmjs.org/write/-/write-0.2.1.tgz" + } + }, + "flow-bin": { + "version": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", + "integrity": "sha1-AJ3Q9Xej9mXHTKi+gnrowt2P1rU=", + "dev": true + }, + "flow-remove-types": { + "version": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.1.tgz", + "integrity": "sha1-WOJhv4uEK9I0yGyvuYKhITr/Dts=", + "dev": true, + "requires": { + "babylon": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "vlq": "https://registry.npmjs.org/vlq/-/vlq-0.2.2.tgz" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "formatio": { + "version": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz" + } + }, + "fs.realpath": { + "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz" + } + }, + "gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", + "requires": { + "ansi": "0.3.1", + "has-unicode": "2.0.1", + "lodash.pad": "4.5.1", + "lodash.padend": "4.6.1", + "lodash.padstart": "4.6.1" + } + }, + "generate-function": { + "version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "ghreleases": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ghreleases/-/ghreleases-1.0.6.tgz", + "integrity": "sha512-uySVPT5T9uP1xeWR7nl3WD8/JjJJXAph/0zdgUQJ7ovFpL3rxBT/HT0sO6w0GDWCj2gwXvzxBKrIeJAgBhs+fw==", + "optional": true, + "requires": { + "after": "0.8.2", + "ghrepos": "2.0.0", + "ghutils": "3.2.1", + "simple-mime": "0.1.0", + "url-template": "2.0.8", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "ghrepos": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ghrepos/-/ghrepos-2.0.0.tgz", + "integrity": "sha1-1m6unZijtTmORg1tt+EKdCaS6Bs=", + "optional": true, + "requires": { + "ghutils": "3.2.1" + } + }, + "ghutils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ghutils/-/ghutils-3.2.1.tgz", + "integrity": "sha1-T87f+sk1/KzgbhKhfGF04sKf/k8=", + "requires": { + "jsonist": "1.3.0", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "optional": true + }, + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "requires": { + "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + } + }, + "globals": { + "version": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", + "dev": true + }, + "globby": { + "version": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "arrify": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + } + }, + "graceful-fs": { + "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "graceful-readlink": { + "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "graph-theory-ford-fulkerson": { + "version": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", + "integrity": "sha1-LDHSHXDxp9KCiZX+BnZFdv9/nik=" + }, + "growl": { + "version": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "requires": { + "ajv": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "har-schema": "1.0.5" + } + }, + "has-ansi": { + "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + } + }, + "has-binary": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", + "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "optional": true + }, + "has-flag": { + "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "minimalistic-assert": "1.0.0" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "hyperquest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-1.2.0.tgz", + "integrity": "sha1-OeH+9miI3Hzg3sbA3YFPb8iUStU=", + "requires": { + "duplexer2": "0.0.2", + "through2": "0.6.5" + } + }, + "ignore": { + "version": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=", + "dev": true + }, + "imurmurhash": { + "version": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + }, + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "optional": true + }, + "inquirer": { + "version": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "cli-cursor": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "cli-width": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "figures": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "readline2": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "run-async": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "rx-lite": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "through": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + } + }, + "interpret": { + "version": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "dev": true + }, + "invariant": { + "version": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz" + } + }, + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + } + }, + "is-my-json-valid": { + "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha1-WoRnd+LCYg0eaRBOXToDsfYIjxE=", + "dev": true, + "requires": { + "generate-function": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "generate-object-property": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "jsonpointer": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "is-path-cwd": { + "version": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz" + } + }, + "is-path-inside": { + "version": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" + } + }, + "is-property": { + "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "js-tokens": { + "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", + "integrity": "sha1-CHdc69/dNZIJ8NKs04PI+GppBKA=", + "dev": true, + "requires": { + "argparse": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "esprima": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-stable-stringify": { + "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "jsonify": { + "version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonist": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsonist/-/jsonist-1.3.0.tgz", + "integrity": "sha1-wMdLle8clSA4YZsp76UgscyYdVY=", + "requires": { + "bl": "1.0.3", + "hyperquest": "1.2.0", + "json-stringify-safe": "5.0.1", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "jsonpointer": { + "version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "leveldown": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-1.5.0.tgz", + "integrity": "sha1-a408vqekqJqkdERgfXNYIT5vy4E=", + "optional": true, + "requires": { + "abstract-leveldown": "2.6.3", + "bindings": "1.2.1", + "fast-future": "1.0.2", + "nan": "2.4.0", + "prebuild": "4.5.0" + }, + "dependencies": { + "nan": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz", + "integrity": "sha1-+zxZ1F/k7/4hXwuJD4rfbrMtIjI=", + "optional": true + } + } + }, + "levn": { + "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "type-check": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" + } + }, + "lodash": { + "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash._baseassign": { + "version": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" + } + }, + "lodash._basecopy": { + "version": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "lodash._basecreate": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "lodash._isiterateecall": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" + } + }, + "lodash.isarguments": { + "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "lodash.isarguments": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "lodash.isarray": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" + } + }, + "lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=" + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=" + }, + "lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" + }, + "lolex": { + "version": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true + }, + "loose-envify": { + "version": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" + } + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "optional": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "optional": true, + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + } + } + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" + }, + "minimatch": { + "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "requires": { + "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + }, + "dependencies": { + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "mocha": { + "version": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", + "integrity": "sha1-EyhWfScX+ZcDD4AGI0vOm4zXJGU=", + "dev": true, + "requires": { + "browser-stdout": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "commander": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "growl": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "json3": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "lodash.create": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz" + }, + "dependencies": { + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + } + }, + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz" + } + } + } + }, + "ms": { + "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "nan": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz", + "integrity": "sha1-1bAWkSUzJql6K77p5hxV2NYDUeI=", + "optional": true + }, + "native-promise-only": { + "version": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "natural-compare": { + "version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", + "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=", + "optional": true + }, + "node-abi": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.1.tgz", + "integrity": "sha512-6oxV13poCOv7TfGvhsSz6XZWpXeKkdGVh72++cs33OfMh3KAX8lN84dCvmqSETyDXAFcUHtV7eJrgFBoOqZbNQ==", + "optional": true + }, + "node-gyp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", + "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "optional": true, + "requires": { + "fstream": "1.0.11", + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "nopt": "3.0.6", + "npmlog": "2.0.4", + "osenv": "0.1.4", + "request": "2.81.0", + "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.3.0" + } + }, + "node-ninja": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/node-ninja/-/node-ninja-1.0.2.tgz", + "integrity": "sha1-IKCeV7kuLfWRmT1L8JisPnJwYrY=", + "optional": true, + "requires": { + "fstream": "1.0.11", + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "nopt": "3.0.6", + "npmlog": "2.0.4", + "osenv": "0.1.4", + "path-array": "1.0.1", + "request": "2.81.0", + "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.3.0" + } + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "optional": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.0" + } + }, + "npmlog": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", + "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "requires": { + "ansi": "0.3.1", + "are-we-there-yet": "1.1.4", + "gauge": "1.2.7" + } + }, + "number-is-nan": { + "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "optional": true + }, + "once": { + "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + } + }, + "onetime": { + "version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "fast-levenshtein": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "levn": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "prelude-ls": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "type-check": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "wordwrap": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" + }, + "os-homedir": { + "version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "requires": { + "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "os-tmpdir": "1.0.2" + } + }, + "parsejson": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.1.tgz", + "integrity": "sha1-mxDGwNglq1ieaFFTgm3go7oni8w=", + "optional": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseqs": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.2.tgz", + "integrity": "sha1-nf5wss3aw4i95PNbHyQPpYrb5sc=", + "optional": true, + "requires": { + "better-assert": "1.0.2" + } + }, + "parseuri": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.4.tgz", + "integrity": "sha1-gGWCo5iH4eoY3V4v4OAZAiaOk1A=", + "requires": { + "better-assert": "1.0.2" + } + }, + "path-array": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.1.tgz", + "integrity": "sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE=", + "optional": true, + "requires": { + "array-index": "1.0.0" + } + }, + "path-is-absolute": { + "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-to-regexp": { + "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + }, + "pify": { + "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + } + }, + "pluralize": { + "version": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "prebuild": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/prebuild/-/prebuild-4.5.0.tgz", + "integrity": "sha1-KqoN8gY7/4FKgDvU3JT/m2Tl3wA=", + "optional": true, + "requires": { + "async": "1.5.2", + "execspawn": "1.0.1", + "expand-template": "1.1.0", + "ghreleases": "1.0.6", + "github-from-package": "0.0.0", + "minimist": "1.2.0", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "node-gyp": "3.6.2", + "node-ninja": "1.0.2", + "noop-logger": "0.1.1", + "npmlog": "2.0.4", + "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "pump": "1.0.2", + "rc": "1.2.1", + "simple-get": "1.4.3", + "tar-fs": "1.15.3", + "tar-stream": "1.5.4", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "prebuild-install": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.2.tgz", + "integrity": "sha512-F46pcvDxtQhbV3B+dm+exHuKxIyJK26fVNiJRmbTW/5D7o0Z2yzc8CKeu7UWbo9XxQZoVOC88aKgySAsza+cWw==", + "optional": true, + "requires": { + "expand-template": "1.1.0", + "github-from-package": "0.0.0", + "minimist": "1.2.0", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "node-abi": "2.1.1", + "noop-logger": "0.1.1", + "npmlog": "4.1.2", + "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "pump": "1.0.2", + "rc": "1.2.1", + "simple-get": "1.4.3", + "tar-fs": "1.15.3", + "tunnel-agent": "0.6.0", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + }, + "dependencies": { + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "1.1.2", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "signal-exit": "3.0.2", + "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "wide-align": "1.1.2" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + } + } + }, + "prelude-ls": { + "version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "progress": { + "version": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "pump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", + "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "requires": { + "end-of-stream": "1.4.0", + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + }, + "rc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + } + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", + "requires": { + "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + }, + "readline2": { + "version": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "mute-stream": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" + } + }, + "rechoir": { + "version": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz" + } + }, + "regenerator-runtime": { + "version": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha1-flT+W1zNXWYk6mJVw0c74JC4AuE=", + "dev": true + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "require-uncached": { + "version": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "resolve-from": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz" + } + }, + "resolve": { + "version": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha1-p1vgHFPaJdk0qY69DkxKcxL5KoY=", + "dev": true, + "requires": { + "path-parse": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz" + } + }, + "resolve-from": { + "version": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "onetime": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz" + } + }, + "rimraf": { + "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "requires": { + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz" + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "requires": { + "hash-base": "2.0.2", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + } + }, + "run-async": { + "version": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + } + }, + "rx-lite": { + "version": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" + }, + "samsam": { + "version": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", + "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=", + "dev": true + }, + "secp256k1": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.2.5.tgz", + "integrity": "sha1-Dd5bJ+UCFmX23/ynssPgEMbBPJM=", + "optional": true, + "requires": { + "bindings": "1.2.1", + "bip66": "1.1.5", + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "drbg.js": "1.0.1", + "elliptic": "6.3.2", + "nan": "2.5.1", + "prebuild-install": "2.2.2" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "sha.js": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", + "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "requires": { + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + } + }, + "shelljs": { + "version": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "interpret": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "rechoir": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" + } + }, + "should": { + "version": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", + "integrity": "sha1-kPVRRVUtAc/CAGZuToGKHJZw7aI=", + "dev": true, + "requires": { + "should-equal": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", + "should-format": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "should-type-adaptors": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz", + "should-util": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz" + } + }, + "should-equal": { + "version": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", + "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", + "dev": true, + "requires": { + "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz" + } + }, + "should-format": { + "version": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "dev": true, + "requires": { + "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "should-type-adaptors": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz" + } + }, + "should-sinon": { + "version": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.5.tgz", + "integrity": "sha1-/8ioUb9FB2fn0K0i/4cVZQvpUOQ=", + "dev": true + }, + "should-type": { + "version": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "dev": true + }, + "should-type-adaptors": { + "version": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz", + "integrity": "sha1-7+VVPN9oz/ZuXF9RtxLcNRx3vqo=", + "dev": true, + "requires": { + "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "should-util": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz" + } + }, + "should-util": { + "version": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", + "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "optional": true + }, + "simple-get": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz", + "integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=", + "optional": true, + "requires": { + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "unzip-response": "1.0.2", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "simple-mime": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/simple-mime/-/simple-mime-0.1.0.tgz", + "integrity": "sha1-lfUXxPRm18/1YacfydqyWW6p7y4=", + "optional": true + }, + "sinon": { + "version": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", + "integrity": "sha1-Ah/WS1TLd9nS+w1Dze3652KcOjY=", + "dev": true, + "requires": { + "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "formatio": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "lolex": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "native-promise-only": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "path-to-regexp": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "samsam": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", + "text-encoding": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "type-detect": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz" + } + }, + "slice-ansi": { + "version": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.16.3" + } + }, + "socket.io": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.4.8.tgz", + "integrity": "sha1-5XbzMM0L7WTlWz/SbfmRFBiEhns=", + "optional": true, + "requires": { + "debug": "2.2.0", + "engine.io": "1.6.11", + "has-binary": "0.1.7", + "socket.io-adapter": "0.4.0", + "socket.io-client": "1.4.8", + "socket.io-parser": "2.2.6" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "optional": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "optional": true + } + } + }, + "socket.io-adapter": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.4.0.tgz", + "integrity": "sha1-+5+CqxqmUpC/csNleVW5MKmRok8=", + "optional": true, + "requires": { + "debug": "2.2.0", + "socket.io-parser": "2.2.2" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "optional": true, + "requires": { + "ms": "0.7.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "optional": true + }, + "json3": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.2.6.tgz", + "integrity": "sha1-9u/JPAagTemuxTBT3yVZuxniA4s=", + "optional": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "optional": true + }, + "socket.io-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.2.tgz", + "integrity": "sha1-PXr2tkSX6Va32f53X5mXFgJ/lBc=", + "optional": true, + "requires": { + "benchmark": "1.0.0", + "component-emitter": "1.1.2", + "debug": "0.7.4", + "isarray": "0.0.1", + "json3": "3.2.6" + }, + "dependencies": { + "debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", + "optional": true + } + } + } + } + }, + "socket.io-client": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.4.8.tgz", + "integrity": "sha1-SBskHnPfFA6hpPsDSGqFrQl/VVg=", + "optional": true, + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "1.2.0", + "debug": "2.2.0", + "engine.io-client": "1.6.11", + "has-binary": "0.1.7", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseuri": "0.0.4", + "socket.io-parser": "2.2.6", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.0.tgz", + "integrity": "sha1-zNETqGOI0GSC0D3j/H35hSa6jv4=", + "optional": true + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "optional": true, + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "optional": true + } + } + }, + "socket.io-parser": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.6.tgz", + "integrity": "sha1-ON/WHfUNz4qx2eIJEyK/kCuii5k=", + "requires": { + "benchmark": "1.0.0", + "component-emitter": "1.1.2", + "debug": "2.2.0", + "isarray": "0.0.1", + "json3": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "sorted-set": { + "version": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", + "integrity": "sha1-POAVeFtkdPH6A6HGn/8ymFL8N+M=" + }, + "sprintf-js": { + "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "requires": { + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + }, + "string-width": { + "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + } + }, + "strip-bom": { + "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "ajv-keywords": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "slice-ansi": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "string-width": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + }, + "dependencies": { + "ansi-regex": { + "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "dev": true, + "requires": { + "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + } + }, + "strip-ansi": { + "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz" + } + } + } + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + } + }, + "tar-fs": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz", + "integrity": "sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA=", + "optional": true, + "requires": { + "chownr": "1.0.1", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "pump": "1.0.2", + "tar-stream": "1.5.4" + } + }, + "tar-stream": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", + "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", + "requires": { + "bl": "1.0.3", + "end-of-stream": "1.4.0", + "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + }, + "text-encoding": { + "version": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "text-table": { + "version": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "optional": true + }, + "to-fast-properties": { + "version": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "requires": { + "punycode": "1.4.1" + } + }, + "tryit": { + "version": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-check": { + "version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" + } + }, + "type-detect": { + "version": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", + "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", + "dev": true + }, + "typedarray": { + "version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" + }, + "unzip-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", + "optional": true + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "optional": true + }, + "user-home": { + "version": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" + } + }, + "utf8": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.0.tgz", + "integrity": "sha1-DP7FyAUtRKI+OqqQgQToB1+V39U=" + }, + "util-deprecate": { + "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", + "optional": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "extsprintf": "1.3.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "vlq": { + "version": "https://registry.npmjs.org/vlq/-/vlq-0.2.2.tgz", + "integrity": "sha1-4xbVJXtAuGu0PLjV/qXX9U1rDKE=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "requires": { + "isexe": "2.0.0" + } + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "optional": true, + "requires": { + "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + } + }, + "wordwrap": { + "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" + } + }, + "ws": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.0.tgz", + "integrity": "sha1-wdb9FRXTzv8fCuJ1m/X9dwMKrR0=", + "optional": true, + "requires": { + "options": "0.0.6", + "ultron": "1.0.2" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.1.tgz", + "integrity": "sha1-O3dB/qSoZnWXbpCNKW1ERZYfqmc=", + "optional": true + }, + "xtend": { + "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "optional": true + } + } +} diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 82d8841..cf5ee8b 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -188,7 +188,7 @@ describe("TrustIsRisk", () => { // By changing the trust recipient from bob to charlie, we make the transaction a // nullifying trust transaction. trustDecreasingMTX.outputs[0] = - testHelpers.getOneOfTwoMultisigOutput(addr.alice.pubKey, addr.charlie.pubKey, 20 * COIN); + testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.charlie.pubKey, 20 * COIN); tir.addTX(trustDecreasingMTX.toTX()); tir.getDirectTrust(alice, bob).should.equal(0); From 037189b1dfbfe62edeb803d394e013988f456de8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 22:09:03 +0100 Subject: [PATCH 072/540] Remove unneeded requires --- test/trust_is_risk.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index cf5ee8b..f59c791 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -10,8 +10,6 @@ var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); var should = require("should"); var fixtures = require("./fixtures"); -var crypto = require("bcoin/lib/crypto"); -var base58 = require("bcoin/lib/utils/base58"); var assert = require("assert"); require("should-sinon"); From 3a9c031646ca2e274476c3f94745106bae2679e4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 22:09:35 +0100 Subject: [PATCH 073/540] Prepend "Address" with "bcoin.primitives." --- test/trust_is_risk.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index f59c791..306de19 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -78,7 +78,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("is a valid bitcoin address", () => { - assert.ok(Address.fromString(tag.toString("ascii"))); + assert.ok(bcoin.primitives.Address.fromString(tag.toString("ascii"))); }); it("corresponds to a public key that contains \"Trust is Risk\"", () => { @@ -88,8 +88,8 @@ describe("TrustIsRisk", () => { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - bcoin.prototype.HDPublicKey.fromBase58(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); - bcoin.http.Wallet.getKey(Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + bcoin.prototype.HDPublicKey.fromBase58(bcoin.primitives.Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + bcoin.http.Wallet.getKey(bcoin.primitives.Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); }); }); From 88a190a7071ae185d2f2a15410486d016ae4a582 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 23:16:51 +0100 Subject: [PATCH 074/540] Remove HDPublicKey --- flow-typed/npm/bcoin_vx.x.x.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index db7d461..f1a55da 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -101,9 +101,6 @@ declare module 'bcoin' { base58 : { encode(str : (string | Buffer)) : Buffer }, - HDPublicKey : { - fromBase58(str : (string | Buffer)) : Buffer - } } } From 78fed482444e3a5d2000b1c603c4551c9d99b18e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 23:17:46 +0100 Subject: [PATCH 075/540] Add secp256k1 --- test/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 306de19..0cd49e3 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -7,6 +7,7 @@ var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); +var secp256k1 = bcoin.crypto.ec-secp256k1; var sinon = require("sinon"); var should = require("should"); var fixtures = require("./fixtures"); From 7f766599e411a9ea90142da88c996d0f59204127 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 23:18:14 +0100 Subject: [PATCH 076/540] Add fakePubKey verification test --- test/trust_is_risk.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 0cd49e3..94af402 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -78,6 +78,10 @@ describe("TrustIsRisk", () => { }); describe("tag", () => { + it("corresponds to a valid public key", () => { + assert(bcoin.crypto.publicKeyVerify(fakePubKey)); + }); + it("is a valid bitcoin address", () => { assert.ok(bcoin.primitives.Address.fromString(tag.toString("ascii"))); }); From 86ea4bcf1624da40cff0e6d24d5c9931554dfd2d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 23:18:40 +0100 Subject: [PATCH 077/540] Remove ".ok" from "assert" --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 94af402..e83bafd 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -83,7 +83,7 @@ describe("TrustIsRisk", () => { }); it("is a valid bitcoin address", () => { - assert.ok(bcoin.primitives.Address.fromString(tag.toString("ascii"))); + assert(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))); }); it("corresponds to a public key that contains \"Trust is Risk\"", () => { From 5457bda4d8c355da1fc5888186301d311ed5156e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 12 Sep 2017 23:19:17 +0100 Subject: [PATCH 078/540] Replace "fromString" with "fromBase58", comment --- test/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index e83bafd..1df4527 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -93,8 +93,8 @@ describe("TrustIsRisk", () => { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - bcoin.prototype.HDPublicKey.fromBase58(bcoin.primitives.Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); - bcoin.http.Wallet.getKey(bcoin.primitives.Address.fromString(tag.toString("ascii"))).should.equal(fakePubKeyArray); + //bcoin.primitives.HDPublicKey.fromBase58(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))).should.equal(fakePubKeyArray); + bcoin.http.Wallet.getKey(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))).should.equal(Buffer.from(fakePubKey)); }); }); From 32085a9ff2b34926deabf2f07a17a3c12a8c6b7b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 13 Sep 2017 20:58:13 +0100 Subject: [PATCH 079/540] Verify fake public key correctly --- test/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1df4527..6775945 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -7,7 +7,7 @@ var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); -var secp256k1 = bcoin.crypto.ec-secp256k1; +var secp256k1 = require("bcoin/lib/crypto/ec-secp256k1"); var sinon = require("sinon"); var should = require("should"); var fixtures = require("./fixtures"); @@ -79,7 +79,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { - assert(bcoin.crypto.publicKeyVerify(fakePubKey)); + assert(secp256k1.publicKeyVerify(fakePubKey)); }); it("is a valid bitcoin address", () => { From 52cf7d66e36401787d8d34f29c6d2cd4349eff9d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 13 Sep 2017 20:58:43 +0100 Subject: [PATCH 080/540] Remove old fake public key --- test/trust_is_risk.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 6775945..2fc85d7 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -87,12 +87,6 @@ describe("TrustIsRisk", () => { }); it("corresponds to a public key that contains \"Trust is Risk\"", () => { - const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00]; //bcoin.primitives.HDPublicKey.fromBase58(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))).should.equal(fakePubKeyArray); bcoin.http.Wallet.getKey(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))).should.equal(Buffer.from(fakePubKey)); }); From db912b5dea6c53b39e791960c1f975dc7d9f7b52 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 13 Sep 2017 21:00:36 +0100 Subject: [PATCH 081/540] Add tag generator This script shows how the fake public key which corresponds to the tag "address" was generated. --- test/tag-generator.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/tag-generator.py diff --git a/test/tag-generator.py b/test/tag-generator.py new file mode 100644 index 0000000..3bab049 --- /dev/null +++ b/test/tag-generator.py @@ -0,0 +1,27 @@ +# Thanks to http://code.activestate.com/recipes/577821-integer-square-root-function/ for isqrt() +def isqrt(x): + if x < 0: + raise ValueError('square root not defined for negative numbers') + n = int(x) + if n == 0: + return 0 + a, b = divmod(n.bit_length(), 2) + x = 2**(a+b) + while True: + y = (x + n//x)//2 + if y >= x: + return x + x = y + +x = 0x5472757374206973205269736b00000000000000000000000000000000000000 +# 54:72:75:73:74:20:69:73:20:52:69:73:6b is the ASCII representation of "Trust is Risk" +p = 2**256 - 2**32 - 977 +y = pow((x**3 + 7), (p+1)//4, p) + +while ((y**2) % p) != (x**3 + 7) % p: + x=x+1 + y = pow((x**3 + 7), (p+1)//4, p) + +print("Found it!") +print("x is " + hex(x)) +print("y is " + hex(y)) From d96f244c991896c36c540ac0783d8d9f893983ad Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 13 Sep 2017 21:02:57 +0100 Subject: [PATCH 082/540] Use valid fake public key --- src/trust_is_risk.js | 17 +++++++++++------ test/helpers.js | 17 +++++++++++------ test/trust_is_risk.js | 18 ++++++++++++------ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 023dcbe..66832cf 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,12 +13,17 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00]; +const fakePubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/helpers.js b/test/helpers.js index 7715c08..e14016a 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,12 +5,17 @@ var fixtures = require("./fixtures"); var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); -const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00]; +const fakePubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 2fc85d7..1039f80 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -15,12 +15,18 @@ var assert = require("assert"); require("should-sinon"); const COIN = bcoin.consensus.COIN; -const fakePubKeyArray = [0x04, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00]; + +const fakePubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + const fakePubKey = Buffer.from(fakePubKeyArray); const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); const step3 = Buffer.concat([Buffer.alloc(1), step2]); From 8235022d61776c9767f03181f96a180bd2d9621c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 15 Sep 2017 12:15:55 +0100 Subject: [PATCH 083/540] Remove TODO --- test/trust_is_risk.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1039f80..1ba391d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -55,7 +55,6 @@ describe("TrustIsRisk", () => { var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; beforeEach(() => { - // TODO: check that tag has correct type and format: Valid address, corresponding public key is "0x04Trust is Risk0x00..0x00" node = new bcoin.fullnode({}); tir = new Trust.TrustIsRisk(node); From caab3be55786d691a33c089d6fe2e0552f029414 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 15 Sep 2017 12:16:15 +0100 Subject: [PATCH 084/540] Use "should" syntax instead of "assert" --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1ba391d..883fad5 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -84,7 +84,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { - assert(secp256k1.publicKeyVerify(fakePubKey)); + secp256k1.publicKeyVerify(fakePubKey).should.equal(true); }); it("is a valid bitcoin address", () => { From fb6b2462065fc28595ca36f9ccc912c7dd306a10 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 15 Sep 2017 16:06:44 +0100 Subject: [PATCH 085/540] Add test that fakePubKey is a buffer --- test/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 883fad5..a90828a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -84,6 +84,7 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { + Buffer.isBuffer(fakePubKey).should.equal(true); secp256k1.publicKeyVerify(fakePubKey).should.equal(true); }); From bb09e2101a155644eeaa6e3385f2e6f94f569d31 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 15 Sep 2017 16:35:28 +0100 Subject: [PATCH 086/540] Simplify tag creation from key Use bcoin libraries instead of reinventing the wheel --- src/trust_is_risk.js | 8 ++------ test/helpers.js | 8 ++------ test/trust_is_risk.js | 9 +++------ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 66832cf..f9ec257 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -25,12 +25,8 @@ const fakePubKeyArray = [0x04, // constant 0x04 prefix 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; const fakePubKey = Buffer.from(fakePubKeyArray); -const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); -const step3 = Buffer.concat([Buffer.alloc(1), step2]); -const step4 = Buffer.from(bcoin.crypto.hash256(step3)); -const step5 = step4.slice(0, 4); -const step6 = Buffer.concat([step3, step5]); -const tag = Buffer.from(bcoin.base58.encode(step6)); +const fakeKeyRing = KeyRing.fromPublic(fakePubKey); +const tag = Buffer.from(fakeKeyRing.getAddress("base58")); class TrustIsRisk { node : bcoin$FullNode diff --git a/test/helpers.js b/test/helpers.js index e14016a..dda2061 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -17,12 +17,8 @@ const fakePubKeyArray = [0x04, // constant 0x04 prefix 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; const fakePubKey = Buffer.from(fakePubKeyArray); -const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); -const step3 = Buffer.concat([Buffer.alloc(1), step2]); -const step4 = Buffer.from(bcoin.crypto.hash256(step3)); -const step5 = step4.slice(0, 4); -const step6 = Buffer.concat([step3, step5]); -const tag = Buffer.from(bcoin.base58.encode(step6)); +const fakeKeyRing = KeyRing.fromPublic(fakePubKey); +const tag = Buffer.from(fakeKeyRing.getAddress("base58")); var testHelpers = { getNode: async () => { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index a90828a..ed0ee61 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -5,6 +5,7 @@ var Coin = bcoin.primitives.Coin; var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; +var KeyRing = bcoin.primitives.KeyRing; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var secp256k1 = require("bcoin/lib/crypto/ec-secp256k1"); @@ -28,12 +29,8 @@ const fakePubKeyArray = [0x04, // constant 0x04 prefix 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; const fakePubKey = Buffer.from(fakePubKeyArray); -const step2 = Buffer.from(bcoin.crypto.hash160(fakePubKey)); -const step3 = Buffer.concat([Buffer.alloc(1), step2]); -const step4 = Buffer.from(bcoin.crypto.hash256(step3)); -const step5 = step4.slice(0, 4); -const step6 = Buffer.concat([step3, step5]); -const tag = Buffer.from(bcoin.base58.encode(step6)); +const fakeKeyRing = KeyRing.fromPublic(fakePubKey); +const tag = Buffer.from(fakeKeyRing.getAddress("base58")); describe("TrustIsRisk", () => { var addr = {}; From d13061e58ca46501b7980860a7c2d355d71ad2fa Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 15 Sep 2017 17:19:59 +0100 Subject: [PATCH 087/540] Add getAddress() type --- flow-typed/npm/bcoin_vx.x.x.js | 1 + 1 file changed, 1 insertion(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index f1a55da..73c672f 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -73,6 +73,7 @@ declare class bcoin$KeyRing { getPublicKey() : Buffer; getPrivateKey() : Buffer; + getAddress() : Buffer; } declare class bcoin$Coin extends bcoin$Output { From 2c60c69d90fedd15cf85467ea7257188fe0ab362 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 15 Sep 2017 17:20:26 +0100 Subject: [PATCH 088/540] Remove last test in tag The test needed to invert a hash... --- test/trust_is_risk.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index ed0ee61..98b9feb 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -88,11 +88,6 @@ describe("TrustIsRisk", () => { it("is a valid bitcoin address", () => { assert(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))); }); - - it("corresponds to a public key that contains \"Trust is Risk\"", () => { - //bcoin.primitives.HDPublicKey.fromBase58(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))).should.equal(fakePubKeyArray); - bcoin.http.Wallet.getKey(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))).should.equal(Buffer.from(fakePubKey)); - }); }); describe(".getDirectTrust()", () => { From 907170ddb5547d273fca592d1628c572641fecd5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 17 Sep 2017 16:09:08 +0100 Subject: [PATCH 089/540] Add spv_node.js Change all occurences of "full" to "spv" in the new file --- src/spv_node.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/spv_node.js diff --git a/src/spv_node.js b/src/spv_node.js new file mode 100644 index 0000000..aa26fa4 --- /dev/null +++ b/src/spv_node.js @@ -0,0 +1,14 @@ +// @flow +var bcoin = require("bcoin"); +var TrustIsRisk = require("./trust_is_risk"); + +class SpvNode extends bcoin.spvnode { + trust : TrustIsRisk + + constructor(options : Object) { + super(options); + this.trust = new TrustIsRisk(this); + } +} + +module.exports = SpvNode; From 37fb6f40f4fbfe07405b6a766734152d519cff56 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 17 Sep 2017 16:20:15 +0100 Subject: [PATCH 090/540] Add SPVNode types and refs to relevant files --- flow-typed/npm/bcoin_vx.x.x.js | 8 ++++++++ src/spv_node.js | 4 ++-- src/trust_is_risk.js | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 73c672f..0903ad9 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -9,6 +9,13 @@ declare class bcoin$FullNode { getCoin(hash : Hash, index : number) : bcoin$Coin; } +declare class bcoin$SPVNode { + on(eventName : string, eventHandler : Function) : void; + getTX(hash : Hash) : Promise; + getCoin(hash : Hash, index : number) : bcoin$Coin; + //TODO Check if changes/additions are needed +} + declare class bcoin$Address { toBase58() : string; hash : Buffer; @@ -84,6 +91,7 @@ declare class bcoin$Coin extends bcoin$Output { declare module 'bcoin' { declare module.exports: { fullnode : Class, + spvnode : Class, script : Class, primitives : { Address : Class, diff --git a/src/spv_node.js b/src/spv_node.js index aa26fa4..91a7e12 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -2,7 +2,7 @@ var bcoin = require("bcoin"); var TrustIsRisk = require("./trust_is_risk"); -class SpvNode extends bcoin.spvnode { +class SPVNode extends bcoin.spvnode { trust : TrustIsRisk constructor(options : Object) { @@ -11,4 +11,4 @@ class SpvNode extends bcoin.spvnode { } } -module.exports = SpvNode; +module.exports = SPVNode; diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index f9ec257..2cc1bb8 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -29,10 +29,10 @@ const fakeKeyRing = KeyRing.fromPublic(fakePubKey); const tag = Buffer.from(fakeKeyRing.getAddress("base58")); class TrustIsRisk { - node : bcoin$FullNode + node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB - constructor(node : bcoin$FullNode) { + constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { this.node = node; this.db = new TrustDB(); From 6b0112b38f9aa024cfedb72d92760ab435608860 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Sep 2017 20:04:12 +0100 Subject: [PATCH 091/540] Add pool.watchAddress() function type --- flow-typed/npm/bcoin_vx.x.x.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 0903ad9..3bad75a 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -13,9 +13,14 @@ declare class bcoin$SPVNode { on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; + pool : bcoin$Pool; //TODO Check if changes/additions are needed } +declare class bcoin$Pool { + watchAddress(address : Buffer) : void; +} + declare class bcoin$Address { toBase58() : string; hash : Buffer; @@ -93,6 +98,7 @@ declare module 'bcoin' { fullnode : Class, spvnode : Class, script : Class, + pool : Class, primitives : { Address : Class, TX : Class, From 63cc3b8160bd03b8c98729065aede90015a95a37 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Sep 2017 20:04:47 +0100 Subject: [PATCH 092/540] Add tag --- src/spv_node.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/spv_node.js b/src/spv_node.js index 91a7e12..8b3ebde 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -2,6 +2,21 @@ var bcoin = require("bcoin"); var TrustIsRisk = require("./trust_is_risk"); +const fakePubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + +const fakePubKey = Buffer.from(fakePubKeyArray); +const fakeKeyRing = bcoin.primitives.KeyRing.fromPublic(fakePubKey); +const tag = Buffer.from(fakeKeyRing.getAddress("base58")); + class SPVNode extends bcoin.spvnode { trust : TrustIsRisk From 1704b5613626403b2cecc6bd3a46a5cd08ffc36a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Sep 2017 20:05:05 +0100 Subject: [PATCH 093/540] Add tag to Bloom filter --- src/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/spv_node.js b/src/spv_node.js index 8b3ebde..721cdec 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -23,6 +23,7 @@ class SPVNode extends bcoin.spvnode { constructor(options : Object) { super(options); this.trust = new TrustIsRisk(this); + this.pool.watchAddress(tag); } } From 6cd6779e8b7d6452af653c990d44d11331650b34 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Sep 2017 20:05:32 +0100 Subject: [PATCH 094/540] Add SPV node test file --- test/spv_node.js | 196 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 test/spv_node.js diff --git a/test/spv_node.js b/test/spv_node.js new file mode 100644 index 0000000..f24d2f5 --- /dev/null +++ b/test/spv_node.js @@ -0,0 +1,196 @@ +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var testHelpers = require("./helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +var assert = require("assert"); +var fixtures = require("./fixtures"); +require("should-sinon"); + +const COIN = consensus.COIN; + +describe("SPVNode", () => { + var node = null; + var walletDB = null; + var NodeWatcher = null; + var watcher = null; + + beforeEach("get node", async () => { + node = await testHelpers.getNode(); + watcher = new testHelpers.NodeWatcher(node); + }); + + beforeEach("get walletDB", async () => { + walletDB = await testHelpers.getWalletDB(node); + }); + + afterEach("close walletDB", async () => walletDB.close()); + afterEach("close node", async () => node.close()); + + it("should call trust.addTX() on every transaction", async function() { + var sender = await testHelpers.createWallet(walletDB, "sender"); + var receiver = await testHelpers.createWallet(walletDB, "receiver"); + + await testHelpers.delay(1000); + // Produce a block and reward the sender, so that we have a coin to spend. + await testHelpers.mineBlock(node, sender.getAddress("base58")); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + await testHelpers.delay(100); + + await sender.send({ + outputs: [{ + value: 10 * COIN, + address: receiver.getAddress("base58") + }] + }); + await watcher.waitForTX(); + + node.trust.addTX.should.be.calledOnce(); + }); + + describe("with the nobodyLikesFrank.json example", () => { + var addresses, rings = {}; + + beforeEach("apply graph transactions", async () => { + addresses = {}; + + for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { + addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); + } + + // Alice mines three blocks, each rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var blockCount = 3; + var coinbaseHashes = []; + for(let i = 0; i < blockCount; i++) { + var block = await testHelpers.mineBlock(node, addresses.alice); + coinbaseHashes.push(block.txs[0].hash()); + await testHelpers.delay(500); + } + + // Alice sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + var outputs = fixtures.names.map((name) => { + return testHelpers.getP2PKHOutput( + Address.fromHash(bcoin.crypto.hash160(fixtures.keyRings[name].getPublicKey())) + .toBase58(), + sendAmount * consensus.COIN); + }); + + // We have to use a change output, because transaction with too large a fee are considered + // invalid. + var fee = 0.01; + var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + fixtures.keyRings.alice.getPublicKey())), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { + return node.getCoin(hash.toString("hex"), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(fixtures.keyRings.alice); + assert(signedCount === blockCount); + assert(await mtx.verify()); + + var tx = mtx.toTX(); + node.sendTX(tx); + await watcher.waitForTX(); + + prevout = {}; + fixtures.names.forEach((name) => { + prevout[name] = { + hash: tx.hash().toString("hex"), + index: fixtures.names.indexOf(name) + }; + }); + + // Alice mines another block + await testHelpers.mineBlock(node, helpers.pubKeyToEntity( + fixtures.keyRings.alice.getPublicKey())); + await testHelpers.delay(500); + + var graph = require("./graphs/nobodyLikesFrank.json"); + for (var origin in graph) { + var neighbours = graph[origin]; + for (var dest in neighbours) { + var value = neighbours[dest]; + if (!value || value < 1) continue; + + let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); + + let mtx = await node.trust.createTrustIncreasingMTX( + fixtures.keyRings[origin].getPrivateKey(), + fixtures.keyRings[dest].getPublicKey(), + outpoint, + value * consensus.COIN); + + assert(await mtx.verify()); + + let tx = mtx.toTX(); + node.sendTX(tx); + await watcher.waitForTX(); + + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; + } + } + + // Alice mines yet another block + await testHelpers.mineBlock(node, helpers.pubKeyToEntity( + fixtures.keyRings.alice.getPublicKey())); + await testHelpers.delay(500); + }); + + it("computes trusts correctly", () => { + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + should(node.trust.getIndirectTrust(alice, alice)).equal(Infinity); + should(node.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); + should(node.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); + should(node.trust.getIndirectTrust(alice, frank)).equal(0); + should(node.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + + should(node.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); + should(node.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); + should(node.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); + should(node.trust.getIndirectTrust(george, eve)).equal(0); + }); + + it("after decreasing some trusts computes trusts correctly", async () => { + var mtxs = node.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), + fixtures.keyRings.bob.getPublicKey(), 3 * COIN); + mtxs.length.should.equal(1); + var mtx = mtxs[0]; + + should(await mtx.verify()); + node.sendTX(mtx.toTX()); + + await testHelpers.delay(750); + should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + }); + }); + + describe("with the topcoder.json example", () => { + //TODO: Write tests here. + }); +}); From 8a89d63f7263197d79419c3b374f76833bfdc7de Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Sep 2017 21:49:19 +0100 Subject: [PATCH 095/540] Put tag in TrustIsRisk constructor --- src/trust_is_risk.js | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 2cc1bb8..1ed8103 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -13,26 +13,30 @@ var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -const fakePubKeyArray = [0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - -const fakePubKey = Buffer.from(fakePubKeyArray); -const fakeKeyRing = KeyRing.fromPublic(fakePubKey); -const tag = Buffer.from(fakeKeyRing.getAddress("base58")); - class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB - + fakePubKeyArray : Array + fakePubKey : Buffer + fakeKeyRing : KeyRing + tag : Buffer + constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { + this.fakePubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + + this.fakePubKey = Buffer.from(this.fakePubKeyArray); + this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); + this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); + this.node = node; this.db = new TrustDB(); @@ -97,7 +101,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, tag]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.tag]), value: trustAmount }) ] @@ -179,7 +183,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, tag]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.tag]), value: remainingTrustAmount })); } From 5aeb1fc969650bca4de0795eb2a849e98452355e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Sep 2017 22:36:01 +0100 Subject: [PATCH 096/540] Separate type declarations and assignments --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 1ed8103..94c44e7 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -20,7 +20,7 @@ class TrustIsRisk { fakePubKey : Buffer fakeKeyRing : KeyRing tag : Buffer - + constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { this.fakePubKeyArray = [0x04, // constant 0x04 prefix 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, From d572b77eb7ce02f8e9828430715a98b70c52c4a2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Sep 2017 22:55:13 +0100 Subject: [PATCH 097/540] Use tag from TrustIsRisk class --- test/helpers.js | 17 +---------------- test/trust_is_risk.js | 24 ++++-------------------- 2 files changed, 5 insertions(+), 36 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index dda2061..be995d3 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -2,24 +2,8 @@ var TrustIsRisk = require("../"); var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); var fixtures = require("./fixtures"); -var KeyRing = bcoin.primitives.KeyRing; var assert = require("assert"); -const fakePubKeyArray = [0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - -const fakePubKey = Buffer.from(fakePubKeyArray); -const fakeKeyRing = KeyRing.fromPublic(fakePubKey); -const tag = Buffer.from(fakeKeyRing.getAddress("base58")); - var testHelpers = { getNode: async () => { var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); @@ -98,6 +82,7 @@ var testHelpers = { }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { + tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).tag; return new bcoin.primitives.Output({ script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 98b9feb..7a29167 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -5,7 +5,6 @@ var Coin = bcoin.primitives.Coin; var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; -var KeyRing = bcoin.primitives.KeyRing; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var secp256k1 = require("bcoin/lib/crypto/ec-secp256k1"); @@ -17,21 +16,6 @@ require("should-sinon"); const COIN = bcoin.consensus.COIN; -const fakePubKeyArray = [0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - -const fakePubKey = Buffer.from(fakePubKeyArray); -const fakeKeyRing = KeyRing.fromPublic(fakePubKey); -const tag = Buffer.from(fakeKeyRing.getAddress("base58")); - describe("TrustIsRisk", () => { var addr = {}; for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { @@ -81,12 +65,12 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { - Buffer.isBuffer(fakePubKey).should.equal(true); - secp256k1.publicKeyVerify(fakePubKey).should.equal(true); + Buffer.isBuffer(tir.fakePubKey).should.equal(true); + secp256k1.publicKeyVerify(tir.fakePubKey).should.equal(true); }); it("is a valid bitcoin address", () => { - assert(bcoin.primitives.Address.fromBase58(tag.toString("ascii"))); + assert(bcoin.primitives.Address.fromBase58(tir.tag.toString("ascii"))); }); }); @@ -232,7 +216,7 @@ describe("TrustIsRisk", () => { trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.deepEqual(tag); + trustOutput.script.get(3).should.deepEqual(tir.tag); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From 14f7cb7f0e667a646cd71d8c06f1fa5baca2fe70 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 17:32:23 +0100 Subject: [PATCH 098/540] Add console capability --- .eslintrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index f8d4494..2d511eb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -30,7 +30,8 @@ ], "flowtype/space-before-type-colon": 0, "no-undef": 0, - "no-unused-vars": 0 + "no-unused-vars": 0, + "no-console": 0 }, "settings": { "flowtype": { From a932ed31c112d1cdea86d8a49728e3b0f871f8a3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:20:39 +0100 Subject: [PATCH 099/540] Run npm install --- package-lock.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index d417c2e..2086d94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "abstract-leveldown": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", - "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", + "integrity": "sha1-HF6Mal75Za6MNd+zqHcMR2uCxLg=", "optional": true, "requires": { "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" @@ -106,7 +106,7 @@ "aproba": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", - "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", + "integrity": "sha1-RcZikJTeTpb2k+9+q3SuB5wkD8E=", "optional": true }, "are-we-there-yet": { @@ -417,7 +417,7 @@ "browserify-aes": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz", - "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==", + "integrity": "sha1-yPo7G3WFu3unfFVgtgmW3extUwk=", "optional": true, "requires": { "buffer-xor": "1.0.3", @@ -478,7 +478,7 @@ "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", "requires": { "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" @@ -1042,7 +1042,7 @@ "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", "optional": true, "requires": { "md5.js": "1.3.4", @@ -1066,7 +1066,7 @@ "expand-template": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz", - "integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==", + "integrity": "sha1-4J77qXe/mPnuDtJavQxpLgKuw/w=", "optional": true }, "extend": { @@ -1361,7 +1361,7 @@ "hash.js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "integrity": "sha1-NA3tvmKQGHFRweodd3o0SJNd+EY=", "requires": { "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "minimalistic-assert": "1.0.0" @@ -1880,7 +1880,7 @@ "node-abi": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.1.tgz", - "integrity": "sha512-6oxV13poCOv7TfGvhsSz6XZWpXeKkdGVh72++cs33OfMh3KAX8lN84dCvmqSETyDXAFcUHtV7eJrgFBoOqZbNQ==", + "integrity": "sha1-yc2iVuyKqZvKsvZEbbOK8UMziyo=", "optional": true }, "node-gyp": { @@ -2138,7 +2138,7 @@ "prebuild-install": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.2.tgz", - "integrity": "sha512-F46pcvDxtQhbV3B+dm+exHuKxIyJK26fVNiJRmbTW/5D7o0Z2yzc8CKeu7UWbo9XxQZoVOC88aKgySAsza+cWw==", + "integrity": "sha1-3UfE1h83VPsXu/YBdZ5ZIuFuBnE=", "optional": true, "requires": { "expand-template": "1.1.0", @@ -3009,7 +3009,7 @@ "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=", "optional": true, "requires": { "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" From df25421b17d3becdb20189a9c4ede279b6cd81c0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:21:56 +0100 Subject: [PATCH 100/540] Create short tag and public key --- src/trust_is_risk.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 94c44e7..0a4b5de 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -17,9 +17,13 @@ class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB fakePubKeyArray : Array + shortFakePubKeyArray : Array fakePubKey : Buffer + shortFakePubKey : Buffer fakeKeyRing : KeyRing + shortFakeKeyRing : KeyRing tag : Buffer + shortTag : Buffer constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { this.fakePubKeyArray = [0x04, // constant 0x04 prefix @@ -32,10 +36,19 @@ class TrustIsRisk { 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - + + this.shortFakePubKeyArray = [0x02, // 0x02 prefix for even y values + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // only x is given in short version + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; + this.fakePubKey = Buffer.from(this.fakePubKeyArray); + this.shortFakePubKey = Buffer.from(this.shortFakePubKeyArray); this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); + this.shortFakeKeyRing = KeyRing.fromPublic(this.shortFakePubKey); this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); + this.shortTag = Buffer.from(this.shortFakeKeyRing.getAddress("base58")); this.node = node; this.db = new TrustDB(); From e393d8568ee5907ab0369c9193f1a608d1285df9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:22:56 +0100 Subject: [PATCH 101/540] Use short tag and public key --- src/trust_is_risk.js | 2 +- test/helpers.js | 2 +- test/trust_is_risk.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0a4b5de..9757077 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -196,7 +196,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.tag]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.shortFakePubKey]), value: remainingTrustAmount })); } diff --git a/test/helpers.js b/test/helpers.js index be995d3..f9b3bd2 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -82,7 +82,7 @@ var testHelpers = { }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { - tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).tag; + tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).shortTag; return new bcoin.primitives.Output({ script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 7a29167..89bb123 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -70,7 +70,7 @@ describe("TrustIsRisk", () => { }); it("is a valid bitcoin address", () => { - assert(bcoin.primitives.Address.fromBase58(tir.tag.toString("ascii"))); + assert(bcoin.primitives.Address.fromBase58(tir.shortTag.toString("ascii"))); }); }); @@ -216,7 +216,7 @@ describe("TrustIsRisk", () => { trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.deepEqual(tir.tag); + trustOutput.script.get(3).should.deepEqual(tir.shortTag); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From c93bcf35ca47299374987a5656b80f2172d9c07b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:24:10 +0100 Subject: [PATCH 102/540] Break down commands into smaller pieces --- test/full_node.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/full_node.js b/test/full_node.js index a3260ba..4737fbf 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -184,7 +184,11 @@ describe("FullNode", () => { var mtx = mtxs[0]; should(await mtx.verify()); - node.sendTX(mtx.toTX()); + var aba = mtx.toTX(); + node.sendTX(aba); + await testHelpers.delay(1000000); + //node.sendTX(mtx.toTX()); + console.log("aha"); await testHelpers.delay(750); should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); From b8147960ff9c0487eacc07a591913da61f1baa8c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:29:58 +0100 Subject: [PATCH 103/540] Rename tag vars for clarity --- src/trust_is_risk.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 9757077..cb60ba6 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -16,17 +16,17 @@ var DirectTrust = require("./direct_trust"); class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB + uncompressedFakePubKeyArray : Array fakePubKeyArray : Array - shortFakePubKeyArray : Array + uncompressedFakePubKey : Buffer fakePubKey : Buffer - shortFakePubKey : Buffer + uncompressedFakeKeyRing : KeyRing fakeKeyRing : KeyRing - shortFakeKeyRing : KeyRing + uncompressedTag : Buffer tag : Buffer - shortTag : Buffer constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { - this.fakePubKeyArray = [0x04, // constant 0x04 prefix + this.uncompressedFakePubKeyArray = [0x04, // constant 0x04 prefix 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" @@ -37,18 +37,18 @@ class TrustIsRisk { 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - this.shortFakePubKeyArray = [0x02, // 0x02 prefix for even y values + this.fakePubKeyArray = [0x02, // 0x02 prefix for even y values 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // only x is given in short version 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; + this.uncompressedFakePubKey = Buffer.from(this.uncompressedFakePubKeyArray); this.fakePubKey = Buffer.from(this.fakePubKeyArray); - this.shortFakePubKey = Buffer.from(this.shortFakePubKeyArray); + this.uncompressedFakeKeyRing = KeyRing.fromPublic(this.uncompressedFakePubKey); this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); - this.shortFakeKeyRing = KeyRing.fromPublic(this.shortFakePubKey); + this.uncompressedTag = Buffer.from(this.uncompressedFakeKeyRing.getAddress("base58")); this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); - this.shortTag = Buffer.from(this.shortFakeKeyRing.getAddress("base58")); this.node = node; this.db = new TrustDB(); From fb33b3a491d64957b9ea25085ac800e54572e01b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:32:04 +0100 Subject: [PATCH 104/540] Use tag instead of shortTag --- test/helpers.js | 2 +- test/trust_is_risk.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index f9b3bd2..be995d3 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -82,7 +82,7 @@ var testHelpers = { }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { - tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).shortTag; + tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).tag; return new bcoin.primitives.Output({ script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 89bb123..7a29167 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -70,7 +70,7 @@ describe("TrustIsRisk", () => { }); it("is a valid bitcoin address", () => { - assert(bcoin.primitives.Address.fromBase58(tir.shortTag.toString("ascii"))); + assert(bcoin.primitives.Address.fromBase58(tir.tag.toString("ascii"))); }); }); @@ -216,7 +216,7 @@ describe("TrustIsRisk", () => { trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.deepEqual(tir.shortTag); + trustOutput.script.get(3).should.deepEqual(tir.tag); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From 3fe3c7ebf4ba148c21ff028c7f86eca74365c400 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:32:22 +0100 Subject: [PATCH 105/540] Use public key instead of tag --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index cb60ba6..5929b0f 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -114,7 +114,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.tag]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), value: trustAmount }) ] From 3ebc94b61aeeef1f28213d8413d2b203406542c0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:39:19 +0100 Subject: [PATCH 106/540] Reorder commands for ease of use --- test/full_node.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 4737fbf..e63acfb 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -184,11 +184,11 @@ describe("FullNode", () => { var mtx = mtxs[0]; should(await mtx.verify()); - var aba = mtx.toTX(); - node.sendTX(aba); - await testHelpers.delay(1000000); - //node.sendTX(mtx.toTX()); - console.log("aha"); + node.sendTX(mtx.toTX()); +// var aba = mtx.toTX(); +// node.sendTX(aba); +// await testHelpers.delay(1000000); +// console.log("aha"); await testHelpers.delay(750); should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); From 9488f7f0f4943aed1fb6ac6143662bf054ff4e4e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:39:35 +0100 Subject: [PATCH 107/540] Replace public keys with tags --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 5929b0f..1b617c9 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -114,7 +114,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.tag]), value: trustAmount }) ] @@ -196,7 +196,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.shortFakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.tag]), value: remainingTrustAmount })); } From 3c7517bb45093f314e5ccf76591f460eff02596e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 20 Sep 2017 21:41:12 +0100 Subject: [PATCH 108/540] Group uncompressed together --- src/trust_is_risk.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 1b617c9..69534d1 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -16,13 +16,15 @@ var DirectTrust = require("./direct_trust"); class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB + uncompressedFakePubKeyArray : Array - fakePubKeyArray : Array uncompressedFakePubKey : Buffer - fakePubKey : Buffer uncompressedFakeKeyRing : KeyRing - fakeKeyRing : KeyRing uncompressedTag : Buffer + + fakePubKeyArray : Array + fakePubKey : Buffer + fakeKeyRing : KeyRing tag : Buffer constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { @@ -37,17 +39,19 @@ class TrustIsRisk { 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + this.uncompressedFakePubKey = Buffer.from(this.uncompressedFakePubKeyArray); + this.uncompressedFakeKeyRing = KeyRing.fromPublic(this.uncompressedFakePubKey); + this.uncompressedTag = Buffer.from(this.uncompressedFakeKeyRing.getAddress("base58")); + + this.fakePubKeyArray = [0x02, // 0x02 prefix for even y values 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // only x is given in short version 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; - this.uncompressedFakePubKey = Buffer.from(this.uncompressedFakePubKeyArray); this.fakePubKey = Buffer.from(this.fakePubKeyArray); - this.uncompressedFakeKeyRing = KeyRing.fromPublic(this.uncompressedFakePubKey); this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); - this.uncompressedTag = Buffer.from(this.uncompressedFakeKeyRing.getAddress("base58")); this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); this.node = node; From 1ed0e59f70811eb3afbbd2ff08c068d157221753 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 22 Sep 2017 22:22:31 +0100 Subject: [PATCH 109/540] Hide spv_node.js temporarily It was hidden in order to avoid running the corresponding tests. It will be brought back after the full node tests are all successful. --- test/{spv_node.js => .spv_node.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{spv_node.js => .spv_node.js} (100%) diff --git a/test/spv_node.js b/test/.spv_node.js similarity index 100% rename from test/spv_node.js rename to test/.spv_node.js From c291ec98985c0110d7e348a7be79110fe12f5d80 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 22 Sep 2017 22:24:07 +0100 Subject: [PATCH 110/540] Use uncompressedFakePubKey instead of tag --- src/trust_is_risk.js | 4 ++-- test/helpers.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 69534d1..17ee375 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -118,7 +118,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.tag]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.uncompressedFakePubKey]), value: trustAmount }) ] @@ -200,7 +200,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.tag]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.uncompressedFakePubKey]), value: remainingTrustAmount })); } diff --git a/test/helpers.js b/test/helpers.js index be995d3..b5ea1b2 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -82,7 +82,7 @@ var testHelpers = { }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { - tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).tag; + tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).uncompressedFakePubKey; return new bcoin.primitives.Output({ script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value From e7cb2fdd76887459d92359ff9c1babef8f9b8ec0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 22 Sep 2017 22:35:08 +0100 Subject: [PATCH 111/540] Replace tag with fakePubKey --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 7a29167..43bb468 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -216,7 +216,7 @@ describe("TrustIsRisk", () => { trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() .should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.deepEqual(tir.tag); + trustOutput.script.get(3).should.deepEqual(tir.fakePubKey); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From 14efb8a4832a9ecdc85a8402e0d9d82b71640ac6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 22 Sep 2017 22:35:36 +0100 Subject: [PATCH 112/540] Remove "uncompressed" from fakePubKey* --- src/trust_is_risk.js | 30 +++++++++++++++--------------- test/helpers.js | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 17ee375..70699c2 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -17,18 +17,18 @@ class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB - uncompressedFakePubKeyArray : Array - uncompressedFakePubKey : Buffer - uncompressedFakeKeyRing : KeyRing - uncompressedTag : Buffer - fakePubKeyArray : Array fakePubKey : Buffer fakeKeyRing : KeyRing tag : Buffer + compressedFakePubKeyArray : Array + compressedFakePubKey : Buffer + compressedFakeKeyRing : KeyRing + compressedTag : Buffer + constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { - this.uncompressedFakePubKeyArray = [0x04, // constant 0x04 prefix + this.fakePubKeyArray = [0x04, // constant 0x04 prefix 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" @@ -39,20 +39,20 @@ class TrustIsRisk { 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - this.uncompressedFakePubKey = Buffer.from(this.uncompressedFakePubKeyArray); - this.uncompressedFakeKeyRing = KeyRing.fromPublic(this.uncompressedFakePubKey); - this.uncompressedTag = Buffer.from(this.uncompressedFakeKeyRing.getAddress("base58")); + this.fakePubKey = Buffer.from(this.fakePubKeyArray); + this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); + this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); - this.fakePubKeyArray = [0x02, // 0x02 prefix for even y values + this.compressedFakePubKeyArray = [0x02, // 0x02 prefix for even y values 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // only x is given in short version 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; - this.fakePubKey = Buffer.from(this.fakePubKeyArray); - this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); - this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); + this.compressedFakePubKey = Buffer.from(this.compressedFakePubKeyArray); + this.compressedFakeKeyRing = KeyRing.fromPublic(this.compressedFakePubKey); + this.compressedTag = Buffer.from(this.compressedFakeKeyRing.getAddress("base58")); this.node = node; this.db = new TrustDB(); @@ -118,7 +118,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.uncompressedFakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), value: trustAmount }) ] @@ -200,7 +200,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.uncompressedFakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.fakePubKey]), value: remainingTrustAmount })); } diff --git a/test/helpers.js b/test/helpers.js index b5ea1b2..4a21a82 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -82,7 +82,7 @@ var testHelpers = { }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { - tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).uncompressedFakePubKey; + tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).fakePubKey; return new bcoin.primitives.Output({ script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value From 16ef72cb35cb6ee08ab57ba59893f95d24faf952 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 22 Sep 2017 22:47:15 +0100 Subject: [PATCH 113/540] Bring back spv_node.js test from hiding --- test/{.spv_node.js => spv_node.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{.spv_node.js => spv_node.js} (100%) diff --git a/test/.spv_node.js b/test/spv_node.js similarity index 100% rename from test/.spv_node.js rename to test/spv_node.js From 7216d41711a94e2ba66f68e58573c3ff76064577 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 23 Sep 2017 19:06:02 +0100 Subject: [PATCH 114/540] Replace "new Buffer" with "Buffer.from" "new Buffer" is [deprecated](https://nodejs.org/api/buffer.html#buffer_new_buffer_string_encoding) --- test/fixtures.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures.js b/test/fixtures.js index a11f021..726417b 100644 --- a/test/fixtures.js +++ b/test/fixtures.js @@ -14,7 +14,7 @@ var privateKeys = { var keyRings = {}; for (let name in privateKeys) { let key = privateKeys[name]; - keyRings[name] = KeyRing.fromPrivate(new Buffer(key, "hex")); + keyRings[name] = KeyRing.fromPrivate(Buffer.from(key, "hex")); } module.exports = { From 270dbe4623586488498914aa65ebc8e5d82596da Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 25 Sep 2017 17:55:14 +0100 Subject: [PATCH 115/540] Remove commented out lines --- test/full_node.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index e63acfb..a3260ba 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -185,10 +185,6 @@ describe("FullNode", () => { should(await mtx.verify()); node.sendTX(mtx.toTX()); -// var aba = mtx.toTX(); -// node.sendTX(aba); -// await testHelpers.delay(1000000); -// console.log("aha"); await testHelpers.delay(750); should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); From eb6ecd7dbb92b6a8dd8fec169c11a1d53c93cad3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 13:16:08 +0100 Subject: [PATCH 116/540] Export SPVNode --- src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.js b/src/index.js index 66a1290..d7211ae 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ // @flow module.exports = { FullNode: require("./full_node"), + SPVNode: require("./spv_node"), TrustIsRisk: require("./trust_is_risk") }; From 625a905401355969679cdf15a64d53bb6690e00a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 13:16:59 +0100 Subject: [PATCH 117/540] Rename getNode() to getFullNode() --- test/full_node.js | 2 +- test/helpers.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index a3260ba..398f226 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -26,7 +26,7 @@ describe("FullNode", () => { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); beforeEach("get node", async () => { - node = await testHelpers.getNode(); + node = await testHelpers.getFullNode(); watcher = new testHelpers.NodeWatcher(node); }); diff --git a/test/helpers.js b/test/helpers.js index 4a21a82..5b93264 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,7 +5,7 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - getNode: async () => { + getFullNode: async () => { var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); await node.open(); From 4cee7a6af567bd11f092c332f151fe0971b4fb3e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 13:18:11 +0100 Subject: [PATCH 118/540] Add getSPVNode() --- test/helpers.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index 5b93264..88826c3 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -15,6 +15,16 @@ var testHelpers = { return node; }, + getSPVNode: async () => { + var node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret"}); + + await node.open(); + await node.connect(); + node.startSync(); + + return node; + }, + getWalletDB: async (node) => { var walletDB = new WalletDB({ network: "regtest", From 4fab69e7088d48ebf916bcea198011958ce3caa2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 18:26:49 +0100 Subject: [PATCH 119/540] Unify getFullNode() and getSPVNode() Use getNode(type) where type == ("full" | "test") --- test/full_node.js | 2 +- test/helpers.js | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 398f226..c76cc13 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -26,7 +26,7 @@ describe("FullNode", () => { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); beforeEach("get node", async () => { - node = await testHelpers.getFullNode(); + node = await testHelpers.getNode("full"); watcher = new testHelpers.NodeWatcher(node); }); diff --git a/test/helpers.js b/test/helpers.js index 88826c3..92d8733 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,18 +5,13 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - getFullNode: async () => { - var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); - - await node.open(); - await node.connect(); - node.startSync(); - - return node; - }, - - getSPVNode: async () => { - var node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret"}); + getNode: async (type) => { + var node; + if (type === "full") + node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); + else if (type === "spv") + node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret"}); + else throw new Error("Not a valid node type (should be \"full\" or \"spv\")"); await node.open(); await node.connect(); From b88f15593dbcaddddecdee056d24f0cf0fae454a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 20:58:37 +0100 Subject: [PATCH 120/540] Revert to original getNode() syntax --- test/full_node.js | 2 +- test/helpers.js | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index c76cc13..a3260ba 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -26,7 +26,7 @@ describe("FullNode", () => { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); beforeEach("get node", async () => { - node = await testHelpers.getNode("full"); + node = await testHelpers.getNode(); watcher = new testHelpers.NodeWatcher(node); }); diff --git a/test/helpers.js b/test/helpers.js index 92d8733..4a21a82 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,13 +5,8 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - getNode: async (type) => { - var node; - if (type === "full") - node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); - else if (type === "spv") - node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret"}); - else throw new Error("Not a valid node type (should be \"full\" or \"spv\")"); + getNode: async () => { + var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); await node.open(); await node.connect(); From d69148c4d1c8ce84ea259a695c43d6c856864fd7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 21:00:19 +0100 Subject: [PATCH 121/540] Add openNode(), closeNode() functions --- test/helpers.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index 4a21a82..eb53f06 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,6 +5,26 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { + openNode: async (node) => { + await node.open(); + await node.connect(); + node.startSync(); + var walletDB = new WalletDB({ + network: "regtest", + db: "memory", + client: new bcoin.node.NodeClient(node) // bad code: copy paste + }); + await walletDB.open(); + await walletDB.connect(); + + return walletDB; + }, + + closeNode: (walletDB, node) => { + walletDB.close(); + node.close(); + }, + getNode: async () => { var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); From 750397fca1f8d968befdc07f278f0b38ff2e7e5e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 21:00:47 +0100 Subject: [PATCH 122/540] Split node into miner and SPV node Keep one node open at a time --- test/spv_node.js | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index f24d2f5..a7bd092 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -19,30 +19,33 @@ require("should-sinon"); const COIN = consensus.COIN; describe("SPVNode", () => { - var node = null; - var walletDB = null; + var SPVNode = null; + var miner = null; + var SPVWalletDB = null; + var minerWalletDB = null; var NodeWatcher = null; - var watcher = null; - - beforeEach("get node", async () => { - node = await testHelpers.getNode(); - watcher = new testHelpers.NodeWatcher(node); - }); - - beforeEach("get walletDB", async () => { - walletDB = await testHelpers.getWalletDB(node); + var SPVWatcher = null; + var minerWatcher = null; + + beforeEach("get an SPV and a full node", async () => { + SPVNode = new Trust.SPVNode({network: "regtest", passphrase: "secret"}); + miner = new Trust.FullNode({network: "regtest", passphrase: "secret"}); + SPVWatcher = new testHelpers.NodeWatcher(SPVNode); + minerWatcher = new testHelpers.NodeWatcher(miner); }); - afterEach("close walletDB", async () => walletDB.close()); - afterEach("close node", async () => node.close()); - it("should call trust.addTX() on every transaction", async function() { - var sender = await testHelpers.createWallet(walletDB, "sender"); - var receiver = await testHelpers.createWallet(walletDB, "receiver"); + + SPVWalletDB = await testHelpers.openNode(SPVNode); + var receiver = await testHelpers.createWallet(SPVWalletDB, "receiver"); + testHelpers.closeNode(SPVWalletDB, SPVNode); + await testHelpers.delay(1000); + minerWalletDB = await testHelpers.openNode(miner); + var sender = await testHelpers.createWallet(minerWalletDB, "sender"); await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. - await testHelpers.mineBlock(node, sender.getAddress("base58")); + await testHelpers.mineBlock(miner, sender.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; @@ -54,9 +57,13 @@ describe("SPVNode", () => { address: receiver.getAddress("base58") }] }); - await watcher.waitForTX(); + await testHelpers.delay(1000); + testHelpers.closeNode(minerWalletDB, miner); + SPVWalletDB = await testHelpers.openNode(SPVNode); + await SPVWatcher.waitForTX(); - node.trust.addTX.should.be.calledOnce(); + SPVNode.trust.addTX.should.be.calledOnce(); + testHelpers.closeNode(SPVWalletDB, SPVNode); }); describe("with the nobodyLikesFrank.json example", () => { From c13ec7372b01c8d443c997bf8fdce4d3470d99c7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Sep 2017 22:10:19 +0100 Subject: [PATCH 123/540] Add TODO for using different ports --- test/spv_node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index a7bd092..516d808 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -27,6 +27,10 @@ describe("SPVNode", () => { var SPVWatcher = null; var minerWatcher = null; +// TODO: Scrap all changes and find a way to use two ports and inform the two +// nodes for each other using the `nodes` or `known-peers` from the pool options +// of https://github.com/bcoin-org/bcoin/wiki/Configuration + beforeEach("get an SPV and a full node", async () => { SPVNode = new Trust.SPVNode({network: "regtest", passphrase: "secret"}); miner = new Trust.FullNode({network: "regtest", passphrase: "secret"}); From 1ebdb092e5abf060fca97bf5ee6319f66d638a83 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 29 Sep 2017 16:07:45 +0100 Subject: [PATCH 124/540] Try to add ports and known nodes --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 516d808..497f677 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -32,8 +32,8 @@ describe("SPVNode", () => { // of https://github.com/bcoin-org/bcoin/wiki/Configuration beforeEach("get an SPV and a full node", async () => { - SPVNode = new Trust.SPVNode({network: "regtest", passphrase: "secret"}); - miner = new Trust.FullNode({network: "regtest", passphrase: "secret"}); + SPVNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48332, node: "127.0.0.1/48333"}); + miner = new Trust.FullNode({network: "regtest", passphrase: "secret", port: 48333, node: "127.0.0.1/48332"}); SPVWatcher = new testHelpers.NodeWatcher(SPVNode); minerWatcher = new testHelpers.NodeWatcher(miner); }); From 66805181af0f13a921cc75220bc807730d22f02d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 19:21:27 +0100 Subject: [PATCH 125/540] Add cases for getNode() --- test/helpers.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index eb53f06..1957a7f 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -25,8 +25,17 @@ var testHelpers = { node.close(); }, - getNode: async () => { - var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); + getNode: async (type) => { + var node = null; + assert(type === undefined || type === "spv" || type === "full"); + if (type === undefined) + node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); + else if (type === "spv") + node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret", + port: 48332, node: "127.0.0.1/48333"}); + else // if type === "full" + node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret", + port: 48333, node: "127.0.0.1/48332"}); await node.open(); await node.connect(); From 9f5c9120579ae6224251a4fbbe285904765a257e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 19:23:24 +0100 Subject: [PATCH 126/540] Declare nodes, wallets, watchers --- test/spv_node.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 497f677..0cacffb 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -19,12 +19,12 @@ require("should-sinon"); const COIN = consensus.COIN; describe("SPVNode", () => { - var SPVNode = null; + var spvNode = null; var miner = null; - var SPVWalletDB = null; + var spvWalletDB = null; var minerWalletDB = null; var NodeWatcher = null; - var SPVWatcher = null; + var spvWatcher = null; var minerWatcher = null; // TODO: Scrap all changes and find a way to use two ports and inform the two From cc5e78b7ca3d0f6f5dff5314cdfaf87d0ad551e3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 19:24:09 +0100 Subject: [PATCH 127/540] Remove redundant NodeWatcher declaration --- test/spv_node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 0cacffb..f5da80d 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -23,7 +23,6 @@ describe("SPVNode", () => { var miner = null; var spvWalletDB = null; var minerWalletDB = null; - var NodeWatcher = null; var spvWatcher = null; var minerWatcher = null; From 4194aad252e0aaf131b7d1243cd3dd3b2c11797b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 19:25:07 +0100 Subject: [PATCH 128/540] Spy addTX() with sinon --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index f5da80d..115ee30 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -25,6 +25,7 @@ describe("SPVNode", () => { var minerWalletDB = null; var spvWatcher = null; var minerWatcher = null; + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); // TODO: Scrap all changes and find a way to use two ports and inform the two // nodes for each other using the `nodes` or `known-peers` from the pool options From c41a48f091714abdbf9656949eb6f86efad631e4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 19:26:55 +0100 Subject: [PATCH 129/540] Add pre-setup and post-maintain --- test/spv_node.js | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 115ee30..5fb5ac9 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -31,13 +31,30 @@ describe("SPVNode", () => { // nodes for each other using the `nodes` or `known-peers` from the pool options // of https://github.com/bcoin-org/bcoin/wiki/Configuration - beforeEach("get an SPV and a full node", async () => { - SPVNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48332, node: "127.0.0.1/48333"}); - miner = new Trust.FullNode({network: "regtest", passphrase: "secret", port: 48333, node: "127.0.0.1/48332"}); - SPVWatcher = new testHelpers.NodeWatcher(SPVNode); + beforeEach("get SPV node", async () => { + spvNode = await testHelpers.getNode("spv"); + spvWatcher = new testHelpers.NodeWatcher(spvNode); + }); + + beforeEach("get miner (full node)", async () => { + miner = await testHelpers.getNode("full"); minerWatcher = new testHelpers.NodeWatcher(miner); }); + beforeEach("get spvWalletDB", async () => { + spvWalletDB = await testHelpers.getWalletDB(spvNode); + }); + + beforeEach("get minerWalletDB", async () => { + minerWalletDB = await testHelpers.getWalletDB(miner); + }); + + afterEach("close spvWalletDB", async () => spvWalletDB.close()); + afterEach("close minerWalletDB", async () => minerWalletDB.close()); + + afterEach("close SPV node", async () => spvNode.close()); + afterEach("close miner (full node)", async () => miner.close()); + it("should call trust.addTX() on every transaction", async function() { SPVWalletDB = await testHelpers.openNode(SPVNode); From 040225d6a6428c7a2c5095c0671b0fc89576b622 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:00:01 +0100 Subject: [PATCH 130/540] Use new ports --- test/helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 1957a7f..743beb2 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -32,10 +32,10 @@ var testHelpers = { node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); else if (type === "spv") node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret", - port: 48332, node: "127.0.0.1/48333"}); + port: 48333, node: "127.0.0.1:48334"}); else // if type === "full" node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret", - port: 48333, node: "127.0.0.1/48332"}); + port: 48334, node: "127.0.0.1:48333"}); await node.open(); await node.connect(); From 11ae4a1368b90af3eb3a8a86f43ab5ef705baa52 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:25:28 +0100 Subject: [PATCH 131/540] Remove redundant sinon.spy() --- test/spv_node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 5fb5ac9..179fb26 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -25,7 +25,6 @@ describe("SPVNode", () => { var minerWalletDB = null; var spvWatcher = null; var minerWatcher = null; - sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); // TODO: Scrap all changes and find a way to use two ports and inform the two // nodes for each other using the `nodes` or `known-peers` from the pool options From c31a6a8414bbf37b1c01632b53ebe53dde6fcc37 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:25:43 +0100 Subject: [PATCH 132/540] Remove TODO comment --- test/spv_node.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 179fb26..2f22e41 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -26,10 +26,6 @@ describe("SPVNode", () => { var spvWatcher = null; var minerWatcher = null; -// TODO: Scrap all changes and find a way to use two ports and inform the two -// nodes for each other using the `nodes` or `known-peers` from the pool options -// of https://github.com/bcoin-org/bcoin/wiki/Configuration - beforeEach("get SPV node", async () => { spvNode = await testHelpers.getNode("spv"); spvWatcher = new testHelpers.NodeWatcher(spvNode); From 92e8a3d41206aa74a5db092979866208697b6a8b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:27:17 +0100 Subject: [PATCH 133/540] Define senders, receivers --- test/spv_node.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 2f22e41..edad5f8 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -51,13 +51,14 @@ describe("SPVNode", () => { afterEach("close miner (full node)", async () => miner.close()); it("should call trust.addTX() on every transaction", async function() { + var spvSender = await testHelpers.createWallet(spvWalletDB, "sender"); + var spvReceiver = await testHelpers.createWallet(spvWalletDB, "receiver"); SPVWalletDB = await testHelpers.openNode(SPVNode); - var receiver = await testHelpers.createWallet(SPVWalletDB, "receiver"); testHelpers.closeNode(SPVWalletDB, SPVNode); - await testHelpers.delay(1000); minerWalletDB = await testHelpers.openNode(miner); - var sender = await testHelpers.createWallet(minerWalletDB, "sender"); + var minerSender = await testHelpers.createWallet(minerWalletDB, "sender"); + var minerReceiver = await testHelpers.createWallet(minerWalletDB, "receiver"); await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. From 2a6f5cfaf8bef15e41bef5bf4d5a929f461205b5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:31:19 +0100 Subject: [PATCH 134/540] Have both nodes open simultaneously --- test/spv_node.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index edad5f8..ad4ab78 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -54,9 +54,6 @@ describe("SPVNode", () => { var spvSender = await testHelpers.createWallet(spvWalletDB, "sender"); var spvReceiver = await testHelpers.createWallet(spvWalletDB, "receiver"); - SPVWalletDB = await testHelpers.openNode(SPVNode); - testHelpers.closeNode(SPVWalletDB, SPVNode); - minerWalletDB = await testHelpers.openNode(miner); var minerSender = await testHelpers.createWallet(minerWalletDB, "sender"); var minerReceiver = await testHelpers.createWallet(minerWalletDB, "receiver"); @@ -75,12 +72,9 @@ describe("SPVNode", () => { }] }); await testHelpers.delay(1000); - testHelpers.closeNode(minerWalletDB, miner); - SPVWalletDB = await testHelpers.openNode(SPVNode); await SPVWatcher.waitForTX(); SPVNode.trust.addTX.should.be.calledOnce(); - testHelpers.closeNode(SPVWalletDB, SPVNode); }); describe("with the nobodyLikesFrank.json example", () => { From 66d7d5a8f732250232a92330fa0a5d3186f0d2f9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:32:43 +0100 Subject: [PATCH 135/540] Remove redundant timeout --- test/spv_node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index ad4ab78..ac42e06 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -71,7 +71,6 @@ describe("SPVNode", () => { address: receiver.getAddress("base58") }] }); - await testHelpers.delay(1000); await SPVWatcher.waitForTX(); SPVNode.trust.addTX.should.be.calledOnce(); From c5e4b9142c9a82fd220e0a11b5f2190c3662df14 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:33:27 +0100 Subject: [PATCH 136/540] Replace sender with minerSender --- test/spv_node.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index ac42e06..d1c92f4 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -58,14 +58,14 @@ describe("SPVNode", () => { var minerReceiver = await testHelpers.createWallet(minerWalletDB, "receiver"); await testHelpers.delay(1000); - // Produce a block and reward the sender, so that we have a coin to spend. - await testHelpers.mineBlock(miner, sender.getAddress("base58")); + // Produce a block and reward the minerSender, so that we have a coin to spend. + await testHelpers.mineBlock(miner, minerSender.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - await sender.send({ + await minerSender.send({ outputs: [{ value: 10 * COIN, address: receiver.getAddress("base58") From 414e79eb8791a4eaf50a91ad2fc810eed7c7e8fc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 20:33:41 +0100 Subject: [PATCH 137/540] Replace node with miner --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index d1c92f4..3872af2 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -73,7 +73,7 @@ describe("SPVNode", () => { }); await SPVWatcher.waitForTX(); - SPVNode.trust.addTX.should.be.calledOnce(); + minerNode.trust.addTX.should.be.calledOnce(); }); describe("with the nobodyLikesFrank.json example", () => { @@ -91,7 +91,7 @@ describe("SPVNode", () => { var blockCount = 3; var coinbaseHashes = []; for(let i = 0; i < blockCount; i++) { - var block = await testHelpers.mineBlock(node, addresses.alice); + var block = await testHelpers.mineBlock(miner, addresses.alice); coinbaseHashes.push(block.txs[0].hash()); await testHelpers.delay(500); } From 53a6b533686b0234e64616a66714340a0784a1dc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 21:52:39 +0100 Subject: [PATCH 138/540] Improve comment appearance and fix typo --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 3872af2..ea0236f 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -105,8 +105,8 @@ describe("SPVNode", () => { sendAmount * consensus.COIN); }); - // We have to use a change output, because transaction with too large a fee are considered - // invalid. + // We have to use a change output, because transactions with too large a fee are + // considered invalid. var fee = 0.01; var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; if (changeAmount >= 0.01) { From cf3da3761e129c4ebf2ecc4743fccc0f61a3b5cb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 21:55:18 +0100 Subject: [PATCH 139/540] Replace node with miner --- test/spv_node.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index ea0236f..49f57a9 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -119,7 +119,7 @@ describe("SPVNode", () => { // Use the coinbase coins as inputs var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { - return node.getCoin(hash.toString("hex"), 0); + return miner.getCoin(hash.toString("hex"), 0); })); var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); @@ -129,8 +129,8 @@ describe("SPVNode", () => { assert(await mtx.verify()); var tx = mtx.toTX(); - node.sendTX(tx); - await watcher.waitForTX(); + miner.sendTX(tx); + await minerWatcher.waitForTX(); prevout = {}; fixtures.names.forEach((name) => { @@ -141,7 +141,7 @@ describe("SPVNode", () => { }); // Alice mines another block - await testHelpers.mineBlock(node, helpers.pubKeyToEntity( + await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( fixtures.keyRings.alice.getPublicKey())); await testHelpers.delay(500); @@ -171,7 +171,7 @@ describe("SPVNode", () => { } // Alice mines yet another block - await testHelpers.mineBlock(node, helpers.pubKeyToEntity( + await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( fixtures.keyRings.alice.getPublicKey())); await testHelpers.delay(500); }); @@ -194,16 +194,16 @@ describe("SPVNode", () => { }); it("after decreasing some trusts computes trusts correctly", async () => { - var mtxs = node.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), + var mtxs = miner.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), fixtures.keyRings.bob.getPublicKey(), 3 * COIN); mtxs.length.should.equal(1); var mtx = mtxs[0]; should(await mtx.verify()); - node.sendTX(mtx.toTX()); + miner.sendTX(mtx.toTX()); await testHelpers.delay(750); - should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + should(miner.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); }); }); From 5073456bacddccf8056ca050a8485cb06d282ff7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 21:56:01 +0100 Subject: [PATCH 140/540] Send some txs from SPV node --- test/spv_node.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 49f57a9..e592981 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -152,6 +152,15 @@ describe("SPVNode", () => { var value = neighbours[dest]; if (!value || value < 1) continue; + if (origin == charlie || origin == dave) { + let node = spvNode; + let watcher = spvWatcher; + } + else { + let node = miner; + let watcher = minerWatcher; + } + let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); let mtx = await node.trust.createTrustIncreasingMTX( From 010837d50e37a585971b9513b132df2b11e67501 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 21:57:38 +0100 Subject: [PATCH 141/540] Test miner computes trusts well --- test/spv_node.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index e592981..3f4c023 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -185,7 +185,23 @@ describe("SPVNode", () => { await testHelpers.delay(500); }); - it("computes trusts correctly", () => { + it("lets the miner compute trusts correctly", () => { + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + should(miner.trust.getIndirectTrust(alice, alice)).equal(Infinity); + should(miner.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); + should(miner.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); + should(miner.trust.getIndirectTrust(alice, frank)).equal(0); + should(miner.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + + should(miner.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); + should(miner.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); + should(miner.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); + should(miner.trust.getIndirectTrust(george, eve)).equal(0); + }); + for (name in addresses) { // Add addresses to scope eval(`var ${name} = "${addresses[name]}";`); } From f1bee94043f2d031083b3c2f6cff4d3deb61aafa Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 21:58:12 +0100 Subject: [PATCH 142/540] Test SPV node computes trusts well --- test/spv_node.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 3f4c023..242438f 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -202,20 +202,21 @@ describe("SPVNode", () => { should(miner.trust.getIndirectTrust(george, eve)).equal(0); }); + it("lets the SPV node compute trusts correctly", () => { for (name in addresses) { // Add addresses to scope eval(`var ${name} = "${addresses[name]}";`); } - should(node.trust.getIndirectTrust(alice, alice)).equal(Infinity); - should(node.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); - should(node.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); - should(node.trust.getIndirectTrust(alice, frank)).equal(0); - should(node.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + should(spvNode.trust.getIndirectTrust(alice, alice)).equal(Infinity); + should(spvNode.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); + should(spvNode.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); + should(spvNode.trust.getIndirectTrust(alice, frank)).equal(0); + should(spvNode.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); - should(node.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); - should(node.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); - should(node.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); - should(node.trust.getIndirectTrust(george, eve)).equal(0); + should(spvNode.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); + should(spvNode.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); + should(spvNode.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); + should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); }); it("after decreasing some trusts computes trusts correctly", async () => { From 43ceb33502ded52e30ef312db18f56e608e9e00d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 22:03:12 +0100 Subject: [PATCH 143/540] Check trust with both nodes --- test/spv_node.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 242438f..1ab9043 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -219,7 +219,7 @@ describe("SPVNode", () => { should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); }); - it("after decreasing some trusts computes trusts correctly", async () => { + it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { var mtxs = miner.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), fixtures.keyRings.bob.getPublicKey(), 3 * COIN); mtxs.length.should.equal(1); @@ -229,7 +229,10 @@ describe("SPVNode", () => { miner.sendTX(mtx.toTX()); await testHelpers.delay(750); + should(miner.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + should(spvNode.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); should(miner.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); + should(spvNode.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); }); }); From 4ecbaa3bdf5917da07f1650f4a2d61a53dc2ab86 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 22:03:42 +0100 Subject: [PATCH 144/540] Decrease a trust with the SPV node --- test/spv_node.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 1ab9043..7f2c522 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -231,6 +231,16 @@ describe("SPVNode", () => { await testHelpers.delay(750); should(miner.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); should(spvNode.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + + mtxs = spvNode.trust.createTrustDecreasingMTXs(fixtures.keyRings.dave.getPrivateKey(), + fixtures.keyRings.eve.getPublicKey(), 2 * COIN); + mtxs.length.should.equal(1); + mtx = mtxs[0]; + + should(await mtx.verify()); + spvNode.sendTX(mtx.toTX()); + + await testHelpers.delay(750); should(miner.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); should(spvNode.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); }); From 288193779f3e212e40c05d2745f371ef6e799bc0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Oct 2017 22:05:40 +0100 Subject: [PATCH 145/540] Replace tabs with spaces --- test/spv_node.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 7f2c522..c62139f 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -154,12 +154,12 @@ describe("SPVNode", () => { if (origin == charlie || origin == dave) { let node = spvNode; - let watcher = spvWatcher; - } - else { - let node = miner; - let watcher = minerWatcher; - } + let watcher = spvWatcher; + } + else { + let node = miner; + let watcher = minerWatcher; + } let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); From 4b2cfd4b002b23c523152a49c32e3967586c0c34 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 02:07:06 +0100 Subject: [PATCH 146/540] Treat sinon "addTX" spy better Enclose its invocation in a mocha "before" and reset() it in an "after". This way the next test, spv_node.js, finds the addTX() invocations counter reset to zero. --- test/full_node.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index a3260ba..2276972 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -18,12 +18,20 @@ require("should-sinon"); const COIN = consensus.COIN; + describe("FullNode", () => { var node = null; var walletDB = null; var NodeWatcher = null; var watcher = null; - sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); + + before("set up addTX() spy", function() { + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); + }); + + after("reset addTX spy", function() { + Trust.TrustIsRisk.prototype.addTX.reset(); + }); beforeEach("get node", async () => { node = await testHelpers.getNode(); @@ -36,7 +44,7 @@ describe("FullNode", () => { afterEach("close walletDB", async () => walletDB.close()); afterEach("close node", async () => node.close()); - + it("should call trust.addTX() on every transaction", async function() { var sender = await testHelpers.createWallet(walletDB, "sender"); var receiver = await testHelpers.createWallet(walletDB, "receiver"); From b178ec842b3e33f8b3ff204bf0718c796bb7564c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 02:12:18 +0100 Subject: [PATCH 147/540] Give senders, receivers unique ids --- test/spv_node.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index c62139f..83a713d 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -51,11 +51,11 @@ describe("SPVNode", () => { afterEach("close miner (full node)", async () => miner.close()); it("should call trust.addTX() on every transaction", async function() { - var spvSender = await testHelpers.createWallet(spvWalletDB, "sender"); - var spvReceiver = await testHelpers.createWallet(spvWalletDB, "receiver"); + var spvSender = await testHelpers.createWallet(spvWalletDB, "spvSender"); + var spvReceiver = await testHelpers.createWallet(spvWalletDB, "spvReceiver"); - var minerSender = await testHelpers.createWallet(minerWalletDB, "sender"); - var minerReceiver = await testHelpers.createWallet(minerWalletDB, "receiver"); + var minerSender = await testHelpers.createWallet(minerWalletDB, "minerSender"); + var minerReceiver = await testHelpers.createWallet(minerWalletDB, "minerReceiver"); await testHelpers.delay(1000); // Produce a block and reward the minerSender, so that we have a coin to spend. From bdbdc47502a22b1c8ec389eea0555c61b9f9f66e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 02:13:40 +0100 Subject: [PATCH 148/540] Use miner node correctly --- test/spv_node.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 83a713d..0a0fb0a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -68,12 +68,12 @@ describe("SPVNode", () => { await minerSender.send({ outputs: [{ value: 10 * COIN, - address: receiver.getAddress("base58") + address: minerReceiver.getAddress("base58") }] }); - await SPVWatcher.waitForTX(); + await minerWatcher.waitForTX(); - minerNode.trust.addTX.should.be.calledOnce(); + miner.trust.addTX.should.be.calledOnce(); }); describe("with the nobodyLikesFrank.json example", () => { From be52d4308b7d89909de82e41f9fec86a3ae38486 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 02:14:07 +0100 Subject: [PATCH 149/540] Fix empty line spaces --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 0a0fb0a..32132d4 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -162,7 +162,7 @@ describe("SPVNode", () => { } let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - + let mtx = await node.trust.createTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), From 73d301d52a1d70d004e2977eaf4fcaf35e798ac3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 02:15:14 +0100 Subject: [PATCH 150/540] Define node, watcher out of "if" Otherwise it is considered undefined later --- test/spv_node.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 32132d4..e2bf7d6 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -152,13 +152,15 @@ describe("SPVNode", () => { var value = neighbours[dest]; if (!value || value < 1) continue; - if (origin == charlie || origin == dave) { - let node = spvNode; - let watcher = spvWatcher; + let node = null; + let watcher = null; + if (origin === "charlie" || origin == "dave") { + node = spvNode; + watcher = spvWatcher; } else { - let node = miner; - let watcher = minerWatcher; + node = miner; + watcher = minerWatcher; } let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); From e6f38ff5384d5b18b0d7f9e151a8f31f8373379a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 21:58:38 +0100 Subject: [PATCH 151/540] Remove openNode(), closeNode() --- test/helpers.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 743beb2..315594e 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,26 +5,6 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - openNode: async (node) => { - await node.open(); - await node.connect(); - node.startSync(); - var walletDB = new WalletDB({ - network: "regtest", - db: "memory", - client: new bcoin.node.NodeClient(node) // bad code: copy paste - }); - await walletDB.open(); - await walletDB.connect(); - - return walletDB; - }, - - closeNode: (walletDB, node) => { - walletDB.close(); - node.close(); - }, - getNode: async (type) => { var node = null; assert(type === undefined || type === "spv" || type === "full"); From c27e848411cbdf39c616101f6e3910361c288e4d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 2 Oct 2017 22:28:44 +0100 Subject: [PATCH 152/540] Activate and restore spy correctly Use `return Trust.TrustIsRisk.prototype.addTX.restore()` in "after" in both test/full_node.js and test/spv_node.js --- test/full_node.js | 2 +- test/spv_node.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/test/full_node.js b/test/full_node.js index 2276972..429814c 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -30,7 +30,7 @@ describe("FullNode", () => { }); after("reset addTX spy", function() { - Trust.TrustIsRisk.prototype.addTX.reset(); + return Trust.TrustIsRisk.prototype.addTX.restore(); }); beforeEach("get node", async () => { diff --git a/test/spv_node.js b/test/spv_node.js index e2bf7d6..7bb5f4c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -26,6 +26,14 @@ describe("SPVNode", () => { var spvWatcher = null; var minerWatcher = null; + before("set up addTX() spy", function() { + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); + }); + + after("reset addTX spy", function() { + return Trust.TrustIsRisk.prototype.addTX.restore(); + }); + beforeEach("get SPV node", async () => { spvNode = await testHelpers.getNode("spv"); spvWatcher = new testHelpers.NodeWatcher(spvNode); From d6130d757984aae43d3f0d4f70f5c9c2d1ab57f9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 01:28:17 +0100 Subject: [PATCH 153/540] CreateMTX differently for spv nodes --- test/spv_node.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 7bb5f4c..1c183dd 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -173,11 +173,14 @@ describe("SPVNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = await node.trust.createTrustIncreasingMTX( + let mtx = null; + if (node.spv) console.log(await spvWalletDB.getHashes()); + else {mtx = await node.trust.createTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, value * consensus.COIN); + console.log(await minerWalletDB.getHashes());} assert(await mtx.verify()); From 5bb29e1f5586017379c43d826f1693af8f3744cc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 12:44:30 +0100 Subject: [PATCH 154/540] stopSync() and disconnect() before close() --- test/full_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 429814c..4486e9a 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -42,8 +42,8 @@ describe("FullNode", () => { walletDB = await testHelpers.getWalletDB(node); }); - afterEach("close walletDB", async () => walletDB.close()); - afterEach("close node", async () => node.close()); + afterEach("close walletDB", async () => testHelpers.closeWalletDB(walletDB)); + afterEach("close node", async () => testHelpers.closeNode(node)); it("should call trust.addTX() on every transaction", async function() { var sender = await testHelpers.createWallet(walletDB, "sender"); From 304e4c57376be27b5eba2b2307c25af1892bc43d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 12:45:05 +0100 Subject: [PATCH 155/540] Define closeNode() and closeWalletDB() --- test/helpers.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index 315594e..8b8325f 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -24,6 +24,12 @@ var testHelpers = { return node; }, + closeNode: async (node) => { + node.stopSync(); + await node.disconnect(); + await node.close(); + }, + getWalletDB: async (node) => { var walletDB = new WalletDB({ network: "regtest", @@ -37,6 +43,11 @@ var testHelpers = { return walletDB; }, + closeWalletDB: async (walletDB) => { + await walletDB.disconnect(); + await walletDB.close(); + }, + createWallet: async (walletDB, id) => { var options = { id, From 032e3c3a61b375f0bef1c3ef47c8e242adbb9979 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 12:45:34 +0100 Subject: [PATCH 156/540] Connect only SPV node to miner --- test/helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 8b8325f..560437e 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -12,10 +12,10 @@ var testHelpers = { node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); else if (type === "spv") node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret", - port: 48333, node: "127.0.0.1:48334"}); + port: 48333, nodes: ["127.0.0.1:48334"]}); else // if type === "full" node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret", - port: 48334, node: "127.0.0.1:48333"}); + port: 48334}); await node.open(); await node.connect(); From 8206f603fe6f23aeb3f9caf41758e4e5c15993d0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 12:47:12 +0100 Subject: [PATCH 157/540] Restructure beforeEach() Attempt to do each step for each node together to get them to connect to each other --- test/spv_node.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 1c183dd..93d1cc7 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -34,14 +34,25 @@ describe("SPVNode", () => { return Trust.TrustIsRisk.prototype.addTX.restore(); }); - beforeEach("get SPV node", async () => { - spvNode = await testHelpers.getNode("spv"); - spvWatcher = new testHelpers.NodeWatcher(spvNode); + beforeEach("get nodes", () => { + miner = new Trust.FullNode({network: "regtest", passphrase: "secret", port: 48334, nodes: ["127.0.0.1:48333"]}); + spvNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48333, nodes: ["127.0.0.1:48334"]}); + }); + + beforeEach("open and connect nodes", async () => { + await miner.open(); + await spvNode.open(); + + await miner.connect(); + await spvNode.connect(); + + miner.startSync(); + spvNode.startSync(); }); - beforeEach("get miner (full node)", async () => { - miner = await testHelpers.getNode("full"); + beforeEach("get watchers", () => { minerWatcher = new testHelpers.NodeWatcher(miner); + spvWatcher = new testHelpers.NodeWatcher(spvNode); }); beforeEach("get spvWalletDB", async () => { From 2c28d52b08d8e748d410e9ae2d5e4ac0f62e933a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 12:49:58 +0100 Subject: [PATCH 158/540] Remove console.log() --- test/spv_node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 93d1cc7..7a51f21 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -191,7 +191,6 @@ describe("SPVNode", () => { fixtures.keyRings[dest].getPublicKey(), outpoint, value * consensus.COIN); - console.log(await minerWalletDB.getHashes());} assert(await mtx.verify()); From b73cf91222de3c740fc029cb3c3b121844cfea48 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 12:50:15 +0100 Subject: [PATCH 159/540] Fix identation and whitespace --- test/spv_node.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 7a51f21..5a88276 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -62,7 +62,7 @@ describe("SPVNode", () => { beforeEach("get minerWalletDB", async () => { minerWalletDB = await testHelpers.getWalletDB(miner); }); - + afterEach("close spvWalletDB", async () => spvWalletDB.close()); afterEach("close minerWalletDB", async () => minerWalletDB.close()); @@ -186,11 +186,13 @@ describe("SPVNode", () => { let mtx = null; if (node.spv) console.log(await spvWalletDB.getHashes()); - else {mtx = await node.trust.createTrustIncreasingMTX( - fixtures.keyRings[origin].getPrivateKey(), - fixtures.keyRings[dest].getPublicKey(), - outpoint, - value * consensus.COIN); + else { // if full node + mtx = await node.trust.createTrustIncreasingMTX( + fixtures.keyRings[origin].getPrivateKey(), + fixtures.keyRings[dest].getPublicKey(), + outpoint, + value * consensus.COIN); + } assert(await mtx.verify()); From 1ac8a6e9d537e171373561b279a2a0841560a957 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 21:09:39 +0100 Subject: [PATCH 160/540] Add missing () --- test/full_node.js | 2 +- test/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 429814c..fc5086b 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -29,7 +29,7 @@ describe("FullNode", () => { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); }); - after("reset addTX spy", function() { + after("reset addTX() spy", function() { return Trust.TrustIsRisk.prototype.addTX.restore(); }); diff --git a/test/spv_node.js b/test/spv_node.js index 1c183dd..65de1c5 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -30,7 +30,7 @@ describe("SPVNode", () => { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); }); - after("reset addTX spy", function() { + after("reset addTX() spy", function() { return Trust.TrustIsRisk.prototype.addTX.restore(); }); From f9e1e24789bc770fb7e8c0976a84cbf157ef14a4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 21:13:19 +0100 Subject: [PATCH 161/540] Remove return before restore() --- test/full_node.js | 2 +- test/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index fc5086b..d7bc1e0 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -30,7 +30,7 @@ describe("FullNode", () => { }); after("reset addTX() spy", function() { - return Trust.TrustIsRisk.prototype.addTX.restore(); + Trust.TrustIsRisk.prototype.addTX.restore(); }); beforeEach("get node", async () => { diff --git a/test/spv_node.js b/test/spv_node.js index 65de1c5..f48486d 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -31,7 +31,7 @@ describe("SPVNode", () => { }); after("reset addTX() spy", function() { - return Trust.TrustIsRisk.prototype.addTX.restore(); + Trust.TrustIsRisk.prototype.addTX.restore(); }); beforeEach("get SPV node", async () => { From e405482a7af41de25d4d573a0634e5eff62faf1a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Oct 2017 22:17:17 +0100 Subject: [PATCH 162/540] Add TODO comments for coin --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 70699c2..3f11267 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -124,7 +124,7 @@ class TrustIsRisk { ] }); - var changeAmount = coin.value - trustAmount - fee; + var changeAmount = coin.value - trustAmount - fee; // TODO: find how to get the value another way assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ @@ -133,7 +133,7 @@ class TrustIsRisk { })); } - mtx.addCoin(coin); + mtx.addCoin(coin); // TODO: use addInput() instead var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); assert(success); From 9bc158f3508bc4298e504deeb2cf27952f186930 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 13:44:01 +0100 Subject: [PATCH 163/540] Add bcoin class --- flow-typed/npm/bcoin_vx.x.x.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 3bad75a..01571ea 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -17,6 +17,10 @@ declare class bcoin$SPVNode { //TODO Check if changes/additions are needed } +declare class bcoin$Wallet { + getTX() : bcoin$TX; +} + declare class bcoin$Pool { watchAddress(address : Buffer) : void; } From a7efec68e6775036b6a816c8c350e09c1fb2f785 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 13:44:29 +0100 Subject: [PATCH 164/540] Add getOutputValue() in bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 1 + 1 file changed, 1 insertion(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 01571ea..081b7e9 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -37,6 +37,7 @@ declare class bcoin$TX { outputs : bcoin$Output[]; hash(enc : ?'hex') : Buffer; + getOutputValue() : number; } From daa1fba9f60e8c7b0ba9cd3f20a3c187be600988 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 13:44:53 +0100 Subject: [PATCH 165/540] Add addInput() in bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 1 + 1 file changed, 1 insertion(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 081b7e9..ec0a33e 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -50,6 +50,7 @@ declare class bcoin$MTX { scriptVector(outputScript : bcoin$Script, inputScript : bcoin$Script, ring : bcoin$KeyRing) : boolean; addOutput(output : bcoin$Output) : void; addCoin(coin : bcoin$Coin) : void; + addInput(input : (bcoin$Input | Object)) : void; sign(ring : bcoin$KeyRing) : number; signInput(index : number, coin : bcoin$Coin, keyRing : bcoin$KeyRing) : boolean; } From c38a674bdb214dd3dcb7b78d8d4e82cdda54acce Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 13:45:26 +0100 Subject: [PATCH 166/540] Add missing parentheses to toTX --- flow-typed/npm/bcoin_vx.x.x.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index ec0a33e..ad17386 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -45,7 +45,7 @@ declare class bcoin$MTX { inputs : bcoin$Input[]; outputs : bcoin$Output[]; - toTX : bcoin$TX; + toTX() : bcoin$TX; template(ring : bcoin$KeyRing) : number; scriptVector(outputScript : bcoin$Script, inputScript : bcoin$Script, ring : bcoin$KeyRing) : boolean; addOutput(output : bcoin$Output) : void; From 5077a4ae81753e528464b3aa8d2ff63a459a030f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 13:48:51 +0100 Subject: [PATCH 167/540] Move pool property up --- flow-typed/npm/bcoin_vx.x.x.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index ad17386..381de85 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -10,10 +10,11 @@ declare class bcoin$FullNode { } declare class bcoin$SPVNode { + pool : bcoin$Pool; + on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; - pool : bcoin$Pool; //TODO Check if changes/additions are needed } From fb68612fcd1dace8d7ded7d0e94d9768bf74a886 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 13:49:17 +0100 Subject: [PATCH 168/540] Add bcoin class --- flow-typed/npm/bcoin_vx.x.x.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 381de85..9fc7fb8 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -18,6 +18,8 @@ declare class bcoin$SPVNode { //TODO Check if changes/additions are needed } +declare class bcoin$WalletDB {} + declare class bcoin$Wallet { getTX() : bcoin$TX; } From 5f66149e7ed095f92df1fae24b9131082c92e796 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 18:06:38 +0100 Subject: [PATCH 169/540] Add txid() to bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 9fc7fb8..e7ecec6 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -86,6 +86,8 @@ declare class bcoin$Script { declare class bcoin$Outpoint { hash : Buffer; index : number; + + txid() : Buffer; } declare class bcoin$KeyRing { From d0f1a5f171fe171b76d87b2647ce66b4b53a6003 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 18:38:28 +0100 Subject: [PATCH 170/540] Define delay() --- src/helpers.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/helpers.js b/src/helpers.js index 6416a31..7d25fcb 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -6,6 +6,12 @@ var Address = bcoin.primitives.Address; var helpers = { pubKeyToEntity: (key : Key) : Entity => { return Address.fromHash(bcoin.crypto.hash160(key)).toBase58(); + }, + + delay: async (milliseconds : number) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); } }; From 5d75e11374ec9c7c13f2c57eabd7af9d2bbd4973 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Oct 2017 18:38:54 +0100 Subject: [PATCH 171/540] Add temporary alternative function --- src/trust_is_risk.js | 64 ++++++++++++++++++++++++++++++++++++++++++++ test/full_node.js | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 3f11267..50f8c2b 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -143,6 +143,70 @@ class TrustIsRisk { return mtx; } + async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, + trustAmount : number, fee : ?number) + : Promise { + if (!fee) fee = 1000; // TODO: estimate this + if (origin === dest) throw new Error("Can not increase self-trust."); + + var originKeyRing = KeyRing.fromPrivate(origin); + var originPubKey = originKeyRing.getPublicKey(); + + var mtx = new MTX({ + outputs: [ + new Output({ + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), + value: trustAmount + }) + ] + }); + + if (node.spv) { + var txid = outpoint.txid(); + node.pool.watchAddress(txid); + helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) + + var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + if (!tx) throw new Error("Could not find tx"); + + + var changeAmount = tx.getOutputValue() - trustAmount - fee; // TODO: find how to get the value another way + assert(changeAmount >= 0); + if (changeAmount) { + mtx.addOutput(new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), + value: changeAmount + })); + } + + mtx.addCoin(coin); // TODO: use addInput() instead + } + + else { // node is full + var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + if (!coin) throw new Error("Could not find coin"); + + + var changeAmount = coin.value - trustAmount - fee; // TODO: find how to get the value another way + assert(changeAmount >= 0); + if (changeAmount) { + mtx.addOutput(new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), + value: changeAmount + })); + } + + mtx.addCoin(coin); // TODO: use addInput() instead + var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); + assert(success); + } + + var signedCount = mtx.sign(originKeyRing); + assert(signedCount === 1); + + return mtx; + } + // Returns an array of trust-decreasing mutable transaction objects, which reduce a trust // relationship by the amount specified. The payee will receive the amount deducted minus the // transaction fees via P2PKH. diff --git a/test/full_node.js b/test/full_node.js index 85253fa..9c7a24a 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -146,7 +146,7 @@ describe("FullNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = await node.trust.createTrustIncreasingMTX( + let mtx = await node.trust.ccreateTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, From a2e4759aacdb110f71907732d05609a791e824e5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 5 Oct 2017 23:20:51 +0100 Subject: [PATCH 172/540] Rephrase comment for clarity --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 50f8c2b..89fb403 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -182,7 +182,7 @@ class TrustIsRisk { mtx.addCoin(coin); // TODO: use addInput() instead } - else { // node is full + else { // it is a full node var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!coin) throw new Error("Could not find coin"); From 38c39e3e2b2e57dabb6a42db31b1c81f63f97023 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:21:33 +0100 Subject: [PATCH 173/540] Type bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index e7ecec6..741c49c 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -4,6 +4,8 @@ type Hash = (string | Buffer); type Network = any; declare class bcoin$FullNode { + pool : bcoin$Pool; + on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; @@ -25,9 +27,20 @@ declare class bcoin$Wallet { } declare class bcoin$Pool { + peers : bcoin$PeerList; + watchAddress(address : Buffer) : void; } +declare class bcoin$Peer {} + +declare class bcoin$PeerList { + get(hostname : string) : bcoin$Peer; + add(peer : bcoin$Peer) : void; + head() : bcoin$Peer; + next() : bcoin$Peer; +} + declare class bcoin$Address { toBase58() : string; hash : Buffer; From ec838444751cddcceab446f94b5600db07f6ea42 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:22:24 +0100 Subject: [PATCH 174/540] Add NodeWatcher from test/helpers.js --- src/helpers.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/helpers.js b/src/helpers.js index 7d25fcb..4d2a36c 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -3,7 +3,58 @@ import type {Entity, TXHash, Key} from "./types"; var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; +class NodeWatcher { + txCount : number; + blockCount : number; + node : (bcoin$FullNode | bcoin$SPVNode); + waitForBlock : Promise; + + constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { + this.txCount = 0; + this.blockCount = 0; + this.node = node; + this.node.on("tx", this.onTX.bind(this)); + this.node.on("block", this.onBlock.bind(this)); + } + + onTX() : void { + this.txCount++; + } + + onBlock() : void { + this.blockCount++; + } + + async waitForBlock(initialCount : number) : Promise { + if (initialCount === undefined) initialCount = this.blockCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.blockCount > initialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } + + async waitForTX(initialCount : ?number) : Promise { + var localInitialCount : number; + if (initialCount === undefined) localInitialCount = this.txCount; + else if (typeof initialCount === "number") localInitialCount = initialCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > localInitialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } +} + var helpers = { + NodeWatcher : NodeWatcher, + pubKeyToEntity: (key : Key) : Entity => { return Address.fromHash(bcoin.crypto.hash160(key)).toBase58(); }, @@ -15,4 +66,6 @@ var helpers = { } }; +helpers.NodeWatcher = NodeWatcher; + module.exports = helpers; From 582790a852f750325e592ac89588f9bf244916bc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:25:45 +0100 Subject: [PATCH 175/540] Declare changeAmount out of if --- src/trust_is_risk.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 89fb403..3461505 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -161,6 +161,8 @@ class TrustIsRisk { ] }); + var changeAmount = null; + if (node.spv) { var txid = outpoint.txid(); node.pool.watchAddress(txid); @@ -170,7 +172,7 @@ class TrustIsRisk { if (!tx) throw new Error("Could not find tx"); - var changeAmount = tx.getOutputValue() - trustAmount - fee; // TODO: find how to get the value another way + changeAmount = tx.getOutputValue() - trustAmount - fee; // TODO: find how to get the value another way assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ @@ -187,7 +189,7 @@ class TrustIsRisk { if (!coin) throw new Error("Could not find coin"); - var changeAmount = coin.value - trustAmount - fee; // TODO: find how to get the value another way + changeAmount = coin.value - trustAmount - fee; // TODO: find how to get the value another way assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ From d68e2e672d4b4d9011b33160ee6eca77f7b683ae Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:27:22 +0100 Subject: [PATCH 176/540] Pass node to ccreateTrustIncreasingMTX() --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 3461505..8bf9570 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -144,7 +144,7 @@ class TrustIsRisk { } async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, - trustAmount : number, fee : ?number) + trustAmount : number, node : (bcoin$FullNode | bcoin$SPVNode), fee : ?number) : Promise { if (!fee) fee = 1000; // TODO: estimate this if (origin === dest) throw new Error("Can not increase self-trust."); From bc179adb561490b6c5a3bd5f681ad07ebe212900 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:28:32 +0100 Subject: [PATCH 177/540] Add watcher and wait for tx --- src/trust_is_risk.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 8bf9570..2839b16 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -165,8 +165,10 @@ class TrustIsRisk { if (node.spv) { var txid = outpoint.txid(); + var watcher = new helpers.NodeWatcher(node); node.pool.watchAddress(txid); helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) + await watcher.waitForTX(); var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!tx) throw new Error("Could not find tx"); From 46900feec8dc1dbf62841ff2b92a063a3f648d89 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:28:52 +0100 Subject: [PATCH 178/540] Declare tx to be filled --- src/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 2839b16..1128759 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -166,6 +166,7 @@ class TrustIsRisk { if (node.spv) { var txid = outpoint.txid(); var watcher = new helpers.NodeWatcher(node); + var tx = null; node.pool.watchAddress(txid); helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) await watcher.waitForTX(); From c4cb51086a76e283f9ba6148bbfca1400a1b8822 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:29:27 +0100 Subject: [PATCH 179/540] Comment out coin related instructions --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 1128759..0c5e76d 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -171,7 +171,7 @@ class TrustIsRisk { helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) await watcher.waitForTX(); - var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + // var coin = await this.node.getCoin(outpoint.hash, outpoint.index); if (!tx) throw new Error("Could not find tx"); @@ -184,7 +184,7 @@ class TrustIsRisk { })); } - mtx.addCoin(coin); // TODO: use addInput() instead + // mtx.addCoin(coin); // TODO: use addInput() instead } else { // it is a full node From 6590768eae758e62ca7dc1f2c591a7d66cc06085 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:30:26 +0100 Subject: [PATCH 180/540] Revert to createTrustIncreasingMTX() --- test/full_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/full_node.js b/test/full_node.js index 9c7a24a..85253fa 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -146,7 +146,7 @@ describe("FullNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = await node.trust.ccreateTrustIncreasingMTX( + let mtx = await node.trust.createTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, From 47f505c143a9ba1f772cf552306fce7877273961 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:32:04 +0100 Subject: [PATCH 181/540] Improve beforeEach, afterEach structure --- test/spv_node.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 35ff3ab..a14da6c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -39,13 +39,17 @@ describe("SPVNode", () => { spvNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48333, nodes: ["127.0.0.1:48334"]}); }); - beforeEach("open and connect nodes", async () => { + beforeEach("open nodes", async () => { await miner.open(); await spvNode.open(); + }); + beforeEach("connect nodes", async () => { await miner.connect(); await spvNode.connect(); + }); + beforeEach("start syncing nodes", () => { miner.startSync(); spvNode.startSync(); }); @@ -55,19 +59,20 @@ describe("SPVNode", () => { spvWatcher = new testHelpers.NodeWatcher(spvNode); }); - beforeEach("get spvWalletDB", async () => { + beforeEach("get walletDBs", async () => { spvWalletDB = await testHelpers.getWalletDB(spvNode); - }); - - beforeEach("get minerWalletDB", async () => { minerWalletDB = await testHelpers.getWalletDB(miner); }); - afterEach("close spvWalletDB", async () => spvWalletDB.close()); - afterEach("close minerWalletDB", async () => minerWalletDB.close()); + afterEach("close walletDBs", async () => { + await testHelpers.closeWalletDB(spvWalletDB); + await testHelpers.closeWalletDB(minerWalletDB); + }); - afterEach("close SPV node", async () => spvNode.close()); - afterEach("close miner (full node)", async () => miner.close()); + afterEach("close nodes", async () => { + await testHelpers.closeNode(spvNode); + await testHelpers.closeNode(miner); + }); it("should call trust.addTX() on every transaction", async function() { var spvSender = await testHelpers.createWallet(spvWalletDB, "spvSender"); From e685e6c419505d4cf2ee033c756724b1ed41d375 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:32:50 +0100 Subject: [PATCH 182/540] Remove "nodes" key from "new Node" --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index a14da6c..24a3dbf 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -35,8 +35,8 @@ describe("SPVNode", () => { }); beforeEach("get nodes", () => { - miner = new Trust.FullNode({network: "regtest", passphrase: "secret", port: 48334, nodes: ["127.0.0.1:48333"]}); - spvNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48333, nodes: ["127.0.0.1:48334"]}); + miner = new Trust.FullNode({network: "regtest", passphrase: "secret", port: 48334}); + spvNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48333}); }); beforeEach("open nodes", async () => { From b989a8c71951b381e9c657ef2fdcc8e612ef8358 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:33:16 +0100 Subject: [PATCH 183/540] Add commented out Peer connection attempt --- test/spv_node.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 24a3dbf..ca456d6 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -64,6 +64,14 @@ describe("SPVNode", () => { minerWalletDB = await testHelpers.getWalletDB(miner); }); +// beforeEach("connect nodes between them", () => { +// var minerPeer = bcoin.net.Peer.fromOptions({network: "regtest", passphrase: "secret", host: "127.0.0.1", port: 48334}); +// var socket = minerPeer.connect({host: "127.0.0.1", port: 48334}); +// console.log(socket); +// spvNode.pool.peers.add(minerPeer); +// console.log("edw"); +// }); + afterEach("close walletDBs", async () => { await testHelpers.closeWalletDB(spvWalletDB); await testHelpers.closeWalletDB(minerWalletDB); From b024b14616c92acf2cc65e56776895db03da0e56 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 9 Oct 2017 19:34:00 +0100 Subject: [PATCH 184/540] Call ccreateTrustIncreasingMTX() in spv --- test/spv_node.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index ca456d6..ee70024 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -198,7 +198,14 @@ describe("SPVNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); let mtx = null; - if (node.spv) console.log(await spvWalletDB.getHashes()); + if (node.spv) { + mtx = await node.trust.ccreateTrustIncreasingMTX( + fixtures.keyRings[origin].getPrivateKey(), + fixtures.keyRings[dest].getPublicKey(), + outpoint, + value * consensus.COIN, + node); + } else { // if full node mtx = await node.trust.createTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), From 211a0bb272414edea5f77ea68a8f97b6923d3a17 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 00:56:51 +0100 Subject: [PATCH 185/540] Improve nodes instatiations appearance --- test/spv_node.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index ee70024..756f865 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -35,8 +35,13 @@ describe("SPVNode", () => { }); beforeEach("get nodes", () => { - miner = new Trust.FullNode({network: "regtest", passphrase: "secret", port: 48334}); - spvNode = new Trust.SPVNode({network: "regtest", passphrase: "secret", port: 48333}); + miner = new Trust.FullNode({ + network: "regtest", passphrase: "secret" + }); + + spvNode = new Trust.SPVNode({ + network: "regtest", passphrase: "secret", port: 48333 + }); }); beforeEach("open nodes", async () => { From 89c35b8936f76373bcc01a65ec4a9f59fb7cd3f6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 00:57:30 +0100 Subject: [PATCH 186/540] Use RPC approach --- test/spv_node.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 756f865..4c66134 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -69,13 +69,16 @@ describe("SPVNode", () => { minerWalletDB = await testHelpers.getWalletDB(miner); }); -// beforeEach("connect nodes between them", () => { -// var minerPeer = bcoin.net.Peer.fromOptions({network: "regtest", passphrase: "secret", host: "127.0.0.1", port: 48334}); -// var socket = minerPeer.connect({host: "127.0.0.1", port: 48334}); -// console.log(socket); -// spvNode.pool.peers.add(minerPeer); -// console.log("edw"); -// }); + beforeEach("add miner to spvNode as peer", async () => { + const minerAddr = miner.http.config.host + ":" + miner.http.config.port; + + (async () => { + const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); + console.log(result); + })().catch((err) => { + console.error(err.stack); + }); + }); afterEach("close walletDBs", async () => { await testHelpers.closeWalletDB(spvWalletDB); From 8097bb0b6eb025c3861aedcb344abf7cf9494b2a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 00:58:03 +0100 Subject: [PATCH 187/540] Print the peers of the SPV node --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index 4c66134..2cb3164 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -207,6 +207,7 @@ describe("SPVNode", () => { let mtx = null; if (node.spv) { + console.log(node.pool.peers); mtx = await node.trust.ccreateTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), From 1929def909c4c34e23cf1d08b6548f81026bf99e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 02:34:39 +0100 Subject: [PATCH 188/540] Comment out RPC approach --- test/spv_node.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 2cb3164..c0b7b45 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -70,14 +70,14 @@ describe("SPVNode", () => { }); beforeEach("add miner to spvNode as peer", async () => { - const minerAddr = miner.http.config.host + ":" + miner.http.config.port; - - (async () => { - const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); - console.log(result); - })().catch((err) => { - console.error(err.stack); - }); +// const minerAddr = miner.http.config.host + ":" + miner.http.config.port; +// +// (async () => { +// const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); +// console.log(result); +// })().catch((err) => { +// console.error(err.stack); +// }); }); afterEach("close walletDBs", async () => { From 3dae01b0e6d5b5171f1883f1c6cf3338a12c977c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 02:35:58 +0100 Subject: [PATCH 189/540] Connect peers with peer.connect --- test/spv_node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index c0b7b45..f2464a0 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -70,6 +70,10 @@ describe("SPVNode", () => { }); beforeEach("add miner to spvNode as peer", async () => { +// const minerAddr = bcoin.netaddress.fromHostname(miner.http.config.host + ":" + miner.http.config.port, "regtest"); +// spvNode.pool.peer.connect(minerAddr); +// spvNode.pool.peer.tryOpen(); + // const minerAddr = miner.http.config.host + ":" + miner.http.config.port; // // (async () => { From 8298b44cd793af81a8730d74495df502d1dd6e72 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 02:36:23 +0100 Subject: [PATCH 190/540] Try to avoid separate new WalletDBs --- test/spv_node.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index f2464a0..d9250cc 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -8,6 +8,7 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; +var WalletDB = bcoin.wallet.WalletDB; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); @@ -95,7 +96,8 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvSender = await testHelpers.createWallet(spvWalletDB, "spvSender"); + var spvSender = await WalletDB.create({id: "spvSender", passphrase: "secret", witness: false, type: + "pubkeyhash"});//testHelpers.createWallet(spvWalletDB, "spvSender"); TODO: kill redundant walletDBs var spvReceiver = await testHelpers.createWallet(spvWalletDB, "spvReceiver"); var minerSender = await testHelpers.createWallet(minerWalletDB, "minerSender"); From 2123bbc324022de1aa809735c8163d39aadcb1d6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 11:03:31 +0100 Subject: [PATCH 191/540] Use correct sequence for before/afterEach actions In order for the node to remain conneted and have a properly set up walletDB, the sequence of beforeEach actions should be as follows: 1. Instantiate and open node 2. Open and connect walletDB 3. connect node The inverse holds for the afterEach actions. --- test/full_node.js | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 85253fa..f085c65 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -34,17 +34,37 @@ describe("FullNode", () => { }); beforeEach("get node", async () => { - node = await testHelpers.getNode(); - watcher = new testHelpers.NodeWatcher(node); + node = new Trust.FullNode({network: "regtest", passphrase: "secret"}); + await node.open(); }); - beforeEach("get walletDB", async () => { + beforeEach("get connected walletDB", async () => { walletDB = await testHelpers.getWalletDB(node); }); - afterEach("close walletDB", async () => testHelpers.closeWalletDB(walletDB)); - afterEach("close node", async () => testHelpers.closeNode(node)); + beforeEach("connect node", async () => { + await node.connect(); + node.startSync(); + }); + + beforeEach("get watcher", async () => { + watcher = new testHelpers.NodeWatcher(node); + }); + + afterEach("disconnect node", async () => { + node.stopSync(); + await node.disconnect(); + }); + + afterEach("disconnect and close walletDB", async () => { + await walletDB.disconnect(); + await walletDB.close(); + }); + afterEach("close node", async () => { + await node.close(); + }); + it("should call trust.addTX() on every transaction", async function() { var sender = await testHelpers.createWallet(walletDB, "sender"); var receiver = await testHelpers.createWallet(walletDB, "receiver"); From f7796cd092320b4019a1a6864c949a3ef66f7dd7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 11:07:41 +0100 Subject: [PATCH 192/540] Remove spv/full node logic from getNode() --- test/helpers.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 560437e..d71c9c0 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -6,17 +6,7 @@ var assert = require("assert"); var testHelpers = { getNode: async (type) => { - var node = null; - assert(type === undefined || type === "spv" || type === "full"); - if (type === undefined) - node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); - else if (type === "spv") - node = new TrustIsRisk.SPVNode({network: "regtest", passphrase: "secret", - port: 48333, nodes: ["127.0.0.1:48334"]}); - else // if type === "full" - node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret", - port: 48334}); - + var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); await node.open(); await node.connect(); node.startSync(); From 32b41e5c5cc8432a75264f8b84994ef5bd23094b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 11:08:08 +0100 Subject: [PATCH 193/540] Move connect actions to dedicated beforeEach --- test/helpers.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index d71c9c0..bc75d2d 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -8,12 +8,15 @@ var testHelpers = { getNode: async (type) => { var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); await node.open(); - await node.connect(); - node.startSync(); return node; }, + connectNode: async (node) => { + await node.connect(); + node.startSync(); + }, + closeNode: async (node) => { node.stopSync(); await node.disconnect(); From aa5ce6b3fd42fdfa4d4a937293373efb337b7447 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 18:33:18 +0100 Subject: [PATCH 194/540] Improve appearance and indenting --- test/full_node.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/full_node.js b/test/full_node.js index f085c65..db2d1f0 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -34,7 +34,10 @@ describe("FullNode", () => { }); beforeEach("get node", async () => { - node = new Trust.FullNode({network: "regtest", passphrase: "secret"}); + node = new Trust.FullNode({ + network: "regtest", passphrase: "secret" + }); + await node.open(); }); From 829b02e8b16a2e35d86a5c1d17ee9b9c24c1061d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 18:43:54 +0100 Subject: [PATCH 195/540] Use correct sequence for before/afterEach actions In order for the node to remain conneted and have a properly set up walletDB, the sequence of beforeEach actions should be as follows: 1. Instantiate and open node 2. Open and connect walletDB 3. connect node The inverse holds for the afterEach actions. --- test/spv_node.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index d9250cc..9bf3dba 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -50,6 +50,11 @@ describe("SPVNode", () => { await spvNode.open(); }); + beforeEach("get connected walletDBs", async () => { + minerWalletDB = await testHelpers.getWalletDB(miner); + spvWalletDB = await testHelpers.getWalletDB(spvNode); + }); + beforeEach("connect nodes", async () => { await miner.connect(); await spvNode.connect(); @@ -65,10 +70,6 @@ describe("SPVNode", () => { spvWatcher = new testHelpers.NodeWatcher(spvNode); }); - beforeEach("get walletDBs", async () => { - spvWalletDB = await testHelpers.getWalletDB(spvNode); - minerWalletDB = await testHelpers.getWalletDB(miner); - }); beforeEach("add miner to spvNode as peer", async () => { // const minerAddr = bcoin.netaddress.fromHostname(miner.http.config.host + ":" + miner.http.config.port, "regtest"); @@ -85,14 +86,25 @@ describe("SPVNode", () => { // }); }); - afterEach("close walletDBs", async () => { - await testHelpers.closeWalletDB(spvWalletDB); - await testHelpers.closeWalletDB(minerWalletDB); + afterEach("disconnect nodes", async () => { + spvNode.stopSync(); + miner.stopSync(); + + await spvNode.disconnect(); + await miner.disconnect(); + }); + + afterEach("disconnect and close walletDBs", async () => { + await spvWalletDB.disconnect(); + await minerWalletDB.disconnet(); + + await spvWalletDB.close(); + await minerWalletDB.close(); }); afterEach("close nodes", async () => { - await testHelpers.closeNode(spvNode); - await testHelpers.closeNode(miner); + await spvNode.close(); + await miner.close(); }); it("should call trust.addTX() on every transaction", async function() { From d3829bad030032c76de60c05e6c1a17e8e305609 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 18:45:21 +0100 Subject: [PATCH 196/540] Remove redundant functions from helpers --- test/helpers.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index bc75d2d..86e58de 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -12,17 +12,6 @@ var testHelpers = { return node; }, - connectNode: async (node) => { - await node.connect(); - node.startSync(); - }, - - closeNode: async (node) => { - node.stopSync(); - await node.disconnect(); - await node.close(); - }, - getWalletDB: async (node) => { var walletDB = new WalletDB({ network: "regtest", @@ -36,11 +25,6 @@ var testHelpers = { return walletDB; }, - closeWalletDB: async (walletDB) => { - await walletDB.disconnect(); - await walletDB.close(); - }, - createWallet: async (walletDB, id) => { var options = { id, From 85d6ea003bc38455097edba3acaf64834ed18b62 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 18:47:18 +0100 Subject: [PATCH 197/540] Fix typo --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 9bf3dba..aba6efd 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -96,7 +96,7 @@ describe("SPVNode", () => { afterEach("disconnect and close walletDBs", async () => { await spvWalletDB.disconnect(); - await minerWalletDB.disconnet(); + await minerWalletDB.disconnect(); await spvWalletDB.close(); await minerWalletDB.close(); From 805717a689d2fdd75f2ca596dcdf2c4597aae844 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 20:46:11 +0100 Subject: [PATCH 198/540] Add console.log()s --- test/spv_node.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index aba6efd..904bf70 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -84,6 +84,11 @@ describe("SPVNode", () => { // })().catch((err) => { // console.error(err.stack); // }); + console.log(minerAddr); + console.log("Before connecting"); + console.log(miner.pool.peers); + console.log(spvNode.pool.peers); + console.log("\n"); }); afterEach("disconnect nodes", async () => { @@ -225,7 +230,6 @@ describe("SPVNode", () => { let mtx = null; if (node.spv) { - console.log(node.pool.peers); mtx = await node.trust.ccreateTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), From 6a1a28b602695e49f87c9f95fa22094189ae4509 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 20:47:15 +0100 Subject: [PATCH 199/540] Uncomment RPC peer connection --- test/spv_node.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 904bf70..0a6e5be 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -76,19 +76,20 @@ describe("SPVNode", () => { // spvNode.pool.peer.connect(minerAddr); // spvNode.pool.peer.tryOpen(); -// const minerAddr = miner.http.config.host + ":" + miner.http.config.port; -// -// (async () => { -// const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); -// console.log(result); -// })().catch((err) => { -// console.error(err.stack); -// }); + const minerAddr = miner.http.config.host + ":" + miner.http.config.port; console.log(minerAddr); console.log("Before connecting"); console.log(miner.pool.peers); console.log(spvNode.pool.peers); console.log("\n"); + + (async () => { + const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); + console.log(result); + })().catch((err) => { + console.error(err.stack); + }); + await testHelpers.delay(1000); }); afterEach("disconnect nodes", async () => { From 9299f82a397de6f4f9378a4ee4b8782b51c4b7d5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 20:47:31 +0100 Subject: [PATCH 200/540] Add more console.log()s --- test/spv_node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 0a6e5be..f10a9e6 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -90,6 +90,10 @@ describe("SPVNode", () => { console.error(err.stack); }); await testHelpers.delay(1000); + console.log("After connecting"); + console.log(miner.pool.peers); + console.log(spvNode.pool.peers); + console.log("\n"); }); afterEach("disconnect nodes", async () => { From c720cdb62bc40b2b54f68d8ce1b4a14c1a75f517 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 10 Oct 2017 20:48:03 +0100 Subject: [PATCH 201/540] Create wallet through walletDB --- test/spv_node.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index f10a9e6..3529c47 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -118,8 +118,7 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvSender = await WalletDB.create({id: "spvSender", passphrase: "secret", witness: false, type: - "pubkeyhash"});//testHelpers.createWallet(spvWalletDB, "spvSender"); TODO: kill redundant walletDBs + var spvSender = await testHelpers.createWallet(spvWalletDB, "spvSender"); var spvReceiver = await testHelpers.createWallet(spvWalletDB, "spvReceiver"); var minerSender = await testHelpers.createWallet(minerWalletDB, "minerSender"); From a6773871f23ade0b753c34499f5d630a420fece6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 15:02:17 +0100 Subject: [PATCH 202/540] Comment out entire connection beforeEach --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index d9250cc..731215b 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -70,7 +70,7 @@ describe("SPVNode", () => { minerWalletDB = await testHelpers.getWalletDB(miner); }); - beforeEach("add miner to spvNode as peer", async () => { +// beforeEach("add miner to spvNode as peer", async () => { // const minerAddr = bcoin.netaddress.fromHostname(miner.http.config.host + ":" + miner.http.config.port, "regtest"); // spvNode.pool.peer.connect(minerAddr); // spvNode.pool.peer.tryOpen(); @@ -83,7 +83,7 @@ describe("SPVNode", () => { // })().catch((err) => { // console.error(err.stack); // }); - }); +// }); afterEach("close walletDBs", async () => { await testHelpers.closeWalletDB(spvWalletDB); From 8f26291d2ef419071318bf7c7f46babfa2f6700e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 15:03:31 +0100 Subject: [PATCH 203/540] Add testnetCreateWallet() --- test/helpers.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index bc75d2d..fbb7421 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -52,6 +52,24 @@ var testHelpers = { return walletDB.create(options); }, + testnetCreateWallet: async (walletDB, id) => { + const addresses = { + "spvSender": "", + "spvReceiver": "", + "minerSender": "", + "minerReceiver": "" + } + var options = { + id, + passphrase: "secret", + witness: false, + type: "pubkeyhash", + master: addresses.id + }; + + return walletDB.create(options); + }, + mineBlock: async (node, rewardAddress) => { var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); await node.chain.add(block); From 83a92d5a83ecc93bc4525e92317c0307160e28a2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 15:03:58 +0100 Subject: [PATCH 204/540] Expand waitForTX() with specific tx --- test/helpers.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index fbb7421..0e7d9a2 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -173,16 +173,28 @@ class NodeWatcher { }); } - async waitForTX(initialCount) { + async waitForTX(initialCount, tx) { if (initialCount === undefined) initialCount = this.txCount; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount) resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); + if (tx === undefined) { + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } + else { + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount && this.node.pool.hasTX(tx)) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } } } From 8f1f008d49fc47f44bf8d6495ae8bcf44a996eb1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 15:04:49 +0100 Subject: [PATCH 205/540] Add testnet_spv_node.js that uses testnet --- test/testnet_spv_node.js | 305 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 test/testnet_spv_node.js diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js new file mode 100644 index 0000000..144a571 --- /dev/null +++ b/test/testnet_spv_node.js @@ -0,0 +1,305 @@ +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var WalletDB = bcoin.wallet.WalletDB; +var testHelpers = require("./helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +var assert = require("assert"); +var fixtures = require("./fixtures"); +require("should-sinon"); + +const COIN = consensus.COIN; + +describe("SPVNode", () => { + var spvNode = null; + var miner = null; + var spvWalletDB = null; + var minerWalletDB = null; + var spvWatcher = null; + var minerWatcher = null; + + before("set up addTX() spy", function() { + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); + }); + + after("reset addTX() spy", function() { + Trust.TrustIsRisk.prototype.addTX.restore(); + }); + + beforeEach("get nodes", () => { + miner = new Trust.FullNode({ + network: "testnet", passphrase: "secret" + }); + + spvNode = new Trust.SPVNode({ + network: "testnet", passphrase: "secret", port: 48333 + }); + }); + + beforeEach("open nodes", async () => { + await miner.open(); + await spvNode.open(); + }); + + beforeEach("connect nodes", async () => { + await miner.connect(); + await spvNode.connect(); + }); + + beforeEach("start syncing nodes", () => { + miner.startSync(); + spvNode.startSync(); + }); + + beforeEach("get watchers", () => { + minerWatcher = new testHelpers.NodeWatcher(miner); + spvWatcher = new testHelpers.NodeWatcher(spvNode); + }); + + beforeEach("get walletDBs", async () => { + spvWalletDB = await testHelpers.getWalletDB(spvNode); + minerWalletDB = await testHelpers.getWalletDB(miner); + }); + +// beforeEach("add miner to spvNode as peer", async () => { +// const minerAddr = bcoin.netaddress.fromHostname(miner.http.config.host + ":" + miner.http.config.port, "regtest"); +// spvNode.pool.peer.connect(minerAddr); +// spvNode.pool.peer.tryOpen(); + +// const minerAddr = miner.http.config.host + ":" + miner.http.config.port; +// +// (async () => { +// const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); +// console.log(result); +// })().catch((err) => { +// console.error(err.stack); +// }); +// }); + + afterEach("close walletDBs", async () => { + await testHelpers.closeWalletDB(spvWalletDB); + await testHelpers.closeWalletDB(minerWalletDB); + }); + + afterEach("close nodes", async () => { + await testHelpers.closeNode(spvNode); + await testHelpers.closeNode(miner); + }); + + it("should call trust.addTX() on every transaction", async function() { + var spvSender = await testHelpers.testnetCreateWallet(spvWalletDB, "spvSender"); + var spvReceiver = await testHelpers.testnetCreateWallet(spvWalletDB, "spvReceiver"); + + var minerSender = await testHelpers.testnetCreateWallet(minerWalletDB, "minerSender"); + var minerReceiver = await testHelpers.testnetCreateWallet(minerWalletDB, "minerReceiver"); + + await testHelpers.delay(100); + + var minerTX = await minerSender.send({ + outputs: [{ + value: 10 * COIN, + address: minerReceiver.getAddress("base58") + }] + }); + await minerWatcher.waitForTX(undefined, minerTX); + + miner.trust.addTX.should.be.calledOnce(); + }); + + describe("with the nobodyLikesFrank.json example", () => { + var addresses, rings = {}; + + beforeEach("apply graph transactions", async () => { + addresses = {}; + + for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { + addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); + } + + // Alice mines three blocks, each rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var blockCount = 3; + var coinbaseHashes = []; + for(let i = 0; i < blockCount; i++) { + var block = await testHelpers.mineBlock(miner, addresses.alice); + coinbaseHashes.push(block.txs[0].hash()); + await testHelpers.delay(500); + } + + // Alice sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + var outputs = fixtures.names.map((name) => { + return testHelpers.getP2PKHOutput( + Address.fromHash(bcoin.crypto.hash160(fixtures.keyRings[name].getPublicKey())) + .toBase58(), + sendAmount * consensus.COIN); + }); + + // We have to use a change output, because transactions with too large a fee are + // considered invalid. + var fee = 0.01; + var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + fixtures.keyRings.alice.getPublicKey())), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { + return miner.getCoin(hash.toString("hex"), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(fixtures.keyRings.alice); + assert(signedCount === blockCount); + assert(await mtx.verify()); + + var tx = mtx.toTX(); + miner.sendTX(tx); + await minerWatcher.waitForTX(); + + prevout = {}; + fixtures.names.forEach((name) => { + prevout[name] = { + hash: tx.hash().toString("hex"), + index: fixtures.names.indexOf(name) + }; + }); + + // Alice mines another block + await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( + fixtures.keyRings.alice.getPublicKey())); + await testHelpers.delay(500); + + var graph = require("./graphs/nobodyLikesFrank.json"); + for (var origin in graph) { + var neighbours = graph[origin]; + for (var dest in neighbours) { + var value = neighbours[dest]; + if (!value || value < 1) continue; + + let node = null; + let watcher = null; + if (origin === "charlie" || origin == "dave") { + node = spvNode; + watcher = spvWatcher; + } + else { + node = miner; + watcher = minerWatcher; + } + + let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); + + let mtx = null; + if (node.spv) { + console.log(node.pool.peers); + mtx = await node.trust.ccreateTrustIncreasingMTX( + fixtures.keyRings[origin].getPrivateKey(), + fixtures.keyRings[dest].getPublicKey(), + outpoint, + value * consensus.COIN, + node); + } + else { // if full node + mtx = await node.trust.createTrustIncreasingMTX( + fixtures.keyRings[origin].getPrivateKey(), + fixtures.keyRings[dest].getPublicKey(), + outpoint, + value * consensus.COIN); + } + + assert(await mtx.verify()); + + let tx = mtx.toTX(); + node.sendTX(tx); + await watcher.waitForTX(); + + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; + } + } + + // Alice mines yet another block + await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( + fixtures.keyRings.alice.getPublicKey())); + await testHelpers.delay(500); + }); + + it("lets the miner compute trusts correctly", () => { + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + should(miner.trust.getIndirectTrust(alice, alice)).equal(Infinity); + should(miner.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); + should(miner.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); + should(miner.trust.getIndirectTrust(alice, frank)).equal(0); + should(miner.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + + should(miner.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); + should(miner.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); + should(miner.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); + should(miner.trust.getIndirectTrust(george, eve)).equal(0); + }); + + it("lets the SPV node compute trusts correctly", () => { + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + should(spvNode.trust.getIndirectTrust(alice, alice)).equal(Infinity); + should(spvNode.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); + should(spvNode.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); + should(spvNode.trust.getIndirectTrust(alice, frank)).equal(0); + should(spvNode.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + + should(spvNode.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); + should(spvNode.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); + should(spvNode.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); + should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); + }); + + it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { + var mtxs = miner.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), + fixtures.keyRings.bob.getPublicKey(), 3 * COIN); + mtxs.length.should.equal(1); + var mtx = mtxs[0]; + + should(await mtx.verify()); + miner.sendTX(mtx.toTX()); + + await testHelpers.delay(750); + should(miner.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + should(spvNode.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + + mtxs = spvNode.trust.createTrustDecreasingMTXs(fixtures.keyRings.dave.getPrivateKey(), + fixtures.keyRings.eve.getPublicKey(), 2 * COIN); + mtxs.length.should.equal(1); + mtx = mtxs[0]; + + should(await mtx.verify()); + spvNode.sendTX(mtx.toTX()); + + await testHelpers.delay(750); + should(miner.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); + should(spvNode.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); + }); + }); + + describe("with the topcoder.json example", () => { + //TODO: Write tests here. + }); +}); From 0d6215b9f309a9249c0db3af471519e55b1e9f2c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:41:40 +0100 Subject: [PATCH 206/540] Hard code private keys from Electrum --- test/helpers.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 1783032..b34c89a 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -37,11 +37,11 @@ var testHelpers = { }, testnetCreateWallet: async (walletDB, id) => { - const addresses = { - "spvSender": "", - "spvReceiver": "", - "minerSender": "", - "minerReceiver": "" + const keys = { + "spvSender": "cQzGHhucP26iPJf4fFSpLBXBN7V99mx7hBXDXm3FfQAEz9UKiDHT", + "spvReceiver": "cSapdQj9U6XwhePBjv3YeQrctodr2imWm2dV1u83e1SWdBFUuVo1", + "minerSender": "cVGmuxkPKwwnMqEw69t2sjr4d7j3XJRF7LbC7yeGwrv9qarxMTLc", // this has the faucet coins + "minerReceiver": "cMjHoh7LRspQSVzJ6wps5XSGvn7jdidj2QhCRXDmaW48Pm9SGqCN" } var options = { id, From 7514ca81cc705aeefbd72553b69ecb7920a24efa Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:42:13 +0100 Subject: [PATCH 207/540] Rename "addresses" to "keys" --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index b34c89a..1e1c129 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -48,7 +48,7 @@ var testHelpers = { passphrase: "secret", witness: false, type: "pubkeyhash", - master: addresses.id + master: keys.id }; return walletDB.create(options); From d7ffd9c90f6fac82e24e655330f055dbb87a335f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:43:12 +0100 Subject: [PATCH 208/540] Add fixtures for testnet --- test/testnetFixtures.js | 23 +++++++++++++++++++++++ test/testnet_spv_node.js | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/testnetFixtures.js diff --git a/test/testnetFixtures.js b/test/testnetFixtures.js new file mode 100644 index 0000000..e840d33 --- /dev/null +++ b/test/testnetFixtures.js @@ -0,0 +1,23 @@ +var bcoin = require("bcoin"); +var KeyRing = bcoin.primitives.KeyRing; + +var privateKeys = { + "alice": "cSxTT76c6Dr9LBqqJUgz5zhvE6TCNdSkM3vVmDnTue99JitVPAa6", + "bob": "cQxfCPseKaNq4hNbcgX53tfk7Y4hYTJNP176eTo1FRACdiFPTJQk", + "charlie": "cSi94uAg7wk8JiwkdWF48uz2rea1zBheRwMoH7z8SLk3tuuysqJg", + "dave": "cNFdijFuW73DyqpayUjo6cGQNvtZzcNBYZr7b84Njkg6GPFYAmGr", + "eve": "cQPKx8fUnn7qh9vnWzqurQDAhigy22AiWq8EBGGcJfdG75j1i6mW", + "frank": "cVejVCD18z8LhibFCxBTz7xdSQ5fuogYR3W4igoBP3BUj26V9yQJ", + "george": "cPno2fuQTfLh7MRTJiPDvyo8Y1XmEJ2JtUo4zwocpxTc22LDSiBi" +}; + +var keyRings = {}; +for (let name in privateKeys) { + let key = privateKeys[name]; + keyRings[name] = KeyRing.fromPrivate(Buffer.from(key, "ascii")); +} + +module.exports = { + keyRings, + names: Object.keys(keyRings) +}; diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 144a571..6718f6e 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -15,6 +15,7 @@ var sinon = require("sinon"); var should = require("should"); var assert = require("assert"); var fixtures = require("./fixtures"); +var testnetFixtures = require("./testnetFixtures"); require("should-sinon"); const COIN = consensus.COIN; @@ -121,7 +122,7 @@ describe("SPVNode", () => { beforeEach("apply graph transactions", async () => { addresses = {}; - for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { + for (var [name, keyRing] of Object.entries(testnetFixtures.keyRings)) { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); } From 262e7d44a064d2c3de376a5462461e7b4ded8ab7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:44:00 +0100 Subject: [PATCH 209/540] Reduce COIN to a small value Since real coins are used and not mined, it is easier to save some --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 6718f6e..e926381 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -18,7 +18,7 @@ var fixtures = require("./fixtures"); var testnetFixtures = require("./testnetFixtures"); require("should-sinon"); -const COIN = consensus.COIN; +const COIN = 10000; describe("SPVNode", () => { var spvNode = null; From 81462749dd92b99a0709bb3292071df02d8e2bc4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:45:24 +0100 Subject: [PATCH 210/540] Add a full circle of txs between nodes --- test/testnet_spv_node.js | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index e926381..76afcdc 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -105,15 +105,45 @@ describe("SPVNode", () => { await testHelpers.delay(100); - var minerTX = await minerSender.send({ + var miner2TX = await minerSender.send({ outputs: [{ value: 10 * COIN, address: minerReceiver.getAddress("base58") }] }); - await minerWatcher.waitForTX(undefined, minerTX); + await minerWatcher.waitForTX(undefined, miner2TX); miner.trust.addTX.should.be.calledOnce(); + + var minerSpvTX = await minerSender.send({ + outputs: [{ + value: 10 * COIN, + address: spvSender.getAddress("base58") + }] + }); + await spvWatcher.waitForTX(undefined, minerSpvTX); + + miner.trust.addTX.should.be.calledTwice(); + + var spv2TX = await spvSender.send({ + outputs: [{ + value : 5 * COIN, + address: spvReceiver.getAddres("base58") + }] + }); + await spvWatcher.waitForTX(undefined, spv2TX); + + spv.trust.addTX.should.be.calledOnce(); // @dionyziz: or maybe Thrice()? + + var spvMinerTX = await spvReceiver.send({ + outputs: [{ + value: 2 * COIN, + address: minerSender.getAddress("base58") + }] + }); + await minerWatcher.waitForTX(undefined, spvMinerTX); + + spv.trust.addTX.should.be.calledTwice(); }); describe("with the nobodyLikesFrank.json example", () => { From c3be61c36427f546763cb0711517c411a8629782 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:45:59 +0100 Subject: [PATCH 211/540] Remove Alice mining --- test/testnet_spv_node.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 76afcdc..c3f505b 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -156,16 +156,6 @@ describe("SPVNode", () => { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); } - // Alice mines three blocks, each rewards her with 50 spendable BTC - consensus.COINBASE_MATURITY = 0; - var blockCount = 3; - var coinbaseHashes = []; - for(let i = 0; i < blockCount; i++) { - var block = await testHelpers.mineBlock(miner, addresses.alice); - coinbaseHashes.push(block.txs[0].hash()); - await testHelpers.delay(500); - } - // Alice sends 20 BTC to everyone (including herself) via P2PKH var sendAmount = 20; var outputs = fixtures.names.map((name) => { From 56f460bc7b48d995ed81a3fa2bca4abcbd0674a4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:46:23 +0100 Subject: [PATCH 212/540] Update comment for new COIN value --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index c3f505b..8dfbdca 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -156,7 +156,7 @@ describe("SPVNode", () => { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); } - // Alice sends 20 BTC to everyone (including herself) via P2PKH + // Alice sends 20*10e-3 BTC to everyone (including herself) via P2PKH var sendAmount = 20; var outputs = fixtures.names.map((name) => { return testHelpers.getP2PKHOutput( From 8a9c972e8c4844364c3cfaf8d6da18dfd090ebfd Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 13 Oct 2017 21:47:33 +0100 Subject: [PATCH 213/540] Mark end of progress with TODO --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 8dfbdca..d2307b4 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -176,7 +176,7 @@ describe("SPVNode", () => { value: changeAmount * consensus.COIN })); } - +// TODO: continue from here // Use the coinbase coins as inputs var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { return miner.getCoin(hash.toString("hex"), 0); From 296c5e1669ccc415bdc856b02a13aff95a5fabad Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 14 Oct 2017 12:07:20 +0100 Subject: [PATCH 214/540] Use underscore instead of camel case in file names --- test/{testnetFixtures.js => testnet_fixtures.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{testnetFixtures.js => testnet_fixtures.js} (100%) diff --git a/test/testnetFixtures.js b/test/testnet_fixtures.js similarity index 100% rename from test/testnetFixtures.js rename to test/testnet_fixtures.js From fd1ed19aa11fa51ac536cac6a38c5c45c420cb8f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 14 Oct 2017 13:03:19 +0100 Subject: [PATCH 215/540] Replace private key with change key --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index 1e1c129..06fc04b 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -40,7 +40,7 @@ var testHelpers = { const keys = { "spvSender": "cQzGHhucP26iPJf4fFSpLBXBN7V99mx7hBXDXm3FfQAEz9UKiDHT", "spvReceiver": "cSapdQj9U6XwhePBjv3YeQrctodr2imWm2dV1u83e1SWdBFUuVo1", - "minerSender": "cVGmuxkPKwwnMqEw69t2sjr4d7j3XJRF7LbC7yeGwrv9qarxMTLc", // this has the faucet coins + "minerSender": "cUw1SoP2DBd6RufEs2bV7nHwoUFi382h5SpaLtBy9zXrjGqs9S3U", // this has the faucet coins "minerReceiver": "cMjHoh7LRspQSVzJ6wps5XSGvn7jdidj2QhCRXDmaW48Pm9SGqCN" } var options = { From 0c0bd7b94821877d7785fd3bd1e29103474519d6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 14 Oct 2017 13:04:38 +0100 Subject: [PATCH 216/540] Use only testnet fixtures --- test/testnet_spv_node.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index d2307b4..74f3072 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -14,8 +14,7 @@ var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); var should = require("should"); var assert = require("assert"); -var fixtures = require("./fixtures"); -var testnetFixtures = require("./testnetFixtures"); +var fixtures = require("./testnet_fixtures"); require("should-sinon"); const COIN = 10000; @@ -152,7 +151,7 @@ describe("SPVNode", () => { beforeEach("apply graph transactions", async () => { addresses = {}; - for (var [name, keyRing] of Object.entries(testnetFixtures.keyRings)) { + for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); } From 11516e5f83eda8c4f298b13a8f80d4106e624607 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 14 Oct 2017 13:05:00 +0100 Subject: [PATCH 217/540] Reduce COIN value --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 74f3072..1280f38 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -17,7 +17,7 @@ var assert = require("assert"); var fixtures = require("./testnet_fixtures"); require("should-sinon"); -const COIN = 10000; +const COIN = 1000; describe("SPVNode", () => { var spvNode = null; From 3f68ef51ce1b4b29e30ba01bf16e3151eb16d12a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 14 Oct 2017 13:06:00 +0100 Subject: [PATCH 218/540] Move TODO comment --- test/testnet_spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 1280f38..1fff73b 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -167,7 +167,7 @@ describe("SPVNode", () => { // We have to use a change output, because transactions with too large a fee are // considered invalid. var fee = 0.01; - var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; + var changeAmount = fixtures.keyRings[alice].getAddress() /*TODO: get balance from keyring*/ - sendAmount * fixtures.names.length - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ script: Script.fromPubkeyhash(bcoin.crypto.hash160( @@ -175,7 +175,7 @@ describe("SPVNode", () => { value: changeAmount * consensus.COIN })); } -// TODO: continue from here + // Use the coinbase coins as inputs var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { return miner.getCoin(hash.toString("hex"), 0); From fd79d105ddebe25a2d4198dbf908e92af8d0757d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:30:47 +0100 Subject: [PATCH 219/540] Pass hashes instead of TXs --- test/testnet_spv_node.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 1fff73b..e976c5d 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -110,7 +110,7 @@ describe("SPVNode", () => { address: minerReceiver.getAddress("base58") }] }); - await minerWatcher.waitForTX(undefined, miner2TX); + await minerWatcher.waitForTX(undefined, miner2TX.rhash()); miner.trust.addTX.should.be.calledOnce(); @@ -120,7 +120,7 @@ describe("SPVNode", () => { address: spvSender.getAddress("base58") }] }); - await spvWatcher.waitForTX(undefined, minerSpvTX); + await spvWatcher.waitForTX(undefined, minerSpvTX.rhash()); miner.trust.addTX.should.be.calledTwice(); @@ -130,7 +130,7 @@ describe("SPVNode", () => { address: spvReceiver.getAddres("base58") }] }); - await spvWatcher.waitForTX(undefined, spv2TX); + await spvWatcher.waitForTX(undefined, spv2TX.rhash()); spv.trust.addTX.should.be.calledOnce(); // @dionyziz: or maybe Thrice()? @@ -140,7 +140,7 @@ describe("SPVNode", () => { address: minerSender.getAddress("base58") }] }); - await minerWatcher.waitForTX(undefined, spvMinerTX); + await minerWatcher.waitForTX(undefined, spvMinerTX.rhash()); spv.trust.addTX.should.be.calledTwice(); }); From e5aa9cc06ba85a60ad9e5988b8274af2c9147084 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:31:39 +0100 Subject: [PATCH 220/540] Add wallets for players --- test/testnet_spv_node.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index e976c5d..967c41a 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -146,13 +146,22 @@ describe("SPVNode", () => { }); describe("with the nobodyLikesFrank.json example", () => { - var addresses, rings = {}; + var addresses, rings = {}, wallets; beforeEach("apply graph transactions", async () => { addresses = {}; + wallets = {}; for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); + // Create wallet for the keyrings + if (name === "charlie" || name === "dave") { + wallets[name] = await testHelpers.testnetCreateWallet(spvWallet, name + "Wallet"); + }; + else { + wallets[name] = await testHelpers.testnetCreateWallet(minerWallet, name + "Wallet"); + } + wallets[name].importKey(null, keyRing, "secret"); } // Alice sends 20*10e-3 BTC to everyone (including herself) via P2PKH From bf4f9957c07c585bba59bad61a015745cd7ff2ab Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:32:23 +0100 Subject: [PATCH 221/540] Apply graph transactions only once --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 967c41a..3930edc 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -148,7 +148,7 @@ describe("SPVNode", () => { describe("with the nobodyLikesFrank.json example", () => { var addresses, rings = {}, wallets; - beforeEach("apply graph transactions", async () => { + before("apply graph transactions", async () => { addresses = {}; wallets = {}; From e5ce7bcdb6af1d70b58f539d0a4bd31a929d451c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:34:26 +0100 Subject: [PATCH 222/540] Replace mining logic with faucet coins --- test/testnet_spv_node.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 3930edc..541858e 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -164,6 +164,10 @@ describe("SPVNode", () => { wallets[name].importKey(null, keyRing, "secret"); } + // Wait for tx where Alice gets coins + txidAliceIsPaid = "888d862cccd0152e6c8ea202480d648dc99c07309a6360dd178c09112b1a9585"; + await minerWatcher.waitForTX(undefined, txidAliceIsPaid); + // Alice sends 20*10e-3 BTC to everyone (including herself) via P2PKH var sendAmount = 20; var outputs = fixtures.names.map((name) => { @@ -176,7 +180,8 @@ describe("SPVNode", () => { // We have to use a change output, because transactions with too large a fee are // considered invalid. var fee = 0.01; - var changeAmount = fixtures.keyRings[alice].getAddress() /*TODO: get balance from keyring*/ - sendAmount * fixtures.names.length - fee; + var aliceBalance = await wallets[alice].getBalance(); + var changeAmount = aliceBalance - sendAmount * fixtures.names.length - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ script: Script.fromPubkeyhash(bcoin.crypto.hash160( @@ -185,15 +190,12 @@ describe("SPVNode", () => { })); } - // Use the coinbase coins as inputs - var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { - return miner.getCoin(hash.toString("hex"), 0); - })); + // Use Alice's coins as input + var initialCoin = await wallets[alice].getCoin(txidAliceIsPaid, 0); var mtx = new MTX({outputs}); - coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + mtx.addCoin(initialCoin); var signedCount = mtx.sign(fixtures.keyRings.alice); - assert(signedCount === blockCount); assert(await mtx.verify()); var tx = mtx.toTX(); From aaa30a31e40de2639e9da450316feb93c348867f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:34:45 +0100 Subject: [PATCH 223/540] Use locally defined COIN --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 541858e..230c32f 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -186,7 +186,7 @@ describe("SPVNode", () => { outputs.push(new Output({ script: Script.fromPubkeyhash(bcoin.crypto.hash160( fixtures.keyRings.alice.getPublicKey())), - value: changeAmount * consensus.COIN + value: changeAmount * COIN })); } From 62219dec29d2edce7236bb3babdc11b578c4fe50 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:35:01 +0100 Subject: [PATCH 224/540] Wait for specific tx --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 230c32f..55bdcbb 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -200,7 +200,7 @@ describe("SPVNode", () => { var tx = mtx.toTX(); miner.sendTX(tx); - await minerWatcher.waitForTX(); + await minerWatcher.waitForTX(undefined, tx); prevout = {}; fixtures.names.forEach((name) => { From 8cb3b77ab562993467478f1172c2c476077fd89c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:54:52 +0100 Subject: [PATCH 225/540] Remove block activity --- test/testnet_spv_node.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 55bdcbb..da680c7 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -210,11 +210,6 @@ describe("SPVNode", () => { }; }); - // Alice mines another block - await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey())); - await testHelpers.delay(500); - var graph = require("./graphs/nobodyLikesFrank.json"); for (var origin in graph) { var neighbours = graph[origin]; @@ -262,11 +257,6 @@ describe("SPVNode", () => { prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } } - - // Alice mines yet another block - await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey())); - await testHelpers.delay(500); }); it("lets the miner compute trusts correctly", () => { From 7a1fce92238fa24e4cd09e96e63f455a01489d00 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:55:21 +0100 Subject: [PATCH 226/540] Wait for specific txs --- test/testnet_spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index da680c7..dc2229f 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -200,7 +200,7 @@ describe("SPVNode", () => { var tx = mtx.toTX(); miner.sendTX(tx); - await minerWatcher.waitForTX(undefined, tx); + await minerWatcher.waitForTX(undefined, tx.rhash()); prevout = {}; fixtures.names.forEach((name) => { @@ -252,7 +252,7 @@ describe("SPVNode", () => { let tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(); + await watcher.waitForTX(undefined, tx.rhash()); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } From 9f0955248e02fe322bf9b3ba708098af062977ba Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:57:02 +0100 Subject: [PATCH 227/540] Remove full node logic from "ccreate[...]()" --- src/trust_is_risk.js | 58 +++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 0c5e76d..036f4ab 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -146,6 +146,7 @@ class TrustIsRisk { async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, node : (bcoin$FullNode | bcoin$SPVNode), fee : ?number) : Promise { + assert(node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this if (origin === dest) throw new Error("Can not increase self-trust."); @@ -163,49 +164,28 @@ class TrustIsRisk { var changeAmount = null; - if (node.spv) { - var txid = outpoint.txid(); - var watcher = new helpers.NodeWatcher(node); - var tx = null; - node.pool.watchAddress(txid); - helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) - await watcher.waitForTX(); + var txid = outpoint.txid(); + var watcher = new helpers.NodeWatcher(node); + var tx = null; + node.pool.watchAddress(txid); + helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) + await watcher.waitForTX(); - // var coin = await this.node.getCoin(outpoint.hash, outpoint.index); - if (!tx) throw new Error("Could not find tx"); - - - changeAmount = tx.getOutputValue() - trustAmount - fee; // TODO: find how to get the value another way - assert(changeAmount >= 0); - if (changeAmount) { - mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), - value: changeAmount - })); - } - - // mtx.addCoin(coin); // TODO: use addInput() instead - } + // var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + if (!tx) throw new Error("Could not find tx"); - else { // it is a full node - var coin = await this.node.getCoin(outpoint.hash, outpoint.index); - if (!coin) throw new Error("Could not find coin"); - - - changeAmount = coin.value - trustAmount - fee; // TODO: find how to get the value another way - assert(changeAmount >= 0); - if (changeAmount) { - mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), - value: changeAmount - })); - } - - mtx.addCoin(coin); // TODO: use addInput() instead - var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); - assert(success); + + changeAmount = tx.getOutputValue() - trustAmount - fee; // TODO: find how to get the value another way + assert(changeAmount >= 0); + if (changeAmount) { + mtx.addOutput(new Output({ + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), + value: changeAmount + })); } + // mtx.addCoin(coin); // TODO: use addInput() instead + var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); From 16e735a02ec9ce321941eff05fb86ba33721fdd9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 00:57:13 +0100 Subject: [PATCH 228/540] Move TODO comment --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index dc2229f..9add865 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -233,7 +233,7 @@ describe("SPVNode", () => { let mtx = null; if (node.spv) { console.log(node.pool.peers); - mtx = await node.trust.ccreateTrustIncreasingMTX( + mtx = await node.trust.ccreateTrustIncreasingMTX( // TODO: fix this fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, From e75b2f1c38f9d97a71a5d23694dc2b64c86627bf Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 21:33:30 +0100 Subject: [PATCH 229/540] Edit waitForTX() to wait for specific tx --- src/helpers.js | 11 ++++++----- test/helpers.js | 31 +++++++++++-------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/helpers.js b/src/helpers.js index 4d2a36c..3a71d0e 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -37,13 +37,14 @@ class NodeWatcher { }); } - async waitForTX(initialCount : ?number) : Promise { - var localInitialCount : number; - if (initialCount === undefined) localInitialCount = this.txCount; - else if (typeof initialCount === "number") localInitialCount = initialCount; + async waitForTX(txid : ?number) : Promise { + var initialCount : number = this.txCount; await new Promise((resolve, reject) => { var check = (() => { - if (this.txCount > localInitialCount) resolve(); + if (this.txCount > initialCount && + (tx === undefined || + this.node.pool.hasTX(txid))) + resolve(); else setTimeout(check, 100); }).bind(this); diff --git a/test/helpers.js b/test/helpers.js index 06fc04b..9a9ee4d 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -157,28 +157,19 @@ class NodeWatcher { }); } - async waitForTX(initialCount, tx) { - if (initialCount === undefined) initialCount = this.txCount; - if (tx === undefined) { + async waitForTX(txid) { + var initialCount = this.txCount; await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount) resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); - } - else { - await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount && this.node.pool.hasTX(tx)) resolve(); - else setTimeout(check, 100); - }).bind(this); + var check = (() => { + if (this.txCount > initialCount && + (tx === undefined || + this.node.pool.hasTX(txid))) + resolve(); + else setTimeout(check, 100); + }).bind(this); - check(); - }); - } + check(); + }); } } From 9ba06d2dbe2dfc33e2731de9070d607164610e43 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 23:42:07 +0100 Subject: [PATCH 230/540] Declare and define variables inline --- src/trust_is_risk.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 036f4ab..467990f 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -162,20 +162,18 @@ class TrustIsRisk { ] }); - var changeAmount = null; - var txid = outpoint.txid(); var watcher = new helpers.NodeWatcher(node); - var tx = null; node.pool.watchAddress(txid); helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) await watcher.waitForTX(); // var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + var tx = await node.chain.getTX(txid); if (!tx) throw new Error("Could not find tx"); - changeAmount = tx.getOutputValue() - trustAmount - fee; // TODO: find how to get the value another way + var changeAmount = tx.getOutputValue() - trustAmount - fee; assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ From 47b7a22382ebdfe18f088f8bbb0e44e664f1eed2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 23:43:07 +0100 Subject: [PATCH 231/540] Wait for specific tx --- src/trust_is_risk.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 467990f..90db927 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -165,8 +165,7 @@ class TrustIsRisk { var txid = outpoint.txid(); var watcher = new helpers.NodeWatcher(node); node.pool.watchAddress(txid); - helpers.delay(1000); // TODO: wait adaptively (like waitForTX() from testHelpers) - await watcher.waitForTX(); + await watcher.waitForTX(txid); // var coin = await this.node.getCoin(outpoint.hash, outpoint.index); var tx = await node.chain.getTX(txid); From ac137a283e1e868fd51a2cc9abfb654805b276e9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 23:45:08 +0100 Subject: [PATCH 232/540] Remove comments from createTrustIncreasingTX() --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 90db927..73bdd2f 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -124,7 +124,7 @@ class TrustIsRisk { ] }); - var changeAmount = coin.value - trustAmount - fee; // TODO: find how to get the value another way + var changeAmount = coin.value - trustAmount - fee; assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ @@ -133,7 +133,7 @@ class TrustIsRisk { })); } - mtx.addCoin(coin); // TODO: use addInput() instead + mtx.addCoin(coin); var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); assert(success); From 6bba93095be9d51f00815a6c2391e059c17aecf8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 15 Oct 2017 23:46:56 +0100 Subject: [PATCH 233/540] Replace coin with tx logic for spv TX creation --- src/trust_is_risk.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 73bdd2f..6127fa1 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -167,7 +167,6 @@ class TrustIsRisk { node.pool.watchAddress(txid); await watcher.waitForTX(txid); - // var coin = await this.node.getCoin(outpoint.hash, outpoint.index); var tx = await node.chain.getTX(txid); if (!tx) throw new Error("Could not find tx"); @@ -181,7 +180,10 @@ class TrustIsRisk { })); } - // mtx.addCoin(coin); // TODO: use addInput() instead + mtx.addInput({ + prevout: outpoint, + script: // TODO: Find script content + }); var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); From 1b48c50ca091414974a16dd2692fd24c4aa88da4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 16:26:42 +0100 Subject: [PATCH 234/540] Remove TODO comment --- flow-typed/npm/bcoin_vx.x.x.js | 1 - 1 file changed, 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 741c49c..2dca499 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -17,7 +17,6 @@ declare class bcoin$SPVNode { on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; - //TODO Check if changes/additions are needed } declare class bcoin$WalletDB {} From 5423c390a29f4c80ccebe340ad8703d71dab28eb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 16:29:46 +0100 Subject: [PATCH 235/540] Add input from outpoint --- src/trust_is_risk.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 6127fa1..4279e74 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -180,10 +180,7 @@ class TrustIsRisk { })); } - mtx.addInput({ - prevout: outpoint, - script: // TODO: Find script content - }); + mtx.addInput(Input.fromOutpoint(outpoint)) var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); From f36dffaac5383ac8ad8dfc8c9ffa773516d4175e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 17:26:11 +0100 Subject: [PATCH 236/540] Add missing semicolons and remove redundant --- src/trust_is_risk.js | 2 +- test/helpers.js | 2 +- test/testnet_spv_node.js | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 4279e74..c2ceeba 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -180,7 +180,7 @@ class TrustIsRisk { })); } - mtx.addInput(Input.fromOutpoint(outpoint)) + mtx.addInput(Input.fromOutpoint(outpoint)); var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); diff --git a/test/helpers.js b/test/helpers.js index 9a9ee4d..1d32c64 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -42,7 +42,7 @@ var testHelpers = { "spvReceiver": "cSapdQj9U6XwhePBjv3YeQrctodr2imWm2dV1u83e1SWdBFUuVo1", "minerSender": "cUw1SoP2DBd6RufEs2bV7nHwoUFi382h5SpaLtBy9zXrjGqs9S3U", // this has the faucet coins "minerReceiver": "cMjHoh7LRspQSVzJ6wps5XSGvn7jdidj2QhCRXDmaW48Pm9SGqCN" - } + }; var options = { id, passphrase: "secret", diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 9add865..92536e7 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -157,8 +157,7 @@ describe("SPVNode", () => { // Create wallet for the keyrings if (name === "charlie" || name === "dave") { wallets[name] = await testHelpers.testnetCreateWallet(spvWallet, name + "Wallet"); - }; - else { + } else { wallets[name] = await testHelpers.testnetCreateWallet(minerWallet, name + "Wallet"); } wallets[name].importKey(null, keyRing, "secret"); From 2a2e094869ea22ca942b348250036babb7683863 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 17:26:34 +0100 Subject: [PATCH 237/540] Fix indentation --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index 1d32c64..4c1d101 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -159,7 +159,7 @@ class NodeWatcher { async waitForTX(txid) { var initialCount = this.txCount; - await new Promise((resolve, reject) => { + await new Promise((resolve, reject) => { var check = (() => { if (this.txCount > initialCount && (tx === undefined || From df80c356e8e4de21ef3bd98b88fa715df4afc507 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 17:27:20 +0100 Subject: [PATCH 238/540] Replace "tx" with "txid" --- src/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers.js b/src/helpers.js index 3a71d0e..655956b 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -42,7 +42,7 @@ class NodeWatcher { await new Promise((resolve, reject) => { var check = (() => { if (this.txCount > initialCount && - (tx === undefined || + (txid === undefined || this.node.pool.hasTX(txid))) resolve(); else setTimeout(check, 100); From 9aef78555e3c710c0ae35c728f0d6b8a5229bdc8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 17:27:58 +0100 Subject: [PATCH 239/540] Type tx hash correctly --- src/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers.js b/src/helpers.js index 655956b..4062aeb 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -37,7 +37,7 @@ class NodeWatcher { }); } - async waitForTX(txid : ?number) : Promise { + async waitForTX(txid : Hash) : Promise { var initialCount : number = this.txCount; await new Promise((resolve, reject) => { var check = (() => { From 7f322312751d74371273666450f3c1c64d49fbd3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 16 Oct 2017 17:28:30 +0100 Subject: [PATCH 240/540] Add missing types --- flow-typed/npm/bcoin_vx.x.x.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 2dca499..8c1df0f 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -5,6 +5,8 @@ type Network = any; declare class bcoin$FullNode { pool : bcoin$Pool; + spv : boolean; + chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; @@ -13,12 +15,18 @@ declare class bcoin$FullNode { declare class bcoin$SPVNode { pool : bcoin$Pool; + spv : boolean; + chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } +declare class bcoin$Chain { + getTX(hash : Hash) : bcoin$TX; +} + declare class bcoin$WalletDB {} declare class bcoin$Wallet { @@ -29,6 +37,7 @@ declare class bcoin$Pool { peers : bcoin$PeerList; watchAddress(address : Buffer) : void; + hasTX(hash : Hash) : boolean; } declare class bcoin$Peer {} From 36ff131a8be19a5fa6beeae15913d8544e433251 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 17:41:08 +0100 Subject: [PATCH 241/540] Correct the private keys They were in WIF, so stripping some bytes from the two ends was due --- test/testnet_fixtures.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/test/testnet_fixtures.js b/test/testnet_fixtures.js index e840d33..1450b6a 100644 --- a/test/testnet_fixtures.js +++ b/test/testnet_fixtures.js @@ -2,19 +2,26 @@ var bcoin = require("bcoin"); var KeyRing = bcoin.primitives.KeyRing; var privateKeys = { - "alice": "cSxTT76c6Dr9LBqqJUgz5zhvE6TCNdSkM3vVmDnTue99JitVPAa6", - "bob": "cQxfCPseKaNq4hNbcgX53tfk7Y4hYTJNP176eTo1FRACdiFPTJQk", - "charlie": "cSi94uAg7wk8JiwkdWF48uz2rea1zBheRwMoH7z8SLk3tuuysqJg", - "dave": "cNFdijFuW73DyqpayUjo6cGQNvtZzcNBYZr7b84Njkg6GPFYAmGr", - "eve": "cQPKx8fUnn7qh9vnWzqurQDAhigy22AiWq8EBGGcJfdG75j1i6mW", - "frank": "cVejVCD18z8LhibFCxBTz7xdSQ5fuogYR3W4igoBP3BUj26V9yQJ", - "george": "cPno2fuQTfLh7MRTJiPDvyo8Y1XmEJ2JtUo4zwocpxTc22LDSiBi" + // cSxTT76c6Dr9LBqqJUgz5zhvE6TCNdSkM3vVmDnTue99JitVPAa6 + "alice": "A060F1B3D346BE056F9E3A2F0972F98756AC1FBBC92490F6625858E8520637B5", + // cQxfCPseKaNq4hNbcgX53tfk7Y4hYTJNP176eTo1FRACdiFPTJQk + "bob": "64CEDE6032121BA1BCCF0F71FC21BE46270CEEDAF5B59B0E2735FAAE2D1E86A0", + // cSi94uAg7wk8JiwkdWF48uz2rea1zBheRwMoH7z8SLk3tuuysqJg + "charlie": "990375528C670D738933B83D10A6481DCB2E5F2E01B24EAAF8E8C6EC92C925DC", + // cNFdijFuW73DyqpayUjo6cGQNvtZzcNBYZr7b84Njkg6GPFYAmGr + "dave": "14073A5D848AEB0F4E507DB712B6333B7C468D3278AEC3E47EB8B697338EDBCC", + // cQPKx8fUnn7qh9vnWzqurQDAhigy22AiWq8EBGGcJfdG75j1i6mW + "eve": "53A93284BFD483539D12B6ACBEB023F8DA08C92C4AA70D8D529CDBFEA76DE7C1", + // cVejVCD18z8LhibFCxBTz7xdSQ5fuogYR3W4igoBP3BUj26V9yQJ + "frank": "F0C5F25C787B6482DA433792CEF1001661F4895C566EA76F30FE358C8B42897C", + // cPno2fuQTfLh7MRTJiPDvyo8Y1XmEJ2JtUo4zwocpxTc22LDSiBi + "george": "41E551884C6F847235F6CAAC14259E7DB3D275B6157D0FF00478AA52B47608D9", }; var keyRings = {}; for (let name in privateKeys) { let key = privateKeys[name]; - keyRings[name] = KeyRing.fromPrivate(Buffer.from(key, "ascii")); + keyRings[name] = KeyRing.fromPrivate(Buffer.from(key, "hex"), false, "testnet"); } module.exports = { From 1234924ed292bfe50f566fd0679ad667854444c7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 17:42:56 +0100 Subject: [PATCH 242/540] Rephrase "beforeEach" string for clarity --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 4796d81..ae7f89b 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -50,7 +50,7 @@ describe("SPVNode", () => { await spvNode.open(); }); - beforeEach("get connected walletDBs", async () => { + beforeEach("get walletDBs", async () => { minerWalletDB = await testHelpers.getWalletDB(miner); spvWalletDB = await testHelpers.getWalletDB(spvNode); }); From 4cf303210c377bb40253879a40f47b71e05e65e9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 17:46:15 +0100 Subject: [PATCH 243/540] Use "describe.only" for faster test --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 92536e7..8b69497 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -19,7 +19,7 @@ require("should-sinon"); const COIN = 1000; -describe("SPVNode", () => { +describe.only("SPVNode", () => { var spvNode = null; var miner = null; var spvWalletDB = null; From 60071da5cd8d7f41876f3478d607eaba3b7946c3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 17:51:40 +0100 Subject: [PATCH 244/540] Break "before/afterEach" in smaller pieces --- test/testnet_spv_node.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 8b69497..6739653 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -50,6 +50,11 @@ describe.only("SPVNode", () => { await spvNode.open(); }); + beforeEach("get walletDBs", async () => { + spvWalletDB = await testHelpers.getWalletDB(spvNode); + minerWalletDB = await testHelpers.getWalletDB(miner); + }); + beforeEach("connect nodes", async () => { await miner.connect(); await spvNode.connect(); @@ -65,9 +70,12 @@ describe.only("SPVNode", () => { spvWatcher = new testHelpers.NodeWatcher(spvNode); }); - beforeEach("get walletDBs", async () => { - spvWalletDB = await testHelpers.getWalletDB(spvNode); - minerWalletDB = await testHelpers.getWalletDB(miner); + afterEach("disconnect nodes", async () => { + spvNode.stopSync(); + miner.stopSync(); + + await spvNode.disconnect(); + await miner.disconnect(); }); // beforeEach("add miner to spvNode as peer", async () => { @@ -85,14 +93,17 @@ describe.only("SPVNode", () => { // }); // }); - afterEach("close walletDBs", async () => { - await testHelpers.closeWalletDB(spvWalletDB); - await testHelpers.closeWalletDB(minerWalletDB); + afterEach("disconnect and close walletDBs", async () => { + await spvWalletDB.disconnect(); + await minerWalletDB.disconnect(); + + await spvWalletDB.close(); + await minerWalletDB.close(); }); afterEach("close nodes", async () => { - await testHelpers.closeNode(spvNode); - await testHelpers.closeNode(miner); + await spvNode.close(); + await miner.close(); }); it("should call trust.addTX() on every transaction", async function() { From 4e0e134249c6a3f8198dc04e354a99635953c339 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:01:29 +0100 Subject: [PATCH 245/540] Replace "tx" with "txid" --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index 4c1d101..3d00720 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -162,7 +162,7 @@ class NodeWatcher { await new Promise((resolve, reject) => { var check = (() => { if (this.txCount > initialCount && - (tx === undefined || + (txid === undefined || this.node.pool.hasTX(txid))) resolve(); else setTimeout(check, 100); From 3510e23139bdb1521339047c2a4a5014e228e2f5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:02:56 +0100 Subject: [PATCH 246/540] Remove peer connect logic --- test/testnet_spv_node.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 6739653..fc3df3a 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -78,21 +78,6 @@ describe.only("SPVNode", () => { await miner.disconnect(); }); -// beforeEach("add miner to spvNode as peer", async () => { -// const minerAddr = bcoin.netaddress.fromHostname(miner.http.config.host + ":" + miner.http.config.port, "regtest"); -// spvNode.pool.peer.connect(minerAddr); -// spvNode.pool.peer.tryOpen(); - -// const minerAddr = miner.http.config.host + ":" + miner.http.config.port; -// -// (async () => { -// const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); -// console.log(result); -// })().catch((err) => { -// console.error(err.stack); -// }); -// }); - afterEach("disconnect and close walletDBs", async () => { await spvWalletDB.disconnect(); await minerWalletDB.disconnect(); From dc5a63c411dbd96f2b5172d615e8e6429583c4df Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:05:06 +0100 Subject: [PATCH 247/540] Fix whitespace --- test/testnet_spv_node.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index fc3df3a..1357fae 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -107,7 +107,7 @@ describe.only("SPVNode", () => { }] }); await minerWatcher.waitForTX(undefined, miner2TX.rhash()); - + miner.trust.addTX.should.be.calledOnce(); var minerSpvTX = await minerSender.send({ @@ -192,7 +192,7 @@ describe.only("SPVNode", () => { var signedCount = mtx.sign(fixtures.keyRings.alice); assert(await mtx.verify()); - + var tx = mtx.toTX(); miner.sendTX(tx); await minerWatcher.waitForTX(undefined, tx.rhash()); @@ -204,7 +204,7 @@ describe.only("SPVNode", () => { index: fixtures.names.indexOf(name) }; }); - + var graph = require("./graphs/nobodyLikesFrank.json"); for (var origin in graph) { var neighbours = graph[origin]; @@ -242,13 +242,13 @@ describe.only("SPVNode", () => { outpoint, value * consensus.COIN); } - + assert(await mtx.verify()); let tx = mtx.toTX(); node.sendTX(tx); await watcher.waitForTX(undefined, tx.rhash()); - + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } } From dac5fbf4ee96b0e1c8578ee58f697671df5aa4e2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:10:27 +0100 Subject: [PATCH 248/540] Start and stop nodes before and after graph tests --- test/testnet_spv_node.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 1357fae..3942b27 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -145,6 +145,21 @@ describe.only("SPVNode", () => { var addresses, rings = {}, wallets; before("apply graph transactions", async () => { + miner = new Trust.FullNode({ + network: "testnet", passphrase: "secret" + }); + spvNode = new Trust.SPVNode({ + network: "testnet", passphrase: "secret", port: 48333 + }); + + await miner.open(); + await spvNode.open(); + + await miner.connect(); + await spvNode.connect(); + + miner.startSync(); + spvNode.startSync(); addresses = {}; wallets = {}; @@ -254,6 +269,20 @@ describe.only("SPVNode", () => { } }); + after("close nodes and walletDBs", async () => { + spvNode.stopSync(); + miner.stopSync(); + + await spvNode.disconnect(); + await miner.disconnect(); + + await spvWalletDB.disconnect(); + await minerWalletDB.disconnect(); + + await spvNode.close(); + await miner.close(); + }); + it("lets the miner compute trusts correctly", () => { for (name in addresses) { // Add addresses to scope eval(`var ${name} = "${addresses[name]}";`); From b30d616abcf0f8d9377b8cb1ac699e789a3873df Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:13:21 +0100 Subject: [PATCH 249/540] Start and stop wallets around graph tests --- test/testnet_spv_node.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 3942b27..2b373c9 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -155,6 +155,9 @@ describe.only("SPVNode", () => { await miner.open(); await spvNode.open(); + spvWalletDB = await testHelpers.getWalletDB(spvNode); + minerWalletDB = await testHelpers.getWalletDB(miner); + await miner.connect(); await spvNode.connect(); @@ -279,6 +282,9 @@ describe.only("SPVNode", () => { await spvWalletDB.disconnect(); await minerWalletDB.disconnect(); + await spvWalletDB.close(); + await minerWalletDB.close(); + await spvNode.close(); await miner.close(); }); From 1d56bd5df86672cf1703a896f25f54264f8f1b0e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:13:53 +0100 Subject: [PATCH 250/540] Start nodeWatchers before graph tests --- test/testnet_spv_node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 2b373c9..5e11364 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -163,6 +163,10 @@ describe.only("SPVNode", () => { miner.startSync(); spvNode.startSync(); + + minerWatcher = new testHelpers.NodeWatcher(miner); + spvWatcher = new testHelpers.NodeWatcher(spvNode); + addresses = {}; wallets = {}; From e8a9b1b28766d1fa1786efe44a6a6b7fc6b391d8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:17:01 +0100 Subject: [PATCH 251/540] Fix typo to use walletDBs instead of wallets --- test/testnet_spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 5e11364..7a555f1 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -174,9 +174,9 @@ describe.only("SPVNode", () => { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); // Create wallet for the keyrings if (name === "charlie" || name === "dave") { - wallets[name] = await testHelpers.testnetCreateWallet(spvWallet, name + "Wallet"); + wallets[name] = await testHelpers.testnetCreateWallet(spvWalletDB, name + "Wallet"); } else { - wallets[name] = await testHelpers.testnetCreateWallet(minerWallet, name + "Wallet"); + wallets[name] = await testHelpers.testnetCreateWallet(minerWalletDB, name + "Wallet"); } wallets[name].importKey(null, keyRing, "secret"); } From 9d7eacff0014e7de4eddc76821ea6df23abe7734 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:17:47 +0100 Subject: [PATCH 252/540] Use string "alice" instead of plain `alice` --- test/testnet_spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index 7a555f1..e8e5ebb 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -197,7 +197,7 @@ describe.only("SPVNode", () => { // We have to use a change output, because transactions with too large a fee are // considered invalid. var fee = 0.01; - var aliceBalance = await wallets[alice].getBalance(); + var aliceBalance = await wallets["alice"].getBalance(); var changeAmount = aliceBalance - sendAmount * fixtures.names.length - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ @@ -208,7 +208,7 @@ describe.only("SPVNode", () => { } // Use Alice's coins as input - var initialCoin = await wallets[alice].getCoin(txidAliceIsPaid, 0); + var initialCoin = await wallets["alice"].getCoin(txidAliceIsPaid, 0); var mtx = new MTX({outputs}); mtx.addCoin(initialCoin); From f18b72e8b2d8b89a7ccb8be9c8c341092c039ebf Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 18:18:02 +0100 Subject: [PATCH 253/540] Remove fixed TODO comment --- test/testnet_spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index e8e5ebb..a915db2 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -250,7 +250,7 @@ describe.only("SPVNode", () => { let mtx = null; if (node.spv) { console.log(node.pool.peers); - mtx = await node.trust.ccreateTrustIncreasingMTX( // TODO: fix this + mtx = await node.trust.ccreateTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, From db051aa5b9a15fb5a5caee0535da62988db7ca99 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:03:10 +0100 Subject: [PATCH 254/540] Move "describe.only" to test/spv_node.js --- test/spv_node.js | 2 +- test/testnet_spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index ae7f89b..4b2273b 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -19,7 +19,7 @@ require("should-sinon"); const COIN = consensus.COIN; -describe("SPVNode", () => { +describe.only("SPVNode", () => { var spvNode = null; var miner = null; var spvWalletDB = null; diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js index a915db2..fcad493 100644 --- a/test/testnet_spv_node.js +++ b/test/testnet_spv_node.js @@ -19,7 +19,7 @@ require("should-sinon"); const COIN = 1000; -describe.only("SPVNode", () => { +describe("SPVNode", () => { var spvNode = null; var miner = null; var spvWalletDB = null; From 7266d9ce97f7df24a3f273b4b73082e90756282f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:03:40 +0100 Subject: [PATCH 255/540] Remove peer connection logic --- test/spv_node.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 4b2273b..001d29d 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -70,22 +70,6 @@ describe.only("SPVNode", () => { spvWatcher = new testHelpers.NodeWatcher(spvNode); }); - -// beforeEach("add miner to spvNode as peer", async () => { -// const minerAddr = bcoin.netaddress.fromHostname(miner.http.config.host + ":" + miner.http.config.port, "regtest"); -// spvNode.pool.peer.connect(minerAddr); -// spvNode.pool.peer.tryOpen(); - -// const minerAddr = miner.http.config.host + ":" + miner.http.config.port; -// -// (async () => { -// const result = await spvNode.rpc.execute("addnode", [minerAddr, "add"]); -// console.log(result); -// })().catch((err) => { -// console.error(err.stack); -// }); -// }); - afterEach("disconnect nodes", async () => { spvNode.stopSync(); miner.stopSync(); From f8606b48b47301a409fdc3bd46420ee3b9f7154c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:04:43 +0100 Subject: [PATCH 256/540] Rename "Sender/Receiver" to "Alpha/Beta" --- test/spv_node.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 001d29d..b33a567 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -92,24 +92,24 @@ describe.only("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvSender = await testHelpers.createWallet(spvWalletDB, "spvSender"); - var spvReceiver = await testHelpers.createWallet(spvWalletDB, "spvReceiver"); + var spvAlpha = await testHelpers.createWallet(spvWalletDB, "spvAlpha"); + var spvBeta = await testHelpers.createWallet(spvWalletDB, "spvBeta"); - var minerSender = await testHelpers.createWallet(minerWalletDB, "minerSender"); - var minerReceiver = await testHelpers.createWallet(minerWalletDB, "minerReceiver"); + var minerAlpha = await testHelpers.createWallet(minerWalletDB, "minerAlpha"); + var minerBeta = await testHelpers.createWallet(minerWalletDB, "minerBeta"); await testHelpers.delay(1000); - // Produce a block and reward the minerSender, so that we have a coin to spend. - await testHelpers.mineBlock(miner, minerSender.getAddress("base58")); + // Produce a block and reward the minerAlpha, so that we have a coin to spend. + await testHelpers.mineBlock(miner, minerAlpha.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - await minerSender.send({ + await minerAlpha.send({ outputs: [{ value: 10 * COIN, - address: minerReceiver.getAddress("base58") + address: minerBeta.getAddress("base58") }] }); await minerWatcher.waitForTX(); From 7807db7e67045e525564bfe6a61876da03e6b38a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:06:34 +0100 Subject: [PATCH 257/540] Add connection options --- test/spv_node.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index b33a567..050f67a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -37,11 +37,20 @@ describe.only("SPVNode", () => { beforeEach("get nodes", () => { miner = new Trust.FullNode({ - network: "regtest", passphrase: "secret" + network: "regtest", + port: 48448, + bip37: true, + listen: true, + passphrase: "secret", }); spvNode = new Trust.SPVNode({ - network: "regtest", passphrase: "secret", port: 48333 + network: "regtest", + port: 48445, + passphrase: "secret", + logConsole: true, + logLevel: "debug", + nodes: ["127.0.0.1:48448"] }); }); From af4570da3a2fb2e5006fe453f6d88c96777ddb94 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:07:00 +0100 Subject: [PATCH 258/540] Add "on TX" spv trigger --- test/spv_node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 050f67a..f102d34 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -72,6 +72,10 @@ describe.only("SPVNode", () => { beforeEach("start syncing nodes", () => { miner.startSync(); spvNode.startSync(); + spvNode.pool.on("tx", async (tx) => { + console.log("TX added!"); + await spvWalletDB.addTX(tx); + }); }); beforeEach("get watchers", () => { From 9d3a4a7387c081bf3b7bdf4ef655910ec87b19ee Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:07:29 +0100 Subject: [PATCH 259/540] Watch for TXs with Alice's public key --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index f102d34..52aca76 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -183,6 +183,7 @@ describe.only("SPVNode", () => { assert(await mtx.verify()); var tx = mtx.toTX(); + spvNode.pool.watchAddress(fixtures.keyRings.alice.getPublicKey()); miner.sendTX(tx); await minerWatcher.waitForTX(); From 3a02fdfee784e05fdf2071c01ec755c11610f29b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Oct 2017 23:07:41 +0100 Subject: [PATCH 260/540] Wait for SPV to see the TX --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index 52aca76..38877f0 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -186,6 +186,7 @@ describe.only("SPVNode", () => { spvNode.pool.watchAddress(fixtures.keyRings.alice.getPublicKey()); miner.sendTX(tx); await minerWatcher.waitForTX(); + await spvWatcher.waitForTX(); // TODO: find why spv doesn't see TX prevout = {}; fixtures.names.forEach((name) => { From 4da0f0b994dc77b7c4cb5485499832409d5955ec Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 20 Oct 2017 00:15:44 +0100 Subject: [PATCH 261/540] Run "npm install" --- package-lock.json | 264 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2086d94..708f46e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "abbrev": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", - "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "abstract-leveldown": { "version": "2.6.3", @@ -74,6 +74,7 @@ "ajv": { "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, "requires": { "co": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" @@ -104,9 +105,9 @@ "dev": true }, "aproba": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", - "integrity": "sha1-RcZikJTeTpb2k+9+q3SuB5wkD8E=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "optional": true }, "are-we-there-yet": { @@ -165,9 +166,9 @@ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "async": { "version": "1.5.2", @@ -181,9 +182,9 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.6.0", @@ -389,11 +390,11 @@ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" }, "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "2.16.3" + "hoek": "4.2.0" } }, "brace-expansion": { @@ -415,9 +416,9 @@ "dev": true }, "browserify-aes": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz", - "integrity": "sha1-yPo7G3WFu3unfFVgtgmW3extUwk=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "optional": true, "requires": { "buffer-xor": "1.0.3", @@ -579,7 +580,7 @@ "cipher-base": "1.0.4", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "ripemd160": "2.0.1", - "sha.js": "2.4.8" + "sha.js": "2.4.9" } }, "create-hmac": { @@ -593,15 +594,25 @@ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "ripemd160": "2.0.1", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "sha.js": "2.4.8" + "sha.js": "2.4.9" } }, "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "2.10.1" + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } } }, "d": { @@ -617,13 +628,6 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "debug": { @@ -688,7 +692,7 @@ "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "optional": true, "requires": { - "browserify-aes": "1.0.8", + "browserify-aes": "1.1.1", "create-hash": "1.1.3", "create-hmac": "1.1.6" } @@ -1079,6 +1083,11 @@ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, "fast-future": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", @@ -1139,9 +1148,9 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", "requires": { "asynckit": "0.4.0", "combined-stream": "1.0.5", @@ -1202,13 +1211,6 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "ghreleases": { @@ -1298,17 +1300,30 @@ "dev": true }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "har-schema": "1.0.5" + "ajv": "5.2.3", + "har-schema": "2.0.0" + }, + "dependencies": { + "ajv": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", + "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "requires": { + "co": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" + } + } } }, "has-ansi": { @@ -1368,27 +1383,27 @@ } }, "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.0.2" } }, "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "0.2.0", + "assert-plus": "1.0.0", "jsprim": "1.4.1", "sshpk": "1.13.1" } @@ -1564,6 +1579,11 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, "json-stable-stringify": { "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", @@ -1609,13 +1629,6 @@ "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "leveldown": { @@ -1897,7 +1910,7 @@ "nopt": "3.0.6", "npmlog": "2.0.4", "osenv": "0.1.4", - "request": "2.81.0", + "request": "2.83.0", "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", "semver": "5.3.0", "tar": "2.2.1", @@ -1919,7 +1932,7 @@ "npmlog": "2.0.4", "osenv": "0.1.4", "path-array": "1.0.1", - "request": "2.81.0", + "request": "2.83.0", "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", "semver": "5.3.0", "tar": "2.2.1", @@ -1937,7 +1950,7 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "requires": { - "abbrev": "1.1.0" + "abbrev": "1.1.1" } }, "npmlog": { @@ -2082,9 +2095,9 @@ } }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -2128,17 +2141,17 @@ "npmlog": "2.0.4", "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "pump": "1.0.2", - "rc": "1.2.1", + "rc": "1.2.2", "simple-get": "1.4.3", - "tar-fs": "1.15.3", + "tar-fs": "1.16.0", "tar-stream": "1.5.4", "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" } }, "prebuild-install": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.2.tgz", - "integrity": "sha1-3UfE1h83VPsXu/YBdZ5ZIuFuBnE=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.3.0.tgz", + "integrity": "sha512-gzjq2oHB8oMbzJSsSh9MQ64zrXZGt092/uT4TLZlz2qnrPxpWqp4vYB7LZrDxnlxf5RfbCjkgDI/z0EIVuYzAw==", "optional": true, "requires": { "expand-template": "1.1.0", @@ -2150,9 +2163,9 @@ "npmlog": "4.1.2", "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "pump": "1.0.2", - "rc": "1.2.1", + "rc": "1.2.2", "simple-get": "1.4.3", - "tar-fs": "1.15.3", + "tar-fs": "1.16.0", "tunnel-agent": "0.6.0", "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" }, @@ -2163,7 +2176,7 @@ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "requires": { - "aproba": "1.1.2", + "aproba": "1.2.0", "console-control-strings": "1.1.0", "has-unicode": "2.0.1", "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2216,14 +2229,14 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", "optional": true, "requires": { "deep-extend": "0.4.2", @@ -2269,30 +2282,30 @@ "dev": true }, "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "requires": { - "aws-sign2": "0.6.0", + "aws-sign2": "0.7.0", "aws4": "1.6.0", "caseless": "0.12.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", "mime-types": "2.1.17", "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", + "performance-now": "2.1.0", + "qs": "6.5.1", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.3", "tunnel-agent": "0.6.0", "uuid": "3.1.0" } @@ -2379,7 +2392,7 @@ "drbg.js": "1.0.1", "elliptic": "6.3.2", "nan": "2.5.1", - "prebuild-install": "2.2.2" + "prebuild-install": "2.3.0" } }, "semver": { @@ -2394,11 +2407,12 @@ "optional": true }, "sha.js": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", - "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, "shelljs": { @@ -2508,11 +2522,11 @@ "dev": true }, "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", + "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", "requires": { - "hoek": "2.16.3" + "hoek": "4.2.0" } }, "socket.io": { @@ -2702,13 +2716,6 @@ "getpass": "0.1.7", "jsbn": "0.1.1", "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "string_decoder": { @@ -2806,9 +2813,9 @@ } }, "tar-fs": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz", - "integrity": "sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA=", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz", + "integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==", "optional": true, "requires": { "chownr": "1.0.1", @@ -2887,9 +2894,9 @@ "dev": true }, "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", "requires": { "punycode": "1.4.1" } @@ -2984,13 +2991,6 @@ "assert-plus": "1.0.0", "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "vlq": { diff --git a/package.json b/package.json index 116b868..3d8c39a 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "sinon": "^2.2.0" }, "dependencies": { - "bcoin": "1.0.0-beta.12", + "bcoin": "^1.0.0-beta.12", "graph-theory-ford-fulkerson": "^1.0.0", "sorted-set": "^0.3.0" } From 80efbc41b16ac719aba836f5963f001dd3787376 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 20 Oct 2017 00:16:07 +0100 Subject: [PATCH 262/540] Stop logging --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 38877f0..6b0ffbc 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -48,8 +48,8 @@ describe.only("SPVNode", () => { network: "regtest", port: 48445, passphrase: "secret", - logConsole: true, - logLevel: "debug", + // logConsole: true, + // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); }); From 330fb320a79b390d52f2d77f6c8d2027c238cafe Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 20 Oct 2017 00:16:12 +0100 Subject: [PATCH 263/540] Ensure that transactions reach the spv node The way to do this is to run spvNode.connect() before miner.connect() --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 6b0ffbc..6623b14 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -65,8 +65,8 @@ describe.only("SPVNode", () => { }); beforeEach("connect nodes", async () => { - await miner.connect(); await spvNode.connect(); + await miner.connect(); }); beforeEach("start syncing nodes", () => { From fe736d55686c6972e4c6233642c149f5ba5b96f6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 21:52:09 +0100 Subject: [PATCH 264/540] Allow tests to run for longer Transaction exchange between nodes is slower --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d8c39a..0809f1c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 10000", + "test": "npm run build && mocha -t 20000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 4f4d825ebb959ac00733dbf9218dd77ea4fccb83 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 21:57:49 +0100 Subject: [PATCH 265/540] Extend waitForTX() functionality Can now wait for a particular transaction, for a particular number of transactions or for just one more transaction. If it waits for a particular transaction, the loop conflicts with the node.pool.on("tx", ...) trigger and the latter does not execute. --- test/helpers.js | 59 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 3d00720..645a121 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -157,19 +157,52 @@ class NodeWatcher { }); } - async waitForTX(txid) { - var initialCount = this.txCount; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount && - (txid === undefined || - this.node.pool.hasTX(txid))) - resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); + async waitForTX(input) { + var initialCount = null; + switch (typeof input) { + case "number": + initialCount = input; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "undefined": // TODO: reuse code + initialCount = this.txCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "object": + var tx = input; + await new Promise((resolve, reject) => { + var check = (() => { + // This breaks node.pool.on("tx", ...) + if (this.node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + default: + throw new Error("input cannot be " + typeof input); // TODO: throw correct error + } } } From 973a1ba0d1a6289b03de32b638065c3d42eb32f9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 21:59:47 +0100 Subject: [PATCH 266/540] Remove .only --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 6623b14..a1fd6fb 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -19,7 +19,7 @@ require("should-sinon"); const COIN = consensus.COIN; -describe.only("SPVNode", () => { +describe("SPVNode", () => { var spvNode = null; var miner = null; var spvWalletDB = null; From fd6466208d4d508ae62330f3983fbcd3b60786f9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 22:00:06 +0100 Subject: [PATCH 267/540] Remove redundant comma (,) --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index a1fd6fb..f3794b4 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -41,7 +41,7 @@ describe("SPVNode", () => { port: 48448, bip37: true, listen: true, - passphrase: "secret", + passphrase: "secret" }); spvNode = new Trust.SPVNode({ From ffa1bb021dc1f233800f20f87695ef65a721bcde Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 22:00:25 +0100 Subject: [PATCH 268/540] Comment about order of instructions --- test/spv_node.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index f3794b4..dd06476 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -65,6 +65,8 @@ describe("SPVNode", () => { }); beforeEach("connect nodes", async () => { + // The spv node must connect BEFORE the full node + // in order for the spv node to correctly receive txs await spvNode.connect(); await miner.connect(); }); From a1535fb3e624a56b9654275537257b7222535bff Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 22:01:55 +0100 Subject: [PATCH 269/540] Remove trigger for adding txs to walletDB This is now done manually, because the way we check if some particular transaction was added with waitForTX() does not allow the trigger to execute correctly. --- test/spv_node.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index dd06476..3eb12d6 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -74,10 +74,6 @@ describe("SPVNode", () => { beforeEach("start syncing nodes", () => { miner.startSync(); spvNode.startSync(); - spvNode.pool.on("tx", async (tx) => { - console.log("TX added!"); - await spvWalletDB.addTX(tx); - }); }); beforeEach("get watchers", () => { @@ -125,11 +121,15 @@ describe("SPVNode", () => { outputs: [{ value: 10 * COIN, address: minerBeta.getAddress("base58") + await spvWalletDB.addTX(miner2TX); + await spvWalletDB.addTX(minerSpvTX); + await minerWalletDB.addTX(spv2TX); }] }); await minerWatcher.waitForTX(); miner.trust.addTX.should.be.calledOnce(); + await minerWalletDB.addTX(spvMinerTX); }); describe("with the nobodyLikesFrank.json example", () => { From 6777304df43892085209a2a8e2aa4cd8dde2d52f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 22:06:39 +0100 Subject: [PATCH 270/540] Rename Alpha, Beta to Wallet1, Wallet2 --- test/spv_node.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 3eb12d6..ea99c90 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -103,24 +103,24 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvAlpha = await testHelpers.createWallet(spvWalletDB, "spvAlpha"); - var spvBeta = await testHelpers.createWallet(spvWalletDB, "spvBeta"); + var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); + var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); - var minerAlpha = await testHelpers.createWallet(minerWalletDB, "minerAlpha"); - var minerBeta = await testHelpers.createWallet(minerWalletDB, "minerBeta"); + var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); + var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); await testHelpers.delay(1000); - // Produce a block and reward the minerAlpha, so that we have a coin to spend. - await testHelpers.mineBlock(miner, minerAlpha.getAddress("base58")); + // Produce a block and reward the minerWallet1, so that we have a coin to spend. + await testHelpers.mineBlock(miner, minerWallet1.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - await minerAlpha.send({ + var miner2TX = await minerWallet1.send({ outputs: [{ value: 10 * COIN, - address: minerBeta.getAddress("base58") + address: minerWallet2.getAddress("base58") await spvWalletDB.addTX(miner2TX); await spvWalletDB.addTX(minerSpvTX); await minerWalletDB.addTX(spv2TX); From 69ee414d4583616cd306a0076b391132dd18cdc2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 22:07:54 +0100 Subject: [PATCH 271/540] Make spv watch all created addresses --- test/spv_node.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index ea99c90..ac12a14 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -109,6 +109,12 @@ describe("SPVNode", () => { var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); + spvNode.pool.watchAddress(minerWallet1.getAddress()); + spvNode.pool.watchAddress(minerWallet2.getAddress()); + + spvNode.pool.watchAddress(spvWallet1.getAddress()); + spvNode.pool.watchAddress(spvWallet2.getAddress()); + await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. await testHelpers.mineBlock(miner, minerWallet1.getAddress("base58")); From d480b2043a2c8feddfbd4e2cc96193061c732023 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 22:08:21 +0100 Subject: [PATCH 272/540] Send all transaction types and test everyone hears Four transactions happen and reach both nodes: 1. full node -> full node 2. full node -> spv node 3. spv node -> spv node 4. spv node -> full node --- test/spv_node.js | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index ac12a14..e1e0c18 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -127,14 +127,50 @@ describe("SPVNode", () => { outputs: [{ value: 10 * COIN, address: minerWallet2.getAddress("base58") + }] + }); + await minerWatcher.waitForTX(miner2TX); + await spvWatcher.waitForTX(miner2TX); await spvWalletDB.addTX(miner2TX); + await testHelpers.delay(300); + + miner.trust.addTX.should.have.been.calledOnce(); + spvNode.trust.addTX.should.have.been.calledOnce(); + + var minerSpvTX = await minerWallet2.send({ + outputs: [{ + value: 9 * COIN, + address: spvWallet1.getAddress("base58") + }] + }); + await minerWatcher.waitForTX(minerSpvTX); + await spvWatcher.waitForTX(minerSpvTX); await spvWalletDB.addTX(minerSpvTX); + + miner.trust.addTX.should.have.been.calledTwice(); + spvNode.trust.addTX.should.have.been.calledTwice(); + + var spv2TX = await spvWallet1.send({ + outputs: [{ + value: 8 * COIN, + address: spvWallet2.getAddress("base58") + }] + }); + await minerWatcher.waitForTX(spv2TX); + await spvWatcher.waitForTX(spv2TX); await minerWalletDB.addTX(spv2TX); + + miner.trust.addTX.should.have.been.calledThrice(); + spvNode.trust.addTX.should.have.been.calledThrice(); + + var spvMinerTX = await spvWallet2.send({ + outputs: [{ + value: 7 * COIN, + address: minerWallet1.getAddress("base58") }] }); - await minerWatcher.waitForTX(); - - miner.trust.addTX.should.be.calledOnce(); + await minerWatcher.waitForTX(spvMinerTX); + await spvWatcher.waitForTX(spvMinerTX); await minerWalletDB.addTX(spvMinerTX); }); From 6db0f0264c1f28e3d8e891606dbaf4ba350bff37 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:53:01 +0100 Subject: [PATCH 273/540] Remove getTX() from bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 8c1df0f..4017d03 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -23,9 +23,7 @@ declare class bcoin$SPVNode { getCoin(hash : Hash, index : number) : bcoin$Coin; } -declare class bcoin$Chain { - getTX(hash : Hash) : bcoin$TX; -} +declare class bcoin$Chain {} declare class bcoin$WalletDB {} From c66b08884b405e8c18018cd834392db658715646 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:53:30 +0100 Subject: [PATCH 274/540] Correct getTX() types in bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 4017d03..700c16a 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -28,7 +28,7 @@ declare class bcoin$Chain {} declare class bcoin$WalletDB {} declare class bcoin$Wallet { - getTX() : bcoin$TX; + getTX(hash : Hash) : Promise; } declare class bcoin$Pool { From 4763767f529b2c97abdd3e809c29a5bbf3fad04d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:54:54 +0100 Subject: [PATCH 275/540] Fix indentation --- src/trust_is_risk.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index c2ceeba..67e1020 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -143,12 +143,14 @@ class TrustIsRisk { return mtx; } - async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, - trustAmount : number, node : (bcoin$FullNode | bcoin$SPVNode), fee : ?number) + async ccreateTrustIncreasingMTX(origin : Key, dest : Key, + outpoint : bcoin$Outpoint, trustAmount : number, + node : (bcoin$FullNode | bcoin$SPVNode), fee : ?number) : Promise { assert(node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this - if (origin === dest) throw new Error("Can not increase self-trust."); + if (origin === dest) + throw new Error("Can not increase self-trust."); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); @@ -156,7 +158,8 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), + script: bcoin.script.fromMultisig(1, 3, + [originPubKey, dest, this.fakePubKey]), value: trustAmount }) ] @@ -175,7 +178,8 @@ class TrustIsRisk { assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), + script: bcoin.script.fromPubkeyhash( + bcoin.crypto.hash160(originPubKey)), value: changeAmount })); } From 76ad42b60ad7c1674f1716fec3658340afaec7a0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:56:55 +0100 Subject: [PATCH 276/540] Use wallet instead of node --- src/trust_is_risk.js | 4 ++-- test/spv_node.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 67e1020..a208243 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -145,7 +145,7 @@ class TrustIsRisk { async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, - node : (bcoin$FullNode | bcoin$SPVNode), fee : ?number) + wallet : bcoin$Wallet, fee : ?number) : Promise { assert(node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this @@ -170,7 +170,7 @@ class TrustIsRisk { node.pool.watchAddress(txid); await watcher.waitForTX(txid); - var tx = await node.chain.getTX(txid); + var tx = await wallet.getTX(hash); if (!tx) throw new Error("Could not find tx"); diff --git a/test/spv_node.js b/test/spv_node.js index e1e0c18..51f217c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -272,7 +272,7 @@ describe("SPVNode", () => { fixtures.keyRings[dest].getPublicKey(), outpoint, value * consensus.COIN, - node); + wallet); // Must pass some wallet to getTX from that } else { // if full node mtx = await node.trust.createTrustIncreasingMTX( From 274050b3592b2c50ab395c8829b93729f35b43ba Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:57:49 +0100 Subject: [PATCH 277/540] Remove redundant watcher --- src/trust_is_risk.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index a208243..329fa3a 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -166,9 +166,6 @@ class TrustIsRisk { }); var txid = outpoint.txid(); - var watcher = new helpers.NodeWatcher(node); - node.pool.watchAddress(txid); - await watcher.waitForTX(txid); var tx = await wallet.getTX(hash); if (!tx) throw new Error("Could not find tx"); From 8d2f58aa3f3f72729bfc8158c094ef972def5549 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:58:09 +0100 Subject: [PATCH 278/540] Use hash instead of txid --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 329fa3a..d18ad10 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -165,7 +165,7 @@ class TrustIsRisk { ] }); - var txid = outpoint.txid(); + var hash = outpoint.hash; var tx = await wallet.getTX(hash); if (!tx) throw new Error("Could not find tx"); From c70a251d67d0009127536ba9ae2c68531fa9e193 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:58:38 +0100 Subject: [PATCH 279/540] Watch for charlie and dave's transactions --- test/spv_node.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 51f217c..40be502 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -184,6 +184,9 @@ describe("SPVNode", () => { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); } + spvNode.pool.watchAddress(addresses["charlie"]); + spvNode.pool.watchAddress(addresses["dave"]); + // Alice mines three blocks, each rewards her with 50 spendable BTC consensus.COINBASE_MATURITY = 0; var blockCount = 3; From 964467e1dd5a2ed72fc5f139ffb2a392299be57e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 21 Oct 2017 23:59:09 +0100 Subject: [PATCH 280/540] Stop watching and waiting for alice's tx --- test/spv_node.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 40be502..7f31c7e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -230,10 +230,9 @@ describe("SPVNode", () => { assert(await mtx.verify()); var tx = mtx.toTX(); - spvNode.pool.watchAddress(fixtures.keyRings.alice.getPublicKey()); + miner.sendTX(tx); await minerWatcher.waitForTX(); - await spvWatcher.waitForTX(); // TODO: find why spv doesn't see TX prevout = {}; fixtures.names.forEach((name) => { From 9bf0f8f1e304eed029aaafb6ff559ddc323b405f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 18:53:12 +0100 Subject: [PATCH 281/540] Remove spv node test that uses testnet Tests using testnet are redundant since regtest nodes connect fine --- test/testnet_fixtures.js | 30 ---- test/testnet_spv_node.js | 360 --------------------------------------- 2 files changed, 390 deletions(-) delete mode 100644 test/testnet_fixtures.js delete mode 100644 test/testnet_spv_node.js diff --git a/test/testnet_fixtures.js b/test/testnet_fixtures.js deleted file mode 100644 index 1450b6a..0000000 --- a/test/testnet_fixtures.js +++ /dev/null @@ -1,30 +0,0 @@ -var bcoin = require("bcoin"); -var KeyRing = bcoin.primitives.KeyRing; - -var privateKeys = { - // cSxTT76c6Dr9LBqqJUgz5zhvE6TCNdSkM3vVmDnTue99JitVPAa6 - "alice": "A060F1B3D346BE056F9E3A2F0972F98756AC1FBBC92490F6625858E8520637B5", - // cQxfCPseKaNq4hNbcgX53tfk7Y4hYTJNP176eTo1FRACdiFPTJQk - "bob": "64CEDE6032121BA1BCCF0F71FC21BE46270CEEDAF5B59B0E2735FAAE2D1E86A0", - // cSi94uAg7wk8JiwkdWF48uz2rea1zBheRwMoH7z8SLk3tuuysqJg - "charlie": "990375528C670D738933B83D10A6481DCB2E5F2E01B24EAAF8E8C6EC92C925DC", - // cNFdijFuW73DyqpayUjo6cGQNvtZzcNBYZr7b84Njkg6GPFYAmGr - "dave": "14073A5D848AEB0F4E507DB712B6333B7C468D3278AEC3E47EB8B697338EDBCC", - // cQPKx8fUnn7qh9vnWzqurQDAhigy22AiWq8EBGGcJfdG75j1i6mW - "eve": "53A93284BFD483539D12B6ACBEB023F8DA08C92C4AA70D8D529CDBFEA76DE7C1", - // cVejVCD18z8LhibFCxBTz7xdSQ5fuogYR3W4igoBP3BUj26V9yQJ - "frank": "F0C5F25C787B6482DA433792CEF1001661F4895C566EA76F30FE358C8B42897C", - // cPno2fuQTfLh7MRTJiPDvyo8Y1XmEJ2JtUo4zwocpxTc22LDSiBi - "george": "41E551884C6F847235F6CAAC14259E7DB3D275B6157D0FF00478AA52B47608D9", -}; - -var keyRings = {}; -for (let name in privateKeys) { - let key = privateKeys[name]; - keyRings[name] = KeyRing.fromPrivate(Buffer.from(key, "hex"), false, "testnet"); -} - -module.exports = { - keyRings, - names: Object.keys(keyRings) -}; diff --git a/test/testnet_spv_node.js b/test/testnet_spv_node.js deleted file mode 100644 index fcad493..0000000 --- a/test/testnet_spv_node.js +++ /dev/null @@ -1,360 +0,0 @@ -var Trust = require("../"); -var helpers = require("../lib/helpers.js"); -var bcoin = require("bcoin"); -var Script = bcoin.script; -var Address = bcoin.primitives.Address; -var KeyRing = bcoin.primitives.KeyRing; -var MTX = bcoin.primitives.MTX; -var Input = bcoin.primitives.Input; -var Output = bcoin.primitives.Output; -var Outpoint = bcoin.primitives.Outpoint; -var WalletDB = bcoin.wallet.WalletDB; -var testHelpers = require("./helpers"); -var consensus = require("bcoin/lib/protocol/consensus"); -var sinon = require("sinon"); -var should = require("should"); -var assert = require("assert"); -var fixtures = require("./testnet_fixtures"); -require("should-sinon"); - -const COIN = 1000; - -describe("SPVNode", () => { - var spvNode = null; - var miner = null; - var spvWalletDB = null; - var minerWalletDB = null; - var spvWatcher = null; - var minerWatcher = null; - - before("set up addTX() spy", function() { - sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); - }); - - after("reset addTX() spy", function() { - Trust.TrustIsRisk.prototype.addTX.restore(); - }); - - beforeEach("get nodes", () => { - miner = new Trust.FullNode({ - network: "testnet", passphrase: "secret" - }); - - spvNode = new Trust.SPVNode({ - network: "testnet", passphrase: "secret", port: 48333 - }); - }); - - beforeEach("open nodes", async () => { - await miner.open(); - await spvNode.open(); - }); - - beforeEach("get walletDBs", async () => { - spvWalletDB = await testHelpers.getWalletDB(spvNode); - minerWalletDB = await testHelpers.getWalletDB(miner); - }); - - beforeEach("connect nodes", async () => { - await miner.connect(); - await spvNode.connect(); - }); - - beforeEach("start syncing nodes", () => { - miner.startSync(); - spvNode.startSync(); - }); - - beforeEach("get watchers", () => { - minerWatcher = new testHelpers.NodeWatcher(miner); - spvWatcher = new testHelpers.NodeWatcher(spvNode); - }); - - afterEach("disconnect nodes", async () => { - spvNode.stopSync(); - miner.stopSync(); - - await spvNode.disconnect(); - await miner.disconnect(); - }); - - afterEach("disconnect and close walletDBs", async () => { - await spvWalletDB.disconnect(); - await minerWalletDB.disconnect(); - - await spvWalletDB.close(); - await minerWalletDB.close(); - }); - - afterEach("close nodes", async () => { - await spvNode.close(); - await miner.close(); - }); - - it("should call trust.addTX() on every transaction", async function() { - var spvSender = await testHelpers.testnetCreateWallet(spvWalletDB, "spvSender"); - var spvReceiver = await testHelpers.testnetCreateWallet(spvWalletDB, "spvReceiver"); - - var minerSender = await testHelpers.testnetCreateWallet(minerWalletDB, "minerSender"); - var minerReceiver = await testHelpers.testnetCreateWallet(minerWalletDB, "minerReceiver"); - - await testHelpers.delay(100); - - var miner2TX = await minerSender.send({ - outputs: [{ - value: 10 * COIN, - address: minerReceiver.getAddress("base58") - }] - }); - await minerWatcher.waitForTX(undefined, miner2TX.rhash()); - - miner.trust.addTX.should.be.calledOnce(); - - var minerSpvTX = await minerSender.send({ - outputs: [{ - value: 10 * COIN, - address: spvSender.getAddress("base58") - }] - }); - await spvWatcher.waitForTX(undefined, minerSpvTX.rhash()); - - miner.trust.addTX.should.be.calledTwice(); - - var spv2TX = await spvSender.send({ - outputs: [{ - value : 5 * COIN, - address: spvReceiver.getAddres("base58") - }] - }); - await spvWatcher.waitForTX(undefined, spv2TX.rhash()); - - spv.trust.addTX.should.be.calledOnce(); // @dionyziz: or maybe Thrice()? - - var spvMinerTX = await spvReceiver.send({ - outputs: [{ - value: 2 * COIN, - address: minerSender.getAddress("base58") - }] - }); - await minerWatcher.waitForTX(undefined, spvMinerTX.rhash()); - - spv.trust.addTX.should.be.calledTwice(); - }); - - describe("with the nobodyLikesFrank.json example", () => { - var addresses, rings = {}, wallets; - - before("apply graph transactions", async () => { - miner = new Trust.FullNode({ - network: "testnet", passphrase: "secret" - }); - spvNode = new Trust.SPVNode({ - network: "testnet", passphrase: "secret", port: 48333 - }); - - await miner.open(); - await spvNode.open(); - - spvWalletDB = await testHelpers.getWalletDB(spvNode); - minerWalletDB = await testHelpers.getWalletDB(miner); - - await miner.connect(); - await spvNode.connect(); - - miner.startSync(); - spvNode.startSync(); - - minerWatcher = new testHelpers.NodeWatcher(miner); - spvWatcher = new testHelpers.NodeWatcher(spvNode); - - addresses = {}; - wallets = {}; - - for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { - addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); - // Create wallet for the keyrings - if (name === "charlie" || name === "dave") { - wallets[name] = await testHelpers.testnetCreateWallet(spvWalletDB, name + "Wallet"); - } else { - wallets[name] = await testHelpers.testnetCreateWallet(minerWalletDB, name + "Wallet"); - } - wallets[name].importKey(null, keyRing, "secret"); - } - - // Wait for tx where Alice gets coins - txidAliceIsPaid = "888d862cccd0152e6c8ea202480d648dc99c07309a6360dd178c09112b1a9585"; - await minerWatcher.waitForTX(undefined, txidAliceIsPaid); - - // Alice sends 20*10e-3 BTC to everyone (including herself) via P2PKH - var sendAmount = 20; - var outputs = fixtures.names.map((name) => { - return testHelpers.getP2PKHOutput( - Address.fromHash(bcoin.crypto.hash160(fixtures.keyRings[name].getPublicKey())) - .toBase58(), - sendAmount * consensus.COIN); - }); - - // We have to use a change output, because transactions with too large a fee are - // considered invalid. - var fee = 0.01; - var aliceBalance = await wallets["alice"].getBalance(); - var changeAmount = aliceBalance - sendAmount * fixtures.names.length - fee; - if (changeAmount >= 0.01) { - outputs.push(new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160( - fixtures.keyRings.alice.getPublicKey())), - value: changeAmount * COIN - })); - } - - // Use Alice's coins as input - var initialCoin = await wallets["alice"].getCoin(txidAliceIsPaid, 0); - var mtx = new MTX({outputs}); - mtx.addCoin(initialCoin); - - var signedCount = mtx.sign(fixtures.keyRings.alice); - assert(await mtx.verify()); - - var tx = mtx.toTX(); - miner.sendTX(tx); - await minerWatcher.waitForTX(undefined, tx.rhash()); - - prevout = {}; - fixtures.names.forEach((name) => { - prevout[name] = { - hash: tx.hash().toString("hex"), - index: fixtures.names.indexOf(name) - }; - }); - - var graph = require("./graphs/nobodyLikesFrank.json"); - for (var origin in graph) { - var neighbours = graph[origin]; - for (var dest in neighbours) { - var value = neighbours[dest]; - if (!value || value < 1) continue; - - let node = null; - let watcher = null; - if (origin === "charlie" || origin == "dave") { - node = spvNode; - watcher = spvWatcher; - } - else { - node = miner; - watcher = minerWatcher; - } - - let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - - let mtx = null; - if (node.spv) { - console.log(node.pool.peers); - mtx = await node.trust.ccreateTrustIncreasingMTX( - fixtures.keyRings[origin].getPrivateKey(), - fixtures.keyRings[dest].getPublicKey(), - outpoint, - value * consensus.COIN, - node); - } - else { // if full node - mtx = await node.trust.createTrustIncreasingMTX( - fixtures.keyRings[origin].getPrivateKey(), - fixtures.keyRings[dest].getPublicKey(), - outpoint, - value * consensus.COIN); - } - - assert(await mtx.verify()); - - let tx = mtx.toTX(); - node.sendTX(tx); - await watcher.waitForTX(undefined, tx.rhash()); - - prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; - } - } - }); - - after("close nodes and walletDBs", async () => { - spvNode.stopSync(); - miner.stopSync(); - - await spvNode.disconnect(); - await miner.disconnect(); - - await spvWalletDB.disconnect(); - await minerWalletDB.disconnect(); - - await spvWalletDB.close(); - await minerWalletDB.close(); - - await spvNode.close(); - await miner.close(); - }); - - it("lets the miner compute trusts correctly", () => { - for (name in addresses) { // Add addresses to scope - eval(`var ${name} = "${addresses[name]}";`); - } - - should(miner.trust.getIndirectTrust(alice, alice)).equal(Infinity); - should(miner.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); - should(miner.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); - should(miner.trust.getIndirectTrust(alice, frank)).equal(0); - should(miner.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); - - should(miner.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); - should(miner.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); - should(miner.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); - should(miner.trust.getIndirectTrust(george, eve)).equal(0); - }); - - it("lets the SPV node compute trusts correctly", () => { - for (name in addresses) { // Add addresses to scope - eval(`var ${name} = "${addresses[name]}";`); - } - - should(spvNode.trust.getIndirectTrust(alice, alice)).equal(Infinity); - should(spvNode.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); - should(spvNode.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); - should(spvNode.trust.getIndirectTrust(alice, frank)).equal(0); - should(spvNode.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); - - should(spvNode.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); - should(spvNode.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); - should(spvNode.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); - should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); - }); - - it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { - var mtxs = miner.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), - fixtures.keyRings.bob.getPublicKey(), 3 * COIN); - mtxs.length.should.equal(1); - var mtx = mtxs[0]; - - should(await mtx.verify()); - miner.sendTX(mtx.toTX()); - - await testHelpers.delay(750); - should(miner.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); - should(spvNode.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); - - mtxs = spvNode.trust.createTrustDecreasingMTXs(fixtures.keyRings.dave.getPrivateKey(), - fixtures.keyRings.eve.getPublicKey(), 2 * COIN); - mtxs.length.should.equal(1); - mtx = mtxs[0]; - - should(await mtx.verify()); - spvNode.sendTX(mtx.toTX()); - - await testHelpers.delay(750); - should(miner.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); - should(spvNode.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); - }); - }); - - describe("with the topcoder.json example", () => { - //TODO: Write tests here. - }); -}); From 3dddf6681f378f0b710bb898fab3acd3ae321463 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 18:55:32 +0100 Subject: [PATCH 282/540] Expand bcoin type annotations with flow 1. Expand class bcoin$Pool a. Add spvFilter property b. Refine watchAddress() argument Both hashes and bcoin$Address objects can be passed c. Add watchOutpoint() method 2. Add class bcoin$Bloom a. Add test() method 3. Add bcoin module wallet a. Add class Wallet b. Add class WalletDB --- flow-typed/npm/bcoin_vx.x.x.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 700c16a..6fd5319 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -33,11 +33,18 @@ declare class bcoin$Wallet { declare class bcoin$Pool { peers : bcoin$PeerList; + spvFilter : bcoin$Bloom; - watchAddress(address : Buffer) : void; + watchAddress(address : (bcoin$Address | Buffer)) : void; + watchOutpoint(outpoint : bcoin$Outpoint) : void; hasTX(hash : Hash) : boolean; } +declare class bcoin$Bloom { + test(val : (Buffer | string), enc : + (typeof undefined | string)) : boolean; +} + declare class bcoin$Peer {} declare class bcoin$PeerList { @@ -129,6 +136,10 @@ declare module 'bcoin' { spvnode : Class, script : Class, pool : Class, + wallet : { + Wallet : Class, + WalletDB : Class + }, primitives : { Address : Class, TX : Class, From a67776c96d684024d2d1b05b9d0683f08b70a887 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 19:00:51 +0100 Subject: [PATCH 283/540] Have waitForTX() accept various input types The function now can accepts bcoin$TX, Hash, number and no input --- src/helpers.js | 72 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/src/helpers.js b/src/helpers.js index 4062aeb..17d8a5a 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -37,19 +37,67 @@ class NodeWatcher { }); } - async waitForTX(txid : Hash) : Promise { - var initialCount : number = this.txCount; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount && - (txid === undefined || - this.node.pool.hasTX(txid))) - resolve(); - else setTimeout(check, 100); - }).bind(this); + async waitForTX(input : (number | bcoin$TX | + Hash | typeof undefined)) : Promise { + var initialCount : number = Number.MAX_VALUE; + switch (typeof input) { + case "number": + initialCount = input; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); - check(); - }); + check(); + }); + break; + + case "object": + var tx : bcoin$TX = input; + await new Promise((resolve, reject) => { + var check = (() => { + // This breaks node.pool.on("tx", ...) + if (this.node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "string": // TODO: reuse code + var hash : Hash = input; + await new Promise((resolve, reject) => { + var check = (() => { + // This breaks node.pool.on("tx", ...) + if (this.node.pool.hasTX(hash)) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "undefined": // TODO: reuse code + initialCount = this.txCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + default: + throw new TypeError("input cannot be " + typeof input); + } } } From 798ab80f574cd955f56f2b7515c758247b8c21dc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 19:03:53 +0100 Subject: [PATCH 284/540] If tx not in pool, watch and wait for it --- src/trust_is_risk.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index d18ad10..071922a 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -152,6 +152,12 @@ class TrustIsRisk { if (origin === dest) throw new Error("Can not increase self-trust."); + var hash : Hash = outpoint.hash; + if (!this.node.pool.spvFilter.test(outpoint.hash)) { + this.node.pool.watchOutpoint(outpoint); + } + var watcher = new helpers.NodeWatcher(this.node); + await watcher.waitForTX(hash); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); @@ -165,8 +171,6 @@ class TrustIsRisk { ] }); - var hash = outpoint.hash; - var tx = await wallet.getTX(hash); if (!tx) throw new Error("Could not find tx"); From f4f09b1a6e9c362275278e459e9bb3e31c79a33d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 19:04:53 +0100 Subject: [PATCH 285/540] Use this.node instead of node from input --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 071922a..7bdc606 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -147,7 +147,7 @@ class TrustIsRisk { outpoint : bcoin$Outpoint, trustAmount : number, wallet : bcoin$Wallet, fee : ?number) : Promise { - assert(node.spv, "Only spv nodes should call this"); + assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this if (origin === dest) throw new Error("Can not increase self-trust."); From bf71997e66621928dc40db3d1c38c8eea5fdb47d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 23:04:48 +0100 Subject: [PATCH 286/540] Watch for tx only if not already available --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 7bdc606..749651d 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -155,9 +155,9 @@ class TrustIsRisk { var hash : Hash = outpoint.hash; if (!this.node.pool.spvFilter.test(outpoint.hash)) { this.node.pool.watchOutpoint(outpoint); + var watcher = new helpers.NodeWatcher(this.node); + await watcher.waitForTX(hash); } - var watcher = new helpers.NodeWatcher(this.node); - await watcher.waitForTX(hash); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); From 0f4f65733f0f9915cd8473d3328a4790910dd0c0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 23:05:32 +0100 Subject: [PATCH 287/540] Use describe.only for faster testing --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 7f31c7e..5a4e73a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -174,7 +174,7 @@ describe("SPVNode", () => { await minerWalletDB.addTX(spvMinerTX); }); - describe("with the nobodyLikesFrank.json example", () => { + describe.only("with the nobodyLikesFrank.json example", () => { var addresses, rings = {}; beforeEach("apply graph transactions", async () => { From b3066e6b64b2de936e71af5a2281ed3c5f4b72d7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 23:06:30 +0100 Subject: [PATCH 288/540] Use local wallet for tx creation (fails) --- src/trust_is_risk.js | 24 +++++++++++++++++++----- test/spv_node.js | 3 +-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 749651d..d754351 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -3,6 +3,8 @@ import type {Entity, TXHash, Key} from "./types"; var bcoin = require("bcoin"); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; +var WalletDB = bcoin.wallet.WalletDB; +var Wallet = bcoin.wallet.Wallet; var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; @@ -145,19 +147,35 @@ class TrustIsRisk { async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, - wallet : bcoin$Wallet, fee : ?number) + fee : ?number) : Promise { assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this if (origin === dest) throw new Error("Can not increase self-trust."); + var walletDB : bcoin$WalletDB = new WalletDB({ + network: this.node.network, + db: "memory", + client: new bcoin.node.NodeClient(this.node) + }); + await walletDB.open(); + await walletDB.connect(); + var wallet : bcoin$Wallet = await walletDB.create({ + id: "local", + witness: false, + type: "pubkeyhash" + }); + var hash : Hash = outpoint.hash; if (!this.node.pool.spvFilter.test(outpoint.hash)) { this.node.pool.watchOutpoint(outpoint); var watcher = new helpers.NodeWatcher(this.node); await watcher.waitForTX(hash); } + var tx : bcoin$TX = await wallet.getTX(hash); + if (!tx) throw new Error("Could not find tx"); + var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); @@ -171,10 +189,6 @@ class TrustIsRisk { ] }); - var tx = await wallet.getTX(hash); - if (!tx) throw new Error("Could not find tx"); - - var changeAmount = tx.getOutputValue() - trustAmount - fee; assert(changeAmount >= 0); if (changeAmount) { diff --git a/test/spv_node.js b/test/spv_node.js index 5a4e73a..a5044d5 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -273,8 +273,7 @@ describe("SPVNode", () => { fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, - value * consensus.COIN, - wallet); // Must pass some wallet to getTX from that + value * consensus.COIN); } else { // if full node mtx = await node.trust.createTrustIncreasingMTX( From 3b50fde4bba005b1e1ae071788f66345755ed680 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 22 Oct 2017 23:29:08 +0100 Subject: [PATCH 289/540] Add TODO for next try --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index a5044d5..f982473 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -182,6 +182,7 @@ describe("SPVNode", () => { for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); + // TODO: create a wallet for each player } spvNode.pool.watchAddress(addresses["charlie"]); From 0ef2e6d064d85d26bfaad21e4c2d3972398b93a9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 08:21:20 +0100 Subject: [PATCH 290/540] Expand type annotations with flow 1. Add class NodeClient 2. Add class Network 3. Add property network to FullNode and SPVNode 4. Expand class WalletDB a. Add open() b. Add connect() c. Add create() 5. Add node with property NodeClient to bcoin module --- flow-typed/npm/bcoin_vx.x.x.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 6fd5319..5c78ced 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -3,7 +3,10 @@ type Hash = (string | Buffer); type Network = any; +declare class bcoin$NodeClient {} + declare class bcoin$FullNode { + network : bcoin$Network; pool : bcoin$Pool; spv : boolean; chain : bcoin$Chain; @@ -14,6 +17,7 @@ declare class bcoin$FullNode { } declare class bcoin$SPVNode { + network : bcoin$Network; pool : bcoin$Pool; spv : boolean; chain : bcoin$Chain; @@ -23,9 +27,15 @@ declare class bcoin$SPVNode { getCoin(hash : Hash, index : number) : bcoin$Coin; } +declare class bcoin$Network {} + declare class bcoin$Chain {} -declare class bcoin$WalletDB {} +declare class bcoin$WalletDB { + open() : Promise; + connect() : Promise; + create(options : ?Object) : Promise; +} declare class bcoin$Wallet { getTX(hash : Hash) : Promise; @@ -132,6 +142,9 @@ declare class bcoin$Coin extends bcoin$Output { declare module 'bcoin' { declare module.exports: { + node : { + NodeClient : Class + }, fullnode : Class, spvnode : Class, script : Class, From 048a33249c55f1af4ed68a66bfaa22035787776f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 11:34:08 +0100 Subject: [PATCH 291/540] Drop fixtures, use wallets --- test/spv_node.js | 62 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index f982473..2f22f65 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -175,46 +175,68 @@ describe("SPVNode", () => { }); describe.only("with the nobodyLikesFrank.json example", () => { - var addresses, rings = {}; + var minerNames = { + "alice": "alice", + "bob": "bob", + "frank": "frank", + "george": "george" + }; + + var spvNames = { + "charlie": "charlie", + "dave": "dave" + }; + + var minerWallets = {}; + var spvWallets = {}; + var name = null; - beforeEach("apply graph transactions", async () => { - addresses = {}; - for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { - addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); - // TODO: create a wallet for each player + beforeEach("apply graph transactions", async () => { + for (name in minerNames) { + minerWallets[name] = await testHelpers.createWallet(minerWalletDB, name); } - spvNode.pool.watchAddress(addresses["charlie"]); - spvNode.pool.watchAddress(addresses["dave"]); + for (name in spvNames) { + spvWallets[name] = await testHelpers.createWallet(spvWalletDB, name); + spvNode.pool.watchAddress(spvWallets[name].getAddress()); + } // Alice mines three blocks, each rewards her with 50 spendable BTC consensus.COINBASE_MATURITY = 0; var blockCount = 3; var coinbaseHashes = []; for(let i = 0; i < blockCount; i++) { - var block = await testHelpers.mineBlock(miner, addresses.alice); + var block = await testHelpers.mineBlock(miner, minerWallets["alice"].getAddress()); coinbaseHashes.push(block.txs[0].hash()); await testHelpers.delay(500); } // Alice sends 20 BTC to everyone (including herself) via P2PKH var sendAmount = 20; - var outputs = fixtures.names.map((name) => { - return testHelpers.getP2PKHOutput( - Address.fromHash(bcoin.crypto.hash160(fixtures.keyRings[name].getPublicKey())) - .toBase58(), - sendAmount * consensus.COIN); - }); + outputs = []; + for (name in minerNames) { + outputs.push(testHelpers.getP2PKHOutput( + minerWallets[name].getAddress("base58"), + sendAmount * consensus.COIN)); + } + + for (name in spvNames) { + outputs.push(testHelpers.getP2PKHOutput( + spvWallets[name].getAddress("base58"), + sendAmount * consensus.COIN)); + } // We have to use a change output, because transactions with too large a fee are // considered invalid. var fee = 0.01; - var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; + console.log(Object.keys(minerNames).length); + var changeAmount = 50 * blockCount - sendAmount * + (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160( - fixtures.keyRings.alice.getPublicKey())), + script: Script.fromPubkeyhash( + minerWallets["alice"].getAddress("base58")), value: changeAmount * consensus.COIN })); } @@ -257,11 +279,13 @@ describe("SPVNode", () => { let node = null; let watcher = null; - if (origin === "charlie" || origin == "dave") { + if (spvNames[origin]) { + console.log("2"); node = spvNode; watcher = spvWatcher; } else { + console.log("4"); node = miner; watcher = minerWatcher; } From 0f5cfe326f287770633bc508a054f05f59a41a65 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 19:46:35 +0100 Subject: [PATCH 292/540] Remove redundant getNode() function --- test/helpers.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 645a121..d481251 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,13 +5,6 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - getNode: async (type) => { - var node = new TrustIsRisk.FullNode({network: "regtest", passphrase: "secret"}); - await node.open(); - - return node; - }, - getWalletDB: async (node) => { var walletDB = new WalletDB({ network: "regtest", From a837e4aee5cc9eade2735af937eda0e1f4796e1a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 19:48:05 +0100 Subject: [PATCH 293/540] Fix indentation --- test/spv_node.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 2f22f65..0668f19 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -207,7 +207,8 @@ describe("SPVNode", () => { var blockCount = 3; var coinbaseHashes = []; for(let i = 0; i < blockCount; i++) { - var block = await testHelpers.mineBlock(miner, minerWallets["alice"].getAddress()); + var block = await testHelpers.mineBlock(miner, + minerWallets["alice"].getAddress("base58")); coinbaseHashes.push(block.txs[0].hash()); await testHelpers.delay(500); } From d04f1bf6f6e4d5fcd1cb65d012404d0e7a901faf Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 19:48:28 +0100 Subject: [PATCH 294/540] Remove logging --- test/spv_node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 0668f19..0cf1641 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -231,7 +231,6 @@ describe("SPVNode", () => { // We have to use a change output, because transactions with too large a fee are // considered invalid. var fee = 0.01; - console.log(Object.keys(minerNames).length); var changeAmount = 50 * blockCount - sendAmount * (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; if (changeAmount >= 0.01) { From 0188667df54b21f9c4985065209dd3b4d34d585d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 19:49:10 +0100 Subject: [PATCH 295/540] Use pubkeyhash instead of address --- test/spv_node.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 0cf1641..f4a02ff 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -234,9 +234,11 @@ describe("SPVNode", () => { var changeAmount = 50 * blockCount - sendAmount * (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; if (changeAmount >= 0.01) { + var alicePrivateKey = await minerWallets["alice"].getPrivateKey( + minerWallets["alice"].getAddress("base58"), "secret"); outputs.push(new Output({ - script: Script.fromPubkeyhash( - minerWallets["alice"].getAddress("base58")), + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + alicePrivateKey.publicKey)), value: changeAmount * consensus.COIN })); } From feef3e5aa47fe060866d9680debc131398e70897 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 19:49:58 +0100 Subject: [PATCH 296/540] Try to use generated keyring instead of fixture --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index f4a02ff..7d1739e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -250,7 +250,7 @@ describe("SPVNode", () => { var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); - var signedCount = mtx.sign(fixtures.keyRings.alice); + var signedCount = mtx.sign(alicePrivateKey); assert(signedCount === blockCount); assert(await mtx.verify()); From 0a0ec84d0ddd173141be3e1a730204b3f4b789e5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 23 Oct 2017 19:50:36 +0100 Subject: [PATCH 297/540] Include minimal.js in .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b4e253f..c09af18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ lib/ *.swp +minimal.js From 343e10598a269afe2a734ace406e3fc12536e2ee Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 14:58:53 +0100 Subject: [PATCH 298/540] Have both miner and spvNode wait for specific tx --- test/spv_node.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 7d1739e..f3d32a4 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -257,7 +257,8 @@ describe("SPVNode", () => { var tx = mtx.toTX(); miner.sendTX(tx); - await minerWatcher.waitForTX(); + await minerWatcher.waitForTX(tx); + await spvWatcher.waitForTX(tx); prevout = {}; fixtures.names.forEach((name) => { From 5ae1f4415b811849f9634b592e6721943a941bff Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 14:59:52 +0100 Subject: [PATCH 299/540] Save addresses and keyrings to new vars --- test/spv_node.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index f3d32a4..b3c7a7e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -189,17 +189,33 @@ describe("SPVNode", () => { var minerWallets = {}; var spvWallets = {}; - var name = null; + var addresses = {}, rings = {}, name = null; beforeEach("apply graph transactions", async () => { for (name in minerNames) { - minerWallets[name] = await testHelpers.createWallet(minerWalletDB, name); + minerWallets[name] = await testHelpers.createWallet( + minerWalletDB, name + ); + rings[name] = await minerWallets[name].getPrivateKey( + minerWallets[name].getAddress("base58"), "secret" + ); + addresses[name] = helpers.pubKeyToEntity( + rings[name].getPublicKey() + ); } for (name in spvNames) { - spvWallets[name] = await testHelpers.createWallet(spvWalletDB, name); - spvNode.pool.watchAddress(spvWallets[name].getAddress()); + spvWallets[name] = await testHelpers.createWallet( + spvWalletDB, name + ); + rings[name] = await spvWallets[name].getPrivateKey( + spvWallets[name].getAddress("base58"), "secret" + ); + addresses[name] = helpers.pubKeyToEntity( + rings[name].getPublicKey() + ); + spvNode.pool.watchAddress(addresses[name]); } // Alice mines three blocks, each rewards her with 50 spendable BTC From cd2095bc4613ebd706c8b1b9142646bcd1e328a2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 15:00:29 +0100 Subject: [PATCH 300/540] Use addresses and keyrings from variables --- test/spv_node.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index b3c7a7e..9031639 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -223,8 +223,9 @@ describe("SPVNode", () => { var blockCount = 3; var coinbaseHashes = []; for(let i = 0; i < blockCount; i++) { - var block = await testHelpers.mineBlock(miner, - minerWallets["alice"].getAddress("base58")); + var block = await testHelpers.mineBlock( + miner, addresses["alice"] + ); coinbaseHashes.push(block.txs[0].hash()); await testHelpers.delay(500); } @@ -234,14 +235,14 @@ describe("SPVNode", () => { outputs = []; for (name in minerNames) { outputs.push(testHelpers.getP2PKHOutput( - minerWallets[name].getAddress("base58"), - sendAmount * consensus.COIN)); + addresses[name], sendAmount * consensus.COIN + )); } for (name in spvNames) { outputs.push(testHelpers.getP2PKHOutput( - spvWallets[name].getAddress("base58"), - sendAmount * consensus.COIN)); + addresses[name], sendAmount * consensus.COIN + )); } // We have to use a change output, because transactions with too large a fee are @@ -250,11 +251,9 @@ describe("SPVNode", () => { var changeAmount = 50 * blockCount - sendAmount * (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; if (changeAmount >= 0.01) { - var alicePrivateKey = await minerWallets["alice"].getPrivateKey( - minerWallets["alice"].getAddress("base58"), "secret"); outputs.push(new Output({ script: Script.fromPubkeyhash(bcoin.crypto.hash160( - alicePrivateKey.publicKey)), + rings["alice"].publicKey)), value: changeAmount * consensus.COIN })); } @@ -266,7 +265,7 @@ describe("SPVNode", () => { var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); - var signedCount = mtx.sign(alicePrivateKey); + var signedCount = mtx.sign(rings["alice"]); assert(signedCount === blockCount); assert(await mtx.verify()); From 41806afc2cd32740d68ceb395f498d054de25bf4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:06:58 +0100 Subject: [PATCH 301/540] Remove getTX() from spv and full nodes --- flow-typed/npm/bcoin_vx.x.x.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 5c78ced..93a342c 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -12,7 +12,6 @@ declare class bcoin$FullNode { chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; - getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } @@ -23,7 +22,6 @@ declare class bcoin$SPVNode { chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; - getTX(hash : Hash) : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } From b096b6fec43fbd7320fa4b8a9b1449b2063a3245 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:07:32 +0100 Subject: [PATCH 302/540] Define TXRecord and use it in wallet.getTX() --- flow-typed/npm/bcoin_vx.x.x.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 93a342c..e97c925 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -36,7 +36,7 @@ declare class bcoin$WalletDB { } declare class bcoin$Wallet { - getTX(hash : Hash) : Promise; + getTX(hash : Hash) : Promise; } declare class bcoin$Pool { @@ -77,6 +77,10 @@ declare class bcoin$TX { getOutputValue() : number; } +declare class bcoin$TXRecord { + tx : bcoin$TX; + hash : Hash; +} declare class bcoin$MTX { inputs : bcoin$Input[]; From e6c0143a93ec979e4f496db193e415a7e1acff8f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:08:23 +0100 Subject: [PATCH 303/540] Stop using local wallet --- src/trust_is_risk.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index d754351..3a00695 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -147,26 +147,13 @@ class TrustIsRisk { async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, - fee : ?number) + wallet : bcoin$Wallet, fee : ?number) : Promise { assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this if (origin === dest) throw new Error("Can not increase self-trust."); - var walletDB : bcoin$WalletDB = new WalletDB({ - network: this.node.network, - db: "memory", - client: new bcoin.node.NodeClient(this.node) - }); - await walletDB.open(); - await walletDB.connect(); - var wallet : bcoin$Wallet = await walletDB.create({ - id: "local", - witness: false, - type: "pubkeyhash" - }); - var hash : Hash = outpoint.hash; if (!this.node.pool.spvFilter.test(outpoint.hash)) { this.node.pool.watchOutpoint(outpoint); From 64257f97d8a04aa0aa1abe685a0071f379b71a49 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:09:12 +0100 Subject: [PATCH 304/540] Use entire keyring instead of private key --- src/trust_is_risk.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 3a00695..5aaeb6f 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -145,13 +145,13 @@ class TrustIsRisk { return mtx; } - async ccreateTrustIncreasingMTX(origin : Key, dest : Key, + async ccreateTrustIncreasingMTX(origin : bcoin$KeyRing, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, wallet : bcoin$Wallet, fee : ?number) : Promise { assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this - if (origin === dest) + if (origin.getPublicKey() === dest) throw new Error("Can not increase self-trust."); var hash : Hash = outpoint.hash; @@ -163,8 +163,8 @@ class TrustIsRisk { var tx : bcoin$TX = await wallet.getTX(hash); if (!tx) throw new Error("Could not find tx"); - var originKeyRing = KeyRing.fromPrivate(origin); - var originPubKey = originKeyRing.getPublicKey(); + //var originKeyRing = KeyRing.fromPrivate(origin); + var originPubKey = origin.getPublicKey(); var mtx = new MTX({ outputs: [ @@ -188,7 +188,7 @@ class TrustIsRisk { mtx.addInput(Input.fromOutpoint(outpoint)); - var signedCount = mtx.sign(originKeyRing); + var signedCount = mtx.sign(origin); assert(signedCount === 1); return mtx; From 20e6feb44b924aaea0d09332dcd53b51fedba87f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:09:42 +0100 Subject: [PATCH 305/540] Get tx from the TXRecord --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 5aaeb6f..9b69714 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -160,7 +160,7 @@ class TrustIsRisk { var watcher = new helpers.NodeWatcher(this.node); await watcher.waitForTX(hash); } - var tx : bcoin$TX = await wallet.getTX(hash); + var tx : bcoin$TX = (await wallet.getTX(hash)).tx; if (!tx) throw new Error("Could not find tx"); //var originKeyRing = KeyRing.fromPrivate(origin); From d5431e333a07d37b3706251a676c4ba9517a3693 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:09:53 +0100 Subject: [PATCH 306/540] Add a console.log for debug --- src/trust_is_risk.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 9b69714..6d1ba7c 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -189,6 +189,7 @@ class TrustIsRisk { mtx.addInput(Input.fromOutpoint(outpoint)); var signedCount = mtx.sign(origin); + console.log(signedCount); assert(signedCount === 1); return mtx; From 58cb9a03d445147806ba4cef65fc7815eca56ec2 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:10:05 +0100 Subject: [PATCH 307/540] add missing eve --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index 9031639..998afb2 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -178,6 +178,7 @@ describe("SPVNode", () => { var minerNames = { "alice": "alice", "bob": "bob", + "eve": "eve", "frank": "frank", "george": "george" }; From d285949ff3f4d32403928699c419b3670b1c07d1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:12:42 +0100 Subject: [PATCH 308/540] Use local variables instead of fixtures --- test/spv_node.js | 106 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 34 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 998afb2..c7d5766 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -276,53 +276,80 @@ describe("SPVNode", () => { await minerWatcher.waitForTX(tx); await spvWatcher.waitForTX(tx); - prevout = {}; - fixtures.names.forEach((name) => { + for(name in minerNames) { + minerWallets[name].db.addTX(tx); + } + + for(name in spvNames) { + spvWallets[name].db.addTX(tx); + } + + var prevout = {}; + var counter = 0; + + for (name in minerNames) { + prevout[name] = { + hash: tx.hash().toString("hex"), + index: counter++ + }; + } + + for (name in spvNames) { prevout[name] = { hash: tx.hash().toString("hex"), - index: fixtures.names.indexOf(name) + index: counter++ }; - }); + } // Alice mines another block - await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey())); + await testHelpers.mineBlock(miner, addresses["alice"]); await testHelpers.delay(500); var graph = require("./graphs/nobodyLikesFrank.json"); for (var origin in graph) { + let node = null; + let watcher = null; + let originWallet = null; + let destWallet = null; + + if (spvNames[origin]) { + console.log("2", origin); + node = spvNode; + watcher = spvWatcher; + originWallet = spvWallets[origin]; + } + + else { + console.log("5", origin); + node = miner; + watcher = minerWatcher; + originWallet = minerWallets[origin]; + } + var neighbours = graph[origin]; + for (var dest in neighbours) { var value = neighbours[dest]; if (!value || value < 1) continue; - let node = null; - let watcher = null; - if (spvNames[origin]) { - console.log("2"); - node = spvNode; - watcher = spvWatcher; - } - else { - console.log("4"); - node = miner; - watcher = minerWatcher; - } + destWallet = (spvNames[dest]) ? spvWallets[dest] + : minerWallets[dest]; let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); let mtx = null; if (node.spv) { mtx = await node.trust.ccreateTrustIncreasingMTX( - fixtures.keyRings[origin].getPrivateKey(), - fixtures.keyRings[dest].getPublicKey(), + rings[origin], + rings[dest].getPublicKey(), outpoint, - value * consensus.COIN); + value * consensus.COIN, + spvWallets[origin]); } else { // if full node mtx = await node.trust.createTrustIncreasingMTX( - fixtures.keyRings[origin].getPrivateKey(), - fixtures.keyRings[dest].getPublicKey(), + rings[origin].getPrivateKey(), + rings[dest].getPublicKey(), outpoint, value * consensus.COIN); } @@ -332,6 +359,9 @@ describe("SPVNode", () => { let tx = mtx.toTX(); node.sendTX(tx); await watcher.waitForTX(); + + originWallet.db.addTX(tx); + destWallet.db.addTX(tx); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } @@ -339,7 +369,7 @@ describe("SPVNode", () => { // Alice mines yet another block await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey())); + rings["alice"].getPublicKey())); await testHelpers.delay(500); }); @@ -378,29 +408,37 @@ describe("SPVNode", () => { }); it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { - var mtxs = miner.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), - fixtures.keyRings.bob.getPublicKey(), 3 * COIN); + var mtxs = miner.trust.createTrustDecreasingMTXs( + rings["alice"].getPrivateKey(), + rings["bob"].getPublicKey(), 3 * COIN + ); mtxs.length.should.equal(1); var mtx = mtxs[0]; should(await mtx.verify()); miner.sendTX(mtx.toTX()); - await testHelpers.delay(750); - should(miner.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); - should(spvNode.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + await testHelpers.delay(3000); + should(miner.trust.getIndirectTrust(addresses["alice"], + addresses["bob"])).equal(7 * COIN); + should(spvNode.trust.getIndirectTrust(addresses["alice"], + addresses["bob"])).equal(7 * COIN); - mtxs = spvNode.trust.createTrustDecreasingMTXs(fixtures.keyRings.dave.getPrivateKey(), - fixtures.keyRings.eve.getPublicKey(), 2 * COIN); + mtxs = spvNode.trust.createTrustDecreasingMTXs( + rings["dave"].getPrivateKey(), + rings["eve"].getPublicKey(), 2 * COIN + ); mtxs.length.should.equal(1); mtx = mtxs[0]; should(await mtx.verify()); spvNode.sendTX(mtx.toTX()); - await testHelpers.delay(750); - should(miner.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); - should(spvNode.trust.getIndirectTrust(addresses.dave, addresses.eve)).equal(10 * COIN); + await testHelpers.delay(3000); + should(miner.trust.getIndirectTrust(addresses["dave"], + addresses["eve"])).equal(10 * COIN); + should(spvNode.trust.getIndirectTrust(addresses["dave"], + addresses["eve"])).equal(10 * COIN); }); }); From 71ef9b0c64b38641653a6bde47175357c0df1a6f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 24 Oct 2017 19:13:09 +0100 Subject: [PATCH 309/540] Improve indentation --- test/spv_node.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index c7d5766..b39549b 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -335,7 +335,8 @@ describe("SPVNode", () => { destWallet = (spvNames[dest]) ? spvWallets[dest] : minerWallets[dest]; - let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); + let outpoint = new Outpoint(prevout[origin].hash, + prevout[origin].index); let mtx = null; if (node.spv) { From 9c21632dc57e1a8e03e634c462f2fb58b229d29f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 25 Oct 2017 00:05:10 +0100 Subject: [PATCH 310/540] Drop originPubKey, use method on keyring --- src/trust_is_risk.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 6d1ba7c..cd5903a 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -163,14 +163,11 @@ class TrustIsRisk { var tx : bcoin$TX = (await wallet.getTX(hash)).tx; if (!tx) throw new Error("Could not find tx"); - //var originKeyRing = KeyRing.fromPrivate(origin); - var originPubKey = origin.getPublicKey(); - var mtx = new MTX({ outputs: [ new Output({ script: bcoin.script.fromMultisig(1, 3, - [originPubKey, dest, this.fakePubKey]), + [origin.getPublicKey(), dest, this.fakePubKey]), value: trustAmount }) ] @@ -181,7 +178,8 @@ class TrustIsRisk { if (changeAmount) { mtx.addOutput(new Output({ script: bcoin.script.fromPubkeyhash( - bcoin.crypto.hash160(originPubKey)), + bcoin.crypto.hash160(origin.getPublicKey()) + ), value: changeAmount })); } From 45ccfff610c175eaaf3a05469446377891899dcd Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 25 Oct 2017 01:24:35 +0100 Subject: [PATCH 311/540] Remove console.log from src/trust_is_risk --- src/trust_is_risk.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index cd5903a..1336688 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -187,7 +187,6 @@ class TrustIsRisk { mtx.addInput(Input.fromOutpoint(outpoint)); var signedCount = mtx.sign(origin); - console.log(signedCount); assert(signedCount === 1); return mtx; From 87bd128ced5d3941618d3cf0e29cadac5230fdf8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 25 Oct 2017 21:09:28 +0300 Subject: [PATCH 312/540] Use private key instead of keyring --- src/trust_is_risk.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 1336688..e40018b 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -145,13 +145,13 @@ class TrustIsRisk { return mtx; } - async ccreateTrustIncreasingMTX(origin : bcoin$KeyRing, dest : Key, + async ccreateTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, trustAmount : number, wallet : bcoin$Wallet, fee : ?number) : Promise { assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this - if (origin.getPublicKey() === dest) + if (origin === dest) throw new Error("Can not increase self-trust."); var hash : Hash = outpoint.hash; @@ -162,12 +162,13 @@ class TrustIsRisk { } var tx : bcoin$TX = (await wallet.getTX(hash)).tx; if (!tx) throw new Error("Could not find tx"); + var originKeyRing = KeyRing.fromPrivate(origin); + var originPubKey = originKeyRing.getPublicKey(); var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, - [origin.getPublicKey(), dest, this.fakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), value: trustAmount }) ] @@ -177,16 +178,14 @@ class TrustIsRisk { assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash( - bcoin.crypto.hash160(origin.getPublicKey()) - ), + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), value: changeAmount })); } mtx.addInput(Input.fromOutpoint(outpoint)); - var signedCount = mtx.sign(origin); + var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); return mtx; From 94c8a6bf557902c736d434559a3e06d00cbe2e4e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 25 Oct 2017 21:10:06 +0300 Subject: [PATCH 313/540] Use coin semantics --- src/trust_is_risk.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index e40018b..bd4eae4 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -151,17 +151,13 @@ class TrustIsRisk { : Promise { assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this + var coin = await bcoin.coin.fromTX( + (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 + ); + if (!coin) throw new Error("Could not find coin"); if (origin === dest) throw new Error("Can not increase self-trust."); - var hash : Hash = outpoint.hash; - if (!this.node.pool.spvFilter.test(outpoint.hash)) { - this.node.pool.watchOutpoint(outpoint); - var watcher = new helpers.NodeWatcher(this.node); - await watcher.waitForTX(hash); - } - var tx : bcoin$TX = (await wallet.getTX(hash)).tx; - if (!tx) throw new Error("Could not find tx"); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); @@ -174,7 +170,7 @@ class TrustIsRisk { ] }); - var changeAmount = tx.getOutputValue() - trustAmount - fee; + var changeAmount = coin.value - trustAmount - fee; assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ @@ -183,7 +179,9 @@ class TrustIsRisk { })); } - mtx.addInput(Input.fromOutpoint(outpoint)); + mtx.addCoin(coin); + var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); + assert(success); var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); From 02fe6c625a05cd15617c93563dc6a6a3fd2083fb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 25 Oct 2017 21:10:40 +0300 Subject: [PATCH 314/540] Remove testnet logic --- test/helpers.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index d481251..220a4fa 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -29,24 +29,6 @@ var testHelpers = { return walletDB.create(options); }, - testnetCreateWallet: async (walletDB, id) => { - const keys = { - "spvSender": "cQzGHhucP26iPJf4fFSpLBXBN7V99mx7hBXDXm3FfQAEz9UKiDHT", - "spvReceiver": "cSapdQj9U6XwhePBjv3YeQrctodr2imWm2dV1u83e1SWdBFUuVo1", - "minerSender": "cUw1SoP2DBd6RufEs2bV7nHwoUFi382h5SpaLtBy9zXrjGqs9S3U", // this has the faucet coins - "minerReceiver": "cMjHoh7LRspQSVzJ6wps5XSGvn7jdidj2QhCRXDmaW48Pm9SGqCN" - }; - var options = { - id, - passphrase: "secret", - witness: false, - type: "pubkeyhash", - master: keys.id - }; - - return walletDB.create(options); - }, - mineBlock: async (node, rewardAddress) => { var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); await node.chain.add(block); From da3b02392b24f00a5895fbed71560a248f25af47 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 25 Oct 2017 21:11:55 +0300 Subject: [PATCH 315/540] Use private key instead of keyring --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index b39549b..3aa6d3d 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -341,7 +341,7 @@ describe("SPVNode", () => { let mtx = null; if (node.spv) { mtx = await node.trust.ccreateTrustIncreasingMTX( - rings[origin], + rings[origin].getPrivateKey(), rings[dest].getPublicKey(), outpoint, value * consensus.COIN, From c1eab882305a16943163d48dfd88af5a41904fd3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 26 Oct 2017 16:53:30 +0300 Subject: [PATCH 316/540] Add static method fromTX() to bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index e97c925..a8b9aea 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -140,6 +140,8 @@ declare class bcoin$KeyRing { declare class bcoin$Coin extends bcoin$Output { script : bcoin$Script; value : number; + + static fromTX(tx : bcoin$TX, index : number, height : number) : bcoin$Coin; } declare module 'bcoin' { From f29d558aeb58538c56fa516a97e1cc7b02ef984d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 26 Oct 2017 16:53:52 +0300 Subject: [PATCH 317/540] Use bcoin.primitives.Coin instead of bcoin.coin --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index bd4eae4..7d047c9 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -151,7 +151,7 @@ class TrustIsRisk { : Promise { assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this - var coin = await bcoin.coin.fromTX( + var coin = await bcoin.primitives.Coin.fromTX( (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 ); if (!coin) throw new Error("Could not find coin"); From cf5c9054e963c1529f027ac95e7acd715846d495 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 27 Oct 2017 11:31:11 +0300 Subject: [PATCH 318/540] Add missing await before WalletDB.addTX() --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 3aa6d3d..1bdee7a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -361,8 +361,8 @@ describe("SPVNode", () => { node.sendTX(tx); await watcher.waitForTX(); - originWallet.db.addTX(tx); - destWallet.db.addTX(tx); + await originWallet.db.addTX(tx); + await destWallet.db.addTX(tx); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } From 70fed11251b928a97e1807b4578e9f3cef0dd902 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 28 Oct 2017 12:46:16 +0300 Subject: [PATCH 319/540] Add network data to generalize pubKeyToEntity() Using Address.fromHash() without a network argument returns a main net address, which is not always desired. Thus pubKeyToEntity() now takes the type of network as an argument and passes it to Address.fromHash(). All cases where this function is used are expanded with the new input. Additionally, the DirectTrust class is expanded with the network property for use in pubKeyToEntity() calls. --- src/direct_trust.js | 10 +++++++--- src/helpers.js | 5 +++-- src/trust_is_risk.js | 19 ++++++++++++++----- test/full_node.js | 10 +++++++--- test/spv_node.js | 7 ++++--- test/trust_is_risk.js | 5 +++-- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/direct_trust.js b/src/direct_trust.js index 3ed4fcf..5f00dc1 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -14,7 +14,9 @@ type DirectTrustOptions = { script? : bcoin$Script, prev? : DirectTrust, - next? : DirectTrust + next? : DirectTrust, + + network? : string } class DirectTrust { @@ -72,11 +74,11 @@ class DirectTrust { } getOriginEntity() : Entity { - return helpers.pubKeyToEntity(this.origin); + return helpers.pubKeyToEntity(this.origin, this.network); } getDestEntity() : Entity { - return helpers.pubKeyToEntity(this.dest); + return helpers.pubKeyToEntity(this.dest, this.network); } spend(next : DirectTrust) : void { @@ -94,6 +96,8 @@ class DirectTrust { dest: this.dest, amount: 0, + network: this.network, + prev: this, txHash, }); diff --git a/src/helpers.js b/src/helpers.js index 17d8a5a..501ecaf 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -104,8 +104,9 @@ class NodeWatcher { var helpers = { NodeWatcher : NodeWatcher, - pubKeyToEntity: (key : Key) : Entity => { - return Address.fromHash(bcoin.crypto.hash160(key)).toBase58(); + pubKeyToEntity: (key : Key, network : string) : Entity => { + return Address.fromHash(bcoin.crypto.hash160(key), + Address.types.PUBKEYHASH, -1, network).toBase58(); }, delay: async (milliseconds : number) => { diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 7d047c9..f2916e1 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -211,8 +211,12 @@ class TrustIsRisk { destKeyRing = KeyRing.fromPrivate(dest); } - var originAddress = helpers.pubKeyToEntity(originKeyRing.getPublicKey()); - var destAddress = helpers.pubKeyToEntity(destKeyRing.getPublicKey()); + var originAddress = helpers.pubKeyToEntity( + originKeyRing.getPublicKey(), this.node.network + ); + var destAddress = helpers.pubKeyToEntity( + destKeyRing.getPublicKey(), this.node.network + ); if (originAddress === destAddress) throw new Error("Can't decrease self-trust"); @@ -312,14 +316,15 @@ class TrustIsRisk { // Returns an array of the corresponding DirectTrust objects. // If the recipient parameter is set, it will limit the results only to the outputs being sent to // the recipient. - searchForDirectTrustOutputs(tx : bcoin$TX, origin : Entity, recipient : ?Entity) : DirectTrust[] { + searchForDirectTrustOutputs(tx : bcoin$TX, origin : Entity, + recipient : ?Entity) : DirectTrust[] { var directTrusts = tx.outputs.map((output, outputIndex) => this.parseOutputAsDirectTrust(tx, outputIndex, origin) ).filter(Boolean); // filter out nulls if (recipient) { directTrusts = directTrusts.filter((trust) => - helpers.pubKeyToEntity(trust.dest) === recipient); + helpers.pubKeyToEntity(trust.dest, this.node.network) === recipient); } return directTrusts; @@ -336,7 +341,9 @@ class TrustIsRisk { var output = tx.outputs[outputIndex]; if (output.getType() !== "multisig") return null; - var entities = [1, 2].map((i) => helpers.pubKeyToEntity(output.script.get(i))); + var entities = [1, 2].map((i) => helpers.pubKeyToEntity( + output.script.get(i), this.node.network + )); if (entities[0] === entities[1]) return null; var originPubKey, destPubKey; @@ -355,6 +362,8 @@ class TrustIsRisk { dest: destPubKey, amount: Number(output.value), + network: this.node.network, + txHash, outputIndex, script: output.script diff --git a/test/full_node.js b/test/full_node.js index db2d1f0..b0d93c0 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -98,7 +98,9 @@ describe("FullNode", () => { addresses = {}; for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { - addresses[name] = helpers.pubKeyToEntity(keyRing.getPublicKey()); + addresses[name] = helpers.pubKeyToEntity( + keyRing.getPublicKey(), node.network + ); } // Alice mines three blocks, each rewards her with 50 spendable BTC @@ -157,7 +159,8 @@ describe("FullNode", () => { // Alice mines another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey())); + fixtures.keyRings.alice.getPublicKey(), node.network + )); await testHelpers.delay(500); var graph = require("./graphs/nobodyLikesFrank.json"); @@ -187,7 +190,8 @@ describe("FullNode", () => { // Alice mines yet another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey())); + fixtures.keyRings.alice.getPublicKey(), node.network + )); await testHelpers.delay(500); }); diff --git a/test/spv_node.js b/test/spv_node.js index 1bdee7a..62b1063 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -202,7 +202,7 @@ describe("SPVNode", () => { minerWallets[name].getAddress("base58"), "secret" ); addresses[name] = helpers.pubKeyToEntity( - rings[name].getPublicKey() + rings[name].getPublicKey(), miner.network ); } @@ -214,7 +214,7 @@ describe("SPVNode", () => { spvWallets[name].getAddress("base58"), "secret" ); addresses[name] = helpers.pubKeyToEntity( - rings[name].getPublicKey() + rings[name].getPublicKey(), spvNode.network ); spvNode.pool.watchAddress(addresses[name]); } @@ -370,7 +370,8 @@ describe("SPVNode", () => { // Alice mines yet another block await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( - rings["alice"].getPublicKey())); + rings["alice"].getPublicKey(), miner.network + )); await testHelpers.delay(500); }); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 43bb468..847b0ee 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -214,8 +214,9 @@ describe("TrustIsRisk", () => { var trustOutput = mtx.outputs[0]; trustOutput.getType().should.equal("multisig"); - [1, 2].map((i) => helpers.pubKeyToEntity(trustOutput.script.get(i))).sort() - .should.deepEqual([alice, bob].sort()); + [1, 2].map((i) => helpers.pubKeyToEntity( + trustOutput.script.get(i), tir.network + )).sort().should.deepEqual([alice, bob].sort()); trustOutput.script.get(3).should.deepEqual(tir.fakePubKey); trustOutput.value.should.equal(100 * COIN); From 7d6484bc3020d00d28291aac70fecb9b53605c29 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 28 Oct 2017 13:07:52 +0300 Subject: [PATCH 320/540] Improve indentation and appearance --- src/direct_trust.js | 2 +- src/trust_is_risk.js | 7 ++++--- test/full_node.js | 6 ++++-- test/spv_node.js | 1 + test/trust_is_risk.js | 18 ++++++++++++------ 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/direct_trust.js b/src/direct_trust.js index 5f00dc1..86735c0 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -99,7 +99,7 @@ class DirectTrust { network: this.network, prev: this, - txHash, + txHash }); } } diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index f2916e1..17ba39d 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -196,7 +196,8 @@ class TrustIsRisk { // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. - createTrustDecreasingMTXs(origin : Key, dest : Key, trustDecreaseAmount : number, payee : ?Entity, + createTrustDecreasingMTXs(origin : Key, dest : Key, + trustDecreaseAmount : number, payee : ?Entity, steal : ?boolean, fee : ?number) : bcoin$MTX[] { if (steal === undefined) steal = false; @@ -335,8 +336,8 @@ class TrustIsRisk { && (output.getAddress().toBase58() === origin); } - parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, origin : Entity) - : (DirectTrust | null) { + parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, + origin : Entity) : (DirectTrust | null) { var txHash = tx.hash().toString("hex"); var output = tx.outputs[outputIndex]; if (output.getType() !== "multisig") return null; diff --git a/test/full_node.js b/test/full_node.js index b0d93c0..9b11d18 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -213,8 +213,10 @@ describe("FullNode", () => { }); it("after decreasing some trusts computes trusts correctly", async () => { - var mtxs = node.trust.createTrustDecreasingMTXs(fixtures.keyRings.alice.getPrivateKey(), - fixtures.keyRings.bob.getPublicKey(), 3 * COIN); + var mtxs = node.trust.createTrustDecreasingMTXs( + fixtures.keyRings.alice.getPrivateKey(), + fixtures.keyRings.bob.getPublicKey(), 3 * COIN + ); mtxs.length.should.equal(1); var mtx = mtxs[0]; diff --git a/test/spv_node.js b/test/spv_node.js index 62b1063..3f52144 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -358,6 +358,7 @@ describe("SPVNode", () => { assert(await mtx.verify()); let tx = mtx.toTX(); + node.sendTX(tx); await watcher.waitForTX(); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 847b0ee..5d969ec 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -287,23 +287,29 @@ describe("TrustIsRisk", () => { }; it("creates correct trust decreasing transactions", () => { - var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN); + var mtxs = tir.createTrustDecreasingMTXs( + addr.alice.privKey, addr.bob.pubKey, 82 * COIN + ); checkMTXs(mtxs, alice); }); it("creates correct trust stealing transactions", () => { - var mtxs = tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie); + var mtxs = tir.createTrustDecreasingMTXs( + addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie + ); checkMTXs(mtxs, charlie); }); it("throws when trying to decrease self-trust", () => { - should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.alice.pubKey, 10 * COIN) - , /self-trust/i); + should.throws(() => tir.createTrustDecreasingMTXs( + addr.alice.privKey, addr.alice.pubKey, 10 * COIN + ), /self-trust/i); }); it("throws when there is not enough trust", () => { - should.throws(() => tir.createTrustDecreasingMTXs(addr.alice.privKey, addr.bob.pubKey, 700 * COIN) - , /insufficient trust/i); + should.throws(() => tir.createTrustDecreasingMTXs( + addr.alice.privKey, addr.bob.pubKey, 700 * COIN + ), /insufficient trust/i); }); }); From 186895f1c37863a029fae0b01d31870458b8507a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 28 Oct 2017 14:05:54 +0300 Subject: [PATCH 321/540] Declare Address.types.PUBKEYHASH with Flow --- flow-typed/npm/bcoin_vx.x.x.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index a8b9aea..92c6d21 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -63,8 +63,12 @@ declare class bcoin$PeerList { } declare class bcoin$Address { - toBase58() : string; hash : Buffer; + static types : { + PUBKEYHASH : number + }; + + toBase58() : string; static fromHash(Hash) : bcoin$Address; static fromBase58(string) : bcoin$Address; } From 581057f73f202ac5fbc18b38797803390193cbe5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 28 Oct 2017 14:07:05 +0300 Subject: [PATCH 322/540] Declare "network" occurences as bcoin$Network --- src/direct_trust.js | 4 +++- src/helpers.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/direct_trust.js b/src/direct_trust.js index 86735c0..a28939c 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -16,7 +16,7 @@ type DirectTrustOptions = { prev? : DirectTrust, next? : DirectTrust, - network? : string + network? : bcoin$Network } class DirectTrust { @@ -34,6 +34,8 @@ class DirectTrust { prev : (DirectTrust | null) next : (DirectTrust | null) + network : bcoin$Network + constructor(options : DirectTrustOptions) { this.outputIndex = null; this.script = null; diff --git a/src/helpers.js b/src/helpers.js index 501ecaf..89b0a34 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -104,7 +104,7 @@ class NodeWatcher { var helpers = { NodeWatcher : NodeWatcher, - pubKeyToEntity: (key : Key, network : string) : Entity => { + pubKeyToEntity: (key : Key, network : bcoin$Network) : Entity => { return Address.fromHash(bcoin.crypto.hash160(key), Address.types.PUBKEYHASH, -1, network).toBase58(); }, From 7c521c2b7485ce08252a083fcb1e27fb3e40520a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 28 Oct 2017 14:53:07 +0300 Subject: [PATCH 323/540] Use helpers.pubKeyToEntity() method --- test/full_node.js | 7 +++---- test/trust_is_risk.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 9b11d18..03b1b0b 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -116,10 +116,9 @@ describe("FullNode", () => { // Alice sends 20 BTC to everyone (including herself) via P2PKH var sendAmount = 20; var outputs = fixtures.names.map((name) => { - return testHelpers.getP2PKHOutput( - Address.fromHash(bcoin.crypto.hash160(fixtures.keyRings[name].getPublicKey())) - .toBase58(), - sendAmount * consensus.COIN); + return testHelpers.getP2PKHOutput(helpers.pubKeyToEntity( + fixtures.keyRings[name].getPublicKey(), node.network + ), sendAmount * consensus.COIN); }); // We have to use a change output, because transaction with too large a fee are considered diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 5d969ec..162bdf3 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -25,7 +25,7 @@ describe("TrustIsRisk", () => { addr[name] = {}; addr[name].pubKey = pubKey; addr[name].privKey = privKey; - addr[name].base58 = bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(pubKey)).toString(); + addr[name].base58 = helpers.pubKeyToEntity(pubKey); } // Add base58 address variables to scope. From 059824304d8b8b097b6626eaa675c85c0e3d5a05 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 29 Oct 2017 11:39:07 +0200 Subject: [PATCH 324/540] Remove redundant empty line --- test/full_node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/full_node.js b/test/full_node.js index 03b1b0b..99ae434 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -18,7 +18,6 @@ require("should-sinon"); const COIN = consensus.COIN; - describe("FullNode", () => { var node = null; var walletDB = null; From 6bc02c56e7e9c3a6a1f471731490c69aab38acb7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 29 Oct 2017 11:39:34 +0200 Subject: [PATCH 325/540] Set regtest when requiring bcoin --- test/full_node.js | 2 +- test/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 99ae434..d83d2e3 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -1,6 +1,6 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); -var bcoin = require("bcoin"); +var bcoin = require("bcoin").set("regtest"); var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; diff --git a/test/spv_node.js b/test/spv_node.js index 3f52144..688a27c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -1,6 +1,6 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); -var bcoin = require("bcoin"); +var bcoin = require("bcoin").set("regtest"); var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; From 2c78eef9273efebabcee1a7ead94bb2941193181 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 29 Oct 2017 12:28:51 +0200 Subject: [PATCH 326/540] Get network from options instead of hardcode --- test/full_node.js | 3 ++- test/helpers.js | 2 +- test/spv_node.js | 4 ++-- test/trust_is_risk.js | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index d83d2e3..2f63ef2 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -34,7 +34,8 @@ describe("FullNode", () => { beforeEach("get node", async () => { node = new Trust.FullNode({ - network: "regtest", passphrase: "secret" + network: bcoin.network.get().toString(), + passphrase: "secret" }); await node.open(); diff --git a/test/helpers.js b/test/helpers.js index 220a4fa..eb8643a 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,7 +7,7 @@ var assert = require("assert"); var testHelpers = { getWalletDB: async (node) => { var walletDB = new WalletDB({ - network: "regtest", + network: node.network, db: "memory", client: new bcoin.node.NodeClient(node) }); diff --git a/test/spv_node.js b/test/spv_node.js index 688a27c..31edada 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -37,7 +37,7 @@ describe("SPVNode", () => { beforeEach("get nodes", () => { miner = new Trust.FullNode({ - network: "regtest", + network: bcoin.network.get().toString(), port: 48448, bip37: true, listen: true, @@ -45,7 +45,7 @@ describe("SPVNode", () => { }); spvNode = new Trust.SPVNode({ - network: "regtest", + network: bcoin.network.get().toString(), port: 48445, passphrase: "secret", // logConsole: true, diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 162bdf3..579bd63 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -36,7 +36,7 @@ describe("TrustIsRisk", () => { var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; beforeEach(() => { - node = new bcoin.fullnode({}); + node = new bcoin.fullnode({network: bcoin.network.get().toString()}); tir = new Trust.TrustIsRisk(node); trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); From 303ca289dfd0779cd9520482dcb3aadaa401a987 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 31 Oct 2017 02:33:24 +0000 Subject: [PATCH 327/540] Circumvent bcoin bug in pool.hasTX() --- test/helpers.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index eb8643a..1c9f9b5 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -166,9 +166,16 @@ class NodeWatcher { await new Promise((resolve, reject) => { var check = (() => { // This breaks node.pool.on("tx", ...) - if (this.node.pool.hasTX(tx.hash().toString("hex"))) - resolve(); - else setTimeout(check, 100); + if (this.node.spv) { + if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) + resolve(); + else setTimeout(check, 100); + } + else { // this is not an SPV node + if (this.node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + } }).bind(this); check(); From 80f57a28ad9404b3ba038d2dee14889a6d1d64e0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 31 Oct 2017 02:34:08 +0000 Subject: [PATCH 328/540] Reorder beforeEach() actions --- test/spv_node.js | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 31edada..c2df267 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -35,15 +35,7 @@ describe("SPVNode", () => { Trust.TrustIsRisk.prototype.addTX.restore(); }); - beforeEach("get nodes", () => { - miner = new Trust.FullNode({ - network: bcoin.network.get().toString(), - port: 48448, - bip37: true, - listen: true, - passphrase: "secret" - }); - + beforeEach("connect SPV node and wallet", async () => { spvNode = new Trust.SPVNode({ network: bcoin.network.get().toString(), port: 48445, @@ -52,31 +44,30 @@ describe("SPVNode", () => { // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); - }); - - beforeEach("open nodes", async () => { - await miner.open(); await spvNode.open(); - }); - - beforeEach("get walletDBs", async () => { - minerWalletDB = await testHelpers.getWalletDB(miner); spvWalletDB = await testHelpers.getWalletDB(spvNode); + await spvNode.connect(); }); - beforeEach("connect nodes", async () => { - // The spv node must connect BEFORE the full node - // in order for the spv node to correctly receive txs - await spvNode.connect(); + beforeEach("connect full node and wallet", async () => { + miner = new Trust.FullNode({ + network: bcoin.network.get().toString(), + port: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + await miner.open(); + minerWalletDB = await testHelpers.getWalletDB(miner); await miner.connect(); }); - beforeEach("start syncing nodes", () => { + beforeEach("start syncing", () => { miner.startSync(); spvNode.startSync(); }); - beforeEach("get watchers", () => { + beforeEach("get watchers", async () => { minerWatcher = new testHelpers.NodeWatcher(miner); spvWatcher = new testHelpers.NodeWatcher(spvNode); }); From 797700104fc6e56869c9d667759527c9244c64e0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 31 Oct 2017 02:35:52 +0000 Subject: [PATCH 329/540] Experiment with first spv test --- test/spv_node.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index c2df267..9ba3376 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -93,7 +93,7 @@ describe("SPVNode", () => { await miner.close(); }); - it("should call trust.addTX() on every transaction", async function() { + it.only("should call trust.addTX() on every transaction", async function() { var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); @@ -121,12 +121,9 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(miner2TX); - await spvWatcher.waitForTX(miner2TX); - await spvWalletDB.addTX(miner2TX); await testHelpers.delay(300); - miner.trust.addTX.should.have.been.calledOnce(); - spvNode.trust.addTX.should.have.been.calledOnce(); + Trust.TrustIsRisk.prototype.addTX.should.have.been.calledOnce(); var minerSpvTX = await minerWallet2.send({ outputs: [{ @@ -135,11 +132,13 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(minerSpvTX); - await spvWatcher.waitForTX(minerSpvTX); - await spvWalletDB.addTX(minerSpvTX); + await testHelpers.delay(6000); + spvNode.pool.getTX(spvNode.pool.peers.head(), [minerSpvTX.hash()]); + console.log(minerSpvTX.hash()); + console.log(minerSpvTX.outputs[0]); + await testHelpers.delay(6000); - miner.trust.addTX.should.have.been.calledTwice(); - spvNode.trust.addTX.should.have.been.calledTwice(); + //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); var spv2TX = await spvWallet1.send({ outputs: [{ @@ -147,12 +146,12 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); + console.log("tria"); await minerWatcher.waitForTX(spv2TX); await spvWatcher.waitForTX(spv2TX); - await minerWalletDB.addTX(spv2TX); + console.log(spvNode.pool.txFilter.test(spv2TX.hash().toString("hex"), "hex")); - miner.trust.addTX.should.have.been.calledThrice(); - spvNode.trust.addTX.should.have.been.calledThrice(); + Trust.TrustIsRisk.prototype.addTX.should.have.been.calledThrice(); var spvMinerTX = await spvWallet2.send({ outputs: [{ @@ -163,9 +162,10 @@ describe("SPVNode", () => { await minerWatcher.waitForTX(spvMinerTX); await spvWatcher.waitForTX(spvMinerTX); await minerWalletDB.addTX(spvMinerTX); + process.exit(); }); - describe.only("with the nobodyLikesFrank.json example", () => { + describe("with the nobodyLikesFrank.json example", () => { var minerNames = { "alice": "alice", "bob": "bob", From 34d2f09936cbe611c62ac969509349451e95b288 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 31 Oct 2017 11:35:03 +0000 Subject: [PATCH 330/540] Add minimal testcases They are currently not integrated with mocha and sinon --- minimal_testcases/hastx.js | 17 +++ minimal_testcases/mfull.js | 96 ++++++++++++++++ minimal_testcases/mspv.js | 151 ++++++++++++++++++++++++ minimal_testcases/regtest.js | 61 ++++++++++ minimal_testcases/sendtx.js | 93 +++++++++++++++ minimal_testcases/sign.js | 214 +++++++++++++++++++++++++++++++++++ 6 files changed, 632 insertions(+) create mode 100644 minimal_testcases/hastx.js create mode 100644 minimal_testcases/mfull.js create mode 100644 minimal_testcases/mspv.js create mode 100644 minimal_testcases/regtest.js create mode 100644 minimal_testcases/sendtx.js create mode 100644 minimal_testcases/sign.js diff --git a/minimal_testcases/hastx.js b/minimal_testcases/hastx.js new file mode 100644 index 0000000..1400a9b --- /dev/null +++ b/minimal_testcases/hastx.js @@ -0,0 +1,17 @@ +const bcoin = require("bcoin"); + +const myhash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + +var spv = new bcoin.node.SPVNode({ + network: "regtest", passphrase: "secret" +}); + +console.log("spv hasTX(), try 1:", spv.pool.hasTX(myhash)); +console.log("spv hasTX(), try 2:", spv.pool.hasTX(myhash)); + +var full = new bcoin.node.FullNode({ + network: "regtest", passphrase: "secret" +}); + +console.log("full hasTX(), try 1:", full.pool.hasTX(myhash)); +console.log("full hasTX(), try 2:", full.pool.hasTX(myhash)); diff --git a/minimal_testcases/mfull.js b/minimal_testcases/mfull.js new file mode 100644 index 0000000..ecbe517 --- /dev/null +++ b/minimal_testcases/mfull.js @@ -0,0 +1,96 @@ +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var testHelpers = require("../test/helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +var assert = require("assert"); +var fixtures = require("../test/fixtures"); + +const COIN = consensus.COIN; + +(async () => { + var node = null; + var walletDB = null; + var NodeWatcher = null; + var watcher = null; + + node = new Trust.FullNode({ + network: "regtest", passphrase: "secret" + }); + + await node.open(); + + walletDB = await testHelpers.getWalletDB(node); + + await node.connect(); + node.startSync(); + + watcher = new testHelpers.NodeWatcher(node); + + var addresses = {}, rings = fixtures.keyRings; + + for (var [name, keyRing] of Object.entries(rings)) { + addresses[name] = helpers.pubKeyToEntity( + keyRing.getPublicKey() + ); + } + + // Alice mines three blocks, each + // rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var blockCount = 3; + var coinbaseHashes = []; + for(let i = 0; i < blockCount; i++) { + var block = await testHelpers.mineBlock( + node, addresses.alice + ); + coinbaseHashes.push(block.txs[0].hash()); + await testHelpers.delay(500); + } + + // Alice sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + var outputs = fixtures.names.map((name) => { + return testHelpers.getP2PKHOutput( + Address.fromHash(bcoin.crypto.hash160( + rings[name].getPublicKey()) + ).toBase58(), + sendAmount * consensus.COIN); + }); + + // We have to use a change output, because transactions + // with too large a fee are considered invalid. + var fee = 0.01; + var changeAmount = 50 * blockCount - sendAmount * + fixtures.names.length - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + rings.alice.getPublicKey())), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all( + coinbaseHashes.map((hash) => { + return node.getCoin(hash.toString("hex"), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(rings.alice); + assert(signedCount === blockCount); + assert(await mtx.verify()); + console("success!"); + process.exit(); +})(); diff --git a/minimal_testcases/mspv.js b/minimal_testcases/mspv.js new file mode 100644 index 0000000..4748ccf --- /dev/null +++ b/minimal_testcases/mspv.js @@ -0,0 +1,151 @@ +var Trust = require("../"); +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin"); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var WalletDB = bcoin.wallet.WalletDB; +var testHelpers = require("../test/helpers"); +var consensus = require("bcoin/lib/protocol/consensus"); +var sinon = require("sinon"); +var should = require("should"); +var assert = require("assert"); + +const COIN = consensus.COIN; + +(async () => { + var spvNode = null; + var miner = null; + var spvWalletDB = null; + var minerWalletDB = null; + var spvWatcher = null; + var minerWatcher = null; + + miner = new Trust.FullNode({ + network: "regtest", + port: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + + spvNode = new Trust.SPVNode({ + network: "regtest", + port: 48445, + passphrase: "secret", + // logConsole: true, + // logLevel: "debug", + nodes: ["127.0.0.1:48448"] + }); + + await miner.open(); + await spvNode.open(); + + minerWalletDB = await testHelpers.getWalletDB(miner); + spvWalletDB = await testHelpers.getWalletDB(spvNode); + + // The spv node must connect BEFORE the full node + // in order for the spv node to correctly receive txs + await spvNode.connect(); + await miner.connect(); + + miner.startSync(); + spvNode.startSync(); + + minerWatcher = new testHelpers.NodeWatcher(miner); + spvWatcher = new testHelpers.NodeWatcher(spvNode); + + var minerNames = { + "alice": "alice", + "bob": "bob", + "eve": "eve", + "frank": "frank", + "george": "george" + }; + + var spvNames = { + "charlie": "charlie", + "dave": "dave" + }; + + var minerWallets = {}; + var spvWallets = {}; + var name = null; + + var addresses = {}, rings = {}; + + for (name in minerNames) { + minerWallets[name] = await testHelpers.createWallet( + minerWalletDB, name); + rings[name] = await minerWallets[name].getPrivateKey(minerWallets[name].getAddress("base58"), "secret"); + addresses[name] = helpers.pubKeyToEntity( + rings[name].getPublicKey() + ); + } + + for (name in spvNames) { + spvWallets[name] = await testHelpers.createWallet(spvWalletDB, name); + rings[name] = await spvWallets[name].getPrivateKey(spvWallets[name].getAddress("base58"), "secret"); + addresses[name] = helpers.pubKeyToEntity( + rings[name].getPublicKey() + ); + spvNode.pool.watchAddress(addresses[name]); + } + + // Alice mines three blocks, each rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var blockCount = 3; + var coinbaseHashes = []; + for(let i = 0; i < blockCount; i++) { + var block = await testHelpers.mineBlock( + miner, addresses["alice"] + ); + coinbaseHashes.push(block.txs[0].hash()); + await testHelpers.delay(500); + } + + // Alice sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + outputs = []; + for (name in minerNames) { + outputs.push(testHelpers.getP2PKHOutput( + addresses[name], sendAmount * consensus.COIN + )); + } + + for (name in spvNames) { + outputs.push(testHelpers.getP2PKHOutput( + addresses[name], sendAmount * consensus.COIN + )); + } + + // We have to use a change output, because transactions + // with too large a fee are considered invalid. + var fee = 0.01; + var changeAmount = 50 * blockCount - sendAmount * + (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + rings["alice"].getPublicKey())), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { + return miner.getCoin(hash.toString("hex"), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(rings["alice"]); + assert(signedCount === blockCount); + assert(await mtx.verify()); + console.log("success!"); + process.exit(); +})(); diff --git a/minimal_testcases/regtest.js b/minimal_testcases/regtest.js new file mode 100644 index 0000000..a8ddab0 --- /dev/null +++ b/minimal_testcases/regtest.js @@ -0,0 +1,61 @@ +var bcoin = require("bcoin").set("regtest"); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var consensus = require("bcoin/lib/protocol/consensus"); +var assert = require("assert"); + +var delay = async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); +}; + +(async () => { + const COIN = consensus.COIN; + consensus.COINBASE_MATURITY = 0; + await delay(100); + + var node = new bcoin.node.FullNode({ + network: "regtest", passphrase: "secret" + }); + + await node.open(); + + var walletDB = new bcoin.wallet.WalletDB({ + network: "regtest", db: "memory", + client: new bcoin.node.NodeClient(node) + }); + + await walletDB.open(); + await walletDB.connect(); + + await node.connect(); + node.startSync(); + + var wallet = await walletDB.create({ + id: "wallet", + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }); + + var block = await node.miner.mineBlock( + node.chain.tip, wallet.getAddress("base58") + ); + await node.chain.add(block); + + await delay(1000); + await wallet.send({ + outputs: [{ + value: 10 * COIN, + address: wallet.getAddress("base58") + }] + }); + console.log("success!"); + process.exit(); +})(); diff --git a/minimal_testcases/sendtx.js b/minimal_testcases/sendtx.js new file mode 100644 index 0000000..88cac33 --- /dev/null +++ b/minimal_testcases/sendtx.js @@ -0,0 +1,93 @@ +var bcoin = require("bcoin").set("regtest"); +var consensus = require("bcoin/lib/protocol/consensus"); +var WalletDB = bcoin.wallet.WalletDB; + +var delay = async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); +}; + +(async () => { + var spvNode = new bcoin.node.SPVNode({ + network: "regtest", + port: 48445, + passphrase: "secret", + nodes: ["127.0.0.1:48448"] + }); + + spvNode.on("tx", () => {console.log("spv says: TX arrived!"); process.exit();}); + + await spvNode.open(); + await spvNode.connect(); + spvNode.startSync(); + + var miner = new bcoin.node.FullNode({ + network: "regtest", + port: 48448, + bip37: true, + listen: true, + // logConsole: true, + // logLevel: "debug", + passphrase: "secret", + }); + await miner.open(); + + var minerWalletDB = await getWalletDB(miner); + var minerAlpha = await createWallet(minerWalletDB, "minerAlpha"); + spvNode.pool.watchAddress(minerAlpha.getAddress()); + + miner.on("tx", () => {console.log("full says: TX arrived!");}); + await miner.connect(); + miner.startSync(); + + await delay(1000); + // Produce a block and reward the minerAlpha, so that we have a coin to spend. + await mineBlock(miner, minerAlpha.getAddress("base58")); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + + + await delay(100); + + await minerAlpha.send({ + outputs: [{ + value: 10 * consensus.COIN, + address: minerAlpha.getAddress("base58") + }] + }); + + delay(1000); + +})(); + +var createWallet = async (walletDB, id) => { + var options = { + id, + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }; + + return walletDB.create(options); +}; + +var getWalletDB = async (node) => { + var walletDB = new bcoin.wallet.WalletDB({ + network: "regtest", + db: "memory", + client: new bcoin.node.NodeClient(node) + }); + + await walletDB.open(); + await walletDB.connect(); + + return walletDB; +}; + +var mineBlock = async (node, rewardAddress) => { + var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); + await node.chain.add(block); + return node.getBlock(node.chain.tip.hash); +}; diff --git a/minimal_testcases/sign.js b/minimal_testcases/sign.js new file mode 100644 index 0000000..73acba1 --- /dev/null +++ b/minimal_testcases/sign.js @@ -0,0 +1,214 @@ +var bcoin = require("bcoin"); +var FullNode = bcoin.node.FullNode; +var SPVNode = bcoin.node.SPVNode; +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var WalletDB = bcoin.wallet.WalletDB; +var Wallet = bcoin.wallet.Wallet; +var consensus = require("bcoin/lib/protocol/consensus"); +var assert = require("assert"); + +(async () => { +/* + * Start Setup + */ + const COIN = consensus.COIN; + + var full = new FullNode({ + network: "regtest", + port: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + + var spv = new SPVNode({ + network: "regtest", + port: 48445, + passphrase: "secret", + // logConsole: true, + // logLevel: "debug", + nodes: ["127.0.0.1:48448"] + }); + + await full.open(); + await spv.open(); + + var fullWalletDB = new WalletDB({ + network: "regtest", + db: "memory", + client: new bcoin.node.NodeClient(full) + }); + await fullWalletDB.open(); + await fullWalletDB.connect(); + + var spvWalletDB = new WalletDB({ + network: "regtest", + db: "memory", + client: new bcoin.node.NodeClient(spv) + }); + await spvWalletDB.open(); + await spvWalletDB.connect(); + + // The spv node must connect BEFORE the full node + // in order for the spv node to correctly receive txs + await spv.connect(); + await full.connect(); + + full.startSync(); + spv.startSync(); + + // var fullWatcher = new testHelpers.NodeWatcher(full); + // var spvWatcher = new testHelpers.NodeWatcher(spv); + + // var minerNames = { + // "alice": "alice", + // "bob": "bob", + // "eve": "eve", + // "frank": "frank", + // "george": "george" + // }; + + // var spvNames = { + // "charlie": "charlie", + // "dave": "dave" + // }; + + var fullWallet = await fullWalletDB.create({ + id: "full", + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }); + + var spvWallet = await spvWalletDB.create({ + id: "full", + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }); + + var fullRing = await fullWallet.getPrivateKey( + fullWallet.getAddress("base58"), "secret" + ); + var fullAddr = Address.fromHash(bcoin.crypto.hash160( + fullRing.getPublicKey())).toBase58(); + var spvRing = await spvWallet.getPrivateKey( + spvWallet.getAddress("base58"), "secret" + ); + var spvAddr = Address.fromHash(bcoin.crypto.hash160( + spvRing.getPublicKey())).toBase58(); + +/* + * End setup + */ + +/* + * Start mining and distributing + */ + + // Full mines three blocks, each rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var blockCount = 3; + var coinbaseHashes = []; + for(let i = 0; i < blockCount; i++) { + var block = await full.miner.mineBlock( + full.chain.tip, fullAddr + ); + await full.chain.add(block); + block = await full.getBlock(full.chain.tip.hash); + coinbaseHashes.push(block.txs[0].hash()); + await delay(500); + } + + // Full sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + outputs = []; + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + fullRing.getPublicKey() + )), + value: sendAmount * consensus.COIN + })); + outputs.push(new bcoin.primitives.Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + spvRing.getPublicKey() + )), + value: sendAmount * consensus.COIN + })); + + // We have to use a change output, because transactions with too large a fee are + // considered invalid. + var fee = 0.01; + var changeAmount = 50 * blockCount - sendAmount * 2 - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + fullRing.getPublicKey() + )), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { + return full.getCoin(hash.toString("hex"), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(fullRing); + assert(signedCount === blockCount); + assert(await mtx.verify()); + + var tx = mtx.toTX(); + + full.sendTX(tx); + await delay(3000); + + fullWallet.db.addTX(tx); + spvWallet.db.addTX(tx); + + /* + * End mining and distributing + */ + + let mtx2 = new MTX({ + outputs: [ new Output({ + script: Script.fromMultisig(1, 2, + [fullRing.getPublicKey(), spvRing.getPublicKey()]), + value: 19 * consensus.COIN + })] + }); + let mtx3 = new MTX({ + outputs: [ new Output({ + script: Script.fromMultisig(1, 2, + [fullRing.getPublicKey(), spvRing.getPublicKey()]), + value: 19 * consensus.COIN + })] + }); + + var coin = bcoin.coin.fromTX(tx, 0, -1); + mtx2.addCoin(await full.getCoin(tx.hash().toString("hex"), 0)); + mtx3.addCoin(coin); + + signedCount = mtx2.sign(fullRing); + assert(signedCount === 1); + signedCount = mtx3.sign(fullRing); + assert(signedCount === 1); + assert(await mtx2.verify()); + + console.log("success!"); + process.exit(); +})(); + +var delay = async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); +} From 35693d3392ae3042666557a8841e4f8252caf389 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 8 Nov 2017 20:54:59 +0000 Subject: [PATCH 331/540] Have flow ignore minimal_testcases/ directory --- .flowconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.flowconfig b/.flowconfig index ef33b81..7fbc6b4 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,6 +1,7 @@ [ignore] .*/node_modules/* .*/test/* +.*/minimal_testcases/* .*/lib/* [include] From ca868f34d57bc16054f8ffd8ce3cfee7ce61c462 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 8 Nov 2017 21:47:06 +0000 Subject: [PATCH 332/540] Fix typo --- minimal_testcases/mfull.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minimal_testcases/mfull.js b/minimal_testcases/mfull.js index ecbe517..e8c0daf 100644 --- a/minimal_testcases/mfull.js +++ b/minimal_testcases/mfull.js @@ -91,6 +91,6 @@ const COIN = consensus.COIN; var signedCount = mtx.sign(rings.alice); assert(signedCount === blockCount); assert(await mtx.verify()); - console("success!"); + console.log("success!"); process.exit(); })(); From 643a0cd15096859b636b42d5719ca3607c8aa233 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 8 Nov 2017 21:49:20 +0000 Subject: [PATCH 333/540] Add bloom.js testcase to debug node connectivity --- minimal_testcases/bloom.js | 175 +++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 minimal_testcases/bloom.js diff --git a/minimal_testcases/bloom.js b/minimal_testcases/bloom.js new file mode 100644 index 0000000..70b08ae --- /dev/null +++ b/minimal_testcases/bloom.js @@ -0,0 +1,175 @@ +var helpers = require("../lib/helpers.js"); +var bcoin = require("bcoin").set("regtest"); +var Script = bcoin.script; +var Address = bcoin.primitives.Address; +var KeyRing = bcoin.primitives.KeyRing; +var MTX = bcoin.primitives.MTX; +var Input = bcoin.primitives.Input; +var Output = bcoin.primitives.Output; +var Outpoint = bcoin.primitives.Outpoint; +var WalletDB = bcoin.wallet.WalletDB; +var consensus = require("bcoin/lib/protocol/consensus"); +var assert = require("assert"); + +const COIN = consensus.COIN; + +var spvNode = null; +var miner = null; +var spvWalletDB = null; +var minerWalletDB = null; +var spvWatcher = null; +var minerWatcher = null; + +(async () => { + spvNode = new bcoin.node.SPVNode({ + network: bcoin.network.get().toString(), + port: 48445, + passphrase: "secret", + // logConsole: true, + // logLevel: "debug", + nodes: ["127.0.0.1:48448"] + }); + await spvNode.open(); + spvWalletDB = await getWalletDB(spvNode); + await spvNode.connect(); + + miner = new bcoin.node.FullNode({ + network: bcoin.network.get().toString(), + port: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + await miner.open(); + minerWalletDB = await getWalletDB(miner); + await miner.connect(); + + miner.startSync(); + spvNode.startSync(); + + // minerWatcher = new testHelpers.NodeWatcher(miner); + // spvWatcher = new testHelpers.NodeWatcher(spvNode); + + var spvWallet1 = await createWallet(spvWalletDB, "spvWallet1"); + var spvWallet2 = await createWallet(spvWalletDB, "spvWallet2"); + + var minerWallet1 = await createWallet(minerWalletDB, "minerWallet1"); + var minerWallet2 = await createWallet(minerWalletDB, "minerWallet2"); + + spvNode.pool.watchAddress(minerWallet1.getAddress()); + spvNode.pool.watchAddress(minerWallet2.getAddress()); + + spvNode.pool.watchAddress(spvWallet1.getAddress()); + spvNode.pool.watchAddress(spvWallet2.getAddress()); + + await delay(1000); + // Produce a block and reward the minerWallet1, so that we have a coin to spend. + await mineBlock(miner, minerWallet1.getAddress("base58")); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + await delay(100); + + var miner2TX = await minerWallet1.send({ + outputs: [{ + value: 10 * COIN, + address: minerWallet2.getAddress("base58") + }] + }); + await waitForTX(miner, miner2TX); + await delay(300); + + var minerSpvTX = await minerWallet2.send({ + outputs: [{ + value: 9 * COIN, + address: spvWallet1.getAddress("base58") + }] + }); + await waitForTX(miner, minerSpvTX); + await delay(600); + spvNode.pool.getTX(spvNode.pool.peers.head(), [minerSpvTX.hash()]); + console.log(minerSpvTX.hash()); + console.log(minerSpvTX.outputs[0]); + await delay(6000); + + var spv2TX = await spvWallet1.send({ + outputs: [{ + value: 8 * COIN, + address: spvWallet2.getAddress("base58") + }] + }); + console.log("tria"); + await waitForTX(spvNode, spv2TX); + await waitForTX(miner, spv2TX); + console.log(spvNode.pool.txFilter.test(spv2TX.hash().toString("hex"), "hex")); + + var spvMinerTX = await spvWallet2.send({ + outputs: [{ + value: 7 * COIN, + address: minerWallet1.getAddress("base58") + }] + }); + await waitForTX(miner, spvMinerTX); + await waitForTX(spvNode, spvMinerTX); + await minerWalletDB.addTX(spvMinerTX); + process.exit(); +})(); + +var getWalletDB = async (node) => { + var walletDB = new WalletDB({ + network: node.network, + db: "memory", + client: new bcoin.node.NodeClient(node) + }); + + await walletDB.open(); + await walletDB.connect(); + + return walletDB; +}; + +var createWallet = async (walletDB, id) => { + var options = { + id, + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }; + + return walletDB.create(options); +}; + +var delay = async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); +}; + +var mineBlock = async (node, rewardAddress) => { + var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); + await node.chain.add(block); + // node.chain.tip does not contain all the properties we want, + // so we need to fetch it: + return node.getBlock(node.chain.tip.hash); +}; + +var waitForTX = async (node, input) => { + var tx = input; + await new Promise((resolve, reject) => { + var check = () => { + // This breaks node.pool.on("tx", ...) + if (node.spv) { + if (node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) + resolve(); + else setTimeout(check, 100); + } + else { // this is not an SPV node + if (node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + } + }; + + check(); + }); +} From b5e99d82f6a2b41552c4b5a49bd5ccd5a7a969b8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 11 Nov 2017 18:37:08 +0000 Subject: [PATCH 334/540] Pinpoint problem with adding TX to walletDB For the spv node, even though a TX has been added to the corresponding walletDB, the wallet that has the receiving address (and belongs to this walletDB) does not have the TX. This testcase makes this fact clear. --- minimal_testcases/bloom.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/minimal_testcases/bloom.js b/minimal_testcases/bloom.js index 70b08ae..091a7a1 100644 --- a/minimal_testcases/bloom.js +++ b/minimal_testcases/bloom.js @@ -31,6 +31,10 @@ var minerWatcher = null; }); await spvNode.open(); spvWalletDB = await getWalletDB(spvNode); + spvNode.pool.on("tx", async (tx) => { + await spvWalletDB.addTX(tx); + console.log("tx", tx.hash().toString("hex"), "added!"); + }); await spvNode.connect(); miner = new bcoin.node.FullNode({ @@ -47,10 +51,10 @@ var minerWatcher = null; miner.startSync(); spvNode.startSync(); - // minerWatcher = new testHelpers.NodeWatcher(miner); - // spvWatcher = new testHelpers.NodeWatcher(spvNode); - var spvWallet1 = await createWallet(spvWalletDB, "spvWallet1"); + spvWallet1.on("balance", (balance) => { + console.log("New spvWallet1 balance:", bcoin.amount.btc(balance.unconfirmed)); + }); var spvWallet2 = await createWallet(spvWalletDB, "spvWallet2"); var minerWallet1 = await createWallet(minerWalletDB, "minerWallet1"); @@ -77,7 +81,7 @@ var minerWatcher = null; }] }); await waitForTX(miner, miner2TX); - await delay(300); + await delay(6000); var minerSpvTX = await minerWallet2.send({ outputs: [{ @@ -86,12 +90,14 @@ var minerWatcher = null; }] }); await waitForTX(miner, minerSpvTX); - await delay(600); - spvNode.pool.getTX(spvNode.pool.peers.head(), [minerSpvTX.hash()]); - console.log(minerSpvTX.hash()); - console.log(minerSpvTX.outputs[0]); + await spvWallet1.getTX(minerSpvTX.hash().toString("hex")); await delay(6000); - + var block = await mineBlock(miner, minerWallet1.getAddress("base58")); + await delay(6000); + // even though the TX has been added to spvWalletDB, spvWallet1 does not know about it + // TODO: ask why this happens + console.log("tx:", await spvWallet1.getTX(minerSpvTX.hash().toString("hex"))); + debugger; var spv2TX = await spvWallet1.send({ outputs: [{ value: 8 * COIN, From 97c5411b82a6755a5e49b22f310f4c287e8caec8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 17 Nov 2017 16:26:31 +0000 Subject: [PATCH 335/540] Simplify bloom.js minimal testcase Avoid wallets and walletDBs and manually generate address instead, avoid mining and sending transactions, create specially crafted trigger for the event of receiving a filterload packet --- minimal_testcases/bloom.js | 176 +++++++------------------------------ 1 file changed, 33 insertions(+), 143 deletions(-) diff --git a/minimal_testcases/bloom.js b/minimal_testcases/bloom.js index 091a7a1..eb85262 100644 --- a/minimal_testcases/bloom.js +++ b/minimal_testcases/bloom.js @@ -1,178 +1,68 @@ -var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); -var Script = bcoin.script; -var Address = bcoin.primitives.Address; -var KeyRing = bcoin.primitives.KeyRing; -var MTX = bcoin.primitives.MTX; -var Input = bcoin.primitives.Input; -var Output = bcoin.primitives.Output; -var Outpoint = bcoin.primitives.Outpoint; -var WalletDB = bcoin.wallet.WalletDB; -var consensus = require("bcoin/lib/protocol/consensus"); -var assert = require("assert"); - -const COIN = consensus.COIN; - -var spvNode = null; -var miner = null; -var spvWalletDB = null; -var minerWalletDB = null; -var spvWatcher = null; -var minerWatcher = null; (async () => { - spvNode = new bcoin.node.SPVNode({ + var spv = new bcoin.node.SPVNode({ network: bcoin.network.get().toString(), port: 48445, passphrase: "secret", - // logConsole: true, - // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); - await spvNode.open(); - spvWalletDB = await getWalletDB(spvNode); - spvNode.pool.on("tx", async (tx) => { - await spvWalletDB.addTX(tx); - console.log("tx", tx.hash().toString("hex"), "added!"); - }); - await spvNode.connect(); + await spv.open(); - miner = new bcoin.node.FullNode({ + var full = new bcoin.node.FullNode({ network: bcoin.network.get().toString(), port: 48448, bip37: true, listen: true, passphrase: "secret" }); - await miner.open(); - minerWalletDB = await getWalletDB(miner); - await miner.connect(); - - miner.startSync(); - spvNode.startSync(); - - var spvWallet1 = await createWallet(spvWalletDB, "spvWallet1"); - spvWallet1.on("balance", (balance) => { - console.log("New spvWallet1 balance:", bcoin.amount.btc(balance.unconfirmed)); - }); - var spvWallet2 = await createWallet(spvWalletDB, "spvWallet2"); + await full.open(); - var minerWallet1 = await createWallet(minerWalletDB, "minerWallet1"); - var minerWallet2 = await createWallet(minerWalletDB, "minerWallet2"); + address = new bcoin.primitives.Address(); + setUpFilterLoadWatcher(full.pool, spv.pool, address); - spvNode.pool.watchAddress(minerWallet1.getAddress()); - spvNode.pool.watchAddress(minerWallet2.getAddress()); + await spv.connect(); + await full.connect(); - spvNode.pool.watchAddress(spvWallet1.getAddress()); - spvNode.pool.watchAddress(spvWallet2.getAddress()); + full.startSync(); + spv.startSync(); - await delay(1000); - // Produce a block and reward the minerWallet1, so that we have a coin to spend. - await mineBlock(miner, minerWallet1.getAddress("base58")); + await delay(3000); - // Make the coin spendable. - consensus.COINBASE_MATURITY = 0; - await delay(100); + spv.pool.watchAddress(address); - var miner2TX = await minerWallet1.send({ - outputs: [{ - value: 10 * COIN, - address: minerWallet2.getAddress("base58") - }] - }); - await waitForTX(miner, miner2TX); - await delay(6000); - - var minerSpvTX = await minerWallet2.send({ - outputs: [{ - value: 9 * COIN, - address: spvWallet1.getAddress("base58") - }] - }); - await waitForTX(miner, minerSpvTX); - await spvWallet1.getTX(minerSpvTX.hash().toString("hex")); - await delay(6000); - var block = await mineBlock(miner, minerWallet1.getAddress("base58")); - await delay(6000); - // even though the TX has been added to spvWalletDB, spvWallet1 does not know about it - // TODO: ask why this happens - console.log("tx:", await spvWallet1.getTX(minerSpvTX.hash().toString("hex"))); - debugger; - var spv2TX = await spvWallet1.send({ - outputs: [{ - value: 8 * COIN, - address: spvWallet2.getAddress("base58") - }] - }); - console.log("tria"); - await waitForTX(spvNode, spv2TX); - await waitForTX(miner, spv2TX); - console.log(spvNode.pool.txFilter.test(spv2TX.hash().toString("hex"), "hex")); - - var spvMinerTX = await spvWallet2.send({ - outputs: [{ - value: 7 * COIN, - address: minerWallet1.getAddress("base58") - }] - }); - await waitForTX(miner, spvMinerTX); - await waitForTX(spvNode, spvMinerTX); - await minerWalletDB.addTX(spvMinerTX); + await delay(3000); + await delay(3000); process.exit(); })(); -var getWalletDB = async (node) => { - var walletDB = new WalletDB({ - network: node.network, - db: "memory", - client: new bcoin.node.NodeClient(node) - }); - - await walletDB.open(); - await walletDB.connect(); - - return walletDB; -}; - -var createWallet = async (walletDB, id) => { - var options = { - id, - passphrase: "secret", - witness: false, - type: "pubkeyhash" - }; - - return walletDB.create(options); -}; - var delay = async (milliseconds) => { return new Promise((resolve, reject) => { setTimeout(resolve, milliseconds); }); }; -var mineBlock = async (node, rewardAddress) => { - var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); - await node.chain.add(block); - // node.chain.tip does not contain all the properties we want, - // so we need to fetch it: - return node.getBlock(node.chain.tip.hash); -}; - -var waitForTX = async (node, input) => { - var tx = input; - await new Promise((resolve, reject) => { +var setUpFilterLoadWatcher = async (fullPool, spvPool, address) => { + return new Promise((resolve, reject) => { var check = () => { - // This breaks node.pool.on("tx", ...) - if (node.spv) { - if (node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) - resolve(); - else setTimeout(check, 100); + if (fullPool.peers.size() > 0 && fullPool.peers.head().handshake) { + fullPool.peers.head().on("packet", (packet) => { + if (packet.cmd == "filterload") { + console.log("\nA filterload packet was just received by full"); + if (packet.filter.test(address.hash)) + console.log("The filter as seen by full *sees* the address") + else + console.log("The filter as seen by full *doesn't see* the address"); + if (spvPool.spvFilter.test(address.hash)) + console.log("The filter as seen by spv *sees* the address") + else + console.log("The filter as seen by spv *doesn't see* the address"); + } + }); + resolve(); } - else { // this is not an SPV node - if (node.pool.hasTX(tx.hash().toString("hex"))) - resolve(); - else setTimeout(check, 100); + else { + setTimeout(check, 90); } }; From db738050c9d2a419b3a61720228c663059a2b3a9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 17 Nov 2017 16:26:31 +0000 Subject: [PATCH 336/540] Simplify bloom.js minimal testcase Avoid wallets and walletDBs and manually generate address instead, avoid mining and sending transactions, create specially crafted trigger for the event of receiving a filterload packet --- minimal_testcases/bloom.js | 177 +++++++------------------------------ 1 file changed, 34 insertions(+), 143 deletions(-) diff --git a/minimal_testcases/bloom.js b/minimal_testcases/bloom.js index 091a7a1..7f875ad 100644 --- a/minimal_testcases/bloom.js +++ b/minimal_testcases/bloom.js @@ -1,178 +1,69 @@ -var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); -var Script = bcoin.script; -var Address = bcoin.primitives.Address; -var KeyRing = bcoin.primitives.KeyRing; -var MTX = bcoin.primitives.MTX; -var Input = bcoin.primitives.Input; -var Output = bcoin.primitives.Output; -var Outpoint = bcoin.primitives.Outpoint; -var WalletDB = bcoin.wallet.WalletDB; -var consensus = require("bcoin/lib/protocol/consensus"); -var assert = require("assert"); - -const COIN = consensus.COIN; - -var spvNode = null; -var miner = null; -var spvWalletDB = null; -var minerWalletDB = null; -var spvWatcher = null; -var minerWatcher = null; (async () => { - spvNode = new bcoin.node.SPVNode({ + var spv = new bcoin.node.SPVNode({ network: bcoin.network.get().toString(), port: 48445, passphrase: "secret", - // logConsole: true, - // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); - await spvNode.open(); - spvWalletDB = await getWalletDB(spvNode); - spvNode.pool.on("tx", async (tx) => { - await spvWalletDB.addTX(tx); - console.log("tx", tx.hash().toString("hex"), "added!"); - }); - await spvNode.connect(); + await spv.open(); - miner = new bcoin.node.FullNode({ + var full = new bcoin.node.FullNode({ network: bcoin.network.get().toString(), port: 48448, bip37: true, listen: true, passphrase: "secret" }); - await miner.open(); - minerWalletDB = await getWalletDB(miner); - await miner.connect(); - - miner.startSync(); - spvNode.startSync(); - - var spvWallet1 = await createWallet(spvWalletDB, "spvWallet1"); - spvWallet1.on("balance", (balance) => { - console.log("New spvWallet1 balance:", bcoin.amount.btc(balance.unconfirmed)); - }); - var spvWallet2 = await createWallet(spvWalletDB, "spvWallet2"); + await full.open(); - var minerWallet1 = await createWallet(minerWalletDB, "minerWallet1"); - var minerWallet2 = await createWallet(minerWalletDB, "minerWallet2"); + address = new bcoin.primitives.Address(); + var promise = setUpFilterLoadWatcher(full.pool, spv.pool, address); - spvNode.pool.watchAddress(minerWallet1.getAddress()); - spvNode.pool.watchAddress(minerWallet2.getAddress()); + await spv.connect(); + await full.connect(); - spvNode.pool.watchAddress(spvWallet1.getAddress()); - spvNode.pool.watchAddress(spvWallet2.getAddress()); + full.startSync(); + spv.startSync(); - await delay(1000); - // Produce a block and reward the minerWallet1, so that we have a coin to spend. - await mineBlock(miner, minerWallet1.getAddress("base58")); + await delay(3000); - // Make the coin spendable. - consensus.COINBASE_MATURITY = 0; - await delay(100); + spv.pool.watchAddress(address); - var miner2TX = await minerWallet1.send({ - outputs: [{ - value: 10 * COIN, - address: minerWallet2.getAddress("base58") - }] - }); - await waitForTX(miner, miner2TX); - await delay(6000); - - var minerSpvTX = await minerWallet2.send({ - outputs: [{ - value: 9 * COIN, - address: spvWallet1.getAddress("base58") - }] - }); - await waitForTX(miner, minerSpvTX); - await spvWallet1.getTX(minerSpvTX.hash().toString("hex")); - await delay(6000); - var block = await mineBlock(miner, minerWallet1.getAddress("base58")); - await delay(6000); - // even though the TX has been added to spvWalletDB, spvWallet1 does not know about it - // TODO: ask why this happens - console.log("tx:", await spvWallet1.getTX(minerSpvTX.hash().toString("hex"))); - debugger; - var spv2TX = await spvWallet1.send({ - outputs: [{ - value: 8 * COIN, - address: spvWallet2.getAddress("base58") - }] - }); - console.log("tria"); - await waitForTX(spvNode, spv2TX); - await waitForTX(miner, spv2TX); - console.log(spvNode.pool.txFilter.test(spv2TX.hash().toString("hex"), "hex")); - - var spvMinerTX = await spvWallet2.send({ - outputs: [{ - value: 7 * COIN, - address: minerWallet1.getAddress("base58") - }] - }); - await waitForTX(miner, spvMinerTX); - await waitForTX(spvNode, spvMinerTX); - await minerWalletDB.addTX(spvMinerTX); + await delay(3000); + await delay(3000); + await promise; process.exit(); })(); -var getWalletDB = async (node) => { - var walletDB = new WalletDB({ - network: node.network, - db: "memory", - client: new bcoin.node.NodeClient(node) - }); - - await walletDB.open(); - await walletDB.connect(); - - return walletDB; -}; - -var createWallet = async (walletDB, id) => { - var options = { - id, - passphrase: "secret", - witness: false, - type: "pubkeyhash" - }; - - return walletDB.create(options); -}; - var delay = async (milliseconds) => { return new Promise((resolve, reject) => { setTimeout(resolve, milliseconds); }); }; -var mineBlock = async (node, rewardAddress) => { - var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); - await node.chain.add(block); - // node.chain.tip does not contain all the properties we want, - // so we need to fetch it: - return node.getBlock(node.chain.tip.hash); -}; - -var waitForTX = async (node, input) => { - var tx = input; - await new Promise((resolve, reject) => { +var setUpFilterLoadWatcher = async (fullPool, spvPool, address) => { + return new Promise((resolve, reject) => { var check = () => { - // This breaks node.pool.on("tx", ...) - if (node.spv) { - if (node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) - resolve(); - else setTimeout(check, 100); + if (fullPool.peers.size() > 0 && fullPool.peers.head().handshake) { + fullPool.peers.head().on("packet", (packet) => { + if (packet.cmd == "filterload") { + console.log("\nA filterload packet was just received by full"); + if (packet.filter.test(address.hash)) + console.log("The filter as seen by full *sees* the address") + else + console.log("The filter as seen by full *doesn't see* the address"); + if (spvPool.spvFilter.test(address.hash)) + console.log("The filter as seen by spv *sees* the address") + else + console.log("The filter as seen by spv *doesn't see* the address"); + } + }); + resolve(); } - else { // this is not an SPV node - if (node.pool.hasTX(tx.hash().toString("hex"))) - resolve(); - else setTimeout(check, 100); + else { + setTimeout(check, 90); } }; From 16077f8f3958d5688dbc20c8d075376e5ac5c53f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 17 Nov 2017 16:26:31 +0000 Subject: [PATCH 337/540] Simplify bloom.js minimal testcase Avoid wallets and walletDBs and manually generate address instead, avoid mining and sending transactions, create specially crafted trigger for the event of receiving a filterload packet --- minimal_testcases/bloom.js | 176 +++++++------------------------------ 1 file changed, 33 insertions(+), 143 deletions(-) diff --git a/minimal_testcases/bloom.js b/minimal_testcases/bloom.js index 091a7a1..eb85262 100644 --- a/minimal_testcases/bloom.js +++ b/minimal_testcases/bloom.js @@ -1,178 +1,68 @@ -var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); -var Script = bcoin.script; -var Address = bcoin.primitives.Address; -var KeyRing = bcoin.primitives.KeyRing; -var MTX = bcoin.primitives.MTX; -var Input = bcoin.primitives.Input; -var Output = bcoin.primitives.Output; -var Outpoint = bcoin.primitives.Outpoint; -var WalletDB = bcoin.wallet.WalletDB; -var consensus = require("bcoin/lib/protocol/consensus"); -var assert = require("assert"); - -const COIN = consensus.COIN; - -var spvNode = null; -var miner = null; -var spvWalletDB = null; -var minerWalletDB = null; -var spvWatcher = null; -var minerWatcher = null; (async () => { - spvNode = new bcoin.node.SPVNode({ + var spv = new bcoin.node.SPVNode({ network: bcoin.network.get().toString(), port: 48445, passphrase: "secret", - // logConsole: true, - // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); - await spvNode.open(); - spvWalletDB = await getWalletDB(spvNode); - spvNode.pool.on("tx", async (tx) => { - await spvWalletDB.addTX(tx); - console.log("tx", tx.hash().toString("hex"), "added!"); - }); - await spvNode.connect(); + await spv.open(); - miner = new bcoin.node.FullNode({ + var full = new bcoin.node.FullNode({ network: bcoin.network.get().toString(), port: 48448, bip37: true, listen: true, passphrase: "secret" }); - await miner.open(); - minerWalletDB = await getWalletDB(miner); - await miner.connect(); - - miner.startSync(); - spvNode.startSync(); - - var spvWallet1 = await createWallet(spvWalletDB, "spvWallet1"); - spvWallet1.on("balance", (balance) => { - console.log("New spvWallet1 balance:", bcoin.amount.btc(balance.unconfirmed)); - }); - var spvWallet2 = await createWallet(spvWalletDB, "spvWallet2"); + await full.open(); - var minerWallet1 = await createWallet(minerWalletDB, "minerWallet1"); - var minerWallet2 = await createWallet(minerWalletDB, "minerWallet2"); + address = new bcoin.primitives.Address(); + setUpFilterLoadWatcher(full.pool, spv.pool, address); - spvNode.pool.watchAddress(minerWallet1.getAddress()); - spvNode.pool.watchAddress(minerWallet2.getAddress()); + await spv.connect(); + await full.connect(); - spvNode.pool.watchAddress(spvWallet1.getAddress()); - spvNode.pool.watchAddress(spvWallet2.getAddress()); + full.startSync(); + spv.startSync(); - await delay(1000); - // Produce a block and reward the minerWallet1, so that we have a coin to spend. - await mineBlock(miner, minerWallet1.getAddress("base58")); + await delay(3000); - // Make the coin spendable. - consensus.COINBASE_MATURITY = 0; - await delay(100); + spv.pool.watchAddress(address); - var miner2TX = await minerWallet1.send({ - outputs: [{ - value: 10 * COIN, - address: minerWallet2.getAddress("base58") - }] - }); - await waitForTX(miner, miner2TX); - await delay(6000); - - var minerSpvTX = await minerWallet2.send({ - outputs: [{ - value: 9 * COIN, - address: spvWallet1.getAddress("base58") - }] - }); - await waitForTX(miner, minerSpvTX); - await spvWallet1.getTX(minerSpvTX.hash().toString("hex")); - await delay(6000); - var block = await mineBlock(miner, minerWallet1.getAddress("base58")); - await delay(6000); - // even though the TX has been added to spvWalletDB, spvWallet1 does not know about it - // TODO: ask why this happens - console.log("tx:", await spvWallet1.getTX(minerSpvTX.hash().toString("hex"))); - debugger; - var spv2TX = await spvWallet1.send({ - outputs: [{ - value: 8 * COIN, - address: spvWallet2.getAddress("base58") - }] - }); - console.log("tria"); - await waitForTX(spvNode, spv2TX); - await waitForTX(miner, spv2TX); - console.log(spvNode.pool.txFilter.test(spv2TX.hash().toString("hex"), "hex")); - - var spvMinerTX = await spvWallet2.send({ - outputs: [{ - value: 7 * COIN, - address: minerWallet1.getAddress("base58") - }] - }); - await waitForTX(miner, spvMinerTX); - await waitForTX(spvNode, spvMinerTX); - await minerWalletDB.addTX(spvMinerTX); + await delay(3000); + await delay(3000); process.exit(); })(); -var getWalletDB = async (node) => { - var walletDB = new WalletDB({ - network: node.network, - db: "memory", - client: new bcoin.node.NodeClient(node) - }); - - await walletDB.open(); - await walletDB.connect(); - - return walletDB; -}; - -var createWallet = async (walletDB, id) => { - var options = { - id, - passphrase: "secret", - witness: false, - type: "pubkeyhash" - }; - - return walletDB.create(options); -}; - var delay = async (milliseconds) => { return new Promise((resolve, reject) => { setTimeout(resolve, milliseconds); }); }; -var mineBlock = async (node, rewardAddress) => { - var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); - await node.chain.add(block); - // node.chain.tip does not contain all the properties we want, - // so we need to fetch it: - return node.getBlock(node.chain.tip.hash); -}; - -var waitForTX = async (node, input) => { - var tx = input; - await new Promise((resolve, reject) => { +var setUpFilterLoadWatcher = async (fullPool, spvPool, address) => { + return new Promise((resolve, reject) => { var check = () => { - // This breaks node.pool.on("tx", ...) - if (node.spv) { - if (node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) - resolve(); - else setTimeout(check, 100); + if (fullPool.peers.size() > 0 && fullPool.peers.head().handshake) { + fullPool.peers.head().on("packet", (packet) => { + if (packet.cmd == "filterload") { + console.log("\nA filterload packet was just received by full"); + if (packet.filter.test(address.hash)) + console.log("The filter as seen by full *sees* the address") + else + console.log("The filter as seen by full *doesn't see* the address"); + if (spvPool.spvFilter.test(address.hash)) + console.log("The filter as seen by spv *sees* the address") + else + console.log("The filter as seen by spv *doesn't see* the address"); + } + }); + resolve(); } - else { // this is not an SPV node - if (node.pool.hasTX(tx.hash().toString("hex"))) - resolve(); - else setTimeout(check, 100); + else { + setTimeout(check, 90); } }; From 92d457221d1d68011fe47dc52170e14ca69a6ad5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 20 Nov 2017 17:42:50 +0000 Subject: [PATCH 338/540] Await properly for trigger setup --- minimal_testcases/bloom.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/minimal_testcases/bloom.js b/minimal_testcases/bloom.js index eb85262..7f875ad 100644 --- a/minimal_testcases/bloom.js +++ b/minimal_testcases/bloom.js @@ -19,7 +19,7 @@ var bcoin = require("bcoin").set("regtest"); await full.open(); address = new bcoin.primitives.Address(); - setUpFilterLoadWatcher(full.pool, spv.pool, address); + var promise = setUpFilterLoadWatcher(full.pool, spv.pool, address); await spv.connect(); await full.connect(); @@ -33,6 +33,7 @@ var bcoin = require("bcoin").set("regtest"); await delay(3000); await delay(3000); + await promise; process.exit(); })(); From e8a66b6066b1357ba577bb50a5f295984ff8caa0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 27 Nov 2017 21:53:53 +0000 Subject: [PATCH 339/540] Remove watchAddress() Apparently the TX is sent even if the address is never watched --- minimal_testcases/sendtx.js | 1 - 1 file changed, 1 deletion(-) diff --git a/minimal_testcases/sendtx.js b/minimal_testcases/sendtx.js index 88cac33..851494e 100644 --- a/minimal_testcases/sendtx.js +++ b/minimal_testcases/sendtx.js @@ -35,7 +35,6 @@ var delay = async (milliseconds) => { var minerWalletDB = await getWalletDB(miner); var minerAlpha = await createWallet(minerWalletDB, "minerAlpha"); - spvNode.pool.watchAddress(minerAlpha.getAddress()); miner.on("tx", () => {console.log("full says: TX arrived!");}); await miner.connect(); From cd35c93fc01687ebf23480858ec8edb039216ffe Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 27 Nov 2017 21:56:25 +0000 Subject: [PATCH 340/540] Change the debug console.log() messages For some reason, when the bloom filter creation bug is fixed at bcoin/lib/utils/bloom.js, Bloom.prototype.fromReader(), the two nodes fail to successfully complete the handshake. These console.log()s help debug this situation. --- test/spv_node.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 9ba3376..33f712b 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -132,11 +132,17 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(minerSpvTX); - await testHelpers.delay(6000); - spvNode.pool.getTX(spvNode.pool.peers.head(), [minerSpvTX.hash()]); - console.log(minerSpvTX.hash()); - console.log(minerSpvTX.outputs[0]); - await testHelpers.delay(6000); + await testHelpers.delay(3000); + await testHelpers.delay(3000); + //spvNode.pool.getTX(spvNode.pool.peers.head(), [minerSpvTX.hash()]); + await testHelpers.delay(3000); + await testHelpers.delay(2000); + console.log(miner.pool.peers.head()); + console.log(spvNode.pool.peers.head()); + console.log(miner.pool.peers.head().spvFilter.test(minerSpvTX.hash)) + console.log(miner.pool.peers.head().filter.test(miner2TX.hash)) + console.log(spv.pool.spvFilter.test(minerSpvTX.hash)) + console.log(spv.pool.spvFilter.test(miner2TX.hash)) //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); From de03220c27d0a11b69052be990447f383b31d994 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 30 Nov 2017 23:53:00 +0000 Subject: [PATCH 341/540] Add spv flag to walletDB creation --- test/helpers.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index 1c9f9b5..77a3122 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -9,7 +9,8 @@ var testHelpers = { var walletDB = new WalletDB({ network: node.network, db: "memory", - client: new bcoin.node.NodeClient(node) + client: new bcoin.node.NodeClient(node), + spv: node.spv }); await walletDB.open(); From 2869a970c4fc0fd4eada5f483244ad028398c825 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 30 Nov 2017 23:54:13 +0000 Subject: [PATCH 342/540] Remove redundat console.log()s, add some delays --- test/spv_node.js | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 33f712b..518987a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -132,17 +132,9 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(minerSpvTX); - await testHelpers.delay(3000); - await testHelpers.delay(3000); - //spvNode.pool.getTX(spvNode.pool.peers.head(), [minerSpvTX.hash()]); - await testHelpers.delay(3000); await testHelpers.delay(2000); - console.log(miner.pool.peers.head()); - console.log(spvNode.pool.peers.head()); - console.log(miner.pool.peers.head().spvFilter.test(minerSpvTX.hash)) - console.log(miner.pool.peers.head().filter.test(miner2TX.hash)) - console.log(spv.pool.spvFilter.test(minerSpvTX.hash)) - console.log(spv.pool.spvFilter.test(miner2TX.hash)) + await testHelpers.delay(2000); + await testHelpers.delay(2000); //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); @@ -152,12 +144,10 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); - console.log("tria"); - await minerWatcher.waitForTX(spv2TX); - await spvWatcher.waitForTX(spv2TX); - console.log(spvNode.pool.txFilter.test(spv2TX.hash().toString("hex"), "hex")); + await testHelpers.delay(2000); + await testHelpers.delay(2000); - Trust.TrustIsRisk.prototype.addTX.should.have.been.calledThrice(); + //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledThrice(); var spvMinerTX = await spvWallet2.send({ outputs: [{ @@ -166,9 +156,9 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(spvMinerTX); - await spvWatcher.waitForTX(spvMinerTX); - await minerWalletDB.addTX(spvMinerTX); - process.exit(); + await testHelpers.delay(2000); + await testHelpers.delay(2000); + console.log(await minerWallet1.getBalance()); }); describe("with the nobodyLikesFrank.json example", () => { From 9b42fbc05e35bdd6925e9df9849def11040c506b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 4 Dec 2017 12:57:46 +0000 Subject: [PATCH 343/540] Replace delays with waits for tx reception Stop using arbitrary delays, use watchers to wait for the arrival of the transactions instead --- test/spv_node.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 518987a..a586bc8 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -121,7 +121,7 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(miner2TX); - await testHelpers.delay(300); + await spvWatcher.waitForTX(miner2TX); Trust.TrustIsRisk.prototype.addTX.should.have.been.calledOnce(); @@ -132,11 +132,8 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(minerSpvTX); - await testHelpers.delay(2000); - await testHelpers.delay(2000); - await testHelpers.delay(2000); - //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); + await spvWatcher.waitForTX(minerSpvTX); var spv2TX = await spvWallet1.send({ outputs: [{ @@ -144,10 +141,9 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); - await testHelpers.delay(2000); - await testHelpers.delay(2000); - //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledThrice(); + await spvWatcher.waitForTX(spv2TX); + await minerWatcher.waitForTX(spv2TX); var spvMinerTX = await spvWallet2.send({ outputs: [{ @@ -155,9 +151,8 @@ describe("SPVNode", () => { address: minerWallet1.getAddress("base58") }] }); + await spvWatcher.waitForTX(spvMinerTX); await minerWatcher.waitForTX(spvMinerTX); - await testHelpers.delay(2000); - await testHelpers.delay(2000); console.log(await minerWallet1.getBalance()); }); From 35ec54f91a4d44958600cfeb7913b322fcc074eb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 4 Dec 2017 13:01:37 +0000 Subject: [PATCH 344/540] Remove old shoulds and console.log()s Keep only one should that ensures that addTX has been called the right number of times --- test/spv_node.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index a586bc8..4444a67 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -123,7 +123,7 @@ describe("SPVNode", () => { await minerWatcher.waitForTX(miner2TX); await spvWatcher.waitForTX(miner2TX); - Trust.TrustIsRisk.prototype.addTX.should.have.been.calledOnce(); + Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); var minerSpvTX = await minerWallet2.send({ outputs: [{ @@ -132,7 +132,6 @@ describe("SPVNode", () => { }] }); await minerWatcher.waitForTX(minerSpvTX); - //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); await spvWatcher.waitForTX(minerSpvTX); var spv2TX = await spvWallet1.send({ @@ -141,7 +140,6 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); - //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledThrice(); await spvWatcher.waitForTX(spv2TX); await minerWatcher.waitForTX(spv2TX); @@ -153,7 +151,6 @@ describe("SPVNode", () => { }); await spvWatcher.waitForTX(spvMinerTX); await minerWatcher.waitForTX(spvMinerTX); - console.log(await minerWallet1.getBalance()); }); describe("with the nobodyLikesFrank.json example", () => { From 81d310c2729a57cb0f338e65d087ed341a7d57fe Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 4 Dec 2017 13:03:08 +0000 Subject: [PATCH 345/540] Test that the final wallet balance is correct Its correctness indicates that the transactions have circulated as needed --- test/spv_node.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 4444a67..eb4f76b 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -151,6 +151,12 @@ describe("SPVNode", () => { }); await spvWatcher.waitForTX(spvMinerTX); await minerWatcher.waitForTX(spvMinerTX); + + var view = await miner.chain.db.getSpentView(miner2TX); + var actualBalance = (await minerWallet1.getBalance()).unconfirmed; + var expectedBalance = + consensus.BASE_REWARD - 10 * COIN + 7 * COIN - miner2TX.getFee(view); + should(actualBalance).equal(expectedBalance); }); describe("with the nobodyLikesFrank.json example", () => { From 1bc78bc2d41f55424b80b33e0df64e885ba7d066 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 4 Dec 2017 13:04:44 +0000 Subject: [PATCH 346/540] Increase tests time limit Needed by "should call trust.addTX() on every transaction" test in test/spv_node.js --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0809f1c..9df4cc1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 20000", + "test": "npm run build && mocha -t 30000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 3e313dce6d7bc194ba4a062f133b26a53a9a7ba5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 4 Dec 2017 13:06:18 +0000 Subject: [PATCH 347/540] Remove "only" from test --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index eb4f76b..e8ffb9e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -93,7 +93,7 @@ describe("SPVNode", () => { await miner.close(); }); - it.only("should call trust.addTX() on every transaction", async function() { + it("should call trust.addTX() on every transaction", async function() { var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); From 03a50dba3bf47310677645578fc323a463336b5d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Dec 2017 16:00:16 +0000 Subject: [PATCH 348/540] Add should() for number of addTX() calls --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index e8ffb9e..352df26 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -157,6 +157,7 @@ describe("SPVNode", () => { var expectedBalance = consensus.BASE_REWARD - 10 * COIN + 7 * COIN - miner2TX.getFee(view); should(actualBalance).equal(expectedBalance); + should(Trust.TrustIsRisk.prototype.addTX.callCount).equal(8); }); describe("with the nobodyLikesFrank.json example", () => { From d7e06c8c0beb4577c6c2258639c155ae8b956ec4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Dec 2017 18:53:43 +0000 Subject: [PATCH 349/540] Increase test time limit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9df4cc1..ce2fc51 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 30000", + "test": "npm run build && mocha -t 40000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 1f0febff2df6da80616a67dd71f359b0a162ae50 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Dec 2017 18:54:53 +0000 Subject: [PATCH 350/540] Renew debug console.log()s --- test/helpers.js | 5 +++-- test/spv_node.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 77a3122..5822139 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -168,8 +168,9 @@ class NodeWatcher { var check = (() => { // This breaks node.pool.on("tx", ...) if (this.node.spv) { - if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) - resolve(); + if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) { + console.log(tx); + resolve();} else setTimeout(check, 100); } else { // this is not an SPV node diff --git a/test/spv_node.js b/test/spv_node.js index 352df26..749a42d 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -299,14 +299,12 @@ describe("SPVNode", () => { let destWallet = null; if (spvNames[origin]) { - console.log("2", origin); node = spvNode; watcher = spvWatcher; originWallet = spvWallets[origin]; } else { - console.log("5", origin); node = miner; watcher = minerWatcher; originWallet = minerWallets[origin]; @@ -408,6 +406,9 @@ describe("SPVNode", () => { miner.sendTX(mtx.toTX()); await testHelpers.delay(3000); + console.log("my words mark"); + console.log(spvNode.pool.txFilter.test(tx.hash().toString("hex"), "hex")); + console.log(miner.pool.hasTX(tx)); should(miner.trust.getIndirectTrust(addresses["alice"], addresses["bob"])).equal(7 * COIN); should(spvNode.trust.getIndirectTrust(addresses["alice"], From a99edffbe49adcd3c975900086c7fa0d0673928f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Dec 2017 18:55:46 +0000 Subject: [PATCH 351/540] Have spv watch all addresses --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index 749a42d..21ff2c9 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -190,6 +190,7 @@ describe("SPVNode", () => { addresses[name] = helpers.pubKeyToEntity( rings[name].getPublicKey(), miner.network ); + spvNode.pool.watchAddress(addresses[name]); } for (name in spvNames) { From c2fa7c4d570269205bb6c5f2eb7d7254a2578171 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Dec 2017 18:56:18 +0000 Subject: [PATCH 352/540] Remember a tx and wait for it --- test/spv_node.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 21ff2c9..45f1719 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -404,9 +404,12 @@ describe("SPVNode", () => { var mtx = mtxs[0]; should(await mtx.verify()); - miner.sendTX(mtx.toTX()); + var tx = mtx.toTX(); + miner.sendTX(tx); await testHelpers.delay(3000); + await minerWatcher.waitForTX(tx); + await spvWatcher.waitForTX(tx); console.log("my words mark"); console.log(spvNode.pool.txFilter.test(tx.hash().toString("hex"), "hex")); console.log(miner.pool.hasTX(tx)); From f9dd580d535b60a896ddb51333db2cf7856bf1d9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 5 Dec 2017 18:56:44 +0000 Subject: [PATCH 353/540] Add ".only" to the current test --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 45f1719..9a08b67 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -395,7 +395,7 @@ describe("SPVNode", () => { should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); }); - it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { + it.only("after decreasing some trusts lets both nodes compute trusts correctly", async () => { var mtxs = miner.trust.createTrustDecreasingMTXs( rings["alice"].getPrivateKey(), rings["bob"].getPublicKey(), 3 * COIN From 2aa6ada811338beee55c1ea5207a76a3ae927a1d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Dec 2017 23:27:29 +0000 Subject: [PATCH 354/540] Increase test time limit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce2fc51..18e13b9 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 40000", + "test": "npm run build && mocha -t 60000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 7e05be294fef596adfbc06a7d53edc9c64395558 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 11 Dec 2017 23:28:14 +0000 Subject: [PATCH 355/540] Remove console.log() from test/helpers.js --- test/helpers.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 5822139..77a3122 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -168,9 +168,8 @@ class NodeWatcher { var check = (() => { // This breaks node.pool.on("tx", ...) if (this.node.spv) { - if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) { - console.log(tx); - resolve();} + if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) + resolve(); else setTimeout(check, 100); } else { // this is not an SPV node From eca7827930d74fc7f7922390cb6ace424e487748 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 14 Dec 2017 02:08:47 +0000 Subject: [PATCH 356/540] Remove console.log()s and ".only" from "it" --- test/spv_node.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 9a08b67..dc4eddb 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -395,7 +395,7 @@ describe("SPVNode", () => { should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); }); - it.only("after decreasing some trusts lets both nodes compute trusts correctly", async () => { + it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { var mtxs = miner.trust.createTrustDecreasingMTXs( rings["alice"].getPrivateKey(), rings["bob"].getPublicKey(), 3 * COIN @@ -410,9 +410,6 @@ describe("SPVNode", () => { await testHelpers.delay(3000); await minerWatcher.waitForTX(tx); await spvWatcher.waitForTX(tx); - console.log("my words mark"); - console.log(spvNode.pool.txFilter.test(tx.hash().toString("hex"), "hex")); - console.log(miner.pool.hasTX(tx)); should(miner.trust.getIndirectTrust(addresses["alice"], addresses["bob"])).equal(7 * COIN); should(spvNode.trust.getIndirectTrust(addresses["alice"], From 08a9fe8ec391e2e6dddc9398594af75d33f5e340 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 14 Dec 2017 02:10:02 +0000 Subject: [PATCH 357/540] Add more should()s Check that both the full and the spv node call trust.addTX() for each transaction --- test/spv_node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index dc4eddb..46938d5 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -134,6 +134,8 @@ describe("SPVNode", () => { await minerWatcher.waitForTX(minerSpvTX); await spvWatcher.waitForTX(minerSpvTX); + should(Trust.TrustIsRisk.prototype.addTX.callCount).equal(4); + var spv2TX = await spvWallet1.send({ outputs: [{ value: 8 * COIN, @@ -143,6 +145,8 @@ describe("SPVNode", () => { await spvWatcher.waitForTX(spv2TX); await minerWatcher.waitForTX(spv2TX); + should(Trust.TrustIsRisk.prototype.addTX.callCount).equal(6); + var spvMinerTX = await spvWallet2.send({ outputs: [{ value: 7 * COIN, From c7f01acf864395c893277066be6d67b64a8d8283 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 14 Dec 2017 02:10:55 +0000 Subject: [PATCH 358/540] Add note documenting bcoin library patch This patch adds broadcasted transactions to the txFilter and emits a 'tx' signal for trust to catch. This is not be the best approach, especially for the first case, since the item broadcast is not necessarily a transaction. --- note | 1 + 1 file changed, 1 insertion(+) create mode 100644 note diff --git a/note b/note new file mode 100644 index 0000000..6097b73 --- /dev/null +++ b/note @@ -0,0 +1 @@ +added lines 268,269 at node_modules/bcoin/lib/node/spvnode.js From 7901c89989f873708253536e034f123587e87533 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 14 Dec 2017 19:26:05 +0000 Subject: [PATCH 359/540] Remove redundant whitespace --- src/trust_is_risk.js | 2 +- test/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 17ba39d..44a3166 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -223,7 +223,7 @@ class TrustIsRisk { var existingTrustAmount = this.db.getDirectTrustAmount(originAddress, destAddress); if (existingTrustAmount < trustDecreaseAmount) throw new Error("Insufficient trust"); - + var directTrusts = this.db.getSpendableDirectTrusts(originAddress, destAddress); return directTrusts.map((directTrust) => { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); diff --git a/test/spv_node.js b/test/spv_node.js index 46938d5..129ad01 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -385,7 +385,7 @@ describe("SPVNode", () => { it("lets the SPV node compute trusts correctly", () => { for (name in addresses) { // Add addresses to scope eval(`var ${name} = "${addresses[name]}";`); - } + } should(spvNode.trust.getIndirectTrust(alice, alice)).equal(Infinity); should(spvNode.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); From 0f1d32ae88ca5b7ef4e6aa31586e93b4d23dd37d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 14 Dec 2017 19:54:21 +0000 Subject: [PATCH 360/540] Replace hardcoded delay() with waitForTX() --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 129ad01..ac3d084 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -429,7 +429,7 @@ describe("SPVNode", () => { should(await mtx.verify()); spvNode.sendTX(mtx.toTX()); - await testHelpers.delay(3000); + await minerWatcher.waitForTX(); should(miner.trust.getIndirectTrust(addresses["dave"], addresses["eve"])).equal(10 * COIN); should(spvNode.trust.getIndirectTrust(addresses["dave"], From 93be70d37c122a5cfc3a7b77603f35910b3e5e26 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Dec 2017 18:55:19 +0000 Subject: [PATCH 361/540] Type bloom filter add() function --- flow-typed/npm/bcoin_vx.x.x.js | 1 + 1 file changed, 1 insertion(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 92c6d21..210f75e 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -51,6 +51,7 @@ declare class bcoin$Pool { declare class bcoin$Bloom { test(val : (Buffer | string), enc : (typeof undefined | string)) : boolean; + add(val : (Buffer | string), enc : ?string) : void; } declare class bcoin$Peer {} From c150267d3e313a177a8885eb553e751a25c7ca47 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Dec 2017 18:56:24 +0000 Subject: [PATCH 362/540] Remove redundant whitespace --- test/full_node.js | 18 +++++++++--------- test/helpers.js | 2 +- test/spv_node.js | 10 +++++----- test/trust_is_risk.js | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 2f63ef2..c29a24a 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -63,7 +63,7 @@ describe("FullNode", () => { await walletDB.disconnect(); await walletDB.close(); }); - + afterEach("close node", async () => { await node.close(); }); @@ -87,7 +87,7 @@ describe("FullNode", () => { }] }); await watcher.waitForTX(); - + node.trust.addTX.should.be.calledOnce(); }); @@ -143,7 +143,7 @@ describe("FullNode", () => { var signedCount = mtx.sign(fixtures.keyRings.alice); assert(signedCount === blockCount); assert(await mtx.verify()); - + var tx = mtx.toTX(); node.sendTX(tx); await watcher.waitForTX(); @@ -155,7 +155,7 @@ describe("FullNode", () => { index: fixtures.names.indexOf(name) }; }); - + // Alice mines another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity( fixtures.keyRings.alice.getPublicKey(), node.network @@ -170,23 +170,23 @@ describe("FullNode", () => { if (!value || value < 1) continue; let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - + let mtx = await node.trust.createTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), outpoint, value * consensus.COIN); - + assert(await mtx.verify()); let tx = mtx.toTX(); node.sendTX(tx); await watcher.waitForTX(); - + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } } - + // Alice mines yet another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity( fixtures.keyRings.alice.getPublicKey(), node.network @@ -197,7 +197,7 @@ describe("FullNode", () => { it("computes trusts correctly", () => { for (name in addresses) { // Add addresses to scope eval(`var ${name} = "${addresses[name]}";`); - } + } should(node.trust.getIndirectTrust(alice, alice)).equal(Infinity); should(node.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); diff --git a/test/helpers.js b/test/helpers.js index 77a3122..7fefe31 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -27,7 +27,7 @@ var testHelpers = { type: "pubkeyhash" }; - return walletDB.create(options); + return walletDB.create(options); }, mineBlock: async (node, rewardAddress) => { diff --git a/test/spv_node.js b/test/spv_node.js index ac3d084..4f4a77a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -260,7 +260,7 @@ describe("SPVNode", () => { var signedCount = mtx.sign(rings["alice"]); assert(signedCount === blockCount); assert(await mtx.verify()); - + var tx = mtx.toTX(); miner.sendTX(tx); @@ -291,7 +291,7 @@ describe("SPVNode", () => { index: counter++ }; } - + // Alice mines another block await testHelpers.mineBlock(miner, addresses["alice"]); await testHelpers.delay(500); @@ -343,7 +343,7 @@ describe("SPVNode", () => { outpoint, value * consensus.COIN); } - + assert(await mtx.verify()); let tx = mtx.toTX(); @@ -353,11 +353,11 @@ describe("SPVNode", () => { await originWallet.db.addTX(tx); await destWallet.db.addTX(tx); - + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } } - + // Alice mines yet another block await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( rings["alice"].getPublicKey(), miner.network diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 579bd63..f9a4867 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -92,7 +92,7 @@ describe("TrustIsRisk", () => { describe(".addTX()", () => { describe("with a non-TIR transaction", () => { it("does not change trust", () => { - trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); + trustIncreasingMTX.outputs[0] = testHelpers.getP2PKHOutput(charlie, 50 * COIN); tir.addTX(trustIncreasingMTX.toTX()); tir.getDirectTrust(alice, bob).should.equal(0); @@ -310,7 +310,7 @@ describe("TrustIsRisk", () => { should.throws(() => tir.createTrustDecreasingMTXs( addr.alice.privKey, addr.bob.pubKey, 700 * COIN ), /insufficient trust/i); - + }); }); @@ -320,7 +320,7 @@ describe("TrustIsRisk", () => { should(tir.getIndirectTrust(bob, alice)).equal(0); should(tir.getIndirectTrust(charlie, alice)).equal(0); should(tir.getIndirectTrust(alice, charlie)).equal(0); - }); + }); it("returns Infinity for one's trust to themselves", () => { should(tir.getIndirectTrust(alice, alice)).equal(Infinity); From ac1b98ba48a48e751223e376b8c94fb8243da510 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Dec 2017 18:56:45 +0000 Subject: [PATCH 363/540] Add await for tests to pass --- test/spv_node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spv_node.js b/test/spv_node.js index 4f4a77a..871e0e0 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -430,6 +430,7 @@ describe("SPVNode", () => { spvNode.sendTX(mtx.toTX()); await minerWatcher.waitForTX(); + await spvWatcher.waitForTX(); should(miner.trust.getIndirectTrust(addresses["dave"], addresses["eve"])).equal(10 * COIN); should(spvNode.trust.getIndirectTrust(addresses["dave"], From 857c7d43238230fa5cf8f00246de519623f1be6b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Dec 2017 18:57:11 +0000 Subject: [PATCH 364/540] Test if TIR tag is present in the spv bloom filter --- test/spv_node.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/spv_node.js b/test/spv_node.js index 871e0e0..1e701e6 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -9,6 +9,7 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var WalletDB = bcoin.wallet.WalletDB; +var EC = bcoin.crypto.ec; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); @@ -93,6 +94,59 @@ describe("SPVNode", () => { await miner.close(); }); + it.only("should match a TIR transaction with the spv bloom filter", async function() { + var fakePubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + + var fakePubKey = Buffer.from(fakePubKeyArray); + + var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); + var privateKey1 = (await wallet1.getPrivateKey( + wallet1.getAddress("base58"), "secret") + ).privateKey; + var origin = EC.publicKeyCreate(privateKey1, true); + + var wallet2 = await testHelpers.createWallet(minerWalletDB, "wallet2"); + var privateKey2 = (await wallet2.getPrivateKey( + wallet2.getAddress("base58"), "secret") + ).privateKey; + var dest = EC.publicKeyCreate(privateKey2, true); + + var block = await testHelpers.mineBlock(miner, wallet1.getAddress("base58")); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + await testHelpers.delay(500); + + var outputs = [ + new Output({ // 1-of-3 multisig trust + script: bcoin.script.fromMultisig(1, 3, [origin, dest, fakePubKey]), + value: 49 * consensus.COIN + }), + new Output({ // paytopubkeyhash change + script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(origin)), + value: consensus.COIN - 100000 // leave a fee of 0.001 BTC + }) + ]; + var mtx = new MTX({outputs}); + var coinbaseCoin = await miner.getCoin(block.txs[0].hash().toString("hex"), 0); + mtx.addCoin(coinbaseCoin); + + mtx.sign(KeyRing.fromPrivate(privateKey1, true, "regtest")); + should(await mtx.verify()); + var tx = mtx.toTX(); + + assert(tx.isWatched(spvNode.pool.spvFilter)); + }); + it("should call trust.addTX() on every transaction", async function() { var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); From 41902e6255499d086b2a8cbc1eae5eef5c12a932 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 18 Dec 2017 18:58:50 +0000 Subject: [PATCH 365/540] Add tag to the bloom filter in a different way --- src/spv_node.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spv_node.js b/src/spv_node.js index 721cdec..6eba16a 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -23,7 +23,8 @@ class SPVNode extends bcoin.spvnode { constructor(options : Object) { super(options); this.trust = new TrustIsRisk(this); - this.pool.watchAddress(tag); + this.pool.spvFilter.add(fakePubKey); + this.pool.spvFilter.add(tag); } } From b0d6f8105ad57a3027b1aa8895b77d3c1175b6fc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Dec 2017 12:40:32 +0000 Subject: [PATCH 366/540] Remove tag, rename fakePubKey to tag Turns out that the tag should be the public key itself, not the address derived from it. --- src/spv_node.js | 5 +---- test/spv_node.js | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/spv_node.js b/src/spv_node.js index 6eba16a..8aabf12 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -13,9 +13,7 @@ const fakePubKeyArray = [0x04, // constant 0x04 prefix 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; -const fakePubKey = Buffer.from(fakePubKeyArray); -const fakeKeyRing = bcoin.primitives.KeyRing.fromPublic(fakePubKey); -const tag = Buffer.from(fakeKeyRing.getAddress("base58")); +const tag = Buffer.from(fakePubKeyArray); class SPVNode extends bcoin.spvnode { trust : TrustIsRisk @@ -23,7 +21,6 @@ class SPVNode extends bcoin.spvnode { constructor(options : Object) { super(options); this.trust = new TrustIsRisk(this); - this.pool.spvFilter.add(fakePubKey); this.pool.spvFilter.add(tag); } } diff --git a/test/spv_node.js b/test/spv_node.js index 1e701e6..aeeadf1 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -106,7 +106,7 @@ describe("SPVNode", () => { 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - var fakePubKey = Buffer.from(fakePubKeyArray); + var tag = Buffer.from(fakePubKeyArray); var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); var privateKey1 = (await wallet1.getPrivateKey( @@ -128,7 +128,7 @@ describe("SPVNode", () => { var outputs = [ new Output({ // 1-of-3 multisig trust - script: bcoin.script.fromMultisig(1, 3, [origin, dest, fakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [origin, dest, tag]), value: 49 * consensus.COIN }), new Output({ // paytopubkeyhash change From 7cb3cb67719eebdbf9f6ea97e43413e5c6dc2fbb Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Dec 2017 14:51:06 +0000 Subject: [PATCH 367/540] Use should(...).be.true() instead of other forms In some places assert(...) was used, in others a plain should(...). --- test/full_node.js | 2 +- test/spv_node.js | 8 ++++---- test/trust_is_risk.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index c29a24a..2c16f6b 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -219,7 +219,7 @@ describe("FullNode", () => { mtxs.length.should.equal(1); var mtx = mtxs[0]; - should(await mtx.verify()); + should(await mtx.verify()).be.true(); node.sendTX(mtx.toTX()); await testHelpers.delay(750); diff --git a/test/spv_node.js b/test/spv_node.js index aeeadf1..d9dea1c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -141,10 +141,10 @@ describe("SPVNode", () => { mtx.addCoin(coinbaseCoin); mtx.sign(KeyRing.fromPrivate(privateKey1, true, "regtest")); - should(await mtx.verify()); + should(await mtx.verify()).be.true(); var tx = mtx.toTX(); - assert(tx.isWatched(spvNode.pool.spvFilter)); + tx.isWatched(spvNode.pool.spvFilter).should.be.true(); }); it("should call trust.addTX() on every transaction", async function() { @@ -461,7 +461,7 @@ describe("SPVNode", () => { mtxs.length.should.equal(1); var mtx = mtxs[0]; - should(await mtx.verify()); + should(await mtx.verify()).be.true(); var tx = mtx.toTX(); miner.sendTX(tx); @@ -480,7 +480,7 @@ describe("SPVNode", () => { mtxs.length.should.equal(1); mtx = mtxs[0]; - should(await mtx.verify()); + should(await mtx.verify()).be.true(); spvNode.sendTX(mtx.toTX()); await minerWatcher.waitForTX(); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index f9a4867..ee41faf 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -65,8 +65,8 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { - Buffer.isBuffer(tir.fakePubKey).should.equal(true); - secp256k1.publicKeyVerify(tir.fakePubKey).should.equal(true); + Buffer.isBuffer(tir.fakePubKey).should.be.true(); + secp256k1.publicKeyVerify(tir.fakePubKey).should.be.true(); }); it("is a valid bitcoin address", () => { @@ -147,7 +147,7 @@ describe("TrustIsRisk", () => { it("which has been processed before throws", () => { var tx = trustIncreasingMTX.toTX(); - should(tir.addTX(tx)); + should(tir.addTX(tx)).be.true(); should.throws(() => tir.addTX(tx), /already processed/i); tir.getDirectTrust(alice, bob).should.equal(42 * COIN); }); From da04968bf649a818333fdd7aa0f10592ec391961 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Dec 2017 15:58:24 +0000 Subject: [PATCH 368/540] Reduce mocha timeout --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18e13b9..ce2fc51 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 60000", + "test": "npm run build && mocha -t 40000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From e1a104f65b896c75b4c096202688c777cd8b423c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Dec 2017 16:08:36 +0000 Subject: [PATCH 369/540] Switch it.only to old test --- test/full_node.js | 2 +- test/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 2c16f6b..18d6f18 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -211,7 +211,7 @@ describe("FullNode", () => { should(node.trust.getIndirectTrust(george, eve)).equal(0); }); - it("after decreasing some trusts computes trusts correctly", async () => { + it.only("after decreasing some trusts computes trusts correctly", async () => { var mtxs = node.trust.createTrustDecreasingMTXs( fixtures.keyRings.alice.getPrivateKey(), fixtures.keyRings.bob.getPublicKey(), 3 * COIN diff --git a/test/spv_node.js b/test/spv_node.js index d9dea1c..5b22ca9 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -94,7 +94,7 @@ describe("SPVNode", () => { await miner.close(); }); - it.only("should match a TIR transaction with the spv bloom filter", async function() { + it("should match a TIR transaction with the spv bloom filter", async function() { var fakePubKeyArray = [0x04, // constant 0x04 prefix 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate From 57cc27df1b8401e10e5e045a7dda4a11427df9e6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 19 Dec 2017 16:09:29 +0000 Subject: [PATCH 370/540] Add local mtx validity tests --- test/full_node.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/full_node.js b/test/full_node.js index 18d6f18..6268acb 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -219,6 +219,23 @@ describe("FullNode", () => { mtxs.length.should.equal(1); var mtx = mtxs[0]; + if (mtx.inputs.length === 0) + console.log(false, 1); + + else if (mtx.isCoinbase()) + console.log(true, 2); + + else for (i = 0; i < mtx.inputs.length; i++) { + input = mtx.inputs[i]; + coin = mtx.view.getOutput(input); + + if (!coin) + console.log(false, i); + + if (!mtx.verifyInput(i, coin, flags)) + console.log(false, 4); + } + should(await mtx.verify()).be.true(); node.sendTX(mtx.toTX()); From e7dc1890d97ad78a29ba5c5a53a4e5bf87245035 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 5 Jan 2018 18:45:27 +0200 Subject: [PATCH 371/540] Copy verification process locally --- test/full_node.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 6268acb..a74dbec 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -219,22 +219,22 @@ describe("FullNode", () => { mtxs.length.should.equal(1); var mtx = mtxs[0]; - if (mtx.inputs.length === 0) - console.log(false, 1); + if (mtx.inputs.length === 0) + console.log(false, 1); - else if (mtx.isCoinbase()) - console.log(true, 2); + else if (mtx.isCoinbase()) + console.log(true, 2); - else for (i = 0; i < mtx.inputs.length; i++) { - input = mtx.inputs[i]; - coin = mtx.view.getOutput(input); + else for (i = 0; i < mtx.inputs.length; i++) { + input = mtx.inputs[i]; + coin = mtx.view.getOutput(input); - if (!coin) - console.log(false, i); + if (!coin) + console.log(false, i); - if (!mtx.verifyInput(i, coin, flags)) - console.log(false, 4); - } + if (!mtx.verifyInput(i, coin, Script.flags.STANDARD_VERIFY_FLAGS)) + console.log(false, 4); + } should(await mtx.verify()).be.true(); node.sendTX(mtx.toTX()); From dda3f06edd427048aa533b2345f2a9c4cefe2f80 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 9 Jan 2018 13:21:35 +0200 Subject: [PATCH 372/540] Add comment on why TX is invalid --- test/trust_is_risk.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index ee41faf..daaad53 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -161,6 +161,8 @@ describe("TrustIsRisk", () => { it("correctly decreases trust", () => { tir.addTX(trustDecreasingMTX.toTX()); tir.getDirectTrust(alice, bob).should.equal(20 * COIN); + // trustDecreasingMTX does not verify correctly + // because it is not part of a valid blockchain }); it("decreases trust to zero for trust decreasing transactions with a wrong recipient", () => { From f28f91ca9a01e06daec06ef84d005d9a9c5f8222 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 9 Jan 2018 15:37:13 +0200 Subject: [PATCH 373/540] Add optimisation TODO comment --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 44a3166..cc3ce29 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -245,7 +245,7 @@ class TrustIsRisk { outputs: [new Output({ script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) - })] + })] // TODO: do not add this output if its value is 0 }); var remainingTrustAmount = directTrust.amount - decreaseAmount; From fc24a750d65918dcffe874f3cec701176d7f192e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 9 Jan 2018 15:38:23 +0200 Subject: [PATCH 374/540] Type getTrustDecreasingMTX() return value --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index cc3ce29..add36b9 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -234,7 +234,7 @@ class TrustIsRisk { } getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, - signingKeyRing : bcoin$KeyRing, fee : ?number) { + signingKeyRing : bcoin$KeyRing, fee : ?number) : Promise { if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this From dba43dd8fcc0994b3b37f48b3373c6e20a49bc65 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 9 Jan 2018 21:51:27 +0100 Subject: [PATCH 375/540] Use async/await to get trust decreasing txs This will allow the use of coins in getTrustDecreasingMTX(), which is needed for these transactions to verify correctly --- src/trust_is_risk.js | 6 +++--- test/full_node.js | 4 ++-- test/trust_is_risk.js | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index add36b9..dad6d87 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -196,9 +196,9 @@ class TrustIsRisk { // and the `dest` key is expected to be a public key. If steal is set to true, then `origin` is // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. - createTrustDecreasingMTXs(origin : Key, dest : Key, + async createTrustDecreasingMTXs(origin : Key, dest : Key, trustDecreaseAmount : number, payee : ?Entity, - steal : ?boolean, fee : ?number) : bcoin$MTX[] { + steal : ?boolean, fee : ?number) : Promise[]> { if (steal === undefined) steal = false; var signingKeyRing, originKeyRing, destKeyRing; @@ -233,7 +233,7 @@ class TrustIsRisk { }).filter(Boolean); } - getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, + async getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, signingKeyRing : bcoin$KeyRing, fee : ?number) : Promise { if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this diff --git a/test/full_node.js b/test/full_node.js index a74dbec..52305da 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -212,12 +212,12 @@ describe("FullNode", () => { }); it.only("after decreasing some trusts computes trusts correctly", async () => { - var mtxs = node.trust.createTrustDecreasingMTXs( + var mtxs = await node.trust.createTrustDecreasingMTXs( fixtures.keyRings.alice.getPrivateKey(), fixtures.keyRings.bob.getPublicKey(), 3 * COIN ); mtxs.length.should.equal(1); - var mtx = mtxs[0]; + var mtx = await mtxs[0]; if (mtx.inputs.length === 0) console.log(false, 1); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index daaad53..fc9f4b3 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -256,10 +256,11 @@ describe("TrustIsRisk", () => { // Checks that mtxs is a list of two trust decreasing transactions. The first one spends the // entire first trust increasing transaction, and the second spends part of the second. // Also checks that the reduced trust is sent via P2PKH outputs to the correct recipient. - var checkMTXs = (mtxs, recipient) => { + var checkMTXs = async (mtxs, recipient) => { + mtxs = await mtxs; mtxs.length.should.equal(2); - var mtx = mtxs[0]; + var mtx = await mtxs[0]; mtx.inputs.length.should.equal(1); mtx.inputs[0].prevout.should.have.properties({ @@ -272,7 +273,7 @@ describe("TrustIsRisk", () => { mtx.outputs[0].getAddress().toBase58().should.equal(recipient); mtx.outputs[0].value.should.equal(42 * COIN - 1000); - mtx = mtxs[1]; + mtx = await mtxs[1]; mtx.inputs.length.should.equal(1); mtx.inputs[0].prevout.should.have.properties({ @@ -303,16 +304,15 @@ describe("TrustIsRisk", () => { }); it("throws when trying to decrease self-trust", () => { - should.throws(() => tir.createTrustDecreasingMTXs( + tir.createTrustDecreasingMTXs( addr.alice.privKey, addr.alice.pubKey, 10 * COIN - ), /self-trust/i); + ).should.be.rejectedWith("Can't decrease self-trust"); }); it("throws when there is not enough trust", () => { - should.throws(() => tir.createTrustDecreasingMTXs( + tir.createTrustDecreasingMTXs( addr.alice.privKey, addr.bob.pubKey, 700 * COIN - ), /insufficient trust/i); - + ).should.be.rejectedWith("Insufficient trust"); }); }); From bb0e4567aece46545415f9d659c1581f2339247a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 10 Jan 2018 16:50:21 +0100 Subject: [PATCH 376/540] Remove manual tx verification and .only This test now completes successfully --- test/full_node.js | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 52305da..db1a94b 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -211,7 +211,7 @@ describe("FullNode", () => { should(node.trust.getIndirectTrust(george, eve)).equal(0); }); - it.only("after decreasing some trusts computes trusts correctly", async () => { + it("after decreasing some trusts computes trusts correctly", async () => { var mtxs = await node.trust.createTrustDecreasingMTXs( fixtures.keyRings.alice.getPrivateKey(), fixtures.keyRings.bob.getPublicKey(), 3 * COIN @@ -219,23 +219,6 @@ describe("FullNode", () => { mtxs.length.should.equal(1); var mtx = await mtxs[0]; - if (mtx.inputs.length === 0) - console.log(false, 1); - - else if (mtx.isCoinbase()) - console.log(true, 2); - - else for (i = 0; i < mtx.inputs.length; i++) { - input = mtx.inputs[i]; - coin = mtx.view.getOutput(input); - - if (!coin) - console.log(false, i); - - if (!mtx.verifyInput(i, coin, Script.flags.STANDARD_VERIFY_FLAGS)) - console.log(false, 4); - } - should(await mtx.verify()).be.true(); node.sendTX(mtx.toTX()); From 3358ed9ae64a9061da93bc81e77e3fe21d004c7a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 10 Jan 2018 16:59:35 +0100 Subject: [PATCH 377/540] Use coin instead of input for trust decreasing txs This change is needed for the txs to successfully verify. Possibly improvements in async/await usage can be done. --- src/trust_is_risk.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index dad6d87..98f0b55 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -237,11 +237,11 @@ class TrustIsRisk { signingKeyRing : bcoin$KeyRing, fee : ?number) : Promise { if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this + var outpoint = new Outpoint(directTrust.txHash, directTrust.outputIndex); + var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + if (!coin) throw new Error("Could not find coin"); var mtx = new MTX({ - inputs: [ - Input.fromOutpoint(new Outpoint(directTrust.txHash, directTrust.outputIndex)) - ], outputs: [new Output({ script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) @@ -256,6 +256,7 @@ class TrustIsRisk { })); } + mtx.addCoin(coin); var success = mtx.scriptVector(((directTrust.script : any) : bcoin$Script), mtx.inputs[0].script, KeyRing.fromPublic(directTrust.origin)); assert(success); From 30a14a4c0e2e7d278f4bb2dedfc36c2ac23e43b6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 12 Jan 2018 19:49:17 +0100 Subject: [PATCH 378/540] Homogenize "should" syntax Replace all should(var).doSomething() with var.should.doSomething() --- test/full_node.js | 24 ++++---- test/spv_node.js | 66 ++++++++++----------- test/trust_is_risk.js | 132 +++++++++++++++++++++--------------------- 3 files changed, 111 insertions(+), 111 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index db1a94b..8d8f068 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -199,16 +199,16 @@ describe("FullNode", () => { eval(`var ${name} = "${addresses[name]}";`); } - should(node.trust.getIndirectTrust(alice, alice)).equal(Infinity); - should(node.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); - should(node.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); - should(node.trust.getIndirectTrust(alice, frank)).equal(0); - should(node.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); - - should(node.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); - should(node.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); - should(node.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); - should(node.trust.getIndirectTrust(george, eve)).equal(0); + node.trust.getIndirectTrust(alice, alice).should.equal(Infinity); + node.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); + node.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); + node.trust.getIndirectTrust(alice, frank).should.equal(0); + node.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); + + node.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); + node.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); + node.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); + node.trust.getIndirectTrust(george, eve).should.equal(0); }); it("after decreasing some trusts computes trusts correctly", async () => { @@ -219,11 +219,11 @@ describe("FullNode", () => { mtxs.length.should.equal(1); var mtx = await mtxs[0]; - should(await mtx.verify()).be.true(); + (await mtx.verify()).should.be.true(); node.sendTX(mtx.toTX()); await testHelpers.delay(750); - should(node.trust.getIndirectTrust(addresses.alice, addresses.bob)).equal(7 * COIN); + node.trust.getIndirectTrust(addresses.alice, addresses.bob).should.equal(7 * COIN); }); }); diff --git a/test/spv_node.js b/test/spv_node.js index 5b22ca9..4c362ef 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -141,7 +141,7 @@ describe("SPVNode", () => { mtx.addCoin(coinbaseCoin); mtx.sign(KeyRing.fromPrivate(privateKey1, true, "regtest")); - should(await mtx.verify()).be.true(); + (await mtx.verify()).should.be.true(); var tx = mtx.toTX(); tx.isWatched(spvNode.pool.spvFilter).should.be.true(); @@ -188,7 +188,7 @@ describe("SPVNode", () => { await minerWatcher.waitForTX(minerSpvTX); await spvWatcher.waitForTX(minerSpvTX); - should(Trust.TrustIsRisk.prototype.addTX.callCount).equal(4); + Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(4); var spv2TX = await spvWallet1.send({ outputs: [{ @@ -199,7 +199,7 @@ describe("SPVNode", () => { await spvWatcher.waitForTX(spv2TX); await minerWatcher.waitForTX(spv2TX); - should(Trust.TrustIsRisk.prototype.addTX.callCount).equal(6); + Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(6); var spvMinerTX = await spvWallet2.send({ outputs: [{ @@ -214,8 +214,8 @@ describe("SPVNode", () => { var actualBalance = (await minerWallet1.getBalance()).unconfirmed; var expectedBalance = consensus.BASE_REWARD - 10 * COIN + 7 * COIN - miner2TX.getFee(view); - should(actualBalance).equal(expectedBalance); - should(Trust.TrustIsRisk.prototype.addTX.callCount).equal(8); + actualBalance.should.equal(expectedBalance); + Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(8); }); describe("with the nobodyLikesFrank.json example", () => { @@ -424,16 +424,16 @@ describe("SPVNode", () => { eval(`var ${name} = "${addresses[name]}";`); } - should(miner.trust.getIndirectTrust(alice, alice)).equal(Infinity); - should(miner.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); - should(miner.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); - should(miner.trust.getIndirectTrust(alice, frank)).equal(0); - should(miner.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + miner.trust.getIndirectTrust(alice, alice).should.equal(Infinity); + miner.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); + miner.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); + miner.trust.getIndirectTrust(alice, frank).should.equal(0); + miner.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); - should(miner.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); - should(miner.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); - should(miner.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); - should(miner.trust.getIndirectTrust(george, eve)).equal(0); + miner.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); + miner.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); + miner.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); + miner.trust.getIndirectTrust(george, eve).should.equal(0); }); it("lets the SPV node compute trusts correctly", () => { @@ -441,16 +441,16 @@ describe("SPVNode", () => { eval(`var ${name} = "${addresses[name]}";`); } - should(spvNode.trust.getIndirectTrust(alice, alice)).equal(Infinity); - should(spvNode.trust.getIndirectTrust(alice, bob)).equal(10 * COIN); - should(spvNode.trust.getIndirectTrust(alice, charlie)).equal(1 * COIN); - should(spvNode.trust.getIndirectTrust(alice, frank)).equal(0); - should(spvNode.trust.getIndirectTrust(alice, eve)).equal(6 * COIN); + spvNode.trust.getIndirectTrust(alice, alice).should.equal(Infinity); + spvNode.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); + spvNode.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); + spvNode.trust.getIndirectTrust(alice, frank).should.equal(0); + spvNode.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); - should(spvNode.trust.getIndirectTrust(bob, alice)).equal(1 * COIN); - should(spvNode.trust.getIndirectTrust(bob, eve)).equal(3 * COIN); - should(spvNode.trust.getIndirectTrust(dave, eve)).equal(12 * COIN); - should(spvNode.trust.getIndirectTrust(george, eve)).equal(0); + spvNode.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); + spvNode.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); + spvNode.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); + spvNode.trust.getIndirectTrust(george, eve).should.equal(0); }); it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { @@ -461,17 +461,17 @@ describe("SPVNode", () => { mtxs.length.should.equal(1); var mtx = mtxs[0]; - should(await mtx.verify()).be.true(); + (await mtx.verify()).should.be.true(); var tx = mtx.toTX(); miner.sendTX(tx); await testHelpers.delay(3000); await minerWatcher.waitForTX(tx); await spvWatcher.waitForTX(tx); - should(miner.trust.getIndirectTrust(addresses["alice"], - addresses["bob"])).equal(7 * COIN); - should(spvNode.trust.getIndirectTrust(addresses["alice"], - addresses["bob"])).equal(7 * COIN); + miner.trust.getIndirectTrust(addresses["alice"], + addresses["bob"]).should.equal(7 * COIN); + spvNode.trust.getIndirectTrust(addresses["alice"], + addresses["bob"]).should.equal(7 * COIN); mtxs = spvNode.trust.createTrustDecreasingMTXs( rings["dave"].getPrivateKey(), @@ -480,15 +480,15 @@ describe("SPVNode", () => { mtxs.length.should.equal(1); mtx = mtxs[0]; - should(await mtx.verify()).be.true(); + (await mtx.verify()).should.be.true(); spvNode.sendTX(mtx.toTX()); await minerWatcher.waitForTX(); await spvWatcher.waitForTX(); - should(miner.trust.getIndirectTrust(addresses["dave"], - addresses["eve"])).equal(10 * COIN); - should(spvNode.trust.getIndirectTrust(addresses["dave"], - addresses["eve"])).equal(10 * COIN); + miner.trust.getIndirectTrust(addresses["dave"], + addresses["eve"]).should.equal(10 * COIN); + spvNode.trust.getIndirectTrust(addresses["dave"], + addresses["eve"]).should.equal(10 * COIN); }); }); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index fc9f4b3..43d9b17 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -147,7 +147,7 @@ describe("TrustIsRisk", () => { it("which has been processed before throws", () => { var tx = trustIncreasingMTX.toTX(); - should(tir.addTX(tx)).be.true(); + tir.addTX(tx).should.be.true(); should.throws(() => tir.addTX(tx), /already processed/i); tir.getDirectTrust(alice, bob).should.equal(42 * COIN); }); @@ -318,15 +318,15 @@ describe("TrustIsRisk", () => { describe(".getIndirectTrust()", () => { it("returns zero for two arbitary parties that do not trust each other", () => { - should(tir.getIndirectTrust(alice, bob)).equal(0); - should(tir.getIndirectTrust(bob, alice)).equal(0); - should(tir.getIndirectTrust(charlie, alice)).equal(0); - should(tir.getIndirectTrust(alice, charlie)).equal(0); + tir.getIndirectTrust(alice, bob).should.equal(0); + tir.getIndirectTrust(bob, alice).should.equal(0); + tir.getIndirectTrust(charlie, alice).should.equal(0); + tir.getIndirectTrust(alice, charlie).should.equal(0); }); it("returns Infinity for one's trust to themselves", () => { - should(tir.getIndirectTrust(alice, alice)).equal(Infinity); - should(tir.getIndirectTrust(bob, bob)).equal(Infinity); + tir.getIndirectTrust(alice, alice).should.equal(Infinity); + tir.getIndirectTrust(bob, bob).should.equal(Infinity); }); describe("after applying the Nobody Likes Frank graph example", () => { @@ -335,69 +335,69 @@ describe("TrustIsRisk", () => { }); it("correctly computes trusts", () => { - should(tir.getIndirectTrust(alice, alice)).equal(Infinity); - should(tir.getIndirectTrust(alice, bob)).equal(10); - should(tir.getIndirectTrust(alice, charlie)).equal(1); - should(tir.getIndirectTrust(alice, dave)).equal(4); - should(tir.getIndirectTrust(alice, eve)).equal(6); - should(tir.getIndirectTrust(alice, frank)).equal(0); - should(tir.getIndirectTrust(alice, george)).equal(2); - - should(tir.getIndirectTrust(bob, alice)).equal(1); - should(tir.getIndirectTrust(bob, bob)).equal(Infinity); - should(tir.getIndirectTrust(bob, charlie)).equal(1); - should(tir.getIndirectTrust(bob, dave)).equal(1); - should(tir.getIndirectTrust(bob, eve)).equal(3); - should(tir.getIndirectTrust(bob, frank)).equal(0); - should(tir.getIndirectTrust(bob, george)).equal(2); - - should(tir.getIndirectTrust(charlie, alice)).equal(0); - should(tir.getIndirectTrust(charlie, bob)).equal(0); - should(tir.getIndirectTrust(charlie, charlie)).equal(Infinity); - should(tir.getIndirectTrust(charlie, dave)).equal(0); - should(tir.getIndirectTrust(charlie, eve)).equal(0); - should(tir.getIndirectTrust(charlie, frank)).equal(0); - should(tir.getIndirectTrust(charlie, george)).equal(3); - - should(tir.getIndirectTrust(dave, alice)).equal(2); - should(tir.getIndirectTrust(dave, bob)).equal(2); - should(tir.getIndirectTrust(dave, charlie)).equal(1); - should(tir.getIndirectTrust(dave, dave)).equal(Infinity); - should(tir.getIndirectTrust(dave, eve)).equal(12); - should(tir.getIndirectTrust(dave, frank)).equal(0); - should(tir.getIndirectTrust(dave, george)).equal(2); - - should(tir.getIndirectTrust(eve, alice)).equal(0); - should(tir.getIndirectTrust(eve, bob)).equal(0); - should(tir.getIndirectTrust(eve, charlie)).equal(0); - should(tir.getIndirectTrust(eve, dave)).equal(0); - should(tir.getIndirectTrust(eve, eve)).equal(Infinity); - should(tir.getIndirectTrust(eve, frank)).equal(0); - should(tir.getIndirectTrust(eve, george)).equal(0); - - should(tir.getIndirectTrust(frank, alice)).equal(0); - should(tir.getIndirectTrust(frank, bob)).equal(0); - should(tir.getIndirectTrust(frank, charlie)).equal(10); - should(tir.getIndirectTrust(frank, dave)).equal(0); - should(tir.getIndirectTrust(frank, eve)).equal(0); - should(tir.getIndirectTrust(frank, frank)).equal(Infinity); - should(tir.getIndirectTrust(frank, george)).equal(3); - - should(tir.getIndirectTrust(george, alice)).equal(0); - should(tir.getIndirectTrust(george, bob)).equal(0); - should(tir.getIndirectTrust(george, charlie)).equal(0); - should(tir.getIndirectTrust(george, dave)).equal(0); - should(tir.getIndirectTrust(george, eve)).equal(0); - should(tir.getIndirectTrust(george, frank)).equal(0); - should(tir.getIndirectTrust(george, george)).equal(Infinity); + tir.getIndirectTrust(alice, alice).should.equal(Infinity); + tir.getIndirectTrust(alice, bob).should.equal(10); + tir.getIndirectTrust(alice, charlie).should.equal(1); + tir.getIndirectTrust(alice, dave).should.equal(4); + tir.getIndirectTrust(alice, eve).should.equal(6); + tir.getIndirectTrust(alice, frank).should.equal(0); + tir.getIndirectTrust(alice, george).should.equal(2); + + tir.getIndirectTrust(bob, alice).should.equal(1); + tir.getIndirectTrust(bob, bob).should.equal(Infinity); + tir.getIndirectTrust(bob, charlie).should.equal(1); + tir.getIndirectTrust(bob, dave).should.equal(1); + tir.getIndirectTrust(bob, eve).should.equal(3); + tir.getIndirectTrust(bob, frank).should.equal(0); + tir.getIndirectTrust(bob, george).should.equal(2); + + tir.getIndirectTrust(charlie, alice).should.equal(0); + tir.getIndirectTrust(charlie, bob).should.equal(0); + tir.getIndirectTrust(charlie, charlie).should.equal(Infinity); + tir.getIndirectTrust(charlie, dave).should.equal(0); + tir.getIndirectTrust(charlie, eve).should.equal(0); + tir.getIndirectTrust(charlie, frank).should.equal(0); + tir.getIndirectTrust(charlie, george).should.equal(3); + + tir.getIndirectTrust(dave, alice).should.equal(2); + tir.getIndirectTrust(dave, bob).should.equal(2); + tir.getIndirectTrust(dave, charlie).should.equal(1); + tir.getIndirectTrust(dave, dave).should.equal(Infinity); + tir.getIndirectTrust(dave, eve).should.equal(12); + tir.getIndirectTrust(dave, frank).should.equal(0); + tir.getIndirectTrust(dave, george).should.equal(2); + + tir.getIndirectTrust(eve, alice).should.equal(0); + tir.getIndirectTrust(eve, bob).should.equal(0); + tir.getIndirectTrust(eve, charlie).should.equal(0); + tir.getIndirectTrust(eve, dave).should.equal(0); + tir.getIndirectTrust(eve, eve).should.equal(Infinity); + tir.getIndirectTrust(eve, frank).should.equal(0); + tir.getIndirectTrust(eve, george).should.equal(0); + + tir.getIndirectTrust(frank, alice).should.equal(0); + tir.getIndirectTrust(frank, bob).should.equal(0); + tir.getIndirectTrust(frank, charlie).should.equal(10); + tir.getIndirectTrust(frank, dave).should.equal(0); + tir.getIndirectTrust(frank, eve).should.equal(0); + tir.getIndirectTrust(frank, frank).should.equal(Infinity); + tir.getIndirectTrust(frank, george).should.equal(3); + + tir.getIndirectTrust(george, alice).should.equal(0); + tir.getIndirectTrust(george, bob).should.equal(0); + tir.getIndirectTrust(george, charlie).should.equal(0); + tir.getIndirectTrust(george, dave).should.equal(0); + tir.getIndirectTrust(george, eve).should.equal(0); + tir.getIndirectTrust(george, frank).should.equal(0); + tir.getIndirectTrust(george, george).should.equal(Infinity); }); it("correctly computes trusts when bob trusts frank", () => { tir.addTX(testHelpers.getTrustIncreasingMTX(addr.bob.pubKey, addr.frank.pubKey, 8).toTX()); - should(tir.getIndirectTrust(george, frank)).equal(0); - should(tir.getIndirectTrust(alice, frank)).equal(8); - should(tir.getIndirectTrust(dave, frank)).equal(2); - should(tir.getIndirectTrust(bob, frank)).equal(8); + tir.getIndirectTrust(george, frank).should.equal(0); + tir.getIndirectTrust(alice, frank).should.equal(8); + tir.getIndirectTrust(dave, frank).should.equal(2); + tir.getIndirectTrust(bob, frank).should.equal(8); }); // TODO: Decrement direct trusts and test that indirect trusts update correctly From 3a7a21f89d32820df529b5836bfe3455b74df849 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 12 Jan 2018 20:18:28 +0100 Subject: [PATCH 379/540] Rename getTrDecMTX() to createTrDecMTX() --- src/trust_is_risk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 98f0b55..5c1b000 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -229,11 +229,11 @@ class TrustIsRisk { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.getTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, fee); + return this.createTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, fee); }).filter(Boolean); } - async getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, + async createTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, signingKeyRing : bcoin$KeyRing, fee : ?number) : Promise { if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this From 673fd463c8f4be0146556d13663b317603c68b5e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 16 Jan 2018 10:51:05 +0000 Subject: [PATCH 380/540] Join short lines --- src/trust_is_risk.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 5c1b000..9bf25fb 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -155,8 +155,7 @@ class TrustIsRisk { (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 ); if (!coin) throw new Error("Could not find coin"); - if (origin === dest) - throw new Error("Can not increase self-trust."); + if (origin === dest) throw new Error("Can not increase self-trust."); var originKeyRing = KeyRing.fromPrivate(origin); var originPubKey = originKeyRing.getPublicKey(); From c67af0d09f4f462ed339ab1cbb9a9bdfda0e0e0c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 16 Jan 2018 10:58:17 +0000 Subject: [PATCH 381/540] Merge full and spv trust increasing functions Remove ccreateTrustIncreasingMTX(), pass wallet to createTrustIncreasingMTX() only from spv node and add logic to discern optional arguments fee and wallet. --- src/trust_is_risk.js | 57 ++++++++++---------------------------------- test/spv_node.js | 23 ++++++------------ 2 files changed, 20 insertions(+), 60 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 9bf25fb..a83c421 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -107,53 +107,22 @@ class TrustIsRisk { // payable to the sender. The origin key must be a private key. Any satoshis not spent will be // returned to the sender, minus the fees, via P2PKH. async createTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, - trustAmount : number, fee : ?number) + trustAmount : number, wallet : ?bcoin$Wallet, fee : ?number) : Promise { - if (!fee) fee = 1000; // TODO: estimate this - var coin = await this.node.getCoin(outpoint.hash, outpoint.index); - if (!coin) throw new Error("Could not find coin"); - if (origin === dest) throw new Error("Can not increase self-trust."); - - var originKeyRing = KeyRing.fromPrivate(origin); - var originPubKey = originKeyRing.getPublicKey(); - - var mtx = new MTX({ - outputs: [ - new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), - value: trustAmount - }) - ] - }); - - var changeAmount = coin.value - trustAmount - fee; - assert(changeAmount >= 0); - if (changeAmount) { - mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), - value: changeAmount - })); + if (wallet && typeof wallet === "number") { + fee = wallet; + wallet = null; } - - mtx.addCoin(coin); - var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); - assert(success); - - var signedCount = mtx.sign(originKeyRing); - assert(signedCount === 1); - - return mtx; - } - - async ccreateTrustIncreasingMTX(origin : Key, dest : Key, - outpoint : bcoin$Outpoint, trustAmount : number, - wallet : bcoin$Wallet, fee : ?number) - : Promise { - assert(this.node.spv, "Only spv nodes should call this"); if (!fee) fee = 1000; // TODO: estimate this - var coin = await bcoin.primitives.Coin.fromTX( - (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 - ); + var coin = null; + if (wallet) { // only the spv node passes the wallet + coin = await bcoin.primitives.Coin.fromTX( + (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 + ); + } + else { // for full nodes, getting the coin is more straightforward + coin = await this.node.getCoin(outpoint.hash, outpoint.index); + } if (!coin) throw new Error("Could not find coin"); if (origin === dest) throw new Error("Can not increase self-trust."); diff --git a/test/spv_node.js b/test/spv_node.js index 4c362ef..09d3606 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -381,22 +381,13 @@ describe("SPVNode", () => { let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let mtx = null; - if (node.spv) { - mtx = await node.trust.ccreateTrustIncreasingMTX( - rings[origin].getPrivateKey(), - rings[dest].getPublicKey(), - outpoint, - value * consensus.COIN, - spvWallets[origin]); - } - else { // if full node - mtx = await node.trust.createTrustIncreasingMTX( - rings[origin].getPrivateKey(), - rings[dest].getPublicKey(), - outpoint, - value * consensus.COIN); - } + let wallet = (node.spv) ? spvWallets[origin] : null; + let mtx = await node.trust.createTrustIncreasingMTX( + rings[origin].getPrivateKey(), + rings[dest].getPublicKey(), + outpoint, + value * consensus.COIN, + wallet); assert(await mtx.verify()); From 98d2fb3b95bfeabe1412c2a4047c6e9d8ba22b6e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 16 Jan 2018 11:02:01 +0000 Subject: [PATCH 382/540] Let spv node decrease trust correctly Use logic similar to createTrustIncreasingMTX() for createTrustDecreasingMTX(s)(). This way only an spv node passes the wallet and thus the former function can correctly decide whether to use the wallet to obtain the coin. Using the wallet is necessary in the case of an spv node, because this kind of node does not have the getCoin() method. --- src/trust_is_risk.js | 20 ++++++++++++++++---- test/spv_node.js | 11 ++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index a83c421..cff560e 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -165,7 +165,7 @@ class TrustIsRisk { // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. async createTrustDecreasingMTXs(origin : Key, dest : Key, - trustDecreaseAmount : number, payee : ?Entity, + trustDecreaseAmount : number, wallet : ?bcoin$Wallet, payee : ?Entity, steal : ?boolean, fee : ?number) : Promise[]> { if (steal === undefined) steal = false; @@ -197,16 +197,28 @@ class TrustIsRisk { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.createTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, fee); + return this.createTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, wallet, fee); }).filter(Boolean); } async createTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, - signingKeyRing : bcoin$KeyRing, fee : ?number) : Promise { + signingKeyRing : bcoin$KeyRing, wallet : ?bcoin$Wallet, fee : ?number) : Promise { if (!payee) payee = directTrust.getOriginEntity(); + if (wallet && typeof wallet === "number") { + fee = wallet; + wallet = null; + } if (!fee) fee = 1000; // TODO: estimate this var outpoint = new Outpoint(directTrust.txHash, directTrust.outputIndex); - var coin = await this.node.getCoin(outpoint.hash, outpoint.index); + var coin = null; + if (wallet) { // only the spv node passes the wallet + coin = await bcoin.primitives.Coin.fromTX( + (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 + ); + } + else { + coin = await this.node.getCoin(outpoint.hash, outpoint.index); + } if (!coin) throw new Error("Could not find coin"); var mtx = new MTX({ diff --git a/test/spv_node.js b/test/spv_node.js index 09d3606..74f0359 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -445,12 +445,12 @@ describe("SPVNode", () => { }); it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { - var mtxs = miner.trust.createTrustDecreasingMTXs( + var mtxs = await miner.trust.createTrustDecreasingMTXs( rings["alice"].getPrivateKey(), rings["bob"].getPublicKey(), 3 * COIN ); mtxs.length.should.equal(1); - var mtx = mtxs[0]; + var mtx = await mtxs[0]; (await mtx.verify()).should.be.true(); var tx = mtx.toTX(); @@ -464,12 +464,13 @@ describe("SPVNode", () => { spvNode.trust.getIndirectTrust(addresses["alice"], addresses["bob"]).should.equal(7 * COIN); - mtxs = spvNode.trust.createTrustDecreasingMTXs( + mtxs = await spvNode.trust.createTrustDecreasingMTXs( rings["dave"].getPrivateKey(), - rings["eve"].getPublicKey(), 2 * COIN + rings["eve"].getPublicKey(), 2 * COIN, + spvWallets["dave"] ); mtxs.length.should.equal(1); - mtx = mtxs[0]; + mtx = await mtxs[0]; (await mtx.verify()).should.be.true(); spvNode.sendTX(mtx.toTX()); From 64c82abd6899d405ace374416c2ca0d57b6c4d95 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 16 Jan 2018 21:45:59 +0000 Subject: [PATCH 383/540] Add changes to note --- note | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/note b/note index 6097b73..37a6c82 100644 --- a/note +++ b/note @@ -1 +1,3 @@ -added lines 268,269 at node_modules/bcoin/lib/node/spvnode.js +added lines 268,269 at node_modules/bcoin/lib/node/spvnode.js: + this.pool.txFilter.add(item.hash()); + this.emit('tx', item); From 2681739af907c6cf2a0709d6e8f61c440741e5a9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 12 Feb 2018 10:55:04 +0000 Subject: [PATCH 384/540] Add suggestion from bcoin --- note | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/note b/note index 37a6c82..422291e 100644 --- a/note +++ b/note @@ -1,3 +1,11 @@ added lines 268,269 at node_modules/bcoin/lib/node/spvnode.js: this.pool.txFilter.add(item.hash()); this.emit('tx', item); + +Javed Khan: + +@orfeas ok yeah I see the problem. Since there's no mempool on a spv node, it seems to be missing unconfirmed transactions, unless relayed by another node + +btw I think you can just listen to 'tx' event on the node rather than digging into the txFilter etc. + +Might make sense to have a way for `relay` to signal and emit the `tx` event in spv mode From 3afc8412e3d0504b44dd90b81e80113c3c133c6f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 13 Feb 2018 13:53:35 +0000 Subject: [PATCH 385/540] Add another suggestion from bcoin --- note | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/note b/note index 422291e..0ff05ea 100644 --- a/note +++ b/note @@ -9,3 +9,10 @@ Javed Khan: btw I think you can just listen to 'tx' event on the node rather than digging into the txFilter etc. Might make sense to have a way for `relay` to signal and emit the `tx` event in spv mode + + +Node Chkuaselidze: + +`pool.txFilter` is used for tracking transactions it has seen, so it doesn't reuqest them again. + +It's a probably good idea to update txFilter when you send tx, if you don't want to redownload your transaction. And yes that should go to sendTX method instead. and relay can use sendTX like in fullnode case. From 8d6ba9c670466420a0f6afb96c2f49cbf60a9718 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 17 Feb 2018 19:11:18 +0000 Subject: [PATCH 386/540] Add minimal testcase for tx circulation This testcase shows that an spv node does not correctly add a newly sent transaction to its txFilter. The same is done with a full node for comparison. --- minimal_testcases/spvandfullsend/helpers.js | 100 ++++++++++++++++++++ minimal_testcases/spvandfullsend/minimal.js | 46 +++++++++ 2 files changed, 146 insertions(+) create mode 100644 minimal_testcases/spvandfullsend/helpers.js create mode 100644 minimal_testcases/spvandfullsend/minimal.js diff --git a/minimal_testcases/spvandfullsend/helpers.js b/minimal_testcases/spvandfullsend/helpers.js new file mode 100644 index 0000000..6ba8b6f --- /dev/null +++ b/minimal_testcases/spvandfullsend/helpers.js @@ -0,0 +1,100 @@ +const WalletDB = require("bcoin/lib/wallet/walletdb"); +const bcoin = require("bcoin"); +const consensus = require("bcoin/lib/protocol/consensus"); + +const helpers = { + delay: async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); + }, + + getNodeAndWalletDB: async (type) => { + if (type !== "spv" && type !== "full") + throw Error("Wrong node type"); + + const node = (type === "spv") ? + new bcoin.spvnode({ + network: bcoin.network.get().toString(), + port: 48445, + passphrase: "secret", + nodes: ["127.0.0.1:48448"] + }) + : // if type === "full" + new bcoin.fullnode({ + network: bcoin.network.get().toString(), + port: 48448, + bip37: true, + listen: true, + passphrase: "secret", + }); + + await node.open(); + + const walletDB = new WalletDB({ + network: node.network, + db: "memory", + client: new bcoin.node.NodeClient(node), + spv: node.spv + }); + + await walletDB.open(); + await walletDB.connect(); + await node.connect(); + node.startSync(); + + return [node, walletDB]; + }, + + getWallet: async (walletDB, id) => { + var options = { + id, + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }; + + return walletDB.create(options); + }, + + mineAndPaySPV: async (fullNode, fullWallet, spvWallet) => { + const block = await fullNode.miner.mineBlock( + fullNode.chain.tip, fullWallet.getAddress("base58") + ); + await fullNode.chain.add(block); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + await helpers.delay(100); + + // @dionyziz: what if I remove await below? + const ret = await fullWallet.send({ + outputs: [{ // give 25 coins to SPV + value: 25 * consensus.COIN, + address: spvWallet.getAddress("base58") + }] + }); + return ret; + }, + + waitForTX: async (node, tx) => { + await new Promise((resolve, reject) => { + var check = (() => { + if (node.spv) { + if (node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) + resolve(); + else setTimeout(check, 100); + } + else { // this is not an SPV node + if (node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + } + }).bind(this); + + check(); + }); + } +}; + +module.exports = helpers; diff --git a/minimal_testcases/spvandfullsend/minimal.js b/minimal_testcases/spvandfullsend/minimal.js new file mode 100644 index 0000000..3235aa4 --- /dev/null +++ b/minimal_testcases/spvandfullsend/minimal.js @@ -0,0 +1,46 @@ +const bcoin = require("bcoin").set("regtest"); +const helpers = require("./helpers"); +const consensus = require("bcoin/lib/protocol/consensus"); +const assert = require("assert"); + +let spvNode; +let spvWalletDB; +let fullNode; +let fullWalletDB; + +(async () => { + [spvNode, spvWalletDB] = await helpers.getNodeAndWalletDB("spv"); + [fullNode, fullWalletDB] = await helpers.getNodeAndWalletDB("full"); + + const spvWallet1 = await helpers.getWallet(spvWalletDB, "spvWallet1"); + const spvWallet2 = await helpers.getWallet(spvWalletDB, "spvWallet2"); + const fullWallet1 = await helpers.getWallet(fullWalletDB, "fullWallet1"); + const fullWallet2 = await helpers.getWallet(fullWalletDB, "fullWallet2"); + + await helpers.delay(1000); + const distributionTX = await helpers.mineAndPaySPV( + fullNode, fullWallet1, spvWallet1 + ); + + await helpers.waitForTX(fullNode, distributionTX); + await helpers.waitForTX(spvNode, distributionTX); + + const TXtoFull = await fullWallet1.send({ + outputs: [{ + value: 10 * consensus.COIN, + address: fullWallet2.getAddress("base58") + }] + }); + await helpers.waitForTX(fullNode, TXtoFull); + console.log("one"); + + const TXtoSPV = await spvWallet1.send({ + outputs: [{ + value: 10 * consensus.COIN, + address: spvWallet2.getAddress("base58") + }] + }); + await helpers.waitForTX(spvNode, TXtoSPV); + console.log("success!"); + process.exit(); +})(); From 966fdd4c55c5693d21e1da76aa810cf135380707 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 17 Feb 2018 19:14:01 +0000 Subject: [PATCH 387/540] Remove old entry from .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index c09af18..b4e253f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ node_modules/ lib/ *.swp -minimal.js From 8b4be6785807e92d66d067a71043b498e7a45acc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Feb 2018 18:59:52 +0000 Subject: [PATCH 388/540] Change spv sendTX() minimal testcase Remove comments, remove full node testing --- minimal_testcases/spvandfullsend/helpers.js | 3 +-- minimal_testcases/spvandfullsend/minimal.js | 9 --------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/minimal_testcases/spvandfullsend/helpers.js b/minimal_testcases/spvandfullsend/helpers.js index 6ba8b6f..e66d61e 100644 --- a/minimal_testcases/spvandfullsend/helpers.js +++ b/minimal_testcases/spvandfullsend/helpers.js @@ -66,8 +66,7 @@ const helpers = { // Make the coin spendable. consensus.COINBASE_MATURITY = 0; await helpers.delay(100); - - // @dionyziz: what if I remove await below? + const ret = await fullWallet.send({ outputs: [{ // give 25 coins to SPV value: 25 * consensus.COIN, diff --git a/minimal_testcases/spvandfullsend/minimal.js b/minimal_testcases/spvandfullsend/minimal.js index 3235aa4..44ff147 100644 --- a/minimal_testcases/spvandfullsend/minimal.js +++ b/minimal_testcases/spvandfullsend/minimal.js @@ -25,15 +25,6 @@ let fullWalletDB; await helpers.waitForTX(fullNode, distributionTX); await helpers.waitForTX(spvNode, distributionTX); - const TXtoFull = await fullWallet1.send({ - outputs: [{ - value: 10 * consensus.COIN, - address: fullWallet2.getAddress("base58") - }] - }); - await helpers.waitForTX(fullNode, TXtoFull); - console.log("one"); - const TXtoSPV = await spvWallet1.send({ outputs: [{ value: 10 * consensus.COIN, From 00a5f47dbe6bd320179c9720e71e221991480811 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Feb 2018 19:06:56 +0000 Subject: [PATCH 389/540] Stop explicitly watching addresses These addresses should (and indeed seem to) be automatically added to the bloom filter. --- test/spv_node.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 74f0359..86233d7 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -154,12 +154,6 @@ describe("SPVNode", () => { var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); - spvNode.pool.watchAddress(minerWallet1.getAddress()); - spvNode.pool.watchAddress(minerWallet2.getAddress()); - - spvNode.pool.watchAddress(spvWallet1.getAddress()); - spvNode.pool.watchAddress(spvWallet2.getAddress()); - await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. await testHelpers.mineBlock(miner, minerWallet1.getAddress("base58")); From 1769c1c4654e45a74f33c1248ef5b691f0906ea7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 26 Feb 2018 19:13:48 +0000 Subject: [PATCH 390/540] Fix bug in trust-is-risk test .getTrustDecreasingMTX() did not await correctly for all checks to complete and erroneously showed that all tests passed. Now we correctly await for the tests to complete. Unfortunately, this way the tests don't pass. --- test/trust_is_risk.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 43d9b17..83ec55a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -289,18 +289,18 @@ describe("TrustIsRisk", () => { mtx.outputs[0].value.should.equal(40 * COIN - 1000); }; - it("creates correct trust decreasing transactions", () => { + it("creates correct trust decreasing transactions", async () => { var mtxs = tir.createTrustDecreasingMTXs( addr.alice.privKey, addr.bob.pubKey, 82 * COIN ); - checkMTXs(mtxs, alice); + await checkMTXs(mtxs, alice); }); - it("creates correct trust stealing transactions", () => { + it("creates correct trust stealing transactions", async () => { var mtxs = tir.createTrustDecreasingMTXs( addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie ); - checkMTXs(mtxs, charlie); + await checkMTXs(mtxs, charlie); }); it("throws when trying to decrease self-trust", () => { From c8f46e2dbcdb1d8d2a8da1452f1b2f0c32aaaffd Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Feb 2018 19:38:33 +0000 Subject: [PATCH 391/540] Use bcoin@1.0.0-beta.15 in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce2fc51..2e411a7 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "sinon": "^2.2.0" }, "dependencies": { - "bcoin": "^1.0.0-beta.12", + "bcoin": "^1.0.0-beta.15", "graph-theory-ford-fulkerson": "^1.0.0", "sorted-set": "^0.3.0" } From 069c3e9b6a12dc1b0c808ab052c15f393a8d37be Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Feb 2018 20:07:33 +0000 Subject: [PATCH 392/540] Change {from,to}Base58 to {from,to}String This change refers to uses of the two functions of Address. Suggested by CHANGELOG.md in bcoin --- flow-typed/npm/bcoin_vx.x.x.js | 4 ++-- minimal_testcases/mfull.js | 2 +- minimal_testcases/sign.js | 4 ++-- src/helpers.js | 2 +- src/trust_is_risk.js | 6 +++--- test/helpers.js | 2 +- test/trust_is_risk.js | 8 ++++---- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 210f75e..d9c9d47 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -69,9 +69,9 @@ declare class bcoin$Address { PUBKEYHASH : number }; - toBase58() : string; + toString() : string; static fromHash(Hash) : bcoin$Address; - static fromBase58(string) : bcoin$Address; + static fromString(string) : bcoin$Address; } declare class bcoin$TX { diff --git a/minimal_testcases/mfull.js b/minimal_testcases/mfull.js index e8c0daf..24bd270 100644 --- a/minimal_testcases/mfull.js +++ b/minimal_testcases/mfull.js @@ -63,7 +63,7 @@ const COIN = consensus.COIN; return testHelpers.getP2PKHOutput( Address.fromHash(bcoin.crypto.hash160( rings[name].getPublicKey()) - ).toBase58(), + ).toString(), sendAmount * consensus.COIN); }); diff --git a/minimal_testcases/sign.js b/minimal_testcases/sign.js index 73acba1..017b7f2 100644 --- a/minimal_testcases/sign.js +++ b/minimal_testcases/sign.js @@ -97,12 +97,12 @@ var assert = require("assert"); fullWallet.getAddress("base58"), "secret" ); var fullAddr = Address.fromHash(bcoin.crypto.hash160( - fullRing.getPublicKey())).toBase58(); + fullRing.getPublicKey())).toString(); var spvRing = await spvWallet.getPrivateKey( spvWallet.getAddress("base58"), "secret" ); var spvAddr = Address.fromHash(bcoin.crypto.hash160( - spvRing.getPublicKey())).toBase58(); + spvRing.getPublicKey())).toString(); /* * End setup diff --git a/src/helpers.js b/src/helpers.js index 89b0a34..7418960 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -106,7 +106,7 @@ var helpers = { pubKeyToEntity: (key : Key, network : bcoin$Network) : Entity => { return Address.fromHash(bcoin.crypto.hash160(key), - Address.types.PUBKEYHASH, -1, network).toBase58(); + Address.types.PUBKEYHASH, -1, network).toString(); }, delay: async (milliseconds : number) => { diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index cff560e..965506c 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -223,7 +223,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), + script: bcoin.script.fromPubkeyhash(Address.fromString(payee).hash), value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) })] // TODO: do not add this output if its value is 0 }); @@ -253,7 +253,7 @@ class TrustIsRisk { var input = tx.inputs[0]; if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; - var origin = tx.inputs[0].getAddress().toBase58(); + var origin = tx.inputs[0].getAddress().toString(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -314,7 +314,7 @@ class TrustIsRisk { isChangeOutput(output : bcoin$Output, origin : Entity) : boolean { return (output.getType() === "pubkeyhash") - && (output.getAddress().toBase58() === origin); + && (output.getAddress().toString() === origin); } parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, diff --git a/test/helpers.js b/test/helpers.js index 7fefe31..dd8cecf 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -49,7 +49,7 @@ var testHelpers = { }, getP2PKHOutput: (dest, value) => { - var address = bcoin.primitives.Address.fromBase58(dest); + var address = bcoin.primitives.Address.fromString(dest); var script = bcoin.script.fromPubkeyhash(address.hash); return new bcoin.primitives.Output({script, value}); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 83ec55a..1951ff5 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -70,7 +70,7 @@ describe("TrustIsRisk", () => { }); it("is a valid bitcoin address", () => { - assert(bcoin.primitives.Address.fromBase58(tir.tag.toString("ascii"))); + assert(bcoin.primitives.Address.fromString(tir.tag.toString("ascii"))); }); }); @@ -224,7 +224,7 @@ describe("TrustIsRisk", () => { var changeOutput = mtx.outputs[1]; changeOutput.getType().should.equal("pubkeyhash"); - changeOutput.getAddress().toBase58().should.equal(alice); + changeOutput.getAddress().toString().should.equal(alice); changeOutput.value.should.equal(900 * COIN - 1000); }); }); @@ -270,7 +270,7 @@ describe("TrustIsRisk", () => { mtx.outputs.length.should.equal(1); // Single P2PKH output mtx.outputs[0].getType().should.equal("pubkeyhash"); - mtx.outputs[0].getAddress().toBase58().should.equal(recipient); + mtx.outputs[0].getAddress().toString().should.equal(recipient); mtx.outputs[0].value.should.equal(42 * COIN - 1000); mtx = await mtxs[1]; @@ -285,7 +285,7 @@ describe("TrustIsRisk", () => { mtx.outputs[1].script.toString().should.equal(trustTXs[1].outputs[0].script.toString()); mtx.outputs[1].value.should.equal(60 * COIN); mtx.outputs[0].getType().should.equal("pubkeyhash"); - mtx.outputs[0].getAddress().toBase58().should.equal(recipient); + mtx.outputs[0].getAddress().toString().should.equal(recipient); mtx.outputs[0].value.should.equal(40 * COIN - 1000); }; From a1f0b5b7b4bfc3a1eda167b77c37d8914f1a5bd6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 26 Feb 2018 09:10:54 +0000 Subject: [PATCH 393/540] Change from ec-secp256k1 to secp256k1 File structure has changed, thus we require() a different file. --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1951ff5..c80b042 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -7,7 +7,7 @@ var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); -var secp256k1 = require("bcoin/lib/crypto/ec-secp256k1"); +var secp256k1 = require("bcoin/lib/crypto/secp256k1"); var sinon = require("sinon"); var should = require("should"); var fixtures = require("./fixtures"); From 138cecaee14a6be59f051ee0e9302db11fdf5b72 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 26 Feb 2018 09:23:24 +0000 Subject: [PATCH 394/540] Update walletDB setup Use walletPlugin, stop using NodeClient --- test/full_node.js | 8 ++++++-- test/helpers.js | 14 -------------- test/spv_node.js | 18 +++++++++++++++--- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 8d8f068..c4daab6 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -8,6 +8,7 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; +var walletPlugin = bcoin.wallet.plugin; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); @@ -38,11 +39,14 @@ describe("FullNode", () => { passphrase: "secret" }); + node.use(walletPlugin); await node.open(); }); - beforeEach("get connected walletDB", async () => { - walletDB = await testHelpers.getWalletDB(node); + beforeEach("prepare walletDB", async () => { + walletDB = node.require("walletdb"); + await walletDB.open(); + await walletDB.connect(); }); beforeEach("connect node", async () => { diff --git a/test/helpers.js b/test/helpers.js index dd8cecf..4b64bc8 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,20 +5,6 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - getWalletDB: async (node) => { - var walletDB = new WalletDB({ - network: node.network, - db: "memory", - client: new bcoin.node.NodeClient(node), - spv: node.spv - }); - - await walletDB.open(); - await walletDB.connect(); - - return walletDB; - }, - createWallet: async (walletDB, id) => { var options = { id, diff --git a/test/spv_node.js b/test/spv_node.js index 86233d7..78b37a9 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -8,7 +8,7 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var WalletDB = bcoin.wallet.WalletDB; +var walletPlugin = bcoin.wallet.plugin; var EC = bcoin.crypto.ec; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); @@ -45,8 +45,14 @@ describe("SPVNode", () => { // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); + + spvNode.use(walletPlugin); await spvNode.open(); - spvWalletDB = await testHelpers.getWalletDB(spvNode); + + spvWalletDB = spvNode.require("walletdb"); + await spvWalletDB.open(); + await spvWalletDB.connect(); + await spvNode.connect(); }); @@ -58,8 +64,14 @@ describe("SPVNode", () => { listen: true, passphrase: "secret" }); + + miner.use(walletPlugin); await miner.open(); - minerWalletDB = await testHelpers.getWalletDB(miner); + + minerWalletDB = miner.require("walletdb"); + await minerWalletDB.open(); + await minerWalletDB.connect(); + await miner.connect(); }); From 781caf91b948f255cb52674d6c8fa19b3963e773 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 26 Feb 2018 09:31:19 +0000 Subject: [PATCH 395/540] Use httpPort instead of port option for nodes --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 78b37a9..6c72e2c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -39,7 +39,7 @@ describe("SPVNode", () => { beforeEach("connect SPV node and wallet", async () => { spvNode = new Trust.SPVNode({ network: bcoin.network.get().toString(), - port: 48445, + httpPort: 48445, passphrase: "secret", // logConsole: true, // logLevel: "debug", @@ -59,7 +59,7 @@ describe("SPVNode", () => { beforeEach("connect full node and wallet", async () => { miner = new Trust.FullNode({ network: bcoin.network.get().toString(), - port: 48448, + httpPort: 48448, bip37: true, listen: true, passphrase: "secret" From 5dd7dca8d4186774f52aad1885109bedf17634f3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 26 Feb 2018 18:10:31 +0000 Subject: [PATCH 396/540] Add .data after all Output.script.get() The structure of the object returned by Output.script.get() has changed. --- src/trust_is_risk.js | 10 +++++----- test/trust_is_risk.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 965506c..d8db05c 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -324,18 +324,18 @@ class TrustIsRisk { if (output.getType() !== "multisig") return null; var entities = [1, 2].map((i) => helpers.pubKeyToEntity( - output.script.get(i), this.node.network + output.script.get(i).data, this.node.network )); if (entities[0] === entities[1]) return null; var originPubKey, destPubKey; if (entities[0] === origin) { - originPubKey = output.script.get(1); - destPubKey = output.script.get(2); + originPubKey = output.script.get(1).data; + destPubKey = output.script.get(2).data; } else if (entities[1] === origin) { - originPubKey = output.script.get(2); - destPubKey = output.script.get(1); + originPubKey = output.script.get(2).data; + destPubKey = output.script.get(1).data; } else return null; diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c80b042..04faf8f 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -217,9 +217,9 @@ describe("TrustIsRisk", () => { var trustOutput = mtx.outputs[0]; trustOutput.getType().should.equal("multisig"); [1, 2].map((i) => helpers.pubKeyToEntity( - trustOutput.script.get(i), tir.network + trustOutput.script.get(i).data, tir.network )).sort().should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).should.deepEqual(tir.fakePubKey); + trustOutput.script.get(3).data.should.deepEqual(tir.fakePubKey); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From adfb0795cde4bf864538971ac06ee11ccccda287 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 26 Feb 2018 23:18:56 +0000 Subject: [PATCH 397/540] Update scriptVector() usage Get script from stack returned by new version of scriptVector() --- src/trust_is_risk.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index d8db05c..5ff763c 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -10,6 +10,7 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var Coin = bcoin.primitives.Coin; +var Script = bcoin.script; var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); @@ -148,8 +149,8 @@ class TrustIsRisk { } mtx.addCoin(coin); - var success = mtx.scriptVector(coin.script, mtx.inputs[0].script, originKeyRing); - assert(success); + mtx.inputs[0].script = Script.fromStack(mtx.scriptVector(coin.script, originKeyRing)); + assert(Script.isScript(mtx.inputs[0].script)); var signedCount = mtx.sign(originKeyRing); assert(signedCount === 1); @@ -237,12 +238,12 @@ class TrustIsRisk { } mtx.addCoin(coin); - var success = mtx.scriptVector(((directTrust.script : any) : bcoin$Script), - mtx.inputs[0].script, KeyRing.fromPublic(directTrust.origin)); - assert(success); + mtx.inputs[0].script = Script.fromStack(mtx.scriptVector( + ((directTrust.script : any) : bcoin$Script), KeyRing.fromPublic(directTrust.origin))); + assert(Script.isScript(mtx.inputs[0].script)); - success = mtx.signInput(0, new Coin({script: directTrust.script, value: directTrust.amount}), - signingKeyRing); + var success = mtx.signInput(0, + new Coin({script: directTrust.script, value: directTrust.amount}), signingKeyRing); assert(success); return mtx; From 9178a666f8ff9e2550e7dd95d75975c5b0407741 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 28 Feb 2018 15:49:49 +0000 Subject: [PATCH 398/540] Update flow types Update scriptVector() and get() declarations in bcoin$Script, declare isScript() function, bcoin$Stack class, bcoin$Opcode class --- flow-typed/npm/bcoin_vx.x.x.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index d9c9d47..1eb1a8a 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -93,7 +93,7 @@ declare class bcoin$MTX { toTX() : bcoin$TX; template(ring : bcoin$KeyRing) : number; - scriptVector(outputScript : bcoin$Script, inputScript : bcoin$Script, ring : bcoin$KeyRing) : boolean; + scriptVector(outputScript : bcoin$Script, ring : bcoin$KeyRing) : bcoin$Stack; addOutput(output : bcoin$Output) : void; addCoin(coin : bcoin$Coin) : void; addInput(input : (bcoin$Input | Object)) : void; @@ -122,8 +122,13 @@ declare class bcoin$Input { declare class bcoin$Script { static fromMultisig(m : number, n : number, keys : Buffer[]) : bcoin$Script; static fromPubkeyhash(hash : Hash) : bcoin$Script; + static fromStack(stack : bcoin$Stack) : bcoin$Script; + static isScript(script : bcoin$Script) : boolean; - get(n : number) : (Buffer); + get(n : number) : bcoin$Opcode; +} + +declare class bcoin$Stack { } declare class bcoin$Outpoint { @@ -133,6 +138,11 @@ declare class bcoin$Outpoint { txid() : Buffer; } +declare class bcoin$Opcode { + value : number; + data : Buffer; +} + declare class bcoin$KeyRing { static fromPrivate(key : Buffer, compressed : ?boolean, network : ?Network) : bcoin$KeyRing; static fromPublic(key : Buffer, network : ?Network) : bcoin$KeyRing; From 1602c36635c7f317fa4195716cb874c1db0b4e52 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 2 Mar 2018 20:38:06 +0000 Subject: [PATCH 399/540] Create tir tag in separate file Update all uses of the tag to use the tag as defined in the file --- src/spv_node.js | 16 ++-------------- src/tag.js | 23 +++++++++++++++++++++++ src/trust_is_risk.js | 41 +++-------------------------------------- test/helpers.js | 4 ++-- test/spv_node.js | 16 ++-------------- test/trust_is_risk.js | 9 +++++---- 6 files changed, 37 insertions(+), 72 deletions(-) create mode 100644 src/tag.js diff --git a/src/spv_node.js b/src/spv_node.js index 8aabf12..245e7e6 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -1,19 +1,7 @@ // @flow var bcoin = require("bcoin"); var TrustIsRisk = require("./trust_is_risk"); - -const fakePubKeyArray = [0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - -const tag = Buffer.from(fakePubKeyArray); +var Tag = require("./tag"); class SPVNode extends bcoin.spvnode { trust : TrustIsRisk @@ -21,7 +9,7 @@ class SPVNode extends bcoin.spvnode { constructor(options : Object) { super(options); this.trust = new TrustIsRisk(this); - this.pool.spvFilter.add(tag); + this.pool.spvFilter.add(Tag.address); } } diff --git a/src/tag.js b/src/tag.js new file mode 100644 index 0000000..79a8b50 --- /dev/null +++ b/src/tag.js @@ -0,0 +1,23 @@ +// @flow +import type {Entity, TXHash, Key} from "./types"; +const bcoin = require("bcoin"); + +const pubKeyArray = [0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; + +const tag : {pubKey : Key, address : Entity} = { + pubKey: Buffer.from(pubKeyArray), + + address: bcoin.primitives.KeyRing.fromPublic( + Buffer.from(pubKeyArray)).getAddress("base58").toString() +}; + +module.exports = tag; diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 5ff763c..40ae42e 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -15,48 +15,13 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); +var Tag = require("./tag"); class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) db : TrustDB - fakePubKeyArray : Array - fakePubKey : Buffer - fakeKeyRing : KeyRing - tag : Buffer - - compressedFakePubKeyArray : Array - compressedFakePubKey : Buffer - compressedFakeKeyRing : KeyRing - compressedTag : Buffer - constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { - this.fakePubKeyArray = [0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - - this.fakePubKey = Buffer.from(this.fakePubKeyArray); - this.fakeKeyRing = KeyRing.fromPublic(this.fakePubKey); - this.tag = Buffer.from(this.fakeKeyRing.getAddress("base58")); - - - this.compressedFakePubKeyArray = [0x02, // 0x02 prefix for even y values - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // only x is given in short version - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; - - this.compressedFakePubKey = Buffer.from(this.compressedFakePubKeyArray); - this.compressedFakeKeyRing = KeyRing.fromPublic(this.compressedFakePubKey); - this.compressedTag = Buffer.from(this.compressedFakeKeyRing.getAddress("base58")); - this.node = node; this.db = new TrustDB(); @@ -133,7 +98,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, this.fakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, Tag.pubKey]), value: trustAmount }) ] @@ -232,7 +197,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, this.fakePubKey]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, Tag.pubKey]), value: remainingTrustAmount })); } diff --git a/test/helpers.js b/test/helpers.js index 4b64bc8..bbaac5d 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,4 +1,5 @@ var TrustIsRisk = require("../"); +var Tag = require("../lib/tag"); var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); var fixtures = require("./fixtures"); @@ -59,9 +60,8 @@ var testHelpers = { }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { - tag = (new TrustIsRisk.TrustIsRisk(new bcoin.fullnode({}))).fakePubKey; return new bcoin.primitives.Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, Tag.pubKey]), value }); }, diff --git a/test/spv_node.js b/test/spv_node.js index 6c72e2c..961fa70 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -10,6 +10,7 @@ var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var walletPlugin = bcoin.wallet.plugin; var EC = bcoin.crypto.ec; +var Tag = require("../lib/tag"); var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); @@ -107,19 +108,6 @@ describe("SPVNode", () => { }); it("should match a TIR transaction with the spv bloom filter", async function() { - var fakePubKeyArray = [0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - - var tag = Buffer.from(fakePubKeyArray); - var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); var privateKey1 = (await wallet1.getPrivateKey( wallet1.getAddress("base58"), "secret") @@ -140,7 +128,7 @@ describe("SPVNode", () => { var outputs = [ new Output({ // 1-of-3 multisig trust - script: bcoin.script.fromMultisig(1, 3, [origin, dest, tag]), + script: bcoin.script.fromMultisig(1, 3, [origin, dest, Tag.pubKey]), value: 49 * consensus.COIN }), new Output({ // paytopubkeyhash change diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 04faf8f..1298e70 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -6,6 +6,7 @@ var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; var testHelpers = require("./helpers"); +var Tag = require("../lib/tag"); var consensus = require("bcoin/lib/protocol/consensus"); var secp256k1 = require("bcoin/lib/crypto/secp256k1"); var sinon = require("sinon"); @@ -65,12 +66,12 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { - Buffer.isBuffer(tir.fakePubKey).should.be.true(); - secp256k1.publicKeyVerify(tir.fakePubKey).should.be.true(); + Buffer.isBuffer(Tag.pubKey).should.be.true(); + secp256k1.publicKeyVerify(Tag.pubKey).should.be.true(); }); it("is a valid bitcoin address", () => { - assert(bcoin.primitives.Address.fromString(tir.tag.toString("ascii"))); + bcoin.primitives.Address.fromString(Tag.address).should.not.throw(); }); }); @@ -219,7 +220,7 @@ describe("TrustIsRisk", () => { [1, 2].map((i) => helpers.pubKeyToEntity( trustOutput.script.get(i).data, tir.network )).sort().should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).data.should.deepEqual(tir.fakePubKey); + trustOutput.script.get(3).data.should.deepEqual(Tag.pubKey); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From 662ec71ac4587cda939feb3811dfd5b2f11cd644 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 3 Mar 2018 13:47:37 +0000 Subject: [PATCH 400/540] Remove obsolete note This note contained some provisional bug fixes made to bcoin/lib/node/spvnode.js, along with the suggestions by the bcoin devs on how to correctly fix those bugs. Since PR https://github.com/bcoin-org/bcoin/pull/417 has been published, this note is redundant. --- note | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 note diff --git a/note b/note deleted file mode 100644 index 0ff05ea..0000000 --- a/note +++ /dev/null @@ -1,18 +0,0 @@ -added lines 268,269 at node_modules/bcoin/lib/node/spvnode.js: - this.pool.txFilter.add(item.hash()); - this.emit('tx', item); - -Javed Khan: - -@orfeas ok yeah I see the problem. Since there's no mempool on a spv node, it seems to be missing unconfirmed transactions, unless relayed by another node - -btw I think you can just listen to 'tx' event on the node rather than digging into the txFilter etc. - -Might make sense to have a way for `relay` to signal and emit the `tx` event in spv mode - - -Node Chkuaselidze: - -`pool.txFilter` is used for tracking transactions it has seen, so it doesn't reuqest them again. - -It's a probably good idea to update txFilter when you send tx, if you don't want to redownload your transaction. And yes that should go to sendTX method instead. and relay can use sendTX like in fullnode case. From ff1f3a8df5e915a452af2259d2f90d208f8c0c6f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 3 Mar 2018 15:07:07 +0000 Subject: [PATCH 401/540] Type walletPlugin class and relevant functions --- flow-typed/npm/bcoin_vx.x.x.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 1eb1a8a..5fc2d78 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -22,6 +22,9 @@ declare class bcoin$SPVNode { chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; + use(walletPlugin : typeof bcoin$WalletPlugin) : void; + require(name : string) : Object; // or bcoin$WalletDB + open() : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } @@ -39,6 +42,10 @@ declare class bcoin$Wallet { getTX(hash : Hash) : Promise; } +declare var bcoin$WalletPlugin: { + init(node : (bcoin$FullNode | bcoin$SPVNode)) : bcoin$WalletDB; +} + declare class bcoin$Pool { peers : bcoin$PeerList; spvFilter : bcoin$Bloom; @@ -170,7 +177,8 @@ declare module 'bcoin' { pool : Class, wallet : { Wallet : Class, - WalletDB : Class + WalletDB : Class, + plugin : typeof bcoin$WalletPlugin }, primitives : { Address : Class, From 44e92cde6d8813a15774829e8d7601230f143761 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sat, 3 Mar 2018 15:07:53 +0000 Subject: [PATCH 402/540] Use crypto.secp256k1 instead of crypto.ec This change is necessary because of the migration to version 15. --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 961fa70..c804903 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -9,7 +9,7 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var walletPlugin = bcoin.wallet.plugin; -var EC = bcoin.crypto.ec; +var secp256k1 = bcoin.crypto.secp256k1; var Tag = require("../lib/tag"); var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); From 386a055f52825f4050807ac30480c6e17343aca9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 00:53:36 +0000 Subject: [PATCH 403/540] Type node init, tag and wallet plugin stuff Declare various functions for bcoin full node, correct tag declaration, declare walletDB in TIR full and spv nodes --- flow-typed/npm/bcoin_vx.x.x.js | 15 +++++++++------ src/full_node.js | 1 + src/spv_node.js | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 5fc2d78..6b6fd72 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -12,6 +12,10 @@ declare class bcoin$FullNode { chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; + use(walletPlugin : bcoin$WalletPlugin) : void; + require(name : string) : bcoin$WalletDB; + open() : Promise; + connect() : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } @@ -22,9 +26,10 @@ declare class bcoin$SPVNode { chain : bcoin$Chain; on(eventName : string, eventHandler : Function) : void; - use(walletPlugin : typeof bcoin$WalletPlugin) : void; - require(name : string) : Object; // or bcoin$WalletDB + use(walletPlugin : bcoin$WalletPlugin) : void; + require(name : string) : bcoin$WalletDB; open() : Promise; + connect() : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } @@ -42,7 +47,7 @@ declare class bcoin$Wallet { getTX(hash : Hash) : Promise; } -declare var bcoin$WalletPlugin: { +declare type bcoin$WalletPlugin = { init(node : (bcoin$FullNode | bcoin$SPVNode)) : bcoin$WalletDB; } @@ -178,7 +183,7 @@ declare module 'bcoin' { wallet : { Wallet : Class, WalletDB : Class, - plugin : typeof bcoin$WalletPlugin + plugin : bcoin$WalletPlugin }, primitives : { Address : Class, @@ -199,5 +204,3 @@ declare module 'bcoin' { }, } } - - diff --git a/src/full_node.js b/src/full_node.js index 93e664d..710a5dd 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -4,6 +4,7 @@ var TrustIsRisk = require("./trust_is_risk"); class FullNode extends bcoin.fullnode { trust : TrustIsRisk + walletDB : bcoin$WalletDB constructor(options : Object) { super(options); diff --git a/src/spv_node.js b/src/spv_node.js index 245e7e6..620399f 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -5,6 +5,7 @@ var Tag = require("./tag"); class SPVNode extends bcoin.spvnode { trust : TrustIsRisk + walletDB : bcoin$WalletDB constructor(options : Object) { super(options); From 86373d4d9ecc1ab9416a69f43c15a7881743fe87 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 00:58:47 +0000 Subject: [PATCH 404/540] Use wallet plugin to setup walletDB --- src/full_node.js | 8 ++++++++ src/spv_node.js | 8 ++++++++ test/full_node.js | 23 ++++++----------------- test/spv_node.js | 44 ++++++++++++++------------------------------ 4 files changed, 36 insertions(+), 47 deletions(-) diff --git a/src/full_node.js b/src/full_node.js index 710a5dd..c82fbfb 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -1,5 +1,6 @@ // @flow var bcoin = require("bcoin"); +var walletPlugin = bcoin.wallet.plugin; var TrustIsRisk = require("./trust_is_risk"); class FullNode extends bcoin.fullnode { @@ -8,8 +9,15 @@ class FullNode extends bcoin.fullnode { constructor(options : Object) { super(options); + this.use(walletPlugin); this.trust = new TrustIsRisk(this); } + + async initialize() { + this.walletDB = this.require("walletdb"); // TODO move walletDB to the hands of the user + await this.open(); + await this.connect(); + } } module.exports = FullNode; diff --git a/src/spv_node.js b/src/spv_node.js index 620399f..58c3f0f 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -1,5 +1,6 @@ // @flow var bcoin = require("bcoin"); +var walletPlugin = bcoin.wallet.plugin; var TrustIsRisk = require("./trust_is_risk"); var Tag = require("./tag"); @@ -9,9 +10,16 @@ class SPVNode extends bcoin.spvnode { constructor(options : Object) { super(options); + this.use(walletPlugin); this.trust = new TrustIsRisk(this); this.pool.spvFilter.add(Tag.address); } + + async initialize() { + this.walletDB = this.require("walletdb"); // TODO move walletDB to the hands of the user + await this.open(); + await this.connect(); + } } module.exports = SPVNode; diff --git a/test/full_node.js b/test/full_node.js index c4daab6..d4297bc 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -33,24 +33,13 @@ describe("FullNode", () => { Trust.TrustIsRisk.prototype.addTX.restore(); }); - beforeEach("get node", async () => { + beforeEach("prepare node", async () => { node = new Trust.FullNode({ network: bcoin.network.get().toString(), passphrase: "secret" }); - node.use(walletPlugin); - await node.open(); - }); - - beforeEach("prepare walletDB", async () => { - walletDB = node.require("walletdb"); - await walletDB.open(); - await walletDB.connect(); - }); - - beforeEach("connect node", async () => { - await node.connect(); + await node.initialize(); node.startSync(); }); @@ -64,8 +53,8 @@ describe("FullNode", () => { }); afterEach("disconnect and close walletDB", async () => { - await walletDB.disconnect(); - await walletDB.close(); + await node.walletDB.disconnect(); + await node.walletDB.close(); }); afterEach("close node", async () => { @@ -73,8 +62,8 @@ describe("FullNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var sender = await testHelpers.createWallet(walletDB, "sender"); - var receiver = await testHelpers.createWallet(walletDB, "receiver"); + var sender = await testHelpers.createWallet(node.walletDB, "sender"); + var receiver = await testHelpers.createWallet(node.walletDB, "receiver"); await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. diff --git a/test/spv_node.js b/test/spv_node.js index c804903..92dba42 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -24,8 +24,6 @@ const COIN = consensus.COIN; describe("SPVNode", () => { var spvNode = null; var miner = null; - var spvWalletDB = null; - var minerWalletDB = null; var spvWatcher = null; var minerWatcher = null; @@ -47,14 +45,7 @@ describe("SPVNode", () => { nodes: ["127.0.0.1:48448"] }); - spvNode.use(walletPlugin); - await spvNode.open(); - - spvWalletDB = spvNode.require("walletdb"); - await spvWalletDB.open(); - await spvWalletDB.connect(); - - await spvNode.connect(); + await spvNode.initialize(); }); beforeEach("connect full node and wallet", async () => { @@ -66,14 +57,7 @@ describe("SPVNode", () => { passphrase: "secret" }); - miner.use(walletPlugin); - await miner.open(); - - minerWalletDB = miner.require("walletdb"); - await minerWalletDB.open(); - await minerWalletDB.connect(); - - await miner.connect(); + await miner.initialize(); }); beforeEach("start syncing", () => { @@ -95,11 +79,11 @@ describe("SPVNode", () => { }); afterEach("disconnect and close walletDBs", async () => { - await spvWalletDB.disconnect(); - await minerWalletDB.disconnect(); + await spvNode.walletDB.disconnect(); + await miner.walletDB.disconnect(); - await spvWalletDB.close(); - await minerWalletDB.close(); + await spvNode.walletDB.close(); + await miner.walletDB.close(); }); afterEach("close nodes", async () => { @@ -108,13 +92,13 @@ describe("SPVNode", () => { }); it("should match a TIR transaction with the spv bloom filter", async function() { - var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); + var wallet1 = await testHelpers.createWallet(miner.walletDB, "wallet1"); var privateKey1 = (await wallet1.getPrivateKey( wallet1.getAddress("base58"), "secret") ).privateKey; var origin = EC.publicKeyCreate(privateKey1, true); - var wallet2 = await testHelpers.createWallet(minerWalletDB, "wallet2"); + var wallet2 = await testHelpers.createWallet(miner.walletDB, "wallet2"); var privateKey2 = (await wallet2.getPrivateKey( wallet2.getAddress("base58"), "secret") ).privateKey; @@ -148,11 +132,11 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); - var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); + var spvWallet1 = await testHelpers.createWallet(spvNode.walletDB, "spvWallet1"); + var spvWallet2 = await testHelpers.createWallet(spvNode.walletDB, "spvWallet2"); - var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); - var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); + var minerWallet1 = await testHelpers.createWallet(miner.walletDB, "minerWallet1"); + var minerWallet2 = await testHelpers.createWallet(miner.walletDB, "minerWallet2"); await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. @@ -234,7 +218,7 @@ describe("SPVNode", () => { beforeEach("apply graph transactions", async () => { for (name in minerNames) { minerWallets[name] = await testHelpers.createWallet( - minerWalletDB, name + miner.walletDB, name ); rings[name] = await minerWallets[name].getPrivateKey( minerWallets[name].getAddress("base58"), "secret" @@ -247,7 +231,7 @@ describe("SPVNode", () => { for (name in spvNames) { spvWallets[name] = await testHelpers.createWallet( - spvWalletDB, name + spvNode.walletDB, name ); rings[name] = await spvWallets[name].getPrivateKey( spvWallets[name].getAddress("base58"), "secret" From 93d55e7f96e14632a71798a2df4932de75f27cbc Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 01:02:52 +0000 Subject: [PATCH 405/540] Remove address from tag Let tag be just the constructed public key, avoid exporting an entire dictionary with both the public key and the corresponding address. The address is not used, since the multisig contains the public key. --- src/spv_node.js | 4 ++-- src/tag.js | 14 +++----------- src/trust_is_risk.js | 6 +++--- test/helpers.js | 4 ++-- test/spv_node.js | 5 +++-- test/trust_is_risk.js | 12 +++++++----- 6 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/spv_node.js b/src/spv_node.js index 58c3f0f..6eadb90 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -2,7 +2,7 @@ var bcoin = require("bcoin"); var walletPlugin = bcoin.wallet.plugin; var TrustIsRisk = require("./trust_is_risk"); -var Tag = require("./tag"); +var tag = require("./tag"); class SPVNode extends bcoin.spvnode { trust : TrustIsRisk @@ -12,13 +12,13 @@ class SPVNode extends bcoin.spvnode { super(options); this.use(walletPlugin); this.trust = new TrustIsRisk(this); - this.pool.spvFilter.add(Tag.address); } async initialize() { this.walletDB = this.require("walletdb"); // TODO move walletDB to the hands of the user await this.open(); await this.connect(); + this.pool.spvFilter.add(tag); } } diff --git a/src/tag.js b/src/tag.js index 79a8b50..13e5dba 100644 --- a/src/tag.js +++ b/src/tag.js @@ -1,8 +1,7 @@ // @flow -import type {Entity, TXHash, Key} from "./types"; -const bcoin = require("bcoin"); +import type {Key} from "./types"; -const pubKeyArray = [0x04, // constant 0x04 prefix +const tag : Key = Buffer.from([0x04, // constant 0x04 prefix 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" @@ -11,13 +10,6 @@ const pubKeyArray = [0x04, // constant 0x04 prefix 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]; - -const tag : {pubKey : Key, address : Entity} = { - pubKey: Buffer.from(pubKeyArray), - - address: bcoin.primitives.KeyRing.fromPublic( - Buffer.from(pubKeyArray)).getAddress("base58").toString() -}; + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]); module.exports = tag; diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 40ae42e..cdf31e5 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -15,7 +15,7 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -var Tag = require("./tag"); +var tag = require("./tag"); class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) @@ -98,7 +98,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, Tag.pubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, tag]), value: trustAmount }) ] @@ -197,7 +197,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, Tag.pubKey]), + script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, tag]), value: remainingTrustAmount })); } diff --git a/test/helpers.js b/test/helpers.js index bbaac5d..19ff502 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,5 +1,5 @@ var TrustIsRisk = require("../"); -var Tag = require("../lib/tag"); +var tag = require("../lib/tag"); var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); var fixtures = require("./fixtures"); @@ -61,7 +61,7 @@ var testHelpers = { getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { return new bcoin.primitives.Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, Tag.pubKey]), + script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value }); }, diff --git a/test/spv_node.js b/test/spv_node.js index 92dba42..43fbc80 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -10,7 +10,7 @@ var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var walletPlugin = bcoin.wallet.plugin; var secp256k1 = bcoin.crypto.secp256k1; -var Tag = require("../lib/tag"); +var tag = require("../lib/tag"); var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); @@ -112,7 +112,7 @@ describe("SPVNode", () => { var outputs = [ new Output({ // 1-of-3 multisig trust - script: bcoin.script.fromMultisig(1, 3, [origin, dest, Tag.pubKey]), + script: bcoin.script.fromMultisig(1, 3, [origin, dest, tag]), value: 49 * consensus.COIN }), new Output({ // paytopubkeyhash change @@ -128,6 +128,7 @@ describe("SPVNode", () => { (await mtx.verify()).should.be.true(); var tx = mtx.toTX(); + spvNode.pool.spvFilter.test(tag).should.be.true(); tx.isWatched(spvNode.pool.spvFilter).should.be.true(); }); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 1298e70..eb9f281 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -6,7 +6,7 @@ var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; var testHelpers = require("./helpers"); -var Tag = require("../lib/tag"); +var tag = require("../lib/tag"); var consensus = require("bcoin/lib/protocol/consensus"); var secp256k1 = require("bcoin/lib/crypto/secp256k1"); var sinon = require("sinon"); @@ -66,12 +66,14 @@ describe("TrustIsRisk", () => { describe("tag", () => { it("corresponds to a valid public key", () => { - Buffer.isBuffer(Tag.pubKey).should.be.true(); - secp256k1.publicKeyVerify(Tag.pubKey).should.be.true(); + Buffer.isBuffer(tag).should.be.true(); + secp256k1.publicKeyVerify(tag).should.be.true(); }); it("is a valid bitcoin address", () => { - bcoin.primitives.Address.fromString(Tag.address).should.not.throw(); + const address = bcoin.primitives.KeyRing.fromPublic( + tag).getAddress("base58").toString(); + bcoin.primitives.Address.fromString(address).should.not.throw(); }); }); @@ -220,7 +222,7 @@ describe("TrustIsRisk", () => { [1, 2].map((i) => helpers.pubKeyToEntity( trustOutput.script.get(i).data, tir.network )).sort().should.deepEqual([alice, bob].sort()); - trustOutput.script.get(3).data.should.deepEqual(Tag.pubKey); + trustOutput.script.get(3).data.should.deepEqual(tag); trustOutput.value.should.equal(100 * COIN); var changeOutput = mtx.outputs[1]; From fa55ea85fb17904ef3d7f4d82d832e737bafba1b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 01:04:41 +0000 Subject: [PATCH 406/540] Update EC to secp256k1 This change is necessary because of the migration to version 15. --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 43fbc80..8cb9fa1 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -96,13 +96,13 @@ describe("SPVNode", () => { var privateKey1 = (await wallet1.getPrivateKey( wallet1.getAddress("base58"), "secret") ).privateKey; - var origin = EC.publicKeyCreate(privateKey1, true); + var origin = secp256k1.publicKeyCreate(privateKey1, true); var wallet2 = await testHelpers.createWallet(miner.walletDB, "wallet2"); var privateKey2 = (await wallet2.getPrivateKey( wallet2.getAddress("base58"), "secret") ).privateKey; - var dest = EC.publicKeyCreate(privateKey2, true); + var dest = secp256k1.publicKeyCreate(privateKey2, true); var block = await testHelpers.mineBlock(miner, wallet1.getAddress("base58")); From 9c282e4fc3bb8bc1b87aebf1c377142d345a6157 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 22:37:01 +0000 Subject: [PATCH 407/540] Type init/tear down node/walletDB functions --- flow-typed/npm/bcoin_vx.x.x.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 6b6fd72..f734800 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -15,7 +15,9 @@ declare class bcoin$FullNode { use(walletPlugin : bcoin$WalletPlugin) : void; require(name : string) : bcoin$WalletDB; open() : Promise; + close() : Promise; connect() : Promise; + disconnect() : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } @@ -29,7 +31,9 @@ declare class bcoin$SPVNode { use(walletPlugin : bcoin$WalletPlugin) : void; require(name : string) : bcoin$WalletDB; open() : Promise; + close() : Promise; connect() : Promise; + disconnect() : Promise; getCoin(hash : Hash, index : number) : bcoin$Coin; } @@ -39,7 +43,9 @@ declare class bcoin$Chain {} declare class bcoin$WalletDB { open() : Promise; + close() : Promise; connect() : Promise; + disconnect() : Promise; create(options : ?Object) : Promise; } From 3c970e3e8c6bbd797fba9ae15331697c1fda8d1c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 22:38:22 +0000 Subject: [PATCH 408/540] Define and use dedicated node.tearDown() functions --- src/full_node.js | 7 +++++++ src/spv_node.js | 7 +++++++ test/full_node.js | 15 ++------------- test/spv_node.js | 19 +++---------------- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/full_node.js b/src/full_node.js index c82fbfb..ec4e9f8 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -18,6 +18,13 @@ class FullNode extends bcoin.fullnode { await this.open(); await this.connect(); } + + async tearDown() { + await this.disconnect(); + await this.walletDB.disconnect(); + await this.walletDB.close(); + await this.close(); + } } module.exports = FullNode; diff --git a/src/spv_node.js b/src/spv_node.js index 6eadb90..0467f2d 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -20,6 +20,13 @@ class SPVNode extends bcoin.spvnode { await this.connect(); this.pool.spvFilter.add(tag); } + + async tearDown() { + await this.disconnect(); + await this.walletDB.disconnect(); + await this.walletDB.close(); + await this.close(); + } } module.exports = SPVNode; diff --git a/test/full_node.js b/test/full_node.js index d4297bc..bff37a6 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -21,8 +21,6 @@ const COIN = consensus.COIN; describe("FullNode", () => { var node = null; - var walletDB = null; - var NodeWatcher = null; var watcher = null; before("set up addTX() spy", function() { @@ -47,18 +45,9 @@ describe("FullNode", () => { watcher = new testHelpers.NodeWatcher(node); }); - afterEach("disconnect node", async () => { + afterEach("tear node down", async () => { node.stopSync(); - await node.disconnect(); - }); - - afterEach("disconnect and close walletDB", async () => { - await node.walletDB.disconnect(); - await node.walletDB.close(); - }); - - afterEach("close node", async () => { - await node.close(); + await node.tearDown(); }); it("should call trust.addTX() on every transaction", async function() { diff --git a/test/spv_node.js b/test/spv_node.js index 8cb9fa1..841960c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -70,25 +70,12 @@ describe("SPVNode", () => { spvWatcher = new testHelpers.NodeWatcher(spvNode); }); - afterEach("disconnect nodes", async () => { + afterEach("tear nodes down", async () => { spvNode.stopSync(); miner.stopSync(); - await spvNode.disconnect(); - await miner.disconnect(); - }); - - afterEach("disconnect and close walletDBs", async () => { - await spvNode.walletDB.disconnect(); - await miner.walletDB.disconnect(); - - await spvNode.walletDB.close(); - await miner.walletDB.close(); - }); - - afterEach("close nodes", async () => { - await spvNode.close(); - await miner.close(); + await spvNode.tearDown(); + await miner.tearDown(); }); it("should match a TIR transaction with the spv bloom filter", async function() { From 6a11ae48d57c7105ef47d2f65a56a50602edc722 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 22:39:03 +0000 Subject: [PATCH 409/540] Pass the node, not the walletDB to createWallet() --- test/full_node.js | 4 ++-- test/helpers.js | 4 ++-- test/spv_node.js | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index bff37a6..5e074ba 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -51,8 +51,8 @@ describe("FullNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var sender = await testHelpers.createWallet(node.walletDB, "sender"); - var receiver = await testHelpers.createWallet(node.walletDB, "receiver"); + var sender = await testHelpers.createWallet(node, "sender"); + var receiver = await testHelpers.createWallet(node, "receiver"); await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. diff --git a/test/helpers.js b/test/helpers.js index 19ff502..637635b 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -6,7 +6,7 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - createWallet: async (walletDB, id) => { + createWallet: async (node, id) => { var options = { id, passphrase: "secret", @@ -14,7 +14,7 @@ var testHelpers = { type: "pubkeyhash" }; - return walletDB.create(options); + return node.walletDB.create(options); }, mineBlock: async (node, rewardAddress) => { diff --git a/test/spv_node.js b/test/spv_node.js index 841960c..33be8e0 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -79,13 +79,13 @@ describe("SPVNode", () => { }); it("should match a TIR transaction with the spv bloom filter", async function() { - var wallet1 = await testHelpers.createWallet(miner.walletDB, "wallet1"); + var wallet1 = await testHelpers.createWallet(miner, "wallet1"); var privateKey1 = (await wallet1.getPrivateKey( wallet1.getAddress("base58"), "secret") ).privateKey; var origin = secp256k1.publicKeyCreate(privateKey1, true); - var wallet2 = await testHelpers.createWallet(miner.walletDB, "wallet2"); + var wallet2 = await testHelpers.createWallet(miner, "wallet2"); var privateKey2 = (await wallet2.getPrivateKey( wallet2.getAddress("base58"), "secret") ).privateKey; @@ -120,11 +120,11 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvWallet1 = await testHelpers.createWallet(spvNode.walletDB, "spvWallet1"); - var spvWallet2 = await testHelpers.createWallet(spvNode.walletDB, "spvWallet2"); + var spvWallet1 = await testHelpers.createWallet(spvNode, "spvWallet1"); + var spvWallet2 = await testHelpers.createWallet(spvNode, "spvWallet2"); - var minerWallet1 = await testHelpers.createWallet(miner.walletDB, "minerWallet1"); - var minerWallet2 = await testHelpers.createWallet(miner.walletDB, "minerWallet2"); + var minerWallet1 = await testHelpers.createWallet(miner, "minerWallet1"); + var minerWallet2 = await testHelpers.createWallet(miner, "minerWallet2"); await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. @@ -206,7 +206,7 @@ describe("SPVNode", () => { beforeEach("apply graph transactions", async () => { for (name in minerNames) { minerWallets[name] = await testHelpers.createWallet( - miner.walletDB, name + miner, name ); rings[name] = await minerWallets[name].getPrivateKey( minerWallets[name].getAddress("base58"), "secret" @@ -219,7 +219,7 @@ describe("SPVNode", () => { for (name in spvNames) { spvWallets[name] = await testHelpers.createWallet( - spvNode.walletDB, name + spvNode, name ); rings[name] = await spvWallets[name].getPrivateKey( spvWallets[name].getAddress("base58"), "secret" From 51e1ce60f864224b655bfb8c7e713126b14123b1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 15 Mar 2018 23:52:28 +0000 Subject: [PATCH 410/540] Add minimal testcase for separating walletDB Show how it is possible for the walletDB to not be a property of the corresponding node --- minimal_testcases/separateWalletDB.js | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 minimal_testcases/separateWalletDB.js diff --git a/minimal_testcases/separateWalletDB.js b/minimal_testcases/separateWalletDB.js new file mode 100644 index 0000000..37871a8 --- /dev/null +++ b/minimal_testcases/separateWalletDB.js @@ -0,0 +1,51 @@ +const bcoin = require("bcoin").set("regtest"); + +(async () => { + const args = process.argv + + const node = new bcoin.node.FullNode({ + network: bcoin.network.get().toString(), + passphrase: "secret" + }) + + if (args[2] == "new") { + node.use(bcoin.wallet.plugin) + node.walletDB = node.require("walletdb") + + await node.open() + await node.connect() + + const options = { + id: "wallet", + passphrase: "secret", + witness: false, + type: "pubkeyhash" + } + + const wallet = await node.walletDB.create(options) + + await node.disconnect() + await node.close() + console.log("success!") + } else if (args[2] == "old") { + node.use(bcoin.wallet.plugin) + walletDB = node.require("walletdb") + await node.open() + await node.connect() + + const options = { + id: "wallet", + passphrase: "secret", + witness: false, + type: "pubkeyhash" + } + + const wallet = await walletDB.create(options) + + await node.disconnect() + await node.close() + console.log("success!") + } else { + console.log("Usage: node separateWalletDB.js new|old") + } +})() From 78631e25b089df6186b764a1ddf851e0a08a0039 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 16 Mar 2018 19:09:00 +0000 Subject: [PATCH 411/540] Have the user create and control walletDB Replace previous mechanism where walletDB was a property of the node, which nevertheless the user had to access directly --- src/full_node.js | 4 ---- src/spv_node.js | 4 ---- test/full_node.js | 6 ++++-- test/helpers.js | 4 ++-- test/spv_node.js | 20 ++++++++++++-------- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/full_node.js b/src/full_node.js index ec4e9f8..de38236 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -5,7 +5,6 @@ var TrustIsRisk = require("./trust_is_risk"); class FullNode extends bcoin.fullnode { trust : TrustIsRisk - walletDB : bcoin$WalletDB constructor(options : Object) { super(options); @@ -14,15 +13,12 @@ class FullNode extends bcoin.fullnode { } async initialize() { - this.walletDB = this.require("walletdb"); // TODO move walletDB to the hands of the user await this.open(); await this.connect(); } async tearDown() { await this.disconnect(); - await this.walletDB.disconnect(); - await this.walletDB.close(); await this.close(); } } diff --git a/src/spv_node.js b/src/spv_node.js index 0467f2d..efdb690 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -6,7 +6,6 @@ var tag = require("./tag"); class SPVNode extends bcoin.spvnode { trust : TrustIsRisk - walletDB : bcoin$WalletDB constructor(options : Object) { super(options); @@ -15,7 +14,6 @@ class SPVNode extends bcoin.spvnode { } async initialize() { - this.walletDB = this.require("walletdb"); // TODO move walletDB to the hands of the user await this.open(); await this.connect(); this.pool.spvFilter.add(tag); @@ -23,8 +21,6 @@ class SPVNode extends bcoin.spvnode { async tearDown() { await this.disconnect(); - await this.walletDB.disconnect(); - await this.walletDB.close(); await this.close(); } } diff --git a/test/full_node.js b/test/full_node.js index 5e074ba..1c251af 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -22,6 +22,7 @@ const COIN = consensus.COIN; describe("FullNode", () => { var node = null; var watcher = null; + var walletDB = null; before("set up addTX() spy", function() { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); @@ -38,6 +39,7 @@ describe("FullNode", () => { }); await node.initialize(); + walletDB = node.require("walletdb"); node.startSync(); }); @@ -51,8 +53,8 @@ describe("FullNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var sender = await testHelpers.createWallet(node, "sender"); - var receiver = await testHelpers.createWallet(node, "receiver"); + var sender = await testHelpers.createWallet(walletDB, "sender"); + var receiver = await testHelpers.createWallet(walletDB, "receiver"); await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. diff --git a/test/helpers.js b/test/helpers.js index 637635b..19ff502 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -6,7 +6,7 @@ var fixtures = require("./fixtures"); var assert = require("assert"); var testHelpers = { - createWallet: async (node, id) => { + createWallet: async (walletDB, id) => { var options = { id, passphrase: "secret", @@ -14,7 +14,7 @@ var testHelpers = { type: "pubkeyhash" }; - return node.walletDB.create(options); + return walletDB.create(options); }, mineBlock: async (node, rewardAddress) => { diff --git a/test/spv_node.js b/test/spv_node.js index 33be8e0..b0f1cb8 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -24,6 +24,8 @@ const COIN = consensus.COIN; describe("SPVNode", () => { var spvNode = null; var miner = null; + var spvWalletDB = null; + var minerWalletDB = null; var spvWatcher = null; var minerWatcher = null; @@ -46,6 +48,7 @@ describe("SPVNode", () => { }); await spvNode.initialize(); + minerWalletDB = spvNode.require("walletdb"); }); beforeEach("connect full node and wallet", async () => { @@ -58,6 +61,7 @@ describe("SPVNode", () => { }); await miner.initialize(); + spvWalletDB = miner.require("walletdb"); }); beforeEach("start syncing", () => { @@ -79,13 +83,13 @@ describe("SPVNode", () => { }); it("should match a TIR transaction with the spv bloom filter", async function() { - var wallet1 = await testHelpers.createWallet(miner, "wallet1"); + var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); var privateKey1 = (await wallet1.getPrivateKey( wallet1.getAddress("base58"), "secret") ).privateKey; var origin = secp256k1.publicKeyCreate(privateKey1, true); - var wallet2 = await testHelpers.createWallet(miner, "wallet2"); + var wallet2 = await testHelpers.createWallet(minerWalletDB, "wallet2"); var privateKey2 = (await wallet2.getPrivateKey( wallet2.getAddress("base58"), "secret") ).privateKey; @@ -120,11 +124,11 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on every transaction", async function() { - var spvWallet1 = await testHelpers.createWallet(spvNode, "spvWallet1"); - var spvWallet2 = await testHelpers.createWallet(spvNode, "spvWallet2"); + var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); + var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); - var minerWallet1 = await testHelpers.createWallet(miner, "minerWallet1"); - var minerWallet2 = await testHelpers.createWallet(miner, "minerWallet2"); + var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); + var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. @@ -206,7 +210,7 @@ describe("SPVNode", () => { beforeEach("apply graph transactions", async () => { for (name in minerNames) { minerWallets[name] = await testHelpers.createWallet( - miner, name + minerWalletDB, name ); rings[name] = await minerWallets[name].getPrivateKey( minerWallets[name].getAddress("base58"), "secret" @@ -219,7 +223,7 @@ describe("SPVNode", () => { for (name in spvNames) { spvWallets[name] = await testHelpers.createWallet( - spvNode, name + spvWalletDB, name ); rings[name] = await spvWallets[name].getPrivateKey( spvWallets[name].getAddress("base58"), "secret" From b1e3dc132823473621f7acbcf8cee10202e2dc69 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 20 Mar 2018 22:37:57 +0000 Subject: [PATCH 412/540] Fix typo Exchange minerWalletDB with spvWalletDB variable names --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index b0f1cb8..e6e04a1 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -48,7 +48,7 @@ describe("SPVNode", () => { }); await spvNode.initialize(); - minerWalletDB = spvNode.require("walletdb"); + spvWalletDB = spvNode.require("walletdb"); }); beforeEach("connect full node and wallet", async () => { @@ -61,7 +61,7 @@ describe("SPVNode", () => { }); await miner.initialize(); - spvWalletDB = miner.require("walletdb"); + minerWalletDB = miner.require("walletdb"); }); beforeEach("start syncing", () => { From aa79d23a1764729138e966de0f19ced7c1e499fe Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Mar 2018 01:52:26 +0000 Subject: [PATCH 413/540] Use stub to return correct coin --- test/trust_is_risk.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index eb9f281..c02a44d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -235,6 +235,8 @@ describe("TrustIsRisk", () => { describe(".getTrustDecreasingMTX()", () => { var trustTXs; beforeEach(() => { + var getTXStub = sinon.stub(node, "getCoin"); + var tx; trustTXs = []; @@ -242,11 +244,25 @@ describe("TrustIsRisk", () => { trustTXs.push(tx); tir.addTX(tx); + getTXStub.withArgs(tx.hash("hex"), 0).returns(new Coin({ + script: tx.outputs[0].script, + value: tx.outputs[0].value, + index: 0, + hash: tx.hash("hex") + })); + trustIncreasingMTX.outputs[0].value = 100 * COIN; tx = trustIncreasingMTX.toTX(); trustTXs.push(tx); tir.addTX(tx); + getTXStub.withArgs(tx.hash("hex"), 0).returns(new Coin({ + script: tx.outputs[0].script, + value: tx.outputs[0].value, + index: 0, + hash: tx.hash("hex") + })); + trustIncreasingMTX.outputs[0].value = 500 * COIN; tx = trustIncreasingMTX.toTX(); trustTXs.push(tx); From 258d9a4b80189cac303adebfb52fe5a9bd5187fe Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Mar 2018 10:03:55 +0000 Subject: [PATCH 414/540] Reorder createTrustDecreasingMTXs() arguments Swap wallet and payee parameters so that the payee is not mistaken for a wallet --- src/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index cdf31e5..6de25ed 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -131,7 +131,7 @@ class TrustIsRisk { // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. async createTrustDecreasingMTXs(origin : Key, dest : Key, - trustDecreaseAmount : number, wallet : ?bcoin$Wallet, payee : ?Entity, + trustDecreaseAmount : number, payee : ?Entity, wallet : ?bcoin$Wallet, steal : ?boolean, fee : ?number) : Promise[]> { if (steal === undefined) steal = false; From 5e6ac53c3b1601a911615650a05990be9cecbbcd Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 23 Mar 2018 12:00:00 +0000 Subject: [PATCH 415/540] Add note for weekly update --- note | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 note diff --git a/note b/note new file mode 100644 index 0000000..6c61ba9 --- /dev/null +++ b/note @@ -0,0 +1,3 @@ +1) tir => node.trust (test/trust_is_risk.js:40) +2) stub (test/trust_is_risk.js:242,263) +3) spv wallet getCoin stuff (src/trust_is_risk.js:75,84-91,133,170,180-187) From 8b18309cd1624b193e96bce2bf9030234b66f3ce Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 29 Mar 2018 23:08:01 +0100 Subject: [PATCH 416/540] Test TrustIsRisk class both for full and spv node --- test/trust_is_risk.js | 106 +++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 43 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c02a44d..c59be54 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -17,53 +17,58 @@ require("should-sinon"); const COIN = bcoin.consensus.COIN; -describe("TrustIsRisk", () => { - var addr = {}; - for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { - var pubKey = keyRing.getPublicKey(); - var privKey = keyRing.getPrivateKey(); - - addr[name] = {}; - addr[name].pubKey = pubKey; - addr[name].privKey = privKey; - addr[name].base58 = helpers.pubKeyToEntity(pubKey); +var addr = {}; +for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { + var pubKey = keyRing.getPublicKey(); + var privKey = keyRing.getPrivateKey(); + + addr[name] = {}; + addr[name].pubKey = pubKey; + addr[name].privKey = privKey; + addr[name].base58 = helpers.pubKeyToEntity(pubKey); +} + +// Add base58 address variables to scope. +for (name in fixtures.keyRings) { + var keyRing = fixtures.keyRings[name]; + eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); +} + +var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; + +setupTest = (isFullNode) => { + if (isFullNode) { + node = new bcoin.fullnode({network: bcoin.network.get().toString()}); } - - // Add base58 address variables to scope. - for (name in fixtures.keyRings) { - var keyRing = fixtures.keyRings[name]; - eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); + else { + node = new bcoin.spvnode({network: bcoin.network.get().toString()}); } - - var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; - beforeEach(() => { - node = new bcoin.fullnode({network: bcoin.network.get().toString()}); - tir = new Trust.TrustIsRisk(node); - - trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); - trustIncreasingTX = trustIncreasingMTX.toTX(); - - var inputOneOfThreeMultisig = new Input({ - prevout: { - hash: trustIncreasingTX.hash().toString("hex"), - index: 0 - }, - script: bcoin.script.fromString( - // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE - "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") - }); - - trustDecreasingMTX = new MTX({ - inputs: [ - inputOneOfThreeMultisig - ], - outputs: [ - testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), - testHelpers.getP2PKHOutput(addr.alice.base58, 22 * COIN) - ] - }); + tir = new Trust.TrustIsRisk(node); + + trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); + trustIncreasingTX = trustIncreasingMTX.toTX(); + + var inputOneOfThreeMultisig = new Input({ + prevout: { + hash: trustIncreasingTX.hash().toString("hex"), + index: 0 + }, + script: bcoin.script.fromString( + // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE + "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") }); + trustDecreasingMTX = new MTX({ + inputs: [ + inputOneOfThreeMultisig + ], + outputs: [ + testHelpers.getOneOfThreeMultisigOutput(addr.alice.pubKey, addr.bob.pubKey, 20 * COIN), + testHelpers.getP2PKHOutput(addr.alice.base58, 22 * COIN) + ] + }); +}; +testEach = (isFullNode) => { describe("tag", () => { it("corresponds to a valid public key", () => { Buffer.isBuffer(tag).should.be.true(); @@ -422,4 +427,19 @@ describe("TrustIsRisk", () => { // TODO: Decrement direct trusts and test that indirect trusts update correctly }); }); +}; + +describeTest = (isFullNode) => { + beforeEach(() => { + setupTest(isFullNode); + }); + testEach(isFullNode); +}; + +describe.only("TrustIsRisk full node", () => { + describeTest(true); +}); + +describe.only("TrustIsRisk SPV node", () => { + describeTest(false); }); From 848d5f45259ea8cf7f153aff987b29e34f904c00 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Apr 2018 15:13:36 +0100 Subject: [PATCH 417/540] Separate tag tests Do not include tag tests in both full and spv node Trust is Risk tests --- test/trust_is_risk.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c59be54..f07d495 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -68,20 +68,21 @@ setupTest = (isFullNode) => { ] }); }; -testEach = (isFullNode) => { - describe("tag", () => { - it("corresponds to a valid public key", () => { - Buffer.isBuffer(tag).should.be.true(); - secp256k1.publicKeyVerify(tag).should.be.true(); - }); - it("is a valid bitcoin address", () => { - const address = bcoin.primitives.KeyRing.fromPublic( - tag).getAddress("base58").toString(); - bcoin.primitives.Address.fromString(address).should.not.throw(); - }); +describe("tag", () => { + it("corresponds to a valid public key", () => { + Buffer.isBuffer(tag).should.be.true(); + secp256k1.publicKeyVerify(tag).should.be.true(); }); + it("is a valid bitcoin address", () => { + const address = bcoin.primitives.KeyRing.fromPublic( + tag).getAddress("base58").toString(); + bcoin.primitives.Address.fromString(address).should.not.throw(); + }); +}); + +testEach = (isFullNode) => { describe(".getDirectTrust()", () => { it("returns zero for two arbitary parties that do not trust each other", () => { tir.getDirectTrust(alice, bob).should.equal(0); From 7b4f3304ff282f3a9f703d73998d1af6f834859a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Apr 2018 15:15:18 +0100 Subject: [PATCH 418/540] Rename prevOutput to prevOutpoint It is an Outpoint, not an Output. The name should reflect it. --- test/trust_is_risk.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index f07d495..c36738d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -206,18 +206,18 @@ testEach = (isFullNode) => { it("creates valid trust-increasing transactions", async () => { var getTXStub = sinon.stub(node, "getCoin"); - var prevOutput = { + var prevOutpoint = { hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", index: 1 }; - getTXStub.withArgs(prevOutput.hash).returns(new Coin({ + getTXStub.withArgs(prevOutpoint.hash).returns(new Coin({ script: testHelpers.getP2PKHOutput(alice, 1).script, value: 1000 * COIN })); - var mtx = await tir.createTrustIncreasingMTX(addr.alice.privKey, addr.bob.pubKey, prevOutput, - 100 * COIN); + var mtx = await tir.createTrustIncreasingMTX(addr.alice.privKey, + addr.bob.pubKey, prevOutpoint, 100 * COIN); mtx.inputs.length.should.equal(1); From c861f13287b1c213a3c3eaa4f1caa5029916662e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Apr 2018 18:14:39 +0100 Subject: [PATCH 419/540] Homogenize createTrustIncreasingMTX() for full/spv Create coin in the same way for both kinds of nodes (the way the spv node did it before), make the wallet argument compulsory, change the stub in the relevant test to return a suitable transaction. --- src/trust_is_risk.js | 16 +++------------- test/trust_is_risk.js | 38 +++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 6de25ed..9f7ad3a 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -73,22 +73,12 @@ class TrustIsRisk { // payable to the sender. The origin key must be a private key. Any satoshis not spent will be // returned to the sender, minus the fees, via P2PKH. async createTrustIncreasingMTX(origin : Key, dest : Key, outpoint : bcoin$Outpoint, - trustAmount : number, wallet : ?bcoin$Wallet, fee : ?number) + trustAmount : number, wallet : bcoin$Wallet, fee : ?number) : Promise { - if (wallet && typeof wallet === "number") { - fee = wallet; - wallet = null; - } if (!fee) fee = 1000; // TODO: estimate this var coin = null; - if (wallet) { // only the spv node passes the wallet - coin = await bcoin.primitives.Coin.fromTX( - (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 - ); - } - else { // for full nodes, getting the coin is more straightforward - coin = await this.node.getCoin(outpoint.hash, outpoint.index); - } + coin = await Coin.fromTX( + (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1); if (!coin) throw new Error("Could not find coin"); if (origin === dest) throw new Error("Can not increase self-trust."); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index c36738d..3f32692 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -5,6 +5,9 @@ var Coin = bcoin.primitives.Coin; var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; var MTX = bcoin.primitives.MTX; +var walletPlugin = bcoin.wallet.plugin; +var TX = bcoin.primitives.TX; +var TXRecord = bcoin.wallet.records.TXRecord; var testHelpers = require("./helpers"); var tag = require("../lib/tag"); var consensus = require("bcoin/lib/protocol/consensus"); @@ -34,16 +37,21 @@ for (name in fixtures.keyRings) { eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); } -var node, tir, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; +var node, tir, walletDB, wallet, + trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; -setupTest = (isFullNode) => { +setupTest = async (isFullNode) => { if (isFullNode) { node = new bcoin.fullnode({network: bcoin.network.get().toString()}); } else { node = new bcoin.spvnode({network: bcoin.network.get().toString()}); } + node.use(walletPlugin); tir = new Trust.TrustIsRisk(node); + walletDB = node.require("walletdb"); + await node.open(); + wallet = await testHelpers.createWallet(walletDB, "wallet"); trustIncreasingMTX = testHelpers.getTrustIncreasingMTX(addr.alice.pubKey, addr.bob.pubKey, 42 * COIN); trustIncreasingTX = trustIncreasingMTX.toTX(); @@ -69,6 +77,10 @@ setupTest = (isFullNode) => { }); }; +tearDownTest = async () => { + await node.close(); +}; + describe("tag", () => { it("corresponds to a valid public key", () => { Buffer.isBuffer(tag).should.be.true(); @@ -204,20 +216,21 @@ testEach = (isFullNode) => { describe(".createTrustIncreasingMTX()", () => { it("creates valid trust-increasing transactions", async () => { - var getTXStub = sinon.stub(node, "getCoin"); + var getTXStub = sinon.stub(wallet, "getTX"); var prevOutpoint = { hash: "v1pnhp2af4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", - index: 1 + index: 0 }; - getTXStub.withArgs(prevOutpoint.hash).returns(new Coin({ - script: testHelpers.getP2PKHOutput(alice, 1).script, - value: 1000 * COIN - })); + getTXStub.withArgs(prevOutpoint.hash).returns(TXRecord.fromTX( + TX.fromOptions({ + inputs: [testHelpers.getP2PKHInput(addr.alice.pubKey)], + outputs: [testHelpers.getP2PKHOutput(alice, 1000 * COIN)] + }))); var mtx = await tir.createTrustIncreasingMTX(addr.alice.privKey, - addr.bob.pubKey, prevOutpoint, 100 * COIN); + addr.bob.pubKey, prevOutpoint, 100 * COIN, wallet); mtx.inputs.length.should.equal(1); @@ -431,10 +444,13 @@ testEach = (isFullNode) => { }; describeTest = (isFullNode) => { - beforeEach(() => { - setupTest(isFullNode); + beforeEach(async () => { + await setupTest(isFullNode); }); testEach(isFullNode); + afterEach(async () => { + await tearDownTest(); + }); }; describe.only("TrustIsRisk full node", () => { From 655e6c41250a23fc55a67e18c0a05ddbda190554 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Apr 2018 18:43:54 +0100 Subject: [PATCH 420/540] Homogenize createTrustDecreasingMTX() for full/spv Create coin in the same way for both kinds of nodes (the way the spv node did it before), make the wallet argument compulsory, change the stub in the relevant test to return a suitable transaction, reorder createTrustDecreasingMTX(s)() arguments to leave optional arguments in the end --- src/trust_is_risk.js | 27 ++++++++++----------------- test/trust_is_risk.js | 27 ++++++++------------------- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 9f7ad3a..edaf2f5 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -121,8 +121,9 @@ class TrustIsRisk { // expected to be a public key and `dest` is expected to be a private key. The private key will be // used to sign the transaction. async createTrustDecreasingMTXs(origin : Key, dest : Key, - trustDecreaseAmount : number, payee : ?Entity, wallet : ?bcoin$Wallet, - steal : ?boolean, fee : ?number) : Promise[]> { + trustDecreaseAmount : number, wallet : bcoin$Wallet, + payee : ?Entity, steal : ?boolean, fee : ?number) + : Promise[]> { if (steal === undefined) steal = false; var signingKeyRing, originKeyRing, destKeyRing; @@ -153,28 +154,20 @@ class TrustIsRisk { var decrease = Math.min(trustDecreaseAmount, directTrust.amount); if (decrease === 0) return null; trustDecreaseAmount -= decrease; - return this.createTrustDecreasingMTX(directTrust, decrease, payee, signingKeyRing, wallet, fee); + return this.createTrustDecreasingMTX(directTrust, decrease, signingKeyRing, wallet, payee, fee); }).filter(Boolean); } - async createTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, - signingKeyRing : bcoin$KeyRing, wallet : ?bcoin$Wallet, fee : ?number) : Promise { + async createTrustDecreasingMTX(directTrust : DirectTrust, + decreaseAmount : number, signingKeyRing : bcoin$KeyRing, + wallet : bcoin$Wallet, payee : ?Entity, fee : ?number) + : Promise { if (!payee) payee = directTrust.getOriginEntity(); - if (wallet && typeof wallet === "number") { - fee = wallet; - wallet = null; - } if (!fee) fee = 1000; // TODO: estimate this var outpoint = new Outpoint(directTrust.txHash, directTrust.outputIndex); var coin = null; - if (wallet) { // only the spv node passes the wallet - coin = await bcoin.primitives.Coin.fromTX( - (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1 - ); - } - else { - coin = await this.node.getCoin(outpoint.hash, outpoint.index); - } + coin = await Coin.fromTX( + (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1); if (!coin) throw new Error("Could not find coin"); var mtx = new MTX({ diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 3f32692..02ce98a 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -254,7 +254,7 @@ testEach = (isFullNode) => { describe(".getTrustDecreasingMTX()", () => { var trustTXs; beforeEach(() => { - var getTXStub = sinon.stub(node, "getCoin"); + var getTXStub = sinon.stub(wallet, "getTX"); var tx; trustTXs = []; @@ -263,24 +263,14 @@ testEach = (isFullNode) => { trustTXs.push(tx); tir.addTX(tx); - getTXStub.withArgs(tx.hash("hex"), 0).returns(new Coin({ - script: tx.outputs[0].script, - value: tx.outputs[0].value, - index: 0, - hash: tx.hash("hex") - })); + getTXStub.withArgs(tx.hash("hex")).returns(TXRecord.fromTX(tx)); trustIncreasingMTX.outputs[0].value = 100 * COIN; tx = trustIncreasingMTX.toTX(); trustTXs.push(tx); tir.addTX(tx); - getTXStub.withArgs(tx.hash("hex"), 0).returns(new Coin({ - script: tx.outputs[0].script, - value: tx.outputs[0].value, - index: 0, - hash: tx.hash("hex") - })); + getTXStub.withArgs(tx.hash("hex")).returns(TXRecord.fromTX(tx)); trustIncreasingMTX.outputs[0].value = 500 * COIN; tx = trustIncreasingMTX.toTX(); @@ -329,15 +319,14 @@ testEach = (isFullNode) => { it("creates correct trust decreasing transactions", async () => { var mtxs = tir.createTrustDecreasingMTXs( - addr.alice.privKey, addr.bob.pubKey, 82 * COIN - ); + addr.alice.privKey, addr.bob.pubKey, 82 * COIN, wallet); await checkMTXs(mtxs, alice); }); it("creates correct trust stealing transactions", async () => { var mtxs = tir.createTrustDecreasingMTXs( - addr.alice.privKey, addr.bob.pubKey, 82 * COIN, charlie - ); + addr.alice.privKey, addr.bob.pubKey, 82 * COIN, + wallet, charlie); await checkMTXs(mtxs, charlie); }); @@ -453,10 +442,10 @@ describeTest = (isFullNode) => { }); }; -describe.only("TrustIsRisk full node", () => { +describe("TrustIsRisk full node", () => { describeTest(true); }); -describe.only("TrustIsRisk SPV node", () => { +describe("TrustIsRisk SPV node", () => { describeTest(false); }); From 675c7f7ff5dcc9fe462bb53942f1a18c0cc0e9b3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Apr 2018 22:11:46 +0100 Subject: [PATCH 421/540] Merge coin declaration and assignment --- src/trust_is_risk.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index edaf2f5..5f333e6 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -76,8 +76,7 @@ class TrustIsRisk { trustAmount : number, wallet : bcoin$Wallet, fee : ?number) : Promise { if (!fee) fee = 1000; // TODO: estimate this - var coin = null; - coin = await Coin.fromTX( + var coin = await Coin.fromTX( (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1); if (!coin) throw new Error("Could not find coin"); if (origin === dest) throw new Error("Can not increase self-trust."); @@ -165,8 +164,7 @@ class TrustIsRisk { if (!payee) payee = directTrust.getOriginEntity(); if (!fee) fee = 1000; // TODO: estimate this var outpoint = new Outpoint(directTrust.txHash, directTrust.outputIndex); - var coin = null; - coin = await Coin.fromTX( + var coin = await Coin.fromTX( (await wallet.getTX(outpoint.hash)).tx, outpoint.index, -1); if (!coin) throw new Error("Could not find coin"); From e4aa45b0d8cbd55f380f693342c4863c6b59eb11 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 3 Apr 2018 21:11:31 +0100 Subject: [PATCH 422/540] Use wallet for createTrust{In,De}creasingMTX() Import all keyrings to wallet in order for the wallet to accept transactions --- test/full_node.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 1c251af..b31a52f 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -23,6 +23,7 @@ describe("FullNode", () => { var node = null; var watcher = null; var walletDB = null; + var wallet = null; before("set up addTX() spy", function() { sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); @@ -33,6 +34,10 @@ describe("FullNode", () => { }); beforeEach("prepare node", async () => { + for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { + keyRing.network = bcoin.network.get(); + } + node = new Trust.FullNode({ network: bcoin.network.get().toString(), passphrase: "secret" @@ -41,6 +46,11 @@ describe("FullNode", () => { await node.initialize(); walletDB = node.require("walletdb"); node.startSync(); + + wallet = await testHelpers.createWallet(walletDB, "wallet"); + for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { + await wallet.importKey(keyRing, "secret"); + } }); beforeEach("get watcher", async () => { @@ -81,10 +91,9 @@ describe("FullNode", () => { beforeEach("apply graph transactions", async () => { addresses = {}; - for (var [name, keyRing] of Object.entries(fixtures.keyRings)) { + for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { addresses[name] = helpers.pubKeyToEntity( - keyRing.getPublicKey(), node.network - ); + keyRing.getPublicKey(), node.network); } // Alice mines three blocks, each rewards her with 50 spendable BTC @@ -142,8 +151,7 @@ describe("FullNode", () => { // Alice mines another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey(), node.network - )); + fixtures.keyRings.alice.getPublicKey(), node.network)); await testHelpers.delay(500); var graph = require("./graphs/nobodyLikesFrank.json"); @@ -158,8 +166,7 @@ describe("FullNode", () => { let mtx = await node.trust.createTrustIncreasingMTX( fixtures.keyRings[origin].getPrivateKey(), fixtures.keyRings[dest].getPublicKey(), - outpoint, - value * consensus.COIN); + outpoint, value * consensus.COIN, wallet); assert(await mtx.verify()); @@ -198,8 +205,7 @@ describe("FullNode", () => { it("after decreasing some trusts computes trusts correctly", async () => { var mtxs = await node.trust.createTrustDecreasingMTXs( fixtures.keyRings.alice.getPrivateKey(), - fixtures.keyRings.bob.getPublicKey(), 3 * COIN - ); + fixtures.keyRings.bob.getPublicKey(), 3 * COIN, wallet); mtxs.length.should.equal(1); var mtx = await mtxs[0]; From 7ac5b8f6165e8b35b5c0c2e9069361888f8e4851 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 4 Apr 2018 14:54:07 +0100 Subject: [PATCH 423/540] Simplify code Shorten selection of node type in trust_is_risk tests, iterate more cleanly over keyrings in full_node tests --- test/full_node.js | 11 +++++------ test/trust_is_risk.js | 8 ++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index b31a52f..2cc2a8e 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -34,8 +34,8 @@ describe("FullNode", () => { }); beforeEach("prepare node", async () => { - for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { - keyRing.network = bcoin.network.get(); + for (let name in fixtures.keyRings) { + fixtures.keyRings[name].network = bcoin.network.get(); } node = new Trust.FullNode({ @@ -48,8 +48,8 @@ describe("FullNode", () => { node.startSync(); wallet = await testHelpers.createWallet(walletDB, "wallet"); - for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { - await wallet.importKey(keyRing, "secret"); + for (let name in fixtures.keyRings) { + await wallet.importKey(fixtures.keyRings[name], "secret"); } }); @@ -180,8 +180,7 @@ describe("FullNode", () => { // Alice mines yet another block await testHelpers.mineBlock(node, helpers.pubKeyToEntity( - fixtures.keyRings.alice.getPublicKey(), node.network - )); + fixtures.keyRings.alice.getPublicKey(), node.network)); await testHelpers.delay(500); }); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 02ce98a..eae5bf9 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -41,12 +41,8 @@ var node, tir, walletDB, wallet, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; setupTest = async (isFullNode) => { - if (isFullNode) { - node = new bcoin.fullnode({network: bcoin.network.get().toString()}); - } - else { - node = new bcoin.spvnode({network: bcoin.network.get().toString()}); - } + const nodeClass = bcoin[isFullNode? "fullnode" : "spvnode"]; + node = new nodeClass({network: bcoin.network.get().toString()}); node.use(walletPlugin); tir = new Trust.TrustIsRisk(node); walletDB = node.require("walletdb"); From a65e66ba905fcd6b8de19ea24a20bee9f0d92aa7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Apr 2018 19:09:16 +0100 Subject: [PATCH 424/540] Use "get" syntax for valid and spendable --- src/direct_trust.js | 4 ++-- src/trust_db.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/direct_trust.js b/src/direct_trust.js index a28939c..b5547c7 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -60,11 +60,11 @@ class DirectTrust { return this.next !== null; } - isSpendable() : boolean { + get spendable() : boolean { return !this.isSpent() && !this.isNull(); } - isValid() : boolean { + get valid() : boolean { // TODO: Consider removing this function and ensure validity at build time by using the flow // type system, possibly by creating sub-types like "IncreasingDirectTrust" etc. if ((this.outputIndex === null) !== (this.script === null)) return false; diff --git a/src/trust_db.js b/src/trust_db.js index d41e680..4507d31 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -38,7 +38,7 @@ class TrustDB { } getSpendableDirectTrusts(origin : Entity, dest : Entity) : DirectTrust[] { - return this.getDirectTrusts(origin, dest).filter((t) => t.isSpendable()); + return this.getDirectTrusts(origin, dest).filter((t) => t.spendable); } getDirectTrusts(origin : Entity, dest : Entity) : DirectTrust[] { @@ -100,10 +100,10 @@ class TrustDB { if (trust.prev !== null) { trust.prev.spend(trust); - assert(trust.prev && trust.prev.isValid() && !trust.prev.isSpendable()); + assert(trust.prev && trust.prev.valid && !trust.prev.spendable); } - assert(trust.isValid()); + assert(trust.valid); trusts.push(trust); this.txToDirectTrust.set(trust.txHash, trust); From dfaf27cd4fb8139b96333b00c032711eb510f900 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 17 Apr 2018 19:13:12 +0100 Subject: [PATCH 425/540] Add minimal testcase for full/spv tx circulation --- minimal_testcases/txcirculation/helpers.js | 126 ++++++++++++++++++ .../txcirculation/txcirculation.js | 114 ++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 minimal_testcases/txcirculation/helpers.js create mode 100644 minimal_testcases/txcirculation/txcirculation.js diff --git a/minimal_testcases/txcirculation/helpers.js b/minimal_testcases/txcirculation/helpers.js new file mode 100644 index 0000000..1a5acb9 --- /dev/null +++ b/minimal_testcases/txcirculation/helpers.js @@ -0,0 +1,126 @@ +var WalletDB = require("bcoin/lib/wallet/walletdb"); +var bcoin = require("bcoin"); +var assert = require("assert"); + +var testHelpers = { + createWallet: async (walletDB, id) => { + var options = { + id, + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }; + + return walletDB.create(options); + }, + + mineBlock: async (node, rewardAddress) => { + var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); + await node.chain.add(block); + // node.chain.tip does not contain all the properties we want, + // so we need to fetch it: + return node.getBlock(node.chain.tip.hash); + }, + + delay: async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); + } +}; + +class NodeWatcher { + constructor(node) { + this.txCount = 0; + this.blockCount = 0; + this.node = node; + this.node.on("tx", this.onTX.bind(this)); + this.node.on("block", this.onBlock.bind(this)); + } + + onTX() { + this.txCount++; + } + + onBlock() { + this.blockCount++; + } + + async waitForBlock(initialCount) { + if (initialCount === undefined) initialCount = this.blockCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.blockCount > initialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } + + async waitForTX(input, wallet) { + if (wallet) { + while (true) { + if (await wallet.getTX(input.hash("hex"))) + break; + await testHelpers.delay(100); + } + } + var initialCount = null; + switch (typeof input) { + case "number": + initialCount = input; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "undefined": // TODO: reuse code + initialCount = this.txCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "object": + var tx = input; + await new Promise((resolve, reject) => { + var check = (() => { + // This breaks node.pool.on("tx", ...) + if (this.node.spv) { + if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) + resolve(); + else setTimeout(check, 100); + } + else { // this is not an SPV node + if (this.node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + } + }).bind(this); + + check(); + }); + break; + + default: + throw new Error("input cannot be " + typeof input); // TODO: throw correct error + } + } +} + +testHelpers.NodeWatcher = NodeWatcher; + +module.exports = testHelpers; diff --git a/minimal_testcases/txcirculation/txcirculation.js b/minimal_testcases/txcirculation/txcirculation.js new file mode 100644 index 0000000..01779ce --- /dev/null +++ b/minimal_testcases/txcirculation/txcirculation.js @@ -0,0 +1,114 @@ +(async () => { + const Trust = require("../../lib") + const bcoin = require("bcoin").set("regtest") + const Script = bcoin.script + const Address = bcoin.primitives.Address + const KeyRing = bcoin.primitives.KeyRing + const MTX = bcoin.primitives.MTX + const Input = bcoin.primitives.Input + const Output = bcoin.primitives.Output + const Outpoint = bcoin.primitives.Outpoint + const walletPlugin = bcoin.wallet.plugin + const secp256k1 = bcoin.crypto.secp256k1 + const consensus = require("bcoin/lib/protocol/consensus") + const should = require("should") + const assert = require("assert") + const helpers = require("./helpers") + + const COIN = consensus.COIN + + const spvNode = new Trust.SPVNode({ + network: bcoin.network.get().toString(), + httpPort: 48445, + passphrase: "secret", + nodes: ["127.0.0.1:48448"] + }) + await spvNode.initialize() + const spvWalletDB = spvNode.require("walletdb") + + const fullNode = new Trust.FullNode({ + network: bcoin.network.get().toString(), + httpPort: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }) + await fullNode.initialize() + const fullWalletDB = fullNode.require("walletdb") + + fullNode.startSync() + spvNode.startSync() + + const fullWatcher = new helpers.NodeWatcher(fullNode) + const spvWatcher = new helpers.NodeWatcher(spvNode) + + const spvWallet1 = await helpers.createWallet( + spvWalletDB, "spvWallet1") + const spvWallet2 = await helpers.createWallet( + spvWalletDB, "spvWallet2") + + const fullWallet1 = await helpers.createWallet( + fullWalletDB, "fullWallet1") + const fullWallet2 = await helpers.createWallet( + fullWalletDB, "fullWallet2") + + await helpers.delay(1000) + // Produce a block and reward the fullWallet1, + // so that we have a coin to spend. + await helpers.mineBlock(fullNode, fullWallet1.getAddress("base58")) + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0 + await helpers.delay(100) + + const full2TX = await fullWallet1.send({ + outputs: [{ + value: 10 * COIN, + address: fullWallet2.getAddress("base58") + }] + }) + await fullWatcher.waitForTX(full2TX, fullWallet1) + await fullWatcher.waitForTX(full2TX, fullWallet2) + + const fullSpvTX = await fullWallet2.send({ + outputs: [{ + value: 9 * COIN, + address: spvWallet1.getAddress("base58") + }] + }) + await spvWatcher.waitForTX(fullSpvTX, spvWallet1) + await fullWatcher.waitForTX(fullSpvTX, fullWallet2) + + const spv2TX = await spvWallet1.send({ + outputs: [{ + value: 8 * COIN, + address: spvWallet2.getAddress("base58") + }] + }) + await spvWatcher.waitForTX(spv2TX, spvWallet1) + await spvWatcher.waitForTX(spv2TX, spvWallet2) + await fullWatcher.waitForTX(spv2TX) + + const spvMinerTX = await spvWallet2.send({ + outputs: [{ + value: 7 * COIN, + address: fullWallet1.getAddress("base58") + }] + }) + await spvWatcher.waitForTX(spvMinerTX, spvWallet2) + await fullWatcher.waitForTX(spvMinerTX, fullWallet1) + + const view = await fullNode.chain.db.getSpentView(full2TX) + const actualBalance = (await fullWallet1.getBalance()).unconfirmed + const expectedBalance = consensus.BASE_REWARD - 10 + * COIN + 7 * COIN - full2TX.getFee(view) + + assert(actualBalance === expectedBalance) + + spvNode.stopSync() + fullNode.stopSync() + + await spvNode.tearDown() + await fullNode.tearDown() + console.log("success!") +})() From 19c0c0dc447a328dd971cbb129009367b10cf0b9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 11 May 2018 20:07:57 +0100 Subject: [PATCH 426/540] Remove redundant await before mtx.verify() --- test/full_node.js | 2 +- test/spv_node.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 2cc2a8e..02ee3d1 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -208,7 +208,7 @@ describe("FullNode", () => { mtxs.length.should.equal(1); var mtx = await mtxs[0]; - (await mtx.verify()).should.be.true(); + mtx.verify().should.be.true(); node.sendTX(mtx.toTX()); await testHelpers.delay(750); diff --git a/test/spv_node.js b/test/spv_node.js index e6e04a1..a9dccbd 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -116,7 +116,7 @@ describe("SPVNode", () => { mtx.addCoin(coinbaseCoin); mtx.sign(KeyRing.fromPrivate(privateKey1, true, "regtest")); - (await mtx.verify()).should.be.true(); + mtx.verify().should.be.true(); var tx = mtx.toTX(); spvNode.pool.spvFilter.test(tag).should.be.true(); @@ -283,7 +283,7 @@ describe("SPVNode", () => { var signedCount = mtx.sign(rings["alice"]); assert(signedCount === blockCount); - assert(await mtx.verify()); + assert(mtx.verify()); var tx = mtx.toTX(); @@ -359,7 +359,7 @@ describe("SPVNode", () => { value * consensus.COIN, wallet); - assert(await mtx.verify()); + assert(mtx.verify()); let tx = mtx.toTX(); @@ -422,7 +422,7 @@ describe("SPVNode", () => { mtxs.length.should.equal(1); var mtx = await mtxs[0]; - (await mtx.verify()).should.be.true(); + mtx.verify().should.be.true(); var tx = mtx.toTX(); miner.sendTX(tx); @@ -442,7 +442,7 @@ describe("SPVNode", () => { mtxs.length.should.equal(1); mtx = await mtxs[0]; - (await mtx.verify()).should.be.true(); + mtx.verify().should.be.true(); spvNode.sendTX(mtx.toTX()); await minerWatcher.waitForTX(); From c4217dfef0c1caddcec9261ffeb1c85b246a8c58 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 11 May 2018 20:09:07 +0100 Subject: [PATCH 427/540] Add missing spaces --- test/spv_node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index a9dccbd..e2590ef 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -291,11 +291,11 @@ describe("SPVNode", () => { await minerWatcher.waitForTX(tx); await spvWatcher.waitForTX(tx); - for(name in minerNames) { + for (name in minerNames) { minerWallets[name].db.addTX(tx); } - for(name in spvNames) { + for (name in spvNames) { spvWallets[name].db.addTX(tx); } From 5bafae9603652ab1c94cbd5db97597c889892d7d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 18 May 2018 16:13:00 +0100 Subject: [PATCH 428/540] Attempt to fix last bugs --- test/helpers.js | 23 +++++++++- test/spv_node.js | 108 +++++++++++++++++++++++++++++------------------ 2 files changed, 89 insertions(+), 42 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 19ff502..c5098ca 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -119,7 +119,15 @@ class NodeWatcher { }); } - async waitForTX(input) { + async waitForTX(input, wallet) { + if (wallet) { + while (true) { + if (await wallet.getTX(input.hash("hex"))) + break; + await testHelpers.delay(100); + } + return; + } var initialCount = null; switch (typeof input) { case "number": @@ -152,7 +160,6 @@ class NodeWatcher { var tx = input; await new Promise((resolve, reject) => { var check = (() => { - // This breaks node.pool.on("tx", ...) if (this.node.spv) { if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) resolve(); @@ -173,6 +180,18 @@ class NodeWatcher { throw new Error("input cannot be " + typeof input); // TODO: throw correct error } } + + async waitForTrustDB(tx) { + await new Promise((resolve, reject) => { + var check = (() => { + if (this.node.trust.db.isTrustTX(tx.hash.toString("hex"))) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } } testHelpers.NodeWatcher = NodeWatcher; diff --git a/test/spv_node.js b/test/spv_node.js index e2590ef..dcf7901 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -144,10 +144,12 @@ describe("SPVNode", () => { address: minerWallet2.getAddress("base58") }] }); - await minerWatcher.waitForTX(miner2TX); - await spvWatcher.waitForTX(miner2TX); + await minerWatcher.waitForTX(miner2TX, minerWallet1); + await minerWatcher.waitForTX(miner2TX, minerWallet2); - Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); + //miner.trust.addTX.should.be.calledTwice() + // @dionyziz: why does the above fail?? + //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); var minerSpvTX = await minerWallet2.send({ outputs: [{ @@ -155,8 +157,8 @@ describe("SPVNode", () => { address: spvWallet1.getAddress("base58") }] }); - await minerWatcher.waitForTX(minerSpvTX); - await spvWatcher.waitForTX(minerSpvTX); + await spvWatcher.waitForTX(minerSpvTX, spvWallet1); + await minerWatcher.waitForTX(minerSpvTX, minerWallet2); Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(4); @@ -166,9 +168,11 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); - await spvWatcher.waitForTX(spv2TX); - await minerWatcher.waitForTX(spv2TX); + await minerWatcher.waitForTX(); + await spvWatcher.waitForTX(spv2TX, spvWallet1); + await spvWatcher.waitForTX(spv2TX, spvWallet2); + // @dionyziz: Fixed it by putting minerWatcher before and removing inputs Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(6); var spvMinerTX = await spvWallet2.send({ @@ -177,8 +181,8 @@ describe("SPVNode", () => { address: minerWallet1.getAddress("base58") }] }); - await spvWatcher.waitForTX(spvMinerTX); - await minerWatcher.waitForTX(spvMinerTX); + await spvWatcher.waitForTX(spvMinerTX, spvWallet2); + await minerWatcher.waitForTX(spvMinerTX, minerWallet1); var view = await miner.chain.db.getSpentView(miner2TX); var actualBalance = (await minerWallet1.getBalance()).unconfirmed; @@ -188,7 +192,7 @@ describe("SPVNode", () => { Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(8); }); - describe("with the nobodyLikesFrank.json example", () => { + describe.only("with the nobodyLikesFrank.json example", () => { var minerNames = { "alice": "alice", "bob": "bob", @@ -321,23 +325,29 @@ describe("SPVNode", () => { await testHelpers.delay(500); var graph = require("./graphs/nobodyLikesFrank.json"); + + function buildVars(player) { + return (spvNames[player]) ? + [spvNode, spvWatcher, spvWallets[player]] : + [miner, minerWatcher, minerWallets[player]] + } + + let node = { + origin: null, + dest: null + }; + let watcher = { + origin: null, + dest: null + }; + let wallet = { + origin: null, + dest: null + }; + for (var origin in graph) { - let node = null; - let watcher = null; - let originWallet = null; - let destWallet = null; - - if (spvNames[origin]) { - node = spvNode; - watcher = spvWatcher; - originWallet = spvWallets[origin]; - } - else { - node = miner; - watcher = minerWatcher; - originWallet = minerWallets[origin]; - } + [node.origin, watcher.origin, wallet.origin] = buildVars(origin); var neighbours = graph[origin]; @@ -345,29 +355,41 @@ describe("SPVNode", () => { var value = neighbours[dest]; if (!value || value < 1) continue; - destWallet = (spvNames[dest]) ? spvWallets[dest] - : minerWallets[dest]; + [node.dest, watcher.dest, wallet.dest] = buildVars(dest); + let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); - let wallet = (node.spv) ? spvWallets[origin] : null; - let mtx = await node.trust.createTrustIncreasingMTX( + let mtx = await node.origin.trust.createTrustIncreasingMTX( rings[origin].getPrivateKey(), rings[dest].getPublicKey(), outpoint, value * consensus.COIN, - wallet); + wallet.origin); assert(mtx.verify()); let tx = mtx.toTX(); - - node.sendTX(tx); - await watcher.waitForTX(); - - await originWallet.db.addTX(tx); - await destWallet.db.addTX(tx); + console.log("ignore above"); + console.log("origin", origin, "accepts tx?", await wallet.origin.add(tx)); + console.log("out and between") + console.log("dest", dest, "accepts tx?", await wallet.dest.add(tx)); + process.exit(); + + node.origin.sendTX(tx); + console.log(origin, dest, "aaa") + await watcher.origin.waitForTX(tx, wallet.origin); + console.log("origin has tx"); + await watcher.dest.waitForTX(tx, wallet.dest); // TODO: dest doesn't get tx + //await spvWatcher.waitForTX(); // it worked one time! race condition + console.log("both sides have tx") + // spv node accepts inv, but does not put tx in the spvNode.txFilter; this is + // reserved for *sent*, not *received* txs + + console.log(origin, dest, "bbb") + await wallet.origin.db.addTX(); + await wallet.dest.db.addTX(); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } @@ -417,7 +439,8 @@ describe("SPVNode", () => { it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { var mtxs = await miner.trust.createTrustDecreasingMTXs( rings["alice"].getPrivateKey(), - rings["bob"].getPublicKey(), 3 * COIN + rings["bob"].getPublicKey(), 3 * COIN, + minerWallets["alice"] ); mtxs.length.should.equal(1); var mtx = await mtxs[0]; @@ -426,9 +449,14 @@ describe("SPVNode", () => { var tx = mtx.toTX(); miner.sendTX(tx); - await testHelpers.delay(3000); - await minerWatcher.waitForTX(tx); - await spvWatcher.waitForTX(tx); + await testHelpers.delay(3000); // combine with next promises with race + for (name in minerNames) { + console.log(name,"aaa") // see why spv node doesn't accept inv + await minerWatcher.waitForTX(tx) + }; + for (name in spvNames) { + await spvWatcher.waitForTX(tx) + }; miner.trust.getIndirectTrust(addresses["alice"], addresses["bob"]).should.equal(7 * COIN); spvNode.trust.getIndirectTrust(addresses["alice"], From 280b53c598042c63a0804b244fd478378f9e1e4a Mon Sep 17 00:00:00 2001 From: Dionysis Zindros Date: Fri, 18 May 2018 18:36:34 +0300 Subject: [PATCH 429/540] Comments to improve test flakiness --- test/helpers.js | 59 ++++++++++++++++++------------------------------ test/spv_node.js | 2 +- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index c5098ca..d1814da 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -38,7 +38,7 @@ var testHelpers = { getP2PKHOutput: (dest, value) => { var address = bcoin.primitives.Address.fromString(dest); var script = bcoin.script.fromPubkeyhash(address.hash); - + return new bcoin.primitives.Output({script, value}); }, @@ -56,7 +56,7 @@ var testHelpers = { // Don't care about the signature "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 " + testHelpers.bufferToScript(pubKey)) - }); + }); }, getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { @@ -84,7 +84,7 @@ var testHelpers = { var neighbours = graph[origin]; for (var dest in neighbours) { var value = neighbours[dest]; - trust.addTX(testHelpers.getTrustIncreasingMTX(addressBook[origin].pubKey, addressBook[dest].pubKey, value).toTX()); + trust.addTX(testHelpers.getTrustIncreasingMTX(addressBook[origin].pubKey, addressBook[dest].pubKey, value).toTX()); } } } @@ -132,48 +132,33 @@ class NodeWatcher { switch (typeof input) { case "number": initialCount = input; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount) - resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); + while (true) { + if (this.txCount > initialCount) { + return; + } + await testHelpers.delay(100); + } break; - case "undefined": // TODO: reuse code - initialCount = this.txCount; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.txCount > initialCount) - resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); + case "undefined": + await waitForTX(1); break; case "object": var tx = input; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.node.spv) { - if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) - resolve(); - else setTimeout(check, 100); + while (true) { + if (this.node.spv) { + if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) { + return; } - else { // this is not an SPV node - if (this.node.pool.hasTX(tx.hash().toString("hex"))) - resolve(); - else setTimeout(check, 100); + } + else { // this is not an SPV node + if (this.node.pool.hasTX(tx.hash().toString("hex"))) { + return; } - }).bind(this); - - check(); - }); + } + await testHelpers.delay(100); + } break; default: diff --git a/test/spv_node.js b/test/spv_node.js index dcf7901..2c4e987 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -168,7 +168,7 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); - await minerWatcher.waitForTX(); + await minerWatcher.waitForTX(); // see why tx is received twice? await spvWatcher.waitForTX(spv2TX, spvWallet1); await spvWatcher.waitForTX(spv2TX, spvWallet2); From c81e3658335ef5a652a58cb04372f4f14ec7265f Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 May 2018 21:40:58 +0100 Subject: [PATCH 430/540] Allow infinite timeout for tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e411a7..a5e335b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 40000", + "test": "npm run build && mocha -t 0", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 88a3618beb7c47e360b0bac34a82c040ddbb7e8a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 May 2018 21:41:26 +0100 Subject: [PATCH 431/540] Remove note --- note | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 note diff --git a/note b/note deleted file mode 100644 index 6c61ba9..0000000 --- a/note +++ /dev/null @@ -1,3 +0,0 @@ -1) tir => node.trust (test/trust_is_risk.js:40) -2) stub (test/trust_is_risk.js:242,263) -3) spv wallet getCoin stuff (src/trust_is_risk.js:75,84-91,133,170,180-187) From 3963d922bcb1ee80c9e4a6757a867fb769fa4fc9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 May 2018 21:44:54 +0100 Subject: [PATCH 432/540] Simplify waitForTrustDB() --- test/helpers.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index d1814da..800ea01 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -167,15 +167,12 @@ class NodeWatcher { } async waitForTrustDB(tx) { - await new Promise((resolve, reject) => { - var check = (() => { - if (this.node.trust.db.isTrustTX(tx.hash.toString("hex"))) - resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); + while (true) { + if (this.node.trust.db.isTrustTX(tx.hash.toString("hex"))) { + return; + } + await testHelpers.delay(100); + } } } From 16810488e1a42d391f63b80f40c0ef5c22a23bab Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 May 2018 22:57:22 +0100 Subject: [PATCH 433/540] Wait for one more tx in waitForTX() --- test/helpers.js | 2 +- test/spv_node.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 800ea01..a8e96e5 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -141,7 +141,7 @@ class NodeWatcher { break; case "undefined": - await waitForTX(1); + await this.waitForTX(this.txCount); break; case "object": diff --git a/test/spv_node.js b/test/spv_node.js index 2c4e987..d653b03 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -471,10 +471,11 @@ describe("SPVNode", () => { mtx = await mtxs[0]; mtx.verify().should.be.true(); - spvNode.sendTX(mtx.toTX()); + tx = mtx.toTX(); + spvNode.sendTX(tx); - await minerWatcher.waitForTX(); - await spvWatcher.waitForTX(); + await minerWatcher.waitForTX(tx); + await spvWatcher.waitForTX(tx); miner.trust.getIndirectTrust(addresses["dave"], addresses["eve"]).should.equal(10 * COIN); spvNode.trust.getIndirectTrust(addresses["dave"], From a12f3c5c9331eaa385cd71273057675025a40fd1 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 May 2018 23:16:39 +0100 Subject: [PATCH 434/540] Rephrase should for clarity --- test/full_node.js | 2 +- test/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 02ee3d1..d80dc06 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -82,7 +82,7 @@ describe("FullNode", () => { }); await watcher.waitForTX(); - node.trust.addTX.should.be.calledOnce(); + node.trust.addTX.should.have.been.calledOnce(); }); describe("with the nobodyLikesFrank.json example", () => { diff --git a/test/spv_node.js b/test/spv_node.js index d653b03..cb12ce1 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -168,7 +168,7 @@ describe("SPVNode", () => { address: spvWallet2.getAddress("base58") }] }); - await minerWatcher.waitForTX(); // see why tx is received twice? + await minerWatcher.waitForTX(spv2TX); // see why tx is received twice? await spvWatcher.waitForTX(spv2TX, spvWallet1); await spvWatcher.waitForTX(spv2TX, spvWallet2); From ffd0cac95a2fab3c713a26f41858e271002b2fb5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 May 2018 23:22:48 +0100 Subject: [PATCH 435/540] Wait for particular txs --- test/full_node.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index d80dc06..f109a70 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -74,13 +74,15 @@ describe("FullNode", () => { consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - await sender.send({ + let tx = await sender.send({ outputs: [{ value: 10 * COIN, address: receiver.getAddress("base58") }] }); - await watcher.waitForTX(); + await watcher.waitForTX(tx, sender); + await watcher.waitForTX(tx, receiver); + await testHelpers.delay(100); // @dionyziz: how to avoid timeout? node.trust.addTX.should.have.been.calledOnce(); }); @@ -139,7 +141,7 @@ describe("FullNode", () => { var tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(); + await watcher.waitForTX(tx); prevout = {}; fixtures.names.forEach((name) => { @@ -172,7 +174,7 @@ describe("FullNode", () => { let tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(); + await watcher.waitForTX(tx, wallet); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } From ebd5926ffba202b3a174fc3f2ae996d4a7148b7e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 22 May 2018 18:26:16 +0100 Subject: [PATCH 436/540] Highlight problem when using waitForTX(tx) --- test/full_node.js | 9 +++++---- test/helpers.js | 1 + test/spv_node.js | 14 +++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index f109a70..90a6664 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -62,7 +62,7 @@ describe("FullNode", () => { await node.tearDown(); }); - it("should call trust.addTX() on every transaction", async function() { + it.only("should call trust.addTX() on every transaction", async function() { var sender = await testHelpers.createWallet(walletDB, "sender"); var receiver = await testHelpers.createWallet(walletDB, "receiver"); @@ -80,9 +80,10 @@ describe("FullNode", () => { address: receiver.getAddress("base58") }] }); - await watcher.waitForTX(tx, sender); - await watcher.waitForTX(tx, receiver); - await testHelpers.delay(100); // @dionyziz: how to avoid timeout? + console.log("prin"); + await watcher.waitForTX(tx); // strange ordering of events on the node.on queue + console.log("meta"); + await testHelpers.delay(100); // @dionyziz: how to avoid timeout when waitForTX(tx)? node.trust.addTX.should.have.been.calledOnce(); }); diff --git a/test/helpers.js b/test/helpers.js index a8e96e5..d089a21 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -101,6 +101,7 @@ class NodeWatcher { onTX() { this.txCount++; + console.log("tx! spv node?", this.node.spv); } onBlock() { diff --git a/test/spv_node.js b/test/spv_node.js index cb12ce1..515487c 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -123,7 +123,7 @@ describe("SPVNode", () => { tx.isWatched(spvNode.pool.spvFilter).should.be.true(); }); - it("should call trust.addTX() on every transaction", async function() { + it.only("should call trust.addTX() on every transaction", async function() { var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); @@ -144,12 +144,12 @@ describe("SPVNode", () => { address: minerWallet2.getAddress("base58") }] }); - await minerWatcher.waitForTX(miner2TX, minerWallet1); - await minerWatcher.waitForTX(miner2TX, minerWallet2); + //await minerWatcher.waitForTX(miner2TX, minerWallet1); + //await minerWatcher.waitForTX(miner2TX, minerWallet2); + await minerWatcher.waitForTX(); + await spvWatcher.waitForTX(); - //miner.trust.addTX.should.be.calledTwice() - // @dionyziz: why does the above fail?? - //Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); + Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); var minerSpvTX = await minerWallet2.send({ outputs: [{ @@ -192,7 +192,7 @@ describe("SPVNode", () => { Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(8); }); - describe.only("with the nobodyLikesFrank.json example", () => { + describe("with the nobodyLikesFrank.json example", () => { var minerNames = { "alice": "alice", "bob": "bob", From e408a0c69ba5aa1bc5d578817588b1915c20ea21 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 22 May 2018 19:16:57 +0100 Subject: [PATCH 437/540] Remove standard eslint checks --- .eslintrc.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2d511eb..8c47cd7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,6 @@ "node": true }, "extends": [ - "eslint:recommended", "plugin:flowtype/recommended" ], "rules": { From 4e2babb64596edddcc75d6aeb989ab4c54d5cb89 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 28 May 2018 01:23:31 +0100 Subject: [PATCH 438/540] Use updated waitForTX() and flushEvents() --- test/full_node.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 90a6664..5f6d3d2 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -80,10 +80,8 @@ describe("FullNode", () => { address: receiver.getAddress("base58") }] }); - console.log("prin"); - await watcher.waitForTX(tx); // strange ordering of events on the node.on queue - console.log("meta"); - await testHelpers.delay(100); // @dionyziz: how to avoid timeout when waitForTX(tx)? + await watcher.waitForTX(tx); + await testHelpers.flushEvents(); // @dionyziz: needs @ least 3 ms...? node.trust.addTX.should.have.been.calledOnce(); }); @@ -140,9 +138,10 @@ describe("FullNode", () => { assert(signedCount === blockCount); assert(await mtx.verify()); - var tx = mtx.toTX(); + let tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(tx); + await watcher.waitForTX(tx); // @dionyziz: does not work with wallet + await testHelpers.flushEvents(); prevout = {}; fixtures.names.forEach((name) => { @@ -175,7 +174,8 @@ describe("FullNode", () => { let tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(tx, wallet); + await watcher.waitForTX(tx); + await testHelpers.flushEvents(); // @dionyziz: needs a long time prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } @@ -212,9 +212,12 @@ describe("FullNode", () => { var mtx = await mtxs[0]; mtx.verify().should.be.true(); - node.sendTX(mtx.toTX()); + let tx = mtx.toTX(); + node.sendTX(tx); + + await watcher.waitForTX(tx); + await testHelpers.flushEvents(); // @dionyziz: needs an even longer time - await testHelpers.delay(750); node.trust.getIndirectTrust(addresses.alice, addresses.bob).should.equal(7 * COIN); }); }); From 8c8aa3337b95d96048a52c8a1caaac49fda4e225 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 28 May 2018 01:25:17 +0100 Subject: [PATCH 439/540] Update waitForTX(), write flushEvents() Wait for new tx in the waitForTX() loop instead of arbitrary timeout, write flushEvents() with a set timeout to emply events queue --- test/helpers.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index d089a21..ffdc9bd 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -31,6 +31,10 @@ var testHelpers = { }); }, + flushEvents: () => { + return testHelpers.delay(100); + }, + bufferToScript: (data) => { return `0x${Number(data.length).toString(16)} 0x${data.toString("hex")}`; }, @@ -97,17 +101,27 @@ class NodeWatcher { this.node = node; this.node.on("tx", this.onTX.bind(this)); this.node.on("block", this.onBlock.bind(this)); + this.waitForSomeTxPromiseResolve = []; } onTX() { this.txCount++; - console.log("tx! spv node?", this.node.spv); + for (const resolve of this.waitForSomeTxPromiseResolve) { + resolve(); + } + this.waitForSomeTxPromiseResolve = []; } onBlock() { this.blockCount++; } + waitForSomeTX() { + return new Promise((resolve, reject) => { + this.waitForSomeTxPromiseResolve.push(resolve); + }); + } + async waitForBlock(initialCount) { if (initialCount === undefined) initialCount = this.blockCount; await new Promise((resolve, reject) => { @@ -125,7 +139,7 @@ class NodeWatcher { while (true) { if (await wallet.getTX(input.hash("hex"))) break; - await testHelpers.delay(100); + await this.waitForSomeTX(); } return; } @@ -137,7 +151,7 @@ class NodeWatcher { if (this.txCount > initialCount) { return; } - await testHelpers.delay(100); + await this.waitForSomeTX(); } break; @@ -158,7 +172,7 @@ class NodeWatcher { return; } } - await testHelpers.delay(100); + await this.waitForSomeTX(); } break; From c5307c09550efa5322a332eb80bc1bfcc7631f68 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 29 May 2018 19:56:34 +0100 Subject: [PATCH 440/540] Remove "only" from test --- test/full_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/full_node.js b/test/full_node.js index 5f6d3d2..104a323 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -62,7 +62,7 @@ describe("FullNode", () => { await node.tearDown(); }); - it.only("should call trust.addTX() on every transaction", async function() { + it("should call trust.addTX() on every transaction", async function() { var sender = await testHelpers.createWallet(walletDB, "sender"); var receiver = await testHelpers.createWallet(walletDB, "receiver"); From 70bd2cab54998a91f3885dcfbb0ee6665ee185d3 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 29 May 2018 20:09:13 +0100 Subject: [PATCH 441/540] Remove "while (true) ... break" to satisfy linter --- test/helpers.js | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index ffdc9bd..93fe8e7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -124,22 +124,15 @@ class NodeWatcher { async waitForBlock(initialCount) { if (initialCount === undefined) initialCount = this.blockCount; - await new Promise((resolve, reject) => { - var check = (() => { - if (this.blockCount > initialCount) resolve(); - else setTimeout(check, 100); - }).bind(this); - - check(); - }); + while (!(this.blockCount > initialCount)) { + await testHelpers.delay(100); + } } async waitForTX(input, wallet) { if (wallet) { - while (true) { - if (await wallet.getTX(input.hash("hex"))) - break; - await this.waitForSomeTX(); + while (!(await wallet.getTX(input.hash("hex")))) { + await this.waitForSomeTX(); // @dionyziz: gets stuck, probably tx received and added asynchronously. cf test/spv_node.js:161 } return; } @@ -147,10 +140,7 @@ class NodeWatcher { switch (typeof input) { case "number": initialCount = input; - while (true) { - if (this.txCount > initialCount) { - return; - } + while (!(this.txCount > initialCount)) { await this.waitForSomeTX(); } break; @@ -161,17 +151,9 @@ class NodeWatcher { case "object": var tx = input; - while (true) { - if (this.node.spv) { - if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) { - return; - } - } - else { // this is not an SPV node - if (this.node.pool.hasTX(tx.hash().toString("hex"))) { - return; - } - } + while ((this.node.spv ? + !(this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) : + !(this.node.pool.hasTX(tx.hash().toString("hex"))))) { await this.waitForSomeTX(); } break; @@ -182,10 +164,7 @@ class NodeWatcher { } async waitForTrustDB(tx) { - while (true) { - if (this.node.trust.db.isTrustTX(tx.hash.toString("hex"))) { - return; - } + while (!(this.node.trust.db.isTrustTX(tx.hash.toString("hex")))) { await testHelpers.delay(100); } } From 0431bfddb1fe8fcf24c3c5bb9a0704c40d60059c Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 29 May 2018 20:11:14 +0100 Subject: [PATCH 442/540] Disallow constant conditions by linter --- .eslintrc.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.json b/.eslintrc.json index 8c47cd7..2d511eb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,6 +8,7 @@ "node": true }, "extends": [ + "eslint:recommended", "plugin:flowtype/recommended" ], "rules": { From e36c94982913fc02e214943c5577815c9bed671e Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 29 May 2018 20:14:05 +0100 Subject: [PATCH 443/540] Allow unsafe getters and setters in Flow Due to a bug in the currently used version of Flow, all getters and setters are considered dangerous, even if they do not have side-effects. This permission will be removed once we migrate to a more recent Flow version. --- .flowconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.flowconfig b/.flowconfig index 7fbc6b4..be6d503 100644 --- a/.flowconfig +++ b/.flowconfig @@ -11,3 +11,4 @@ [options] all=true +unsafe.enable_getters_and_setters=true From c9ecc06c407cf538d7b664b29fc4bf6bca4d2727 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 1 Jun 2018 20:08:14 +0100 Subject: [PATCH 444/540] Improve console.log()s, add missing semicolons --- test/spv_node.js | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 515487c..dc6335e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -144,10 +144,10 @@ describe("SPVNode", () => { address: minerWallet2.getAddress("base58") }] }); - //await minerWatcher.waitForTX(miner2TX, minerWallet1); - //await minerWatcher.waitForTX(miner2TX, minerWallet2); - await minerWatcher.waitForTX(); - await spvWatcher.waitForTX(); + await minerWatcher.waitForTX(miner2TX, minerWallet1); + await minerWatcher.waitForTX(miner2TX, minerWallet2); + await spvWatcher.waitForTX(miner2TX); + await testHelpers.flushEvents(); Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); @@ -156,9 +156,13 @@ describe("SPVNode", () => { value: 9 * COIN, address: spvWallet1.getAddress("base58") }] - }); - await spvWatcher.waitForTX(minerSpvTX, spvWallet1); + }); // @dionyziz: wtf spv doesn't receive inv! + console.log(miner.pool.selfish, "is miner selfish?"); + console.log("lookie here"); + console.log(minerSpvTX.hash().toString("hex")); await minerWatcher.waitForTX(minerSpvTX, minerWallet2); + await spvWatcher.waitForTX(minerSpvTX); + await testHelpers.flushEvents(); Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(4); @@ -329,7 +333,7 @@ describe("SPVNode", () => { function buildVars(player) { return (spvNames[player]) ? [spvNode, spvWatcher, spvWallets[player]] : - [miner, minerWatcher, minerWallets[player]] + [miner, minerWatcher, minerWallets[player]]; } let node = { @@ -372,22 +376,22 @@ describe("SPVNode", () => { let tx = mtx.toTX(); console.log("ignore above"); - console.log("origin", origin, "accepts tx?", await wallet.origin.add(tx)); - console.log("out and between") - console.log("dest", dest, "accepts tx?", await wallet.dest.add(tx)); + console.log("origin", origin, "accepts tx?", (await wallet.origin.add(tx)) ? true : false); + console.log("out and between"); + console.log("dest", dest, "accepts tx?", (await wallet.dest.add(tx)) ? true : false); process.exit(); node.origin.sendTX(tx); - console.log(origin, dest, "aaa") + console.log(origin, dest, "aaa"); await watcher.origin.waitForTX(tx, wallet.origin); console.log("origin has tx"); await watcher.dest.waitForTX(tx, wallet.dest); // TODO: dest doesn't get tx //await spvWatcher.waitForTX(); // it worked one time! race condition - console.log("both sides have tx") + console.log("both sides have tx"); // spv node accepts inv, but does not put tx in the spvNode.txFilter; this is // reserved for *sent*, not *received* txs - console.log(origin, dest, "bbb") + console.log(origin, dest, "bbb"); await wallet.origin.db.addTX(); await wallet.dest.db.addTX(); @@ -451,12 +455,12 @@ describe("SPVNode", () => { await testHelpers.delay(3000); // combine with next promises with race for (name in minerNames) { - console.log(name,"aaa") // see why spv node doesn't accept inv - await minerWatcher.waitForTX(tx) - }; + console.log(name,"aaa"); // see why spv node doesn't accept inv + await minerWatcher.waitForTX(tx); + } for (name in spvNames) { - await spvWatcher.waitForTX(tx) - }; + await spvWatcher.waitForTX(tx); + } miner.trust.getIndirectTrust(addresses["alice"], addresses["bob"]).should.equal(7 * COIN); spvNode.trust.getIndirectTrust(addresses["alice"], From 699e09f420f90c8dbdd5e2bb4f401f733ee0f963 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 3 Jun 2018 13:33:25 +0100 Subject: [PATCH 445/540] Remove redundant walletPlugin from node tests The wallet plugin is already used in src/{full,spv}_node when setting up the node. --- test/full_node.js | 1 - test/spv_node.js | 1 - 2 files changed, 2 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 104a323..0b250e6 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -8,7 +8,6 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var walletPlugin = bcoin.wallet.plugin; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); diff --git a/test/spv_node.js b/test/spv_node.js index dc6335e..5bdab88 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -8,7 +8,6 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var walletPlugin = bcoin.wallet.plugin; var secp256k1 = bcoin.crypto.secp256k1; var tag = require("../lib/tag"); var testHelpers = require("./helpers"); From 9574b7ba5e743d5adcdb36616833c79cbd2900c9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 3 Jun 2018 17:50:24 +0100 Subject: [PATCH 446/540] Reinstall packages --- package-lock.json | 4417 ++++++++++++++++++++++----------------------- 1 file changed, 2152 insertions(+), 2265 deletions(-) diff --git a/package-lock.json b/package-lock.json index 708f46e..98746b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,106 +4,34 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, "abstract-leveldown": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", - "integrity": "sha1-HF6Mal75Za6MNd+zqHcMR2uCxLg=", + "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", "optional": true, "requires": { "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" } }, "accepts": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", - "integrity": "sha1-1xyW99QdD+2iw4zRToonwEFY30o=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "optional": true, "requires": { - "mime-types": "2.0.14", - "negotiator": "0.4.9" - }, - "dependencies": { - "mime-db": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", - "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=", - "optional": true - }, - "mime-types": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", - "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", - "optional": true, - "requires": { - "mime-db": "1.12.0" - } - } - } - }, - "acorn": { - "version": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha1-kRy1PgNoB88Pp3jcXTcPvYZCRtc=", - "dev": true - }, - "acorn-jsx": { - "version": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz" - }, - "dependencies": { - "acorn": { - "version": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "mime-types": "2.1.18", + "negotiator": "0.6.1" } }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "optional": true - }, - "ajv": { - "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" - } - }, - "ajv-keywords": { - "version": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" - }, - "ansi-escapes": { - "version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" }, "ansi-regex": { "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, - "ansi-styles": { - "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -111,156 +39,266 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "requires": { - "delegates": "1.0.0", - "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz" - } - }, - "argparse": { - "version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - } - }, - "array-index": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz", - "integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "optional": true, "requires": { - "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" - } - }, - "array-union": { - "version": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + "delegates": "1.0.0", + "readable-stream": "2.3.6" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "optional": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, + "requires": { + "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "process-nextick-args": "2.0.0", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "string_decoder": "1.1.1", + "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } + } } }, - "array-uniq": { - "version": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=" - }, - "arrify": { - "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" - }, - "assert-plus": { + "async-limiter": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" - }, - "babel-code-frame": { - "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "js-tokens": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" - } + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, "babel-eslint": { - "version": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", "dev": true, "requires": { - "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "babel-traverse": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "babel-types": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "babylon": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz" - } - }, - "babel-messages": { - "version": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" - } - }, - "babel-runtime": { - "version": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", - "regenerator-runtime": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz" - } - }, - "babel-traverse": { - "version": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "babel-messages": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "babel-types": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "babylon": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "globals": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "invariant": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" - } - }, - "babel-types": { - "version": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "to-fast-properties": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz" + "babel-code-frame": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.4", + "lodash": "4.17.10" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } } }, - "babylon": { - "version": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha1-ry87iPpvXB5MY00aD46sT1WzleM=", - "dev": true - }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -269,57 +307,45 @@ }, "balanced-match": { "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base64-arraybuffer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz", - "integrity": "sha1-R030qfLaJOBd8xWMOx2zw81GoVQ=" + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" }, "base64id": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz", - "integrity": "sha1-As4P3u4M709ACA4ec+g08LG/zj8=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", "optional": true }, "bcoin": { - "version": "1.0.0-beta.12", - "resolved": "https://registry.npmjs.org/bcoin/-/bcoin-1.0.0-beta.12.tgz", - "integrity": "sha1-hb+4F/VjDlnKsLeHv51DaPwSRsQ=", + "version": "1.0.0-beta.15", + "resolved": "https://registry.npmjs.org/bcoin/-/bcoin-1.0.0-beta.15.tgz", + "integrity": "sha512-W35ksmbcoGdFZL9LgJpV3jBNI72ZxyJHqb932wTiMAtfI7puyQDz9Cfv8sVY603nvtN+wVleAvFR68gz080NVQ==", "requires": { - "bcoin-native": "0.0.14", - "bn.js": "4.11.6", - "elliptic": "6.3.2", - "leveldown": "1.5.0", - "secp256k1": "3.2.5", - "socket.io": "1.4.8", - "socket.io-client": "1.4.8" + "bcoin-native": "0.0.23", + "bn.js": "4.11.8", + "elliptic": "6.4.0", + "leveldown": "1.7.2", + "n64": "0.0.18", + "secp256k1": "3.3.0", + "socket.io": "2.0.3", + "socket.io-client": "2.0.3" } }, "bcoin-native": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/bcoin-native/-/bcoin-native-0.0.14.tgz", - "integrity": "sha1-gRvFFbIJRlvnGESsPzo7kO+J9BE=", - "optional": true, - "requires": { - "bindings": "1.2.1", - "nan": "2.5.1" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/bcoin-native/-/bcoin-native-0.0.23.tgz", + "integrity": "sha512-bk2XK9EtOcTiqS4cgJ5dy77R2bVJC65dTvLuhH+SxLemjERC3jbf8jadYvOYfZx/x8TF6fuxZzWruhc0OF3Bnw==", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "bindings": "1.3.0", + "nan": "2.10.0" } }, - "benchmark": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz", - "integrity": "sha1-Lx4vpMNZ8REiqhgwgiGOlX45DHM=" - }, "better-assert": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", @@ -329,9 +355,9 @@ } }, "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", "optional": true }, "bip66": { @@ -344,30 +370,44 @@ } }, "bl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz", - "integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "optional": true, "requires": { - "readable-stream": "2.0.6" + "readable-stream": "2.3.6", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" }, "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "optional": true + }, "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, "requires": { "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "string_decoder": "0.10.31", + "process-nextick-args": "2.0.0", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "string_decoder": "1.1.1", "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } }, "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } } } }, @@ -376,30 +416,15 @@ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - } - }, "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.0" - } + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "brace-expansion": { "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, "requires": { "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -416,60 +441,58 @@ "dev": true }, "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "optional": true, "requires": { "buffer-xor": "1.0.3", "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "optional": true, + "requires": { + "buffer-alloc-unsafe": "1.1.0", + "buffer-fill": "1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "optional": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "optional": true + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "optional": true }, - "caller-path": { - "version": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz" - } - }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" }, - "callsites": { - "version": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "has-ansi": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - } - }, "chownr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", @@ -479,46 +502,16 @@ "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "requires": { "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, - "circular-json": { - "version": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", - "dev": true - }, - "cli-cursor": { - "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz" - } - }, - "cli-width": { - "version": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, "code-point-at": { "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "requires": { - "delayed-stream": "1.0.0" - } - }, "commander": { "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", @@ -534,9 +527,9 @@ "optional": true }, "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, "component-inherit": { "version": "0.0.3", @@ -546,385 +539,181 @@ }, "concat-map": { "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "typedarray": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" - } + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, - "core-js": { - "version": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", - "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", - "dev": true + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "optional": true }, "core-util-is": { "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "1.0.4", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "ripemd160": "2.0.1", - "sha.js": "2.4.9" + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" } }, "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "optional": true, "requires": { "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "ripemd160": "2.0.1", + "ripemd160": "2.0.2", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "sha.js": "2.4.9" - } - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.0" - } - } + "sha.js": "2.4.11" } }, - "d": { - "version": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "requires": { - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "debug": { - "version": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "optional": true, "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "mimic-response": "1.0.0" } }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "optional": true }, - "deep-is": { - "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "del": { - "version": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "is-path-cwd": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "is-path-in-cwd": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "optional": true }, "diff": { "version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", "dev": true }, - "doctrine": { - "version": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true, - "requires": { - "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - } - }, "drbg.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "optional": true, "requires": { - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6" - } - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "requires": { - "readable-stream": "1.1.14" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, - "requires": { - "jsbn": "0.1.1" + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "create-hmac": "1.1.7" } }, "elliptic": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.2.tgz", - "integrity": "sha1-5MgeCCnPCmWrcOmYuCMnI7XBvEg=", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "requires": { - "bn.js": "4.11.6", + "bn.js": "4.11.8", "brorand": "1.1.0", "hash.js": "1.1.3", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + "hmac-drbg": "1.0.1", + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" } }, "engine.io": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.6.11.tgz", - "integrity": "sha1-JTOpemWHbED/z5U5e375tJXEI/4=", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "optional": true, "requires": { - "accepts": "1.1.4", - "base64id": "0.1.0", - "debug": "2.2.0", - "engine.io-parser": "1.2.4", - "ws": "1.1.0" + "accepts": "1.3.5", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "optional": true, "requires": { - "ms": "0.7.1" + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "optional": true } } }, "engine.io-client": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.6.11.tgz", - "integrity": "sha1-fSUNj6HCGBGezeUTkEWKV9UXE3Y=", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", + "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", "optional": true, "requires": { - "component-emitter": "1.1.2", + "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "2.2.0", - "engine.io-parser": "1.2.4", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", "has-cors": "1.1.0", "indexof": "0.0.1", - "parsejson": "0.0.1", - "parseqs": "0.0.2", - "parseuri": "0.0.4", - "ws": "1.0.1", - "xmlhttprequest-ssl": "1.5.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", "yeast": "0.1.2" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "optional": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "optional": true - }, - "ws": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz", - "integrity": "sha1-fQsqLljN3YGQOcKcneZQReGzEOk=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "optional": true, "requires": { - "options": "0.0.6", - "ultron": "1.0.2" + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" } } } }, "engine.io-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.2.4.tgz", - "integrity": "sha1-4Il7C/FOeS1M0qWVBVORnFaUjEI=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", "requires": { - "after": "0.8.1", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.2", + "after": "0.8.2", + "arraybuffer.slice": "0.0.7", + "base64-arraybuffer": "0.1.5", "blob": "0.0.4", - "has-binary": "0.1.6", - "utf8": "2.1.0" - }, - "dependencies": { - "after": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.1.tgz", - "integrity": "sha1-q11PuIP1loFtNRX495HAr0ht1ic=" - }, - "has-binary": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.6.tgz", - "integrity": "sha1-JTJvOc+k9hath4eJTjryz7x7bhA=", - "requires": { - "isarray": "0.0.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - } - } - }, - "es5-ext": { - "version": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", - "requires": { - "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" - } - }, - "es6-iterator": { - "version": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", - "requires": { - "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" - } - }, - "es6-map": { - "version": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "es6-set": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "event-emitter": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz" - } - }, - "es6-set": { - "version": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "event-emitter": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz" - } - }, - "es6-symbol": { - "version": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "requires": { - "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz" - } - }, - "es6-weak-map": { - "version": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "es6-iterator": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "es6-symbol": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz" + "has-binary2": "1.0.3" } }, "escape-string-regexp": { @@ -932,358 +721,1268 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "escope": { - "version": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "es6-weak-map": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "esrecurse": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" - } - }, "eslint": { - "version": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", "dev": true, "requires": { - "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "concat-stream": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "doctrine": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "escope": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "espree": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", - "esquery": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "file-entry-cache": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "globals": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "ignore": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "imurmurhash": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "inquirer": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "is-my-json-valid": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "is-resolvable": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "js-yaml": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", - "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "levn": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "natural-compare": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "optionator": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "path-is-inside": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "pluralize": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "progress": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "require-uncached": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "shelljs": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "strip-bom": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "table": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "text-table": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "user-home": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz" - } - }, - "eslint-plugin-flowtype": { - "version": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.35.1.tgz", - "integrity": "sha1-mtmBgbRno2RfvSqNQwOTzBek6mM=", - "dev": true, - "requires": { - "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" - } - }, - "espree": { - "version": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", - "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=", - "dev": true, - "requires": { - "acorn": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "acorn-jsx": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz" - } - }, - "esprima": { - "version": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", - "dev": true - }, - "esquery": { - "version": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" - } - }, - "esrecurse": { - "version": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "dev": true, - "requires": { - "estraverse": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - } - }, - "estraverse": { - "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "es5-ext": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", - "optional": true, - "requires": { - "md5.js": "1.3.4", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" - } - }, - "execspawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/execspawn/-/execspawn-1.0.1.tgz", - "integrity": "sha1-gob53efOzeeQX73ATiTzaPI/jaY=", - "optional": true, - "requires": { - "util-extend": "1.0.3" - } - }, - "exit-hook": { - "version": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "expand-template": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz", - "integrity": "sha1-4J77qXe/mPnuDtJavQxpLgKuw/w=", - "optional": true - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" - }, - "fast-future": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", - "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=", - "optional": true - }, - "fast-levenshtein": { - "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - } - }, - "file-entry-cache": { - "version": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - } - }, - "flat-cache": { - "version": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "dev": true, - "requires": { - "circular-json": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "del": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "write": "https://registry.npmjs.org/write/-/write-0.2.1.tgz" - } - }, - "flow-bin": { - "version": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", - "integrity": "sha1-AJ3Q9Xej9mXHTKi+gnrowt2P1rU=", - "dev": true - }, - "flow-remove-types": { - "version": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.1.tgz", - "integrity": "sha1-WOJhv4uEK9I0yGyvuYKhITr/Dts=", - "dev": true, - "requires": { - "babylon": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "vlq": "https://registry.npmjs.org/vlq/-/vlq-0.2.2.tgz" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "formatio": { - "version": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", - "dev": true, - "requires": { - "samsam": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz" - } - }, - "fs.realpath": { - "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz" - } - }, - "gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", - "requires": { - "ansi": "0.3.1", - "has-unicode": "2.0.1", - "lodash.pad": "4.5.1", - "lodash.padend": "4.6.1", - "lodash.padstart": "4.6.1" - } - }, - "generate-function": { - "version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "ghreleases": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/ghreleases/-/ghreleases-1.0.6.tgz", - "integrity": "sha512-uySVPT5T9uP1xeWR7nl3WD8/JjJJXAph/0zdgUQJ7ovFpL3rxBT/HT0sO6w0GDWCj2gwXvzxBKrIeJAgBhs+fw==", - "optional": true, - "requires": { - "after": "0.8.2", - "ghrepos": "2.0.0", - "ghutils": "3.2.1", - "simple-mime": "0.1.0", - "url-template": "2.0.8", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - } - }, - "ghrepos": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ghrepos/-/ghrepos-2.0.0.tgz", - "integrity": "sha1-1m6unZijtTmORg1tt+EKdCaS6Bs=", - "optional": true, - "requires": { - "ghutils": "3.2.1" - } - }, - "ghutils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ghutils/-/ghutils-3.2.1.tgz", - "integrity": "sha1-T87f+sk1/KzgbhKhfGF04sKf/k8=", - "requires": { - "jsonist": "1.3.0", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - } - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "optional": true - }, - "glob": { - "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", - "requires": { - "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.2", + "debug": "2.6.9", + "doctrine": "2.1.0", + "escope": "3.6.0", + "espree": "3.5.4", + "esquery": "1.0.1", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.8", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.17.2", + "is-resolvable": "1.1.0", + "js-yaml": "3.12.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.10", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.1.tgz", + "integrity": "sha512-XH4o5BK5jmw9PzSGK7mNf+/xV+mPxQxGZoeC36OVsJZYV77JAG9NnI7T90hoUpI/C1TOfXWTvugRdZ9ZR3iE2Q==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "1.1.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.45" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "next-tick": "1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.1", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "5.6.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "ignore": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", + "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.10", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-my-json-valid": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", + "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "1.0.1" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "1.0.10", + "esprima": "4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.7.1" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.10", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "eslint-plugin-flowtype": { + "version": "2.49.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.49.3.tgz", + "integrity": "sha512-wO0S4QbXPReKtydxbY5A0UieOaF9jBO5BMuxYPQOTa082JCpKEoC7+o3fnKsVVycwX47lvqLiUGRsWauCiA9aw==", + "dev": true, + "requires": { + "lodash": "4.17.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "optional": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, - "globals": { - "version": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", + "expand-template": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz", + "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==", + "optional": true + }, + "fast-future": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", + "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=", + "optional": true + }, + "flow-bin": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", + "integrity": "sha1-AJ3Q9Xej9mXHTKi+gnrowt2P1rU=", "dev": true }, - "globby": { - "version": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "flow-remove-types": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.3.tgz", + "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==", "dev": true, "requires": { - "array-union": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "arrify": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "babylon": "6.18.0", + "vlq": "0.2.3" + }, + "dependencies": { + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + } + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "optional": true + }, + "fs.realpath": { + "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + "signal-exit": "3.0.2", + "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "wide-align": "1.1.3" } }, - "graceful-fs": { - "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "optional": true }, "graceful-readlink": { "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", @@ -1291,7 +1990,8 @@ "dev": true }, "graph-theory-ford-fulkerson": { - "version": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", "integrity": "sha1-LDHSHXDxp9KCiZX+BnZFdv9/nik=" }, "growl": { @@ -1299,61 +1999,25 @@ "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "5.2.3", - "har-schema": "2.0.0" - }, - "dependencies": { - "ajv": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", - "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", - "requires": { - "co": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "fast-deep-equal": "1.0.0", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" - } - } - } - }, - "has-ansi": { - "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - } - }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "requires": { - "isarray": "0.0.1" + "isarray": "2.0.1" }, "dependencies": { "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" } } }, "has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "optional": true + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" }, "has-flag": { "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", @@ -1363,309 +2027,111 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true }, "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, "hash.js": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha1-NA3tvmKQGHFRweodd3o0SJNd+EY=", - "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "minimalistic-assert": "1.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.0.2" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "hyperquest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-1.2.0.tgz", - "integrity": "sha1-OeH+9miI3Hzg3sbA3YFPb8iUStU=", - "requires": { - "duplexer2": "0.0.2", - "through2": "0.6.5" - } - }, - "ignore": { - "version": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=", - "dev": true - }, - "imurmurhash": { - "version": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" - }, - "inflight": { - "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - } - }, - "inherits": { - "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", - "optional": true - }, - "inquirer": { - "version": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "cli-cursor": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "cli-width": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "figures": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "readline2": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "run-async": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "rx-lite": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "through": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - } - }, - "interpret": { - "version": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", - "dev": true - }, - "invariant": { - "version": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, - "requires": { - "loose-envify": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz" - } - }, - "is-fullwidth-code-point": { - "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" - } - }, - "is-my-json-valid": { - "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha1-WoRnd+LCYg0eaRBOXToDsfYIjxE=", - "dev": true, - "requires": { - "generate-function": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "generate-object-property": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "jsonpointer": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - } - }, - "is-path-cwd": { - "version": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz" - } - }, - "is-path-inside": { - "version": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "dev": true, - "requires": { - "path-is-inside": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" - } - }, - "is-property": { - "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-resolvable": { - "version": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true, + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "requires": { - "tryit": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz" + "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "minimalistic-assert": "1.0.1" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "js-yaml": { - "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", - "integrity": "sha1-CHdc69/dNZIJ8NKs04PI+GppBKA=", - "dev": true, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "argparse": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "esprima": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz" + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" }, - "json-stable-stringify": { - "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "inflight": { + "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { - "jsonify": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" } }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json3": { - "version": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "jsonify": { - "version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "optional": true }, - "jsonist": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsonist/-/jsonist-1.3.0.tgz", - "integrity": "sha1-wMdLle8clSA4YZsp76UgscyYdVY=", + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "bl": "1.0.3", - "hyperquest": "1.2.0", - "json-stringify-safe": "5.0.1", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" } }, - "jsonpointer": { - "version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", "dev": true }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "leveldown": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-1.5.0.tgz", - "integrity": "sha1-a408vqekqJqkdERgfXNYIT5vy4E=", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-1.7.2.tgz", + "integrity": "sha1-XjRnuyfuJGpKe429j7KxYgam64s=", "optional": true, "requires": { "abstract-leveldown": "2.6.3", "bindings": "1.2.1", "fast-future": "1.0.2", - "nan": "2.4.0", - "prebuild": "4.5.0" + "nan": "2.6.2", + "prebuild-install": "2.5.3" }, "dependencies": { + "bindings": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", + "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=", + "optional": true + }, "nan": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz", - "integrity": "sha1-+zxZ1F/k7/4hXwuJD4rfbrMtIjI=", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", "optional": true } } }, - "levn": { - "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "type-check": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" - } - }, - "lodash": { - "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, "lodash._baseassign": { "version": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", @@ -1725,77 +2191,50 @@ "lodash.isarray": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" } }, - "lodash.pad": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=" - }, - "lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=" - }, - "lodash.padstart": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" - }, - "lolex": { - "version": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", - "dev": true - }, - "loose-envify": { - "version": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, - "requires": { - "js-tokens": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" - } - }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "optional": true, "requires": { "hash-base": "3.0.4", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "optional": true, - "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" - } - } } }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "optional": true }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "optional": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "1.33.0" } }, - "minimalistic-assert": { + "mimic-response": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", + "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", + "optional": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, "requires": { "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz" } @@ -1819,25 +2258,37 @@ } }, "mocha": { - "version": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", - "integrity": "sha1-EyhWfScX+ZcDD4AGI0vOm4zXJGU=", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", "dev": true, "requires": { "browser-stdout": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", "commander": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "debug": "2.6.8", "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "glob": "7.1.1", "growl": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "json3": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "he": "1.1.1", + "json3": "3.3.2", "lodash.create": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz" + "supports-color": "3.1.2" }, "dependencies": { + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + } + }, "glob": { - "version": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", "dev": true, "requires": { @@ -1849,8 +2300,15 @@ "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" } }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, "supports-color": { - "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", "dev": true, "requires": { @@ -1863,80 +2321,36 @@ "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "mute-stream": { - "version": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true + "n64": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/n64/-/n64-0.0.18.tgz", + "integrity": "sha512-z5gRoCNFTY5fderO8n5tt6p7+jZiivzN1LhuR4EqrTkciYDCpJy8xkwkd1YO5eyfimeLAjXy/6k3FLC+GQ6lLw==" }, "nan": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz", - "integrity": "sha1-1bAWkSUzJql6K77p5hxV2NYDUeI=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", "optional": true }, - "native-promise-only": { - "version": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true - }, - "natural-compare": { - "version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, "negotiator": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", - "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=", - "optional": true - }, - "node-abi": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.1.tgz", - "integrity": "sha1-yc2iVuyKqZvKsvZEbbOK8UMziyo=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "optional": true }, - "node-gyp": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", - "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", - "optional": true, - "requires": { - "fstream": "1.0.11", - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "nopt": "3.0.6", - "npmlog": "2.0.4", - "osenv": "0.1.4", - "request": "2.83.0", - "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "semver": "5.3.0", - "tar": "2.2.1", - "which": "1.3.0" - } + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true }, - "node-ninja": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/node-ninja/-/node-ninja-1.0.2.tgz", - "integrity": "sha1-IKCeV7kuLfWRmT1L8JisPnJwYrY=", + "node-abi": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.1.tgz", + "integrity": "sha512-pUlswqpHQ7zGPI9lGjZ4XDNIEUDbHxsltfIRb7dTnYdhgHWHOcB0MLZKLoCz6UMcGzSPG5wGl1HODZVQAUsH6w==", "optional": true, "requires": { - "fstream": "1.0.11", - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "nopt": "3.0.6", - "npmlog": "2.0.4", - "osenv": "0.1.4", - "path-array": "1.0.1", - "request": "2.83.0", - "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "semver": "5.3.0", - "tar": "2.2.1", - "which": "1.3.0" + "semver": "5.5.0" } }, "noop-logger": { @@ -1945,36 +2359,26 @@ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", "optional": true }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1.1.1" - } - }, "npmlog": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", - "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, "requires": { - "ansi": "0.3.1", - "are-we-there-yet": "1.1.4", - "gauge": "1.2.7" + "are-we-there-yet": "1.1.5", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "number-is-nan": { "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" - }, "object-assign": { "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "optional": true }, "object-component": { "version": "0.0.3", @@ -1989,416 +2393,112 @@ "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" } }, - "onetime": { - "version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optionator": { - "version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "fast-levenshtein": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "levn": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "prelude-ls": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "type-check": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "wordwrap": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" - } - }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" - }, "os-homedir": { "version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "requires": { - "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "os-tmpdir": "1.0.2" - } - }, - "parsejson": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.1.tgz", - "integrity": "sha1-mxDGwNglq1ieaFFTgm3go7oni8w=", - "optional": true, - "requires": { - "better-assert": "1.0.2" - } + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "optional": true }, "parseqs": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.2.tgz", - "integrity": "sha1-nf5wss3aw4i95PNbHyQPpYrb5sc=", - "optional": true, + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "requires": { "better-assert": "1.0.2" } }, "parseuri": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.4.tgz", - "integrity": "sha1-gGWCo5iH4eoY3V4v4OAZAiaOk1A=", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "requires": { "better-assert": "1.0.2" } }, - "path-array": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.1.tgz", - "integrity": "sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE=", - "optional": true, - "requires": { - "array-index": "1.0.0" - } - }, "path-is-absolute": { "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-to-regexp": { - "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "dependencies": { - "isarray": { - "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "pinkie-promise": { - "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" - } - }, - "pluralize": { - "version": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "prebuild": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/prebuild/-/prebuild-4.5.0.tgz", - "integrity": "sha1-KqoN8gY7/4FKgDvU3JT/m2Tl3wA=", - "optional": true, - "requires": { - "async": "1.5.2", - "execspawn": "1.0.1", - "expand-template": "1.1.0", - "ghreleases": "1.0.6", - "github-from-package": "0.0.0", - "minimist": "1.2.0", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "node-gyp": "3.6.2", - "node-ninja": "1.0.2", - "noop-logger": "0.1.1", - "npmlog": "2.0.4", - "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "pump": "1.0.2", - "rc": "1.2.2", - "simple-get": "1.4.3", - "tar-fs": "1.16.0", - "tar-stream": "1.5.4", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - } - }, "prebuild-install": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.3.0.tgz", - "integrity": "sha512-gzjq2oHB8oMbzJSsSh9MQ64zrXZGt092/uT4TLZlz2qnrPxpWqp4vYB7LZrDxnlxf5RfbCjkgDI/z0EIVuYzAw==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.3.tgz", + "integrity": "sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g==", "optional": true, "requires": { - "expand-template": "1.1.0", + "detect-libc": "1.0.3", + "expand-template": "1.1.1", "github-from-package": "0.0.0", "minimist": "1.2.0", "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "node-abi": "2.1.1", + "node-abi": "2.4.1", "noop-logger": "0.1.1", "npmlog": "4.1.2", "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "pump": "1.0.2", - "rc": "1.2.2", - "simple-get": "1.4.3", - "tar-fs": "1.16.0", + "pump": "2.0.1", + "rc": "1.2.8", + "simple-get": "2.8.1", + "tar-fs": "1.16.2", "tunnel-agent": "0.6.0", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - }, - "dependencies": { - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "optional": true, - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "signal-exit": "3.0.2", - "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "wide-align": "1.1.2" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - } + "which-pm-runs": "1.0.0" } }, - "prelude-ls": { - "version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "progress": { - "version": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, "pump": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", - "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "optional": true, "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" } }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - }, "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", + "deep-extend": "0.6.0", + "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" } }, - "readable-stream": { - "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", - "requires": { - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - }, - "readline2": { - "version": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "mute-stream": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" - } - }, - "rechoir": { - "version": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz" - } - }, - "regenerator-runtime": { - "version": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", - "integrity": "sha1-flT+W1zNXWYk6mJVw0c74JC4AuE=", - "dev": true - }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "require-uncached": { - "version": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "resolve-from": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz" - } - }, - "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha1-p1vgHFPaJdk0qY69DkxKcxL5KoY=", - "dev": true, - "requires": { - "path-parse": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz" - } - }, - "resolve-from": { - "version": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "onetime": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz" - } - }, - "rimraf": { - "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "requires": { - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz" - } - }, "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "requires": { - "hash-base": "2.0.2", + "hash-base": "3.0.4", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - } - }, - "run-async": { - "version": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - } - }, - "rx-lite": { - "version": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true + } }, "safe-buffer": { "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" }, - "samsam": { - "version": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", - "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=", - "dev": true - }, "secp256k1": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.2.5.tgz", - "integrity": "sha1-Dd5bJ+UCFmX23/ynssPgEMbBPJM=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.3.0.tgz", + "integrity": "sha512-CbrQoeGG5V0kQ1ohEMGI+J7oKerapLTpivLICBaXR0R4HyQcN3kM9itLsV5fdpV1UR1bD14tOkJ1xughmlDIiQ==", "optional": true, "requires": { - "bindings": "1.2.1", + "bindings": "1.3.0", "bip66": "1.1.5", - "bn.js": "4.11.6", - "create-hash": "1.1.3", + "bn.js": "4.11.8", + "create-hash": "1.2.0", "drbg.js": "1.0.1", - "elliptic": "6.3.2", - "nan": "2.5.1", - "prebuild-install": "2.3.0" + "elliptic": "6.4.0", + "nan": "2.10.0", + "prebuild-install": "2.5.3", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "optional": true }, "set-blocking": { "version": "2.0.0", @@ -2407,324 +2507,271 @@ "optional": true }, "sha.js": { - "version": "2.4.9", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", - "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, - "shelljs": { - "version": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "interpret": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "rechoir": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" - } - }, "should": { - "version": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", "integrity": "sha1-kPVRRVUtAc/CAGZuToGKHJZw7aI=", "dev": true, "requires": { - "should-equal": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", - "should-format": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "should-type-adaptors": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz", - "should-util": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz" - } - }, - "should-equal": { - "version": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", - "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", - "dev": true, - "requires": { - "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz" - } - }, - "should-format": { - "version": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", - "dev": true, - "requires": { - "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "should-type-adaptors": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz" + "should-equal": "1.0.1", + "should-format": "3.0.3", + "should-type": "1.4.0", + "should-type-adaptors": "1.1.0", + "should-util": "1.0.0" + }, + "dependencies": { + "should-equal": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", + "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", + "dev": true, + "requires": { + "should-type": "1.4.0" + } + }, + "should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "dev": true, + "requires": { + "should-type": "1.4.0", + "should-type-adaptors": "1.1.0" + } + }, + "should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "dev": true + }, + "should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "requires": { + "should-type": "1.4.0", + "should-util": "1.0.0" + } + }, + "should-util": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", + "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", + "dev": true + } } }, "should-sinon": { - "version": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.5.tgz", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.5.tgz", "integrity": "sha1-/8ioUb9FB2fn0K0i/4cVZQvpUOQ=", "dev": true }, - "should-type": { - "version": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", - "dev": true - }, - "should-type-adaptors": { - "version": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz", - "integrity": "sha1-7+VVPN9oz/ZuXF9RtxLcNRx3vqo=", - "dev": true, - "requires": { - "should-type": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "should-util": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz" - } - }, - "should-util": { - "version": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", - "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", - "dev": true - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "optional": true }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "optional": true + }, "simple-get": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz", - "integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", "optional": true, "requires": { + "decompress-response": "3.3.0", "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "unzip-response": "1.0.2", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + "simple-concat": "1.0.0" } }, - "simple-mime": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/simple-mime/-/simple-mime-0.1.0.tgz", - "integrity": "sha1-lfUXxPRm18/1YacfydqyWW6p7y4=", - "optional": true - }, "sinon": { - "version": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", - "integrity": "sha1-Ah/WS1TLd9nS+w1Dze3652KcOjY=", - "dev": true, - "requires": { - "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "formatio": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "lolex": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "native-promise-only": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "path-to-regexp": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "samsam": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", - "text-encoding": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "type-detect": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz" - } - }, - "slice-ansi": { - "version": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "sntp": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", - "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", - "requires": { - "hoek": "4.2.0" - } - }, - "socket.io": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.4.8.tgz", - "integrity": "sha1-5XbzMM0L7WTlWz/SbfmRFBiEhns=", - "optional": true, - "requires": { - "debug": "2.2.0", - "engine.io": "1.6.11", - "has-binary": "0.1.7", - "socket.io-adapter": "0.4.0", - "socket.io-client": "1.4.8", - "socket.io-parser": "2.2.6" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", + "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", + "dev": true, + "requires": { + "diff": "3.5.0", + "formatio": "1.2.0", + "lolex": "1.6.0", + "native-promise-only": "0.8.1", + "path-to-regexp": "1.7.0", + "samsam": "1.3.0", + "text-encoding": "0.6.4", + "type-detect": "4.0.8" }, "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "optional": true, - "requires": { - "ms": "0.7.1" - } + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "optional": true - } - } - }, - "socket.io-adapter": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.4.0.tgz", - "integrity": "sha1-+5+CqxqmUpC/csNleVW5MKmRok8=", - "optional": true, - "requires": { - "debug": "2.2.0", - "socket.io-parser": "2.2.2" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "optional": true, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, "requires": { - "ms": "0.7.1" + "samsam": "1.3.0" } }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "optional": true + "dev": true }, - "json3": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.2.6.tgz", - "integrity": "sha1-9u/JPAagTemuxTBT3yVZuxniA4s=", - "optional": true + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "optional": true + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true }, - "socket.io-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.2.tgz", - "integrity": "sha1-PXr2tkSX6Va32f53X5mXFgJ/lBc=", + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } + } + }, + "socket.io": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.3.tgz", + "integrity": "sha1-Q1nwaiSTOua9CHeYr3jGgOrjReM=", + "optional": true, + "requires": { + "debug": "2.6.9", + "engine.io": "3.1.5", + "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.0.3", + "socket.io-parser": "3.1.3" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "optional": true, "requires": { - "benchmark": "1.0.0", - "component-emitter": "1.1.2", - "debug": "0.7.4", - "isarray": "0.0.1", - "json3": "3.2.6" - }, - "dependencies": { - "debug": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", - "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", - "optional": true - } + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" } } } }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "optional": true + }, "socket.io-client": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.4.8.tgz", - "integrity": "sha1-SBskHnPfFA6hpPsDSGqFrQl/VVg=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.3.tgz", + "integrity": "sha1-bK9K/5+FsZ/ZG2zhPWmttWT4hzs=", "optional": true, "requires": { "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", - "component-emitter": "1.2.0", - "debug": "2.2.0", - "engine.io-client": "1.6.11", - "has-binary": "0.1.7", + "component-emitter": "1.2.1", + "debug": "2.6.9", + "engine.io-client": "3.1.6", + "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", - "parseuri": "0.0.4", - "socket.io-parser": "2.2.6", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "3.1.3", "to-array": "0.1.4" }, "dependencies": { - "component-emitter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.0.tgz", - "integrity": "sha1-zNETqGOI0GSC0D3j/H35hSa6jv4=", - "optional": true - }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "optional": true, "requires": { - "ms": "0.7.1" + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "optional": true } } }, "socket.io-parser": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.2.6.tgz", - "integrity": "sha1-ON/WHfUNz4qx2eIJEyK/kCuii5k=", - "requires": { - "benchmark": "1.0.0", - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "requires": { + "component-emitter": "1.2.1", + "debug": "3.1.0", + "has-binary2": "1.0.3", + "isarray": "2.0.1" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "ms": "0.7.1" + "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" } }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" } } }, "sorted-set": { - "version": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", "integrity": "sha1-POAVeFtkdPH6A6HGn/8ymFL8N+M=" }, - "sprintf-js": { - "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - } - }, - "string_decoder": { - "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", - "requires": { - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" - } - }, "string-width": { "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", @@ -2734,11 +2781,6 @@ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" } }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" - }, "strip-ansi": { "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", @@ -2746,139 +2788,79 @@ "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" } }, - "strip-bom": { - "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-json-comments": { "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "optional": true }, - "table": { - "version": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, + "tar-fs": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz", + "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==", + "optional": true, "requires": { - "ajv": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "ajv-keywords": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "slice-ansi": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "string-width": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + "chownr": "1.0.1", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "pump": "1.0.3", + "tar-stream": "1.6.1" }, "dependencies": { - "ansi-regex": { - "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", - "dev": true, - "requires": { - "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" - } - }, - "strip-ansi": { - "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "optional": true, "requires": { - "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz" + "end-of-stream": "1.4.1", + "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" } } } }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - } - }, - "tar-fs": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz", - "integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==", - "optional": true, - "requires": { - "chownr": "1.0.1", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "pump": "1.0.2", - "tar-stream": "1.5.4" - } - }, "tar-stream": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", - "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", - "requires": { - "bl": "1.0.3", - "end-of-stream": "1.4.0", - "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - } - }, - "text-encoding": { - "version": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true - }, - "text-table": { - "version": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", + "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "optional": true, "requires": { - "readable-stream": "1.0.34", + "bl": "1.2.2", + "buffer-alloc": "1.2.0", + "end-of-stream": "1.4.1", + "fs-constants": "1.0.0", + "readable-stream": "2.3.6", + "to-buffer": "1.1.1", "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "optional": true }, "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, "requires": { "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "0.0.1", - "string_decoder": "0.10.31" + "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "process-nextick-args": "2.0.0", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "string_decoder": "1.1.1", + "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } }, "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + } } } }, @@ -2888,164 +2870,69 @@ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", "optional": true }, - "to-fast-properties": { - "version": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "requires": { - "punycode": "1.4.1" - } - }, - "tryit": { - "version": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "optional": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, "requires": { "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true - }, - "type-check": { - "version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" - } - }, - "type-detect": { - "version": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", - "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", - "dev": true - }, - "typedarray": { - "version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "optional": true - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", - "optional": true - }, - "user-home": { - "version": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" - } - }, - "utf8": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.0.tgz", - "integrity": "sha1-DP7FyAUtRKI+OqqQgQToB1+V39U=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "util-deprecate": { "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "util-extend": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", - "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", + "uws": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", "optional": true }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "extsprintf": "1.3.0" - } - }, - "vlq": { - "version": "https://registry.npmjs.org/vlq/-/vlq-0.2.2.tgz", - "integrity": "sha1-4xbVJXtAuGu0PLjV/qXX9U1rDKE=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "requires": { - "isexe": "2.0.0" - } + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "optional": true }, "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "optional": true, "requires": { "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" } }, - "wordwrap": { - "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, "wrappy": { "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "write": { - "version": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" - } - }, "ws": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.0.tgz", - "integrity": "sha1-wdb9FRXTzv8fCuJ1m/X9dwMKrR0=", - "optional": true, + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "requires": { - "options": "0.0.6", - "ultron": "1.0.2" + "async-limiter": "1.0.0", + "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "ultron": "1.1.1" } }, "xmlhttprequest-ssl": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.1.tgz", - "integrity": "sha1-O3dB/qSoZnWXbpCNKW1ERZYfqmc=", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", "optional": true }, "xtend": { From f6528bb69cd38cb98ad6152126038308c54ea651 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 8 Jun 2018 23:29:47 +0100 Subject: [PATCH 447/540] Update to latest sinon version --- package-lock.json | 163 ++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 101 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98746b0..8d63434 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,15 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, "abstract-leveldown": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", @@ -2105,6 +2114,12 @@ "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "just-extend": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "dev": true + }, "leveldown": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-1.7.2.tgz", @@ -2171,6 +2186,12 @@ "lodash._isiterateecall": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" } }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.isarguments": { "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", @@ -2191,6 +2212,12 @@ "lodash.isarray": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" } }, + "lolex": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.0.tgz", + "integrity": "sha512-uJkH2e0BVfU5KOJUevbTOtpDduooSarH5PopO+LfM/vZf8Z9sJzODqKev804JYM2i++ktJfUmC1le4LwFQ1VMg==", + "dev": true + }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", @@ -2344,6 +2371,19 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, + "nise": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.1.tgz", + "integrity": "sha512-9JX3YwoIt3kS237scmSSOpEv7vCukVzLfwK0I0XhocDSHUANid8ZHnLEULbbSkfeMn98B2y5kphIWzZUylESRQ==", + "dev": true, + "requires": { + "@sinonjs/formatio": "2.0.0", + "just-extend": "1.1.27", + "lolex": "2.7.0", + "path-to-regexp": "1.7.0", + "text-encoding": "0.6.4" + } + }, "node-abi": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.1.tgz", @@ -2419,6 +2459,23 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, "prebuild-install": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.3.tgz", @@ -2477,6 +2534,12 @@ "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, "secp256k1": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.3.0.tgz", @@ -2601,18 +2664,17 @@ } }, "sinon": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", - "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", + "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", "dev": true, "requires": { + "@sinonjs/formatio": "2.0.0", "diff": "3.5.0", - "formatio": "1.2.0", - "lolex": "1.6.0", - "native-promise-only": "0.8.1", - "path-to-regexp": "1.7.0", - "samsam": "1.3.0", - "text-encoding": "0.6.4", + "lodash.get": "4.4.2", + "lolex": "2.7.0", + "nise": "1.4.1", + "supports-color": "5.4.0", "type-detect": "4.0.8" }, "dependencies": { @@ -2621,60 +2683,6 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true - }, - "formatio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "lolex": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", - "dev": true - }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true } } }, @@ -2793,6 +2801,23 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "optional": true }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + } + } + }, "tar-fs": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz", @@ -2864,6 +2889,12 @@ } } }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", @@ -2885,6 +2916,12 @@ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", diff --git a/package.json b/package.json index a5e335b..9ea8ab9 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "mocha": "^3.4.2", "should": "^11.2.1", "should-sinon": "0.0.5", - "sinon": "^2.2.0" + "sinon": "^5.1.1" }, "dependencies": { "bcoin": "^1.0.0-beta.15", From 6ef35c535a9413820924f1b2e1d234276f817ca4 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 8 Jun 2018 23:31:37 +0100 Subject: [PATCH 448/540] Add circulateCoins() for deduplication --- test/helpers.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index 93fe8e7..b6cf148 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -4,6 +4,7 @@ var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); var fixtures = require("./fixtures"); var assert = require("assert"); +const consensus = require("bcoin/lib/protocol/consensus"); var testHelpers = { createWallet: async (walletDB, id) => { @@ -25,6 +26,20 @@ var testHelpers = { return node.getBlock(node.chain.tip.hash); }, + circulateCoins: async (fromWallet, fromWatcher, + toWallet, toWatcher, coins) => { + const tx = await fromWallet.send({ + outputs: [{ + value: coins * consensus.COIN, + address: toWallet.getAddress("base58") + }] + }); + await fromWatcher.waitForTX(tx, fromWallet); + await toWatcher.waitForTX(tx, toWallet); + await testHelpers.flushEvents(); + return tx; + }, + delay: async (milliseconds) => { return new Promise((resolve, reject) => { setTimeout(resolve, milliseconds); From f480c8351c45c688c8a8151bbcf17128c71f53cf Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 8 Jun 2018 23:33:02 +0100 Subject: [PATCH 449/540] Use circulateCoins() for miner to miner --- test/spv_node.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 5bdab88..9d0a18e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -137,16 +137,8 @@ describe("SPVNode", () => { consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - var miner2TX = await minerWallet1.send({ - outputs: [{ - value: 10 * COIN, - address: minerWallet2.getAddress("base58") - }] - }); - await minerWatcher.waitForTX(miner2TX, minerWallet1); - await minerWatcher.waitForTX(miner2TX, minerWallet2); - await spvWatcher.waitForTX(miner2TX); - await testHelpers.flushEvents(); + var miner2TX = await testHelpers.circulateCoins(minerWallet1, + minerWatcher, minerWallet2, minerWatcher, 10); Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); From fa7466560b9354fe00949729eda77f75fa13ddef Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 8 Jun 2018 23:33:28 +0100 Subject: [PATCH 450/540] Use {before,after}Each for addTX() spy Change from simple before, after --- test/spv_node.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 9d0a18e..2e3c027 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -28,12 +28,8 @@ describe("SPVNode", () => { var spvWatcher = null; var minerWatcher = null; - before("set up addTX() spy", function() { - sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); - }); - - after("reset addTX() spy", function() { - Trust.TrustIsRisk.prototype.addTX.restore(); + beforeEach("set up addTX() spy", () => { + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); }); beforeEach("connect SPV node and wallet", async () => { @@ -81,6 +77,10 @@ describe("SPVNode", () => { await miner.tearDown(); }); + afterEach("remove addTX() spy", () => { + Trust.TrustIsRisk.addTX.restore(); + }); + it("should match a TIR transaction with the spv bloom filter", async function() { var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); var privateKey1 = (await wallet1.getPrivateKey( From 30367a6a5846d7ed543362dda9e09d97f403fcff Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Fri, 8 Jun 2018 23:35:02 +0100 Subject: [PATCH 451/540] Check call count of miner's addTX(), not prototype --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 2e3c027..e13d0f4 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -140,7 +140,7 @@ describe("SPVNode", () => { var miner2TX = await testHelpers.circulateCoins(minerWallet1, minerWatcher, minerWallet2, minerWatcher, 10); - Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); + miner.trust.addTX.should.have.been.calledOnce(); var minerSpvTX = await minerWallet2.send({ outputs: [{ From 867e79164b6380f2627a4974a939fbd727ea06f0 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Jun 2018 15:35:27 +0100 Subject: [PATCH 452/540] Add sinon spy minimal testcase --- minimal_testcases/spy.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 minimal_testcases/spy.js diff --git a/minimal_testcases/spy.js b/minimal_testcases/spy.js new file mode 100644 index 0000000..6c6fb4b --- /dev/null +++ b/minimal_testcases/spy.js @@ -0,0 +1,18 @@ +const sinon = require("sinon"); + +class MyClass { + constructor() { + } + + func() { + return; + } +}; + +const obj = new MyClass(); + +sinon.spy(obj, "func"); + +obj.func() + +console.log(obj.func.calledOnce) From 4b4760ce143df0ecfa0cbd91f5cac34b79fcfb06 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Jun 2018 15:37:15 +0100 Subject: [PATCH 453/540] Add spv tx circulation minimal testcase --- minimal_testcases/spv_tx_circulation.js | 93 +++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 minimal_testcases/spv_tx_circulation.js diff --git a/minimal_testcases/spv_tx_circulation.js b/minimal_testcases/spv_tx_circulation.js new file mode 100644 index 0000000..3aaa486 --- /dev/null +++ b/minimal_testcases/spv_tx_circulation.js @@ -0,0 +1,93 @@ +const Trust = require("../"); +const bcoin = require("bcoin").set("regtest"); +const consensus = require("bcoin/lib/protocol/consensus"); +const testHelpers = require("../test/helpers"); +const sinon = require("sinon"); +const should = require("should"); +require("should-sinon"); + +const COIN = consensus.COIN; + +(async () => { + sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); + + const spvnode = new Trust.SPVNode({ + network: bcoin.network.get().toString(), + httpPort: 48445, + passphrase: "secret", + // logConsole: true, + // logLevel: "debug", + nodes: ["127.0.0.1:48448"] + }); + + await spvnode.initialize(); + const spvWalletDB = spvnode.require("walletdb"); + + const fullnode = new Trust.FullNode({ + network: bcoin.network.get().toString(), + httpPort: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + + await fullnode.initialize(); + const fullWalletDB = fullnode.require("walletdb"); + + fullnode.startSync(); + spvnode.startSync(); + + const fullWatcher = new testHelpers.NodeWatcher(fullnode); + const spvWatcher = new testHelpers.NodeWatcher(spvnode); + + const spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); + const spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); + + const fullWallet1 = await testHelpers.createWallet(fullWalletDB, "fullWallet1"); + const fullWallet2 = await testHelpers.createWallet(fullWalletDB, "fullWallet2"); + + await testHelpers.delay(1000); + // Produce a block and reward the fullWallet1, so that we have a coin to spend. + await testHelpers.mineBlock(fullnode, fullWallet1.getAddress("base58")); + + // Make the coin spendable. + consensus.COINBASE_MATURITY = 0; + await testHelpers.delay(100); + + var full2TX = await fullWallet1.send({ + outputs: [{ + value: 10 * COIN, + address: fullWallet2.getAddress("base58") + }] + }); + await fullWatcher.waitForTX(full2TX, fullWallet1); + await fullWatcher.waitForTX(full2TX, fullWallet2); + await spvWatcher.waitForTX(full2TX); + await testHelpers.flushEvents(); + + Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); + + var fullSpvTX = await fullWallet2.send({ + outputs: [{ + value: 9 * COIN, + address: spvWallet1.getAddress("base58") + }] + }); + + await fullWatcher.waitForTX(fullSpvTX, fullWallet2); + console.log("aaa"); + await spvWatcher.waitForTX(fullSpvTX); + await testHelpers.flushEvents(); + + Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(4); + + spvnode.stopSync(); + fullnode.stopSync(); + + await spvnode.tearDown(); + await fullnode.tearDown(); + + Trust.TrustIsRisk.prototype.addTX.restore(); + + console.log("success!"); +})(); From b67e0ddabffd4df39e479afc6eed13a6e1a3303a Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 10 Jun 2018 15:38:32 +0100 Subject: [PATCH 454/540] Add multisig/p2pkh tx to wallet minimal testcase --- minimal_testcases/msigwallet/helpers.js | 126 +++++++++++++++++++++ minimal_testcases/msigwallet/msigwallet.js | 74 ++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 minimal_testcases/msigwallet/helpers.js create mode 100644 minimal_testcases/msigwallet/msigwallet.js diff --git a/minimal_testcases/msigwallet/helpers.js b/minimal_testcases/msigwallet/helpers.js new file mode 100644 index 0000000..1a5acb9 --- /dev/null +++ b/minimal_testcases/msigwallet/helpers.js @@ -0,0 +1,126 @@ +var WalletDB = require("bcoin/lib/wallet/walletdb"); +var bcoin = require("bcoin"); +var assert = require("assert"); + +var testHelpers = { + createWallet: async (walletDB, id) => { + var options = { + id, + passphrase: "secret", + witness: false, + type: "pubkeyhash" + }; + + return walletDB.create(options); + }, + + mineBlock: async (node, rewardAddress) => { + var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); + await node.chain.add(block); + // node.chain.tip does not contain all the properties we want, + // so we need to fetch it: + return node.getBlock(node.chain.tip.hash); + }, + + delay: async (milliseconds) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, milliseconds); + }); + } +}; + +class NodeWatcher { + constructor(node) { + this.txCount = 0; + this.blockCount = 0; + this.node = node; + this.node.on("tx", this.onTX.bind(this)); + this.node.on("block", this.onBlock.bind(this)); + } + + onTX() { + this.txCount++; + } + + onBlock() { + this.blockCount++; + } + + async waitForBlock(initialCount) { + if (initialCount === undefined) initialCount = this.blockCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.blockCount > initialCount) resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + } + + async waitForTX(input, wallet) { + if (wallet) { + while (true) { + if (await wallet.getTX(input.hash("hex"))) + break; + await testHelpers.delay(100); + } + } + var initialCount = null; + switch (typeof input) { + case "number": + initialCount = input; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "undefined": // TODO: reuse code + initialCount = this.txCount; + await new Promise((resolve, reject) => { + var check = (() => { + if (this.txCount > initialCount) + resolve(); + else setTimeout(check, 100); + }).bind(this); + + check(); + }); + break; + + case "object": + var tx = input; + await new Promise((resolve, reject) => { + var check = (() => { + // This breaks node.pool.on("tx", ...) + if (this.node.spv) { + if (this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) + resolve(); + else setTimeout(check, 100); + } + else { // this is not an SPV node + if (this.node.pool.hasTX(tx.hash().toString("hex"))) + resolve(); + else setTimeout(check, 100); + } + }).bind(this); + + check(); + }); + break; + + default: + throw new Error("input cannot be " + typeof input); // TODO: throw correct error + } + } +} + +testHelpers.NodeWatcher = NodeWatcher; + +module.exports = testHelpers; diff --git a/minimal_testcases/msigwallet/msigwallet.js b/minimal_testcases/msigwallet/msigwallet.js new file mode 100644 index 0000000..d3a6aff --- /dev/null +++ b/minimal_testcases/msigwallet/msigwallet.js @@ -0,0 +1,74 @@ +const bcoin = require("bcoin").set("regtest"); +const consensus = require("bcoin/lib/protocol/consensus"); +const helpers = require("./helpers"); + +(async () => { + const node = new bcoin.fullnode({ + network: bcoin.network.get().toString(), + passphrase: "secret" + }); + node.use(bcoin.wallet.plugin); + await node.open(); + await node.connect(); + node.startSync(); + + const walletDB = node.require("walletdb"); + + const alice = await walletDB.create(); // make type multisig + const bob = await walletDB.create(); + + await helpers.mineBlock(node, alice.getAddress()); + consensus.COINBASE_MATURITY = 0; + await helpers.delay(100); + + const p2pkh = await alice.send({ + outputs: [{ + address: bob.getAddress(), + value: 10 * consensus.COIN + }] + }); + console.log("does alice contain p2pkh?", + (await alice.getTX(p2pkh.hash("hex"))) ? true : false); + console.log("does bob contain p2pkh?", + (await bob.getTX(p2pkh.hash("hex"))) ? true : false); + + const multisigScript = bcoin.script.fromMultisig(1, 2, + [(await alice.getKey(alice.getAddress())).publicKey, + (await bob.getKey(bob.getAddress())).publicKey]); + + const p2pkhScript = bcoin.script.fromPubkeyhash( + bcoin.crypto.hash160( + (await alice.getKey(alice.getAddress())).publicKey)); + + const msig = new bcoin.primitives.MTX({ + outputs: [ + new bcoin.primitives.Output({ + script: multisigScript, + value: 10 * consensus.COIN + }), + new bcoin.primitives.Output({ + script: p2pkhScript, + value: (await alice.getBalance()) - 10 * consensus.COIN + }) + ], + inputs: [ + new bcoin.primitives.Input({ + prevout: new bcoin.primitives.Outpoint({ + hash: // find coinbase tx + index: 0 + }) + }) + ] + }); + + assert(msig.verify()); + const smsig = msig.toTX(); + node.sendTX(smsig); + + console.log("does alice contain multisig?", + (await alice.getTX(smsig.hash("hex"))) ? true : false); + console.log("does bob contain multisig?", + (await bob.getTX(smsig.hash("hex"))) ? true : false); + + node.close(); +})(); From ea4ebc3a4f264838044fcc670c1ca85977a87e24 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Jun 2018 22:58:41 +0300 Subject: [PATCH 455/540] Simplify tx circulation minimal testcase Use bcoin nodes instead of TIR nodes --- minimal_testcases/spv_tx_circulation.js | 83 +++++++++---------------- 1 file changed, 31 insertions(+), 52 deletions(-) diff --git a/minimal_testcases/spv_tx_circulation.js b/minimal_testcases/spv_tx_circulation.js index 3aaa486..ea3da20 100644 --- a/minimal_testcases/spv_tx_circulation.js +++ b/minimal_testcases/spv_tx_circulation.js @@ -1,17 +1,10 @@ -const Trust = require("../"); const bcoin = require("bcoin").set("regtest"); const consensus = require("bcoin/lib/protocol/consensus"); +const walletPlugin = bcoin.wallet.plugin; const testHelpers = require("../test/helpers"); -const sinon = require("sinon"); -const should = require("should"); -require("should-sinon"); - -const COIN = consensus.COIN; (async () => { - sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); - - const spvnode = new Trust.SPVNode({ + const spvNode = new bcoin.spvnode({ network: bcoin.network.get().toString(), httpPort: 48445, passphrase: "secret", @@ -20,10 +13,12 @@ const COIN = consensus.COIN; nodes: ["127.0.0.1:48448"] }); - await spvnode.initialize(); - const spvWalletDB = spvnode.require("walletdb"); + spvNode.use(walletPlugin); + await spvNode.open(); + await spvNode.connect(); + const spvWalletDB = spvNode.require("walletdb"); - const fullnode = new Trust.FullNode({ + const fullNode = new bcoin.fullnode({ network: bcoin.network.get().toString(), httpPort: 48448, bip37: true, @@ -31,63 +26,47 @@ const COIN = consensus.COIN; passphrase: "secret" }); - await fullnode.initialize(); - const fullWalletDB = fullnode.require("walletdb"); - - fullnode.startSync(); - spvnode.startSync(); + fullNode.use(walletPlugin); + await fullNode.open(); + await fullNode.connect(); + const fullWalletDB = fullNode.require("walletdb"); - const fullWatcher = new testHelpers.NodeWatcher(fullnode); - const spvWatcher = new testHelpers.NodeWatcher(spvnode); + fullNode.startSync(); + spvNode.startSync(); - const spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); - const spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); + const fullWatcher = new testHelpers.NodeWatcher(fullNode); + const spvWatcher = new testHelpers.NodeWatcher(spvNode); - const fullWallet1 = await testHelpers.createWallet(fullWalletDB, "fullWallet1"); - const fullWallet2 = await testHelpers.createWallet(fullWalletDB, "fullWallet2"); + const spvWallet = await testHelpers.createWallet(spvWalletDB, "spvWallet"); + const fullWallet = await testHelpers.createWallet(fullWalletDB, "fullWallet"); + const fullWalle = await testHelpers.createWallet(fullWalletDB, "fullWalle"); await testHelpers.delay(1000); // Produce a block and reward the fullWallet1, so that we have a coin to spend. - await testHelpers.mineBlock(fullnode, fullWallet1.getAddress("base58")); + await testHelpers.mineBlock(fullNode, fullWallet.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - var full2TX = await fullWallet1.send({ - outputs: [{ - value: 10 * COIN, - address: fullWallet2.getAddress("base58") - }] - }); - await fullWatcher.waitForTX(full2TX, fullWallet1); - await fullWatcher.waitForTX(full2TX, fullWallet2); - await spvWatcher.waitForTX(full2TX); - await testHelpers.flushEvents(); - - Trust.TrustIsRisk.prototype.addTX.should.have.been.calledTwice(); - - var fullSpvTX = await fullWallet2.send({ + var tx = await fullWallet.send({ outputs: [{ - value: 9 * COIN, - address: spvWallet1.getAddress("base58") + value: 10 * consensus.COIN, + address: fullWalle.getAddress("base58") }] }); - - await fullWatcher.waitForTX(fullSpvTX, fullWallet2); - console.log("aaa"); - await spvWatcher.waitForTX(fullSpvTX); + await fullWatcher.waitForTX(tx, fullWallet); + await fullWatcher.waitForTX(tx, fullWalle); + //await spvWatcher.waitForTX(tx, spvWallet); await testHelpers.flushEvents(); - Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(4); - - spvnode.stopSync(); - fullnode.stopSync(); - - await spvnode.tearDown(); - await fullnode.tearDown(); + spvNode.stopSync(); + fullNode.stopSync(); - Trust.TrustIsRisk.prototype.addTX.restore(); + await spvNode.disconnect(); + await fullNode.disconnect(); + await spvNode.close(); + await fullNode.close(); console.log("success!"); })(); From ca2c4bc0ee74e262aca07b0f33dfcb547e31d3db Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Jun 2018 22:59:58 +0300 Subject: [PATCH 456/540] Complete spy minimal testcase --- minimal_testcases/spy.js | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/minimal_testcases/spy.js b/minimal_testcases/spy.js index 6c6fb4b..0fcb464 100644 --- a/minimal_testcases/spy.js +++ b/minimal_testcases/spy.js @@ -1,18 +1,33 @@ -const sinon = require("sinon"); +async function delay(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }) +}; -class MyClass { - constructor() { - } +(async () => { + const sinon = require("sinon"); + const EventEmitter = require("events"); - func() { - return; - } -}; + class MyClass { + constructor() { + EventEmitter.call(this); + this.dummy = (() => {console.log("dummy was called")}).bind(this); + } + + func() { + console.log("I have indeed been called!"); + } + }; -const obj = new MyClass(); + Object.setPrototypeOf(MyClass.prototype, EventEmitter.prototype); -sinon.spy(obj, "func"); + const obj = new MyClass(); + sinon.spy(obj, "dummy"); + obj.on("tx", obj.dummy); -obj.func() + obj.emit("tx"); + //obj.func.call(null); // weird -console.log(obj.func.calledOnce) + console.log((obj.dummy.calledOnce) ? + "And the spy knows!" : "But the spy is ignorant..."); +})(); From f83958d5950dfcf8d3977f7641af025a6962ffd5 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 26 Jun 2018 23:01:04 +0300 Subject: [PATCH 457/540] Register addTX() on tx event separately The event is now registered through a separate initialize() function and not in the TIR constructor for improved testability. --- src/full_node.js | 1 + src/spv_node.js | 1 + src/trust_is_risk.js | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/full_node.js b/src/full_node.js index de38236..cd5d135 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -13,6 +13,7 @@ class FullNode extends bcoin.fullnode { } async initialize() { + await this.trust.initialize(); await this.open(); await this.connect(); } diff --git a/src/spv_node.js b/src/spv_node.js index efdb690..d543a44 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -14,6 +14,7 @@ class SPVNode extends bcoin.spvnode { } async initialize() { + await this.trust.initialize(); await this.open(); await this.connect(); this.pool.spvFilter.add(tag); diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 5f333e6..14dbc69 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -24,7 +24,9 @@ class TrustIsRisk { constructor(node : (bcoin$FullNode | bcoin$SPVNode)) { this.node = node; this.db = new TrustDB(); + } + async initialize() { this.node.on("tx", this.addTX.bind(this)); } From 8babcab60a8fff883ebe28cdf1ee07b4133577f6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Jul 2018 21:39:39 +0100 Subject: [PATCH 458/540] Complete spv tx circulation minimal testcase Highlight that polling for the arrival of a transaction works, whereas sleeping until a new transaction arrives fails. --- minimal_testcases/spv_tx_circulation.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/minimal_testcases/spv_tx_circulation.js b/minimal_testcases/spv_tx_circulation.js index ea3da20..60d7766 100644 --- a/minimal_testcases/spv_tx_circulation.js +++ b/minimal_testcases/spv_tx_circulation.js @@ -39,26 +39,24 @@ const testHelpers = require("../test/helpers"); const spvWallet = await testHelpers.createWallet(spvWalletDB, "spvWallet"); const fullWallet = await testHelpers.createWallet(fullWalletDB, "fullWallet"); - const fullWalle = await testHelpers.createWallet(fullWalletDB, "fullWalle"); await testHelpers.delay(1000); - // Produce a block and reward the fullWallet1, so that we have a coin to spend. + // Produce a block and reward the fullWallet, so that we have a coin to spend. await testHelpers.mineBlock(fullNode, fullWallet.getAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); - var tx = await fullWallet.send({ + const tx = await fullWallet.send({ outputs: [{ value: 10 * consensus.COIN, - address: fullWalle.getAddress("base58") + address: spvWallet.getAddress("base58") }] }); await fullWatcher.waitForTX(tx, fullWallet); - await fullWatcher.waitForTX(tx, fullWalle); - //await spvWatcher.waitForTX(tx, spvWallet); - await testHelpers.flushEvents(); + console.log("aaand..."); // works only with polling in waitForTX() + await spvWatcher.waitForTX(tx, spvWallet); spvNode.stopSync(); fullNode.stopSync(); From 329a9e27f538d9e463c8247fa819655b09968df6 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Jul 2018 21:42:25 +0100 Subject: [PATCH 459/540] Keep waiting for tx signal as comment --- test/helpers.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index b6cf148..e8afca7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -147,7 +147,8 @@ class NodeWatcher { async waitForTX(input, wallet) { if (wallet) { while (!(await wallet.getTX(input.hash("hex")))) { - await this.waitForSomeTX(); // @dionyziz: gets stuck, probably tx received and added asynchronously. cf test/spv_node.js:161 + await testHelpers.delay(100); + //await this.waitForSomeTX(); } return; } From b13007a20920bb33bf2f64bfd6bb6ec046d8ef2d Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Jul 2018 22:36:51 +0100 Subject: [PATCH 460/540] Modularize tx circulation tests Refactor {before,after}Each, separate tx circulation within full node and between full and spv node --- test/spv_node.js | 110 +++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index e13d0f4..895ed6a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -28,11 +28,11 @@ describe("SPVNode", () => { var spvWatcher = null; var minerWatcher = null; - beforeEach("set up addTX() spy", () => { - sinon.spy(Trust.TrustIsRisk.prototype, "addTX"); + beforeEach("make mined coins immediately spendable", () => { + consensus.COINBASE_MATURITY = 0; }); - beforeEach("connect SPV node and wallet", async () => { + beforeEach("create SPV node", async () => { spvNode = new Trust.SPVNode({ network: bcoin.network.get().toString(), httpPort: 48445, @@ -41,12 +41,18 @@ describe("SPVNode", () => { // logLevel: "debug", nodes: ["127.0.0.1:48448"] }); + }); + + beforeEach("set up SPV addTX() spy", () => { + sinon.spy(spvNode.trust, "addTX"); + }); + beforeEach("connect SPV node, create walletDB", async () => { await spvNode.initialize(); spvWalletDB = spvNode.require("walletdb"); }); - beforeEach("connect full node and wallet", async () => { + beforeEach("create full node", async () => { miner = new Trust.FullNode({ network: bcoin.network.get().toString(), httpPort: 48448, @@ -54,7 +60,13 @@ describe("SPVNode", () => { listen: true, passphrase: "secret" }); + }); + + beforeEach("set up full node addTX() spy", () => { + sinon.spy(miner.trust, "addTX"); + }); + beforeEach("connect full node, create walletDB", async () => { await miner.initialize(); minerWalletDB = miner.require("walletdb"); }); @@ -64,7 +76,7 @@ describe("SPVNode", () => { spvNode.startSync(); }); - beforeEach("get watchers", async () => { + beforeEach("create watchers", async () => { minerWatcher = new testHelpers.NodeWatcher(miner); spvWatcher = new testHelpers.NodeWatcher(spvNode); }); @@ -77,8 +89,13 @@ describe("SPVNode", () => { await miner.tearDown(); }); - afterEach("remove addTX() spy", () => { - Trust.TrustIsRisk.addTX.restore(); + afterEach("remove addTX() spies", () => { + spvNode.trust.addTX.restore(); + miner.trust.addTX.restore(); + }); + + afterEach("make mined coins spendable after 100 blocks (default)", () => { + consensus.COINBASE_MATURITY = 100; }); it("should match a TIR transaction with the spv bloom filter", async function() { @@ -122,69 +139,53 @@ describe("SPVNode", () => { tx.isWatched(spvNode.pool.spvFilter).should.be.true(); }); - it.only("should call trust.addTX() on every transaction", async function() { - var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); - var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); - + it("should call trust.addTX() on transaction within a full node", async function() { var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. await testHelpers.mineBlock(miner, minerWallet1.getAddress("base58")); - - // Make the coin spendable. - consensus.COINBASE_MATURITY = 0; await testHelpers.delay(100); var miner2TX = await testHelpers.circulateCoins(minerWallet1, minerWatcher, minerWallet2, minerWatcher, 10); miner.trust.addTX.should.have.been.calledOnce(); + }); - var minerSpvTX = await minerWallet2.send({ - outputs: [{ - value: 9 * COIN, - address: spvWallet1.getAddress("base58") - }] - }); // @dionyziz: wtf spv doesn't receive inv! - console.log(miner.pool.selfish, "is miner selfish?"); - console.log("lookie here"); - console.log(minerSpvTX.hash().toString("hex")); - await minerWatcher.waitForTX(minerSpvTX, minerWallet2); - await spvWatcher.waitForTX(minerSpvTX); - await testHelpers.flushEvents(); - - Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(4); - - var spv2TX = await spvWallet1.send({ - outputs: [{ - value: 8 * COIN, - address: spvWallet2.getAddress("base58") - }] - }); - await minerWatcher.waitForTX(spv2TX); // see why tx is received twice? - await spvWatcher.waitForTX(spv2TX, spvWallet1); - await spvWatcher.waitForTX(spv2TX, spvWallet2); - - // @dionyziz: Fixed it by putting minerWatcher before and removing inputs - Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(6); - - var spvMinerTX = await spvWallet2.send({ - outputs: [{ - value: 7 * COIN, - address: minerWallet1.getAddress("base58") - }] - }); - await spvWatcher.waitForTX(spvMinerTX, spvWallet2); - await minerWatcher.waitForTX(spvMinerTX, minerWallet1); + it("should call trust.addTX() on transaction between full and spv node", async function() { + var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); + var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); + + var minerWallet = await testHelpers.createWallet(minerWalletDB, "minerWallet"); - var view = await miner.chain.db.getSpentView(miner2TX); - var actualBalance = (await minerWallet1.getBalance()).unconfirmed; + await testHelpers.delay(1000); + // Produce a block and reward the minerWallet, so that we have a coin to spend. + await testHelpers.mineBlock(miner, minerWallet.getAddress("base58")); + await testHelpers.delay(100); + + var minerSpvTX = await testHelpers.circulateCoins(minerWallet, + minerWatcher, spvWallet1, spvWatcher, 10); + + spvNode.trust.addTX.should.have.been.calledOnce(); + + var spv2TX = await testHelpers.circulateCoins(spvWallet1, + spvWatcher, spvWallet2, spvWatcher, 9); + + spvNode.trust.addTX.should.have.been.calledTwice(); + + var spvMinerTX = await testHelpers.circulateCoins(spvWallet2, + spvWatcher, minerWallet, minerWatcher, 8); + + var view = await miner.chain.db.getSpentView(minerSpvTX); + var actualBalance = (await minerWallet.getBalance()).unconfirmed; var expectedBalance = - consensus.BASE_REWARD - 10 * COIN + 7 * COIN - miner2TX.getFee(view); + consensus.BASE_REWARD - 10 * COIN + 8 * COIN - minerSpvTX.getFee(view); actualBalance.should.equal(expectedBalance); - Trust.TrustIsRisk.prototype.addTX.callCount.should.equal(8); + + spvNode.trust.addTX.should.have.been.calledThrice(); + miner.trust.addTX.should.have.been.calledThrice(); }); describe("with the nobodyLikesFrank.json example", () => { @@ -370,7 +371,6 @@ describe("SPVNode", () => { console.log("origin", origin, "accepts tx?", (await wallet.origin.add(tx)) ? true : false); console.log("out and between"); console.log("dest", dest, "accepts tx?", (await wallet.dest.add(tx)) ? true : false); - process.exit(); node.origin.sendTX(tx); console.log(origin, dest, "aaa"); From bb4888537b0f186968aa243cfd371fa4fd12cafe Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Sun, 1 Jul 2018 22:38:04 +0100 Subject: [PATCH 461/540] Add mocha test timeout again --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ea8ab9..a4ff8a6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 0", + "test": "npm run build && mocha -t 20000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From fd717edfffd2243e94db5aa29b70f2a3ecbe16a8 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 5 Jul 2018 01:52:23 +0100 Subject: [PATCH 462/540] Add minimal testcase for multisig tx circulation --- minimal_testcases/multisig_tx.js | 358 +++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 minimal_testcases/multisig_tx.js diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js new file mode 100644 index 0000000..3b4fa26 --- /dev/null +++ b/minimal_testcases/multisig_tx.js @@ -0,0 +1,358 @@ +(async () => { + var Trust = require("../"); + var helpers = require("../lib/helpers.js"); + var bcoin = require("bcoin").set("regtest"); + var Script = bcoin.script; + var Address = bcoin.primitives.Address; + var KeyRing = bcoin.primitives.KeyRing; + var MTX = bcoin.primitives.MTX; + var Input = bcoin.primitives.Input; + var Output = bcoin.primitives.Output; + var Outpoint = bcoin.primitives.Outpoint; + var secp256k1 = bcoin.crypto.secp256k1; + var tag = require("../lib/tag"); + var testHelpers = require("../test/helpers"); + var consensus = require("bcoin/lib/protocol/consensus"); + var sinon = require("sinon"); + var should = require("should"); + var assert = require("assert"); + var fixtures = require("../test/fixtures"); + require("should-sinon"); + + const COIN = consensus.COIN; + + var spvNode = null; + var miner = null; + var spvWalletDB = null; + var minerWalletDB = null; + var spvWatcher = null; + var minerWatcher = null; + + consensus.COINBASE_MATURITY = 0; + + spvNode = new Trust.SPVNode({ + network: bcoin.network.get().toString(), + httpPort: 48445, + passphrase: "secret", + // logConsole: true, + // logLevel: "debug", + nodes: ["127.0.0.1:48448"] + }); + + await spvNode.initialize(); + spvWalletDB = spvNode.require("walletdb"); + + miner = new Trust.FullNode({ + network: bcoin.network.get().toString(), + httpPort: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + + await miner.initialize(); + minerWalletDB = miner.require("walletdb"); + + miner.startSync(); + spvNode.startSync(); + + minerWatcher = new testHelpers.NodeWatcher(miner); + spvWatcher = new testHelpers.NodeWatcher(spvNode); + + // describe + var minerNames = { + "alice": "alice", + "bob": "bob", + "eve": "eve", + "frank": "frank", + "george": "george" + }; + + var spvNames = { + "charlie": "charlie", + "dave": "dave" + }; + + var minerWallets = {}; + var spvWallets = {}; + + var addresses = {}, rings = {}, name = null; + + for (name in minerNames) { + minerWallets[name] = await testHelpers.createWallet( + minerWalletDB, name + ); + rings[name] = await minerWallets[name].getPrivateKey( + minerWallets[name].getAddress("base58"), "secret" + ); + addresses[name] = helpers.pubKeyToEntity( + rings[name].getPublicKey(), miner.network + ); + spvNode.pool.watchAddress(addresses[name]); + } + + for (name in spvNames) { + spvWallets[name] = await testHelpers.createWallet( + spvWalletDB, name + ); + rings[name] = await spvWallets[name].getPrivateKey( + spvWallets[name].getAddress("base58"), "secret" + ); + addresses[name] = helpers.pubKeyToEntity( + rings[name].getPublicKey(), spvNode.network + ); + spvNode.pool.watchAddress(addresses[name]); + } + + // Alice mines three blocks, each rewards her with 50 spendable BTC + consensus.COINBASE_MATURITY = 0; + var blockCount = 3; + var coinbaseHashes = []; + for(let i = 0; i < blockCount; i++) { + var block = await testHelpers.mineBlock( + miner, addresses["alice"] + ); + coinbaseHashes.push(block.txs[0].hash()); + await testHelpers.delay(500); + } + + // Alice sends 20 BTC to everyone (including herself) via P2PKH + var sendAmount = 20; + outputs = []; + for (name in minerNames) { + outputs.push(testHelpers.getP2PKHOutput( + addresses[name], sendAmount * consensus.COIN + )); + } + + for (name in spvNames) { + outputs.push(testHelpers.getP2PKHOutput( + addresses[name], sendAmount * consensus.COIN + )); + } + + // We have to use a change output, because transactions with too large a fee are + // considered invalid. + var fee = 0.01; + var changeAmount = 50 * blockCount - sendAmount * + (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; + if (changeAmount >= 0.01) { + outputs.push(new Output({ + script: Script.fromPubkeyhash(bcoin.crypto.hash160( + rings["alice"].publicKey)), + value: changeAmount * consensus.COIN + })); + } + + // Use the coinbase coins as inputs + var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { + return miner.getCoin(hash.toString("hex"), 0); + })); + var mtx = new MTX({outputs}); + coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); + + var signedCount = mtx.sign(rings["alice"]); + assert(signedCount === blockCount); + assert(mtx.verify()); + + var tx = mtx.toTX(); + + miner.sendTX(tx); + await minerWatcher.waitForTX(tx); + await spvWatcher.waitForTX(tx); + + for (name in minerNames) { + minerWallets[name].db.addTX(tx); + } + + for (name in spvNames) { + spvWallets[name].db.addTX(tx); + } + + var prevout = {}; + var counter = 0; + + for (name in minerNames) { + prevout[name] = { + hash: tx.hash().toString("hex"), + index: counter++ + }; + } + + for (name in spvNames) { + prevout[name] = { + hash: tx.hash().toString("hex"), + index: counter++ + }; + } + + // Alice mines another block + await testHelpers.mineBlock(miner, addresses["alice"]); + await testHelpers.delay(500); + + var graph = require("../test/graphs/nobodyLikesFrank.json"); + + function buildVars(player) { + return (spvNames[player]) ? + [spvNode, spvWatcher, spvWallets[player]] : + [miner, minerWatcher, minerWallets[player]]; + } + + let node = { + origin: null, + dest: null + }; + let watcher = { + origin: null, + dest: null + }; + let wallet = { + origin: null, + dest: null + }; + + for (var origin in graph) { + + [node.origin, watcher.origin, wallet.origin] = buildVars(origin); + + var neighbours = graph[origin]; + + for (var dest in neighbours) { + var value = neighbours[dest]; + if (!value || value < 1) continue; + + [node.dest, watcher.dest, wallet.dest] = buildVars(dest); + + + let outpoint = new Outpoint(prevout[origin].hash, + prevout[origin].index); + + let mtx = await node.origin.trust.createTrustIncreasingMTX( + rings[origin].getPrivateKey(), + rings[dest].getPublicKey(), + outpoint, + value * consensus.COIN, + wallet.origin); + + assert(mtx.verify()); + + let tx = mtx.toTX(); + console.log("ignore above"); + console.log("origin", origin, "accepts tx?", (await wallet.origin.add(tx)) ? true : false); + console.log("out and between"); + console.log("dest", dest, "accepts tx?", (await wallet.dest.add(tx)) ? true : false); + + node.origin.sendTX(tx); + console.log(origin, dest, "aaa"); + await watcher.origin.waitForTX(tx, wallet.origin); + console.log("origin has tx"); + await watcher.dest.waitForTX(tx, wallet.dest); // TODO: dest doesn't get tx + //await spvWatcher.waitForTX(); // it worked one time! race condition + console.log("both sides have tx"); + // spv node accepts inv, but does not put tx in the spvNode.txFilter; this is + // reserved for *sent*, not *received* txs + + console.log(origin, dest, "bbb"); + await wallet.origin.db.addTX(); + await wallet.dest.db.addTX(); + + prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; + } + } + + // Alice mines yet another block + await testHelpers.mineBlock(miner, helpers.pubKeyToEntity( + rings["alice"].getPublicKey(), miner.network + )); + await testHelpers.delay(500); + + // it 1 begin + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + miner.trust.getIndirectTrust(alice, alice).should.equal(Infinity); + miner.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); + miner.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); + miner.trust.getIndirectTrust(alice, frank).should.equal(0); + miner.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); + + miner.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); + miner.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); + miner.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); + miner.trust.getIndirectTrust(george, eve).should.equal(0); + // it 1 end + + // it 2 begin + for (name in addresses) { // Add addresses to scope + eval(`var ${name} = "${addresses[name]}";`); + } + + spvNode.trust.getIndirectTrust(alice, alice).should.equal(Infinity); + spvNode.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); + spvNode.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); + spvNode.trust.getIndirectTrust(alice, frank).should.equal(0); + spvNode.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); + + spvNode.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); + spvNode.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); + spvNode.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); + spvNode.trust.getIndirectTrust(george, eve).should.equal(0); + // it 2 end + +// it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { +// var mtxs = await miner.trust.createTrustDecreasingMTXs( +// rings["alice"].getPrivateKey(), +// rings["bob"].getPublicKey(), 3 * COIN, +// minerWallets["alice"] +// ); +// mtxs.length.should.equal(1); +// var mtx = await mtxs[0]; +// +// mtx.verify().should.be.true(); +// var tx = mtx.toTX(); +// miner.sendTX(tx); +// +// await testHelpers.delay(3000); // combine with next promises with race +// for (name in minerNames) { +// console.log(name,"aaa"); // see why spv node doesn't accept inv +// await minerWatcher.waitForTX(tx); +// } +// for (name in spvNames) { +// await spvWatcher.waitForTX(tx); +// } +// miner.trust.getIndirectTrust(addresses["alice"], +// addresses["bob"]).should.equal(7 * COIN); +// spvNode.trust.getIndirectTrust(addresses["alice"], +// addresses["bob"]).should.equal(7 * COIN); +// +// mtxs = await spvNode.trust.createTrustDecreasingMTXs( +// rings["dave"].getPrivateKey(), +// rings["eve"].getPublicKey(), 2 * COIN, +// spvWallets["dave"] +// ); +// mtxs.length.should.equal(1); +// mtx = await mtxs[0]; +// +// mtx.verify().should.be.true(); +// tx = mtx.toTX(); +// spvNode.sendTX(tx); +// +// await minerWatcher.waitForTX(tx); +// await spvWatcher.waitForTX(tx); +// miner.trust.getIndirectTrust(addresses["dave"], +// addresses["eve"]).should.equal(10 * COIN); +// spvNode.trust.getIndirectTrust(addresses["dave"], +// addresses["eve"]).should.equal(10 * COIN); +// }); + + spvNode.stopSync(); + miner.stopSync(); + + await spvNode.tearDown(); + await miner.tearDown(); + + consensus.COINBASE_MATURITY = 100; + + console.log("success!"); +})(); From 65e35477cc31dc8f52031756333088fb6715399a Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 14 Jul 2018 18:19:17 +0100 Subject: [PATCH 463/540] Update mocha for security --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a4ff8a6..0e39224 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "eslint-plugin-flowtype": "^2.33.0", "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.0", - "mocha": "^3.4.2", + "mocha": "^5.2.0", "should": "^11.2.1", "should-sinon": "0.0.5", "sinon": "^5.1.1" From 6844eafb8c2494140dc1053343c70f1b2ce5072e Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 14 Jul 2018 18:21:33 +0100 Subject: [PATCH 464/540] Update package-lock.json due to install --- package-lock.json | 1150 +++++++++++++++++++++------------------------ 1 file changed, 546 insertions(+), 604 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8d63434..d947ba1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", "optional": true, "requires": { - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + "xtend": "~4.0.0" } }, "accepts": { @@ -28,7 +28,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "optional": true, "requires": { - "mime-types": "2.1.18", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -38,7 +38,8 @@ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" }, "ansi-regex": { - "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { @@ -53,8 +54,8 @@ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" }, "dependencies": { "process-nextick-args": { @@ -69,13 +70,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "optional": true, "requires": { - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "process-nextick-args": "2.0.0", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "string_decoder": "1.1.1", - "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -84,7 +85,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "optional": true, "requires": { - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "safe-buffer": "~5.1.0" } } } @@ -105,10 +106,10 @@ "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0" + "babel-code-frame": "^6.22.0", + "babel-traverse": "^6.23.1", + "babel-types": "^6.23.0", + "babylon": "^6.17.0" }, "dependencies": { "ansi-regex": { @@ -129,9 +130,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "babel-messages": { @@ -140,7 +141,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-runtime": { @@ -149,8 +150,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "babel-traverse": { @@ -159,15 +160,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.4", - "lodash": "4.17.10" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, "babel-types": { @@ -176,10 +177,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.10", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "babylon": { @@ -194,11 +195,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "core-js": { @@ -240,7 +241,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "invariant": { @@ -249,7 +250,7 @@ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "js-tokens": { @@ -270,7 +271,7 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0" } }, "ms": { @@ -291,7 +292,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "supports-color": { @@ -315,7 +316,8 @@ "optional": true }, "balanced-match": { - "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, @@ -351,8 +353,8 @@ "integrity": "sha512-bk2XK9EtOcTiqS4cgJ5dy77R2bVJC65dTvLuhH+SxLemjERC3jbf8jadYvOYfZx/x8TF6fuxZzWruhc0OF3Bnw==", "optional": true, "requires": { - "bindings": "1.3.0", - "nan": "2.10.0" + "bindings": "^1.2.1", + "nan": "^2.6.2" } }, "better-assert": { @@ -375,7 +377,7 @@ "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", "optional": true, "requires": { - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "safe-buffer": "^5.0.1" } }, "bl": { @@ -384,8 +386,8 @@ "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "optional": true, "requires": { - "readable-stream": "2.3.6", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" }, "dependencies": { "process-nextick-args": { @@ -400,13 +402,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "optional": true, "requires": { - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "process-nextick-args": "2.0.0", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "string_decoder": "1.1.1", - "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -415,7 +417,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "optional": true, "requires": { - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "safe-buffer": "~5.1.0" } } } @@ -431,12 +433,13 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "brace-expansion": { - "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "brorand": { @@ -445,8 +448,9 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browser-stdout": { - "version": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "browserify-aes": { @@ -455,12 +459,12 @@ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "optional": true, "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "buffer-alloc": { @@ -469,8 +473,8 @@ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "optional": true, "requires": { - "buffer-alloc-unsafe": "1.1.0", - "buffer-fill": "1.0.0" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, "buffer-alloc-unsafe": { @@ -513,21 +517,20 @@ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "code-point-at": { - "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "commander": { - "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" - } + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true }, "component-bind": { "version": "1.0.0", @@ -547,7 +550,8 @@ "optional": true }, "concat-map": { - "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, @@ -563,7 +567,8 @@ "optional": true }, "core-util-is": { - "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-hash": { @@ -571,11 +576,11 @@ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { - "cipher-base": "1.0.4", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "md5.js": "1.3.4", - "ripemd160": "2.0.2", - "sha.js": "2.4.11" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, "create-hmac": { @@ -584,12 +589,21 @@ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "optional": true, "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "ripemd160": "2.0.2", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "sha.js": "2.4.11" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" } }, "decompress-response": { @@ -598,7 +612,7 @@ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "optional": true, "requires": { - "mimic-response": "1.0.0" + "mimic-response": "^1.0.0" } }, "deep-extend": { @@ -620,8 +634,9 @@ "optional": true }, "diff": { - "version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "drbg.js": { @@ -630,9 +645,9 @@ "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "optional": true, "requires": { - "browserify-aes": "1.2.0", - "create-hash": "1.2.0", - "create-hmac": "1.1.7" + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" } }, "elliptic": { @@ -640,13 +655,13 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, "end-of-stream": { @@ -654,7 +669,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "once": "^1.4.0" } }, "engine.io": { @@ -663,13 +678,13 @@ "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "optional": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.4", "base64id": "1.0.0", "cookie": "0.3.1", - "debug": "3.1.0", - "engine.io-parser": "2.1.2", - "uws": "9.14.0", - "ws": "3.3.3" + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "uws": "~9.14.0", + "ws": "~3.3.1" }, "dependencies": { "debug": { @@ -678,7 +693,7 @@ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "optional": true, "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "ms": "2.0.0" } } } @@ -691,14 +706,14 @@ "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "3.1.0", - "engine.io-parser": "2.1.2", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", "has-cors": "1.1.0", "indexof": "0.0.1", "parseqs": "0.0.5", "parseuri": "0.0.5", - "ws": "3.3.3", - "xmlhttprequest-ssl": "1.5.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", "yeast": "0.1.2" }, "dependencies": { @@ -708,7 +723,7 @@ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "optional": true, "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "ms": "2.0.0" } } } @@ -719,14 +734,15 @@ "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", "requires": { "after": "0.8.2", - "arraybuffer.slice": "0.0.7", + "arraybuffer.slice": "~0.0.7", "base64-arraybuffer": "0.1.5", "blob": "0.0.4", - "has-binary2": "1.0.3" + "has-binary2": "~1.0.2" } }, "escape-string-regexp": { - "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, @@ -736,41 +752,41 @@ "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.6.2", - "debug": "2.6.9", - "doctrine": "2.1.0", - "escope": "3.6.0", - "espree": "3.5.4", - "esquery": "1.0.1", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.8", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.17.2", - "is-resolvable": "1.1.0", - "js-yaml": "3.12.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.10", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" }, "dependencies": { "acorn": { @@ -785,7 +801,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { @@ -802,8 +818,8 @@ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "dev": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ajv-keywords": { @@ -836,7 +852,7 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "array-union": { @@ -845,7 +861,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -866,9 +882,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "balanced-match": { @@ -883,7 +899,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -893,7 +909,7 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, "callsites": { @@ -908,11 +924,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "circular-json": { @@ -927,7 +943,7 @@ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "dev": true, "requires": { - "restore-cursor": "1.0.1" + "restore-cursor": "^1.0.1" } }, "cli-width": { @@ -960,10 +976,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "1.1.0", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "core-util-is": { @@ -978,7 +994,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.45" + "es5-ext": "^0.10.9" } }, "debug": { @@ -1002,13 +1018,13 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" } }, "doctrine": { @@ -1017,7 +1033,7 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "es5-ext": { @@ -1026,9 +1042,9 @@ "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", "dev": true, "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "next-tick": "1.0.0" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" } }, "es6-iterator": { @@ -1037,9 +1053,9 @@ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.45", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, "es6-map": { @@ -1048,12 +1064,12 @@ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.45", - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" } }, "es6-set": { @@ -1062,11 +1078,11 @@ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.45", - "es6-iterator": "2.0.3", + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "event-emitter": "~0.3.5" } }, "es6-symbol": { @@ -1075,8 +1091,8 @@ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.45" + "d": "1", + "es5-ext": "~0.10.14" } }, "es6-weak-map": { @@ -1085,10 +1101,10 @@ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.45", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" } }, "escape-string-regexp": { @@ -1103,10 +1119,10 @@ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "dev": true, "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "espree": { @@ -1115,8 +1131,8 @@ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "5.6.1", - "acorn-jsx": "3.0.1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -1131,7 +1147,7 @@ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -1140,7 +1156,7 @@ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.1.0" } }, "estraverse": { @@ -1161,8 +1177,8 @@ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.45" + "d": "1", + "es5-ext": "~0.10.14" } }, "exit-hook": { @@ -1183,8 +1199,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "file-entry-cache": { @@ -1193,8 +1209,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "flat-cache": { @@ -1203,10 +1219,10 @@ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "fs.realpath": { @@ -1227,7 +1243,7 @@ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", "dev": true, "requires": { - "is-property": "1.0.2" + "is-property": "^1.0.0" } }, "glob": { @@ -1236,12 +1252,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "globals": { @@ -1256,12 +1272,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "graceful-fs": { @@ -1276,7 +1292,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "ignore": { @@ -1297,8 +1313,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -1313,19 +1329,19 @@ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", - "lodash": "4.17.10", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" } }, "interpret": { @@ -1340,7 +1356,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-my-json-valid": { @@ -1349,11 +1365,11 @@ "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", "dev": true, "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "is-my-ip-valid": "1.0.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" } }, "is-path-cwd": { @@ -1368,7 +1384,7 @@ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -1377,7 +1393,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-property": { @@ -1410,8 +1426,8 @@ "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "dev": true, "requires": { - "argparse": "1.0.10", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "json-stable-stringify": { @@ -1420,7 +1436,7 @@ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "jsonify": { @@ -1441,8 +1457,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "lodash": { @@ -1457,7 +1473,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1511,7 +1527,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -1526,12 +1542,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "os-homedir": { @@ -1576,7 +1592,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pluralize": { @@ -1609,13 +1625,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readline2": { @@ -1624,8 +1640,8 @@ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", "mute-stream": "0.0.5" } }, @@ -1635,7 +1651,7 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "1.7.1" + "resolve": "^1.1.6" } }, "require-uncached": { @@ -1644,8 +1660,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" } }, "resolve": { @@ -1654,7 +1670,7 @@ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "resolve-from": { @@ -1669,8 +1685,8 @@ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "dev": true, "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, "rimraf": { @@ -1679,7 +1695,7 @@ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "run-async": { @@ -1688,7 +1704,7 @@ "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "dev": true, "requires": { - "once": "1.4.0" + "once": "^1.3.0" } }, "rx-lite": { @@ -1709,9 +1725,9 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "7.1.2", - "interpret": "1.1.0", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "slice-ansi": { @@ -1732,9 +1748,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1743,7 +1759,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1752,7 +1768,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -1779,12 +1795,12 @@ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.10", + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", "slice-ansi": "0.0.4", - "string-width": "2.1.1" + "string-width": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -1805,8 +1821,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "strip-ansi": { @@ -1815,7 +1831,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -1838,7 +1854,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "typedarray": { @@ -1853,7 +1869,7 @@ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } }, "util-deprecate": { @@ -1880,7 +1896,7 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "xtend": { @@ -1897,7 +1913,7 @@ "integrity": "sha512-wO0S4QbXPReKtydxbY5A0UieOaF9jBO5BMuxYPQOTa082JCpKEoC7+o3fnKsVVycwX47lvqLiUGRsWauCiA9aw==", "dev": true, "requires": { - "lodash": "4.17.10" + "lodash": "^4.17.10" }, "dependencies": { "lodash": { @@ -1914,8 +1930,8 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "optional": true, "requires": { - "md5.js": "1.3.4", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "expand-template": { @@ -1942,8 +1958,8 @@ "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==", "dev": true, "requires": { - "babylon": "6.18.0", - "vlq": "0.2.3" + "babylon": "^6.15.0", + "vlq": "^0.2.1" }, "dependencies": { "babylon": { @@ -1967,7 +1983,8 @@ "optional": true }, "fs.realpath": { - "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, @@ -1977,14 +1994,14 @@ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "signal-exit": "3.0.2", - "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "wide-align": "1.1.3" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "github-from-package": { @@ -1993,10 +2010,19 @@ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", "optional": true }, - "graceful-readlink": { - "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } }, "graph-theory-ford-fulkerson": { "version": "1.0.0", @@ -2004,8 +2030,9 @@ "integrity": "sha1-LDHSHXDxp9KCiZX+BnZFdv9/nik=" }, "growl": { - "version": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "has-binary2": { @@ -2028,11 +2055,6 @@ "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" }, - "has-flag": { - "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -2044,8 +2066,8 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "hash.js": { @@ -2053,8 +2075,8 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "minimalistic-assert": "1.0.1" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" } }, "he": { @@ -2068,9 +2090,9 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "indexof": { @@ -2079,16 +2101,18 @@ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" }, "inflight": { - "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { - "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { @@ -2098,10 +2122,11 @@ "optional": true }, "is-fullwidth-code-point": { - "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + "number-is-nan": "^1.0.0" } }, "is-my-ip-valid": { @@ -2111,7 +2136,8 @@ "dev": true }, "isarray": { - "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "just-extend": { @@ -2126,11 +2152,11 @@ "integrity": "sha1-XjRnuyfuJGpKe429j7KxYgam64s=", "optional": true, "requires": { - "abstract-leveldown": "2.6.3", - "bindings": "1.2.1", - "fast-future": "1.0.2", - "nan": "2.6.2", - "prebuild-install": "2.5.3" + "abstract-leveldown": "~2.6.1", + "bindings": "~1.2.1", + "fast-future": "~1.0.2", + "nan": "~2.6.1", + "prebuild-install": "^2.1.0" }, "dependencies": { "bindings": { @@ -2147,71 +2173,12 @@ } } }, - "lodash._baseassign": { - "version": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" - } - }, - "lodash._basecopy": { - "version": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basecreate": { - "version": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash.create": { - "version": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "lodash._basecreate": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "lodash._isiterateecall": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" - } - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "lodash.isarguments": { - "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "lodash.isarguments": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "lodash.isarray": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" - } - }, "lolex": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.0.tgz", @@ -2223,8 +2190,8 @@ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "3.0.4", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, "mime-db": { @@ -2239,7 +2206,7 @@ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "optional": true, "requires": { - "mime-db": "1.33.0" + "mime-db": "~1.33.0" } }, "mimic-response": { @@ -2259,11 +2226,12 @@ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { - "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -2272,80 +2240,42 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mkdirp": { - "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { - "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + "minimist": "0.0.8" }, "dependencies": { "minimist": { - "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, "mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "dev": true, "requires": { - "browser-stdout": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "commander": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "debug": "2.6.8", - "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "glob": "7.1.1", - "growl": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "supports-color": "3.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - } - }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", - "dev": true, - "requires": { - "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - } - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", - "dev": true, - "requires": { - "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz" - } - } + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" } }, "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "n64": { @@ -2377,11 +2307,11 @@ "integrity": "sha512-9JX3YwoIt3kS237scmSSOpEv7vCukVzLfwK0I0XhocDSHUANid8ZHnLEULbbSkfeMn98B2y5kphIWzZUylESRQ==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "just-extend": "1.1.27", - "lolex": "2.7.0", - "path-to-regexp": "1.7.0", - "text-encoding": "0.6.4" + "@sinonjs/formatio": "^2.0.0", + "just-extend": "^1.1.27", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" } }, "node-abi": { @@ -2390,7 +2320,7 @@ "integrity": "sha512-pUlswqpHQ7zGPI9lGjZ4XDNIEUDbHxsltfIRb7dTnYdhgHWHOcB0MLZKLoCz6UMcGzSPG5wGl1HODZVQAUsH6w==", "optional": true, "requires": { - "semver": "5.5.0" + "semver": "^5.4.1" } }, "noop-logger": { @@ -2405,18 +2335,20 @@ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "optional": true, "requires": { - "are-we-there-yet": "1.1.5", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { - "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { - "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "optional": true }, @@ -2427,14 +2359,16 @@ "optional": true }, "once": { - "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "wrappy": "1" } }, "os-homedir": { - "version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "optional": true }, @@ -2443,7 +2377,7 @@ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "parseuri": { @@ -2451,11 +2385,12 @@ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "path-is-absolute": { - "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -2482,21 +2417,21 @@ "integrity": "sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g==", "optional": true, "requires": { - "detect-libc": "1.0.3", - "expand-template": "1.1.1", + "detect-libc": "^1.0.3", + "expand-template": "^1.0.2", "github-from-package": "0.0.0", - "minimist": "1.2.0", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "node-abi": "2.4.1", - "noop-logger": "0.1.1", - "npmlog": "4.1.2", - "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "pump": "2.0.1", - "rc": "1.2.8", - "simple-get": "2.8.1", - "tar-fs": "1.16.2", - "tunnel-agent": "0.6.0", - "which-pm-runs": "1.0.0" + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-abi": "^2.2.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "os-homedir": "^1.0.1", + "pump": "^2.0.1", + "rc": "^1.1.6", + "simple-get": "^2.7.0", + "tar-fs": "^1.13.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" } }, "pump": { @@ -2505,8 +2440,8 @@ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "optional": true, "requires": { - "end-of-stream": "1.4.1", - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "rc": { @@ -2515,10 +2450,10 @@ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "optional": true, "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, "ripemd160": { @@ -2526,12 +2461,13 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "requires": { - "hash-base": "3.0.4", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, "safe-buffer": { - "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" }, "samsam": { @@ -2546,15 +2482,15 @@ "integrity": "sha512-CbrQoeGG5V0kQ1ohEMGI+J7oKerapLTpivLICBaXR0R4HyQcN3kM9itLsV5fdpV1UR1bD14tOkJ1xughmlDIiQ==", "optional": true, "requires": { - "bindings": "1.3.0", - "bip66": "1.1.5", - "bn.js": "4.11.8", - "create-hash": "1.2.0", - "drbg.js": "1.0.1", - "elliptic": "6.4.0", - "nan": "2.10.0", - "prebuild-install": "2.5.3", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "bindings": "^1.2.1", + "bip66": "^1.1.3", + "bn.js": "^4.11.3", + "create-hash": "^1.1.2", + "drbg.js": "^1.0.1", + "elliptic": "^6.2.3", + "nan": "^2.2.1", + "prebuild-install": "^2.0.0", + "safe-buffer": "^5.1.0" } }, "semver": { @@ -2574,8 +2510,8 @@ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "should": { @@ -2584,11 +2520,11 @@ "integrity": "sha1-kPVRRVUtAc/CAGZuToGKHJZw7aI=", "dev": true, "requires": { - "should-equal": "1.0.1", - "should-format": "3.0.3", - "should-type": "1.4.0", - "should-type-adaptors": "1.1.0", - "should-util": "1.0.0" + "should-equal": "^1.0.0", + "should-format": "^3.0.2", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" }, "dependencies": { "should-equal": { @@ -2597,7 +2533,7 @@ "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", "dev": true, "requires": { - "should-type": "1.4.0" + "should-type": "^1.0.0" } }, "should-format": { @@ -2606,8 +2542,8 @@ "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", "dev": true, "requires": { - "should-type": "1.4.0", - "should-type-adaptors": "1.1.0" + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" } }, "should-type": { @@ -2622,8 +2558,8 @@ "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", "dev": true, "requires": { - "should-type": "1.4.0", - "should-util": "1.0.0" + "should-type": "^1.3.0", + "should-util": "^1.0.0" } }, "should-util": { @@ -2658,9 +2594,9 @@ "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", "optional": true, "requires": { - "decompress-response": "3.3.0", - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "simple-concat": "1.0.0" + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "sinon": { @@ -2669,13 +2605,13 @@ "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "diff": "3.5.0", - "lodash.get": "4.4.2", - "lolex": "2.7.0", - "nise": "1.4.1", - "supports-color": "5.4.0", - "type-detect": "4.0.8" + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.5.0", + "lodash.get": "^4.4.2", + "lolex": "^2.4.2", + "nise": "^1.3.3", + "supports-color": "^5.4.0", + "type-detect": "^4.0.8" }, "dependencies": { "diff": { @@ -2692,12 +2628,12 @@ "integrity": "sha1-Q1nwaiSTOua9CHeYr3jGgOrjReM=", "optional": true, "requires": { - "debug": "2.6.9", - "engine.io": "3.1.5", - "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "socket.io-adapter": "1.1.1", - "socket.io-client": "2.0.3", - "socket.io-parser": "3.1.3" + "debug": "~2.6.6", + "engine.io": "~3.1.0", + "object-assign": "~4.1.1", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "~2.0.2", + "socket.io-parser": "~3.1.1" }, "dependencies": { "debug": { @@ -2706,7 +2642,7 @@ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "optional": true, "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "ms": "2.0.0" } } } @@ -2727,14 +2663,14 @@ "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "2.6.9", - "engine.io-client": "3.1.6", + "debug": "~2.6.4", + "engine.io-client": "~3.1.0", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "3.1.3", + "socket.io-parser": "~3.1.1", "to-array": "0.1.4" }, "dependencies": { @@ -2744,7 +2680,7 @@ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "optional": true, "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "ms": "2.0.0" } } } @@ -2755,8 +2691,8 @@ "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", "requires": { "component-emitter": "1.2.1", - "debug": "3.1.0", - "has-binary2": "1.0.3", + "debug": "~3.1.0", + "has-binary2": "~1.0.2", "isarray": "2.0.1" }, "dependencies": { @@ -2765,7 +2701,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "ms": "2.0.0" } }, "isarray": { @@ -2781,23 +2717,26 @@ "integrity": "sha1-POAVeFtkdPH6A6HGn/8ymFL8N+M=" }, "string-width": { - "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "strip-ansi": { - "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { - "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "optional": true }, @@ -2807,7 +2746,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" }, "dependencies": { "has-flag": { @@ -2824,10 +2763,10 @@ "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==", "optional": true, "requires": { - "chownr": "1.0.1", - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "pump": "1.0.3", - "tar-stream": "1.6.1" + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" }, "dependencies": { "pump": { @@ -2836,8 +2775,8 @@ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", "optional": true, "requires": { - "end-of-stream": "1.4.1", - "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } } } @@ -2848,13 +2787,13 @@ "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", "optional": true, "requires": { - "bl": "1.2.2", - "buffer-alloc": "1.2.0", - "end-of-stream": "1.4.1", - "fs-constants": "1.0.0", - "readable-stream": "2.3.6", - "to-buffer": "1.1.1", - "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + "bl": "^1.0.0", + "buffer-alloc": "^1.1.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.0", + "xtend": "^4.0.0" }, "dependencies": { "process-nextick-args": { @@ -2869,13 +2808,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "optional": true, "requires": { - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "process-nextick-args": "2.0.0", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "string_decoder": "1.1.1", - "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -2884,7 +2823,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "optional": true, "requires": { - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "safe-buffer": "~5.1.0" } } } @@ -2913,7 +2852,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "optional": true, "requires": { - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" + "safe-buffer": "^5.0.1" } }, "type-detect": { @@ -2928,7 +2867,8 @@ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "util-deprecate": { - "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uws": { @@ -2949,11 +2889,12 @@ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "optional": true, "requires": { - "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + "string-width": "^1.0.2 || 2" } }, "wrappy": { - "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { @@ -2961,9 +2902,9 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "ultron": "1.1.1" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, "xmlhttprequest-ssl": { @@ -2973,7 +2914,8 @@ "optional": true }, "xtend": { - "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "yeast": { From 91b7418ee9fe3665987afaf7ae769048f1149121 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 14 Jul 2018 18:21:49 +0100 Subject: [PATCH 465/540] Update tag verification Use result property to check for public key validity --- test/trust_is_risk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index eae5bf9..e31b987 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -80,7 +80,7 @@ tearDownTest = async () => { describe("tag", () => { it("corresponds to a valid public key", () => { Buffer.isBuffer(tag).should.be.true(); - secp256k1.publicKeyVerify(tag).should.be.true(); + secp256k1.publicKeyVerify(tag).result.should.be.true(); }); it("is a valid bitcoin address", () => { From bf469544b59475608ecaa545fded092b86cee382 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 14 Jul 2018 21:05:40 +0100 Subject: [PATCH 466/540] Update to new bcoin version --- package-lock.json | 926 +++++++++++++++++----------------------------- package.json | 4 +- 2 files changed, 334 insertions(+), 596 deletions(-) diff --git a/package-lock.json b/package-lock.json index d947ba1..bb1a227 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,29 +14,13 @@ } }, "abstract-leveldown": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", - "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", - "optional": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", "requires": { "xtend": "~4.0.0" } }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "optional": true, - "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" - } - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -45,61 +29,17 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "optional": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" - }, "babel-eslint": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", @@ -309,73 +249,135 @@ } } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "optional": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + "bcfg": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.0.tgz", + "integrity": "sha512-Kk5TJRbjnX5irARDolBmbMzjj0Nc3uXeg0kqOJW1iDUA0+l7rDS8SNTAEd0s4hCENK2X626ZelQCA2TurDpFRA==" }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "optional": true + "bclient": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.1.tgz", + "integrity": "sha512-x7OhFmlR3G/XBWE8wowh2ZK0YjYTkEuS0+QLMFrkMGn74xpdjvAYRELSQa8aTtoBZjSfXWRQ2baerVc3DKnvHg==", + "requires": { + "bcfg": "~0.1.0", + "bcurl": "~0.1.1" + } }, "bcoin": { - "version": "1.0.0-beta.15", - "resolved": "https://registry.npmjs.org/bcoin/-/bcoin-1.0.0-beta.15.tgz", - "integrity": "sha512-W35ksmbcoGdFZL9LgJpV3jBNI72ZxyJHqb932wTiMAtfI7puyQDz9Cfv8sVY603nvtN+wVleAvFR68gz080NVQ==", - "requires": { - "bcoin-native": "0.0.23", - "bn.js": "4.11.8", - "elliptic": "6.4.0", - "leveldown": "1.7.2", - "n64": "0.0.18", - "secp256k1": "3.3.0", - "socket.io": "2.0.3", - "socket.io-client": "2.0.3" - } - }, - "bcoin-native": { - "version": "0.0.23", - "resolved": "https://registry.npmjs.org/bcoin-native/-/bcoin-native-0.0.23.tgz", - "integrity": "sha512-bk2XK9EtOcTiqS4cgJ5dy77R2bVJC65dTvLuhH+SxLemjERC3jbf8jadYvOYfZx/x8TF6fuxZzWruhc0OF3Bnw==", - "optional": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcoin/-/bcoin-1.0.2.tgz", + "integrity": "sha512-eG7j7giwjWHa6et1ZSTgqELRKOFRaQYWDdpA0AbQQO1Xw5K8nqIDPuXySwO18Y9S2Ik+VkvAqL6IlmfnYzA3mw==", + "requires": { + "bcfg": "~0.1.0", + "bclient": "~0.1.1", + "bcrypto": "~0.3.7", + "bdb": "~0.2.1", + "bdns": "~0.1.0", + "bevent": "~0.1.0", + "bfile": "~0.1.0", + "bfilter": "~0.2.0", + "bheep": "~0.1.0", + "binet": "~0.3.0", + "blgr": "~0.1.0", + "blru": "~0.1.0", + "blst": "~0.1.0", + "bmutex": "~0.1.0", + "bn.js": "~4.11.8", + "bsip": "~0.1.0", + "bsock": "~0.1.0", + "bsocks": "~0.2.0", + "bstring": "~0.1.0", + "btcp": "~0.1.0", + "bufio": "~0.2.0", + "bupnp": "~0.2.1", + "bval": "~0.1.0", + "bweb": "~0.1.1", + "mrmr": "~0.1.0", + "n64": "~0.2.0" + } + }, + "bcrypto": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-0.3.7.tgz", + "integrity": "sha512-ZFeKszFo4abpbzLUK8sqQx87Np5ptaskhszU4Jf9JDFa1Bjuanwrv0a7z1xZJOWNG9abz8krgwvO1Z/NBtsgbg==", + "requires": { + "bindings": "~1.3.0", + "bn.js": "~4.11.8", + "bufio": "~0.2.0", + "elliptic": "~6.4.0", + "nan": "~2.10.0", + "secp256k1": "3.5.0" + } + }, + "bcurl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.1.tgz", + "integrity": "sha512-yPRWseKphdB9KZEkx/VGncr7PHlZtyIc30S4PwGlVTLvSQAAMSk5PcUCrUf3r3ny4ZBOAhf5hrHLqSUUTWSwtw==", "requires": { - "bindings": "^1.2.1", - "nan": "^2.6.2" + "brq": "~0.1.1", + "bsock": "~0.1.0" } }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "bdb": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/bdb/-/bdb-0.2.2.tgz", + "integrity": "sha512-xhAlkaONuXezzHkvEVUrbNpriv5iq4aoy+Zaf0M8iSPEdtzZKr6eA68xl9fxKY3gVNYxOqLgbphtd6PqZOMXaA==", "requires": { - "callsite": "1.0.0" + "leveldown": "4.0.1" } }, + "bdns": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.0.tgz", + "integrity": "sha512-rlAUuoa+wxdvsZzyGZJYbpWLys9hE2J40IMhH+RIWO2BfpsmFVi0nD9NNJwAuFY/51xjLODkF5RTAb8llQNdGA==" + }, + "bevent": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.0.tgz", + "integrity": "sha512-SjN5/WFO7BFtFJ9ThXlI+fmkcEpcH2LuyMGB3cqT97i13J/Z6fZYDfwcoy9uua2mEtS8d/wI5r6EuUBySW33og==" + }, + "bfile": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.0.tgz", + "integrity": "sha512-EUS2HiB25FPKlcP9QCtzOKnew5eQQGs0+xtk/3b31WevFlEiFvy9yPyhcb+QR77LAOrjDLaKsb9AevzU2p9tlg==" + }, + "bfilter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bfilter/-/bfilter-0.2.0.tgz", + "integrity": "sha512-kQ+LV1FTS3un6iiOqg9qp2kAF+fADZNMZpmv2DHMFIgRSCAjH4NHi9p9X3i34kGJlZzP7+KkySK5it/8/oWKEA==", + "requires": { + "bufio": "~0.2.0", + "mrmr": "~0.1.0" + } + }, + "bheep": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.0.tgz", + "integrity": "sha512-AS83MBzYDL3fQ8lRdSWUysa8fsTibtXXEuvnUfYKWnyQx4mfKsrg3SeNCODXoa+S8M85Tzxfej7ylBV67dj7mQ==" + }, "bindings": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", - "optional": true + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" + }, + "binet": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.0.tgz", + "integrity": "sha512-gKyPRu3UO3/dmaIXWq238XD/EDTEmye2kFXTBTWPEO3QOaEaxC03evkDcVn7ma0GUi1zYvN9coTaQDOml21q6A==", + "requires": { + "bs32": "~0.1.0" + } }, "bip66": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "optional": true, "requires": { "safe-buffer": "^5.0.1" } @@ -384,48 +386,30 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "optional": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + "blgr": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.0.tgz", + "integrity": "sha512-Bbrl6hM0Tp0OfH3YmF0RXJfipuljyFmWpqVTC+aJafHX8t69J/Uduc6M3hKWi4VJIZI2DzaRxdpVjZ8fb862Cw==" + }, + "blru": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.1.tgz", + "integrity": "sha512-c4QlxUxAskEqYZxy28vT+iS2ZQ2l8+Rzq609Ha30MDnL5kQu4N44LulYMW96TB2Vn1XsjbVcIKIEk09PBtiutw==" + }, + "blst": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.0.tgz", + "integrity": "sha512-PozFN/9YgmwBcDF6H9GS4N3Y9Qp1VTEYkdzwdww6YLpvBLIKzgRrDa7B9inXs3mmWGgRo8N3pCWBPWVjOPScLA==" + }, + "bmutex": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.1.tgz", + "integrity": "sha512-cED+iW4gPUqAxLUjHj+QVH/CHMTb4TXS5mnB1cVwSoEYmUEZQVc0BGVDPrken/Yp8RPu5KVDui44o1++jhXu0A==" }, "bn.js": { "version": "4.11.8", @@ -457,7 +441,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "optional": true, "requires": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -467,11 +450,59 @@ "safe-buffer": "^5.0.1" } }, + "brq": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.1.tgz", + "integrity": "sha512-hRJyN3AJnbPiGudKj/ppJhkM+gaBqBx6FKdE6WLuBD+4jeU9/XQfxn0k79fBKRaXzaJcdNaXtev/2/rbNRYJfA==" + }, + "bs32": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.0.tgz", + "integrity": "sha512-aNTjwcrCMQZ6yBMVwvVh0G5xzhbWJCm8mbTerxx52SCkOmIAZipBJUfOF29aliU88Za0gB+BfZr8hBNss9j43g==" + }, + "bsip": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.0.tgz", + "integrity": "sha512-+eiWVVRcfcjI9uGg2xF5PpOdM3sUsPcVatpGX48+0XFUzVUv5nPWiEydDTuh6AC0qOjZN2p1SNwisO84Ie7+TQ==", + "requires": { + "bindings": "~1.3.0", + "nan": "~2.10.0" + } + }, + "bsock": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.0.tgz", + "integrity": "sha512-ksIqK8Djyk2Q88gVd8evM54I1tuqQhBZshMLRJ0sjPpoFX0BvquGUFTGC6rKLy9hGWWVVWOqz/2PZei9xqcSYg==", + "requires": { + "faye-websocket": "~0.11.1" + } + }, + "bsocks": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.0.tgz", + "integrity": "sha512-Wq/muS0UO1WfQMQP0KZa/Xt0akpfCNQ7Y+xyPiF15WRcZDbO4wn60wvXIr2sUjqWyGv4MuPePbYW/mYyfwbk7w==", + "requires": { + "binet": "~0.3.0" + } + }, + "bstring": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bstring/-/bstring-0.1.0.tgz", + "integrity": "sha512-uOgKi6gitLAbnmNk+VJQi3LDLd3DU6lxqaVR/3HOHboCuhYdqPJA/fhuB5O6XGbYfzRt/IJyx8NsEKPGyTtGIQ==", + "requires": { + "bindings": "~1.3.0", + "nan": "~2.10.0" + } + }, + "btcp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.0.tgz", + "integrity": "sha512-JJMuuYT/BHuX2SUKBBXvk8F9HSC+ng8HA842zCELhtQFytzQ0l2G2xUMnJ3WK8maIW0TOyk5Ssu/sZlkZtAP3g==" + }, "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "optional": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -480,14 +511,12 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "optional": true + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "optional": true + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" }, "buffer-from": { "version": "1.1.0", @@ -498,19 +527,39 @@ "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "optional": true + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + "bufio": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bufio/-/bufio-0.2.0.tgz", + "integrity": "sha512-PjL1QglhgZCWEKWbxzlVB4ExvNorHMu0JSu4ehzeKi38R74Fp7duHAl8xNEqsbJXP5Dfym7XuSEkVol1KX5mhw==" + }, + "bupnp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.1.tgz", + "integrity": "sha512-KKdgJF8RXjbhWL1e7szjAlF1akYYUZeb0RMn/oNsOeIoVlNdd+fIBd6v3V2+YZfPjJbDb/5Et5KyzfvhJ5QP9w==", + "requires": { + "binet": "~0.3.0", + "brq": "~0.1.0" + } + }, + "bval": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.1.tgz", + "integrity": "sha512-Yj2q9+RRSsbKhrmleGp/bXYV9NBM3pjBQJGsJ+8SM60YQREMLLr3Nz7wogao73ki7khYuLz+b33qCGv6685k3A==" + }, + "bweb": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.1.tgz", + "integrity": "sha512-+Yf/R/54hDradHivlmogZAVe8BnOI6U5T9hP3pbGxhGUQqBYapaAYP1/t8PwY6CFvrB3UNc6KYjKfv1DIicAdw==", + "requires": { + "bsock": "~0.1.0" + } }, "chownr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "optional": true + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" }, "cipher-base": { "version": "1.0.4", @@ -532,23 +581,6 @@ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "optional": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "optional": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -560,12 +592,6 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "optional": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -587,7 +613,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "optional": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -610,7 +635,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "optional": true, "requires": { "mimic-response": "^1.0.0" } @@ -618,20 +642,17 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "optional": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "optional": true + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "optional": true + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, "diff": { "version": "3.5.0", @@ -643,7 +664,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "optional": true, "requires": { "browserify-aes": "^1.0.6", "create-hash": "^1.1.2", @@ -672,74 +692,6 @@ "once": "^1.4.0" } }, - "engine.io": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", - "optional": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "uws": "~9.14.0", - "ws": "~3.3.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "optional": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "engine.io-client": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", - "optional": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "optional": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary2": "~1.0.2" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1908,27 +1860,18 @@ } }, "eslint-plugin-flowtype": { - "version": "2.49.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.49.3.tgz", - "integrity": "sha512-wO0S4QbXPReKtydxbY5A0UieOaF9jBO5BMuxYPQOTa082JCpKEoC7+o3fnKsVVycwX47lvqLiUGRsWauCiA9aw==", + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.0.tgz", + "integrity": "sha512-10FnBXCp8odYcpUFXGAh+Zko7py0hUWutTd3BN/R9riukH360qNPLYPR3/xV9eu9K7OJDjJrsflBnL6RwxFnlw==", "dev": true, "requires": { "lodash": "^4.17.10" - }, - "dependencies": { - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - } } }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "optional": true, "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -1937,14 +1880,20 @@ "expand-template": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz", - "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==", - "optional": true + "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==" }, "fast-future": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", - "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=", - "optional": true + "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=" + }, + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "requires": { + "websocket-driver": ">=0.5.1" + } }, "flow-bin": { "version": "0.45.0", @@ -1979,8 +1928,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "optional": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs.realpath": { "version": "1.0.0", @@ -1992,7 +1940,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -2007,8 +1954,7 @@ "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "optional": true + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" }, "glob": { "version": "7.1.2", @@ -2035,31 +1981,10 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "optional": true + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "hash-base": { "version": "3.0.4", @@ -2071,12 +1996,12 @@ } }, "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", "requires": { "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.1" } }, "he": { @@ -2095,10 +2020,10 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + "http-parser-js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", + "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=" }, "inflight": { "version": "1.0.6", @@ -2118,8 +2043,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "optional": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -2147,32 +2071,23 @@ "dev": true }, "leveldown": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-1.7.2.tgz", - "integrity": "sha1-XjRnuyfuJGpKe429j7KxYgam64s=", - "optional": true, + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-4.0.1.tgz", + "integrity": "sha512-ZlBKVSsglPIPJnz4ggB8o2R0bxDxbsMzuQohbfgoFMVApyTE118DK5LNRG0cRju6rt3OkGxe0V6UYACGlq/byg==", "requires": { - "abstract-leveldown": "~2.6.1", - "bindings": "~1.2.1", + "abstract-leveldown": "~5.0.0", + "bindings": "~1.3.0", "fast-future": "~1.0.2", - "nan": "~2.6.1", - "prebuild-install": "^2.1.0" - }, - "dependencies": { - "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=", - "optional": true - }, - "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", - "optional": true - } + "nan": "~2.10.0", + "prebuild-install": "^4.0.0" } }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -2194,26 +2109,10 @@ "inherits": "^2.0.1" } }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "optional": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "optional": true, - "requires": { - "mime-db": "~1.33.0" - } - }, "mimic-response": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", - "optional": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "minimalistic-assert": { "version": "1.0.1", @@ -2273,27 +2172,30 @@ "supports-color": "5.4.0" } }, + "mrmr": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.0.tgz", + "integrity": "sha512-jwarZT20LbjYM+jvbkciut+fVCz5O5qqGU97a62z6FXst3WHb93QS3kBgdJyed+nc7CXSbAMScjPUcruenRfrQ==", + "requires": { + "bindings": "~1.3.0", + "nan": "~2.10.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, "n64": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/n64/-/n64-0.0.18.tgz", - "integrity": "sha512-z5gRoCNFTY5fderO8n5tt6p7+jZiivzN1LhuR4EqrTkciYDCpJy8xkwkd1YO5eyfimeLAjXy/6k3FLC+GQ6lLw==" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.0.tgz", + "integrity": "sha512-qNXq/YX546Ccv46GLbkGePc6u65Syp2wync+iG5hR4EB4I+QBtxe5lG076sGkni+9lvuPtN3r3Ut/LXm8PxUzA==" }, "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "optional": true - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "optional": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "next-tick": { "version": "1.0.0", @@ -2315,10 +2217,9 @@ } }, "node-abi": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.1.tgz", - "integrity": "sha512-pUlswqpHQ7zGPI9lGjZ4XDNIEUDbHxsltfIRb7dTnYdhgHWHOcB0MLZKLoCz6UMcGzSPG5wGl1HODZVQAUsH6w==", - "optional": true, + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.3.tgz", + "integrity": "sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg==", "requires": { "semver": "^5.4.1" } @@ -2326,14 +2227,12 @@ "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "optional": true + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -2349,14 +2248,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "optional": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "optional": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "once": { "version": "1.4.0", @@ -2369,24 +2261,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "optional": true - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "requires": { - "better-assert": "~1.0.0" - } + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "path-is-absolute": { "version": "1.0.1", @@ -2412,10 +2287,9 @@ } }, "prebuild-install": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.3.tgz", - "integrity": "sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g==", - "optional": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-4.0.0.tgz", + "integrity": "sha512-7tayxeYboJX0RbVzdnKyGl2vhQRWr6qfClEXDhOkXjuaOKCw2q8aiuFhONRYVsG/czia7KhpykIlI2S2VaPunA==", "requires": { "detect-libc": "^1.0.3", "expand-template": "^1.0.2", @@ -2434,11 +2308,15 @@ "which-pm-runs": "^1.0.0" } }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "optional": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -2448,7 +2326,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "optional": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -2456,6 +2333,20 @@ "strip-json-comments": "~2.0.1" } }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -2466,9 +2357,9 @@ } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "samsam": { "version": "1.3.0", @@ -2477,10 +2368,9 @@ "dev": true }, "secp256k1": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.3.0.tgz", - "integrity": "sha512-CbrQoeGG5V0kQ1ohEMGI+J7oKerapLTpivLICBaXR0R4HyQcN3kM9itLsV5fdpV1UR1bD14tOkJ1xughmlDIiQ==", - "optional": true, + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", + "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", "requires": { "bindings": "^1.2.1", "bip66": "^1.1.3", @@ -2489,21 +2379,18 @@ "drbg.js": "^1.0.1", "elliptic": "^6.2.3", "nan": "^2.2.1", - "prebuild-install": "^2.0.0", "safe-buffer": "^5.1.0" } }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "optional": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "optional": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "sha.js": { "version": "2.4.11", @@ -2579,20 +2466,17 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "optional": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", - "optional": true + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" }, "simple-get": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "optional": true, "requires": { "decompress-response": "^3.3.0", "once": "^1.3.1", @@ -2622,95 +2506,6 @@ } } }, - "socket.io": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.3.tgz", - "integrity": "sha1-Q1nwaiSTOua9CHeYr3jGgOrjReM=", - "optional": true, - "requires": { - "debug": "~2.6.6", - "engine.io": "~3.1.0", - "object-assign": "~4.1.1", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "~2.0.2", - "socket.io-parser": "~3.1.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "optional": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", - "optional": true - }, - "socket.io-client": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.3.tgz", - "integrity": "sha1-bK9K/5+FsZ/ZG2zhPWmttWT4hzs=", - "optional": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "optional": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "socket.io-parser": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "has-binary2": "~1.0.2", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - } - } - }, "sorted-set": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", @@ -2726,6 +2521,14 @@ "strip-ansi": "^3.0.0" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -2737,8 +2540,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "optional": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { "version": "5.4.0", @@ -2758,10 +2560,9 @@ } }, "tar-fs": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz", - "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==", - "optional": true, + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", "requires": { "chownr": "^1.0.1", "mkdirp": "^0.5.1", @@ -2773,7 +2574,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", - "optional": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -2785,7 +2585,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", - "optional": true, "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.1.0", @@ -2794,38 +2593,6 @@ "readable-stream": "^2.3.0", "to-buffer": "^1.1.0", "xtend": "^4.0.0" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "text-encoding": { @@ -2834,23 +2601,15 @@ "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", "dev": true }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "optional": true - }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "optional": true + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "optional": true, "requires": { "safe-buffer": "^5.0.1" } @@ -2861,33 +2620,34 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "uws": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", - "optional": true + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" }, "which-pm-runs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "optional": true + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "optional": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -2897,32 +2657,10 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "optional": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "optional": true } } } diff --git a/package.json b/package.json index 0e39224..2cbee05 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "devDependencies": { "babel-eslint": "^7.2.3", "eslint": "^3.19.0", - "eslint-plugin-flowtype": "^2.33.0", + "eslint-plugin-flowtype": "^2.50.0", "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.0", "mocha": "^5.2.0", @@ -38,7 +38,7 @@ "sinon": "^5.1.1" }, "dependencies": { - "bcoin": "^1.0.0-beta.15", + "bcoin": "^1.0.2", "graph-theory-ford-fulkerson": "^1.0.0", "sorted-set": "^0.3.0" } From e26ce839276cbea0777c56bee51996e29a2863bb Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 15 Jul 2018 19:04:14 +0100 Subject: [PATCH 467/540] Change full,spv nodes' types to capitalized --- flow-typed/npm/bcoin_vx.x.x.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index f734800..9fceeb9 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -182,8 +182,8 @@ declare module 'bcoin' { node : { NodeClient : Class }, - fullnode : Class, - spvnode : Class, + FullNode : Class, + SPVNode : Class, script : Class, pool : Class, wallet : { From b760f21a6262b03e04549c6417e063f6f3177867 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 15 Jul 2018 22:22:46 +0100 Subject: [PATCH 468/540] Capitalize Script, Network --- flow-typed/npm/bcoin_vx.x.x.js | 2 +- src/direct_trust.js | 2 +- src/full_node.js | 2 +- src/spv_node.js | 2 +- src/trust_is_risk.js | 10 +++++----- test/full_node.js | 4 ++-- test/helpers.js | 6 +++--- test/spv_node.js | 4 ++-- test/trust_is_risk.js | 6 +++--- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 9fceeb9..e611d9a 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -184,7 +184,7 @@ declare module 'bcoin' { }, FullNode : Class, SPVNode : Class, - script : Class, + Script : Class, pool : Class, wallet : { Wallet : Class, diff --git a/src/direct_trust.js b/src/direct_trust.js index b5547c7..fb635d9 100644 --- a/src/direct_trust.js +++ b/src/direct_trust.js @@ -1,6 +1,6 @@ // @flow import type {Entity, Key} from "./types"; -import type {script} from "bcoin"; +import type {Script} from "bcoin"; var assert = require("assert"); var helpers = require("./helpers"); diff --git a/src/full_node.js b/src/full_node.js index cd5d135..ab18978 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -3,7 +3,7 @@ var bcoin = require("bcoin"); var walletPlugin = bcoin.wallet.plugin; var TrustIsRisk = require("./trust_is_risk"); -class FullNode extends bcoin.fullnode { +class FullNode extends bcoin.FullNode { trust : TrustIsRisk constructor(options : Object) { diff --git a/src/spv_node.js b/src/spv_node.js index d543a44..0beed64 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -4,7 +4,7 @@ var walletPlugin = bcoin.wallet.plugin; var TrustIsRisk = require("./trust_is_risk"); var tag = require("./tag"); -class SPVNode extends bcoin.spvnode { +class SPVNode extends bcoin.SPVNode { trust : TrustIsRisk constructor(options : Object) { diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 14dbc69..8c2262a 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -10,7 +10,7 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var Coin = bcoin.primitives.Coin; -var Script = bcoin.script; +var Script = bcoin.Script; var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); @@ -89,7 +89,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [ new Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, dest, tag]), + script: bcoin.Script.fromMultisig(1, 3, [originPubKey, dest, tag]), value: trustAmount }) ] @@ -99,7 +99,7 @@ class TrustIsRisk { assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), + script: bcoin.Script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), value: changeAmount })); } @@ -172,7 +172,7 @@ class TrustIsRisk { var mtx = new MTX({ outputs: [new Output({ - script: bcoin.script.fromPubkeyhash(Address.fromString(payee).hash), + script: bcoin.Script.fromPubkeyhash(Address.fromString(payee).hash), value: ((decreaseAmount - fee) < 0) ? 0 : (decreaseAmount - fee) })] // TODO: do not add this output if its value is 0 }); @@ -180,7 +180,7 @@ class TrustIsRisk { var remainingTrustAmount = directTrust.amount - decreaseAmount; if (remainingTrustAmount > 0) { mtx.addOutput(new Output({ - script: bcoin.script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, tag]), + script: bcoin.Script.fromMultisig(1, 3, [directTrust.origin, directTrust.dest, tag]), value: remainingTrustAmount })); } diff --git a/test/full_node.js b/test/full_node.js index 0b250e6..ae476d4 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -34,11 +34,11 @@ describe("FullNode", () => { beforeEach("prepare node", async () => { for (let name in fixtures.keyRings) { - fixtures.keyRings[name].network = bcoin.network.get(); + fixtures.keyRings[name].network = bcoin.Network.get(); } node = new Trust.FullNode({ - network: bcoin.network.get().toString(), + network: bcoin.Network.get().toString(), passphrase: "secret" }); diff --git a/test/helpers.js b/test/helpers.js index e8afca7..f500ab4 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -56,7 +56,7 @@ var testHelpers = { getP2PKHOutput: (dest, value) => { var address = bcoin.primitives.Address.fromString(dest); - var script = bcoin.script.fromPubkeyhash(address.hash); + var script = bcoin.Script.fromPubkeyhash(address.hash); return new bcoin.primitives.Output({script, value}); }, @@ -71,7 +71,7 @@ var testHelpers = { return new bcoin.primitives.Input({ prevout, - script: bcoin.script.fromString( + script: bcoin.Script.fromString( // Don't care about the signature "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 " + testHelpers.bufferToScript(pubKey)) @@ -80,7 +80,7 @@ var testHelpers = { getOneOfThreeMultisigOutput: (originPubKey, destPubKey, value) => { return new bcoin.primitives.Output({ - script: bcoin.script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), + script: bcoin.Script.fromMultisig(1, 3, [originPubKey, destPubKey, tag]), value }); }, diff --git a/test/spv_node.js b/test/spv_node.js index 895ed6a..40b2a58 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -34,7 +34,7 @@ describe("SPVNode", () => { beforeEach("create SPV node", async () => { spvNode = new Trust.SPVNode({ - network: bcoin.network.get().toString(), + network: bcoin.Network.get().toString(), httpPort: 48445, passphrase: "secret", // logConsole: true, @@ -54,7 +54,7 @@ describe("SPVNode", () => { beforeEach("create full node", async () => { miner = new Trust.FullNode({ - network: bcoin.network.get().toString(), + network: bcoin.Network.get().toString(), httpPort: 48448, bip37: true, listen: true, diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index e31b987..ef949f7 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -41,8 +41,8 @@ var node, tir, walletDB, wallet, trustIncreasingMTX, trustDecreasingMTX, trustIncreasingTX; setupTest = async (isFullNode) => { - const nodeClass = bcoin[isFullNode? "fullnode" : "spvnode"]; - node = new nodeClass({network: bcoin.network.get().toString()}); + const nodeClass = bcoin[isFullNode? "FullNode" : "SPVNode"]; + node = new nodeClass({network: bcoin.Network.get().toString()}); node.use(walletPlugin); tir = new Trust.TrustIsRisk(node); walletDB = node.require("walletdb"); @@ -57,7 +57,7 @@ setupTest = async (isFullNode) => { hash: trustIncreasingTX.hash().toString("hex"), index: 0 }, - script: bcoin.script.fromString( + script: bcoin.Script.fromString( // 17P8kCbDBPmqLDCCe9dYwbfiEDaRb5xDYE "0x47 0x3044022035e32834c6ee4db1696cc06762feca2809d865ca12a3b98c801f3f451341a2570220573bf3ffef55f2651e1563acc0a22f8056222f277f5ddf17dd583d4edd40fa6001 0x21 0x02b8f07a401eca4888039b1898f94db44c43ccc6d3aa8b27e9b6ed7b377b24c083") }); From 4a5b195318e716e853e55214c260ca864cd049ca Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 15 Jul 2018 22:24:19 +0100 Subject: [PATCH 469/540] Use bcrypto Hash160 and secp256k1 --- flow-typed/npm/bcoin_vx.x.x.js | 4 ---- flow-typed/npm/bcrypto_vx.x.x.js | 14 ++++++++++++++ src/helpers.js | 4 +++- src/trust_is_risk.js | 3 ++- test/spv_node.js | 3 ++- test/trust_is_risk.js | 7 ++++--- 6 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 flow-typed/npm/bcrypto_vx.x.x.js diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index e611d9a..042d0ff 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -201,10 +201,6 @@ declare module 'bcoin' { KeyRing : Class, Coin : Class }, - crypto : { - hash160(str : (string | Buffer)) : Hash, - hash256(str : (string | Buffer)) : Hash - }, base58 : { encode(str : (string | Buffer)) : Buffer }, diff --git a/flow-typed/npm/bcrypto_vx.x.x.js b/flow-typed/npm/bcrypto_vx.x.x.js new file mode 100644 index 0000000..2a113f7 --- /dev/null +++ b/flow-typed/npm/bcrypto_vx.x.x.js @@ -0,0 +1,14 @@ +declare class bcrypto$Hash160 { + static digest(data : (string | Buffer)) : Hash +} + +declare class bcrypto$secp256k1 { + publicKeyCreate(key : Buffer, bool: boolean) : Buffer; +} + +declare module 'bcrypto' { + declare module.exports: { + Hash160 : Class, + secp256k1 : Class + } +} diff --git a/src/helpers.js b/src/helpers.js index 7418960..e2a2549 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,6 +1,8 @@ // @flow import type {Entity, TXHash, Key} from "./types"; var bcoin = require("bcoin"); +var bcrypto = require("bcrypto"); +var hash160 = bcrypto.Hash160; var Address = bcoin.primitives.Address; class NodeWatcher { @@ -105,7 +107,7 @@ var helpers = { NodeWatcher : NodeWatcher, pubKeyToEntity: (key : Key, network : bcoin$Network) : Entity => { - return Address.fromHash(bcoin.crypto.hash160(key), + return Address.fromHash(hash160.digest(key), Address.types.PUBKEYHASH, -1, network).toString(); }, diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index 8c2262a..a8a7dc9 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -1,6 +1,7 @@ // @flow import type {Entity, TXHash, Key} from "./types"; var bcoin = require("bcoin"); +var bcrypto = require("bcrypto"); var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var WalletDB = bcoin.wallet.WalletDB; @@ -99,7 +100,7 @@ class TrustIsRisk { assert(changeAmount >= 0); if (changeAmount) { mtx.addOutput(new Output({ - script: bcoin.Script.fromPubkeyhash(bcoin.crypto.hash160(originPubKey)), + script: bcoin.Script.fromPubkeyhash(bcrypto.Hash160.digest(originPubKey)), value: changeAmount })); } diff --git a/test/spv_node.js b/test/spv_node.js index 40b2a58..8f40c8a 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -1,6 +1,7 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); +var bcrypto = require("bcrypto"); var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -8,7 +9,7 @@ var MTX = bcoin.primitives.MTX; var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; -var secp256k1 = bcoin.crypto.secp256k1; +var secp256k1 = bcrypto.secp256k1; var tag = require("../lib/tag"); var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index ef949f7..450f0ba 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -1,6 +1,8 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin"); +var bcrypto = require("bcrypto"); +var secp256k1 = bcrypto.secp256k1; var Coin = bcoin.primitives.Coin; var Address = bcoin.primitives.Address; var Input = bcoin.primitives.Input; @@ -11,7 +13,6 @@ var TXRecord = bcoin.wallet.records.TXRecord; var testHelpers = require("./helpers"); var tag = require("../lib/tag"); var consensus = require("bcoin/lib/protocol/consensus"); -var secp256k1 = require("bcoin/lib/crypto/secp256k1"); var sinon = require("sinon"); var should = require("should"); var fixtures = require("./fixtures"); @@ -34,7 +35,7 @@ for (let [name, keyRing] of Object.entries(fixtures.keyRings)) { // Add base58 address variables to scope. for (name in fixtures.keyRings) { var keyRing = fixtures.keyRings[name]; - eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcoin.crypto.hash160(keyRing.getPublicKey())).toString()}";`); + eval(`var ${name} = "${bcoin.primitives.Address.fromHash(bcrypto.Hash160.digest(keyRing.getPublicKey())).toString()}";`); } var node, tir, walletDB, wallet, @@ -80,7 +81,7 @@ tearDownTest = async () => { describe("tag", () => { it("corresponds to a valid public key", () => { Buffer.isBuffer(tag).should.be.true(); - secp256k1.publicKeyVerify(tag).result.should.be.true(); + secp256k1.publicKeyVerify(tag).should.be.true(); }); it("is a valid bitcoin address", () => { From f9835e230a91887795ee99895f03a65dde23c30d Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 15 Jul 2018 22:24:55 +0100 Subject: [PATCH 470/540] Use node.require("walletdb").wdb --- test/full_node.js | 2 +- test/spv_node.js | 4 ++-- test/trust_is_risk.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index ae476d4..a21ea28 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -43,7 +43,7 @@ describe("FullNode", () => { }); await node.initialize(); - walletDB = node.require("walletdb"); + walletDB = node.require("walletdb").wdb; node.startSync(); wallet = await testHelpers.createWallet(walletDB, "wallet"); diff --git a/test/spv_node.js b/test/spv_node.js index 8f40c8a..fd043f0 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -50,7 +50,7 @@ describe("SPVNode", () => { beforeEach("connect SPV node, create walletDB", async () => { await spvNode.initialize(); - spvWalletDB = spvNode.require("walletdb"); + spvWalletDB = spvNode.require("walletdb").wdb; }); beforeEach("create full node", async () => { @@ -69,7 +69,7 @@ describe("SPVNode", () => { beforeEach("connect full node, create walletDB", async () => { await miner.initialize(); - minerWalletDB = miner.require("walletdb"); + minerWalletDB = miner.require("walletdb").wdb; }); beforeEach("start syncing", () => { diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 450f0ba..116987d 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -46,7 +46,7 @@ setupTest = async (isFullNode) => { node = new nodeClass({network: bcoin.Network.get().toString()}); node.use(walletPlugin); tir = new Trust.TrustIsRisk(node); - walletDB = node.require("walletdb"); + walletDB = node.require("walletdb").wdb; await node.open(); wallet = await testHelpers.createWallet(walletDB, "wallet"); From 3793324845573b3045d3deda0d2f3b815c528243 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 16 Jul 2018 22:13:11 +0100 Subject: [PATCH 471/540] Update multisig_tx minimal testcase for new bcoin --- minimal_testcases/multisig_tx.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index 3b4fa26..c1fb673 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -2,6 +2,7 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); + var bcrypto = require("bcrypto"); var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -9,7 +10,7 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; - var secp256k1 = bcoin.crypto.secp256k1; + var secp256k1 = bcrypto.secp256k1; var tag = require("../lib/tag"); var testHelpers = require("../test/helpers"); var consensus = require("bcoin/lib/protocol/consensus"); @@ -31,7 +32,7 @@ consensus.COINBASE_MATURITY = 0; spvNode = new Trust.SPVNode({ - network: bcoin.network.get().toString(), + network: bcoin.Network.get().toString(), httpPort: 48445, passphrase: "secret", // logConsole: true, @@ -43,7 +44,7 @@ spvWalletDB = spvNode.require("walletdb"); miner = new Trust.FullNode({ - network: bcoin.network.get().toString(), + network: bcoin.Network.get().toString(), httpPort: 48448, bip37: true, listen: true, From a6db5e0c6f3513e414331287056cf21a4235f521 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 17 Jul 2018 23:56:02 +0100 Subject: [PATCH 472/540] Use wdb the new way --- minimal_testcases/multisig_tx.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index c1fb673..a60fba8 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -41,7 +41,7 @@ }); await spvNode.initialize(); - spvWalletDB = spvNode.require("walletdb"); + spvWalletDB = spvNode.require("walletdb").wdb; miner = new Trust.FullNode({ network: bcoin.Network.get().toString(), @@ -51,8 +51,9 @@ passphrase: "secret" }); +debugger; await miner.initialize(); - minerWalletDB = miner.require("walletdb"); + minerWalletDB = miner.require("walletdb").wdb; miner.startSync(); spvNode.startSync(); From d1eece6df629e52805e7b6e1c2a3d240316c6a66 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 18 Jul 2018 00:21:28 +0100 Subject: [PATCH 473/540] Add port for wallet Would work only with the PR in the comment --- minimal_testcases/multisig_tx.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index a60fba8..db355d7 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -34,6 +34,8 @@ spvNode = new Trust.SPVNode({ network: bcoin.Network.get().toString(), httpPort: 48445, + walletHttpPort: 48449, // works with PR + // https://github.com/bcoin-org/bcfg/pull/1 passphrase: "secret", // logConsole: true, // logLevel: "debug", From ba867073b03388e7dc16eff81305333ac7501d48 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 19 Jul 2018 00:27:41 +0100 Subject: [PATCH 474/540] Use internal WalletDB instead of plugin --- minimal_testcases/multisig_tx.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index db355d7..5d8cc88 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -3,6 +3,8 @@ var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); var bcrypto = require("bcrypto"); + var WalletDB = bcoin.wallet.WalletDB; + var NodeClient = bcoin.wallet.NodeClient; var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -43,7 +45,12 @@ }); await spvNode.initialize(); - spvWalletDB = spvNode.require("walletdb").wdb; + + spvWalletDB = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(spvNode) + }); + await spvWalletDB.open(); miner = new Trust.FullNode({ network: bcoin.Network.get().toString(), @@ -53,9 +60,13 @@ passphrase: "secret" }); -debugger; await miner.initialize(); - minerWalletDB = miner.require("walletdb").wdb; + + minerWalletDB = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(miner) + }); + await minerWalletDB.open(); miner.startSync(); spvNode.startSync(); From 429a28714c16762021c78a22a3fcc3ac0c6d3c7d Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 21 Jul 2018 00:16:34 +0100 Subject: [PATCH 475/540] Use default account the new way --- minimal_testcases/multisig_tx.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index 5d8cc88..4cc1d85 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -97,8 +97,10 @@ minerWallets[name] = await testHelpers.createWallet( minerWalletDB, name ); + account = await minerWallets[name].getAccount('default'); + rings[name] = await minerWallets[name].getPrivateKey( - minerWallets[name].getAddress("base58"), "secret" + account.receiveAddress(), "secret" ); addresses[name] = helpers.pubKeyToEntity( rings[name].getPublicKey(), miner.network @@ -110,8 +112,10 @@ spvWallets[name] = await testHelpers.createWallet( spvWalletDB, name ); + account = await spvWallets[name].getAccount('default'); + rings[name] = await spvWallets[name].getPrivateKey( - spvWallets[name].getAddress("base58"), "secret" + account.receiveAddress(), "secret" ); addresses[name] = helpers.pubKeyToEntity( rings[name].getPublicKey(), spvNode.network From 732f9e74cfba5c9a6524a35ac8fc0000afde3a80 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 21 Jul 2018 00:16:53 +0100 Subject: [PATCH 476/540] Use script and hash160 the new way --- minimal_testcases/multisig_tx.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index 4cc1d85..a431fcd 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -5,7 +5,7 @@ var bcrypto = require("bcrypto"); var WalletDB = bcoin.wallet.WalletDB; var NodeClient = bcoin.wallet.NodeClient; - var Script = bcoin.script; + var Script = bcoin.script.Script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; @@ -157,7 +157,7 @@ (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160( + script: Script.fromPubkeyhash(bcrypto.Hash160.digest( rings["alice"].publicKey)), value: changeAmount * consensus.COIN })); From 4b3d5cb0cf5671f743d9a1f8b80ffb4d5a50e062 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 21 Jul 2018 00:19:57 +0100 Subject: [PATCH 477/540] Remove redundant wallet port --- minimal_testcases/multisig_tx.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index a431fcd..48b94dc 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -36,8 +36,6 @@ spvNode = new Trust.SPVNode({ network: bcoin.Network.get().toString(), httpPort: 48445, - walletHttpPort: 48449, // works with PR - // https://github.com/bcoin-org/bcfg/pull/1 passphrase: "secret", // logConsole: true, // logLevel: "debug", From 67faf2255b3f676223e2f5e609e27ba4d5a86699 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 24 Jul 2018 20:56:36 +0100 Subject: [PATCH 478/540] Debug bcoin node handshake packet reject Write a minimal testcase where the rejection of a packet on handshake appears --- minimal_testcases/magicno.js | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 minimal_testcases/magicno.js diff --git a/minimal_testcases/magicno.js b/minimal_testcases/magicno.js new file mode 100644 index 0000000..ef5c3f3 --- /dev/null +++ b/minimal_testcases/magicno.js @@ -0,0 +1,41 @@ +const bcoin = require("bcoin").set("regtest"); + +async function delay(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); +} + +const one = new bcoin.FullNode({ + network: bcoin.Network.get().toString(), + //logConsole: true, + //logLevel: "debug", + nodes: ["127.0.0.1:48448"] +}); + +const two = new bcoin.FullNode({ + network: bcoin.Network.get().toString(), + httpPort: 48448 +}); + +(async () => { +if (one.pool.peers.head()) console.log("1",one.pool.peers.head().socket._events.drain); + await one.open() +if (one.pool.peers.head()) console.log("2",one.pool.peers.head().socket._events.drain); + await one.connect(); +if (one.pool.peers.head()) console.log("3",one.pool.peers.head().socket._events.drain); + + await two.open(); +if (one.pool.peers.head()) console.log("4",one.pool.peers.head().socket._events.drain); + await two.connect(); +if (one.pool.peers.head()) console.log("5",one.pool.peers.head().socket._events.drain); + + await delay(3000); +if (one.pool.peers.head()) console.log("6",one.pool.peers.head().socket._events.drain); + + await two.disconnect(); + await two.close(); + + await one.disconnect(); + await one.close(); +})(); From c1d7a041775caec4e9d4b2588e7de24d7f4355c1 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 25 Jul 2018 00:37:29 +0100 Subject: [PATCH 479/540] Add missing let --- minimal_testcases/multisig_tx.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/minimal_testcases/multisig_tx.js b/minimal_testcases/multisig_tx.js index 48b94dc..7d5aa1e 100644 --- a/minimal_testcases/multisig_tx.js +++ b/minimal_testcases/multisig_tx.js @@ -95,7 +95,7 @@ minerWallets[name] = await testHelpers.createWallet( minerWalletDB, name ); - account = await minerWallets[name].getAccount('default'); + let account = await minerWallets[name].getAccount('default'); rings[name] = await minerWallets[name].getPrivateKey( account.receiveAddress(), "secret" @@ -110,7 +110,7 @@ spvWallets[name] = await testHelpers.createWallet( spvWalletDB, name ); - account = await spvWallets[name].getAccount('default'); + let account = await spvWallets[name].getAccount('default'); rings[name] = await spvWallets[name].getPrivateKey( account.receiveAddress(), "secret" From 6f21f9feeb1e2093f4fde1184eeb20ba7acb07cf Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 25 Jul 2018 00:45:11 +0100 Subject: [PATCH 480/540] Remove console.log()s --- minimal_testcases/magicno.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/minimal_testcases/magicno.js b/minimal_testcases/magicno.js index ef5c3f3..2bf1026 100644 --- a/minimal_testcases/magicno.js +++ b/minimal_testcases/magicno.js @@ -19,19 +19,13 @@ const two = new bcoin.FullNode({ }); (async () => { -if (one.pool.peers.head()) console.log("1",one.pool.peers.head().socket._events.drain); await one.open() -if (one.pool.peers.head()) console.log("2",one.pool.peers.head().socket._events.drain); await one.connect(); -if (one.pool.peers.head()) console.log("3",one.pool.peers.head().socket._events.drain); await two.open(); -if (one.pool.peers.head()) console.log("4",one.pool.peers.head().socket._events.drain); await two.connect(); -if (one.pool.peers.head()) console.log("5",one.pool.peers.head().socket._events.drain); await delay(3000); -if (one.pool.peers.head()) console.log("6",one.pool.peers.head().socket._events.drain); await two.disconnect(); await two.close(); From 9991ebc689b6ee9b709d5e7a193dae8ead3c2a50 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 25 Jul 2018 00:45:38 +0100 Subject: [PATCH 481/540] Rebuild modules --- package-lock.json | 217 ++++++++++++++++++++++++++++------------------ 1 file changed, 133 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb1a227..a713dc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -256,17 +256,21 @@ "dev": true }, "bcfg": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.0.tgz", - "integrity": "sha512-Kk5TJRbjnX5irARDolBmbMzjj0Nc3uXeg0kqOJW1iDUA0+l7rDS8SNTAEd0s4hCENK2X626ZelQCA2TurDpFRA==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.2.tgz", + "integrity": "sha512-vKp2Pqf8z4wk9213SQPv307/qh4bI6NPmYlW4rtTLPeNrkHMWNn2dLpxHQ4Fe/CganPcoR0xKZDopFKYeneQKw==", + "requires": { + "bsert": "~0.0.3" + } }, "bclient": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.1.tgz", - "integrity": "sha512-x7OhFmlR3G/XBWE8wowh2ZK0YjYTkEuS0+QLMFrkMGn74xpdjvAYRELSQa8aTtoBZjSfXWRQ2baerVc3DKnvHg==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.3.tgz", + "integrity": "sha512-XPnREmUZLYc0mYy8rxUGsO+VIGXQuLfx+cauqKrq2apzMWxHGs5aTpI3agKgrf2aa3JpWUIFbPpKuItwsYcQWw==", "requires": { - "bcfg": "~0.1.0", - "bcurl": "~0.1.1" + "bcfg": "~0.1.2", + "bcurl": "~0.1.2", + "bsert": "~0.0.3" } }, "bcoin": { @@ -316,36 +320,44 @@ } }, "bcurl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.1.tgz", - "integrity": "sha512-yPRWseKphdB9KZEkx/VGncr7PHlZtyIc30S4PwGlVTLvSQAAMSk5PcUCrUf3r3ny4ZBOAhf5hrHLqSUUTWSwtw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.2.tgz", + "integrity": "sha512-VrOb7DzrByO8Aazqic65HVPS51R/JNu/IbUY4ozu3zaft7dcpDgkE9GFRHc1dBeI5urj22ehLWw8/ZcDeh29wg==", "requires": { - "brq": "~0.1.1", - "bsock": "~0.1.0" + "brq": "~0.1.2", + "bsert": "~0.0.3", + "bsock": "~0.1.1" } }, "bdb": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bdb/-/bdb-0.2.2.tgz", - "integrity": "sha512-xhAlkaONuXezzHkvEVUrbNpriv5iq4aoy+Zaf0M8iSPEdtzZKr6eA68xl9fxKY3gVNYxOqLgbphtd6PqZOMXaA==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/bdb/-/bdb-0.2.3.tgz", + "integrity": "sha512-GOfUit8Rq9Y5pUuD3N4zFdZ99sXfswj7QIoFyKQnqq0zmLeQ7riJcpReJZadluOWOmQovzNij75kgA/zlKRnsw==", "requires": { + "bsert": "~0.0.3", "leveldown": "4.0.1" } }, "bdns": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.0.tgz", - "integrity": "sha512-rlAUuoa+wxdvsZzyGZJYbpWLys9hE2J40IMhH+RIWO2BfpsmFVi0nD9NNJwAuFY/51xjLODkF5RTAb8llQNdGA==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.1.tgz", + "integrity": "sha512-XnZAjI4DOlwYW7V4uhekGXOwTmJ3zSZtG5iHybqTPTSFwh1XsxZreXcKLoPZcvBz7v+vqo934JMYPprmtc62lA==", + "requires": { + "bsert": "~0.0.3" + } }, "bevent": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.0.tgz", - "integrity": "sha512-SjN5/WFO7BFtFJ9ThXlI+fmkcEpcH2LuyMGB3cqT97i13J/Z6fZYDfwcoy9uua2mEtS8d/wI5r6EuUBySW33og==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.1.tgz", + "integrity": "sha512-0CbDBnwxyqSdO/63kOi190mHNYpbG1bS7OBNl/PdbA2tHk5ewMfdZaaU+njn9kgr23NGbdoocfXR5Wo7bjYsIg==", + "requires": { + "bsert": "~0.0.3" + } }, "bfile": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.0.tgz", - "integrity": "sha512-EUS2HiB25FPKlcP9QCtzOKnew5eQQGs0+xtk/3b31WevFlEiFvy9yPyhcb+QR77LAOrjDLaKsb9AevzU2p9tlg==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.1.tgz", + "integrity": "sha512-BzQX3loGHgVKfu4KhZ1lI3yaZeBSFar6kKBJNTBCtI+SvYhXn4OALgCxX0C0/9Ca39vjcSkwLhOLMZZGoC0F6g==" }, "bfilter": { "version": "0.2.0", @@ -357,9 +369,12 @@ } }, "bheep": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.0.tgz", - "integrity": "sha512-AS83MBzYDL3fQ8lRdSWUysa8fsTibtXXEuvnUfYKWnyQx4mfKsrg3SeNCODXoa+S8M85Tzxfej7ylBV67dj7mQ==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.1.tgz", + "integrity": "sha512-kDgcu6BXj/6XsCc+fjjo9ViRETdkQqt0FYxQR+ZqQ4edbWE6x8o51k/BwzqkXWPHrsB2/qLjsgnnMPezJvSnpw==", + "requires": { + "bsert": "~0.0.3" + } }, "bindings": { "version": "1.3.0", @@ -367,11 +382,12 @@ "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" }, "binet": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.0.tgz", - "integrity": "sha512-gKyPRu3UO3/dmaIXWq238XD/EDTEmye2kFXTBTWPEO3QOaEaxC03evkDcVn7ma0GUi1zYvN9coTaQDOml21q6A==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.1.tgz", + "integrity": "sha512-4ZCsooGoTYG6BwikD1bjXStzhR5wZnc16CA13cm6ot3jsN3Ridrj7G02sL2yzXTegXILIZy25Au+RHqC8F/jzQ==", "requires": { - "bs32": "~0.1.0" + "bs32": "~0.1.1", + "bsert": "~0.0.3" } }, "bip66": { @@ -392,24 +408,36 @@ } }, "blgr": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.0.tgz", - "integrity": "sha512-Bbrl6hM0Tp0OfH3YmF0RXJfipuljyFmWpqVTC+aJafHX8t69J/Uduc6M3hKWi4VJIZI2DzaRxdpVjZ8fb862Cw==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.1.tgz", + "integrity": "sha512-paJmBPpsYYllidj7UvFvkrwtr2j6YLo7tmk0J885iY4Zw0ZFquV+OVtjDTpTOdeSFJefdi5URGrzOkrFm4M8QQ==", + "requires": { + "bsert": "~0.0.3" + } }, "blru": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.1.tgz", - "integrity": "sha512-c4QlxUxAskEqYZxy28vT+iS2ZQ2l8+Rzq609Ha30MDnL5kQu4N44LulYMW96TB2Vn1XsjbVcIKIEk09PBtiutw==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.2.tgz", + "integrity": "sha512-S3rvHlFMFYOZT+1gQct44FLIeNjf51RZBUWunuMXb7GDREtI98m6MxBVjdfxYKrdIX5YI8gY4FrVLCq59oQeXQ==", + "requires": { + "bsert": "~0.0.3" + } }, "blst": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.0.tgz", - "integrity": "sha512-PozFN/9YgmwBcDF6H9GS4N3Y9Qp1VTEYkdzwdww6YLpvBLIKzgRrDa7B9inXs3mmWGgRo8N3pCWBPWVjOPScLA==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.1.tgz", + "integrity": "sha512-avNp9dO3fXFObDYqh8rY12uUenbLLZaySKIKI32Mlq1czTw7Szah9nzQsMh5ejmkBsR3FjUyuWczGzi4o8BVdQ==", + "requires": { + "bsert": "~0.0.3" + } }, "bmutex": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.1.tgz", - "integrity": "sha512-cED+iW4gPUqAxLUjHj+QVH/CHMTb4TXS5mnB1cVwSoEYmUEZQVc0BGVDPrken/Yp8RPu5KVDui44o1++jhXu0A==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.2.tgz", + "integrity": "sha512-H5mZOJQgtK2SMPStn0Zgo+Z/5jf71ZPSblcsepqf4MGa9SrJRsL6jF4jWLlgayGtq6DCAfRuHokZC+WRoHn+AA==", + "requires": { + "bsert": "~0.0.3" + } }, "bn.js": { "version": "4.11.8", @@ -451,53 +479,68 @@ } }, "brq": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.1.tgz", - "integrity": "sha512-hRJyN3AJnbPiGudKj/ppJhkM+gaBqBx6FKdE6WLuBD+4jeU9/XQfxn0k79fBKRaXzaJcdNaXtev/2/rbNRYJfA==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.2.tgz", + "integrity": "sha512-YE+G82KUl6HWScDfS3gGCxqGv4CsL+LI3K8oKtzZQVjvGu+LqgbRboT+6dCgXhaWRTTZXCaAsRdzK2tCemdcyw==", + "requires": { + "bsert": "~0.0.3" + } }, "bs32": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.0.tgz", - "integrity": "sha512-aNTjwcrCMQZ6yBMVwvVh0G5xzhbWJCm8mbTerxx52SCkOmIAZipBJUfOF29aliU88Za0gB+BfZr8hBNss9j43g==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.1.tgz", + "integrity": "sha512-mvHV7pk3ub6jLKpztr2+KMcx4uR2L/9rl5x0BKBgXBmImeILjkTeEjG1ts4gZ302qW/z7mxDf07W9sPovjlHtA==", + "requires": { + "bsert": "~0.0.3" + } + }, + "bsert": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.3.tgz", + "integrity": "sha512-3MnMGtKFjqEXSzfQnABAhCGTCOpSjJuhmxACInJxGwfT2Yz1eXipHg1feVi1CGG0wVaYPrgCs6FLr+Y79adY1A==" }, "bsip": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.0.tgz", - "integrity": "sha512-+eiWVVRcfcjI9uGg2xF5PpOdM3sUsPcVatpGX48+0XFUzVUv5nPWiEydDTuh6AC0qOjZN2p1SNwisO84Ie7+TQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.1.tgz", + "integrity": "sha512-LQdhDedZQuwezVneaojtV7CPJSiDUsVvB+HVIG9BmMi9cEtPC1MKKtRMLNm1HEaXauhc3fTdfCjXnBmPkOcTng==", "requires": { "bindings": "~1.3.0", + "bsert": "~0.0.3", "nan": "~2.10.0" } }, "bsock": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.0.tgz", - "integrity": "sha512-ksIqK8Djyk2Q88gVd8evM54I1tuqQhBZshMLRJ0sjPpoFX0BvquGUFTGC6rKLy9hGWWVVWOqz/2PZei9xqcSYg==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.1.tgz", + "integrity": "sha512-rFY2MiUEdxhC21lzEVf7vV51c/vuADSYTySzHYML5uRl0bs013PrAF02j9dz0MaNRSivTxPMbAZvRlUhEahXdw==", "requires": { + "bsert": "~0.0.3", "faye-websocket": "~0.11.1" } }, "bsocks": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.0.tgz", - "integrity": "sha512-Wq/muS0UO1WfQMQP0KZa/Xt0akpfCNQ7Y+xyPiF15WRcZDbO4wn60wvXIr2sUjqWyGv4MuPePbYW/mYyfwbk7w==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.1.tgz", + "integrity": "sha512-RSoJL6j7C1bw9IHaxiKhEj2iga1TRNyW9EiMpDhfunbMM9xvP5xJ+oVmOCJLE+JEDRdWNESAgOeNZnn3q9fGdg==", "requires": { - "binet": "~0.3.0" + "binet": "~0.3.1", + "bsert": "~0.0.3" } }, "bstring": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bstring/-/bstring-0.1.0.tgz", - "integrity": "sha512-uOgKi6gitLAbnmNk+VJQi3LDLd3DU6lxqaVR/3HOHboCuhYdqPJA/fhuB5O6XGbYfzRt/IJyx8NsEKPGyTtGIQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bstring/-/bstring-0.1.1.tgz", + "integrity": "sha512-xpJd187BAzrW9DbXuttGhAnsPRZNfRuehYd1Qds7IGj64TISNtvXqlqqebRmOcpweGwkZiBGItNoMkGbF4Qomg==", "requires": { "bindings": "~1.3.0", + "bsert": "~0.0.3", "nan": "~2.10.0" } }, "btcp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.0.tgz", - "integrity": "sha512-JJMuuYT/BHuX2SUKBBXvk8F9HSC+ng8HA842zCELhtQFytzQ0l2G2xUMnJ3WK8maIW0TOyk5Ssu/sZlkZtAP3g==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.1.tgz", + "integrity": "sha512-EwqraaSVjrMYSuSchJ0t2gdeA/4BGgKu+tFVJpTpc4pjzrlu9O6kc3NNffSyIzoxd7jToRdrsT3TorA03a/qwQ==" }, "buffer-alloc": { "version": "1.2.0", @@ -535,25 +578,30 @@ "integrity": "sha512-PjL1QglhgZCWEKWbxzlVB4ExvNorHMu0JSu4ehzeKi38R74Fp7duHAl8xNEqsbJXP5Dfym7XuSEkVol1KX5mhw==" }, "bupnp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.1.tgz", - "integrity": "sha512-KKdgJF8RXjbhWL1e7szjAlF1akYYUZeb0RMn/oNsOeIoVlNdd+fIBd6v3V2+YZfPjJbDb/5Et5KyzfvhJ5QP9w==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.2.tgz", + "integrity": "sha512-VauG03WYuZqqP+n/4gf/ItoZPgmSR76whDRFvAYvzsQzotTs3NfIKa7GGlykjAmvOPuuXqa2yVPNGV8dS+MomA==", "requires": { - "binet": "~0.3.0", - "brq": "~0.1.0" + "binet": "~0.3.1", + "brq": "~0.1.2", + "bsert": "~0.0.3" } }, "bval": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.1.tgz", - "integrity": "sha512-Yj2q9+RRSsbKhrmleGp/bXYV9NBM3pjBQJGsJ+8SM60YQREMLLr3Nz7wogao73ki7khYuLz+b33qCGv6685k3A==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.2.tgz", + "integrity": "sha512-ewri8C/nc9ZHzkCMcpl6gVv9lMEvXw2CXppYIgDY0n1QKIVu8j0K1LT8F2Gm2kyqPGJI7Tp71V5bMhh4bPaZoA==", + "requires": { + "bsert": "~0.0.3" + } }, "bweb": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.1.tgz", - "integrity": "sha512-+Yf/R/54hDradHivlmogZAVe8BnOI6U5T9hP3pbGxhGUQqBYapaAYP1/t8PwY6CFvrB3UNc6KYjKfv1DIicAdw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.2.tgz", + "integrity": "sha512-vNS62uURu16GpoByzfAUkwIjzgBcDI8GCgUKDmqSQD3eJPr3Lpu1QmU0nESbmC6HvLvWRy4OXdZu+dLobs0uog==", "requires": { - "bsock": "~0.1.0" + "bsert": "~0.0.3", + "bsock": "~0.1.1" } }, "chownr": { @@ -2173,11 +2221,12 @@ } }, "mrmr": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.0.tgz", - "integrity": "sha512-jwarZT20LbjYM+jvbkciut+fVCz5O5qqGU97a62z6FXst3WHb93QS3kBgdJyed+nc7CXSbAMScjPUcruenRfrQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.1.tgz", + "integrity": "sha512-2nJ8KlBZiFsj629GsqSBfx/ILWpL3+Kam8eMBn/YL84lvPUuAG0SNvtaGr8Z7T19wKOYnJAV5N+MCEXVgguxtQ==", "requires": { "bindings": "~1.3.0", + "bsert": "~0.0.3", "nan": "~2.10.0" } }, @@ -2188,9 +2237,9 @@ "dev": true }, "n64": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.0.tgz", - "integrity": "sha512-qNXq/YX546Ccv46GLbkGePc6u65Syp2wync+iG5hR4EB4I+QBtxe5lG076sGkni+9lvuPtN3r3Ut/LXm8PxUzA==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.1.tgz", + "integrity": "sha512-rs7dj53A2qK/bk4gQnBAp3DYwtyHKs5y2tbuQkgM4mDwGBI7fPJBbfBaXaNOpbVtnru2Aw++qVCNDYJ3XAuc7A==" }, "nan": { "version": "2.10.0", From 6ea9a85209af6a3cd2a9dbe9ac8f648c041f62ef Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 1 Aug 2018 20:50:23 +0100 Subject: [PATCH 482/540] Attempt to connect nodes by hand --- minimal_testcases/magicno.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/minimal_testcases/magicno.js b/minimal_testcases/magicno.js index 2bf1026..c59249f 100644 --- a/minimal_testcases/magicno.js +++ b/minimal_testcases/magicno.js @@ -1,4 +1,5 @@ const bcoin = require("bcoin").set("regtest"); +const NetAddress = require("bcoin/lib/net/netaddress"); async function delay(ms) { return new Promise(resolve => { @@ -8,14 +9,17 @@ async function delay(ms) { const one = new bcoin.FullNode({ network: bcoin.Network.get().toString(), - //logConsole: true, - //logLevel: "debug", - nodes: ["127.0.0.1:48448"] +// logConsole: true, +// logLevel: "debug", + httpPort: 48440, + port: 48441 }); const two = new bcoin.FullNode({ network: bcoin.Network.get().toString(), - httpPort: 48448 + httpPort: 48444, + port: 48445, + listen: true }); (async () => { @@ -25,8 +29,18 @@ const two = new bcoin.FullNode({ await two.open(); await two.connect(); + const addr = new NetAddress({ + host: "127.0.0.1", + port: 48445 + }); + const peer = one.pool.createOutbound(addr); + //one.pool.peers.add(peer); + //one.pool.setLoader(one.pool.peers.head()); + await delay(3000); + console.log(one.pool.peers.size()); + console.log(two.pool.peers.size()); await two.disconnect(); await two.close(); From cf9a4e02f8837f900d081c1986db58a3999ed12a Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 2 Aug 2018 23:58:03 +0100 Subject: [PATCH 483/540] Connect two nodes cleanly --- minimal_testcases/magicno.js | 38 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/minimal_testcases/magicno.js b/minimal_testcases/magicno.js index c59249f..6d7279e 100644 --- a/minimal_testcases/magicno.js +++ b/minimal_testcases/magicno.js @@ -9,41 +9,45 @@ async function delay(ms) { const one = new bcoin.FullNode({ network: bcoin.Network.get().toString(), -// logConsole: true, -// logLevel: "debug", - httpPort: 48440, - port: 48441 + //logConsole: true, + //logLevel: "debug", + httpPort: 48449 }); const two = new bcoin.FullNode({ network: bcoin.Network.get().toString(), - httpPort: 48444, port: 48445, listen: true }); (async () => { - await one.open() - await one.connect(); - + await one.open(); await two.open(); + + await one.connect(); await two.connect(); const addr = new NetAddress({ host: "127.0.0.1", - port: 48445 + port: two.pool.options.port }); const peer = one.pool.createOutbound(addr); - //one.pool.peers.add(peer); - //one.pool.setLoader(one.pool.peers.head()); + one.pool.peers.add(peer); - await delay(3000); + await delay(4000); - console.log(one.pool.peers.size()); - console.log(two.pool.peers.size()); - await two.disconnect(); - await two.close(); + for (node of [one, two]) + if (node.pool.peers.size() !== 1) + throw new Error("Node " + ((node === one) ? "one" : "two") + + " has peer list size " + node.pool.peers.size()); + await two.disconnect(); await one.disconnect(); + + await two.close(); await one.close(); -})(); + console.log("success!"); +})().catch((err) => { + console.error(err); + process.exit(1); +}); From a393ff128e1b802f38ef661523e01b3433ec03f4 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 4 Aug 2018 17:48:46 +0100 Subject: [PATCH 484/540] Simplify require() for NetAddress --- minimal_testcases/magicno.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minimal_testcases/magicno.js b/minimal_testcases/magicno.js index 6d7279e..8a00d3c 100644 --- a/minimal_testcases/magicno.js +++ b/minimal_testcases/magicno.js @@ -1,5 +1,5 @@ const bcoin = require("bcoin").set("regtest"); -const NetAddress = require("bcoin/lib/net/netaddress"); +const NetAddress = bcoin.net.NetAddress; async function delay(ms) { return new Promise(resolve => { From 78c3dcf40692179c4e3499b5aa405a1bf37b224e Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 7 Aug 2018 23:07:42 +0100 Subject: [PATCH 485/540] Comment out walletPlugin --- src/full_node.js | 2 +- src/spv_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/full_node.js b/src/full_node.js index ab18978..a79e5ea 100644 --- a/src/full_node.js +++ b/src/full_node.js @@ -8,7 +8,7 @@ class FullNode extends bcoin.FullNode { constructor(options : Object) { super(options); - this.use(walletPlugin); +// this.use(walletPlugin); this.trust = new TrustIsRisk(this); } diff --git a/src/spv_node.js b/src/spv_node.js index 0beed64..98329d1 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -9,7 +9,7 @@ class SPVNode extends bcoin.SPVNode { constructor(options : Object) { super(options); - this.use(walletPlugin); +// this.use(walletPlugin); this.trust = new TrustIsRisk(this); } From 9e447e1492b107bac176fe7fa85bb1ba6d314140 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 25 Aug 2018 23:38:14 +0100 Subject: [PATCH 486/540] Add local nodes connect testcases --- ...agicno.js => connect-nodes-wo-walletdb.js} | 1 + minimal_testcases/connect-spv-w-walletdb.js | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) rename minimal_testcases/{magicno.js => connect-nodes-wo-walletdb.js} (99%) create mode 100644 minimal_testcases/connect-spv-w-walletdb.js diff --git a/minimal_testcases/magicno.js b/minimal_testcases/connect-nodes-wo-walletdb.js similarity index 99% rename from minimal_testcases/magicno.js rename to minimal_testcases/connect-nodes-wo-walletdb.js index 8a00d3c..f72b6e8 100644 --- a/minimal_testcases/magicno.js +++ b/minimal_testcases/connect-nodes-wo-walletdb.js @@ -46,6 +46,7 @@ const two = new bcoin.FullNode({ await two.close(); await one.close(); + console.log("success!"); })().catch((err) => { console.error(err); diff --git a/minimal_testcases/connect-spv-w-walletdb.js b/minimal_testcases/connect-spv-w-walletdb.js new file mode 100644 index 0000000..4f7ad8f --- /dev/null +++ b/minimal_testcases/connect-spv-w-walletdb.js @@ -0,0 +1,77 @@ +// Works with bcoin PR #578 +const bcoin = require('bcoin').set('regtest'); +const NetAddress = bcoin.net.NetAddress; +const WalletDB = bcoin.wallet.WalletDB; +const NodeClient = bcoin.wallet.NodeClient; + +const regtest = bcoin.Network.get().toString(); + +function delay(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }) +} + +const one = new bcoin.SPVNode({ // Full: OK | SPV: Fail + network: regtest, + // logConsole: true, // try to see the logs of + // logLevel: 'debug', // the Full node as well + httpPort: 48445, + passphrase: 'secret' +}); + +const oneWalletDB = new WalletDB({ + network: regtest, + client: new NodeClient(one) +}); + +const two = new bcoin.FullNode({ + network: regtest, + port: 48448, + bip37: true, + listen: true, + passphrase: 'secret' +}); + +const addr = new NetAddress({ + host: '127.0.0.1', + port: two.pool.options.port +}); + +(async () => { + // You can experiment with delay()s + // and reorder open()s and connect()s + // for a variety of similar errors + await one.open(); + + // Comment next line out and nodes connect + await oneWalletDB.open(); + + await two.open(); + + //await delay(4000); + + await one.connect(); + await two.connect(); + + const peer = one.pool.createOutbound(addr); + one.pool.peers.add(peer); + + await delay(4000); + + for (node of [one, two]) + if (node.pool.peers.size() !== 1) + throw new Error('Node ' + ((node === one) ? 'one' : 'two') + + ' has peer list size ' + node.pool.peers.size()); + + await two.disconnect(); + await two.close(); + + await one.disconnect(); + await one.close(); + + console.log('success!'); +})().catch((err) => { + console.error(err); + process.exit(1); +}); From ede96a5c94ce69fae4415594b18f95fe69e04f00 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 26 Aug 2018 02:01:02 +0100 Subject: [PATCH 487/540] Use native walletDB --- test/full_node.js | 11 +++++++++-- test/spv_node.js | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index a21ea28..677bc9d 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -2,6 +2,8 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); var Script = bcoin.script; +var WalletDB = bcoin.wallet.WalletDB; +var NodeClient = bcoin.wallet.NodeClient; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; @@ -41,9 +43,14 @@ describe("FullNode", () => { network: bcoin.Network.get().toString(), passphrase: "secret" }); - + walletDB = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(node) + }); await node.initialize(); - walletDB = node.require("walletdb").wdb; + + await walletDB.open(); + node.startSync(); wallet = await testHelpers.createWallet(walletDB, "wallet"); diff --git a/test/spv_node.js b/test/spv_node.js index fd043f0..29757fc 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -2,6 +2,8 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); var bcrypto = require("bcrypto"); +var WalletDB = bcoin.wallet.WalletDB; +var NodeClient = bcoin.wallet.NodeClient; var Script = bcoin.script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; @@ -49,8 +51,12 @@ describe("SPVNode", () => { }); beforeEach("connect SPV node, create walletDB", async () => { + spvWalletDB = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(spvNode) + }); await spvNode.initialize(); - spvWalletDB = spvNode.require("walletdb").wdb; + await spvWalletDB.open(); }); beforeEach("create full node", async () => { @@ -68,8 +74,12 @@ describe("SPVNode", () => { }); beforeEach("connect full node, create walletDB", async () => { + minerWalletDB = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(miner) + }); await miner.initialize(); - minerWalletDB = miner.require("walletdb").wdb; + await minerWalletDB.open(); }); beforeEach("start syncing", () => { From 56808e3805b026ab543eef6f26670308e55100fa Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 5 Sep 2018 00:24:12 +0100 Subject: [PATCH 488/540] Fix bloom filter test Make it work for new bcoin version --- test/spv_node.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 29757fc..9454808 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -3,8 +3,9 @@ var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); var bcrypto = require("bcrypto"); var WalletDB = bcoin.wallet.WalletDB; +var WalletKey = bcoin.wallet.WalletKey; var NodeClient = bcoin.wallet.NodeClient; -var Script = bcoin.script; +var Script = bcoin.script.Script; var Address = bcoin.primitives.Address; var KeyRing = bcoin.primitives.KeyRing; var MTX = bcoin.primitives.MTX; @@ -62,7 +63,7 @@ describe("SPVNode", () => { beforeEach("create full node", async () => { miner = new Trust.FullNode({ network: bcoin.Network.get().toString(), - httpPort: 48448, + port: 48448, bip37: true, listen: true, passphrase: "secret" @@ -111,18 +112,18 @@ describe("SPVNode", () => { it("should match a TIR transaction with the spv bloom filter", async function() { var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); - var privateKey1 = (await wallet1.getPrivateKey( - wallet1.getAddress("base58"), "secret") - ).privateKey; - var origin = secp256k1.publicKeyCreate(privateKey1, true); + var account1 = await wallet1.getAccount('default'); + var type1 = account1.network.keyPrefix.coinType; + var hd1 = wallet1.master.key.deriveAccount(44, type1, account1.accountIndex); + var origin = WalletKey.fromHD(account1, hd1, 0, 0) var wallet2 = await testHelpers.createWallet(minerWalletDB, "wallet2"); - var privateKey2 = (await wallet2.getPrivateKey( - wallet2.getAddress("base58"), "secret") - ).privateKey; - var dest = secp256k1.publicKeyCreate(privateKey2, true); + var account2 = await wallet2.getAccount('default'); + var type2 = account2.network.keyPrefix.coinType; + var hd2 = wallet2.master.key.deriveAccount(44, type2, account2.accountIndex); + var dest = WalletKey.fromHD(account2, hd2, 0, 0) - var block = await testHelpers.mineBlock(miner, wallet1.getAddress("base58")); + var block = await testHelpers.mineBlock(miner, origin.getKeyAddress("base58")); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; @@ -130,11 +131,12 @@ describe("SPVNode", () => { var outputs = [ new Output({ // 1-of-3 multisig trust - script: bcoin.script.fromMultisig(1, 3, [origin, dest, tag]), + script: Script.fromMultisig(1, 3, [origin.getPublicKey(), dest.getPublicKey(), tag]), value: 49 * consensus.COIN }), new Output({ // paytopubkeyhash change - script: bcoin.script.fromPubkeyhash(bcoin.crypto.hash160(origin)), + script: Script.fromPubkeyhash( + bcrypto.hash160.digest(origin.getPublicKey())), value: consensus.COIN - 100000 // leave a fee of 0.001 BTC }) ]; @@ -142,7 +144,7 @@ describe("SPVNode", () => { var coinbaseCoin = await miner.getCoin(block.txs[0].hash().toString("hex"), 0); mtx.addCoin(coinbaseCoin); - mtx.sign(KeyRing.fromPrivate(privateKey1, true, "regtest")); + mtx.sign(origin); mtx.verify().should.be.true(); var tx = mtx.toTX(); From e32848e0090643c171320afb4817682a77d7cb2e Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 9 Sep 2018 23:51:32 +0100 Subject: [PATCH 489/540] Fix full node addTX() test --- test/helpers.js | 3 ++- test/spv_node.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index f500ab4..6ffdfbd 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -28,10 +28,11 @@ var testHelpers = { circulateCoins: async (fromWallet, fromWatcher, toWallet, toWatcher, coins) => { + const toAccount = await toWallet.getAccount("default"); const tx = await fromWallet.send({ outputs: [{ value: coins * consensus.COIN, - address: toWallet.getAddress("base58") + address: toAccount.receiveAddress() }] }); await fromWatcher.waitForTX(tx, fromWallet); diff --git a/test/spv_node.js b/test/spv_node.js index 9454808..788a55e 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -155,10 +155,11 @@ describe("SPVNode", () => { it("should call trust.addTX() on transaction within a full node", async function() { var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); + var account1 = await minerWallet1.getAccount("default"); await testHelpers.delay(1000); // Produce a block and reward the minerWallet1, so that we have a coin to spend. - await testHelpers.mineBlock(miner, minerWallet1.getAddress("base58")); + await testHelpers.mineBlock(miner, account1.receiveAddress()); await testHelpers.delay(100); var miner2TX = await testHelpers.circulateCoins(minerWallet1, From bab29128da159a76c020ce978373102ebd7583ea Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 7 Oct 2018 15:54:33 +0100 Subject: [PATCH 490/540] Add regression test for NodeClient.setFilter() --- minimal_testcases/setFilterRegression.js | 90 ++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 minimal_testcases/setFilterRegression.js diff --git a/minimal_testcases/setFilterRegression.js b/minimal_testcases/setFilterRegression.js new file mode 100644 index 0000000..9e7cca1 --- /dev/null +++ b/minimal_testcases/setFilterRegression.js @@ -0,0 +1,90 @@ +(async () => { + var Trust = require("../"); + var helpers = require("../lib/helpers.js"); + var bcoin = require("bcoin").set("regtest"); + var NetAddress = bcoin.net.NetAddress; + var Peer = bcoin.net.Peer; + var bcrypto = require("bcrypto"); + var WalletDB = bcoin.wallet.WalletDB; + var NodeClient = bcoin.wallet.NodeClient; + var Script = bcoin.script.Script; + var Address = bcoin.primitives.Address; + var KeyRing = bcoin.primitives.KeyRing; + var MTX = bcoin.primitives.MTX; + var Input = bcoin.primitives.Input; + var Output = bcoin.primitives.Output; + var Outpoint = bcoin.primitives.Outpoint; + var secp256k1 = bcrypto.secp256k1; + var tag = require("../lib/tag"); + var testHelpers = require("../test/helpers"); + var consensus = require("bcoin/lib/protocol/consensus"); + var sinon = require("sinon"); + var should = require("should"); + var assert = require("assert"); + var fixtures = require("../test/fixtures"); + require("should-sinon"); + + const COIN = consensus.COIN; + const regtest = bcoin.Network.get().toString(); + + var spvNode = null; + var miner = null; + var spvWalletDB = null; + var minerWalletDB = null; + var spvWatcher = null; + var minerWatcher = null; + + consensus.COINBASE_MATURITY = 0; + + spvNode = new Trust.SPVNode({ + network: regtest, + httpPort: 48445, + passphrase: "secret" + }); + await spvNode.initialize(); + + spvWalletDB = new WalletDB({ + network: regtest, + client: new NodeClient(spvNode) + }); + await spvWalletDB.open(); // this breaks stuff + + miner = new Trust.FullNode({ + network: regtest, + //logConsole: true, + //logLevel: "debug", + port: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + await miner.initialize(); + + minerWalletDB = new WalletDB({ + network: regtest, + client: new NodeClient(miner) + }); + await minerWalletDB.open(); + + const addr = new NetAddress({ + host: "127.0.0.1", + port: miner.pool.options.port + }); + const peer = spvNode.pool.createOutbound(addr); + spvNode.pool.peers.add(peer); + + await testHelpers.delay(4000); + + for (node of [spvNode, miner]) + if (node.pool.peers.size() !== 1) + throw new Error("Node " + + ((node === spvNode) ? "spvNode" : "miner") + + " has peer list size " + node.pool.peers.size()); + + await miner.tearDown(); + await spvNode.tearDown(); + console.log("success!"); +})().catch((err) => { + console.error(err); + process.exit(1); +}); From de7e5a4be611838673908346645859e775495b42 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 7 Oct 2018 16:29:29 +0100 Subject: [PATCH 491/540] Add isAllZeroes(buffer) to testHelpers --- test/helpers.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index 6ffdfbd..f76a676 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,6 +7,18 @@ var assert = require("assert"); const consensus = require("bcoin/lib/protocol/consensus"); var testHelpers = { + isAllZeroes: (buf) => { + let flag = false + for (let i of buf) { + if (i) { + console.log("there's an 1...") + flag = true + break + } + } + if (!flag) console.log("it's all 0!") + }, + createWallet: async (walletDB, id) => { var options = { id, From f5cec47fda5211b504abcd8d1265d9afa4e9aae0 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 7 Oct 2018 22:06:42 +0100 Subject: [PATCH 492/540] Add template for spv tests --- minimal_testcases/spv_test_template.js | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 minimal_testcases/spv_test_template.js diff --git a/minimal_testcases/spv_test_template.js b/minimal_testcases/spv_test_template.js new file mode 100644 index 0000000..35151d5 --- /dev/null +++ b/minimal_testcases/spv_test_template.js @@ -0,0 +1,116 @@ +let Trust = require("../"); +let helpers = require("../lib/helpers.js"); +let bcoin = require("bcoin").set("regtest"); +var bcrypto = require("bcrypto"); +let NetAddress = bcoin.net.NetAddress; +let Peer = bcoin.net.Peer; +let WalletDB = bcoin.wallet.WalletDB; +var WalletKey = bcoin.wallet.WalletKey; +let NodeClient = bcoin.wallet.NodeClient; +let Script = bcoin.script.Script; +let Address = bcoin.primitives.Address; +let KeyRing = bcoin.primitives.KeyRing; +let MTX = bcoin.primitives.MTX; +let Input = bcoin.primitives.Input; +let Output = bcoin.primitives.Output; +let Outpoint = bcoin.primitives.Outpoint; +let tag = require("../lib/tag"); +let testHelpers = require("../test/helpers"); +let consensus = require("bcoin/lib/protocol/consensus"); +let sinon = require("sinon"); +let should = require("should"); +let assert = require("assert"); +let fixtures = require("../test/fixtures"); +require("should-sinon"); + +const COIN = consensus.COIN; +const regtest = bcoin.Network.get().toString(); + +let spvNode1, spvNode2, miner; +let spvWalletDB1, spvWalletDB2, minerWalletDB; +let minerWatcher, spvWatcher1, spvWatcher2; + +async function test() { +} + +(async () => { + consensus.COINBASE_MATURITY = 0; + + spvNode1 = new Trust.SPVNode({ + network: regtest, + httpPort: 48445, + passphrase: "secret", + nodes: ["127.0.0.1:48448"] + }); + + spvNode2 = new Trust.SPVNode({ + network: regtest, + httpPort: 48446, + passphrase: "secret", + nodes: ["127.0.0.1:48448"] + }); + sinon.spy(spvNode1.trust, "addTX"); + sinon.spy(spvNode2.trust, "addTX"); + + spvWalletDB1 = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(spvNode1) + }); + + spvWalletDB2 = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(spvNode2) + }); + + await spvNode1.initialize(); + await spvWalletDB1.open(); + await spvNode2.initialize(); + await spvWalletDB2.open(); + + miner = new Trust.FullNode({ + network: regtest, + //logConsole: true, + //logLevel: "debug", + port: 48448, + bip37: true, + listen: true, + passphrase: "secret" + }); + sinon.spy(miner.trust, "addTX"); + + minerWalletDB = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(miner) + }); + + await miner.initialize(); + await minerWalletDB.open(); + + + miner.startSync(); + spvNode1.startSync(); + spvNode2.startSync(); + + minerWatcher = new testHelpers.NodeWatcher(miner); + spvWatcher1 = new testHelpers.NodeWatcher(spvNode1); + spvWatcher2 = new testHelpers.NodeWatcher(spvNode2); + + await test() + + spvNode1.stopSync(); + spvNode2.stopSync(); + miner.stopSync(); + + await minerWalletDB.close(); + await spvWalletDB1.close(); + await spvWalletDB2.close(); + + await spvNode1.tearDown(); + await spvNode2.tearDown(); + await miner.tearDown(); + + console.log("success!"); +})().catch((err) => { + console.error(err); + process.exit(1); +}); From 830dc5ab0b75f5e1638f990ed68fffc9ed310719 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 8 Oct 2018 21:52:04 +0100 Subject: [PATCH 493/540] Add test for account address in bloom filter --- minimal_testcases/account_bloom.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 minimal_testcases/account_bloom.js diff --git a/minimal_testcases/account_bloom.js b/minimal_testcases/account_bloom.js new file mode 100644 index 0000000..bc0a1a0 --- /dev/null +++ b/minimal_testcases/account_bloom.js @@ -0,0 +1,22 @@ +const bcoin = require("bcoin"); +const WalletDB = bcoin.wallet.WalletDB; +const NodeClient = bcoin.wallet.NodeClient; + +const node = new bcoin.SPVNode({}); + +const wdb = new WalletDB({ + client: new NodeClient(node) +}); + +(async () => { + await node.open(); + await wdb.open(); + + const wallet = await wdb.create({}); + const account = await wallet.getAccount("default"); + + console.log(node.pool.spvFilter.test(account.receiveAddress().getHash())); + + await wdb.close(); + await node.close(); +})(); From 1e2a6351cfa359448190ae24f6d637535f1df60b Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 8 Oct 2018 21:54:36 +0100 Subject: [PATCH 494/540] Add address to filter --- minimal_testcases/account_bloom.js | 1 + 1 file changed, 1 insertion(+) diff --git a/minimal_testcases/account_bloom.js b/minimal_testcases/account_bloom.js index bc0a1a0..e7f83ef 100644 --- a/minimal_testcases/account_bloom.js +++ b/minimal_testcases/account_bloom.js @@ -15,6 +15,7 @@ const wdb = new WalletDB({ const wallet = await wdb.create({}); const account = await wallet.getAccount("default"); + node.pool.spvFilter.add(account.receiveAddress().getHash()) console.log(node.pool.spvFilter.test(account.receiveAddress().getHash())); await wdb.close(); From 63a83ecd353c432aa9abb05e0c367bb4a0db0640 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 8 Oct 2018 22:10:35 +0100 Subject: [PATCH 495/540] Fix spv tx circulation test Use two separate nodes, manually add receive address to spv filter --- test/spv_node.js | 95 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 788a55e..c4e78de 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -25,39 +25,54 @@ require("should-sinon"); const COIN = consensus.COIN; describe("SPVNode", () => { - var spvNode = null; + var spvNode1 = null; + var spvNode2 = null; var miner = null; - var spvWalletDB = null; + var spvWalletDB1 = null; + var spvWalletDB2 = null; var minerWalletDB = null; - var spvWatcher = null; + var spvWatcher1 = null; + var spvWatcher2 = null; var minerWatcher = null; beforeEach("make mined coins immediately spendable", () => { consensus.COINBASE_MATURITY = 0; }); - beforeEach("create SPV node", async () => { - spvNode = new Trust.SPVNode({ + beforeEach("create SPV nodes", async () => { + spvNode1 = new Trust.SPVNode({ network: bcoin.Network.get().toString(), httpPort: 48445, passphrase: "secret", - // logConsole: true, - // logLevel: "debug", + nodes: ["127.0.0.1:48448"] + }); + + spvNode2 = new Trust.SPVNode({ + network: bcoin.Network.get().toString(), + httpPort: 48446, + passphrase: "secret", nodes: ["127.0.0.1:48448"] }); }); beforeEach("set up SPV addTX() spy", () => { - sinon.spy(spvNode.trust, "addTX"); + sinon.spy(spvNode1.trust, "addTX"); + sinon.spy(spvNode2.trust, "addTX"); }); - beforeEach("connect SPV node, create walletDB", async () => { - spvWalletDB = new WalletDB({ + beforeEach("connect SPV node, create walletDBs", async () => { + spvWalletDB1 = new WalletDB({ network: bcoin.Network.get().toString(), - client: new NodeClient(spvNode) + client: new NodeClient(spvNode1) }); - await spvNode.initialize(); - await spvWalletDB.open(); + spvWalletDB2 = new WalletDB({ + network: bcoin.Network.get().toString(), + client: new NodeClient(spvNode2) + }); + await spvNode1.initialize(); + await spvWalletDB1.open(); + await spvNode2.initialize(); + await spvWalletDB2.open(); }); beforeEach("create full node", async () => { @@ -65,6 +80,8 @@ describe("SPVNode", () => { network: bcoin.Network.get().toString(), port: 48448, bip37: true, + //logConsole: true, + //logLevel: "debug", listen: true, passphrase: "secret" }); @@ -85,24 +102,33 @@ describe("SPVNode", () => { beforeEach("start syncing", () => { miner.startSync(); - spvNode.startSync(); + spvNode1.startSync(); + spvNode2.startSync(); }); beforeEach("create watchers", async () => { minerWatcher = new testHelpers.NodeWatcher(miner); - spvWatcher = new testHelpers.NodeWatcher(spvNode); + spvWatcher1 = new testHelpers.NodeWatcher(spvNode1); + spvWatcher2 = new testHelpers.NodeWatcher(spvNode2); }); - afterEach("tear nodes down", async () => { - spvNode.stopSync(); + afterEach("tear nodes and walletDBs down", async () => { + spvNode1.stopSync(); + spvNode2.stopSync(); miner.stopSync(); - await spvNode.tearDown(); + await minerWalletDB.close(); + await spvWalletDB1.close(); + await spvWalletDB2.close(); + + await spvNode1.tearDown(); + await spvNode2.tearDown(); await miner.tearDown(); }); afterEach("remove addTX() spies", () => { - spvNode.trust.addTX.restore(); + spvNode1.trust.addTX.restore(); + spvNode2.trust.addTX.restore(); miner.trust.addTX.restore(); }); @@ -148,8 +174,10 @@ describe("SPVNode", () => { mtx.verify().should.be.true(); var tx = mtx.toTX(); - spvNode.pool.spvFilter.test(tag).should.be.true(); - tx.isWatched(spvNode.pool.spvFilter).should.be.true(); + spvNode1.pool.spvFilter.test(tag).should.be.true(); + spvNode2.pool.spvFilter.test(tag).should.be.true(); + tx.isWatched(spvNode1.pool.spvFilter).should.be.true(); + tx.isWatched(spvNode2.pool.spvFilter).should.be.true(); }); it("should call trust.addTX() on transaction within a full node", async function() { @@ -169,28 +197,33 @@ describe("SPVNode", () => { }); it("should call trust.addTX() on transaction between full and spv node", async function() { - var spvWallet1 = await testHelpers.createWallet(spvWalletDB, "spvWallet1"); - var spvWallet2 = await testHelpers.createWallet(spvWalletDB, "spvWallet2"); + var spvWallet1 = await testHelpers.createWallet(spvWalletDB1, "spvWallet1"); + var spvWallet2 = await testHelpers.createWallet(spvWalletDB2, "spvWallet2"); var minerWallet = await testHelpers.createWallet(minerWalletDB, "minerWallet"); + var minerAccount = await minerWallet.getAccount("default"); - await testHelpers.delay(1000); + var spvAccount1 = await spvWallet1.getAccount("default"); + var spvAccount2 = await spvWallet2.getAccount("default"); + + spvNode1.pool.spvFilter.add(spvAccount1.receiveAddress().getHash()); + spvNode2.pool.spvFilter.add(spvAccount2.receiveAddress().getHash()); // Produce a block and reward the minerWallet, so that we have a coin to spend. - await testHelpers.mineBlock(miner, minerWallet.getAddress("base58")); + await testHelpers.mineBlock(miner, minerAccount.receiveAddress()); await testHelpers.delay(100); var minerSpvTX = await testHelpers.circulateCoins(minerWallet, - minerWatcher, spvWallet1, spvWatcher, 10); + minerWatcher, spvWallet1, spvWatcher1, 10); - spvNode.trust.addTX.should.have.been.calledOnce(); + spvNode1.trust.addTX.should.have.been.calledOnce(); var spv2TX = await testHelpers.circulateCoins(spvWallet1, - spvWatcher, spvWallet2, spvWatcher, 9); + spvWatcher1, spvWallet2, spvWatcher2, 9); - spvNode.trust.addTX.should.have.been.calledTwice(); + spvNode2.trust.addTX.should.have.been.calledTwice(); var spvMinerTX = await testHelpers.circulateCoins(spvWallet2, - spvWatcher, minerWallet, minerWatcher, 8); + spvWatcher2, minerWallet, minerWatcher, 8); var view = await miner.chain.db.getSpentView(minerSpvTX); var actualBalance = (await minerWallet.getBalance()).unconfirmed; @@ -198,7 +231,7 @@ describe("SPVNode", () => { consensus.BASE_REWARD - 10 * COIN + 8 * COIN - minerSpvTX.getFee(view); actualBalance.should.equal(expectedBalance); - spvNode.trust.addTX.should.have.been.calledThrice(); + spvNode2.trust.addTX.should.have.been.calledTwice(); miner.trust.addTX.should.have.been.calledThrice(); }); From 54872b5319498a3e7cb5f91c62bc1c3bda993acb Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 10 Oct 2018 23:49:42 +0100 Subject: [PATCH 496/540] Add example with keyring manipulation --- minimal_testcases/keyring.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 minimal_testcases/keyring.js diff --git a/minimal_testcases/keyring.js b/minimal_testcases/keyring.js new file mode 100644 index 0000000..9d488a9 --- /dev/null +++ b/minimal_testcases/keyring.js @@ -0,0 +1,27 @@ +const bcoin = require("bcoin"); +const WalletDB = bcoin.wallet.WalletDB; +const KeyRing = bcoin.primitives.KeyRing; +const secp256k1 = require("bcrypto").secp256k1; + +(async () => { + const wdb = new WalletDB({ + network: "testnet", + db: "memory" + }); + await wdb.open(); + const wallet = await wdb.create(); + + console.log(secp256k1.privateKeyVerify(Buffer.from(wallet.master.key.xprivkey()))); + // how to get true private key from wallet? read account.receiveAddress() and stuff... + console.log(Buffer.from(wallet.master.key.xprivkey()).toString("hex")); + + const privkey = secp256k1.generatePrivateKey(true); + console.log(privkey.toString("hex")); + const pubkey = secp256k1.publicKeyCreate(privkey, true); + console.log(pubkey.toString("hex")); + const keyring = KeyRing.fromPrivate(privkey, true); + console.log(keyring.getPrivateKey("hex", "regtest")); + console.log(keyring.getPublicKey("hex", "regtest")); + const address = keyring.getAddress("base58", "regtest"); + console.log(address); +})(); From 38f756cb169dbf6c62d765d69e03d5ee527647c1 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 11 Oct 2018 23:53:40 +0100 Subject: [PATCH 497/540] Make keyring example more robust --- minimal_testcases/keyring.js | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/minimal_testcases/keyring.js b/minimal_testcases/keyring.js index 9d488a9..a90a489 100644 --- a/minimal_testcases/keyring.js +++ b/minimal_testcases/keyring.js @@ -2,26 +2,36 @@ const bcoin = require("bcoin"); const WalletDB = bcoin.wallet.WalletDB; const KeyRing = bcoin.primitives.KeyRing; const secp256k1 = require("bcrypto").secp256k1; +const assert = require("assert"); +const _ = require("lodash"); (async () => { const wdb = new WalletDB({ network: "testnet", - db: "memory" + db: "memory", + passphrase: "secret" }); await wdb.open(); const wallet = await wdb.create(); + const account = await wallet.getAccount("default"); + // const account2 = await wallet.ensureAccount({}, "secret"); - console.log(secp256k1.privateKeyVerify(Buffer.from(wallet.master.key.xprivkey()))); - // how to get true private key from wallet? read account.receiveAddress() and stuff... - console.log(Buffer.from(wallet.master.key.xprivkey()).toString("hex")); + const keyring = account.deriveReceive( + account.receiveDepth - 1, wallet.master + ); - const privkey = secp256k1.generatePrivateKey(true); - console.log(privkey.toString("hex")); + // const privkey = secp256k1.generatePrivateKey(true); + const privkey = keyring.privateKey; const pubkey = secp256k1.publicKeyCreate(privkey, true); - console.log(pubkey.toString("hex")); - const keyring = KeyRing.fromPrivate(privkey, true); - console.log(keyring.getPrivateKey("hex", "regtest")); - console.log(keyring.getPublicKey("hex", "regtest")); + + // const keyring = KeyRing.fromPrivate(privkey, true); + + const privKeyFromKeyRing = keyring.getPrivateKey("hex", "regtest"); + assert(_.isEqual(privKeyFromKeyRing, privkey.toString("hex"))); + + const pubKeyFromKeyRing = keyring.getPublicKey("hex", "regtest"); + assert(_.isEqual(pubKeyFromKeyRing, pubkey.toString("hex"))); + const address = keyring.getAddress("base58", "regtest"); - console.log(address); + console.log("success!"); })(); From c856b3fbe08928568a664b83a72384deed4f289e Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 15 Oct 2018 21:38:58 +0100 Subject: [PATCH 498/540] Have P2PKHOUtput() accept Address objects --- test/helpers.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index f76a676..a4d897f 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -68,7 +68,13 @@ var testHelpers = { }, getP2PKHOutput: (dest, value) => { - var address = bcoin.primitives.Address.fromString(dest); + let address; + if (typeof dest === "string") { + address = bcoin.primitives.Address.fromString(dest); + } + else { + address = dest; + } var script = bcoin.Script.fromPubkeyhash(address.hash); return new bcoin.primitives.Output({script, value}); From 811bc62c987b427df97824e98f41a8f5723b32fc Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 17 Oct 2018 10:03:30 +0100 Subject: [PATCH 499/540] Update npm installs --- package-lock.json | 309 ++++++++++++++++++++++------------------------ 1 file changed, 148 insertions(+), 161 deletions(-) diff --git a/package-lock.json b/package-lock.json index a713dc4..9246d4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -256,21 +256,21 @@ "dev": true }, "bcfg": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.2.tgz", - "integrity": "sha512-vKp2Pqf8z4wk9213SQPv307/qh4bI6NPmYlW4rtTLPeNrkHMWNn2dLpxHQ4Fe/CganPcoR0xKZDopFKYeneQKw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.3.tgz", + "integrity": "sha512-N/ZpKumfVYcAE5nYc0t4guvMGmtFaFn2QLUVZ0+0e1DBoRR7U6uh94pES7d2R7BKiYuVN1EI9bgOGmWGK4Kvig==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bclient": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.3.tgz", - "integrity": "sha512-XPnREmUZLYc0mYy8rxUGsO+VIGXQuLfx+cauqKrq2apzMWxHGs5aTpI3agKgrf2aa3JpWUIFbPpKuItwsYcQWw==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.4.tgz", + "integrity": "sha512-1/O/X1iVy1Vxydcuw5zIe/5AERcfUNbV48MPs1g7ZWa0/1Lhve432vgA5OKLQXrHADABF1vuE+ar+mGMKEiOiw==", "requires": { - "bcfg": "~0.1.2", - "bcurl": "~0.1.2", - "bsert": "~0.0.3" + "bcfg": "~0.1.3", + "bcurl": "~0.1.3", + "bsert": "~0.0.4" } }, "bcoin": { @@ -320,13 +320,13 @@ } }, "bcurl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.2.tgz", - "integrity": "sha512-VrOb7DzrByO8Aazqic65HVPS51R/JNu/IbUY4ozu3zaft7dcpDgkE9GFRHc1dBeI5urj22ehLWw8/ZcDeh29wg==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.3.tgz", + "integrity": "sha512-l9tG3yH52f0QYwP0g0G6K9fwpOi/1A95D9vIjAcoEMQaGl2jETxvRjiVsxMWBzo0OTwjjAZOc6HyDo1ZbkfI4g==", "requires": { - "brq": "~0.1.2", - "bsert": "~0.0.3", - "bsock": "~0.1.1" + "brq": "~0.1.3", + "bsert": "~0.0.4", + "bsock": "~0.1.3" } }, "bdb": { @@ -339,25 +339,25 @@ } }, "bdns": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.1.tgz", - "integrity": "sha512-XnZAjI4DOlwYW7V4uhekGXOwTmJ3zSZtG5iHybqTPTSFwh1XsxZreXcKLoPZcvBz7v+vqo934JMYPprmtc62lA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.2.tgz", + "integrity": "sha512-/b5KwvM5Uxb+CTFN/PjaJttHEcwTDQoZingvJViyQXS61aau4sqMBAZbKaS30ULq9c08sWamUWEnJGSSKq5gcA==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bevent": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.1.tgz", - "integrity": "sha512-0CbDBnwxyqSdO/63kOi190mHNYpbG1bS7OBNl/PdbA2tHk5ewMfdZaaU+njn9kgr23NGbdoocfXR5Wo7bjYsIg==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.2.tgz", + "integrity": "sha512-YOqqEs+hvQ7n/VmxnfxM3jwxYAGcGO1Ls09RTCAsstROi9nVGhSMTnRi5OIPjlT9l+oFdQFUrExPxdSlXj4laQ==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bfile": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.1.tgz", - "integrity": "sha512-BzQX3loGHgVKfu4KhZ1lI3yaZeBSFar6kKBJNTBCtI+SvYhXn4OALgCxX0C0/9Ca39vjcSkwLhOLMZZGoC0F6g==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.2.tgz", + "integrity": "sha512-k/GnFlGvy3Pxsko3BLpvyEPdFeSXrsq56fB6Zms8jlsiRv3BFDvzm2DI/RWFZzhEpiGPFjjFA6UamJZVBKUyzQ==" }, "bfilter": { "version": "0.2.0", @@ -369,11 +369,11 @@ } }, "bheep": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.1.tgz", - "integrity": "sha512-kDgcu6BXj/6XsCc+fjjo9ViRETdkQqt0FYxQR+ZqQ4edbWE6x8o51k/BwzqkXWPHrsB2/qLjsgnnMPezJvSnpw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.2.tgz", + "integrity": "sha512-Ud+Y5iPGlHMgu2oaYSOPZNBqtUGn+/f7sLrvjpY81mHGDiH5bVDOCp13Wey57pdV6UBzz3L+LpskPRvN1YJ65g==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bindings": { @@ -382,12 +382,12 @@ "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" }, "binet": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.1.tgz", - "integrity": "sha512-4ZCsooGoTYG6BwikD1bjXStzhR5wZnc16CA13cm6ot3jsN3Ridrj7G02sL2yzXTegXILIZy25Au+RHqC8F/jzQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.2.tgz", + "integrity": "sha512-ZsH2u3HlVgtN0K1XyQO9wLHe8qFpBq4c4tmOK8y83nnm8+VgI6Am365VVgpigwg4zZmMSa9MYfcPWdWWMMrBAA==", "requires": { - "bs32": "~0.1.1", - "bsert": "~0.0.3" + "bs32": "~0.1.2", + "bsert": "~0.0.4" } }, "bip66": { @@ -400,7 +400,7 @@ }, "bl": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { "readable-stream": "^2.3.5", @@ -408,35 +408,35 @@ } }, "blgr": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.1.tgz", - "integrity": "sha512-paJmBPpsYYllidj7UvFvkrwtr2j6YLo7tmk0J885iY4Zw0ZFquV+OVtjDTpTOdeSFJefdi5URGrzOkrFm4M8QQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.2.tgz", + "integrity": "sha512-PPX5ULDnOM8Hrky+6SihZQpHniIKp+0RjXVzFI0Ca6533ItHnd6YXU0VbM5VFWZ/dYc7FC74hWPu0j7yYJm2MQ==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "blru": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.2.tgz", - "integrity": "sha512-S3rvHlFMFYOZT+1gQct44FLIeNjf51RZBUWunuMXb7GDREtI98m6MxBVjdfxYKrdIX5YI8gY4FrVLCq59oQeXQ==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.3.tgz", + "integrity": "sha512-VABNB1X4/9hahUwZL299ogkkob0+oHS65Hx3rKSVs+mUEU1VURhOkkzXxnvOCBSlECSjGHbd88gEc9PiEboDeA==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "blst": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.1.tgz", - "integrity": "sha512-avNp9dO3fXFObDYqh8rY12uUenbLLZaySKIKI32Mlq1czTw7Szah9nzQsMh5ejmkBsR3FjUyuWczGzi4o8BVdQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.2.tgz", + "integrity": "sha512-R4lsoIwklHXTxGEkp7hhknr0zN41UhGNFsRd5zNJ7Wa67kAFlUFqcMqTpgzbFTZ9S0Cf37hn8OfeBhvFwVtvrg==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bmutex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.2.tgz", - "integrity": "sha512-H5mZOJQgtK2SMPStn0Zgo+Z/5jf71ZPSblcsepqf4MGa9SrJRsL6jF4jWLlgayGtq6DCAfRuHokZC+WRoHn+AA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.3.tgz", + "integrity": "sha512-VR6fZbVl2/GZOSUy2Cpl7ijVZKP/Ma9JUaGQBSw/xW5lJB7fF2qzmY0BLJ0s0TG+lAY0+1yqPiA3Nj1mlDEUdA==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bn.js": { @@ -467,7 +467,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "^1.0.3", @@ -479,52 +479,58 @@ } }, "brq": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.2.tgz", - "integrity": "sha512-YE+G82KUl6HWScDfS3gGCxqGv4CsL+LI3K8oKtzZQVjvGu+LqgbRboT+6dCgXhaWRTTZXCaAsRdzK2tCemdcyw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.3.tgz", + "integrity": "sha512-3wTf6IXQInJ8MedIuWmFcKL33dce7EZ7fY5aDSxzStSuvuODmpjXqNhxJ8RZ497l9CDA55Eyq1g1fJrT4LSfQQ==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bs32": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.1.tgz", - "integrity": "sha512-mvHV7pk3ub6jLKpztr2+KMcx4uR2L/9rl5x0BKBgXBmImeILjkTeEjG1ts4gZ302qW/z7mxDf07W9sPovjlHtA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.2.tgz", + "integrity": "sha512-d+6l8lN4OBd2Xp3hGqfRofR0QVztY2cdCyT4eSGjKFnEpEwrCW+h/FvInm13hHmjTqkkrxgdsKyPtvH7pGNV7Q==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bsert": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.3.tgz", - "integrity": "sha512-3MnMGtKFjqEXSzfQnABAhCGTCOpSjJuhmxACInJxGwfT2Yz1eXipHg1feVi1CGG0wVaYPrgCs6FLr+Y79adY1A==" + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.4.tgz", + "integrity": "sha512-VReLe1aTaHRmf80YLOHUk8ONQ48SjseZP76GlNIDheD5REYByn/Mm9yrtI0/ZCaFrcfxzgpiw1/hMMCUOSMa3w==" }, "bsip": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.1.tgz", - "integrity": "sha512-LQdhDedZQuwezVneaojtV7CPJSiDUsVvB+HVIG9BmMi9cEtPC1MKKtRMLNm1HEaXauhc3fTdfCjXnBmPkOcTng==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.2.tgz", + "integrity": "sha512-Pa3zJIghawS9kyYdmlYBYRMjOueCNSJ41IRwye5T0ptqB42Y91myD5jyf5dI7jcCDXePLAi6lGg1Pv2VsJUL5A==", "requires": { "bindings": "~1.3.0", - "bsert": "~0.0.3", - "nan": "~2.10.0" + "bsert": "~0.0.4", + "nan": "~2.11.0" + }, + "dependencies": { + "nan": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" + } } }, "bsock": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.1.tgz", - "integrity": "sha512-rFY2MiUEdxhC21lzEVf7vV51c/vuADSYTySzHYML5uRl0bs013PrAF02j9dz0MaNRSivTxPMbAZvRlUhEahXdw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.3.tgz", + "integrity": "sha512-XE/xHURZU1jVZ3u7ByLr4ecUWmy/3IePIbf4yBEMA5mpOBgwgyBUEOZg7stjsbx1+3MYjNvE4G1y84WuLELulg==", "requires": { - "bsert": "~0.0.3", - "faye-websocket": "~0.11.1" + "bsert": "~0.0.4" } }, "bsocks": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.1.tgz", - "integrity": "sha512-RSoJL6j7C1bw9IHaxiKhEj2iga1TRNyW9EiMpDhfunbMM9xvP5xJ+oVmOCJLE+JEDRdWNESAgOeNZnn3q9fGdg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.2.tgz", + "integrity": "sha512-RRs21CTDM2hXt6Aj8rKu0ojzK9dKuJHmrQJstx/bneyhIyRDd+HItR4AbhficfvlcEy2zXUJ7eGypMHsIh91DQ==", "requires": { - "binet": "~0.3.1", - "bsert": "~0.0.3" + "binet": "~0.3.2", + "bsert": "~0.0.4" } }, "bstring": { @@ -538,9 +544,9 @@ } }, "btcp": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.1.tgz", - "integrity": "sha512-EwqraaSVjrMYSuSchJ0t2gdeA/4BGgKu+tFVJpTpc4pjzrlu9O6kc3NNffSyIzoxd7jToRdrsT3TorA03a/qwQ==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.2.tgz", + "integrity": "sha512-pLCWOthLQVRkgrVmIjyuL1/NVEhz0lnmgc0I+jm5ZYZ7rkuHYkjmq4qAzqMo/4EYMMAAbdq1CNhuhgVs65nl+A==" }, "buffer-alloc": { "version": "1.2.0", @@ -578,36 +584,36 @@ "integrity": "sha512-PjL1QglhgZCWEKWbxzlVB4ExvNorHMu0JSu4ehzeKi38R74Fp7duHAl8xNEqsbJXP5Dfym7XuSEkVol1KX5mhw==" }, "bupnp": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.2.tgz", - "integrity": "sha512-VauG03WYuZqqP+n/4gf/ItoZPgmSR76whDRFvAYvzsQzotTs3NfIKa7GGlykjAmvOPuuXqa2yVPNGV8dS+MomA==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.3.tgz", + "integrity": "sha512-2Q4AAQbpGWr2znRGrwdqjMcl6WzA7/aWtRaFYQWJ3qKxgNdTvPfA68g4/Ie4Bp/N4zBWgvZA0IO8CrEs6/olSQ==", "requires": { - "binet": "~0.3.1", - "brq": "~0.1.2", - "bsert": "~0.0.3" + "binet": "~0.3.2", + "brq": "~0.1.3", + "bsert": "~0.0.4" } }, "bval": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.2.tgz", - "integrity": "sha512-ewri8C/nc9ZHzkCMcpl6gVv9lMEvXw2CXppYIgDY0n1QKIVu8j0K1LT8F2Gm2kyqPGJI7Tp71V5bMhh4bPaZoA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.3.tgz", + "integrity": "sha512-DLQAjvVCbAUFVy2jnMyKtk4gjoYyQTXeu61ykPiTEOl/wdzgYGu5gdxvp3cLi6hzZzplOAgGG5zMc6w6+ZzoPA==", "requires": { - "bsert": "~0.0.3" + "bsert": "~0.0.4" } }, "bweb": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.2.tgz", - "integrity": "sha512-vNS62uURu16GpoByzfAUkwIjzgBcDI8GCgUKDmqSQD3eJPr3Lpu1QmU0nESbmC6HvLvWRy4OXdZu+dLobs0uog==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.4.tgz", + "integrity": "sha512-FcqJgkA8SA89KsqEcGo3nr6ZaOP4sobkocQn0vhwcoBrbl8an1vo27/2XazqhHaCuCPr2BhWK6q6ITHc00WGew==", "requires": { - "bsert": "~0.0.3", - "bsock": "~0.1.1" + "bsert": "~0.0.4", + "bsock": "~0.1.3" } }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" }, "cipher-base": { "version": "1.0.4", @@ -647,7 +653,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", @@ -659,7 +665,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", @@ -719,9 +725,9 @@ } }, "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -1935,14 +1941,6 @@ "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=" }, - "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, "flow-bin": { "version": "0.45.0", "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", @@ -2068,11 +2066,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "http-parser-js": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", - "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2149,12 +2142,13 @@ "dev": true }, "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "requires": { "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "mimic-response": { @@ -2183,7 +2177,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mkdirp": { @@ -2221,13 +2215,20 @@ } }, "mrmr": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.1.tgz", - "integrity": "sha512-2nJ8KlBZiFsj629GsqSBfx/ILWpL3+Kam8eMBn/YL84lvPUuAG0SNvtaGr8Z7T19wKOYnJAV5N+MCEXVgguxtQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.2.tgz", + "integrity": "sha512-Mp9g9pOJzR8sQT4hZhji4rICLM7FiJOfIvSuAYo8bRnWt3h4UuU0FNJFWuaOBKI+EJos0KVsVE3ddrewTrsVSg==", "requires": { "bindings": "~1.3.0", - "bsert": "~0.0.3", - "nan": "~2.10.0" + "bsert": "~0.0.4", + "nan": "~2.11.0" + }, + "dependencies": { + "nan": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" + } } }, "ms": { @@ -2237,13 +2238,13 @@ "dev": true }, "n64": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.1.tgz", - "integrity": "sha512-rs7dj53A2qK/bk4gQnBAp3DYwtyHKs5y2tbuQkgM4mDwGBI7fPJBbfBaXaNOpbVtnru2Aw++qVCNDYJ3XAuc7A==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.2.tgz", + "integrity": "sha512-GZwT9n1Il1T4v+CKlefieFcaq7rubLTsqbGIBtXpt8rDMhw/ZmjJMdoj0hT/Qk86uSYnQ/RisRHp4ZmPS2Qfjw==" }, "nan": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "next-tick": { @@ -2266,9 +2267,9 @@ } }, "node-abi": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.3.tgz", - "integrity": "sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.5.tgz", + "integrity": "sha512-aa/UC6Nr3+tqhHGRsAuw/edz7/q9nnetBrKWxj6rpTtm+0X9T1qU7lIEHMS3yN9JwAbRiKUbRRFy1PLz/y3aaA==", "requires": { "semver": "^5.4.1" } @@ -2384,7 +2385,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -2432,9 +2433,9 @@ } }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, "set-blocking": { "version": "2.0.0", @@ -2443,7 +2444,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "^2.0.1", @@ -2580,7 +2581,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -2631,16 +2632,16 @@ } }, "tar-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", - "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "requires": { "bl": "^1.0.0", - "buffer-alloc": "^1.1.0", + "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", "fs-constants": "^1.0.0", "readable-stream": "^2.3.0", - "to-buffer": "^1.1.0", + "to-buffer": "^1.1.1", "xtend": "^4.0.0" } }, @@ -2674,20 +2675,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", - "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" - }, "which-pm-runs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", From 4464140ff1fe61bd4dce51b626f2b71d3d4b2181 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 23 Oct 2018 16:25:36 +0100 Subject: [PATCH 500/540] Add testcase for no multisig addition to wallet --- minimal_testcases/msig_circulation.js | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 minimal_testcases/msig_circulation.js diff --git a/minimal_testcases/msig_circulation.js b/minimal_testcases/msig_circulation.js new file mode 100644 index 0000000..e645133 --- /dev/null +++ b/minimal_testcases/msig_circulation.js @@ -0,0 +1,107 @@ +const bcoin = require("bcoin").set("regtest"); +const WalletDB = bcoin.wallet.WalletDB; +const NodeClient = bcoin.wallet.NodeClient; +const MTX = bcoin.primitives.MTX; +const Script = bcoin.Script; +const Output = bcoin.primitives.Output; +const testHelpers = require("../test/helpers"); +const consensus = require("bcoin/lib/protocol/consensus"); +const assert = require("assert"); +const tag = require("../lib/tag"); + +const regtest = bcoin.Network.get().toString(); + +const wallets = Array(2); +const accounts = Array(2); +const rings = Array(2); +const pubKeys = Array(2); +const addresses = Array(2); + +let watcher = null; +let tx = null; + +const node = new bcoin.FullNode({ + network: regtest, + // passphrase: "secret" +}); + +const wdb = new WalletDB({ + network: regtest, + client: new NodeClient(node) +}); + +async function setup() { + await node.open(); + await node.connect(); + await wdb.open(); + node.startSync(); + + for (let i = 0; i < 2; i++) { + wallets[i] = await wdb.create({}); + accounts[i] = await wallets[i].getAccount("default"); + addresses[i] = accounts[i].receiveAddress(); + rings[i] = accounts[i].deriveReceive( + accounts[i].receiveDepth - 1, wallets[i].master + ); + pubKeys[i] = rings[i].getPublicKey(); + } + + consensus.COINBASE_MATURITY = 0; + await testHelpers.delay(500); + + watcher = new testHelpers.NodeWatcher(node); +} + +async function tearDown() { + await wdb.close(); + await node.close(); +} + +async function wait() { + for (let i = 0; i < 2; i++) { + console.log(i + " before"); + await watcher.waitForTX(tx, wallets[i]); + console.log(i + " after"); + } +} + +async function buildTX() { + // get coin + const block = await testHelpers.mineBlock(node, addresses[0]); + await testHelpers.delay(500); + + const hash = block.txs[0].hash().toString("hex"); + const coin = await node.getCoin(hash, 0); + + // build and send tx + const script = Script.fromMultisig(1, 3, [pubKeys[0], pubKeys[1], tag]); + //const script = Script.fromPubkeyhash(addresses[1].getHash()); + + const fee = 1000; + const trustAmount = coin.value - fee; + const outputs = [ + new Output({ + script: script, + value: trustAmount + }) + ] + const mtx = new MTX({outputs}); + mtx.addCoin(coin); + const signedCount = mtx.sign(rings[0]); + assert(signedCount === 1); + assert(mtx.verify()); + + return mtx.toTX(); +} + +(async () => { + await setup(); + + tx = await buildTX(); + + node.sendTX(tx); + + await wait(); + + await tearDown(); +})(); From 28422ff2ea88333e672996852a7184faa8bc31c3 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 1 Nov 2018 15:58:47 +0200 Subject: [PATCH 501/540] Attempt to waitForTX() through TIR --- minimal_testcases/msig_circulation.js | 6 ++++-- test/helpers.js | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/minimal_testcases/msig_circulation.js b/minimal_testcases/msig_circulation.js index e645133..861f026 100644 --- a/minimal_testcases/msig_circulation.js +++ b/minimal_testcases/msig_circulation.js @@ -1,4 +1,5 @@ const bcoin = require("bcoin").set("regtest"); +const Trust = require("../"); const WalletDB = bcoin.wallet.WalletDB; const NodeClient = bcoin.wallet.NodeClient; const MTX = bcoin.primitives.MTX; @@ -20,7 +21,7 @@ const addresses = Array(2); let watcher = null; let tx = null; -const node = new bcoin.FullNode({ +const node = new Trust.FullNode({ network: regtest, // passphrase: "secret" }); @@ -60,10 +61,11 @@ async function tearDown() { async function wait() { for (let i = 0; i < 2; i++) { console.log(i + " before"); - await watcher.waitForTX(tx, wallets[i]); + await watcher.waitForTX(tx/*, wallets[i]*/); console.log(i + " after"); } } +// TOUNDERSTAND: trustisrisk.addTX() is never called... async function buildTX() { // get coin diff --git a/test/helpers.js b/test/helpers.js index a4d897f..6f741fa 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -2,6 +2,7 @@ var TrustIsRisk = require("../"); var tag = require("../lib/tag"); var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); +var Wallet = bcoin.wallet.Wallet; var fixtures = require("./fixtures"); var assert = require("assert"); const consensus = require("bcoin/lib/protocol/consensus"); @@ -171,6 +172,10 @@ class NodeWatcher { } return; } + while (!this.node.trust.db.isTrustTX(input.hash("hex"))) { + await testHelpers.delay(100); + } + return; var initialCount = null; switch (typeof input) { case "number": From fd04d7aab5278ac4daa6b128dae667074d036902 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 6 Nov 2018 18:30:21 +0200 Subject: [PATCH 502/540] Lint --- test/helpers.js | 10 +++++----- test/spv_node.js | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 6f741fa..fe65ecc 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -9,15 +9,15 @@ const consensus = require("bcoin/lib/protocol/consensus"); var testHelpers = { isAllZeroes: (buf) => { - let flag = false + let flag = false; for (let i of buf) { if (i) { - console.log("there's an 1...") - flag = true - break + console.log("there's an 1..."); + flag = true; + break; } } - if (!flag) console.log("it's all 0!") + if (!flag) console.log("it's all 0!"); }, createWallet: async (walletDB, id) => { diff --git a/test/spv_node.js b/test/spv_node.js index c4e78de..729c0cd 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -138,16 +138,16 @@ describe("SPVNode", () => { it("should match a TIR transaction with the spv bloom filter", async function() { var wallet1 = await testHelpers.createWallet(minerWalletDB, "wallet1"); - var account1 = await wallet1.getAccount('default'); + var account1 = await wallet1.getAccount("default"); var type1 = account1.network.keyPrefix.coinType; var hd1 = wallet1.master.key.deriveAccount(44, type1, account1.accountIndex); - var origin = WalletKey.fromHD(account1, hd1, 0, 0) + var origin = WalletKey.fromHD(account1, hd1, 0, 0); var wallet2 = await testHelpers.createWallet(minerWalletDB, "wallet2"); - var account2 = await wallet2.getAccount('default'); + var account2 = await wallet2.getAccount("default"); var type2 = account2.network.keyPrefix.coinType; var hd2 = wallet2.master.key.deriveAccount(44, type2, account2.accountIndex); - var dest = WalletKey.fromHD(account2, hd2, 0, 0) + var dest = WalletKey.fromHD(account2, hd2, 0, 0); var block = await testHelpers.mineBlock(miner, origin.getKeyAddress("base58")); From 13ac321037b381ea42aebc2c5c8e98c5e7a0981d Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 6 Nov 2018 18:31:14 +0200 Subject: [PATCH 503/540] Check that wallet is of class Wallet --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index fe65ecc..2176621 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -165,7 +165,7 @@ class NodeWatcher { } async waitForTX(input, wallet) { - if (wallet) { + if (wallet instanceof Wallet) { while (!(await wallet.getTX(input.hash("hex")))) { await testHelpers.delay(100); //await this.waitForSomeTX(); From 01d5e960588caf53d72c7aa3b370674710f60d0d Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 6 Nov 2018 18:32:27 +0200 Subject: [PATCH 504/540] Initialize properly Trust node --- minimal_testcases/msig_circulation.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/minimal_testcases/msig_circulation.js b/minimal_testcases/msig_circulation.js index 861f026..ac95071 100644 --- a/minimal_testcases/msig_circulation.js +++ b/minimal_testcases/msig_circulation.js @@ -32,8 +32,7 @@ const wdb = new WalletDB({ }); async function setup() { - await node.open(); - await node.connect(); + await node.initialize(); await wdb.open(); node.startSync(); From c1367f6aae8943fb59206f85a1c90ddce1ec2ebc Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 11 Nov 2018 17:44:06 +0200 Subject: [PATCH 505/540] Increase test timeout to 30000ms Needed for spv circulation completion --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2cbee05..c129d20 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 20000", + "test": "npm run build && mocha -t 30000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 0682f81e7a3ad75af4247becc0fa04bc39998a43 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 11 Nov 2018 18:00:30 +0200 Subject: [PATCH 506/540] Export and use tag more cleanly --- src/index.js | 3 ++- test/helpers.js | 2 +- test/spv_node.js | 2 +- test/trust_is_risk.js | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index d7211ae..af35fd2 100644 --- a/src/index.js +++ b/src/index.js @@ -2,5 +2,6 @@ module.exports = { FullNode: require("./full_node"), SPVNode: require("./spv_node"), - TrustIsRisk: require("./trust_is_risk") + TrustIsRisk: require("./trust_is_risk"), + tag: require("./tag") }; diff --git a/test/helpers.js b/test/helpers.js index 2176621..0e1d81a 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,5 +1,5 @@ var TrustIsRisk = require("../"); -var tag = require("../lib/tag"); +var tag = TrustIsRisk.tag; var WalletDB = require("bcoin/lib/wallet/walletdb"); var bcoin = require("bcoin"); var Wallet = bcoin.wallet.Wallet; diff --git a/test/spv_node.js b/test/spv_node.js index 729c0cd..ee61231 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -13,7 +13,7 @@ var Input = bcoin.primitives.Input; var Output = bcoin.primitives.Output; var Outpoint = bcoin.primitives.Outpoint; var secp256k1 = bcrypto.secp256k1; -var tag = require("../lib/tag"); +var tag = Trust.tag; var testHelpers = require("./helpers"); var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 116987d..6b04849 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -11,7 +11,7 @@ var walletPlugin = bcoin.wallet.plugin; var TX = bcoin.primitives.TX; var TXRecord = bcoin.wallet.records.TXRecord; var testHelpers = require("./helpers"); -var tag = require("../lib/tag"); +var tag = Trust.tag; var consensus = require("bcoin/lib/protocol/consensus"); var sinon = require("sinon"); var should = require("should"); From 78489a40f37f440dadc59bbb3fb1d95cb72be056 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 11 Nov 2018 18:04:19 +0200 Subject: [PATCH 507/540] Let wdb know that it is spv --- test/spv_node.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index ee61231..46b1abf 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -63,11 +63,13 @@ describe("SPVNode", () => { beforeEach("connect SPV node, create walletDBs", async () => { spvWalletDB1 = new WalletDB({ network: bcoin.Network.get().toString(), - client: new NodeClient(spvNode1) + client: new NodeClient(spvNode1), + spv: true }); spvWalletDB2 = new WalletDB({ network: bcoin.Network.get().toString(), - client: new NodeClient(spvNode2) + client: new NodeClient(spvNode2), + spv: true }); await spvNode1.initialize(); await spvWalletDB1.open(); From ecb16a8b65fd5dcc1a753b62346b1afa25b80cae Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 11 Nov 2018 18:05:06 +0200 Subject: [PATCH 508/540] Add tag to spvFilter after opening wdb --- src/spv_node.js | 11 +++++++++-- test/spv_node.js | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/spv_node.js b/src/spv_node.js index 98329d1..fec13bb 100644 --- a/src/spv_node.js +++ b/src/spv_node.js @@ -2,7 +2,15 @@ var bcoin = require("bcoin"); var walletPlugin = bcoin.wallet.plugin; var TrustIsRisk = require("./trust_is_risk"); -var tag = require("./tag"); + +// Usage: +// const node = new Trust.SPVNode; +// const wdb = new bcoin.wallet.WalletDB({ +// client: new bcoin.wallet.NodeClient(node), +// spv: true +// }); +// await node.initialize(); +// node.pool.spvFilter.add(Trust.tag); class SPVNode extends bcoin.SPVNode { trust : TrustIsRisk @@ -17,7 +25,6 @@ class SPVNode extends bcoin.SPVNode { await this.trust.initialize(); await this.open(); await this.connect(); - this.pool.spvFilter.add(tag); } async tearDown() { diff --git a/test/spv_node.js b/test/spv_node.js index 46b1abf..afdbd15 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -73,8 +73,11 @@ describe("SPVNode", () => { }); await spvNode1.initialize(); await spvWalletDB1.open(); + spvNode1.pool.spvFilter.add(tag); + await spvNode2.initialize(); await spvWalletDB2.open(); + spvNode2.pool.spvFilter.add(tag); }); beforeEach("create full node", async () => { From 2732e78ea4c6e2c1aca78080da7459072896b30d Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 11 Nov 2018 18:06:37 +0200 Subject: [PATCH 509/540] Update TODOs --- minimal_testcases/msig_circulation.js | 1 - test/helpers.js | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/minimal_testcases/msig_circulation.js b/minimal_testcases/msig_circulation.js index ac95071..d441885 100644 --- a/minimal_testcases/msig_circulation.js +++ b/minimal_testcases/msig_circulation.js @@ -64,7 +64,6 @@ async function wait() { console.log(i + " after"); } } -// TOUNDERSTAND: trustisrisk.addTX() is never called... async function buildTX() { // get coin diff --git a/test/helpers.js b/test/helpers.js index 0e1d81a..413ba55 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -164,6 +164,9 @@ class NodeWatcher { } } + // TODO: + // 1. Wait gracefully with waitForSomeTX() (avoid polling) + // 2. Automatically add msig to wallet, like p2pkh (Make bcoin PR) async waitForTX(input, wallet) { if (wallet instanceof Wallet) { while (!(await wallet.getTX(input.hash("hex")))) { From 5d8449b6ed0a0bb7bd1e5f5224773e4173606c35 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 11 Nov 2018 18:07:12 +0200 Subject: [PATCH 510/540] Comment out part of testHelpers.waitForTX() --- test/helpers.js | 50 ++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 413ba55..887c3dc 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -179,31 +179,31 @@ class NodeWatcher { await testHelpers.delay(100); } return; - var initialCount = null; - switch (typeof input) { - case "number": - initialCount = input; - while (!(this.txCount > initialCount)) { - await this.waitForSomeTX(); - } - break; - - case "undefined": - await this.waitForTX(this.txCount); - break; - - case "object": - var tx = input; - while ((this.node.spv ? - !(this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) : - !(this.node.pool.hasTX(tx.hash().toString("hex"))))) { - await this.waitForSomeTX(); - } - break; - - default: - throw new Error("input cannot be " + typeof input); // TODO: throw correct error - } +// var initialCount = null; +// switch (typeof input) { +// case "number": +// initialCount = input; +// while (!(this.txCount > initialCount)) { +// await this.waitForSomeTX(); +// } +// break; +// +// case "undefined": +// await this.waitForTX(this.txCount); +// break; +// +// case "object": +// var tx = input; +// while ((this.node.spv ? +// !(this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) : +// !(this.node.pool.hasTX(tx.hash().toString("hex"))))) { +// await this.waitForSomeTX(); +// } +// break; +// +// default: +// throw new Error("input cannot be " + typeof input); // TODO: throw correct error +// } } async waitForTrustDB(tx) { From 8b2e20ca49f2f0cfc25fdd413b14d1413fa464ca Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Tue, 13 Nov 2018 00:15:56 +0000 Subject: [PATCH 511/540] Update node.js version --- package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9246d4d..d12289a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -400,7 +400,7 @@ }, "bl": { "version": "1.2.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { "readable-stream": "^2.3.5", @@ -467,7 +467,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "^1.0.3", @@ -653,7 +653,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", @@ -665,7 +665,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", @@ -2177,7 +2177,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mkdirp": { @@ -2244,7 +2244,7 @@ }, "nan": { "version": "2.10.0", - "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "next-tick": { @@ -2385,7 +2385,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -2444,7 +2444,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "^2.0.1", @@ -2581,7 +2581,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" From 347321d55ae01f433d836e72442ec755c1f60c12 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 10 Jan 2019 00:50:55 +0000 Subject: [PATCH 512/540] Change tag to master HD key --- flow-typed/npm/bcoin_vx.x.x.js | 11 +++++++++++ src/index.js | 2 +- src/tag.js | 12 +++++++++++- src/trust_is_risk.js | 2 +- src/types.js | 2 +- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/flow-typed/npm/bcoin_vx.x.x.js b/flow-typed/npm/bcoin_vx.x.x.js index 042d0ff..e0e6798 100644 --- a/flow-typed/npm/bcoin_vx.x.x.js +++ b/flow-typed/npm/bcoin_vx.x.x.js @@ -66,6 +66,12 @@ declare class bcoin$Pool { hasTX(hash : Hash) : boolean; } +declare class bcoin$HDPublicKey { + publicKey : Buffer; + + fromOptions(options : Object) : bcoin$HDPublicKey; +} + declare class bcoin$Bloom { test(val : (Buffer | string), enc : (typeof undefined | string)) : boolean; @@ -201,6 +207,11 @@ declare module 'bcoin' { KeyRing : Class, Coin : Class }, + hd : { + HD : { + HDPublicKey : bcoin$HDPublicKey; + } + }, base58 : { encode(str : (string | Buffer)) : Buffer }, diff --git a/src/index.js b/src/index.js index af35fd2..540ab0f 100644 --- a/src/index.js +++ b/src/index.js @@ -3,5 +3,5 @@ module.exports = { FullNode: require("./full_node"), SPVNode: require("./spv_node"), TrustIsRisk: require("./trust_is_risk"), - tag: require("./tag") + tag: require("./tag").publicKey }; diff --git a/src/tag.js b/src/tag.js index 13e5dba..50ad55b 100644 --- a/src/tag.js +++ b/src/tag.js @@ -1,7 +1,9 @@ // @flow import type {Key} from "./types"; +const bcoin = require("bcoin"); +const HDPublicKey = bcoin.hd.HD.HDPublicKey; -const tag : Key = Buffer.from([0x04, // constant 0x04 prefix +const pubKey : Key = Buffer.from([0x04, // constant 0x04 prefix 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" @@ -12,4 +14,12 @@ const tag : Key = Buffer.from([0x04, // constant 0x04 prefix 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]); +const tag : bcoin$HDPublicKey = HDPublicKey.fromOptions({ + depth: 0, + parentFingerPrint: 0, + childIndex: 0, + chainCode: Buffer.from("dc446622bb58bc4bb95c7972ee75ff7bc5d23cb9e7edefe79cb9234080b9f243", "hex"), + publicKey: pubKey +}); + module.exports = tag; diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index a8a7dc9..ae8862c 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -16,7 +16,7 @@ var assert = require("assert"); var helpers = require("./helpers"); var TrustDB = require("./trust_db"); var DirectTrust = require("./direct_trust"); -var tag = require("./tag"); +var tag = require("./tag").publicKey; class TrustIsRisk { node : (bcoin$FullNode | bcoin$SPVNode) diff --git a/src/types.js b/src/types.js index 1bb788b..35752de 100644 --- a/src/types.js +++ b/src/types.js @@ -1,6 +1,6 @@ //@flow -// base58 bitcoin address: +// base58 bitcoin address: export type Entity = string; export type TXHash = string; From fc576282d1f5414244629d1256ef7d32f30dc5ef Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 10 Jan 2019 09:00:01 +0000 Subject: [PATCH 513/540] Update partly full node test for bcoin@1.0.2 --- test/full_node.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index 677bc9d..ddbeee4 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -55,7 +55,7 @@ describe("FullNode", () => { wallet = await testHelpers.createWallet(walletDB, "wallet"); for (let name in fixtures.keyRings) { - await wallet.importKey(fixtures.keyRings[name], "secret"); + await wallet.importKey("default", fixtures.keyRings[name], "secret"); } }); @@ -74,7 +74,8 @@ describe("FullNode", () => { await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. - await testHelpers.mineBlock(node, sender.getAddress("base58")); + const sendAddr = await sender.receiveAddress(); + await testHelpers.mineBlock(node, {hash: sendAddr.hash}); // Make the coin spendable. consensus.COINBASE_MATURITY = 0; @@ -83,10 +84,10 @@ describe("FullNode", () => { let tx = await sender.send({ outputs: [{ value: 10 * COIN, - address: receiver.getAddress("base58") + address: await receiver.receiveAddress(); }] }); - await watcher.waitForTX(tx); + await watcher.waitForTX(tx/*, wallet*/); // gets stuck here... await testHelpers.flushEvents(); // @dionyziz: needs @ least 3 ms...? node.trust.addTX.should.have.been.calledOnce(); From be555d20654f9f6ec910f959673f515fe612337f Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 9 Feb 2019 13:21:31 +0000 Subject: [PATCH 514/540] Add example of keyring generation from HD path --- minimal_testcases/keyring-from-path.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 minimal_testcases/keyring-from-path.js diff --git a/minimal_testcases/keyring-from-path.js b/minimal_testcases/keyring-from-path.js new file mode 100644 index 0000000..5b9d73d --- /dev/null +++ b/minimal_testcases/keyring-from-path.js @@ -0,0 +1,19 @@ +// this is how to generate a keyring from a path! +const _ = require("lodash") +const assert = require("assert") +const WalletDB = require("bcoin/lib/wallet/walletdb") +const WalletKey = require("bcoin/lib/wallet/walletkey"); + +(async () => { + const wdb = new WalletDB() + await wdb.open() + const wallet = wdb.create() + const acct = await wdb.getAccount(0, 0) + const key1 = acct.receiveKey() + const path = await wdb.getPath(0, key1.getHash()) + const acctKey = acct.accountKey.derive(path.branch).derive(path.index) + const key2 = WalletKey.fromHD(acct, acctKey, path.branch, path.index) + // just to populate key2._keyHash + key2.getHash() + assert(_.isEqual(key1, key2)) +})() From 54d6e08a2addc3ae1026b0f2a58fe3ab119235a7 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sat, 9 Feb 2019 13:24:34 +0000 Subject: [PATCH 515/540] Update --- package-lock.json | 299 ++++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 169 insertions(+), 132 deletions(-) diff --git a/package-lock.json b/package-lock.json index d12289a..28bb764 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,15 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@sinonjs/commons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, "@sinonjs/formatio": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", @@ -13,6 +22,17 @@ "samsam": "1.3.0" } }, + "@sinonjs/samsam": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.1.0.tgz", + "integrity": "sha512-IXio+GWY+Q8XUjHUOgK7wx8fpvr7IFffgyXb1bnJFfX3001KmHt35Zq4tp7MXZyjJPCLPuadesDYNk41LYtVjw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash.get": "^4.4.2" + } + }, "abstract-leveldown": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", @@ -40,6 +60,12 @@ "readable-stream": "^2.0.6" } }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, "babel-eslint": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", @@ -256,21 +282,21 @@ "dev": true }, "bcfg": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.3.tgz", - "integrity": "sha512-N/ZpKumfVYcAE5nYc0t4guvMGmtFaFn2QLUVZ0+0e1DBoRR7U6uh94pES7d2R7BKiYuVN1EI9bgOGmWGK4Kvig==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.4.tgz", + "integrity": "sha512-tgweKJnFlFqg/QA3l+9i4cSJTHPcABrBriRZkUd+MM9mUCv8tBqAZFoykR0Cn3Fi9ygJ/pyWfmjDkRVZQwvPkQ==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bclient": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.4.tgz", - "integrity": "sha512-1/O/X1iVy1Vxydcuw5zIe/5AERcfUNbV48MPs1g7ZWa0/1Lhve432vgA5OKLQXrHADABF1vuE+ar+mGMKEiOiw==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.5.tgz", + "integrity": "sha512-LtlH6i66dVIztUVyd2ItU3sRwNT/+X/zIEXP5wxz8boP0tARIRjCB1THoYg6PtPaONZ+k/W2VkzYl9XjWTsOpQ==", "requires": { - "bcfg": "~0.1.3", - "bcurl": "~0.1.3", - "bsert": "~0.0.4" + "bcfg": "~0.1.4", + "bcurl": "~0.1.4", + "bsert": "~0.0.5" } }, "bcoin": { @@ -320,13 +346,13 @@ } }, "bcurl": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.3.tgz", - "integrity": "sha512-l9tG3yH52f0QYwP0g0G6K9fwpOi/1A95D9vIjAcoEMQaGl2jETxvRjiVsxMWBzo0OTwjjAZOc6HyDo1ZbkfI4g==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.4.tgz", + "integrity": "sha512-wy+/9uBQWrcNcMy4qCl241qATNnB0evBO5oTJboINXXG3c152wDyEnedAvypkOp4Mh0fYrlsO6yYr5RmRXnVIQ==", "requires": { - "brq": "~0.1.3", - "bsert": "~0.0.4", - "bsock": "~0.1.3" + "brq": "~0.1.4", + "bsert": "~0.0.5", + "bsock": "~0.1.4" } }, "bdb": { @@ -339,25 +365,25 @@ } }, "bdns": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.2.tgz", - "integrity": "sha512-/b5KwvM5Uxb+CTFN/PjaJttHEcwTDQoZingvJViyQXS61aau4sqMBAZbKaS30ULq9c08sWamUWEnJGSSKq5gcA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.3.tgz", + "integrity": "sha512-d071TLX00NZCqhKNspsKU8N8ApqqVizSEdEB7bCE5tUQgFS1UMHjnN0C8HDd5kRYwIX3jAIsN+oNgREvZCGOcA==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bevent": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.2.tgz", - "integrity": "sha512-YOqqEs+hvQ7n/VmxnfxM3jwxYAGcGO1Ls09RTCAsstROi9nVGhSMTnRi5OIPjlT9l+oFdQFUrExPxdSlXj4laQ==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.3.tgz", + "integrity": "sha512-bTsC1MSSWxn0E0OrjrY8j/Sz/C2u3FuAhaO2CaEyc5a5uLwcvC8MK9b14oW0fW/k0AGKQHkuebJOI1RRzArBFQ==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bfile": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.2.tgz", - "integrity": "sha512-k/GnFlGvy3Pxsko3BLpvyEPdFeSXrsq56fB6Zms8jlsiRv3BFDvzm2DI/RWFZzhEpiGPFjjFA6UamJZVBKUyzQ==" + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.3.tgz", + "integrity": "sha512-7OScx3u416zFsloaN2CyVXRwVAOJdFBpNrpvGlUbkVD2gEzpj+d7/38MInEXnFtcmErDiY1DFR2URBT4J/7kRg==" }, "bfilter": { "version": "0.2.0", @@ -369,25 +395,25 @@ } }, "bheep": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.2.tgz", - "integrity": "sha512-Ud+Y5iPGlHMgu2oaYSOPZNBqtUGn+/f7sLrvjpY81mHGDiH5bVDOCp13Wey57pdV6UBzz3L+LpskPRvN1YJ65g==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.3.tgz", + "integrity": "sha512-Epqqqokl8M0o2qPx/3Z4OPxzGVFmp3JTQubzoUfWD7uucx5x3opRvcPA/UltLrSL9/b2LA+KIg1s/zyPlpGyrQ==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bindings": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", + "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==" }, "binet": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.2.tgz", - "integrity": "sha512-ZsH2u3HlVgtN0K1XyQO9wLHe8qFpBq4c4tmOK8y83nnm8+VgI6Am365VVgpigwg4zZmMSa9MYfcPWdWWMMrBAA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.3.tgz", + "integrity": "sha512-EQX5k4WfYDkDhiKyK11Z90jkTLC9yAw4luSpr7+zfT0VW+/fy4Zizf3FoRyAtI7CWV803NybAcfDZz94wAtziA==", "requires": { - "bs32": "~0.1.2", - "bsert": "~0.0.4" + "bs32": "~0.1.3", + "bsert": "~0.0.5" } }, "bip66": { @@ -408,35 +434,35 @@ } }, "blgr": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.2.tgz", - "integrity": "sha512-PPX5ULDnOM8Hrky+6SihZQpHniIKp+0RjXVzFI0Ca6533ItHnd6YXU0VbM5VFWZ/dYc7FC74hWPu0j7yYJm2MQ==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.4.tgz", + "integrity": "sha512-eAYRZxI0mtInsANQbhm9zJAkpSQh4QUBYiW8pPznrLeH34NqQxTmFHY1ot3d7wFZoSGIDZ0wFBd5CDzFNP0h5A==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "blru": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.3.tgz", - "integrity": "sha512-VABNB1X4/9hahUwZL299ogkkob0+oHS65Hx3rKSVs+mUEU1VURhOkkzXxnvOCBSlECSjGHbd88gEc9PiEboDeA==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.4.tgz", + "integrity": "sha512-qq82TVa2GDcjv/BswxH7hpDZEr2Cu8XLVoHmLt7jZMAHKZ3jzTtyQCsuUOZXILpOwduqB8AC6R79bvclNWwRKw==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "blst": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.2.tgz", - "integrity": "sha512-R4lsoIwklHXTxGEkp7hhknr0zN41UhGNFsRd5zNJ7Wa67kAFlUFqcMqTpgzbFTZ9S0Cf37hn8OfeBhvFwVtvrg==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.3.tgz", + "integrity": "sha512-bDZC68tjfflVuC7OGy+vlF6VtlW1Jtk8isH2116LoCLE9MCgTu2N2yTaT5CFuUF3yB1s0gGiWVR3uJpF+27HFw==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bmutex": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.3.tgz", - "integrity": "sha512-VR6fZbVl2/GZOSUy2Cpl7ijVZKP/Ma9JUaGQBSw/xW5lJB7fF2qzmY0BLJ0s0TG+lAY0+1yqPiA3Nj1mlDEUdA==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.4.tgz", + "integrity": "sha512-uSlUggS46kO/ziGZQKVE6nMbZrrlhmG+uw/VgBi54dkDO32DLTTlSQsLeRQHeKj4Zl+B389Pmizvz5J+VYYKFw==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bn.js": { @@ -479,34 +505,34 @@ } }, "brq": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.3.tgz", - "integrity": "sha512-3wTf6IXQInJ8MedIuWmFcKL33dce7EZ7fY5aDSxzStSuvuODmpjXqNhxJ8RZ497l9CDA55Eyq1g1fJrT4LSfQQ==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.4.tgz", + "integrity": "sha512-VPQtZgDjc3awXuzpuGrjuJtqsImDKrj7z4tVWC2bMafutD4Efx50otZMyxvQzJlQz3kXK3uAKonrHLKWy0Yo+A==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bs32": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.2.tgz", - "integrity": "sha512-d+6l8lN4OBd2Xp3hGqfRofR0QVztY2cdCyT4eSGjKFnEpEwrCW+h/FvInm13hHmjTqkkrxgdsKyPtvH7pGNV7Q==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.3.tgz", + "integrity": "sha512-pTVLcFJxmAUMjtfLqaBkqCPybquBQCjxKcpVIYEDqPpXIabctuNTnK+6W4Z8WcGyLJijkAWU9ZOI9xARexT8uQ==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bsert": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.4.tgz", - "integrity": "sha512-VReLe1aTaHRmf80YLOHUk8ONQ48SjseZP76GlNIDheD5REYByn/Mm9yrtI0/ZCaFrcfxzgpiw1/hMMCUOSMa3w==" + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.5.tgz", + "integrity": "sha512-prgSa82RHcsdEM7SKYl1S7j0tKeiE3SF8C3B39MyUrpbP66diJK16RIkbFC2pXvQx4xitN0xMgBHKBAgBldX1w==" }, "bsip": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.2.tgz", - "integrity": "sha512-Pa3zJIghawS9kyYdmlYBYRMjOueCNSJ41IRwye5T0ptqB42Y91myD5jyf5dI7jcCDXePLAi6lGg1Pv2VsJUL5A==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.4.tgz", + "integrity": "sha512-ZC5Dsa5k1+24DorSOgXeDgV9f7OxLcvZiXDYYjHN1mkW8OF/abNSKlogDgVrx/znpAAZ1yJPkWgrub/FsIxEmA==", "requires": { - "bindings": "~1.3.0", - "bsert": "~0.0.4", - "nan": "~2.11.0" + "bindings": "~1.3.1", + "bsert": "~0.0.5", + "nan": "~2.11.1" }, "dependencies": { "nan": { @@ -517,26 +543,26 @@ } }, "bsock": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.3.tgz", - "integrity": "sha512-XE/xHURZU1jVZ3u7ByLr4ecUWmy/3IePIbf4yBEMA5mpOBgwgyBUEOZg7stjsbx1+3MYjNvE4G1y84WuLELulg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.4.tgz", + "integrity": "sha512-3hfPScf58kC13udMqXL/GiBubUOmwwMaTljIY8xJI0pO2uOmAaDyBCqT/PiteXRHHC1lDinK2wkFayc4xX92Wg==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bsocks": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.2.tgz", - "integrity": "sha512-RRs21CTDM2hXt6Aj8rKu0ojzK9dKuJHmrQJstx/bneyhIyRDd+HItR4AbhficfvlcEy2zXUJ7eGypMHsIh91DQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.3.tgz", + "integrity": "sha512-Mc6yqYNqPHaZkYYppCctrsZUmoISGBZQmjKnd4P8xxKeKH4KnM0JZJigF6y0QTRjq+e/+7AvSSxoSsUeGh7CYQ==", "requires": { - "binet": "~0.3.2", - "bsert": "~0.0.4" + "binet": "~0.3.3", + "bsert": "~0.0.5" } }, "bstring": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bstring/-/bstring-0.1.1.tgz", - "integrity": "sha512-xpJd187BAzrW9DbXuttGhAnsPRZNfRuehYd1Qds7IGj64TISNtvXqlqqebRmOcpweGwkZiBGItNoMkGbF4Qomg==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/bstring/-/bstring-0.1.2.tgz", + "integrity": "sha512-n7FeLSrKfsPnZstqA9PfPME1apI9u9WB35aDbsubWzLz1GjpgXewCXYyq9/m8c/IB/pFXRwqs0XwL/qq5IGJPQ==", "requires": { "bindings": "~1.3.0", "bsert": "~0.0.3", @@ -544,9 +570,9 @@ } }, "btcp": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.2.tgz", - "integrity": "sha512-pLCWOthLQVRkgrVmIjyuL1/NVEhz0lnmgc0I+jm5ZYZ7rkuHYkjmq4qAzqMo/4EYMMAAbdq1CNhuhgVs65nl+A==" + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.3.tgz", + "integrity": "sha512-5UV2yOHOwpIhAVqUqiC7MyHdX4coTJPcOnJik3guV+99cVo5ZK/2oKb/w+e2PBxLrsy2c93EF5/DamzmG1QqSA==" }, "buffer-alloc": { "version": "1.2.0", @@ -584,30 +610,30 @@ "integrity": "sha512-PjL1QglhgZCWEKWbxzlVB4ExvNorHMu0JSu4ehzeKi38R74Fp7duHAl8xNEqsbJXP5Dfym7XuSEkVol1KX5mhw==" }, "bupnp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.3.tgz", - "integrity": "sha512-2Q4AAQbpGWr2znRGrwdqjMcl6WzA7/aWtRaFYQWJ3qKxgNdTvPfA68g4/Ie4Bp/N4zBWgvZA0IO8CrEs6/olSQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.4.tgz", + "integrity": "sha512-7H1zZkX4Jba+CmY1sxAuceIZoEXAYGi767chlBrGfqFwwf1Bt4DYMsAw65Xxdu/zsLd2nsUSXliV20Txdf76xw==", "requires": { - "binet": "~0.3.2", - "brq": "~0.1.3", - "bsert": "~0.0.4" + "binet": "~0.3.3", + "brq": "~0.1.4", + "bsert": "~0.0.5" } }, "bval": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.3.tgz", - "integrity": "sha512-DLQAjvVCbAUFVy2jnMyKtk4gjoYyQTXeu61ykPiTEOl/wdzgYGu5gdxvp3cLi6hzZzplOAgGG5zMc6w6+ZzoPA==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.4.tgz", + "integrity": "sha512-mCPe86NoWCCO/W4Yvx6dfA2Tr45wP3NAKCeZvwN01ODj5ecdllaD/UHthVjH16/yZa59nxtrA2sBi6Mi83QmXg==", "requires": { - "bsert": "~0.0.4" + "bsert": "~0.0.5" } }, "bweb": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.4.tgz", - "integrity": "sha512-FcqJgkA8SA89KsqEcGo3nr6ZaOP4sobkocQn0vhwcoBrbl8an1vo27/2XazqhHaCuCPr2BhWK6q6ITHc00WGew==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.6.tgz", + "integrity": "sha512-Fuyi0DrtpeQbXO0Srg8JtHWM+t5/XPFcXcXcu61zU3lVeYrYdcITu6+I+qKy6v9esRWbvc+yh117lz9/Wm/Qnw==", "requires": { - "bsert": "~0.0.4", - "bsock": "~0.1.3" + "bsert": "~0.0.5", + "bsock": "~0.1.4" } }, "chownr": { @@ -1914,9 +1940,9 @@ } }, "eslint-plugin-flowtype": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.0.tgz", - "integrity": "sha512-10FnBXCp8odYcpUFXGAh+Zko7py0hUWutTd3BN/R9riukH360qNPLYPR3/xV9eu9K7OJDjJrsflBnL6RwxFnlw==", + "version": "2.50.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", + "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", "dev": true, "requires": { "lodash": "^4.17.10" @@ -2042,9 +2068,9 @@ } }, "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -2106,9 +2132,9 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "just-extend": { - "version": "1.1.27", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", - "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", "dev": true }, "leveldown": { @@ -2124,9 +2150,9 @@ } }, "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lodash.get": { @@ -2215,13 +2241,13 @@ } }, "mrmr": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.2.tgz", - "integrity": "sha512-Mp9g9pOJzR8sQT4hZhji4rICLM7FiJOfIvSuAYo8bRnWt3h4UuU0FNJFWuaOBKI+EJos0KVsVE3ddrewTrsVSg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.4.tgz", + "integrity": "sha512-i2kWXVPLExnVOO7qP861WZxK+pfJ9Rppujfl7lS5sfqWSvQbNz8OouEUgcVk6EsRiH4tDHx6yM6LQQhl0jrjXw==", "requires": { - "bindings": "~1.3.0", - "bsert": "~0.0.4", - "nan": "~2.11.0" + "bindings": "~1.3.1", + "bsert": "~0.0.5", + "nan": "~2.11.1" }, "dependencies": { "nan": { @@ -2238,9 +2264,9 @@ "dev": true }, "n64": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.2.tgz", - "integrity": "sha512-GZwT9n1Il1T4v+CKlefieFcaq7rubLTsqbGIBtXpt8rDMhw/ZmjJMdoj0hT/Qk86uSYnQ/RisRHp4ZmPS2Qfjw==" + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.5.tgz", + "integrity": "sha512-wry9grq4tNsxvpW2hqXNJIxqv9pT3+NEs/nyg9z5nKQ4QCB6b9IF2DSpVBEC/9fxX6c6G5hJ+SzK/Iv2k+896w==" }, "nan": { "version": "2.10.0", @@ -2254,22 +2280,33 @@ "dev": true }, "nise": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.1.tgz", - "integrity": "sha512-9JX3YwoIt3kS237scmSSOpEv7vCukVzLfwK0I0XhocDSHUANid8ZHnLEULbbSkfeMn98B2y5kphIWzZUylESRQ==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", "dev": true, "requires": { - "@sinonjs/formatio": "^2.0.0", - "just-extend": "^1.1.27", + "@sinonjs/formatio": "^3.1.0", + "just-extend": "^4.0.2", "lolex": "^2.3.2", "path-to-regexp": "^1.7.0", "text-encoding": "^0.6.4" + }, + "dependencies": { + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + } } }, "node-abi": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.5.tgz", - "integrity": "sha512-aa/UC6Nr3+tqhHGRsAuw/edz7/q9nnetBrKWxj6rpTtm+0X9T1qU7lIEHMS3yN9JwAbRiKUbRRFy1PLz/y3aaA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.5.0.tgz", + "integrity": "sha512-9g2twBGSP6wIR5PW7tXvAWnEWKJDH/VskdXp168xsw9VVxpEGov8K4jsP4/VeoC7b2ZAyzckvMCuQuQlw44lXg==", "requires": { "semver": "^5.4.1" } diff --git a/package.json b/package.json index c129d20..2b4e8f4 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "devDependencies": { "babel-eslint": "^7.2.3", "eslint": "^3.19.0", - "eslint-plugin-flowtype": "^2.50.0", + "eslint-plugin-flowtype": "^2.50.3", "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.0", "mocha": "^5.2.0", From e0fa45c3aad7c54dfe1bef90be6703799aac6c15 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 10 Feb 2019 03:41:20 +0000 Subject: [PATCH 516/540] Update full node --- test/full_node.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index ddbeee4..fd66efb 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -1,7 +1,8 @@ var Trust = require("../"); var helpers = require("../lib/helpers.js"); var bcoin = require("bcoin").set("regtest"); -var Script = bcoin.script; +var bcrypto = require("bcrypto"); +var Script = bcoin.script.Script; var WalletDB = bcoin.wallet.WalletDB; var NodeClient = bcoin.wallet.NodeClient; var Address = bcoin.primitives.Address; @@ -84,11 +85,11 @@ describe("FullNode", () => { let tx = await sender.send({ outputs: [{ value: 10 * COIN, - address: await receiver.receiveAddress(); + address: await receiver.receiveAddress() }] }); - await watcher.waitForTX(tx/*, wallet*/); // gets stuck here... - await testHelpers.flushEvents(); // @dionyziz: needs @ least 3 ms...? + await watcher.waitForTX(tx, receiver); + await testHelpers.flushEvents(); node.trust.addTX.should.have.been.calledOnce(); }); @@ -128,7 +129,7 @@ describe("FullNode", () => { var changeAmount = 50 * blockCount - sendAmount * fixtures.names.length - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160( + script: Script.fromPubkeyhash(bcrypto.Hash160.digest( fixtures.keyRings.alice.getPublicKey())), value: changeAmount * consensus.COIN })); @@ -147,7 +148,7 @@ describe("FullNode", () => { let tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(tx); // @dionyziz: does not work with wallet + await watcher.waitForTX(tx, wallet); await testHelpers.flushEvents(); prevout = {}; From 0211eef6dff5d681b2aba8671e0bb730e027f5d8 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 10 Feb 2019 15:49:15 +0000 Subject: [PATCH 517/540] Increase test time --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b4e8f4..3afdc75 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 30000", + "test": "npm run build && mocha -t 60000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", From 29ccd7bc3007d5e30f43cc5e5f3dbfb81c4563a7 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 10 Feb 2019 15:50:03 +0000 Subject: [PATCH 518/540] Update spv test for latest bcoin --- test/spv_node.js | 147 +++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 74 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index afdbd15..4697fd1 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -23,6 +23,7 @@ var fixtures = require("./fixtures"); require("should-sinon"); const COIN = consensus.COIN; +const regtest = bcoin.Network.get().toString(); describe("SPVNode", () => { var spvNode1 = null; @@ -41,14 +42,14 @@ describe("SPVNode", () => { beforeEach("create SPV nodes", async () => { spvNode1 = new Trust.SPVNode({ - network: bcoin.Network.get().toString(), + network: regtest, httpPort: 48445, passphrase: "secret", nodes: ["127.0.0.1:48448"] }); spvNode2 = new Trust.SPVNode({ - network: bcoin.Network.get().toString(), + network: regtest, httpPort: 48446, passphrase: "secret", nodes: ["127.0.0.1:48448"] @@ -62,12 +63,12 @@ describe("SPVNode", () => { beforeEach("connect SPV node, create walletDBs", async () => { spvWalletDB1 = new WalletDB({ - network: bcoin.Network.get().toString(), + network: regtest, client: new NodeClient(spvNode1), spv: true }); spvWalletDB2 = new WalletDB({ - network: bcoin.Network.get().toString(), + network: regtest, client: new NodeClient(spvNode2), spv: true }); @@ -82,7 +83,7 @@ describe("SPVNode", () => { beforeEach("create full node", async () => { miner = new Trust.FullNode({ - network: bcoin.Network.get().toString(), + network: regtest, port: 48448, bip37: true, //logConsole: true, @@ -98,7 +99,7 @@ describe("SPVNode", () => { beforeEach("connect full node, create walletDB", async () => { minerWalletDB = new WalletDB({ - network: bcoin.Network.get().toString(), + network: regtest, client: new NodeClient(miner) }); await miner.initialize(); @@ -254,40 +255,65 @@ describe("SPVNode", () => { "dave": "dave" }; + const names = Object.assign({}, minerNames, spvNames); + var minerWallets = {}; var spvWallets = {}; - var addresses = {}, rings = {}, name = null; + const addresses = {}, accounts = {}, rings = {}; beforeEach("apply graph transactions", async () => { - for (name in minerNames) { + for (const name in minerNames) { minerWallets[name] = await testHelpers.createWallet( minerWalletDB, name ); - rings[name] = await minerWallets[name].getPrivateKey( - minerWallets[name].getAddress("base58"), "secret" - ); - addresses[name] = helpers.pubKeyToEntity( - rings[name].getPublicKey(), miner.network + accounts[name] = await minerWallets[name].getAccount("default"); + rings[name] = accounts[name].deriveReceive( + accounts[name].receiveDepth - 1, minerWallets[name].master ); - spvNode.pool.watchAddress(addresses[name]); + spvNode1.pool.watch(rings[name].getPublicKey(null, regtest)); + addresses[name] = rings[name].getAddress(null, regtest); + spvNode1.pool.watchAddress(addresses[name]); + + const wid = minerWallets[name].wid; + const unlock = await minerWallets[name].writeLock.lock(); + try { + const batch = minerWallets[name].db.batch(); + await minerWalletDB.addPathMap(batch, bcoin.primitives.KeyRing.fromPublic( + tag).getHash('hex'), wid); + batch.write(); + } finally { + unlock(); + } } - for (name in spvNames) { + const layout = require('bcoin/lib/wallet/layout').wdb; + for (const name in spvNames) { spvWallets[name] = await testHelpers.createWallet( - spvWalletDB, name - ); - rings[name] = await spvWallets[name].getPrivateKey( - spvWallets[name].getAddress("base58"), "secret" + spvWalletDB1, name ); - addresses[name] = helpers.pubKeyToEntity( - rings[name].getPublicKey(), spvNode.network + accounts[name] = await spvWallets[name].getAccount("default"); + rings[name] = accounts[name].deriveReceive( + accounts[name].receiveDepth - 1, spvWallets[name].master ); - spvNode.pool.watchAddress(addresses[name]); + spvNode1.pool.watch(rings[name].getPublicKey("hex", regtest)); + addresses[name] = rings[name].getAddress(null, regtest); + spvNode1.pool.watchAddress(addresses[name]); + + const wid = spvWallets[name].wid; + const unlock = await spvWallets[name].writeLock.lock(); + try { + const batch = spvWallets[name].db.batch(); + await spvWalletDB1.addPathMap(batch, bcoin.primitives.KeyRing.fromPublic( + tag).getHash('hex'), wid); + batch.write(); + } finally { + unlock(); + } } // Alice mines three blocks, each rewards her with 50 spendable BTC - consensus.COINBASE_MATURITY = 0; + //consensus.COINBASE_MATURITY = 0; var blockCount = 3; var coinbaseHashes = []; for(let i = 0; i < blockCount; i++) { @@ -320,8 +346,8 @@ describe("SPVNode", () => { (Object.keys(minerNames).length + Object.keys(spvNames).length) - fee; if (changeAmount >= 0.01) { outputs.push(new Output({ - script: Script.fromPubkeyhash(bcoin.crypto.hash160( - rings["alice"].publicKey)), + script: Script.fromPubkeyhash(bcrypto.Hash160.digest( + rings["alice"].getPublicKey())), value: changeAmount * consensus.COIN })); } @@ -332,7 +358,6 @@ describe("SPVNode", () => { })); var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); - var signedCount = mtx.sign(rings["alice"]); assert(signedCount === blockCount); assert(mtx.verify()); @@ -340,28 +365,18 @@ describe("SPVNode", () => { var tx = mtx.toTX(); miner.sendTX(tx); - await minerWatcher.waitForTX(tx); - await spvWatcher.waitForTX(tx); - + //TODO: use Promise.all for (name in minerNames) { - minerWallets[name].db.addTX(tx); + await minerWatcher.waitForTX(tx, minerWallets[name]); } - for (name in spvNames) { - spvWallets[name].db.addTX(tx); + await spvWatcher1.waitForTX(tx, spvWallets[name]); } var prevout = {}; var counter = 0; - for (name in minerNames) { - prevout[name] = { - hash: tx.hash().toString("hex"), - index: counter++ - }; - } - - for (name in spvNames) { + for (const name in names) { prevout[name] = { hash: tx.hash().toString("hex"), index: counter++ @@ -376,7 +391,7 @@ describe("SPVNode", () => { function buildVars(player) { return (spvNames[player]) ? - [spvNode, spvWatcher, spvWallets[player]] : + [spvNode1, spvWatcher1, spvWallets[player]] : [miner, minerWatcher, minerWallets[player]]; } @@ -405,7 +420,6 @@ describe("SPVNode", () => { [node.dest, watcher.dest, wallet.dest] = buildVars(dest); - let outpoint = new Outpoint(prevout[origin].hash, prevout[origin].index); @@ -419,24 +433,10 @@ describe("SPVNode", () => { assert(mtx.verify()); let tx = mtx.toTX(); - console.log("ignore above"); - console.log("origin", origin, "accepts tx?", (await wallet.origin.add(tx)) ? true : false); - console.log("out and between"); - console.log("dest", dest, "accepts tx?", (await wallet.dest.add(tx)) ? true : false); node.origin.sendTX(tx); - console.log(origin, dest, "aaa"); await watcher.origin.waitForTX(tx, wallet.origin); - console.log("origin has tx"); - await watcher.dest.waitForTX(tx, wallet.dest); // TODO: dest doesn't get tx - //await spvWatcher.waitForTX(); // it worked one time! race condition - console.log("both sides have tx"); - // spv node accepts inv, but does not put tx in the spvNode.txFilter; this is - // reserved for *sent*, not *received* txs - - console.log(origin, dest, "bbb"); - await wallet.origin.db.addTX(); - await wallet.dest.db.addTX(); + await watcher.dest.waitForTX(tx, wallet.dest); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } @@ -471,16 +471,16 @@ describe("SPVNode", () => { eval(`var ${name} = "${addresses[name]}";`); } - spvNode.trust.getIndirectTrust(alice, alice).should.equal(Infinity); - spvNode.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); - spvNode.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); - spvNode.trust.getIndirectTrust(alice, frank).should.equal(0); - spvNode.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); + spvNode1.trust.getIndirectTrust(alice, alice).should.equal(Infinity); + spvNode1.trust.getIndirectTrust(alice, bob).should.equal(10 * COIN); + spvNode1.trust.getIndirectTrust(alice, charlie).should.equal(1 * COIN); + spvNode1.trust.getIndirectTrust(alice, frank).should.equal(0); + spvNode1.trust.getIndirectTrust(alice, eve).should.equal(6 * COIN); - spvNode.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); - spvNode.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); - spvNode.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); - spvNode.trust.getIndirectTrust(george, eve).should.equal(0); + spvNode1.trust.getIndirectTrust(bob, alice).should.equal(1 * COIN); + spvNode1.trust.getIndirectTrust(bob, eve).should.equal(3 * COIN); + spvNode1.trust.getIndirectTrust(dave, eve).should.equal(12 * COIN); + spvNode1.trust.getIndirectTrust(george, eve).should.equal(0); }); it("after decreasing some trusts lets both nodes compute trusts correctly", async () => { @@ -497,19 +497,18 @@ describe("SPVNode", () => { miner.sendTX(tx); await testHelpers.delay(3000); // combine with next promises with race - for (name in minerNames) { - console.log(name,"aaa"); // see why spv node doesn't accept inv + for (const name in minerNames) { await minerWatcher.waitForTX(tx); } for (name in spvNames) { - await spvWatcher.waitForTX(tx); + await spvWatcher1.waitForTX(tx); } miner.trust.getIndirectTrust(addresses["alice"], addresses["bob"]).should.equal(7 * COIN); - spvNode.trust.getIndirectTrust(addresses["alice"], + spvNode1.trust.getIndirectTrust(addresses["alice"], addresses["bob"]).should.equal(7 * COIN); - mtxs = await spvNode.trust.createTrustDecreasingMTXs( + mtxs = await spvNode1.trust.createTrustDecreasingMTXs( rings["dave"].getPrivateKey(), rings["eve"].getPublicKey(), 2 * COIN, spvWallets["dave"] @@ -519,13 +518,13 @@ describe("SPVNode", () => { mtx.verify().should.be.true(); tx = mtx.toTX(); - spvNode.sendTX(tx); + spvNode1.sendTX(tx); await minerWatcher.waitForTX(tx); - await spvWatcher.waitForTX(tx); + await spvWatcher1.waitForTX(tx); miner.trust.getIndirectTrust(addresses["dave"], addresses["eve"]).should.equal(10 * COIN); - spvNode.trust.getIndirectTrust(addresses["dave"], + spvNode1.trust.getIndirectTrust(addresses["dave"], addresses["eve"]).should.equal(10 * COIN); }); }); From 785bdf427e664c3a35df8f8e115c7c98e6cf9b55 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 10 Feb 2019 20:18:49 +0000 Subject: [PATCH 519/540] Use Promise.all --- test/spv_node.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index 4697fd1..a276679 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -365,13 +365,14 @@ describe("SPVNode", () => { var tx = mtx.toTX(); miner.sendTX(tx); - //TODO: use Promise.all + const promises = []; for (name in minerNames) { - await minerWatcher.waitForTX(tx, minerWallets[name]); + promises.push(minerWatcher.waitForTX(tx, minerWallets[name])); } for (name in spvNames) { - await spvWatcher1.waitForTX(tx, spvWallets[name]); + promises.push(spvWatcher1.waitForTX(tx, spvWallets[name])); } + await Promise.all(promises); var prevout = {}; var counter = 0; From c465391e982233c259305441628550c608563e2c Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 10 Feb 2019 21:05:43 +0000 Subject: [PATCH 520/540] Dedup code by unifying {miner,spv}Wallets --- test/spv_node.js | 74 +++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 55 deletions(-) diff --git a/test/spv_node.js b/test/spv_node.js index a276679..62d8170 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -257,54 +257,26 @@ describe("SPVNode", () => { const names = Object.assign({}, minerNames, spvNames); - var minerWallets = {}; - var spvWallets = {}; - const addresses = {}, accounts = {}, rings = {}; + const wallets = {}, addresses = {}, accounts = {}, rings = {}; beforeEach("apply graph transactions", async () => { - for (const name in minerNames) { - minerWallets[name] = await testHelpers.createWallet( - minerWalletDB, name - ); - accounts[name] = await minerWallets[name].getAccount("default"); - rings[name] = accounts[name].deriveReceive( - accounts[name].receiveDepth - 1, minerWallets[name].master - ); - spvNode1.pool.watch(rings[name].getPublicKey(null, regtest)); - addresses[name] = rings[name].getAddress(null, regtest); - spvNode1.pool.watchAddress(addresses[name]); - - const wid = minerWallets[name].wid; - const unlock = await minerWallets[name].writeLock.lock(); - try { - const batch = minerWallets[name].db.batch(); - await minerWalletDB.addPathMap(batch, bcoin.primitives.KeyRing.fromPublic( - tag).getHash('hex'), wid); - batch.write(); - } finally { - unlock(); - } - } - - const layout = require('bcoin/lib/wallet/layout').wdb; - for (const name in spvNames) { - spvWallets[name] = await testHelpers.createWallet( - spvWalletDB1, name + const wdb = (spvNames[name]) ? minerWalletDB : spvWalletDB1; + for (const name in names) { + wallets[name] = await testHelpers.createWallet( + wdb, name ); - accounts[name] = await spvWallets[name].getAccount("default"); + accounts[name] = await wallets[name].getAccount("default"); rings[name] = accounts[name].deriveReceive( - accounts[name].receiveDepth - 1, spvWallets[name].master + accounts[name].receiveDepth - 1, wallets[name].master ); - spvNode1.pool.watch(rings[name].getPublicKey("hex", regtest)); addresses[name] = rings[name].getAddress(null, regtest); - spvNode1.pool.watchAddress(addresses[name]); - const wid = spvWallets[name].wid; - const unlock = await spvWallets[name].writeLock.lock(); + const wid = wallets[name].wid; + const unlock = await wallets[name].writeLock.lock(); try { - const batch = spvWallets[name].db.batch(); - await spvWalletDB1.addPathMap(batch, bcoin.primitives.KeyRing.fromPublic( + const batch = wallets[name].db.batch(); + await wdb.addPathMap(batch, bcoin.primitives.KeyRing.fromPublic( tag).getHash('hex'), wid); batch.write(); } finally { @@ -327,13 +299,7 @@ describe("SPVNode", () => { // Alice sends 20 BTC to everyone (including herself) via P2PKH var sendAmount = 20; outputs = []; - for (name in minerNames) { - outputs.push(testHelpers.getP2PKHOutput( - addresses[name], sendAmount * consensus.COIN - )); - } - - for (name in spvNames) { + for (name in names) { outputs.push(testHelpers.getP2PKHOutput( addresses[name], sendAmount * consensus.COIN )); @@ -366,11 +332,9 @@ describe("SPVNode", () => { miner.sendTX(tx); const promises = []; - for (name in minerNames) { - promises.push(minerWatcher.waitForTX(tx, minerWallets[name])); - } - for (name in spvNames) { - promises.push(spvWatcher1.waitForTX(tx, spvWallets[name])); + for (name in names) { + const watcher = (spvNames[name]) ? minerWatcher : spvWatcher1; + promises.push(watcher.waitForTX(tx, wallets[name])); } await Promise.all(promises); @@ -392,8 +356,8 @@ describe("SPVNode", () => { function buildVars(player) { return (spvNames[player]) ? - [spvNode1, spvWatcher1, spvWallets[player]] : - [miner, minerWatcher, minerWallets[player]]; + [spvNode1, spvWatcher1, wallets[player]] : + [miner, minerWatcher, wallets[player]]; } let node = { @@ -488,7 +452,7 @@ describe("SPVNode", () => { var mtxs = await miner.trust.createTrustDecreasingMTXs( rings["alice"].getPrivateKey(), rings["bob"].getPublicKey(), 3 * COIN, - minerWallets["alice"] + wallets["alice"] ); mtxs.length.should.equal(1); var mtx = await mtxs[0]; @@ -512,7 +476,7 @@ describe("SPVNode", () => { mtxs = await spvNode1.trust.createTrustDecreasingMTXs( rings["dave"].getPrivateKey(), rings["eve"].getPublicKey(), 2 * COIN, - spvWallets["dave"] + wallets["dave"] ); mtxs.length.should.equal(1); mtx = await mtxs[0]; From a0112295a56bdfee8a9444bfd75db960270383d5 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 11 Feb 2019 23:17:14 +0000 Subject: [PATCH 521/540] Wait for TX gracefully --- test/helpers.js | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 887c3dc..1e87c16 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -164,46 +164,16 @@ class NodeWatcher { } } - // TODO: - // 1. Wait gracefully with waitForSomeTX() (avoid polling) - // 2. Automatically add msig to wallet, like p2pkh (Make bcoin PR) async waitForTX(input, wallet) { if (wallet instanceof Wallet) { while (!(await wallet.getTX(input.hash("hex")))) { - await testHelpers.delay(100); - //await this.waitForSomeTX(); + await this.waitForSomeTX(); } return; } while (!this.node.trust.db.isTrustTX(input.hash("hex"))) { await testHelpers.delay(100); } - return; -// var initialCount = null; -// switch (typeof input) { -// case "number": -// initialCount = input; -// while (!(this.txCount > initialCount)) { -// await this.waitForSomeTX(); -// } -// break; -// -// case "undefined": -// await this.waitForTX(this.txCount); -// break; -// -// case "object": -// var tx = input; -// while ((this.node.spv ? -// !(this.node.pool.txFilter.test(tx.hash().toString("hex"), "hex")) : -// !(this.node.pool.hasTX(tx.hash().toString("hex"))))) { -// await this.waitForSomeTX(); -// } -// break; -// -// default: -// throw new Error("input cannot be " + typeof input); // TODO: throw correct error -// } } async waitForTrustDB(tx) { From 2d5812f3f8882cefb8d771aee77e43a42f2a3455 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 11 Feb 2019 23:17:50 +0000 Subject: [PATCH 522/540] Remove dead function --- test/helpers.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 1e87c16..8c9df9b 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -8,18 +8,6 @@ var assert = require("assert"); const consensus = require("bcoin/lib/protocol/consensus"); var testHelpers = { - isAllZeroes: (buf) => { - let flag = false; - for (let i of buf) { - if (i) { - console.log("there's an 1..."); - flag = true; - break; - } - } - if (!flag) console.log("it's all 0!"); - }, - createWallet: async (walletDB, id) => { var options = { id, From ad14a400af9966226bcc0e9f2df6906c14763e8f Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Mon, 11 Feb 2019 23:18:09 +0000 Subject: [PATCH 523/540] Implement and use WalletWatcher --- test/full_node.js | 7 ++++--- test/helpers.js | 30 ++++++++++++++++++++++++++++-- test/spv_node.js | 33 +++++++++++++++++++++------------ 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/test/full_node.js b/test/full_node.js index fd66efb..d901cdb 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -61,7 +61,7 @@ describe("FullNode", () => { }); beforeEach("get watcher", async () => { - watcher = new testHelpers.NodeWatcher(node); + watcher = new testHelpers.WalletWatcher(wallet); }); afterEach("tear node down", async () => { @@ -72,6 +72,7 @@ describe("FullNode", () => { it("should call trust.addTX() on every transaction", async function() { var sender = await testHelpers.createWallet(walletDB, "sender"); var receiver = await testHelpers.createWallet(walletDB, "receiver"); + const recvWatcher = new testHelpers.WalletWatcher(receiver); await testHelpers.delay(1000); // Produce a block and reward the sender, so that we have a coin to spend. @@ -88,7 +89,7 @@ describe("FullNode", () => { address: await receiver.receiveAddress() }] }); - await watcher.waitForTX(tx, receiver); + await recvWatcher.waitForTX(tx); await testHelpers.flushEvents(); node.trust.addTX.should.have.been.calledOnce(); @@ -148,7 +149,7 @@ describe("FullNode", () => { let tx = mtx.toTX(); node.sendTX(tx); - await watcher.waitForTX(tx, wallet); + await watcher.waitForTX(tx); await testHelpers.flushEvents(); prevout = {}; diff --git a/test/helpers.js b/test/helpers.js index 8c9df9b..98424aa 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -119,7 +119,6 @@ var testHelpers = { class NodeWatcher { constructor(node) { - this.txCount = 0; this.blockCount = 0; this.node = node; this.node.on("tx", this.onTX.bind(this)); @@ -128,7 +127,6 @@ class NodeWatcher { } onTX() { - this.txCount++; for (const resolve of this.waitForSomeTxPromiseResolve) { resolve(); } @@ -171,6 +169,34 @@ class NodeWatcher { } } +class WalletWatcher { + constructor(wallet) { + this.wallet = wallet; + this.wallet.on("tx", this.onTX.bind(this)); + this.waitForSomeTxPromiseResolve = []; + } + + onTX() { + for (const resolve of this.waitForSomeTxPromiseResolve) { + resolve(); + } + this.waitForSomeTxPromiseResolve = []; + } + + waitForSomeTX() { + return new Promise((resolve, reject) => { + this.waitForSomeTxPromiseResolve.push(resolve); + }); + } + + async waitForTX(input) { + while (!(await this.wallet.getTX(input.hash("hex")))) { + await this.waitForSomeTX(); + } + } +} + testHelpers.NodeWatcher = NodeWatcher; +testHelpers.WalletWatcher = WalletWatcher; module.exports = testHelpers; diff --git a/test/spv_node.js b/test/spv_node.js index 62d8170..690c131 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -188,7 +188,9 @@ describe("SPVNode", () => { it("should call trust.addTX() on transaction within a full node", async function() { var minerWallet1 = await testHelpers.createWallet(minerWalletDB, "minerWallet1"); + const watcher1 = new testHelpers.WalletWatcher(minerWallet1); var minerWallet2 = await testHelpers.createWallet(minerWalletDB, "minerWallet2"); + const watcher2 = new testHelpers.WalletWatcher(minerWallet2); var account1 = await minerWallet1.getAccount("default"); await testHelpers.delay(1000); @@ -197,16 +199,19 @@ describe("SPVNode", () => { await testHelpers.delay(100); var miner2TX = await testHelpers.circulateCoins(minerWallet1, - minerWatcher, minerWallet2, minerWatcher, 10); + watcher1, minerWallet2, watcher2, 10); miner.trust.addTX.should.have.been.calledOnce(); }); it("should call trust.addTX() on transaction between full and spv node", async function() { var spvWallet1 = await testHelpers.createWallet(spvWalletDB1, "spvWallet1"); + const watcher1 = new testHelpers.WalletWatcher(spvWallet1); var spvWallet2 = await testHelpers.createWallet(spvWalletDB2, "spvWallet2"); + const watcher2 = new testHelpers.WalletWatcher(spvWallet2); var minerWallet = await testHelpers.createWallet(minerWalletDB, "minerWallet"); + const minerWatcher = new testHelpers.WalletWatcher(minerWallet); var minerAccount = await minerWallet.getAccount("default"); var spvAccount1 = await spvWallet1.getAccount("default"); @@ -219,17 +224,17 @@ describe("SPVNode", () => { await testHelpers.delay(100); var minerSpvTX = await testHelpers.circulateCoins(minerWallet, - minerWatcher, spvWallet1, spvWatcher1, 10); + minerWatcher, spvWallet1, watcher1, 10); spvNode1.trust.addTX.should.have.been.calledOnce(); var spv2TX = await testHelpers.circulateCoins(spvWallet1, - spvWatcher1, spvWallet2, spvWatcher2, 9); + spvWatcher1, spvWallet2, watcher2, 9); spvNode2.trust.addTX.should.have.been.calledTwice(); var spvMinerTX = await testHelpers.circulateCoins(spvWallet2, - spvWatcher2, minerWallet, minerWatcher, 8); + watcher2, minerWallet, minerWatcher, 8); var view = await miner.chain.db.getSpentView(minerSpvTX); var actualBalance = (await minerWallet.getBalance()).unconfirmed; @@ -257,8 +262,8 @@ describe("SPVNode", () => { const names = Object.assign({}, minerNames, spvNames); - - const wallets = {}, addresses = {}, accounts = {}, rings = {}; + const wallets = {}, addresses = {}, accounts = {}; + const rings = {}, watchers = {}; beforeEach("apply graph transactions", async () => { const wdb = (spvNames[name]) ? minerWalletDB : spvWalletDB1; @@ -266,6 +271,7 @@ describe("SPVNode", () => { wallets[name] = await testHelpers.createWallet( wdb, name ); + watchers[name] = new testHelpers.WalletWatcher(wallets[name]); accounts[name] = await wallets[name].getAccount("default"); rings[name] = accounts[name].deriveReceive( accounts[name].receiveDepth - 1, wallets[name].master @@ -333,8 +339,7 @@ describe("SPVNode", () => { miner.sendTX(tx); const promises = []; for (name in names) { - const watcher = (spvNames[name]) ? minerWatcher : spvWatcher1; - promises.push(watcher.waitForTX(tx, wallets[name])); + promises.push(watchers[name].waitForTX(tx, wallets[name])); } await Promise.all(promises); @@ -356,8 +361,8 @@ describe("SPVNode", () => { function buildVars(player) { return (spvNames[player]) ? - [spvNode1, spvWatcher1, wallets[player]] : - [miner, minerWatcher, wallets[player]]; + [spvNode1, watchers[player], wallets[player]] : + [miner, watchers[player], wallets[player]]; } let node = { @@ -400,8 +405,8 @@ describe("SPVNode", () => { let tx = mtx.toTX(); node.origin.sendTX(tx); - await watcher.origin.waitForTX(tx, wallet.origin); - await watcher.dest.waitForTX(tx, wallet.dest); + await watcher.origin.waitForTX(tx); + await watcher.dest.waitForTX(tx); prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; } @@ -462,12 +467,16 @@ describe("SPVNode", () => { miner.sendTX(tx); await testHelpers.delay(3000); // combine with next promises with race + //for (const name in names) { + // await watchers[name].waitForTX(tx); + //} for (const name in minerNames) { await minerWatcher.waitForTX(tx); } for (name in spvNames) { await spvWatcher1.waitForTX(tx); } + miner.trust.getIndirectTrust(addresses["alice"], addresses["bob"]).should.equal(7 * COIN); spvNode1.trust.getIndirectTrust(addresses["alice"], From 3dafa5a053860856ce5ac33fff18d2eeff8eee7e Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Wed, 13 Feb 2019 21:17:48 +0000 Subject: [PATCH 524/540] Create tag instead of hardcoding --- src/tag.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/tag.js b/src/tag.js index 50ad55b..ea89682 100644 --- a/src/tag.js +++ b/src/tag.js @@ -3,16 +3,67 @@ import type {Key} from "./types"; const bcoin = require("bcoin"); const HDPublicKey = bcoin.hd.HD.HDPublicKey; -const pubKey : Key = Buffer.from([0x04, // constant 0x04 prefix - 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - // secp256k1 curve: y^2 = x^3 + 7 - 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, - 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, - 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate - 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]); +const P = BigInt(2)**BigInt(256) - BigInt(2)**BigInt(32) - BigInt(977); + +function modPow(b, e, m) { + if (m === BigInt(1)) { + return BigInt(0); + } + + let c = BigInt(1); + b %= m; + while (e > 0) { + if (e % BigInt(2) === BigInt(1)) { + c = (c*b) % m; + } + e >>= BigInt(1); + b = (b*b) % m; + } + + return c; +} + +function yFromX(x) { + return modPow((x**BigInt(3) + BigInt(7)), (P+BigInt(1))/BigInt(4), P); +} + +function isCurvePoint(x, y) { + return ((y**BigInt(2)) % P) === (x**BigInt(3) + BigInt(7)) % P; +} + +function hexToArr(x) { + let str = x.toString(16); + + if (str.length % 2 === 1) { + str = "0" + str; + } + let res = []; + for (let i = 0; i < str.length; i += 2) { + res.push(parseInt("0x" + str[i] + str[i+1], 16)); + } + + return res; +} + +const str = "Trust is Risk"; +let hex = ""; +for (i in str) { + hex += str.charCodeAt(i).toString(16); +} + +const zeroes = "0".repeat(64 - hex.length); +let x = BigInt("0x" + hex + zeroes); +let y = yFromX(x); +while (!isCurvePoint(x, y)) { + x++; + y = yFromX(x); +} + +x = hexToArr(x); +y = hexToArr(y); + +// constant 0x04 prefix +const pubKey : Key = Buffer.from([0x04].concat(x).concat(y)) const tag : bcoin$HDPublicKey = HDPublicKey.fromOptions({ depth: 0, From 037cb00b6e0bc777dcf450a46618604c419be3cf Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 14 Feb 2019 22:15:52 +0000 Subject: [PATCH 525/540] Remove python tag generator --- test/tag-generator.py | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 test/tag-generator.py diff --git a/test/tag-generator.py b/test/tag-generator.py deleted file mode 100644 index 3bab049..0000000 --- a/test/tag-generator.py +++ /dev/null @@ -1,27 +0,0 @@ -# Thanks to http://code.activestate.com/recipes/577821-integer-square-root-function/ for isqrt() -def isqrt(x): - if x < 0: - raise ValueError('square root not defined for negative numbers') - n = int(x) - if n == 0: - return 0 - a, b = divmod(n.bit_length(), 2) - x = 2**(a+b) - while True: - y = (x + n//x)//2 - if y >= x: - return x - x = y - -x = 0x5472757374206973205269736b00000000000000000000000000000000000000 -# 54:72:75:73:74:20:69:73:20:52:69:73:6b is the ASCII representation of "Trust is Risk" -p = 2**256 - 2**32 - 977 -y = pow((x**3 + 7), (p+1)//4, p) - -while ((y**2) % p) != (x**3 + 7) % p: - x=x+1 - y = pow((x**3 + 7), (p+1)//4, p) - -print("Found it!") -print("x is " + hex(x)) -print("y is " + hex(y)) From 6e05718846202a53b31ac61c8979b05ea4963903 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 14 Feb 2019 22:17:26 +0000 Subject: [PATCH 526/540] Test that tag matches the expected public key --- test/trust_is_risk.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 6b04849..2fabeea 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -89,6 +89,21 @@ describe("tag", () => { tag).getAddress("base58").toString(); bcoin.primitives.Address.fromString(address).should.not.throw(); }); + + it("matches the expected value", () => { + const expected = Buffer.from([0x04, // constant 0x04 prefix + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x52, 0x69, 0x73, 0x6b, 0x00, 0x00, 0x00, // 32 bytes with the x coordinate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // containing ASCII "Trust is Risk" + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // secp256k1 curve: y^2 = x^3 + 7 + 0x05, 0x5d, 0x5f, 0x28, 0x5e, 0xd7, 0x9d, 0x0c, + 0x6f, 0x61, 0xc3, 0x0e, 0xfc, 0x9d, 0x21, 0x91, + 0x65, 0x82, 0x80, 0x59, 0xa6, 0x01, 0x25, 0x0c, // 32 bytes with the y coordinate + 0x8e, 0xce, 0x18, 0x00, 0x14, 0xde, 0x48, 0x1a]); + + tag.should.deepEqual(expected); + }); }); testEach = (isFullNode) => { From 37975481bb73c1d50cdcb0c743efc9d3b074d127 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 3 Jan 2021 20:51:09 +0200 Subject: [PATCH 527/540] Update deps and fix ensuing issues * Change Hash type from String to Buffer * Use new bcrypto library * Use getCoinView() instead of getSpentView() --- package-lock.json | 4166 ++++++++++++++++++++--------------------- package.json | 9 +- src/helpers.js | 2 +- src/trust_db.js | 6 +- src/trust_is_risk.js | 8 +- test/full_node.js | 6 +- test/helpers.js | 8 +- test/spv_node.js | 16 +- test/trust_is_risk.js | 10 +- 9 files changed, 2012 insertions(+), 2219 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28bb764..ddf6788 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@sinonjs/commons": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", - "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -23,41 +23,108 @@ } }, "@sinonjs/samsam": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.1.0.tgz", - "integrity": "sha512-IXio+GWY+Q8XUjHUOgK7wx8fpvr7IFffgyXb1bnJFfX3001KmHt35Zq4tp7MXZyjJPCLPuadesDYNk41LYtVjw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", "dev": true, "requires": { - "@sinonjs/commons": "^1.0.2", + "@sinonjs/commons": "^1.3.0", "array-from": "^2.1.1", - "lodash.get": "^4.4.2" + "lodash": "^4.17.15" } }, - "abstract-leveldown": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", - "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, "requires": { - "xtend": "~4.0.0" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "sprintf-js": "~1.0.2" } }, "array-from": { @@ -66,6 +133,17 @@ "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, "babel-eslint": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", @@ -76,2083 +154,1272 @@ "babel-traverse": "^6.23.1", "babel-types": "^6.23.0", "babylon": "^6.17.0" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcoin": { + "version": "git+https://github.com/bcoin-org/bcoin.git#2dece4fbe10fffa369e9dd0e8263eb57ba30dcac", + "from": "git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", + "requires": { + "bcfg": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.6", + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.0.4", + "bcurl": "git+https://github.com/bcoin-org/bcurl.git#semver:^0.1.6", + "bdb": "git+https://github.com/bcoin-org/bdb.git#semver:~1.2.1", + "bdns": "git+https://github.com/bcoin-org/bdns.git#semver:~0.1.5", + "bevent": "git+https://github.com/bcoin-org/bevent.git#semver:~0.1.5", + "bfile": "git+https://github.com/bcoin-org/bfile.git#semver:~0.2.1", + "bfilter": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.0.0", + "bheep": "git+https://github.com/bcoin-org/bheep.git#semver:~0.1.5", + "binet": "git+https://github.com/bcoin-org/binet.git#semver:~0.3.5", + "blgr": "git+https://github.com/bcoin-org/blgr.git#semver:~0.1.7", + "blru": "git+https://github.com/bcoin-org/blru.git#semver:~0.1.6", + "blst": "git+https://github.com/bcoin-org/blst.git#semver:~0.1.5", + "bmutex": "git+https://github.com/bcoin-org/bmutex.git#semver:~0.1.6", + "brq": "git+https://github.com/bcoin-org/brq.git#semver:~0.1.7", + "bs32": "git+https://github.com/bcoin-org/bs32.git#semver:=0.1.6", + "bsert": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", + "bsock": "git+https://github.com/bcoin-org/bsock.git#semver:~0.1.9", + "bsocks": "git+https://github.com/bcoin-org/bsocks.git#semver:~0.2.6", + "btcp": "git+https://github.com/bcoin-org/btcp.git#semver:~0.1.5", + "buffer-map": "git+https://github.com/chjj/buffer-map.git#semver:~0.0.7", + "bufio": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", + "bupnp": "git+https://github.com/bcoin-org/bupnp.git#semver:~0.2.6", + "bval": "git+https://github.com/bcoin-org/bval.git#semver:~0.1.6", + "bweb": "git+https://github.com/bcoin-org/bweb.git#semver:=0.1.9", + "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1", + "n64": "git+https://github.com/chjj/n64.git#semver:~0.2.10", + "nan": "git+https://github.com/braydonf/nan.git#semver:=2.14.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "bcfg": { + "version": "0.1.6", + "from": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.6", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, + "bcrypto": { + "version": "5.0.4", + "from": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.0.4", + "bundled": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "bufio": "~1.0.6", + "loady": "~0.0.1", + "nan": "^2.14.0" } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, + "bcurl": { + "version": "0.1.6", + "from": "git+https://github.com/bcoin-org/bcurl.git#semver:^0.1.6", + "bundled": true, "requires": { - "babel-runtime": "^6.22.0" + "brq": "~0.1.7", + "bsert": "~0.0.10", + "bsock": "~0.1.8" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, + "bdb": { + "version": "1.2.1", + "from": "git+https://github.com/bcoin-org/bdb.git#semver:~1.2.1", + "bundled": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "bsert": "~0.0.10", + "loady": "~0.0.1" } }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, + "bdns": { + "version": "0.1.5", + "from": "git+https://github.com/bcoin-org/bdns.git#semver:~0.1.5", + "bundled": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "bsert": "~0.0.10" } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, + "bevent": { + "version": "0.1.5", + "from": "git+https://github.com/bcoin-org/bevent.git#semver:~0.1.5", + "bundled": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "bsert": "~0.0.10" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true + "bfile": { + "version": "0.2.2", + "from": "git+https://github.com/bcoin-org/bfile.git#semver:~0.2.1", + "bundled": true }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, + "bfilter": { + "version": "2.0.0", + "from": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.0.0", + "bundled": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.0.4", + "bsert": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", + "bufio": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", + "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1", + "nan": "git+https://github.com/braydonf/nan.git#semver:=2.14.0" } }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true + "bheep": { + "version": "0.1.5", + "from": "git+https://github.com/bcoin-org/bheep.git#semver:~0.1.5", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, + "binet": { + "version": "0.3.5", + "from": "git+https://github.com/bcoin-org/binet.git#semver:~0.3.5", + "bundled": true, "requires": { - "ms": "2.0.0" + "bs32": "~0.1.5", + "bsert": "~0.0.10" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "blgr": { + "version": "0.1.7", + "from": "git+https://github.com/bcoin-org/blgr.git#semver:~0.1.7", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "blru": { + "version": "0.1.6", + "from": "git+https://github.com/bcoin-org/blru.git#semver:~0.1.6", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true + "blst": { + "version": "0.1.5", + "from": "git+https://github.com/bcoin-org/blst.git#semver:~0.1.5", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, + "bmutex": { + "version": "0.1.6", + "from": "git+https://github.com/bcoin-org/bmutex.git#semver:~0.1.6", + "bundled": true, "requires": { - "ansi-regex": "^2.0.0" + "bsert": "~0.0.10" } }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, + "brq": { + "version": "0.1.8", + "from": "git+https://github.com/bcoin-org/brq.git#semver:~0.1.7", + "bundled": true, "requires": { - "loose-envify": "^1.0.0" + "bsert": "~0.0.10" } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "bs32": { + "version": "0.1.6", + "from": "git+https://github.com/bcoin-org/bs32.git#semver:=0.1.6", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true + "bsert": { + "version": "0.0.10", + "from": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", + "bundled": true }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, + "bsock": { + "version": "0.1.9", + "from": "git+https://github.com/bcoin-org/bsock.git#semver:~0.1.9", + "bundled": true, "requires": { - "js-tokens": "^3.0.0" + "bsert": "~0.0.10" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "bsocks": { + "version": "0.2.6", + "from": "git+https://github.com/bcoin-org/bsocks.git#semver:~0.2.6", + "bundled": true, + "requires": { + "binet": "~0.3.5", + "bsert": "~0.0.10" + } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "btcp": { + "version": "0.1.5", + "from": "git+https://github.com/bcoin-org/btcp.git#semver:~0.1.5", + "bundled": true }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, + "buffer-map": { + "version": "0.0.7", + "from": "git+https://github.com/chjj/buffer-map.git#semver:~0.0.7", + "bundled": true + }, + "bufio": { + "version": "1.0.6", + "from": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", + "bundled": true + }, + "bupnp": { + "version": "0.2.6", + "from": "git+https://github.com/bcoin-org/bupnp.git#semver:~0.2.6", + "bundled": true, "requires": { - "ansi-regex": "^2.0.0" + "binet": "~0.3.5", + "brq": "~0.1.7", + "bsert": "~0.0.10" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "bval": { + "version": "0.1.6", + "from": "git+https://github.com/bcoin-org/bval.git#semver:~0.1.6", + "bundled": true, + "requires": { + "bsert": "~0.0.10" + } }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true + "bweb": { + "version": "0.1.9", + "from": "git+https://github.com/bcoin-org/bweb.git#semver:=0.1.9", + "bundled": true, + "requires": { + "bsert": "~0.0.10", + "bsock": "~0.1.8" + } + }, + "loady": { + "version": "0.0.1", + "from": "git+https://github.com/chjj/loady.git#semver:~0.0.1", + "bundled": true + }, + "n64": { + "version": "0.2.10", + "from": "git+https://github.com/chjj/n64.git#semver:~0.2.10", + "bundled": true + }, + "nan": { + "version": "2.14.0", + "from": "git+https://github.com/braydonf/nan.git#semver:=2.14.0", + "bundled": true } } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "bcrypto": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-5.3.0.tgz", + "integrity": "sha512-SP48cpoc4BkEPNOErdsZ1VjbtdXY/C0f5wAywWniLne/Fd/5oOBqLbC6ZavngLvk4oik76g4I7PO5KduJoqECQ==", + "requires": { + "bufio": "~1.0.7", + "loady": "~0.0.5" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, - "bcfg": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.1.4.tgz", - "integrity": "sha512-tgweKJnFlFqg/QA3l+9i4cSJTHPcABrBriRZkUd+MM9mUCv8tBqAZFoykR0Cn3Fi9ygJ/pyWfmjDkRVZQwvPkQ==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "bclient": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/bclient/-/bclient-0.1.5.tgz", - "integrity": "sha512-LtlH6i66dVIztUVyd2ItU3sRwNT/+X/zIEXP5wxz8boP0tARIRjCB1THoYg6PtPaONZ+k/W2VkzYl9XjWTsOpQ==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { - "bcfg": "~0.1.4", - "bcurl": "~0.1.4", - "bsert": "~0.0.5" + "fill-range": "^7.0.1" } }, - "bcoin": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcoin/-/bcoin-1.0.2.tgz", - "integrity": "sha512-eG7j7giwjWHa6et1ZSTgqELRKOFRaQYWDdpA0AbQQO1Xw5K8nqIDPuXySwO18Y9S2Ik+VkvAqL6IlmfnYzA3mw==", - "requires": { - "bcfg": "~0.1.0", - "bclient": "~0.1.1", - "bcrypto": "~0.3.7", - "bdb": "~0.2.1", - "bdns": "~0.1.0", - "bevent": "~0.1.0", - "bfile": "~0.1.0", - "bfilter": "~0.2.0", - "bheep": "~0.1.0", - "binet": "~0.3.0", - "blgr": "~0.1.0", - "blru": "~0.1.0", - "blst": "~0.1.0", - "bmutex": "~0.1.0", - "bn.js": "~4.11.8", - "bsip": "~0.1.0", - "bsock": "~0.1.0", - "bsocks": "~0.2.0", - "bstring": "~0.1.0", - "btcp": "~0.1.0", - "bufio": "~0.2.0", - "bupnp": "~0.2.1", - "bval": "~0.1.0", - "bweb": "~0.1.1", - "mrmr": "~0.1.0", - "n64": "~0.2.0" - } + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, - "bcrypto": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-0.3.7.tgz", - "integrity": "sha512-ZFeKszFo4abpbzLUK8sqQx87Np5ptaskhszU4Jf9JDFa1Bjuanwrv0a7z1xZJOWNG9abz8krgwvO1Z/NBtsgbg==", - "requires": { - "bindings": "~1.3.0", - "bn.js": "~4.11.8", - "bufio": "~0.2.0", - "elliptic": "~6.4.0", - "nan": "~2.10.0", - "secp256k1": "3.5.0" - } + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, - "bcurl": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.1.4.tgz", - "integrity": "sha512-wy+/9uBQWrcNcMy4qCl241qATNnB0evBO5oTJboINXXG3c152wDyEnedAvypkOp4Mh0fYrlsO6yYr5RmRXnVIQ==", + "bufio": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", + "integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, "requires": { - "brq": "~0.1.4", - "bsert": "~0.0.5", - "bsock": "~0.1.4" + "callsites": "^0.2.0" } }, - "bdb": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/bdb/-/bdb-0.2.3.tgz", - "integrity": "sha512-GOfUit8Rq9Y5pUuD3N4zFdZ99sXfswj7QIoFyKQnqq0zmLeQ7riJcpReJZadluOWOmQovzNij75kgA/zlKRnsw==", - "requires": { - "bsert": "~0.0.3", - "leveldown": "4.0.1" - } + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true }, - "bdns": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.3.tgz", - "integrity": "sha512-d071TLX00NZCqhKNspsKU8N8ApqqVizSEdEB7bCE5tUQgFS1UMHjnN0C8HDd5kRYwIX3jAIsN+oNgREvZCGOcA==", + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, "requires": { - "bsert": "~0.0.5" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, - "bevent": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.3.tgz", - "integrity": "sha512-bTsC1MSSWxn0E0OrjrY8j/Sz/C2u3FuAhaO2CaEyc5a5uLwcvC8MK9b14oW0fW/k0AGKQHkuebJOI1RRzArBFQ==", + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" } }, - "bfile": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bfile/-/bfile-0.1.3.tgz", - "integrity": "sha512-7OScx3u416zFsloaN2CyVXRwVAOJdFBpNrpvGlUbkVD2gEzpj+d7/38MInEXnFtcmErDiY1DFR2URBT4J/7kRg==" + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true }, - "bfilter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bfilter/-/bfilter-0.2.0.tgz", - "integrity": "sha512-kQ+LV1FTS3un6iiOqg9qp2kAF+fADZNMZpmv2DHMFIgRSCAjH4NHi9p9X3i34kGJlZzP7+KkySK5it/8/oWKEA==", + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, "requires": { - "bufio": "~0.2.0", - "mrmr": "~0.1.0" + "restore-cursor": "^1.0.1" } }, - "bheep": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.3.tgz", - "integrity": "sha512-Epqqqokl8M0o2qPx/3Z4OPxzGVFmp3JTQubzoUfWD7uucx5x3opRvcPA/UltLrSL9/b2LA+KIg1s/zyPlpGyrQ==", + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, - "bindings": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", - "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==" + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true }, - "binet": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/binet/-/binet-0.3.3.tgz", - "integrity": "sha512-EQX5k4WfYDkDhiKyK11Z90jkTLC9yAw4luSpr7+zfT0VW+/fy4Zizf3FoRyAtI7CWV803NybAcfDZz94wAtziA==", - "requires": { - "bs32": "~0.1.3", - "bsert": "~0.0.5" - } + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "color-name": "~1.1.4" } }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "blgr": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/blgr/-/blgr-0.1.4.tgz", - "integrity": "sha512-eAYRZxI0mtInsANQbhm9zJAkpSQh4QUBYiW8pPznrLeH34NqQxTmFHY1ot3d7wFZoSGIDZ0wFBd5CDzFNP0h5A==", + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "es5-ext": "^0.10.50", + "type": "^1.0.1" } }, - "blru": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/blru/-/blru-0.1.4.tgz", - "integrity": "sha512-qq82TVa2GDcjv/BswxH7hpDZEr2Cu8XLVoHmLt7jZMAHKZ3jzTtyQCsuUOZXILpOwduqB8AC6R79bvclNWwRKw==", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "ms": "2.0.0" } }, - "blst": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-is": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/blst/-/blst-0.1.3.tgz", - "integrity": "sha512-bDZC68tjfflVuC7OGy+vlF6VtlW1Jtk8isH2116LoCLE9MCgTu2N2yTaT5CFuUF3yB1s0gGiWVR3uJpF+27HFw==", - "requires": { - "bsert": "~0.0.5" - } + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true }, - "bmutex": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.4.tgz", - "integrity": "sha512-uSlUggS46kO/ziGZQKVE6nMbZrrlhmG+uw/VgBi54dkDO32DLTTlSQsLeRQHeKj4Zl+B389Pmizvz5J+VYYKFw==", + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "esutils": "^2.0.2" } }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } } }, - "brq": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/brq/-/brq-0.1.4.tgz", - "integrity": "sha512-VPQtZgDjc3awXuzpuGrjuJtqsImDKrj7z4tVWC2bMafutD4Efx50otZMyxvQzJlQz3kXK3uAKonrHLKWy0Yo+A==", + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "d": "^1.0.1", + "ext": "^1.1.2" } }, - "bs32": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.3.tgz", - "integrity": "sha512-pTVLcFJxmAUMjtfLqaBkqCPybquBQCjxKcpVIYEDqPpXIabctuNTnK+6W4Z8WcGyLJijkAWU9ZOI9xARexT8uQ==", + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, "requires": { - "bsert": "~0.0.5" + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" } }, - "bsert": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.5.tgz", - "integrity": "sha512-prgSa82RHcsdEM7SKYl1S7j0tKeiE3SF8C3B39MyUrpbP66diJK16RIkbFC2pXvQx4xitN0xMgBHKBAgBldX1w==" + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, - "bsip": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bsip/-/bsip-0.1.4.tgz", - "integrity": "sha512-ZC5Dsa5k1+24DorSOgXeDgV9f7OxLcvZiXDYYjHN1mkW8OF/abNSKlogDgVrx/znpAAZ1yJPkWgrub/FsIxEmA==", + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, "requires": { - "bindings": "~1.3.1", - "bsert": "~0.0.5", - "nan": "~2.11.1" - }, - "dependencies": { - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" - } + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, - "bsock": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.4.tgz", - "integrity": "sha512-3hfPScf58kC13udMqXL/GiBubUOmwwMaTljIY8xJI0pO2uOmAaDyBCqT/PiteXRHHC1lDinK2wkFayc4xX92Wg==", + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, "requires": { - "bsert": "~0.0.5" + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" } }, - "bsocks": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.3.tgz", - "integrity": "sha512-Mc6yqYNqPHaZkYYppCctrsZUmoISGBZQmjKnd4P8xxKeKH4KnM0JZJigF6y0QTRjq+e/+7AvSSxoSsUeGh7CYQ==", + "eslint-plugin-flowtype": { + "version": "2.50.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", + "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", + "dev": true, "requires": { - "binet": "~0.3.3", - "bsert": "~0.0.5" + "lodash": "^4.17.10" } }, - "bstring": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/bstring/-/bstring-0.1.2.tgz", - "integrity": "sha512-n7FeLSrKfsPnZstqA9PfPME1apI9u9WB35aDbsubWzLz1GjpgXewCXYyq9/m8c/IB/pFXRwqs0XwL/qq5IGJPQ==", + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, "requires": { - "bindings": "~1.3.0", - "bsert": "~0.0.3", - "nan": "~2.10.0" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, - "btcp": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.3.tgz", - "integrity": "sha512-5UV2yOHOwpIhAVqUqiC7MyHdX4coTJPcOnJik3guV+99cVo5ZK/2oKb/w+e2PBxLrsy2c93EF5/DamzmG1QqSA==" + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true }, - "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } }, - "bufio": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bufio/-/bufio-0.2.0.tgz", - "integrity": "sha512-PjL1QglhgZCWEKWbxzlVB4ExvNorHMu0JSu4ehzeKi38R74Fp7duHAl8xNEqsbJXP5Dfym7XuSEkVol1KX5mhw==" + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true }, - "bupnp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.4.tgz", - "integrity": "sha512-7H1zZkX4Jba+CmY1sxAuceIZoEXAYGi767chlBrGfqFwwf1Bt4DYMsAw65Xxdu/zsLd2nsUSXliV20Txdf76xw==", + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, "requires": { - "binet": "~0.3.3", - "brq": "~0.1.4", - "bsert": "~0.0.5" + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "dev": true + } } }, - "bval": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/bval/-/bval-0.1.4.tgz", - "integrity": "sha512-mCPe86NoWCCO/W4Yvx6dfA2Tr45wP3NAKCeZvwN01ODj5ecdllaD/UHthVjH16/yZa59nxtrA2sBi6Mi83QmXg==", + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, "requires": { - "bsert": "~0.0.5" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, - "bweb": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/bweb/-/bweb-0.1.6.tgz", - "integrity": "sha512-Fuyi0DrtpeQbXO0Srg8JtHWM+t5/XPFcXcXcu61zU3lVeYrYdcITu6+I+qKy6v9esRWbvc+yh117lz9/Wm/Qnw==", + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, "requires": { - "bsert": "~0.0.5", - "bsock": "~0.1.4" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + } }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "flow-bin": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", + "integrity": "sha1-AJ3Q9Xej9mXHTKi+gnrowt2P1rU=", "dev": true }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "flow-remove-types": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.3.tgz", + "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==", + "dev": true, + "requires": { + "babylon": "^6.15.0", + "vlq": "^0.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "is-property": "^1.0.2" } }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "is-property": "^1.0.0" } }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { - "ms": "2.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, "requires": { - "mimic-response": "^1.0.0" + "is-glob": "^4.0.1" } }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "graph-theory-ford-fulkerson": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", + "integrity": "sha1-LDHSHXDxp9KCiZX+BnZFdv9/nik=" }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" + "function-bind": "^1.1.1" } }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "ansi-regex": "^2.0.0" } }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" - }, - "dependencies": { - "acorn": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.1.tgz", - "integrity": "sha512-XH4o5BK5jmw9PzSGK7mNf+/xV+mPxQxGZoeC36OVsJZYV77JAG9NnI7T90hoUpI/C1TOfXWTvugRdZ9ZR3iE2Q==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "es5-ext": { - "version": "0.10.45", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", - "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "ignore": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", - "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-my-json-valid": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", - "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "^1.3.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - } - } - }, - "eslint-plugin-flowtype": { - "version": "2.50.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", - "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-template": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz", - "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==" - }, - "fast-future": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", - "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=" + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true }, - "flow-bin": { - "version": "0.45.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", - "integrity": "sha1-AJ3Q9Xej9mXHTKi+gnrowt2P1rU=", + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "flow-remove-types": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.3.tgz", - "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==", + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "babylon": "^6.15.0", - "vlq": "^0.2.1" - }, - "dependencies": { - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - } + "once": "^1.3.0", + "wrappy": "1" } }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" } }, - "graph-theory-ford-fulkerson": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", - "integrity": "sha1-LDHSHXDxp9KCiZX+BnZFdv9/nik=" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "loose-envify": "^1.0.0" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "binary-extensions": "^2.0.0" } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "has": "^1.0.3" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", "dev": true }, + "is-my-json-valid": { + "version": "2.20.5", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", + "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", + "dev": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", + "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==", + "dev": true }, "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", + "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", "dev": true }, - "leveldown": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-4.0.1.tgz", - "integrity": "sha512-ZlBKVSsglPIPJnz4ggB8o2R0bxDxbsMzuQohbfgoFMVApyTE118DK5LNRG0cRju6rt3OkGxe0V6UYACGlq/byg==", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "loady": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/loady/-/loady-0.0.5.tgz", + "integrity": "sha512-uxKD2HIj042/HBx77NBcmEPsD+hxCgAtjEWlYNScuUjIsh/62Uyu39GOR68TBR68v+jqDL9zfftCWoUo4y03sQ==" + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "requires": { - "abstract-leveldown": "~5.0.0", - "bindings": "~1.3.0", - "fast-future": "~1.0.2", - "nan": "~2.10.0", - "prebuild-install": "^4.0.0" + "p-locate": "^5.0.0" } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, "lodash.get": { @@ -2161,37 +1428,66 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "lolex": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.0.tgz", - "integrity": "sha512-uJkH2e0BVfU5KOJUevbTOtpDduooSarH5PopO+LfM/vZf8Z9sJzODqKev804JYM2i++ktJfUmC1le4LwFQ1VMg==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "js-tokens": "^3.0.0 || ^4.0.0" } }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2202,58 +1498,110 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } + "minimist": "^1.2.5" } }, "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", "dev": true, "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", "growl": "1.10.5", - "he": "1.1.1", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } - }, - "mrmr": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/mrmr/-/mrmr-0.1.4.tgz", - "integrity": "sha512-i2kWXVPLExnVOO7qP861WZxK+pfJ9Rppujfl7lS5sfqWSvQbNz8OouEUgcVk6EsRiH4tDHx6yM6LQQhl0jrjXw==", - "requires": { - "bindings": "~1.3.1", - "bsert": "~0.0.5", - "nan": "~2.11.1" + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" }, "dependencies": { - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -2263,15 +1611,23 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "n64": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/n64/-/n64-0.2.5.tgz", - "integrity": "sha512-wry9grq4tNsxvpW2hqXNJIxqv9pT3+NEs/nyg9z5nKQ4QCB6b9IF2DSpVBEC/9fxX6c6G5hJ+SzK/Iv2k+896w==" + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true }, "next-tick": { "version": "1.0.0", @@ -2280,75 +1636,121 @@ "dev": true }, "nise": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", - "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", + "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", "dev": true, "requires": { - "@sinonjs/formatio": "^3.1.0", + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", - "lolex": "^2.3.2", - "path-to-regexp": "^1.7.0", - "text-encoding": "^0.6.4" + "lolex": "^5.0.1", + "path-to-regexp": "^1.7.0" }, "dependencies": { "@sinonjs/formatio": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", - "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "requires": { - "@sinonjs/samsam": "^2 || ^3" + "@sinonjs/commons": "^1.7.0" } } } }, - "node-abi": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.5.0.tgz", - "integrity": "sha512-9g2twBGSP6wIR5PW7tXvAWnEWKJDH/VskdXp168xsw9VVxpEGov8K4jsP4/VeoC7b2ZAyzckvMCuQuQlw44lXg==", - "requires": { - "semver": "^5.4.1" - } - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -2356,10 +1758,22 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" @@ -2373,80 +1787,172 @@ } } }, - "prebuild-install": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-4.0.0.tgz", - "integrity": "sha512-7tayxeYboJX0RbVzdnKyGl2vhQRWr6qfClEXDhOkXjuaOKCw2q8aiuFhONRYVsG/czia7KhpykIlI2S2VaPunA==", - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^1.0.2", - "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "node-abi": "^2.2.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "os-homedir": "^1.0.1", - "pump": "^2.0.1", - "rc": "^1.1.6", - "simple-get": "^2.7.0", - "tar-fs": "^1.13.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - } + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true }, "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "glob": "^7.1.3" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "once": "^1.3.0" } }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "samsam": { "version": "1.3.0", @@ -2454,38 +1960,30 @@ "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, - "secp256k1": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", - "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", - "requires": { - "bindings": "^1.2.1", - "bip66": "^1.1.3", - "bn.js": "^4.11.3", - "create-hash": "^1.1.2", - "drbg.js": "^1.0.1", - "elliptic": "^6.2.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" } }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "should": { @@ -2499,49 +1997,25 @@ "should-type": "^1.4.0", "should-type-adaptors": "^1.0.1", "should-util": "^1.0.0" - }, - "dependencies": { - "should-equal": { - "version": "1.0.1", - "resolved": "http://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", - "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", - "dev": true, - "requires": { - "should-type": "^1.0.0" - } - }, - "should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", - "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", - "dev": true - }, - "should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "should-util": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", - "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", - "dev": true - } + } + }, + "should-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", + "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", + "dev": true, + "requires": { + "should-type": "^1.0.0" + } + }, + "should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "dev": true, + "requires": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" } }, "should-sinon": { @@ -2550,26 +2024,28 @@ "integrity": "sha1-/8ioUb9FB2fn0K0i/4cVZQvpUOQ=", "dev": true }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + "should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "dev": true }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "should-type": "^1.3.0", + "should-util": "^1.0.0" } }, + "should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "dev": true + }, "sinon": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", @@ -2585,23 +2061,39 @@ "type-detect": "^4.0.8" }, "dependencies": { - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, "sorted-set": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", "integrity": "sha1-POAVeFtkdPH6A6HGn/8ymFL8N+M=" }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2612,6 +2104,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -2620,85 +2113,116 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" }, "dependencies": { - "has-flag": { + "ansi-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true - } - } - }, - "tar-fs": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", - "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", - "requires": { - "chownr": "^1.0.1", - "mkdirp": "^0.5.1", - "pump": "^1.0.0", - "tar-stream": "^1.1.2" - }, - "dependencies": { - "pump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", - "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "ansi-regex": "^3.0.0" } } } }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - } + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "prelude-ls": "~1.1.2" } }, "type-detect": { @@ -2707,33 +2231,301 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, "requires": { "string-width": "^1.0.2 || 2" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } }, "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 3afdc75..b37efd0 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "build": "flow-remove-types -d lib/ src/", - "test": "npm run build && mocha -t 60000", + "test": "npm run build && mocha -t 100000", "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", @@ -31,14 +31,15 @@ "eslint": "^3.19.0", "eslint-plugin-flowtype": "^2.50.3", "flow-bin": "^0.45.0", - "flow-remove-types": "^1.2.0", - "mocha": "^5.2.0", + "flow-remove-types": "^1.2.3", + "mocha": "^8.2.1", "should": "^11.2.1", "should-sinon": "0.0.5", "sinon": "^5.1.1" }, "dependencies": { - "bcoin": "^1.0.2", + "bcoin": "git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", + "bcrypto": "^5.3.0", "graph-theory-ford-fulkerson": "^1.0.0", "sorted-set": "^0.3.0" } diff --git a/src/helpers.js b/src/helpers.js index e2a2549..498db7b 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -61,7 +61,7 @@ class NodeWatcher { await new Promise((resolve, reject) => { var check = (() => { // This breaks node.pool.on("tx", ...) - if (this.node.pool.hasTX(tx.hash().toString("hex"))) + if (this.node.pool.hasTX(tx.hash())) resolve(); else setTimeout(check, 100); }).bind(this); diff --git a/src/trust_db.js b/src/trust_db.js index 4507d31..53b8a9a 100644 --- a/src/trust_db.js +++ b/src/trust_db.js @@ -79,11 +79,11 @@ class TrustDB { } isTrustTX(txHash : string) : boolean { - return this.txToDirectTrust.has(txHash); + return this.txToDirectTrust.has(txHash.toString("hex")); } isTrustOutput(txHash : string, outputIndex : number) : boolean { - var trust = this.txToDirectTrust.get(txHash); + var trust = this.txToDirectTrust.get(txHash.toString("hex")); return trust !== undefined && trust.outputIndex === outputIndex; } @@ -105,7 +105,7 @@ class TrustDB { assert(trust.valid); trusts.push(trust); - this.txToDirectTrust.set(trust.txHash, trust); + this.txToDirectTrust.set(trust.txHash.toString("hex"), trust); this.entities.add(origin); this.entities.add(dest); diff --git a/src/trust_is_risk.js b/src/trust_is_risk.js index ae8862c..1f00575 100644 --- a/src/trust_is_risk.js +++ b/src/trust_is_risk.js @@ -45,7 +45,7 @@ class TrustIsRisk { // network, false otherwise. // Throws an error if the transaction was processed earlier. addTX(tx : bcoin$TX) : boolean { - var txHash = tx.hash().toString("hex"); + var txHash = tx.hash(); if (this.db.isTrustTX(txHash)) { throw new Error(`Transaction already processed: Transaction ${txHash} already carries trust`); } @@ -202,7 +202,7 @@ class TrustIsRisk { if (tx.inputs.length !== 1) return null; var input = tx.inputs[0]; if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable - if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; + if (this.db.isTrustOutput(input.prevout.hash, input.prevout.index)) return null; var origin = tx.inputs[0].getAddress().toString(); if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; @@ -228,7 +228,7 @@ class TrustIsRisk { } getTrustDecrease(tx : bcoin$TX, prevTrust : DirectTrust) : DirectTrust { - var txHash = tx.hash().toString("hex"); + var txHash = tx.hash(); var nullTrust = prevTrust.getNullifying(txHash); if (tx.inputs.length !== 1) return nullTrust; @@ -269,7 +269,7 @@ class TrustIsRisk { parseOutputAsDirectTrust(tx : bcoin$TX, outputIndex : number, origin : Entity) : (DirectTrust | null) { - var txHash = tx.hash().toString("hex"); + var txHash = tx.hash(); var output = tx.outputs[outputIndex]; if (output.getType() !== "multisig") return null; diff --git a/test/full_node.js b/test/full_node.js index d901cdb..b72ac10 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -138,7 +138,7 @@ describe("FullNode", () => { // Use the coinbase coins as inputs var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { - return node.getCoin(hash.toString("hex"), 0); + return node.getCoin(hash, 0); })); var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); @@ -155,7 +155,7 @@ describe("FullNode", () => { prevout = {}; fixtures.names.forEach((name) => { prevout[name] = { - hash: tx.hash().toString("hex"), + hash: tx.hash(), index: fixtures.names.indexOf(name) }; }); @@ -186,7 +186,7 @@ describe("FullNode", () => { await watcher.waitForTX(tx); await testHelpers.flushEvents(); // @dionyziz: needs a long time - prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; + prevout[origin] = {hash: tx.hash(), index: 1}; } } diff --git a/test/helpers.js b/test/helpers.js index 98424aa..f50f4b7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -72,7 +72,7 @@ var testHelpers = { getP2PKHInput: (pubKey, prevout) => { if (!prevout) { prevout = { // Don't care - hash: "v0pnhphaf4r5wz63j60vnh27s1bftl260qq621y458tn0g4x64u64yqz6d7qi6i8", + hash: Buffer.from("v0pnhphaf4r5wz63j60vnh27s1bftl26"), index: 2 }; } @@ -152,12 +152,12 @@ class NodeWatcher { async waitForTX(input, wallet) { if (wallet instanceof Wallet) { - while (!(await wallet.getTX(input.hash("hex")))) { + while (!(await wallet.getTX(input.hash()))) { await this.waitForSomeTX(); } return; } - while (!this.node.trust.db.isTrustTX(input.hash("hex"))) { + while (!this.node.trust.db.isTrustTX(input.hash())) { await testHelpers.delay(100); } } @@ -190,7 +190,7 @@ class WalletWatcher { } async waitForTX(input) { - while (!(await this.wallet.getTX(input.hash("hex")))) { + while (!(await this.wallet.getTX(input.hash()))) { await this.waitForSomeTX(); } } diff --git a/test/spv_node.js b/test/spv_node.js index 690c131..7288396 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -168,12 +168,12 @@ describe("SPVNode", () => { }), new Output({ // paytopubkeyhash change script: Script.fromPubkeyhash( - bcrypto.hash160.digest(origin.getPublicKey())), + bcrypto.Hash160.digest(origin.getPublicKey())), value: consensus.COIN - 100000 // leave a fee of 0.001 BTC }) ]; var mtx = new MTX({outputs}); - var coinbaseCoin = await miner.getCoin(block.txs[0].hash().toString("hex"), 0); + var coinbaseCoin = await miner.getCoin(block.txs[0].hash(), 0); mtx.addCoin(coinbaseCoin); mtx.sign(origin); @@ -236,7 +236,7 @@ describe("SPVNode", () => { var spvMinerTX = await testHelpers.circulateCoins(spvWallet2, watcher2, minerWallet, minerWatcher, 8); - var view = await miner.chain.db.getSpentView(minerSpvTX); + var view = await miner.chain.db.getCoinView(minerSpvTX); var actualBalance = (await minerWallet.getBalance()).unconfirmed; var expectedBalance = consensus.BASE_REWARD - 10 * COIN + 8 * COIN - minerSpvTX.getFee(view); @@ -266,8 +266,8 @@ describe("SPVNode", () => { const rings = {}, watchers = {}; beforeEach("apply graph transactions", async () => { - const wdb = (spvNames[name]) ? minerWalletDB : spvWalletDB1; for (const name in names) { + const wdb = (spvNames[name]) ? minerWalletDB : spvWalletDB1; wallets[name] = await testHelpers.createWallet( wdb, name ); @@ -283,7 +283,7 @@ describe("SPVNode", () => { try { const batch = wallets[name].db.batch(); await wdb.addPathMap(batch, bcoin.primitives.KeyRing.fromPublic( - tag).getHash('hex'), wid); + tag).getHash(), wid); batch.write(); } finally { unlock(); @@ -326,7 +326,7 @@ describe("SPVNode", () => { // Use the coinbase coins as inputs var coinbaseCoins = await Promise.all(coinbaseHashes.map((hash) => { - return miner.getCoin(hash.toString("hex"), 0); + return miner.getCoin(hash, 0); })); var mtx = new MTX({outputs}); coinbaseCoins.forEach((coin) => mtx.addCoin(coin)); @@ -348,7 +348,7 @@ describe("SPVNode", () => { for (const name in names) { prevout[name] = { - hash: tx.hash().toString("hex"), + hash: tx.hash(), index: counter++ }; } @@ -408,7 +408,7 @@ describe("SPVNode", () => { await watcher.origin.waitForTX(tx); await watcher.dest.waitForTX(tx); - prevout[origin] = {hash: tx.hash().toString("hex"), index: 1}; + prevout[origin] = {hash: tx.hash(), index: 1}; } } diff --git a/test/trust_is_risk.js b/test/trust_is_risk.js index 2fabeea..e781c04 100644 --- a/test/trust_is_risk.js +++ b/test/trust_is_risk.js @@ -55,7 +55,7 @@ setupTest = async (isFullNode) => { var inputOneOfThreeMultisig = new Input({ prevout: { - hash: trustIncreasingTX.hash().toString("hex"), + hash: trustIncreasingTX.hash(), index: 0 }, script: bcoin.Script.fromString( @@ -275,14 +275,14 @@ testEach = (isFullNode) => { trustTXs.push(tx); tir.addTX(tx); - getTXStub.withArgs(tx.hash("hex")).returns(TXRecord.fromTX(tx)); + getTXStub.withArgs(tx.hash()).returns(TXRecord.fromTX(tx)); trustIncreasingMTX.outputs[0].value = 100 * COIN; tx = trustIncreasingMTX.toTX(); trustTXs.push(tx); tir.addTX(tx); - getTXStub.withArgs(tx.hash("hex")).returns(TXRecord.fromTX(tx)); + getTXStub.withArgs(tx.hash()).returns(TXRecord.fromTX(tx)); trustIncreasingMTX.outputs[0].value = 500 * COIN; tx = trustIncreasingMTX.toTX(); @@ -304,7 +304,7 @@ testEach = (isFullNode) => { mtx.inputs.length.should.equal(1); mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[0].hash().toString("hex"), + hash: trustTXs[0].hash(), index: 0 }); @@ -317,7 +317,7 @@ testEach = (isFullNode) => { mtx.inputs.length.should.equal(1); mtx.inputs[0].prevout.should.have.properties({ - hash: trustTXs[1].hash().toString("hex"), + hash: trustTXs[1].hash(), index: 0 }); From a9fec53f2d502edac939174ce91113cc6ea1857b Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 7 Jan 2021 23:36:15 +0200 Subject: [PATCH 528/540] Attempt to connect nodes unsuccessfully --- minimal_testcases/connect-spv-w-walletdb.js | 3 +++ minimal_testcases/spvandfullsend/helpers.js | 19 +++++++++---------- minimal_testcases/spvandfullsend/minimal.js | 3 ++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/minimal_testcases/connect-spv-w-walletdb.js b/minimal_testcases/connect-spv-w-walletdb.js index 4f7ad8f..5ec7302 100644 --- a/minimal_testcases/connect-spv-w-walletdb.js +++ b/minimal_testcases/connect-spv-w-walletdb.js @@ -17,6 +17,8 @@ const one = new bcoin.SPVNode({ // Full: OK | SPV: Fail // logConsole: true, // try to see the logs of // logLevel: 'debug', // the Full node as well httpPort: 48445, + port: 48446, + nodes: ["127.0.0.1:48448"], passphrase: 'secret' }); @@ -27,6 +29,7 @@ const oneWalletDB = new WalletDB({ const two = new bcoin.FullNode({ network: regtest, + httpPort: 48446, port: 48448, bip37: true, listen: true, diff --git a/minimal_testcases/spvandfullsend/helpers.js b/minimal_testcases/spvandfullsend/helpers.js index e66d61e..55ebc7e 100644 --- a/minimal_testcases/spvandfullsend/helpers.js +++ b/minimal_testcases/spvandfullsend/helpers.js @@ -14,15 +14,15 @@ const helpers = { throw Error("Wrong node type"); const node = (type === "spv") ? - new bcoin.spvnode({ - network: bcoin.network.get().toString(), + new bcoin.SPVNode({ + network: bcoin.Network.get().toString(), port: 48445, passphrase: "secret", nodes: ["127.0.0.1:48448"] }) - : // if type === "full" - new bcoin.fullnode({ - network: bcoin.network.get().toString(), + : // type === "full" + new bcoin.FullNode({ + network: bcoin.Network.get().toString(), port: 48448, bip37: true, listen: true, @@ -34,12 +34,11 @@ const helpers = { const walletDB = new WalletDB({ network: node.network, db: "memory", - client: new bcoin.node.NodeClient(node), + client: new bcoin.wallet.NodeClient(node), spv: node.spv }); await walletDB.open(); - await walletDB.connect(); await node.connect(); node.startSync(); @@ -59,7 +58,7 @@ const helpers = { mineAndPaySPV: async (fullNode, fullWallet, spvWallet) => { const block = await fullNode.miner.mineBlock( - fullNode.chain.tip, fullWallet.getAddress("base58") + fullNode.chain.tip, await fullWallet.receiveAddress() ); await fullNode.chain.add(block); @@ -70,7 +69,7 @@ const helpers = { const ret = await fullWallet.send({ outputs: [{ // give 25 coins to SPV value: 25 * consensus.COIN, - address: spvWallet.getAddress("base58") + address: await spvWallet.receiveAddress() }] }); return ret; @@ -85,7 +84,7 @@ const helpers = { else setTimeout(check, 100); } else { // this is not an SPV node - if (node.pool.hasTX(tx.hash().toString("hex"))) + if (node.pool.hasTX(tx.hash())) resolve(); else setTimeout(check, 100); } diff --git a/minimal_testcases/spvandfullsend/minimal.js b/minimal_testcases/spvandfullsend/minimal.js index 44ff147..38d9ead 100644 --- a/minimal_testcases/spvandfullsend/minimal.js +++ b/minimal_testcases/spvandfullsend/minimal.js @@ -28,9 +28,10 @@ let fullWalletDB; const TXtoSPV = await spvWallet1.send({ outputs: [{ value: 10 * consensus.COIN, - address: spvWallet2.getAddress("base58") + address: await spvWallet2.receiveAddress() }] }); + await helpers.waitForTX(spvNode, TXtoSPV); console.log("success!"); process.exit(); From 0a79bf0d76edf6e80ed053d132aee8cd622dd501 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Thu, 7 Jan 2021 23:39:04 +0200 Subject: [PATCH 529/540] Skip tests that need nodes connecting --- test/spv_node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spv_node.js b/test/spv_node.js index 7288396..706bd19 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -246,7 +246,7 @@ describe("SPVNode", () => { miner.trust.addTX.should.have.been.calledThrice(); }); - describe("with the nobodyLikesFrank.json example", () => { + describe.skip("with the nobodyLikesFrank.json example", () => { var minerNames = { "alice": "alice", "bob": "bob", From 2ad2d08943c4c67a299b2321677fac4065431543 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 24 Jan 2021 12:37:53 +0200 Subject: [PATCH 530/540] Postinstall hook: Use modified tx.js, txdb.js Please enter the commit message for your changes. Lines starting --- package.json | 3 +- scripts/postinstall.sh | 2 + scripts/tx.js | 2587 +++++++++++++++++++++++++++++++++++++ scripts/txdb.js | 2746 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 5337 insertions(+), 1 deletion(-) create mode 100755 scripts/postinstall.sh create mode 100644 scripts/tx.js create mode 100644 scripts/txdb.js diff --git a/package.json b/package.json index b37efd0..8f88766 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "prepublish": "npm run build", "typecheck": "flow check", "lint": "./node_modules/.bin/eslint --fix src/ test/", - "check": "npm run lint && npm run typecheck && npm run test" + "check": "npm run lint && npm run typecheck && npm run test", + "postinstall": "scripts/postinstall.sh" }, "repository": { "type": "git", diff --git a/scripts/postinstall.sh b/scripts/postinstall.sh new file mode 100755 index 0000000..2524810 --- /dev/null +++ b/scripts/postinstall.sh @@ -0,0 +1,2 @@ +cp scripts/tx.js node_modules/bcoin/lib/primitives +cp scripts/txdb.js node_modules/bcoin/lib/wallet diff --git a/scripts/tx.js b/scripts/tx.js new file mode 100644 index 0000000..2ada014 --- /dev/null +++ b/scripts/tx.js @@ -0,0 +1,2587 @@ +/*! + * tx.js - transaction object for bcoin + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +const assert = require('bsert'); +const bio = require('bufio'); +const hash256 = require('bcrypto/lib/hash256'); +const secp256k1 = require('bcrypto/lib/secp256k1'); +const {BufferSet} = require('buffer-map'); +const util = require('../utils/util'); +const Amount = require('../btc/amount'); +const Network = require('../protocol/network'); +const Script = require('../script/script'); +const Input = require('./input'); +const Output = require('./output'); +const Outpoint = require('./outpoint'); +const KeyRing = require('./keyring'); +const InvItem = require('./invitem'); +const consensus = require('../protocol/consensus'); +const policy = require('../protocol/policy'); +const ScriptError = require('../script/scripterror'); +const {encoding} = bio; +const {hashType} = Script; +const {inspectSymbol} = require('../utils'); + +/** + * TX + * A static transaction object. + * @alias module:primitives.TX + * @property {Number} version + * @property {Input[]} inputs + * @property {Output[]} outputs + * @property {Number} locktime + */ + +class TX { + /** + * Create a transaction. + * @constructor + * @param {Object?} options + */ + + constructor(options) { + this.version = 1; + this.inputs = []; + this.outputs = []; + this.locktime = 0; + + this.mutable = false; + + this._hash = null; + this._hhash = null; + this._whash = null; + + this._raw = null; + this._offset = -1; + this._block = false; + this._size = -1; + this._witness = -1; + this._sigops = -1; + + this._hashPrevouts = null; + this._hashSequence = null; + this._hashOutputs = null; + + if (options) + this.fromOptions(options); + } + + /** + * Inject properties from options object. + * @private + * @param {Object} options + */ + + fromOptions(options) { + assert(options, 'TX data is required.'); + + if (options.version != null) { + assert((options.version >>> 0) === options.version, + 'Version must be a uint32.'); + this.version = options.version; + } + + if (options.inputs) { + assert(Array.isArray(options.inputs), 'Inputs must be an array.'); + for (const input of options.inputs) + this.inputs.push(new Input(input)); + } + + if (options.outputs) { + assert(Array.isArray(options.outputs), 'Outputs must be an array.'); + for (const output of options.outputs) + this.outputs.push(new Output(output)); + } + + if (options.locktime != null) { + assert((options.locktime >>> 0) === options.locktime, + 'Locktime must be a uint32.'); + this.locktime = options.locktime; + } + + return this; + } + + /** + * Instantiate TX from options object. + * @param {Object} options + * @returns {TX} + */ + + static fromOptions(options) { + return new this().fromOptions(options); + } + + /** + * Clone the transaction. + * @returns {TX} + */ + + clone() { + return new this.constructor().inject(this); + } + + /** + * Inject properties from tx. + * Used for cloning. + * @private + * @param {TX} tx + * @returns {TX} + */ + + inject(tx) { + this.version = tx.version; + + for (const input of tx.inputs) + this.inputs.push(input.clone()); + + for (const output of tx.outputs) + this.outputs.push(output.clone()); + + this.locktime = tx.locktime; + + return this; + } + + /** + * Clear any cached values. + */ + + refresh() { + this._hash = null; + this._hhash = null; + this._whash = null; + + this._raw = null; + this._size = -1; + this._offset = -1; + this._block = false; + this._witness = -1; + this._sigops = -1; + + this._hashPrevouts = null; + this._hashSequence = null; + this._hashOutputs = null; + } + + /** + * Hash the transaction with the non-witness serialization. + * @param {String?} enc - Can be `'hex'` or `null`. + * @returns {Hash|Buffer} hash + */ + + hash(enc) { + let h = this._hash; + + if (!h) { + h = hash256.digest(this.toNormal()); + if (!this.mutable) + this._hash = h; + } + + if (enc === 'hex') { + let hex = this._hhash; + if (!hex) { + hex = h.toString('hex'); + if (!this.mutable) + this._hhash = hex; + } + h = hex; + } + + return h; + } + + /** + * Hash the transaction with the witness + * serialization, return the wtxid (normal + * hash if no witness is present, all zeroes + * if coinbase). + * @param {String?} enc - Can be `'hex'` or `null`. + * @returns {Hash|Buffer} hash + */ + + witnessHash(enc) { + if (!this.hasWitness()) + return this.hash(enc); + + let hash = this._whash; + + if (!hash) { + hash = hash256.digest(this.toRaw()); + if (!this.mutable) + this._whash = hash; + } + + return enc === 'hex' ? hash.toString('hex') : hash; + } + + /** + * Serialize the transaction. Note + * that this is cached. This will use + * the witness serialization if a + * witness is present. + * @returns {Buffer} Serialized transaction. + */ + + toRaw() { + return this.frame().data; + } + + /** + * Serialize the transaction without the + * witness vector, regardless of whether it + * is a witness transaction or not. + * @returns {Buffer} Serialized transaction. + */ + + toNormal() { + if (this.hasWitness()) + return this.frameNormal().data; + return this.toRaw(); + } + + /** + * Write the transaction to a buffer writer. + * @param {BufferWriter} bw + * @param {Boolean} block + */ + + toWriter(bw, block) { + if (this.mutable) { + if (this.hasWitness()) + return this.writeWitness(bw); + return this.writeNormal(bw); + } + + if (block) { + this._offset = bw.offset; + this._block = true; + } + + bw.writeBytes(this.toRaw()); + + return bw; + } + + /** + * Write the transaction to a buffer writer. + * Uses non-witness serialization. + * @param {BufferWriter} bw + */ + + toNormalWriter(bw) { + if (this.hasWitness()) { + this.writeNormal(bw); + return bw; + } + return this.toWriter(bw); + } + + /** + * Serialize the transaction. Note + * that this is cached. This will use + * the witness serialization if a + * witness is present. + * @private + * @returns {RawTX} + */ + + frame() { + if (this.mutable) { + assert(!this._raw); + if (this.hasWitness()) + return this.frameWitness(); + return this.frameNormal(); + } + + if (this._raw) { + assert(this._size >= 0); + assert(this._witness >= 0); + const raw = new RawTX(this._size, this._witness); + raw.data = this._raw; + return raw; + } + + let raw; + if (this.hasWitness()) + raw = this.frameWitness(); + else + raw = this.frameNormal(); + + this._raw = raw.data; + this._size = raw.size; + this._witness = raw.witness; + + return raw; + } + + /** + * Return the offset and size of the transaction. Useful + * when the transaction is deserialized within a block. + * @returns {Object} Contains `size` and `offset`. + */ + + getPosition() { + assert(this._block && this._offset > 80, 'Position not available.'); + + return { + offset: this._offset, + size: this._size + }; + } + + /** + * Calculate total size and size of the witness bytes. + * @returns {Object} Contains `size` and `witness`. + */ + + getSizes() { + if (this.mutable) { + if (this.hasWitness()) + return this.getWitnessSizes(); + return this.getNormalSizes(); + } + return this.frame(); + } + + /** + * Calculate the virtual size of the transaction. + * Note that this is cached. + * @returns {Number} vsize + */ + + getVirtualSize() { + const scale = consensus.WITNESS_SCALE_FACTOR; + return (this.getWeight() + scale - 1) / scale | 0; + } + + /** + * Calculate the virtual size of the transaction + * (weighted against bytes per sigop cost). + * @param {Number} sigops - Sigops cost. + * @returns {Number} vsize + */ + + getSigopsSize(sigops) { + const scale = consensus.WITNESS_SCALE_FACTOR; + const bytes = policy.BYTES_PER_SIGOP; + const weight = Math.max(this.getWeight(), sigops * bytes); + return (weight + scale - 1) / scale | 0; + } + + /** + * Calculate the weight of the transaction. + * Note that this is cached. + * @returns {Number} weight + */ + + getWeight() { + const raw = this.getSizes(); + const base = raw.size - raw.witness; + return base * (consensus.WITNESS_SCALE_FACTOR - 1) + raw.size; + } + + /** + * Calculate the real size of the transaction + * with the witness included. + * @returns {Number} size + */ + + getSize() { + return this.getSizes().size; + } + + /** + * Calculate the size of the transaction + * without the witness. + * with the witness included. + * @returns {Number} size + */ + + getBaseSize() { + const raw = this.getSizes(); + return raw.size - raw.witness; + } + + /** + * Test whether the transaction has a non-empty witness. + * @returns {Boolean} + */ + + hasWitness() { + if (this._witness !== -1) + return this._witness !== 0; + + for (const input of this.inputs) { + if (input.witness.items.length > 0) + return true; + } + + return false; + } + + /** + * Get the signature hash of the transaction for signing verifying. + * @param {Number} index - Index of input being signed/verified. + * @param {Script} prev - Previous output script or redeem script + * (in the case of witnesspubkeyhash, this should be the generated + * p2pkh script). + * @param {Amount} value - Previous output value. + * @param {SighashType} type - Sighash type. + * @param {Number} version - Sighash version (0=legacy, 1=segwit). + * @returns {Buffer} Signature hash. + */ + + signatureHash(index, prev, value, type, version) { + assert(index >= 0 && index < this.inputs.length); + assert(prev instanceof Script); + assert(typeof value === 'number'); + assert(typeof type === 'number'); + + // Traditional sighashing + if (version === 0) + return this.signatureHashV0(index, prev, type); + + // Segwit sighashing + if (version === 1) + return this.signatureHashV1(index, prev, value, type); + + throw new Error('Unknown sighash version.'); + } + + /** + * Legacy sighashing -- O(n^2). + * @private + * @param {Number} index + * @param {Script} prev + * @param {SighashType} type + * @returns {Buffer} + */ + + signatureHashV0(index, prev, type) { + if ((type & 0x1f) === hashType.SINGLE) { + // Bitcoind used to return 1 as an error code: + // it ended up being treated like a hash. + if (index >= this.outputs.length) { + const hash = Buffer.alloc(32, 0x00); + hash[0] = 0x01; + return hash; + } + } + + // Remove all code separators. + prev = prev.removeSeparators(); + + // Calculate buffer size. + const size = this.hashSize(index, prev, type); + const bw = bio.pool(size); + + bw.writeU32(this.version); + + // Serialize inputs. + if (type & hashType.ANYONECANPAY) { + // Serialize only the current + // input if ANYONECANPAY. + const input = this.inputs[index]; + + // Count. + bw.writeVarint(1); + + // Outpoint. + input.prevout.toWriter(bw); + + // Replace script with previous + // output script if current index. + bw.writeVarBytes(prev.toRaw()); + bw.writeU32(input.sequence); + } else { + bw.writeVarint(this.inputs.length); + for (let i = 0; i < this.inputs.length; i++) { + const input = this.inputs[i]; + + // Outpoint. + input.prevout.toWriter(bw); + + // Replace script with previous + // output script if current index. + if (i === index) { + bw.writeVarBytes(prev.toRaw()); + bw.writeU32(input.sequence); + continue; + } + + // Script is null. + bw.writeVarint(0); + + // Sequences are 0 if NONE or SINGLE. + switch (type & 0x1f) { + case hashType.NONE: + case hashType.SINGLE: + bw.writeU32(0); + break; + default: + bw.writeU32(input.sequence); + break; + } + } + } + + // Serialize outputs. + switch (type & 0x1f) { + case hashType.NONE: { + // No outputs if NONE. + bw.writeVarint(0); + break; + } + case hashType.SINGLE: { + const output = this.outputs[index]; + + // Drop all outputs after the + // current input index if SINGLE. + bw.writeVarint(index + 1); + + for (let i = 0; i < index; i++) { + // Null all outputs not at + // current input index. + bw.writeI64(-1); + bw.writeVarint(0); + } + + // Regular serialization + // at current input index. + output.toWriter(bw); + + break; + } + default: { + // Regular output serialization if ALL. + bw.writeVarint(this.outputs.length); + for (const output of this.outputs) + output.toWriter(bw); + break; + } + } + + bw.writeU32(this.locktime); + + // Append the hash type. + bw.writeU32(type); + + return hash256.digest(bw.render()); + } + + /** + * Calculate sighash size. + * @private + * @param {Number} index + * @param {Script} prev + * @param {Number} type + * @returns {Number} + */ + + hashSize(index, prev, type) { + let size = 0; + + size += 4; + + if (type & hashType.ANYONECANPAY) { + size += 1; + size += 36; + size += prev.getVarSize(); + size += 4; + } else { + size += encoding.sizeVarint(this.inputs.length); + size += 41 * (this.inputs.length - 1); + size += 36; + size += prev.getVarSize(); + size += 4; + } + + switch (type & 0x1f) { + case hashType.NONE: + size += 1; + break; + case hashType.SINGLE: + size += encoding.sizeVarint(index + 1); + size += 9 * index; + size += this.outputs[index].getSize(); + break; + default: + size += encoding.sizeVarint(this.outputs.length); + for (const output of this.outputs) + size += output.getSize(); + break; + } + + size += 8; + + return size; + } + + /** + * Witness sighashing -- O(n). + * @private + * @param {Number} index + * @param {Script} prev + * @param {Amount} value + * @param {SighashType} type + * @returns {Buffer} + */ + + signatureHashV1(index, prev, value, type) { + const input = this.inputs[index]; + let prevouts = consensus.ZERO_HASH; + let sequences = consensus.ZERO_HASH; + let outputs = consensus.ZERO_HASH; + + if (!(type & hashType.ANYONECANPAY)) { + if (this._hashPrevouts) { + prevouts = this._hashPrevouts; + } else { + const bw = bio.pool(this.inputs.length * 36); + + for (const input of this.inputs) + input.prevout.toWriter(bw); + + prevouts = hash256.digest(bw.render()); + + if (!this.mutable) + this._hashPrevouts = prevouts; + } + } + + if (!(type & hashType.ANYONECANPAY) + && (type & 0x1f) !== hashType.SINGLE + && (type & 0x1f) !== hashType.NONE) { + if (this._hashSequence) { + sequences = this._hashSequence; + } else { + const bw = bio.pool(this.inputs.length * 4); + + for (const input of this.inputs) + bw.writeU32(input.sequence); + + sequences = hash256.digest(bw.render()); + + if (!this.mutable) + this._hashSequence = sequences; + } + } + + if ((type & 0x1f) !== hashType.SINGLE + && (type & 0x1f) !== hashType.NONE) { + if (this._hashOutputs) { + outputs = this._hashOutputs; + } else { + let size = 0; + + for (const output of this.outputs) + size += output.getSize(); + + const bw = bio.pool(size); + + for (const output of this.outputs) + output.toWriter(bw); + + outputs = hash256.digest(bw.render()); + + if (!this.mutable) + this._hashOutputs = outputs; + } + } else if ((type & 0x1f) === hashType.SINGLE) { + if (index < this.outputs.length) { + const output = this.outputs[index]; + outputs = hash256.digest(output.toRaw()); + } + } + + const size = 156 + prev.getVarSize(); + const bw = bio.pool(size); + + bw.writeU32(this.version); + bw.writeBytes(prevouts); + bw.writeBytes(sequences); + bw.writeHash(input.prevout.hash); + bw.writeU32(input.prevout.index); + bw.writeVarBytes(prev.toRaw()); + bw.writeI64(value); + bw.writeU32(input.sequence); + bw.writeBytes(outputs); + bw.writeU32(this.locktime); + bw.writeU32(type); + + return hash256.digest(bw.render()); + } + + /** + * Verify signature. + * @param {Number} index + * @param {Script} prev + * @param {Amount} value + * @param {Buffer} sig + * @param {Buffer} key + * @param {Number} version + * @returns {Boolean} + */ + + checksig(index, prev, value, sig, key, version) { + if (sig.length === 0) + return false; + + const type = sig[sig.length - 1]; + const hash = this.signatureHash(index, prev, value, type, version); + + return secp256k1.verifyDER(hash, sig.slice(0, -1), key); + } + + /** + * Create a signature suitable for inserting into scriptSigs/witnesses. + * @param {Number} index - Index of input being signed. + * @param {Script} prev - Previous output script or redeem script + * (in the case of witnesspubkeyhash, this should be the generated + * p2pkh script). + * @param {Amount} value - Previous output value. + * @param {Buffer} key + * @param {SighashType} type + * @param {Number} version - Sighash version (0=legacy, 1=segwit). + * @returns {Buffer} Signature in DER format. + */ + + signature(index, prev, value, key, type, version) { + if (type == null) + type = hashType.ALL; + + if (version == null) + version = 0; + + const hash = this.signatureHash(index, prev, value, type, version); + const sig = secp256k1.signDER(hash, key); + const bw = bio.write(sig.length + 1); + + bw.writeBytes(sig); + bw.writeU8(type); + + return bw.render(); + } + + /** + * Verify all transaction inputs. + * @param {CoinView} view + * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] + * @throws {ScriptError} on invalid inputs + */ + + check(view, flags) { + if (this.inputs.length === 0) + throw new ScriptError('UNKNOWN_ERROR', 'No inputs.'); + + if (this.isCoinbase()) + return; + + for (let i = 0; i < this.inputs.length; i++) { + const {prevout} = this.inputs[i]; + const coin = view.getOutput(prevout); + + if (!coin) + throw new ScriptError('UNKNOWN_ERROR', 'No coin available.'); + + this.checkInput(i, coin, flags); + } + } + + /** + * Verify a transaction input. + * @param {Number} index - Index of output being + * verified. + * @param {Coin|Output} coin - Previous output. + * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] + * @throws {ScriptError} on invalid input + */ + + checkInput(index, coin, flags) { + const input = this.inputs[index]; + + assert(input, 'Input does not exist.'); + assert(coin, 'No coin passed.'); + + Script.verify( + input.script, + input.witness, + coin.script, + this, + index, + coin.value, + flags + ); + } + + /** + * Verify the transaction inputs on the worker pool + * (if workers are enabled). + * @param {CoinView} view + * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] + * @param {WorkerPool?} pool + * @returns {Promise} + */ + + async checkAsync(view, flags, pool) { + if (this.inputs.length === 0) + throw new ScriptError('UNKNOWN_ERROR', 'No inputs.'); + + if (this.isCoinbase()) + return; + + if (!pool) { + this.check(view, flags); + return; + } + + await pool.check(this, view, flags); + } + + /** + * Verify a transaction input asynchronously. + * @param {Number} index - Index of output being + * verified. + * @param {Coin|Output} coin - Previous output. + * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] + * @param {WorkerPool?} pool + * @returns {Promise} + */ + + async checkInputAsync(index, coin, flags, pool) { + const input = this.inputs[index]; + + assert(input, 'Input does not exist.'); + assert(coin, 'No coin passed.'); + + if (!pool) { + this.checkInput(index, coin, flags); + return; + } + + await pool.checkInput(this, index, coin, flags); + } + + /** + * Verify all transaction inputs. + * @param {CoinView} view + * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] + * @returns {Boolean} Whether the inputs are valid. + */ + + verify(view, flags) { + try { + this.check(view, flags); + } catch (e) { + if (e.type === 'ScriptError') + return false; + throw e; + } + return true; + } + + /** + * Verify a transaction input. + * @param {Number} index - Index of output being + * verified. + * @param {Coin|Output} coin - Previous output. + * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] + * @returns {Boolean} Whether the input is valid. + */ + + verifyInput(index, coin, flags) { + try { + this.checkInput(index, coin, flags); + } catch (e) { + if (e.type === 'ScriptError') + return false; + throw e; + } + return true; + } + + /** + * Verify the transaction inputs on the worker pool + * (if workers are enabled). + * @param {CoinView} view + * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] + * @param {WorkerPool?} pool + * @returns {Promise} + */ + + async verifyAsync(view, flags, pool) { + try { + await this.checkAsync(view, flags, pool); + } catch (e) { + if (e.type === 'ScriptError') + return false; + throw e; + } + return true; + } + + /** + * Verify a transaction input asynchronously. + * @param {Number} index - Index of output being + * verified. + * @param {Coin|Output} coin - Previous output. + * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] + * @param {WorkerPool?} pool + * @returns {Promise} + */ + + async verifyInputAsync(index, coin, flags, pool) { + try { + await this.checkInput(index, coin, flags, pool); + } catch (e) { + if (e.type === 'ScriptError') + return false; + throw e; + } + return true; + } + + /** + * Test whether the transaction is a coinbase + * by examining the inputs. + * @returns {Boolean} + */ + + isCoinbase() { + return this.inputs.length === 1 && this.inputs[0].prevout.isNull(); + } + + /** + * Test whether the transaction is replaceable. + * @returns {Boolean} + */ + + isRBF() { + // Core doesn't do this, but it should: + if (this.version === 2) + return false; + + for (const input of this.inputs) { + if (input.isRBF()) + return true; + } + + return false; + } + + /** + * Calculate the fee for the transaction. + * @param {CoinView} view + * @returns {Amount} fee (zero if not all coins are available). + */ + + getFee(view) { + if (!this.hasCoins(view)) + return 0; + + return this.getInputValue(view) - this.getOutputValue(); + } + + /** + * Calculate the total input value. + * @param {CoinView} view + * @returns {Amount} value + */ + + getInputValue(view) { + let total = 0; + + for (const {prevout} of this.inputs) { + const coin = view.getOutput(prevout); + + if (!coin) + return 0; + + total += coin.value; + } + + return total; + } + + /** + * Calculate the total output value. + * @returns {Amount} value + */ + + getOutputValue() { + let total = 0; + + for (const output of this.outputs) + total += output.value; + + return total; + } + + /** + * Get all input addresses. + * @private + * @param {CoinView} view + * @returns {Array} [addrs, table] + */ + + _getInputAddresses(view) { + const table = new BufferSet(); + const addrs = []; + + if (this.isCoinbase()) + return [addrs, table]; + + for (const input of this.inputs) { + const coin = view ? view.getOutputFor(input) : null; + const addr = input.getAddress(coin); + + if (!addr) + continue; + + const hash = addr.getHash(); + + if (!table.has(hash)) { + table.add(hash); + addrs.push(addr); + } + } + + return [addrs, table]; + } + + /** + * Get all output addresses. + * @private + * @returns {Array} [addrs, table] + */ + + _getOutputAddresses() { + const table = new BufferSet(); + const addrs = []; + + for (const output of this.outputs) { + if (output.script.isMultisig()) { + const [, n] = output.script.getMultisig(); + + for (let i = 1; i <= n; i++) { + const keyring = KeyRing.fromMultisigScript(output.script, i); + table.add(keyring.getHash()); + } + } else { + const addr = output.getAddress(); + + if (!addr) + continue; + + const hash = addr.getHash(); + + if (!table.has(hash)) { + table.add(hash); + addrs.push(addr); + } + } + } + + return [addrs, table]; + } + + /** + * Get all addresses. + * @private + * @param {CoinView} view + * @returns {Array} [addrs, table] + */ + + _getAddresses(view) { + const [addrs, table] = this._getInputAddresses(view); + const output = this.getOutputAddresses(); + + for (const addr of output) { + const hash = addr.getHash(); + + if (!table.has(hash)) { + table.add(hash); + addrs.push(addr); + } + } + + return [addrs, table]; + } + + /** + * Get all input addresses. + * @param {CoinView|null} view + * @returns {Address[]} addresses + */ + + getInputAddresses(view) { + const [addrs] = this._getInputAddresses(view); + return addrs; + } + + /** + * Get all output addresses. + * @returns {Address[]} addresses + */ + + getOutputAddresses() { + const [addrs] = this._getOutputAddresses(); + return addrs; + } + + /** + * Get all addresses. + * @param {CoinView|null} view + * @returns {Address[]} addresses + */ + + getAddresses(view) { + const [addrs] = this._getAddresses(view); + return addrs; + } + + /** + * Get all input address hashes. + * @param {CoinView|null} view + * @returns {Hash[]} hashes + */ + + getInputHashes(view, enc) { + const [, table] = this._getInputAddresses(view); + + if (enc !== 'hex') + return table.toArray(); + + return table.toArray().map(h => h.toString('hex')); + } + + /** + * Get all output address hashes. + * @returns {Hash[]} hashes + */ + + getOutputHashes(enc) { + const [, table] = this._getOutputAddresses(); + + if (enc !== 'hex') + return table.toArray(); + + return table.toArray().map(h => h.toString('hex')); + } + + /** + * Get all address hashes. + * @param {CoinView|null} view + * @returns {Hash[]} hashes + */ + + getHashes(view, enc) { + const [, table] = this._getAddresses(view); + + if (enc !== 'hex') + return table.toArray(); + + return table.toArray().map(h => h.toString('hex')); + } + + /** + * Test whether the transaction has + * all coins available. + * @param {CoinView} view + * @returns {Boolean} + */ + + hasCoins(view) { + if (this.inputs.length === 0) + return false; + + for (const {prevout} of this.inputs) { + if (!view.hasEntry(prevout)) + return false; + } + + return true; + } + + /** + * Check finality of transaction by examining + * nLocktime and nSequence values. + * @example + * tx.isFinal(chain.height + 1, network.now()); + * @param {Number} height - Height at which to test. This + * is usually the chain height, or the chain height + 1 + * when the transaction entered the mempool. + * @param {Number} time - Time at which to test. This is + * usually the chain tip's parent's median time, or the + * time at which the transaction entered the mempool. If + * MEDIAN_TIME_PAST is enabled this will be the median + * time of the chain tip's previous entry's median time. + * @returns {Boolean} + */ + + isFinal(height, time) { + const THRESHOLD = consensus.LOCKTIME_THRESHOLD; + + if (this.locktime === 0) + return true; + + if (this.locktime < (this.locktime < THRESHOLD ? height : time)) + return true; + + for (const input of this.inputs) { + if (input.sequence !== 0xffffffff) + return false; + } + + return true; + } + + /** + * Verify the absolute locktime of a transaction. + * Called by OP_CHECKLOCKTIMEVERIFY. + * @param {Number} index - Index of input being verified. + * @param {Number} predicate - Locktime to verify against. + * @returns {Boolean} + */ + + verifyLocktime(index, predicate) { + const THRESHOLD = consensus.LOCKTIME_THRESHOLD; + const input = this.inputs[index]; + + assert(input, 'Input does not exist.'); + assert(predicate >= 0, 'Locktime must be non-negative.'); + + // Locktimes must be of the same type (blocks or seconds). + if ((this.locktime < THRESHOLD) !== (predicate < THRESHOLD)) + return false; + + if (predicate > this.locktime) + return false; + + if (input.sequence === 0xffffffff) + return false; + + return true; + } + + /** + * Verify the relative locktime of an input. + * Called by OP_CHECKSEQUENCEVERIFY. + * @param {Number} index - Index of input being verified. + * @param {Number} predicate - Relative locktime to verify against. + * @returns {Boolean} + */ + + verifySequence(index, predicate) { + const DISABLE_FLAG = consensus.SEQUENCE_DISABLE_FLAG; + const TYPE_FLAG = consensus.SEQUENCE_TYPE_FLAG; + const MASK = consensus.SEQUENCE_MASK; + const input = this.inputs[index]; + + assert(input, 'Input does not exist.'); + assert(predicate >= 0, 'Locktime must be non-negative.'); + + // For future softfork capability. + if (predicate & DISABLE_FLAG) + return true; + + // Version must be >=2. + if (this.version < 2) + return false; + + // Cannot use the disable flag without + // the predicate also having the disable + // flag (for future softfork capability). + if (input.sequence & DISABLE_FLAG) + return false; + + // Locktimes must be of the same type (blocks or seconds). + if ((input.sequence & TYPE_FLAG) !== (predicate & TYPE_FLAG)) + return false; + + if ((predicate & MASK) > (input.sequence & MASK)) + return false; + + return true; + } + + /** + * Calculate legacy (inaccurate) sigop count. + * @returns {Number} sigop count + */ + + getLegacySigops() { + if (this._sigops !== -1) + return this._sigops; + + let total = 0; + + for (const input of this.inputs) + total += input.script.getSigops(false); + + for (const output of this.outputs) + total += output.script.getSigops(false); + + if (!this.mutable) + this._sigops = total; + + return total; + } + + /** + * Calculate accurate sigop count, taking into account redeem scripts. + * @param {CoinView} view + * @returns {Number} sigop count + */ + + getScripthashSigops(view) { + if (this.isCoinbase()) + return 0; + + let total = 0; + + for (const input of this.inputs) { + const coin = view.getOutputFor(input); + + if (!coin) + continue; + + if (!coin.script.isScripthash()) + continue; + + total += coin.script.getScripthashSigops(input.script); + } + + return total; + } + + /** + * Calculate accurate sigop count, taking into account redeem scripts. + * @param {CoinView} view + * @returns {Number} sigop count + */ + + getWitnessSigops(view) { + if (this.isCoinbase()) + return 0; + + let total = 0; + + for (const input of this.inputs) { + const coin = view.getOutputFor(input); + + if (!coin) + continue; + + total += coin.script.getWitnessSigops(input.script, input.witness); + } + + return total; + } + + /** + * Calculate sigops cost, taking into account witness programs. + * @param {CoinView} view + * @param {VerifyFlags?} flags + * @returns {Number} sigop weight + */ + + getSigopsCost(view, flags) { + if (flags == null) + flags = Script.flags.STANDARD_VERIFY_FLAGS; + + const scale = consensus.WITNESS_SCALE_FACTOR; + + let cost = this.getLegacySigops() * scale; + + if (flags & Script.flags.VERIFY_P2SH) + cost += this.getScripthashSigops(view) * scale; + + if (flags & Script.flags.VERIFY_WITNESS) + cost += this.getWitnessSigops(view); + + return cost; + } + + /** + * Calculate virtual sigop count. + * @param {CoinView} view + * @param {VerifyFlags?} flags + * @returns {Number} sigop count + */ + + getSigops(view, flags) { + const scale = consensus.WITNESS_SCALE_FACTOR; + return (this.getSigopsCost(view, flags) + scale - 1) / scale | 0; + } + + /** + * Non-contextual sanity checks for the transaction. + * Will mostly verify coin and output values. + * @see CheckTransaction() + * @returns {Array} [result, reason, score] + */ + + isSane() { + const [valid] = this.checkSanity(); + return valid; + } + + /** + * Non-contextual sanity checks for the transaction. + * Will mostly verify coin and output values. + * @see CheckTransaction() + * @returns {Array} [valid, reason, score] + */ + + checkSanity() { + if (this.inputs.length === 0) + return [false, 'bad-txns-vin-empty', 100]; + + if (this.outputs.length === 0) + return [false, 'bad-txns-vout-empty', 100]; + + if (this.getBaseSize() > consensus.MAX_BLOCK_SIZE) + return [false, 'bad-txns-oversize', 100]; + + let total = 0; + + for (const output of this.outputs) { + if (output.value < 0) + return [false, 'bad-txns-vout-negative', 100]; + + if (output.value > consensus.MAX_MONEY) + return [false, 'bad-txns-vout-toolarge', 100]; + + total += output.value; + + if (total < 0 || total > consensus.MAX_MONEY) + return [false, 'bad-txns-txouttotal-toolarge', 100]; + } + + const prevout = new BufferSet(); + + for (const input of this.inputs) { + const key = input.prevout.toKey(); + + if (prevout.has(key)) + return [false, 'bad-txns-inputs-duplicate', 100]; + + prevout.add(key); + } + + if (this.isCoinbase()) { + const size = this.inputs[0].script.getSize(); + if (size < 2 || size > 100) + return [false, 'bad-cb-length', 100]; + } else { + for (const input of this.inputs) { + if (input.prevout.isNull()) + return [false, 'bad-txns-prevout-null', 10]; + } + } + + return [true, 'valid', 0]; + } + + /** + * Non-contextual checks to determine whether the + * transaction has all standard output script + * types and standard input script size with only + * pushdatas in the code. + * Will mostly verify coin and output values. + * @see IsStandardTx() + * @returns {Array} [valid, reason, score] + */ + + isStandard() { + const [valid] = this.checkStandard(); + return valid; + } + + /** + * Non-contextual checks to determine whether the + * transaction has all standard output script + * types and standard input script size with only + * pushdatas in the code. + * Will mostly verify coin and output values. + * @see IsStandardTx() + * @returns {Array} [valid, reason, score] + */ + + checkStandard() { + if (this.version < 1 || this.version > policy.MAX_TX_VERSION) + return [false, 'version', 0]; + + if (this.getWeight() >= policy.MAX_TX_WEIGHT) + return [false, 'tx-size', 0]; + + for (const input of this.inputs) { + if (input.script.getSize() > 1650) + return [false, 'scriptsig-size', 0]; + + if (!input.script.isPushOnly()) + return [false, 'scriptsig-not-pushonly', 0]; + } + + let nulldata = 0; + + for (const output of this.outputs) { + if (!output.script.isStandard()) + return [false, 'scriptpubkey', 0]; + + if (output.script.isNulldata()) { + nulldata++; + continue; + } + + if (output.script.isMultisig() && !policy.BARE_MULTISIG) + return [false, 'bare-multisig', 0]; + + if (output.isDust(policy.MIN_RELAY)) + return [false, 'dust', 0]; + } + + if (nulldata > 1) + return [false, 'multi-op-return', 0]; + + return [true, 'valid', 0]; + } + + /** + * Perform contextual checks to verify coin and input + * script standardness (including the redeem script). + * @see AreInputsStandard() + * @param {CoinView} view + * @param {VerifyFlags?} flags + * @returns {Boolean} + */ + + hasStandardInputs(view) { + if (this.isCoinbase()) + return true; + + for (const input of this.inputs) { + const coin = view.getOutputFor(input); + + if (!coin) + return false; + + if (coin.script.isPubkeyhash()) + continue; + + if (coin.script.isScripthash()) { + const redeem = input.script.getRedeem(); + + if (!redeem) + return false; + + if (redeem.getSigops(true) > policy.MAX_P2SH_SIGOPS) + return false; + + continue; + } + + if (coin.script.isUnknown()) + return false; + } + + return true; + } + + /** + * Perform contextual checks to verify coin and witness standardness. + * @see IsBadWitness() + * @param {CoinView} view + * @returns {Boolean} + */ + + hasStandardWitness(view) { + if (this.isCoinbase()) + return true; + + for (const input of this.inputs) { + const witness = input.witness; + const coin = view.getOutputFor(input); + + if (!coin) + continue; + + if (witness.items.length === 0) + continue; + + let prev = coin.script; + + if (prev.isScripthash()) { + prev = input.script.getRedeem(); + if (!prev) + return false; + } + + if (!prev.isProgram()) + return false; + + if (prev.isWitnessPubkeyhash()) { + if (witness.items.length !== 2) + return false; + + if (witness.items[0].length > 73) + return false; + + if (witness.items[1].length > 65) + return false; + + continue; + } + + if (prev.isWitnessScripthash()) { + if (witness.items.length - 1 > policy.MAX_P2WSH_STACK) + return false; + + for (let i = 0; i < witness.items.length - 1; i++) { + const item = witness.items[i]; + if (item.length > policy.MAX_P2WSH_PUSH) + return false; + } + + const raw = witness.items[witness.items.length - 1]; + + if (raw.length > policy.MAX_P2WSH_SIZE) + return false; + + const redeem = Script.fromRaw(raw); + + if (redeem.isPubkey()) { + if (witness.items.length - 1 !== 1) + return false; + + if (witness.items[0].length > 73) + return false; + + continue; + } + + if (redeem.isPubkeyhash()) { + if (input.witness.items.length - 1 !== 2) + return false; + + if (witness.items[0].length > 73) + return false; + + if (witness.items[1].length > 65) + return false; + + continue; + } + + const [m] = redeem.getMultisig(); + + if (m !== -1) { + if (witness.items.length - 1 !== m + 1) + return false; + + if (witness.items[0].length !== 0) + return false; + + for (let i = 1; i < witness.items.length - 1; i++) { + const item = witness.items[i]; + if (item.length > 73) + return false; + } + } + + continue; + } + + if (witness.items.length > policy.MAX_P2WSH_STACK) + return false; + + for (const item of witness.items) { + if (item.length > policy.MAX_P2WSH_PUSH) + return false; + } + } + + return true; + } + + /** + * Perform contextual checks to verify input, output, + * and fee values, as well as coinbase spend maturity + * (coinbases can only be spent 100 blocks or more + * after they're created). Note that this function is + * consensus critical. + * @param {CoinView} view + * @param {Number} height - Height at which the + * transaction is being spent. In the mempool this is + * the chain height plus one at the time it entered the pool. + * @returns {Boolean} + */ + + verifyInputs(view, height) { + const [fee] = this.checkInputs(view, height); + return fee !== -1; + } + + /** + * Perform contextual checks to verify input, output, + * and fee values, as well as coinbase spend maturity + * (coinbases can only be spent 100 blocks or more + * after they're created). Note that this function is + * consensus critical. + * @param {CoinView} view + * @param {Number} height - Height at which the + * transaction is being spent. In the mempool this is + * the chain height plus one at the time it entered the pool. + * @returns {Array} [fee, reason, score] + */ + + checkInputs(view, height) { + assert(typeof height === 'number'); + + let total = 0; + + for (const {prevout} of this.inputs) { + const entry = view.getEntry(prevout); + + if (!entry) + return [-1, 'bad-txns-inputs-missingorspent', 0]; + + if (entry.coinbase) { + if (height - entry.height < consensus.COINBASE_MATURITY) + return [-1, 'bad-txns-premature-spend-of-coinbase', 0]; + } + + const coin = view.getOutput(prevout); + assert(coin); + + if (coin.value < 0 || coin.value > consensus.MAX_MONEY) + return [-1, 'bad-txns-inputvalues-outofrange', 100]; + + total += coin.value; + + if (total < 0 || total > consensus.MAX_MONEY) + return [-1, 'bad-txns-inputvalues-outofrange', 100]; + } + + // Overflows already checked in `isSane()`. + const value = this.getOutputValue(); + + if (total < value) + return [-1, 'bad-txns-in-belowout', 100]; + + const fee = total - value; + + if (fee < 0) + return [-1, 'bad-txns-fee-negative', 100]; + + if (fee > consensus.MAX_MONEY) + return [-1, 'bad-txns-fee-outofrange', 100]; + + return [fee, 'valid', 0]; + } + + /** + * Calculate the modified size of the transaction. This + * is used in the mempool for calculating priority. + * @param {Number?} size - The size to modify. If not present, + * virtual size will be used. + * @returns {Number} Modified size. + */ + + getModifiedSize(size) { + if (size == null) + size = this.getVirtualSize(); + + for (const input of this.inputs) { + const offset = 41 + Math.min(110, input.script.getSize()); + if (size > offset) + size -= offset; + } + + return size; + } + + /** + * Calculate the transaction priority. + * @param {CoinView} view + * @param {Number} height + * @param {Number?} size - Size to calculate priority + * based on. If not present, virtual size will be used. + * @returns {Number} + */ + + getPriority(view, height, size) { + assert(typeof height === 'number', 'Must pass in height.'); + + if (this.isCoinbase()) + return 0; + + if (size == null) + size = this.getVirtualSize(); + + let sum = 0; + + for (const {prevout} of this.inputs) { + const coin = view.getOutput(prevout); + + if (!coin) + continue; + + const coinHeight = view.getHeight(prevout); + + if (coinHeight === -1) + continue; + + if (coinHeight <= height) { + const age = height - coinHeight; + sum += coin.value * age; + } + } + + return Math.floor(sum / size); + } + + /** + * Calculate the transaction's on-chain value. + * @param {CoinView} view + * @returns {Number} + */ + + getChainValue(view) { + if (this.isCoinbase()) + return 0; + + let value = 0; + + for (const {prevout} of this.inputs) { + const coin = view.getOutput(prevout); + + if (!coin) + continue; + + const height = view.getHeight(prevout); + + if (height === -1) + continue; + + value += coin.value; + } + + return value; + } + + /** + * Determine whether the transaction is above the + * free threshold in priority. A transaction which + * passed this test is most likely relayable + * without a fee. + * @param {CoinView} view + * @param {Number?} height - If not present, tx + * height or network height will be used. + * @param {Number?} size - If not present, modified + * size will be calculated and used. + * @returns {Boolean} + */ + + isFree(view, height, size) { + const priority = this.getPriority(view, height, size); + return priority > policy.FREE_THRESHOLD; + } + + /** + * Calculate minimum fee in order for the transaction + * to be relayable (not the constant min relay fee). + * @param {Number?} size - If not present, max size + * estimation will be calculated and used. + * @param {Rate?} rate - Rate of satoshi per kB. + * @returns {Amount} fee + */ + + getMinFee(size, rate) { + if (size == null) + size = this.getVirtualSize(); + + return policy.getMinFee(size, rate); + } + + /** + * Calculate the minimum fee in order for the transaction + * to be relayable, but _round to the nearest kilobyte + * when taking into account size. + * @param {Number?} size - If not present, max size + * estimation will be calculated and used. + * @param {Rate?} rate - Rate of satoshi per kB. + * @returns {Amount} fee + */ + + getRoundFee(size, rate) { + if (size == null) + size = this.getVirtualSize(); + + return policy.getRoundFee(size, rate); + } + + /** + * Calculate the transaction's rate based on size + * and fees. Size will be calculated if not present. + * @param {CoinView} view + * @param {Number?} size + * @returns {Rate} + */ + + getRate(view, size) { + const fee = this.getFee(view); + + if (fee < 0) + return 0; + + if (size == null) + size = this.getVirtualSize(); + + return policy.getRate(size, fee); + } + + /** + * Get all unique outpoint hashes. + * @returns {Hash[]} Outpoint hashes. + */ + + getPrevout() { + if (this.isCoinbase()) + return []; + + const prevout = new BufferSet(); + + for (const input of this.inputs) + prevout.add(input.prevout.hash); + + return prevout.toArray(); + } + + /** + * Test a transaction against a bloom filter using + * the BIP37 matching algorithm. Note that this may + * update the filter depending on what the `update` + * value is. + * @see "Filter matching algorithm": + * @see https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki + * @param {BloomFilter} filter + * @returns {Boolean} True if the transaction matched. + */ + + isWatched(filter) { + let found = false; + + // 1. Test the tx hash + if (filter.test(this.hash())) + found = true; + + // 2. Test data elements in output scripts + // (may need to update filter on match) + for (let i = 0; i < this.outputs.length; i++) { + const output = this.outputs[i]; + // Test the output script + if (output.script.test(filter)) { + if (filter.update === 1 /* ALL */) { + const prevout = Outpoint.fromTX(this, i); + filter.add(prevout.toRaw()); + } else if (filter.update === 2 /* PUBKEY_ONLY */) { + if (output.script.isPubkey() || output.script.isMultisig()) { + const prevout = Outpoint.fromTX(this, i); + filter.add(prevout.toRaw()); + } + } + found = true; + } + } + + if (found) + return found; + + // 3. Test prev_out structure + // 4. Test data elements in input scripts + for (const input of this.inputs) { + const prevout = input.prevout; + + // Test the COutPoint structure + if (filter.test(prevout.toRaw())) + return true; + + // Test the input script + if (input.script.test(filter)) + return true; + } + + // 5. No match + return false; + } + + /** + * Get little-endian tx hash. + * @returns {Hash} + */ + + rhash() { + return util.revHex(this.hash()); + } + + /** + * Get little-endian wtx hash. + * @returns {Hash} + */ + + rwhash() { + return util.revHex(this.witnessHash()); + } + + /** + * Get little-endian tx hash. + * @returns {Hash} + */ + + txid() { + return this.rhash(); + } + + /** + * Get little-endian wtx hash. + * @returns {Hash} + */ + + wtxid() { + return this.rwhash(); + } + + /** + * Convert the tx to an inv item. + * @returns {InvItem} + */ + + toInv() { + return new InvItem(InvItem.types.TX, this.hash()); + } + + /** + * Inspect the transaction and return a more + * user-friendly representation of the data. + * @returns {Object} + */ + + [inspectSymbol]() { + return this.format(); + } + + /** + * Inspect the transaction and return a more + * user-friendly representation of the data. + * @param {CoinView} view + * @param {ChainEntry} entry + * @param {Number} index + * @returns {Object} + */ + + format(view, entry, index) { + let rate = 0; + let fee = 0; + let height = -1; + let block = null; + let time = 0; + let date = null; + + if (view) { + fee = this.getFee(view); + rate = this.getRate(view); + + // Rate can exceed 53 bits in testing. + if (!Number.isSafeInteger(rate)) + rate = 0; + } + + if (entry) { + height = entry.height; + block = util.revHex(entry.hash); + time = entry.time; + date = util.date(time); + } + + if (index == null) + index = -1; + + return { + hash: this.txid(), + witnessHash: this.wtxid(), + size: this.getSize(), + virtualSize: this.getVirtualSize(), + value: Amount.btc(this.getOutputValue()), + fee: Amount.btc(fee), + rate: Amount.btc(rate), + minFee: Amount.btc(this.getMinFee()), + height: height, + block: block, + time: time, + date: date, + index: index, + version: this.version, + inputs: this.inputs.map((input) => { + const coin = view ? view.getOutputFor(input) : null; + return input.format(coin); + }), + outputs: this.outputs, + locktime: this.locktime + }; + } + + /** + * Convert the transaction to an object suitable + * for JSON serialization. + * @returns {Object} + */ + + toJSON() { + return this.getJSON(); + } + + /** + * Convert the transaction to an object suitable + * for JSON serialization. Note that the hashes + * will be reversed to abide by bitcoind's legacy + * of little-endian uint256s. + * @param {Network} network + * @param {CoinView} view + * @param {ChainEntry} entry + * @param {Number} index + * @returns {Object} + */ + + getJSON(network, view, entry, index) { + let rate, fee, height, block, time, date; + + if (view) { + fee = this.getFee(view); + rate = this.getRate(view); + + // Rate can exceed 53 bits in testing. + if (!Number.isSafeInteger(rate)) + rate = 0; + } + + if (entry) { + height = entry.height; + block = util.revHex(entry.hash); + time = entry.time; + date = util.date(time); + } + + network = Network.get(network); + + return { + hash: this.txid(), + witnessHash: this.wtxid(), + fee: fee, + rate: rate, + mtime: util.now(), + height: height, + block: block, + time: time, + date: date, + index: index, + version: this.version, + inputs: this.inputs.map((input) => { + const coin = view ? view.getCoinFor(input) : null; + return input.getJSON(network, coin); + }), + outputs: this.outputs.map((output) => { + return output.getJSON(network); + }), + locktime: this.locktime, + hex: this.toRaw().toString('hex') + }; + } + + /** + * Inject properties from a json object. + * @private + * @param {Object} json + */ + + fromJSON(json) { + assert(json, 'TX data is required.'); + assert((json.version >>> 0) === json.version, 'Version must be a uint32.'); + assert(Array.isArray(json.inputs), 'Inputs must be an array.'); + assert(Array.isArray(json.outputs), 'Outputs must be an array.'); + assert((json.locktime >>> 0) === json.locktime, + 'Locktime must be a uint32.'); + + this.version = json.version; + + for (const input of json.inputs) + this.inputs.push(Input.fromJSON(input)); + + for (const output of json.outputs) + this.outputs.push(Output.fromJSON(output)); + + this.locktime = json.locktime; + + return this; + } + + /** + * Instantiate a transaction from a + * jsonified transaction object. + * @param {Object} json - The jsonified transaction object. + * @returns {TX} + */ + + static fromJSON(json) { + return new this().fromJSON(json); + } + + /** + * Instantiate a transaction from a serialized Buffer. + * @param {Buffer} data + * @param {String?} enc - Encoding, can be `'hex'` or null. + * @returns {TX} + */ + + static fromRaw(data, enc) { + if (typeof data === 'string') + data = Buffer.from(data, enc); + return new this().fromRaw(data); + } + + /** + * Instantiate a transaction from a buffer reader. + * @param {BufferReader} br + * @param {Boolean} block + * @returns {TX} + */ + + static fromReader(br, block) { + return new this().fromReader(br, block); + } + + /** + * Inject properties from serialized data. + * @private + * @param {Buffer} data + */ + + fromRaw(data) { + return this.fromReader(bio.read(data)); + } + + /** + * Inject properties from buffer reader. + * @private + * @param {BufferReader} br + * @param {Boolean} block + */ + + fromReader(br, block) { + if (hasWitnessBytes(br)) + return this.fromWitnessReader(br, block); + + const start = br.start(); + + this.version = br.readU32(); + + const inCount = br.readVarint(); + + for (let i = 0; i < inCount; i++) + this.inputs.push(Input.fromReader(br)); + + const outCount = br.readVarint(); + + for (let i = 0; i < outCount; i++) + this.outputs.push(Output.fromReader(br)); + + this.locktime = br.readU32(); + + if (block) { + this._offset = start; + this._block = true; + } + + if (!this.mutable) { + this._raw = br.endData(); + this._size = this._raw.length; + this._witness = 0; + } else { + br.end(); + } + + return this; + } + + /** + * Inject properties from serialized + * buffer reader (witness serialization). + * @private + * @param {BufferReader} br + * @param {Boolean} block + */ + + fromWitnessReader(br, block) { + const start = br.start(); + + this.version = br.readU32(); + + assert(br.readU8() === 0, 'Non-zero marker.'); + + let flags = br.readU8(); + + assert(flags !== 0, 'Flags byte is zero.'); + + const inCount = br.readVarint(); + + for (let i = 0; i < inCount; i++) + this.inputs.push(Input.fromReader(br)); + + const outCount = br.readVarint(); + + for (let i = 0; i < outCount; i++) + this.outputs.push(Output.fromReader(br)); + + let witness = 0; + let hasWitness = false; + + if (flags & 1) { + flags ^= 1; + + witness = br.offset; + + for (const input of this.inputs) { + input.witness.fromReader(br); + if (input.witness.items.length > 0) + hasWitness = true; + } + + witness = (br.offset - witness) + 2; + } + + if (flags !== 0) + throw new Error('Unknown witness flag.'); + + // We'll never be able to reserialize + // this to get the regular txid, and + // there's no way it's valid anyway. + if (this.inputs.length === 0 && this.outputs.length !== 0) + throw new Error('Zero input witness tx.'); + + this.locktime = br.readU32(); + + if (block) { + this._offset = start; + this._block = true; + } + + if (!this.mutable && hasWitness) { + this._raw = br.endData(); + this._size = this._raw.length; + this._witness = witness; + } else { + br.end(); + } + + return this; + } + + /** + * Serialize transaction without witness. + * @private + * @returns {RawTX} + */ + + frameNormal() { + const raw = this.getNormalSizes(); + const bw = bio.write(raw.size); + this.writeNormal(bw); + raw.data = bw.render(); + return raw; + } + + /** + * Serialize transaction with witness. Calculates the witness + * size as it is framing (exposed on return value as `witness`). + * @private + * @returns {RawTX} + */ + + frameWitness() { + const raw = this.getWitnessSizes(); + const bw = bio.write(raw.size); + this.writeWitness(bw); + raw.data = bw.render(); + return raw; + } + + /** + * Serialize transaction without witness. + * @private + * @param {BufferWriter} bw + * @returns {RawTX} + */ + + writeNormal(bw) { + if (this.inputs.length === 0 && this.outputs.length !== 0) + throw new Error('Cannot serialize zero-input tx.'); + + bw.writeU32(this.version); + + bw.writeVarint(this.inputs.length); + + for (const input of this.inputs) + input.toWriter(bw); + + bw.writeVarint(this.outputs.length); + + for (const output of this.outputs) + output.toWriter(bw); + + bw.writeU32(this.locktime); + + return bw; + } + + /** + * Serialize transaction with witness. Calculates the witness + * size as it is framing (exposed on return value as `witness`). + * @private + * @param {BufferWriter} bw + * @returns {RawTX} + */ + + writeWitness(bw) { + if (this.inputs.length === 0 && this.outputs.length !== 0) + throw new Error('Cannot serialize zero-input tx.'); + + bw.writeU32(this.version); + bw.writeU8(0); + bw.writeU8(1); + + bw.writeVarint(this.inputs.length); + + for (const input of this.inputs) + input.toWriter(bw); + + bw.writeVarint(this.outputs.length); + + for (const output of this.outputs) + output.toWriter(bw); + + const start = bw.offset; + + for (const input of this.inputs) + input.witness.toWriter(bw); + + const witness = bw.offset - start; + + bw.writeU32(this.locktime); + + if (witness === this.inputs.length) + throw new Error('Cannot serialize empty-witness tx.'); + + return bw; + } + + /** + * Calculate the real size of the transaction + * without the witness vector. + * @returns {RawTX} + */ + + getNormalSizes() { + let base = 0; + + base += 4; + + base += encoding.sizeVarint(this.inputs.length); + + for (const input of this.inputs) + base += input.getSize(); + + base += encoding.sizeVarint(this.outputs.length); + + for (const output of this.outputs) + base += output.getSize(); + + base += 4; + + return new RawTX(base, 0); + } + + /** + * Calculate the real size of the transaction + * with the witness included. + * @returns {RawTX} + */ + + getWitnessSizes() { + let base = 0; + let witness = 0; + + base += 4; + witness += 2; + + base += encoding.sizeVarint(this.inputs.length); + + for (const input of this.inputs) { + base += input.getSize(); + witness += input.witness.getVarSize(); + } + + base += encoding.sizeVarint(this.outputs.length); + + for (const output of this.outputs) + base += output.getSize(); + + base += 4; + + return new RawTX(base + witness, witness); + } + + /** + * Test whether an object is a TX. + * @param {Object} obj + * @returns {Boolean} + */ + + static isTX(obj) { + return obj instanceof TX; + } +} + +/* + * Helpers + */ + +function hasWitnessBytes(br) { + if (br.left() < 6) + return false; + + return br.data[br.offset + 4] === 0 + && br.data[br.offset + 5] !== 0; +} + +class RawTX { + constructor(size, witness) { + this.data = null; + this.size = size; + this.witness = witness; + } +} + +/* + * Expose + */ + +module.exports = TX; diff --git a/scripts/txdb.js b/scripts/txdb.js new file mode 100644 index 0000000..2542db6 --- /dev/null +++ b/scripts/txdb.js @@ -0,0 +1,2746 @@ +/*! + * txdb.js - persistent transaction pool + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +const assert = require('bsert'); +const bio = require('bufio'); +const {BufferSet} = require('buffer-map'); +const util = require('../utils/util'); +const Amount = require('../btc/amount'); +const CoinView = require('../coins/coinview'); +const Coin = require('../primitives/coin'); +const Outpoint = require('../primitives/outpoint'); +const records = require('./records'); +const layout = require('./layout').txdb; +const consensus = require('../protocol/consensus'); +const policy = require('../protocol/policy'); +const {TXRecord} = records; +const {inspectSymbol} = require('../utils'); + +/** + * TXDB + * @alias module:wallet.TXDB + */ + +class TXDB { + /** + * Create a TXDB. + * @constructor + * @param {WalletDB} wdb + */ + + constructor(wdb, wid) { + this.wdb = wdb; + this.db = wdb.db; + this.logger = wdb.logger; + + this.wid = wid || 0; + this.bucket = null; + this.wallet = null; + this.locked = new BufferSet(); + } + + /** + * Open TXDB. + * @returns {Promise} + */ + + async open(wallet) { + const prefix = layout.prefix.encode(wallet.wid); + + this.wid = wallet.wid; + this.bucket = this.db.bucket(prefix); + this.wallet = wallet; + } + + /** + * Emit transaction event. + * @private + * @param {String} event + * @param {Object} data + * @param {Details} details + */ + + emit(event, data, details) { + this.wdb.emit(event, this.wallet, data, details); + this.wallet.emit(event, data, details); + } + + /** + * Get wallet path for output. + * @param {Output} output + * @returns {Promise} - Returns {@link Path}. + */ + + getPath(output) { + const hash = output.getHash(); + + if (!hash) + return null; + + return this.wdb.getPath(this.wid, hash); + } + + /** + * Test whether path exists for output. + * @param {Output} output + * @returns {Promise} - Returns Boolean. + */ + + hasPath(output) { + const hash = output.getHash(); + + if (!hash) + return false; + + return this.wdb.hasPath(this.wid, hash); + } + + /** + * Save credit. + * @param {Credit} credit + * @param {Path} path + */ + + async saveCredit(b, credit, path) { + const {coin} = credit; + + b.put(layout.c.encode(coin.hash, coin.index), credit.toRaw()); + b.put(layout.C.encode(path.account, coin.hash, coin.index), null); + + return this.addOutpointMap(b, coin.hash, coin.index); + } + + /** + * Remove credit. + * @param {Credit} credit + * @param {Path} path + */ + + async removeCredit(b, credit, path) { + const {coin} = credit; + + b.del(layout.c.encode(coin.hash, coin.index)); + b.del(layout.C.encode(path.account, coin.hash, coin.index)); + + return this.removeOutpointMap(b, coin.hash, coin.index); + } + + /** + * Spend credit. + * @param {Credit} credit + * @param {TX} tx + * @param {Number} index + */ + + spendCredit(b, credit, tx, index) { + const prevout = tx.inputs[index].prevout; + const spender = Outpoint.fromTX(tx, index); + b.put(layout.s.encode(prevout.hash, prevout.index), spender.toRaw()); + b.put(layout.d.encode(spender.hash, spender.index), credit.coin.toRaw()); + } + + /** + * Unspend credit. + * @param {TX} tx + * @param {Number} index + */ + + unspendCredit(b, tx, index) { + const prevout = tx.inputs[index].prevout; + const spender = Outpoint.fromTX(tx, index); + b.del(layout.s.encode(prevout.hash, prevout.index)); + b.del(layout.d.encode(spender.hash, spender.index)); + } + + /** + * Write input record. + * @param {TX} tx + * @param {Number} index + */ + + async writeInput(b, tx, index) { + const prevout = tx.inputs[index].prevout; + const spender = Outpoint.fromTX(tx, index); + b.put(layout.s.encode(prevout.hash, prevout.index), spender.toRaw()); + return this.addOutpointMap(b, prevout.hash, prevout.index); + } + + /** + * Remove input record. + * @param {TX} tx + * @param {Number} index + */ + + async removeInput(b, tx, index) { + const prevout = tx.inputs[index].prevout; + b.del(layout.s.encode(prevout.hash, prevout.index)); + return this.removeOutpointMap(b, prevout.hash, prevout.index); + } + + /** + * Update wallet balance. + * @param {BalanceDelta} state + */ + + async updateBalance(b, state) { + const balance = await this.getWalletBalance(); + state.applyTo(balance); + b.put(layout.R.encode(), balance.toRaw()); + return balance; + } + + /** + * Update account balance. + * @param {Number} acct + * @param {Balance} delta + */ + + async updateAccountBalance(b, acct, delta) { + const balance = await this.getAccountBalance(acct); + delta.applyTo(balance); + b.put(layout.r.encode(acct), balance.toRaw()); + return balance; + } + + /** + * Test a whether a coin has been spent. + * @param {Hash} hash + * @param {Number} index + * @returns {Promise} - Returns Boolean. + */ + + async getSpent(hash, index) { + const data = await this.bucket.get(layout.s.encode(hash, index)); + + if (!data) + return null; + + return Outpoint.fromRaw(data); + } + + /** + * Test a whether a coin has been spent. + * @param {Hash} hash + * @param {Number} index + * @returns {Promise} - Returns Boolean. + */ + + isSpent(hash, index) { + return this.bucket.has(layout.s.encode(hash, index)); + } + + /** + * Append to global map. + * @param {Number} height + * @returns {Promise} + */ + + addBlockMap(b, height) { + return this.wdb.addBlockMap(b.root(), height, this.wid); + } + + /** + * Remove from global map. + * @param {Number} height + * @returns {Promise} + */ + + removeBlockMap(b, height) { + return this.wdb.removeBlockMap(b.root(), height, this.wid); + } + + /** + * Append to global map. + * @param {Hash} hash + * @returns {Promise} + */ + + addTXMap(b, hash) { + return this.wdb.addTXMap(b.root(), hash, this.wid); + } + + /** + * Remove from global map. + * @param {Hash} hash + * @returns {Promise} + */ + + removeTXMap(b, hash) { + return this.wdb.removeTXMap(b.root(), hash, this.wid); + } + + /** + * Append to global map. + * @param {Hash} hash + * @param {Number} index + * @returns {Promise} + */ + + addOutpointMap(b, hash, index) { + return this.wdb.addOutpointMap(b.root(), hash, index, this.wid); + } + + /** + * Remove from global map. + * @param {Hash} hash + * @param {Number} index + * @returns {Promise} + */ + + removeOutpointMap(b, hash, index) { + return this.wdb.removeOutpointMap(b.root(), hash, index, this.wid); + } + + /** + * List block records. + * @returns {Promise} + */ + + getBlocks() { + return this.bucket.keys({ + gte: layout.b.min(), + lte: layout.b.max(), + parse: key => layout.b.decode(key)[0] + }); + } + + /** + * Get block record. + * @param {Number} height + * @returns {Promise} + */ + + async getBlock(height) { + const data = await this.bucket.get(layout.b.encode(height)); + + if (!data) + return null; + + return BlockRecord.fromRaw(data); + } + + /** + * Append to the global block record. + * @param {Hash} hash + * @param {BlockMeta} block + * @returns {Promise} + */ + + async addBlock(b, hash, block) { + const key = layout.b.encode(block.height); + const data = await this.bucket.get(key); + + if (!data) { + const blk = BlockRecord.fromMeta(block); + blk.add(hash); + b.put(key, blk.toRaw()); + return; + } + + const raw = Buffer.allocUnsafe(data.length + 32); + data.copy(raw, 0); + + const size = raw.readUInt32LE(40, true); + raw.writeUInt32LE(size + 1, 40, true); + hash.copy(raw, data.length); + + b.put(key, raw); + } + + /** + * Remove from the global block record. + * @param {Hash} hash + * @param {Number} height + * @returns {Promise} + */ + + async removeBlock(b, hash, height) { + const key = layout.b.encode(height); + const data = await this.bucket.get(key); + + if (!data) + return; + + const size = data.readUInt32LE(40, true); + + assert(size > 0); + assert(data.slice(-32).equals(hash)); + + if (size === 1) { + b.del(key); + return; + } + + const raw = data.slice(0, -32); + raw.writeUInt32LE(size - 1, 40, true); + + b.put(key, raw); + } + + /** + * Remove from the global block record. + * @param {Hash} hash + * @param {Number} height + * @returns {Promise} + */ + + async spliceBlock(b, hash, height) { + const block = await this.getBlock(height); + + if (!block) + return; + + if (!block.remove(hash)) + return; + + if (block.hashes.size === 0) { + b.del(layout.b.encode(height)); + return; + } + + b.put(layout.b.encode(height), block.toRaw()); + } + + /** + * Add transaction without a batch. + * @private + * @param {TX} tx + * @returns {Promise} + */ + + async add(tx, block) { + const hash = tx.hash(); + const existing = await this.getTX(hash); + + assert(!tx.mutable, 'Cannot add mutable TX to wallet.'); + + if (existing) { + // Existing tx is already confirmed. Ignore. + if (existing.height !== -1) + return null; + + // The incoming tx won't confirm the + // existing one anyway. Ignore. + if (!block) + return null; + + // Confirm transaction. + return this.confirm(existing, block); + } + + const wtx = TXRecord.fromTX(tx, block); + + if (!block) { + // Potentially remove double-spenders. + // Only remove if they're not confirmed. + if (!await this.removeConflicts(tx, true)) + return null; + } else { + // Potentially remove double-spenders. + await this.removeConflicts(tx, false); + } + + // Finally we can do a regular insertion. + return this.insert(wtx, block); + } + + /** + * Insert transaction. + * @private + * @param {TXRecord} wtx + * @param {BlockMeta} block + * @returns {Promise} + */ + + async insert(wtx, block) { + const b = this.bucket.batch(); + const {tx, hash} = wtx; + const height = block ? block.height : -1; + const details = new Details(wtx, block); + const state = new BalanceDelta(); + + let own = false; + + if (!tx.isCoinbase()) { + // We need to potentially spend some coins here. + for (let i = 0; i < tx.inputs.length; i++) { + const input = tx.inputs[i]; + const {hash, index} = input.prevout; + const credit = await this.getCredit(hash, index); + + if (!credit) { + // Watch all inputs for incoming txs. + // This allows us to check for double spends. + if (!block) + await this.writeInput(b, tx, i); + continue; + } + + const coin = credit.coin; + const path = await this.getPath(coin); + assert(path); + + // Build the tx details object + // as we go, for speed. + details.setInput(i, path, coin); + + // Write an undo coin for the credit + // and add it to the stxo set. + this.spendCredit(b, credit, tx, i); + + // Unconfirmed balance should always + // be updated as it reflects the on-chain + // balance _and_ mempool balance assuming + // everything in the mempool were to confirm. + state.tx(path, 1); + state.coin(path, -1); + state.unconfirmed(path, -coin.value); + + if (!block) { + // If the tx is not mined, we do not + // disconnect the coin, we simply mark + // a `spent` flag on the credit. This + // effectively prevents the mempool + // from altering our utxo state + // permanently. It also makes it + // possible to compare the on-chain + // state vs. the mempool state. + credit.spent = true; + await this.saveCredit(b, credit, path); + } else { + // If the tx is mined, we can safely + // remove the coin being spent. This + // coin will be indexed as an undo + // coin so it can be reconnected + // later during a reorg. + state.confirmed(path, -coin.value); + await this.removeCredit(b, credit, path); + } + + own = true; + } + } + + // Potentially add coins to the utxo set. + for (let i = 0; i < tx.outputs.length; i++) { + const output = tx.outputs[i]; + const path = await this.getPath(output); + + if (!path) + continue; + + details.setOutput(i, path); + + const credit = Credit.fromTX(tx, i, height); + credit.own = own; + + state.tx(path, 1); + state.coin(path, 1); + state.unconfirmed(path, output.value); + + if (block) + state.confirmed(path, output.value); + + await this.saveCredit(b, credit, path); + } + + // Save and index the transaction record. + b.put(layout.t.encode(hash), wtx.toRaw()); + b.put(layout.m.encode(wtx.mtime, hash), null); + + if (!block) + b.put(layout.p.encode(hash), null); + else + b.put(layout.h.encode(height, hash), null); + + // Do some secondary indexing for account-based + // queries. This saves us a lot of time for + // queries later. + for (const [acct, delta] of state.accounts) { + await this.updateAccountBalance(b, acct, delta); + + b.put(layout.T.encode(acct, hash), null); + b.put(layout.M.encode(acct, wtx.mtime, hash), null); + + if (!block) + b.put(layout.P.encode(acct, hash), null); + else + b.put(layout.H.encode(acct, height, hash), null); + } + + // Update block records. + if (block) { + await this.addBlockMap(b, height); + await this.addBlock(b, tx.hash(), block); + } else { + await this.addTXMap(b, hash); + } + + // Commit the new state. + let balance; + if (state.updated()) + balance = await this.updateBalance(b, state); + + await b.write(); + + // This transaction may unlock some + // coins now that we've seen it. + this.unlockTX(tx); + + // Emit events for potential local and + // websocket listeners. Note that these + // will only be emitted if the batch is + // successfully written to disk. + this.emit('tx', tx, details); + if (state.updated()) + this.emit('balance', balance); + + return details; + } + + /** + * Attempt to confirm a transaction. + * @private + * @param {TXRecord} wtx + * @param {BlockMeta} block + * @returns {Promise} + */ + + async confirm(wtx, block) { + const b = this.bucket.batch(); + const {tx, hash} = wtx; + const height = block.height; + const details = new Details(wtx, block); + const state = new BalanceDelta(); + let own = false; + + wtx.setBlock(block); + + if (!tx.isCoinbase()) { + const credits = await this.getSpentCredits(tx); + + // Potentially spend coins. Now that the tx + // is mined, we can actually _remove_ coins + // from the utxo state. + for (let i = 0; i < tx.inputs.length; i++) { + const input = tx.inputs[i]; + const {hash, index} = input.prevout; + + let resolved = false; + + // There may be new credits available + // that we haven't seen yet. + if (!credits[i]) { + await this.removeInput(b, tx, i); + + const credit = await this.getCredit(hash, index); + + if (!credit) + continue; + + // Add a spend record and undo coin + // for the coin we now know is ours. + // We don't need to remove the coin + // since it was never added in the + // first place. + this.spendCredit(b, credit, tx, i); + + credits[i] = credit; + resolved = true; + } + + const credit = credits[i]; + const coin = credit.coin; + + assert(coin.height !== -1); + + const path = await this.getPath(coin); + assert(path); + own = true; + + details.setInput(i, path, coin); + + if (resolved) { + state.coin(path, -1); + state.unconfirmed(path, -coin.value); + } + + // We can now safely remove the credit + // entirely, now that we know it's also + // been removed on-chain. + state.confirmed(path, -coin.value); + + await this.removeCredit(b, credit, path); + } + } + + // Update credit heights, including undo coins. + for (let i = 0; i < tx.outputs.length; i++) { + const output = tx.outputs[i]; + const path = await this.getPath(output); + + if (!path) + continue; + + details.setOutput(i, path); + + let credit = await this.getCredit(hash, i); + + if (!credit) { + // This credit didn't belong to us the first time we + // saw the transaction (before confirmation or rescan). + // Create new credit for database. + credit = Credit.fromTX(tx, i, height); + + // If this tx spent any of our own coins, we "own" this output, + // meaning if it becomes unconfirmed, we can still confidently spend it. + credit.own = own; + + // Add coin to "unconfirmed" balance (which includes confirmed coins) + state.coin(path, 1); + state.unconfirmed(path, credit.coin.value); + } + + // Credits spent in the mempool add an + // undo coin for ease. If this credit is + // spent in the mempool, we need to + // update the undo coin's height. + if (credit.spent) + await this.updateSpentCoin(b, tx, i, height); + + // Update coin height and confirmed + // balance. Save once again. + state.confirmed(path, output.value); + credit.coin.height = height; + + await this.saveCredit(b, credit, path); + } + + // Save the new serialized transaction as + // the block-related properties have been + // updated. Also reindex for height. + b.put(layout.t.encode(hash), wtx.toRaw()); + b.del(layout.p.encode(hash)); + b.put(layout.h.encode(height, hash), null); + + // Secondary indexing also needs to change. + for (const [acct, delta] of state.accounts) { + await this.updateAccountBalance(b, acct, delta); + b.del(layout.P.encode(acct, hash)); + b.put(layout.H.encode(acct, height, hash), null); + } + + await this.removeTXMap(b, hash); + await this.addBlockMap(b, height); + await this.addBlock(b, tx.hash(), block); + + // Commit the new state. The balance has updated. + const balance = await this.updateBalance(b, state); + + await b.write(); + + this.unlockTX(tx); + + this.emit('confirmed', tx, details); + this.emit('balance', balance); + + return details; + } + + /** + * Recursively remove a transaction + * from the database. + * @param {Hash} hash + * @returns {Promise} + */ + + async remove(hash) { + const wtx = await this.getTX(hash); + + if (!wtx) + return null; + + return this.removeRecursive(wtx); + } + + /** + * Remove a transaction from the + * database. Disconnect inputs. + * @private + * @param {TXRecord} wtx + * @returns {Promise} + */ + + async erase(wtx, block) { + const b = this.bucket.batch(); + const {tx, hash} = wtx; + const height = block ? block.height : -1; + const details = new Details(wtx, block); + const state = new BalanceDelta(); + + if (!tx.isCoinbase()) { + // We need to undo every part of the + // state this transaction ever touched. + // Start by getting the undo coins. + const credits = await this.getSpentCredits(tx); + + for (let i = 0; i < tx.inputs.length; i++) { + const credit = credits[i]; + + if (!credit) { + if (!block) + await this.removeInput(b, tx, i); + continue; + } + + const coin = credit.coin; + const path = await this.getPath(coin); + assert(path); + + details.setInput(i, path, coin); + + // Recalculate the balance, remove + // from stxo set, remove the undo + // coin, and resave the credit. + state.tx(path, -1); + state.coin(path, 1); + state.unconfirmed(path, coin.value); + + if (block) + state.confirmed(path, coin.value); + + this.unspendCredit(b, tx, i); + + credit.spent = false; + await this.saveCredit(b, credit, path); + } + } + + // We need to remove all credits + // this transaction created. + for (let i = 0; i < tx.outputs.length; i++) { + const output = tx.outputs[i]; + const path = await this.getPath(output); + + if (!path) + continue; + + details.setOutput(i, path); + + const credit = Credit.fromTX(tx, i, height); + + state.tx(path, -1); + state.coin(path, -1); + state.unconfirmed(path, -output.value); + + if (block) + state.confirmed(path, -output.value); + + await this.removeCredit(b, credit, path); + } + + // Remove the transaction data + // itself as well as unindex. + b.del(layout.t.encode(hash)); + b.del(layout.m.encode(wtx.mtime, hash)); + + if (!block) + b.del(layout.p.encode(hash)); + else + b.del(layout.h.encode(height, hash)); + + // Remove all secondary indexing. + for (const [acct, delta] of state.accounts) { + await this.updateAccountBalance(b, acct, delta); + + b.del(layout.T.encode(acct, hash)); + b.del(layout.M.encode(acct, wtx.mtime, hash)); + + if (!block) + b.del(layout.P.encode(acct, hash)); + else + b.del(layout.H.encode(acct, height, hash)); + } + + // Update block records. + if (block) { + await this.removeBlockMap(b, height); + await this.spliceBlock(b, hash, height); + } else { + await this.removeTXMap(b, hash); + } + + // Update the transaction counter + // and commit new state due to + // balance change. + const balance = await this.updateBalance(b, state); + + await b.write(); + + this.emit('remove tx', tx, details); + this.emit('balance', balance); + + return details; + } + + /** + * Remove a transaction and recursively + * remove all of its spenders. + * @private + * @param {TXRecord} wtx + * @returns {Promise} + */ + + async removeRecursive(wtx) { + const {tx, hash} = wtx; + + if (!await this.hasTX(hash)) + return null; + + for (let i = 0; i < tx.outputs.length; i++) { + const spent = await this.getSpent(hash, i); + + if (!spent) + continue; + + // Remove all of the spender's spenders first. + const stx = await this.getTX(spent.hash); + + assert(stx); + + await this.removeRecursive(stx); + } + + // Remove the spender. + return this.erase(wtx, wtx.getBlock()); + } + + /** + * Revert a block. + * @param {Number} height + * @returns {Promise} + */ + + async revert(height) { + const block = await this.getBlock(height); + + if (!block) + return 0; + + this.logger.debug('Rescan: reverting block %d', height); + const hashes = block.toArray(); + + for (let i = hashes.length - 1; i >= 0; i--) { + const hash = hashes[i]; + await this.unconfirm(hash); + } + + return hashes.length; + } + + /** + * Unconfirm a transaction without a batch. + * @private + * @param {Hash} hash + * @returns {Promise} + */ + + async unconfirm(hash) { + const wtx = await this.getTX(hash); + + if (!wtx) + return null; + + if (wtx.height === -1) + return null; + + return this.disconnect(wtx, wtx.getBlock()); + } + + /** + * Unconfirm a transaction. Necessary after a reorg. + * @param {TXRecord} wtx + * @returns {Promise} + */ + + async disconnect(wtx, block) { + const b = this.bucket.batch(); + const {tx, hash, height} = wtx; + const details = new Details(wtx, block); + const state = new BalanceDelta(); + + assert(block); + + wtx.unsetBlock(); + + if (!tx.isCoinbase()) { + // We need to reconnect the coins. Start + // by getting all of the undo coins we know + // about. + const credits = await this.getSpentCredits(tx); + + for (let i = 0; i < tx.inputs.length; i++) { + const credit = credits[i]; + + if (!credit) { + await this.writeInput(b, tx, i); + continue; + } + + const coin = credit.coin; + + assert(coin.height !== -1); + + const path = await this.getPath(coin); + assert(path); + + details.setInput(i, path, coin); + + state.confirmed(path, coin.value); + + // Resave the credit and mark it + // as spent in the mempool instead. + credit.spent = true; + await this.saveCredit(b, credit, path); + } + } + + // We need to remove heights on + // the credits and undo coins. + for (let i = 0; i < tx.outputs.length; i++) { + const output = tx.outputs[i]; + const path = await this.getPath(output); + + if (!path) + continue; + + const credit = await this.getCredit(hash, i); + + // Potentially update undo coin height. + if (!credit) { + await this.updateSpentCoin(b, tx, i, height); + continue; + } + + if (credit.spent) + await this.updateSpentCoin(b, tx, i, height); + + details.setOutput(i, path); + + // Update coin height and confirmed + // balance. Save once again. + credit.coin.height = -1; + + state.confirmed(path, -output.value); + + await this.saveCredit(b, credit, path); + } + + await this.addTXMap(b, hash); + await this.removeBlockMap(b, height); + await this.removeBlock(b, tx.hash(), height); + + // We need to update the now-removed + // block properties and reindex due + // to the height change. + b.put(layout.t.encode(hash), wtx.toRaw()); + b.put(layout.p.encode(hash), null); + b.del(layout.h.encode(height, hash)); + + // Secondary indexing also needs to change. + for (const [acct, delta] of state.accounts) { + await this.updateAccountBalance(b, acct, delta); + b.put(layout.P.encode(acct, hash), null); + b.del(layout.H.encode(acct, height, hash)); + } + + // Commit state due to unconfirmed + // vs. confirmed balance change. + const balance = await this.updateBalance(b, state); + + await b.write(); + + this.emit('unconfirmed', tx, details); + this.emit('balance', balance); + + return details; + } + + /** + * Remove spenders that have not been confirmed. We do this in the + * odd case of stuck transactions or when a coin is double-spent + * by a newer transaction. All previously-spending transactions + * of that coin that are _not_ confirmed will be removed from + * the database. + * @private + * @param {Hash} hash + * @param {TX} ref - Reference tx, the tx that double-spent. + * @returns {Promise} - Returns Boolean. + */ + + async removeConflict(wtx) { + const tx = wtx.tx; + + this.logger.warning('Handling conflicting tx: %h.', tx.hash()); + + const details = await this.removeRecursive(wtx); + + if (!details) + return null; + + this.logger.warning('Removed conflict: %h.', tx.hash()); + + // Emit the _removed_ transaction. + this.emit('conflict', tx, details); + + return details; + } + + /** + * Retrieve coins for own inputs, remove + * double spenders, and verify inputs. + * @private + * @param {TX} tx + * @returns {Promise} + */ + + async removeConflicts(tx, conf) { + if (tx.isCoinbase()) + return true; + + const txid = tx.hash(); + const spends = []; + + // Gather all spent records first. + for (const {prevout} of tx.inputs) { + const {hash, index} = prevout; + + // Is it already spent? + const spent = await this.getSpent(hash, index); + + if (!spent) + continue; + + // Did _we_ spend it? + if (spent.hash.equals(txid)) + continue; + + const spender = await this.getTX(spent.hash); + assert(spender); + + if (conf && spender.height !== -1) + return false; + + spends.push(spender); + } + + // Once we know we're not going to + // screw things up, remove the double + // spenders. + for (const spender of spends) { + // Remove the double spender. + await this.removeConflict(spender); + } + + return true; + } + + /** + * Lock all coins in a transaction. + * @param {TX} tx + */ + + lockTX(tx) { + if (tx.isCoinbase()) + return; + + for (const input of tx.inputs) + this.lockCoin(input.prevout); + } + + /** + * Unlock all coins in a transaction. + * @param {TX} tx + */ + + unlockTX(tx) { + if (tx.isCoinbase()) + return; + + for (const input of tx.inputs) + this.unlockCoin(input.prevout); + } + + /** + * Lock a single coin. + * @param {Coin|Outpoint} coin + */ + + lockCoin(coin) { + const key = coin.toKey(); + this.locked.add(key); + } + + /** + * Unlock a single coin. + * @param {Coin|Outpoint} coin + */ + + unlockCoin(coin) { + const key = coin.toKey(); + return this.locked.delete(key); + } + + /** + * Unlock all coins. + */ + + unlockCoins() { + for (const coin of this.getLocked()) + this.unlockCoin(coin); + } + + /** + * Test locked status of a single coin. + * @param {Coin|Outpoint} coin + */ + + isLocked(coin) { + const key = coin.toKey(); + return this.locked.has(key); + } + + /** + * Filter array of coins or outpoints + * for only unlocked ones. + * @param {Coin[]|Outpoint[]} + * @returns {Array} + */ + + filterLocked(coins) { + const out = []; + + for (const coin of coins) { + if (!this.isLocked(coin)) + out.push(coin); + } + + return out; + } + + /** + * Return an array of all locked outpoints. + * @returns {Outpoint[]} + */ + + getLocked() { + const outpoints = []; + + for (const key of this.locked.keys()) + outpoints.push(Outpoint.fromKey(key)); + + return outpoints; + } + + /** + * Get hashes of all transactions in the database. + * @param {Number} acct + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getAccountHistoryHashes(acct) { + assert(typeof acct === 'number'); + return this.bucket.keys({ + gte: layout.T.min(acct), + lte: layout.T.max(acct), + parse: (key) => { + const [, hash] = layout.T.decode(key); + return hash; + } + }); + } + + /** + * Get hashes of all transactions in the database. + * @param {Number} acct + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getHistoryHashes(acct) { + assert(typeof acct === 'number'); + + if (acct !== -1) + return this.getAccountHistoryHashes(acct); + + return this.bucket.keys({ + gte: layout.t.min(), + lte: layout.t.max(), + parse: key => layout.t.decode(key)[0] + }); + } + + /** + * Get hashes of all unconfirmed transactions in the database. + * @param {Number} acct + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getAccountPendingHashes(acct) { + assert(typeof acct === 'number'); + return this.bucket.keys({ + gte: layout.P.min(acct), + lte: layout.P.max(acct), + parse: (key) => { + const [, hash] = layout.P.decode(key); + return hash; + } + }); + } + + /** + * Get hashes of all unconfirmed transactions in the database. + * @param {Number} acct + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getPendingHashes(acct) { + assert(typeof acct === 'number'); + + if (acct !== -1) + return this.getAccountPendingHashes(acct); + + return this.bucket.keys({ + gte: layout.p.min(), + lte: layout.p.max(), + parse: key => layout.p.decode(key)[0] + }); + } + + /** + * Test whether the database has a pending transaction. + * @param {Hash} hash + * @returns {Promise} - Returns Boolean. + */ + + async hasPending(hash) { + return this.bucket.has(layout.p.encode(hash)); + } + + /** + * Get all coin hashes in the database. + * @param {Number} acct + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getAccountOutpoints(acct) { + assert(typeof acct === 'number'); + return this.bucket.keys({ + gte: layout.C.min(acct), + lte: layout.C.max(acct), + parse: (key) => { + const [, hash, index] = layout.C.decode(key); + return new Outpoint(hash, index); + } + }); + } + + /** + * Get all coin hashes in the database. + * @param {Number} acct + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getOutpoints(acct) { + assert(typeof acct === 'number'); + + if (acct !== -1) + return this.getAccountOutpoints(acct); + + return this.bucket.keys({ + gte: layout.c.min(), + lte: layout.c.max(), + parse: (key) => { + const [hash, index] = layout.c.decode(key); + return new Outpoint(hash, index); + } + }); + } + + /** + * Get TX hashes by height range. + * @param {Number} acct + * @param {Object} options + * @param {Number} options.start - Start height. + * @param {Number} options.end - End height. + * @param {Number?} options.limit - Max number of records. + * @param {Boolean?} options.reverse - Reverse order. + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getAccountHeightRangeHashes(acct, options) { + assert(typeof acct === 'number'); + + const start = options.start || 0; + const end = options.end || 0xffffffff; + + return this.bucket.keys({ + gte: layout.H.min(acct, start), + lte: layout.H.max(acct, end), + limit: options.limit, + reverse: options.reverse, + parse: (key) => { + const [,, hash] = layout.H.decode(key); + return hash; + } + }); + } + + /** + * Get TX hashes by height range. + * @param {Number} acct + * @param {Object} options + * @param {Number} options.start - Start height. + * @param {Number} options.end - End height. + * @param {Number?} options.limit - Max number of records. + * @param {Boolean?} options.reverse - Reverse order. + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getHeightRangeHashes(acct, options) { + assert(typeof acct === 'number'); + + if (acct !== -1) + return this.getAccountHeightRangeHashes(acct, options); + + const start = options.start || 0; + const end = options.end || 0xffffffff; + + return this.bucket.keys({ + gte: layout.h.min(start), + lte: layout.h.max(end), + limit: options.limit, + reverse: options.reverse, + parse: (key) => { + const [, hash] = layout.h.decode(key); + return hash; + } + }); + } + + /** + * Get TX hashes by height. + * @param {Number} height + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getHeightHashes(height) { + return this.getHeightRangeHashes({ start: height, end: height }); + } + + /** + * Get TX hashes by timestamp range. + * @param {Number} acct + * @param {Object} options + * @param {Number} options.start - Start height. + * @param {Number} options.end - End height. + * @param {Number?} options.limit - Max number of records. + * @param {Boolean?} options.reverse - Reverse order. + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getAccountRangeHashes(acct, options) { + assert(typeof acct === 'number'); + + const start = options.start || 0; + const end = options.end || 0xffffffff; + + return this.bucket.keys({ + gte: layout.M.min(acct, start), + lte: layout.M.max(acct, end), + limit: options.limit, + reverse: options.reverse, + parse: (key) => { + const [,, hash] = layout.M.decode(key); + return hash; + } + }); + } + + /** + * Get TX hashes by timestamp range. + * @param {Number} acct + * @param {Object} options + * @param {Number} options.start - Start height. + * @param {Number} options.end - End height. + * @param {Number?} options.limit - Max number of records. + * @param {Boolean?} options.reverse - Reverse order. + * @returns {Promise} - Returns {@link Hash}[]. + */ + + getRangeHashes(acct, options) { + assert(typeof acct === 'number'); + + if (acct !== -1) + return this.getAccountRangeHashes(acct, options); + + const start = options.start || 0; + const end = options.end || 0xffffffff; + + return this.bucket.keys({ + gte: layout.m.min(start), + lte: layout.m.max(end), + limit: options.limit, + reverse: options.reverse, + parse: (key) => { + const [, hash] = layout.m.decode(key); + return hash; + } + }); + } + + /** + * Get transactions by timestamp range. + * @param {Number} acct + * @param {Object} options + * @param {Number} options.start - Start time. + * @param {Number} options.end - End time. + * @param {Number?} options.limit - Max number of records. + * @param {Boolean?} options.reverse - Reverse order. + * @returns {Promise} - Returns {@link TX}[]. + */ + + async getRange(acct, options) { + const hashes = await this.getRangeHashes(acct, options); + const txs = []; + + for (const hash of hashes) { + const tx = await this.getTX(hash); + assert(tx); + txs.push(tx); + } + + return txs; + } + + /** + * Get last N transactions. + * @param {Number} acct + * @param {Number} limit - Max number of transactions. + * @returns {Promise} - Returns {@link TX}[]. + */ + + getLast(acct, limit) { + return this.getRange(acct, { + start: 0, + end: 0xffffffff, + reverse: true, + limit: limit || 10 + }); + } + + /** + * Get all transactions. + * @param {Number} acct + * @returns {Promise} - Returns {@link TX}[]. + */ + + getHistory(acct) { + assert(typeof acct === 'number'); + + // Slow case + if (acct !== -1) + return this.getAccountHistory(acct); + + // Fast case + return this.bucket.values({ + gte: layout.t.min(), + lte: layout.t.max(), + parse: data => TXRecord.fromRaw(data) + }); + } + + /** + * Get all acct transactions. + * @param {Number} acct + * @returns {Promise} - Returns {@link TX}[]. + */ + + async getAccountHistory(acct) { + const hashes = await this.getHistoryHashes(acct); + const txs = []; + + for (const hash of hashes) { + const tx = await this.getTX(hash); + assert(tx); + txs.push(tx); + } + + return txs; + } + + /** + * Get unconfirmed transactions. + * @param {Number} acct + * @returns {Promise} - Returns {@link TX}[]. + */ + + async getPending(acct) { + const hashes = await this.getPendingHashes(acct); + const txs = []; + + for (const hash of hashes) { + const tx = await this.getTX(hash); + assert(tx); + txs.push(tx); + } + + return txs; + } + + /** + * Get coins. + * @param {Number} acct + * @returns {Promise} - Returns {@link Coin}[]. + */ + + getCredits(acct) { + assert(typeof acct === 'number'); + + // Slow case + if (acct !== -1) + return this.getAccountCredits(acct); + + // Fast case + return this.bucket.range({ + gte: layout.c.min(), + lte: layout.c.max(), + parse: (key, value) => { + const [hash, index] = layout.c.decode(key); + const credit = Credit.fromRaw(value); + credit.coin.hash = hash; + credit.coin.index = index; + return credit; + } + }); + } + + /** + * Get coins by account. + * @param {Number} acct + * @returns {Promise} - Returns {@link Coin}[]. + */ + + async getAccountCredits(acct) { + const outpoints = await this.getOutpoints(acct); + const credits = []; + + for (const {hash, index} of outpoints) { + const credit = await this.getCredit(hash, index); + if (!credit) + continue; + credits.push(credit); + } + + return credits; + } + + /** + * Fill a transaction with coins (all historical coins). + * @param {TX} tx + * @returns {Promise} - Returns {@link TX}. + */ + + async getSpentCredits(tx) { + if (tx.isCoinbase()) + return []; + + const hash = tx.hash(); + const credits = []; + + for (let i = 0; i < tx.inputs.length; i++) + credits.push(null); + + await this.bucket.range({ + gte: layout.d.min(hash), + lte: layout.d.max(hash), + parse: (key, value) => { + const [, index] = layout.d.decode(key); + const coin = Coin.fromRaw(value); + const input = tx.inputs[index]; + assert(input); + coin.hash = input.prevout.hash; + coin.index = input.prevout.index; + credits[index] = new Credit(coin); + } + }); + + return credits; + } + + /** + * Get coins. + * @param {Number} acct + * @returns {Promise} - Returns {@link Coin}[]. + */ + + async getCoins(acct) { + const credits = await this.getCredits(acct); + const coins = []; + + for (const credit of credits) { + if (credit.spent) + continue; + + coins.push(credit.coin); + } + + return coins; + } + + /** + * Get coins by account. + * @param {Number} acct + * @returns {Promise} - Returns {@link Coin}[]. + */ + + async getAccountCoins(acct) { + const credits = await this.getAccountCredits(acct); + const coins = []; + + for (const credit of credits) { + if (credit.spent) + continue; + + coins.push(credit.coin); + } + + return coins; + } + + /** + * Get historical coins for a transaction. + * @param {TX} tx + * @returns {Promise} - Returns {@link TX}. + */ + + async getSpentCoins(tx) { + if (tx.isCoinbase()) + return []; + + const credits = await this.getSpentCredits(tx); + const coins = []; + + for (const credit of credits) { + if (!credit) { + coins.push(null); + continue; + } + + coins.push(credit.coin); + } + + return coins; + } + + /** + * Get a coin viewpoint. + * @param {TX} tx + * @returns {Promise} - Returns {@link CoinView}. + */ + + async getCoinView(tx) { + const view = new CoinView(); + + if (tx.isCoinbase()) + return view; + + for (const {prevout} of tx.inputs) { + const {hash, index} = prevout; + const coin = await this.getCoin(hash, index); + + if (!coin) + continue; + + view.addCoin(coin); + } + + return view; + } + + /** + * Get historical coin viewpoint. + * @param {TX} tx + * @returns {Promise} - Returns {@link CoinView}. + */ + + async getSpentView(tx) { + const view = new CoinView(); + + if (tx.isCoinbase()) + return view; + + const coins = await this.getSpentCoins(tx); + + for (const coin of coins) { + if (!coin) + continue; + + view.addCoin(coin); + } + + return view; + } + + /** + * Get transaction. + * @param {Hash} hash + * @returns {Promise} - Returns {@link TX}. + */ + + async getTX(hash) { + const raw = await this.bucket.get(layout.t.encode(hash)); + + if (!raw) + return null; + + return TXRecord.fromRaw(raw); + } + + /** + * Get transaction details. + * @param {Hash} hash + * @returns {Promise} - Returns {@link TXDetails}. + */ + + async getDetails(hash) { + const wtx = await this.getTX(hash); + + if (!wtx) + return null; + + return this.toDetails(wtx); + } + + /** + * Convert transaction to transaction details. + * @param {TXRecord[]} wtxs + * @returns {Promise} + */ + + async toDetails(wtxs) { + const out = []; + + if (!Array.isArray(wtxs)) + return this._toDetails(wtxs); + + for (const wtx of wtxs) { + const details = await this._toDetails(wtx); + + if (!details) + continue; + + out.push(details); + } + + return out; + } + + /** + * Convert transaction to transaction details. + * @private + * @param {TXRecord} wtx + * @returns {Promise} + */ + + async _toDetails(wtx) { + const tx = wtx.tx; + const block = wtx.getBlock(); + const details = new Details(wtx, block); + const coins = await this.getSpentCoins(tx); + + for (let i = 0; i < tx.inputs.length; i++) { + const coin = coins[i]; + + let path = null; + + if (coin) + path = await this.getPath(coin); + + details.setInput(i, path, coin); + } + + for (let i = 0; i < tx.outputs.length; i++) { + const output = tx.outputs[i]; + const path = await this.getPath(output); + details.setOutput(i, path); + } + + return details; + } + + /** + * Test whether the database has a transaction. + * @param {Hash} hash + * @returns {Promise} - Returns Boolean. + */ + + hasTX(hash) { + return this.bucket.has(layout.t.encode(hash)); + } + + /** + * Get coin. + * @param {Hash} hash + * @param {Number} index + * @returns {Promise} - Returns {@link Coin}. + */ + + async getCoin(hash, index) { + const credit = await this.getCredit(hash, index); + + if (!credit) + return null; + + return credit.coin; + } + + /** + * Get coin. + * @param {Hash} hash + * @param {Number} index + * @returns {Promise} - Returns {@link Coin}. + */ + + async getCredit(hash, index) { + const data = await this.bucket.get(layout.c.encode(hash, index)); + + if (!data) + return null; + + const credit = Credit.fromRaw(data); + credit.coin.hash = hash; + credit.coin.index = index; + + return credit; + } + + /** + * Get spender coin. + * @param {Outpoint} spent + * @param {Outpoint} prevout + * @returns {Promise} - Returns {@link Coin}. + */ + + async getSpentCoin(spent, prevout) { + const data = await this.bucket.get(layout.d.encode( + spent.hash, + spent.index + )); + + if (!data) + return null; + + const coin = Coin.fromRaw(data); + coin.hash = prevout.hash; + coin.index = prevout.index; + + return coin; + } + + /** + * Test whether the database has a spent coin. + * @param {Outpoint} spent + * @returns {Promise} - Returns {@link Coin}. + */ + + hasSpentCoin(spent) { + return this.bucket.has(layout.d.encode(spent.hash, spent.index)); + } + + /** + * Update spent coin height in storage. + * @param {TX} tx - Sending transaction. + * @param {Number} index + * @param {Number} height + * @returns {Promise} + */ + + async updateSpentCoin(b, tx, index, height) { + const prevout = Outpoint.fromTX(tx, index); + const spent = await this.getSpent(prevout.hash, prevout.index); + + if (!spent) + return; + + const coin = await this.getSpentCoin(spent, prevout); + + if (!coin) + return; + + coin.height = height; + + b.put(layout.d.encode(spent.hash, spent.index), coin.toRaw()); + } + + /** + * Test whether the database has a transaction. + * @param {Hash} hash + * @returns {Promise} - Returns Boolean. + */ + + async hasCoin(hash, index) { + return this.bucket.has(layout.c.encode(hash, index)); + } + + /** + * Calculate balance. + * @param {Number?} account + * @returns {Promise} - Returns {@link Balance}. + */ + + async getBalance(acct) { + assert(typeof acct === 'number'); + + if (acct !== -1) + return this.getAccountBalance(acct); + + return this.getWalletBalance(); + } + + /** + * Calculate balance. + * @returns {Promise} - Returns {@link Balance}. + */ + + async getWalletBalance() { + const data = await this.bucket.get(layout.R.encode()); + + if (!data) + return new Balance(); + + return Balance.fromRaw(-1, data); + } + + /** + * Calculate balance by account. + * @param {Number} acct + * @returns {Promise} - Returns {@link Balance}. + */ + + async getAccountBalance(acct) { + const data = await this.bucket.get(layout.r.encode(acct)); + + if (!data) + return new Balance(acct); + + return Balance.fromRaw(acct, data); + } + + /** + * Zap pending transactions older than `age`. + * @param {Number} acct + * @param {Number} age - Age delta. + * @returns {Promise} + */ + + async zap(acct, age) { + assert((age >>> 0) === age); + + const now = util.now(); + + const txs = await this.getRange(acct, { + start: 0, + end: now - age + }); + + const hashes = []; + + for (const wtx of txs) { + if (wtx.height !== -1) + continue; + + assert(now - wtx.mtime >= age); + + this.logger.debug('Zapping TX: %h (%d)', + wtx.tx.hash(), this.wid); + + await this.remove(wtx.hash); + + hashes.push(wtx.hash); + } + + return hashes; + } + + /** + * Abandon transaction. + * @param {Hash} hash + * @returns {Promise} + */ + + async abandon(hash) { + const result = await this.bucket.has(layout.p.encode(hash)); + + if (!result) + throw new Error('TX not eligible.'); + + return this.remove(hash); + } +} + +/** + * Balance + * @alias module:wallet.Balance + */ + +class Balance { + /** + * Create a balance. + * @constructor + * @param {Number} account + */ + + constructor(acct = -1) { + assert(typeof acct === 'number'); + + this.account = acct; + this.tx = 0; + this.coin = 0; + this.unconfirmed = 0; + this.confirmed = 0; + } + + /** + * Apply delta. + * @param {Balance} balance + */ + + applyTo(balance) { + balance.tx += this.tx; + balance.coin += this.coin; + balance.unconfirmed += this.unconfirmed; + balance.confirmed += this.confirmed; + + assert(balance.tx >= 0); + assert(balance.coin >= 0); + assert(balance.unconfirmed >= 0); + assert(balance.confirmed >= 0); + } + + /** + * Serialize balance. + * @returns {Buffer} + */ + + toRaw() { + const bw = bio.write(32); + + bw.writeU64(this.tx); + bw.writeU64(this.coin); + bw.writeU64(this.unconfirmed); + bw.writeU64(this.confirmed); + + return bw.render(); + } + + /** + * Inject properties from serialized data. + * @private + * @param {Buffer} data + * @returns {TXDBState} + */ + + fromRaw(data) { + const br = bio.read(data); + this.tx = br.readU64(); + this.coin = br.readU64(); + this.unconfirmed = br.readU64(); + this.confirmed = br.readU64(); + return this; + } + + /** + * Instantiate balance from serialized data. + * @param {Number} acct + * @param {Buffer} data + * @returns {TXDBState} + */ + + static fromRaw(acct, data) { + return new this(acct).fromRaw(data); + } + + /** + * Convert balance to a more json-friendly object. + * @param {Boolean?} minimal + * @returns {Object} + */ + + toJSON(minimal) { + return { + account: !minimal ? this.account : undefined, + tx: this.tx, + coin: this.coin, + unconfirmed: this.unconfirmed, + confirmed: this.confirmed + }; + } + + /** + * Inspect balance. + * @param {String} + */ + + [inspectSymbol]() { + return ''; + } +} + +/** + * Balance Delta + * @ignore + */ + +class BalanceDelta { + /** + * Create a balance delta. + * @constructor + */ + + constructor() { + this.wallet = new Balance(); + this.accounts = new Map(); + } + + updated() { + return this.wallet.tx !== 0; + } + + applyTo(balance) { + this.wallet.applyTo(balance); + } + + get(path) { + if (!this.accounts.has(path.account)) + this.accounts.set(path.account, new Balance()); + + return this.accounts.get(path.account); + } + + tx(path, value) { + const account = this.get(path); + account.tx = value; + this.wallet.tx = value; + } + + coin(path, value) { + const account = this.get(path); + account.coin += value; + this.wallet.coin += value; + } + + unconfirmed(path, value) { + const account = this.get(path); + account.unconfirmed += value; + this.wallet.unconfirmed += value; + } + + confirmed(path, value) { + const account = this.get(path); + account.confirmed += value; + this.wallet.confirmed += value; + } +} + +/** + * Credit (wrapped coin) + * @alias module:wallet.Credit + * @property {Coin} coin + * @property {Boolean} spent + */ + +class Credit { + /** + * Create a credit. + * @constructor + * @param {Coin} coin + * @param {Boolean?} spent + */ + + constructor(coin, spent) { + this.coin = coin || new Coin(); + this.spent = spent || false; + this.own = false; + } + + /** + * Inject properties from serialized data. + * @private + * @param {Buffer} data + */ + + fromRaw(data) { + const br = bio.read(data); + this.coin.fromReader(br); + this.spent = br.readU8() === 1; + this.own = br.readU8() === 1; + return this; + } + + /** + * Instantiate credit from serialized data. + * @param {Buffer} data + * @returns {Credit} + */ + + static fromRaw(data) { + return new this().fromRaw(data); + } + + /** + * Get serialization size. + * @returns {Number} + */ + + getSize() { + return this.coin.getSize() + 2; + } + + /** + * Serialize credit. + * @returns {Buffer} + */ + + toRaw() { + const size = this.getSize(); + const bw = bio.write(size); + this.coin.toWriter(bw); + bw.writeU8(this.spent ? 1 : 0); + bw.writeU8(this.own ? 1 : 0); + return bw.render(); + } + + /** + * Inject properties from tx object. + * @private + * @param {TX} tx + * @param {Number} index + * @returns {Credit} + */ + + fromTX(tx, index, height) { + this.coin.fromTX(tx, index, height); + this.spent = false; + this.own = false; + return this; + } + + /** + * Instantiate credit from transaction. + * @param {TX} tx + * @param {Number} index + * @returns {Credit} + */ + + static fromTX(tx, index, height) { + return new this().fromTX(tx, index, height); + } +} + +/** + * Transaction Details + * @alias module:wallet.Details + */ + +class Details { + /** + * Create transaction details. + * @constructor + * @param {TXRecord} wtx + * @param {BlockMeta} block + */ + + constructor(wtx, block) { + this.hash = wtx.hash; + this.tx = wtx.tx; + this.mtime = wtx.mtime; + this.size = this.tx.getSize(); + this.vsize = this.tx.getVirtualSize(); + + this.block = null; + this.height = -1; + this.time = 0; + + if (block) { + this.block = block.hash; + this.height = block.height; + this.time = block.time; + } + + this.inputs = []; + this.outputs = []; + + this.init(); + } + + /** + * Initialize transaction details. + * @private + */ + + init() { + for (const input of this.tx.inputs) { + const member = new DetailsMember(); + member.address = input.getAddress(); + this.inputs.push(member); + } + + for (const output of this.tx.outputs) { + const member = new DetailsMember(); + member.value = output.value; + member.address = output.getAddress(); + this.outputs.push(member); + } + } + + /** + * Add necessary info to input member. + * @param {Number} i + * @param {Path} path + * @param {Coin} coin + */ + + setInput(i, path, coin) { + const member = this.inputs[i]; + + if (coin) { + member.value = coin.value; + member.address = coin.getAddress(); + } + + if (path) + member.path = path; + } + + /** + * Add necessary info to output member. + * @param {Number} i + * @param {Path} path + */ + + setOutput(i, path) { + const member = this.outputs[i]; + + if (path) + member.path = path; + } + + /** + * Calculate confirmations. + * @returns {Number} + */ + + getDepth(height) { + if (this.height === -1) + return 0; + + if (height == null) + return 0; + + const depth = height - this.height; + + if (depth < 0) + return 0; + + return depth + 1; + } + + /** + * Calculate fee. Only works if wallet + * owns all inputs. Returns 0 otherwise. + * @returns {Amount} + */ + + getFee() { + let inputValue = 0; + let outputValue = 0; + + for (const input of this.inputs) { + if (!input.path) + return 0; + + inputValue += input.value; + } + + for (const output of this.outputs) + outputValue += output.value; + + return inputValue - outputValue; + } + + /** + * Calculate fee rate. Only works if wallet + * owns all inputs. Returns 0 otherwise. + * @param {Amount} fee + * @returns {Rate} + */ + + getRate(fee) { + return policy.getRate(this.vsize, fee); + } + + /** + * Convert details to a more json-friendly object. + * @returns {Object} + */ + + toJSON(network, height) { + const fee = this.getFee(); + const rate = this.getRate(fee); + + return { + hash: util.revHex(this.hash), + height: this.height, + block: this.block ? util.revHex(this.block) : null, + time: this.time, + mtime: this.mtime, + date: util.date(this.time), + mdate: util.date(this.mtime), + size: this.size, + virtualSize: this.vsize, + fee: fee, + rate: rate, + confirmations: this.getDepth(height), + inputs: this.inputs.map((input) => { + return input.getJSON(network); + }), + outputs: this.outputs.map((output) => { + return output.getJSON(network); + }), + tx: this.tx.toRaw().toString('hex') + }; + } +} + +/** + * Transaction Details Member + * @property {Number} value + * @property {Address} address + * @property {Path} path + */ + +class DetailsMember { + /** + * Create details member. + * @constructor + */ + + constructor() { + this.value = 0; + this.address = null; + this.path = null; + } + + /** + * Convert the member to a more json-friendly object. + * @returns {Object} + */ + + toJSON() { + return this.getJSON(); + } + + /** + * Convert the member to a more json-friendly object. + * @param {Network} network + * @returns {Object} + */ + + getJSON(network) { + return { + value: this.value, + address: this.address + ? this.address.toString(network) + : null, + path: this.path + ? this.path.toJSON() + : null + }; + } +} + +/** + * Block Record + * @alias module:wallet.BlockRecord + */ + +class BlockRecord { + /** + * Create a block record. + * @constructor + * @param {Hash} hash + * @param {Number} height + * @param {Number} time + */ + + constructor(hash, height, time) { + this.hash = hash || consensus.ZERO_HASH; + this.height = height != null ? height : -1; + this.time = time || 0; + this.hashes = new BufferSet(); + } + + /** + * Add transaction to block record. + * @param {Hash} hash + * @returns {Boolean} + */ + + add(hash) { + if (this.hashes.has(hash)) + return false; + + this.hashes.add(hash); + + return true; + } + + /** + * Remove transaction from block record. + * @param {Hash} hash + * @returns {Boolean} + */ + + remove(hash) { + return this.hashes.delete(hash); + } + + /** + * Instantiate wallet block from serialized tip data. + * @private + * @param {Buffer} data + */ + + fromRaw(data) { + const br = bio.read(data); + + this.hash = br.readHash(); + this.height = br.readU32(); + this.time = br.readU32(); + + const count = br.readU32(); + + for (let i = 0; i < count; i++) { + const hash = br.readHash(); + this.hashes.add(hash); + } + + return this; + } + + /** + * Instantiate wallet block from serialized data. + * @param {Buffer} data + * @returns {BlockRecord} + */ + + static fromRaw(data) { + return new this().fromRaw(data); + } + + /** + * Get serialization size. + * @returns {Number} + */ + + getSize() { + return 44 + this.hashes.size * 32; + } + + /** + * Serialize the wallet block as a tip (hash and height). + * @returns {Buffer} + */ + + toRaw() { + const size = this.getSize(); + const bw = bio.write(size); + + bw.writeHash(this.hash); + bw.writeU32(this.height); + bw.writeU32(this.time); + + bw.writeU32(this.hashes.size); + + for (const hash of this.hashes) + bw.writeHash(hash); + + return bw.render(); + } + + /** + * Convert hashes set to an array. + * @returns {Hash[]} + */ + + toArray() { + const hashes = []; + for (const hash of this.hashes) + hashes.push(hash); + return hashes; + } + + /** + * Convert the block to a more json-friendly object. + * @returns {Object} + */ + + toJSON() { + return { + hash: util.revHex(this.hash), + height: this.height, + time: this.time, + hashes: this.toArray().map(util.revHex) + }; + } + + /** + * Instantiate wallet block from block meta. + * @private + * @param {BlockMeta} block + */ + + fromMeta(block) { + this.hash = block.hash; + this.height = block.height; + this.time = block.time; + return this; + } + + /** + * Instantiate wallet block from block meta. + * @param {BlockMeta} block + * @returns {BlockRecord} + */ + + static fromMeta(block) { + return new this().fromMeta(block); + } +} + +/* + * Expose + */ + +module.exports = TXDB; From 8d6afe10819208a682ac06405c55946979bb866e Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 24 Jan 2021 12:39:27 +0200 Subject: [PATCH 531/540] Update nodejs version in .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9af64ac..a6bbe99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "7" + - "15" install: - npm install From a63f36c4c7ff5e0df3bc26548ffcc0cad3508371 Mon Sep 17 00:00:00 2001 From: Orfeas Litos Date: Sun, 24 Jan 2021 13:00:18 +0200 Subject: [PATCH 532/540] flow: Ignore scripts/ directory --- .flowconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.flowconfig b/.flowconfig index be6d503..b25225a 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,6 +3,7 @@ .*/test/* .*/minimal_testcases/* .*/lib/* +.*/scripts/* [include] ./src From b969dda8a416fe029523d799908c41e4e2f2af85 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 17 May 2023 17:15:47 +0100 Subject: [PATCH 533/540] Update packages --- package-lock.json | 4179 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 3629 insertions(+), 550 deletions(-) diff --git a/package-lock.json b/package-lock.json index ddf6788..b0467f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,3183 @@ { "name": "trust-is-risk", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "trust-is-risk", + "version": "0.0.1", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bcoin": "git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", + "bcrypto": "^5.3.0", + "graph-theory-ford-fulkerson": "^1.0.0", + "sorted-set": "^0.3.0" + }, + "devDependencies": { + "babel-eslint": "^7.2.3", + "eslint": "^3.19.0", + "eslint-plugin-flowtype": "^2.50.3", + "flow-bin": "^0.45.0", + "flow-remove-types": "^1.2.3", + "mocha": "^8.2.1", + "should": "^11.2.1", + "should-sinon": "0.0.5", + "sinon": "^5.1.1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "dependencies": { + "samsam": "1.3.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, + "dependencies": { + "acorn": "^3.0.4" + } + }, + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "node_modules/ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==", + "dev": true, + "peerDependencies": { + "ajv": ">=4.10.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", + "dev": true + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-eslint": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha512-i2yKOhjgwUbUrJ8oJm6QqRzltIoFahGNPZ0HF22lUN4H1DW03JQyJm7WSv+I1LURQWjDNhVqFo04acYa07rhOQ==", + "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.22.0", + "babel-traverse": "^6.23.1", + "babel-types": "^6.23.0", + "babylon": "^6.17.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "dev": true, + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true, + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bcoin": { + "version": "2.2.0", + "resolved": "git+ssh://git@github.com/bcoin-org/bcoin.git#acdeb84767f3ceb82b4a75931fe353229c3bc7b5", + "bundleDependencies": [ + "bcfg", + "bcrypto", + "bcurl", + "bdb", + "bdns", + "bevent", + "bfile", + "bfilter", + "bheep", + "binet", + "blgr", + "blru", + "blst", + "bmutex", + "brq", + "bs32", + "bsert", + "bsock", + "bsocks", + "btcp", + "buffer-map", + "bufio", + "bupnp", + "bval", + "bweb", + "loady", + "n64", + "nan" + ], + "license": "MIT", + "dependencies": { + "bcfg": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.7", + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", + "bcurl": "git+https://github.com/bcoin-org/bcurl.git#semver:^0.1.6", + "bdb": "git+https://github.com/bcoin-org/bdb.git#semver:~1.2.1", + "bdns": "git+https://github.com/bcoin-org/bdns.git#semver:~0.1.5", + "bevent": "git+https://github.com/bcoin-org/bevent.git#semver:~0.1.5", + "bfile": "git+https://github.com/bcoin-org/bfile.git#semver:~0.2.1", + "bfilter": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.3.0", + "bheep": "git+https://github.com/bcoin-org/bheep.git#semver:~0.1.5", + "binet": "git+https://github.com/bcoin-org/binet.git#semver:~0.3.5", + "blgr": "git+https://github.com/bcoin-org/blgr.git#semver:~0.2.0", + "blru": "git+https://github.com/bcoin-org/blru.git#semver:~0.1.6", + "blst": "git+https://github.com/bcoin-org/blst.git#semver:~0.1.5", + "bmutex": "git+https://github.com/bcoin-org/bmutex.git#semver:~0.1.6", + "brq": "git+https://github.com/bcoin-org/brq.git#semver:~0.1.7", + "bs32": "git+https://github.com/bcoin-org/bs32.git#semver:=0.1.6", + "bsert": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", + "bsock": "git+https://github.com/bcoin-org/bsock.git#semver:~0.1.9", + "bsocks": "git+https://github.com/bcoin-org/bsocks.git#semver:~0.2.6", + "btcp": "git+https://github.com/bcoin-org/btcp.git#semver:~0.1.5", + "buffer-map": "git+https://github.com/chjj/buffer-map.git#semver:~0.0.7", + "bufio": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", + "bupnp": "git+https://github.com/bcoin-org/bupnp.git#semver:~0.2.6", + "bval": "git+https://github.com/bcoin-org/bval.git#semver:~0.1.6", + "bweb": "git+https://github.com/bcoin-org/bweb.git#semver:=0.1.9", + "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1", + "n64": "git+https://github.com/chjj/n64.git#semver:~0.2.10", + "nan": "git+https://github.com/braydonf/nan.git#semver:=2.14.0" + }, + "bin": { + "bcoin": "bin/bcoin", + "bcoin-cli": "bin/bcoin-cli", + "bcoin-node": "bin/node", + "bcoin-spvnode": "bin/spvnode", + "bwallet": "bin/bwallet", + "bwallet-cli": "bin/bwallet-cli" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/bcoin/node_modules/bcfg": { + "version": "0.1.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bcrypto": { + "version": "5.5.0", + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bufio": "~1.0.7", + "loady": "~0.0.5" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bcurl": { + "version": "0.1.9", + "inBundle": true, + "license": "MIT", + "dependencies": { + "brq": "~0.1.8", + "bsert": "~0.0.10", + "bsock": "~0.1.9" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bdb": { + "version": "1.2.2", + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10", + "loady": "~0.0.1" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/bcoin/node_modules/bdns": { + "version": "0.1.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bevent": { + "version": "0.1.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bfile": { + "version": "0.2.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bfilter": { + "version": "2.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", + "bsert": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", + "bufio": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", + "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bheep": { + "version": "0.1.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/binet": { + "version": "0.3.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bs32": "~0.1.5", + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/blgr": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/blru": { + "version": "0.1.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/blst": { + "version": "0.1.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bmutex": { + "version": "0.1.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/brq": { + "version": "0.1.8", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bs32": { + "version": "0.1.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bsert": { + "version": "0.0.10", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bsock": { + "version": "0.1.9", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bsocks": { + "version": "0.2.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "binet": "~0.3.5", + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/btcp": { + "version": "0.1.5", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/buffer-map": { + "version": "0.0.7", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bufio": { + "version": "1.0.7", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bupnp": { + "version": "0.2.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "binet": "~0.3.5", + "brq": "~0.1.7", + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bval": { + "version": "0.1.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/bweb": { + "version": "0.1.9", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bsert": "~0.0.10", + "bsock": "~0.1.8" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/loady": { + "version": "0.0.5", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bcoin/node_modules/n64": { + "version": "0.2.10", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=2.0.0" + } + }, + "node_modules/bcoin/node_modules/nan": { + "version": "2.14.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/bcrypto": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-5.4.0.tgz", + "integrity": "sha512-KDX2CR29o6ZoqpQndcCxFZAtYA1jDMnXU3jmCfzP44g++Cu7AHHtZN/JbrN/MXAg9SLvtQ8XISG+eVD9zH1+Jg==", + "hasInstallScript": true, + "dependencies": { + "bufio": "~1.0.7", + "loady": "~0.0.5" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bufio": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", + "integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "dev": true, + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", + "dev": true, + "dependencies": { + "restore-cursor": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "node_modules/es6-set": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", + "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "es6-iterator": "~2.0.3", + "es6-symbol": "^3.1.3", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-set/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==", + "dev": true, + "dependencies": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "2.50.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", + "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.10" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": ">=2.0.0" + } + }, + "node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "dependencies": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flow-bin": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", + "integrity": "sha512-ReN7RtA5PZ/q3VJHkMCTZsPIgpwGsDlHcMfw05+e8ynSR+I62VJSgc1Yh0ROPEAZysyXNS2p270CBziAzpc5fg==", + "dev": true, + "bin": { + "flow": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flow-remove-types": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.3.tgz", + "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==", + "dev": true, + "dependencies": { + "babylon": "^6.15.0", + "vlq": "^0.2.1" + }, + "bin": { + "flow-node": "flow-node", + "flow-remove-types": "flow-remove-types" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", + "dev": true, + "dependencies": { + "is-property": "^1.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graph-theory-ford-fulkerson": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", + "integrity": "sha512-HntwL+yfi+2uduSpn/vjdlH4uGmpDgce86/zbk0t88pUGApl8cFhjTrbAFrJzEu/JQSeoa6SgtWsazIt5Ww+Nw==" + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-my-ip-valid": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", + "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", + "dev": true + }, + "node_modules/is-my-json-valid": { + "version": "2.20.6", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", + "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", + "dev": true, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^5.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "dev": true + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-stable-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", + "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", + "dev": true, + "dependencies": { + "jsonify": "^0.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/loady": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/loady/-/loady-0.0.5.tgz", + "integrity": "sha512-uxKD2HIj042/HBx77NBcmEPsD+hxCgAtjEWlYNScuUjIsh/62Uyu39GOR68TBR68v+jqDL9zfftCWoUo4y03sQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "node_modules/nise": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", + "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "dev": true, + "dependencies": { + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^5.0.1", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/formatio": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "node_modules/nise/node_modules/lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "mute-stream": "0.0.5" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", + "dev": true, + "dependencies": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==", + "dev": true, + "dependencies": { + "once": "^1.3.0" + } + }, + "node_modules/rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "deprecated": "This package has been deprecated in favour of @sinonjs/samsam", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "iojs": "*", + "node": ">=0.11.0" + } + }, + "node_modules/should": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", + "integrity": "sha512-TsX7f9e6f7h+ijEJwga7baYTCspzs0KJRJafafCqiPpgp2/eZ1b7LK3RNZZ5uIK8J0nhFOXVvpbcRwy09piO4w==", + "dev": true, + "dependencies": { + "should-equal": "^1.0.0", + "should-format": "^3.0.2", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "node_modules/should-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", + "integrity": "sha512-V78BKdBq92TbvEHjVJRwWItXtV6G813dMBviJZ01sn57sdOqb8pJUPHZhs9vUa8e6wQOHzPW7RTWv5wFFyJYmQ==", + "dev": true, + "dependencies": { + "should-type": "^1.0.0" + } + }, + "node_modules/should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "dev": true, + "dependencies": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "node_modules/should-sinon": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.5.tgz", + "integrity": "sha512-X9kFJwgRqxXFpP7RupHSzTMPnG7e9g92/EpmrKr3Xv9a4bkECPG1Gg58igERECSM2F7OqACzNrIYX5lPudARsg==", + "dev": true, + "peerDependencies": { + "should": ">= 8.x" + } + }, + "node_modules/should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", + "dev": true + }, + "node_modules/should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "dependencies": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "node_modules/should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "dev": true + }, + "node_modules/sinon": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", + "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", + "dev": true, + "dependencies": { + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.5.0", + "lodash.get": "^4.4.2", + "lolex": "^2.4.2", + "nise": "^1.3.3", + "supports-color": "^5.4.0", + "type-detect": "^4.0.8" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sorted-set": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", + "integrity": "sha512-Qr0pN64VzHGGQS5BwYophLZMMkx0cAbzH07JQ6JpFw5AiDwGGDxQ8HsFUzbYPpijZGIVC4WONgZvwRzYolkN8g==", + "engines": { + "node": "*" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==", + "dev": true, + "dependencies": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", + "slice-ansi": "0.0.4", + "string-width": "^2.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, "dependencies": { "@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -34,9 +3204,9 @@ } }, "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "@ungap/promise-all-settled": { @@ -54,7 +3224,7 @@ "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", "dev": true, "requires": { "acorn": "^3.0.4" @@ -63,7 +3233,7 @@ "acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", "dev": true } } @@ -71,7 +3241,7 @@ "ajv": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==", "dev": true, "requires": { "co": "^4.6.0", @@ -81,8 +3251,9 @@ "ajv-keywords": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true + "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==", + "dev": true, + "requires": {} }, "ansi-colors": { "version": "4.1.1", @@ -93,25 +3264,25 @@ "ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", "dev": true }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -130,13 +3301,13 @@ "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", "dev": true }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, "requires": { "chalk": "^1.1.3", @@ -147,7 +3318,7 @@ "babel-eslint": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", - "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "integrity": "sha512-i2yKOhjgwUbUrJ8oJm6QqRzltIoFahGNPZ0HF22lUN4H1DW03JQyJm7WSv+I1LURQWjDNhVqFo04acYa07rhOQ==", "dev": true, "requires": { "babel-code-frame": "^6.22.0", @@ -159,7 +3330,7 @@ "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", "dev": true, "requires": { "babel-runtime": "^6.22.0" @@ -168,7 +3339,7 @@ "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", "dev": true, "requires": { "core-js": "^2.4.0", @@ -178,7 +3349,7 @@ "babel-traverse": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, "requires": { "babel-code-frame": "^6.26.0", @@ -195,7 +3366,7 @@ "babel-types": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -211,26 +3382,26 @@ "dev": true }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "bcoin": { - "version": "git+https://github.com/bcoin-org/bcoin.git#2dece4fbe10fffa369e9dd0e8263eb57ba30dcac", - "from": "git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", + "version": "git+ssh://git@github.com/bcoin-org/bcoin.git#acdeb84767f3ceb82b4a75931fe353229c3bc7b5", + "from": "bcoin@git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", "requires": { - "bcfg": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.6", - "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.0.4", + "bcfg": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.7", + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", "bcurl": "git+https://github.com/bcoin-org/bcurl.git#semver:^0.1.6", "bdb": "git+https://github.com/bcoin-org/bdb.git#semver:~1.2.1", "bdns": "git+https://github.com/bcoin-org/bdns.git#semver:~0.1.5", "bevent": "git+https://github.com/bcoin-org/bevent.git#semver:~0.1.5", "bfile": "git+https://github.com/bcoin-org/bfile.git#semver:~0.2.1", - "bfilter": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.0.0", + "bfilter": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.3.0", "bheep": "git+https://github.com/bcoin-org/bheep.git#semver:~0.1.5", "binet": "git+https://github.com/bcoin-org/binet.git#semver:~0.3.5", - "blgr": "git+https://github.com/bcoin-org/blgr.git#semver:~0.1.7", + "blgr": "git+https://github.com/bcoin-org/blgr.git#semver:~0.2.0", "blru": "git+https://github.com/bcoin-org/blru.git#semver:~0.1.6", "blst": "git+https://github.com/bcoin-org/blst.git#semver:~0.1.5", "bmutex": "git+https://github.com/bcoin-org/bmutex.git#semver:~0.1.6", @@ -251,36 +3422,31 @@ }, "dependencies": { "bcfg": { - "version": "0.1.6", - "from": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.6", + "version": "0.1.7", "bundled": true, "requires": { "bsert": "~0.0.10" } }, "bcrypto": { - "version": "5.0.4", - "from": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.0.4", + "version": "5.5.0", "bundled": true, "requires": { - "bufio": "~1.0.6", - "loady": "~0.0.1", - "nan": "^2.14.0" + "bufio": "~1.0.7", + "loady": "~0.0.5" } }, "bcurl": { - "version": "0.1.6", - "from": "git+https://github.com/bcoin-org/bcurl.git#semver:^0.1.6", + "version": "0.1.9", "bundled": true, "requires": { - "brq": "~0.1.7", + "brq": "~0.1.8", "bsert": "~0.0.10", - "bsock": "~0.1.8" + "bsock": "~0.1.9" } }, "bdb": { - "version": "1.2.1", - "from": "git+https://github.com/bcoin-org/bdb.git#semver:~1.2.1", + "version": "1.2.2", "bundled": true, "requires": { "bsert": "~0.0.10", @@ -289,7 +3455,6 @@ }, "bdns": { "version": "0.1.5", - "from": "git+https://github.com/bcoin-org/bdns.git#semver:~0.1.5", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -297,7 +3462,6 @@ }, "bevent": { "version": "0.1.5", - "from": "git+https://github.com/bcoin-org/bevent.git#semver:~0.1.5", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -305,32 +3469,27 @@ }, "bfile": { "version": "0.2.2", - "from": "git+https://github.com/bcoin-org/bfile.git#semver:~0.2.1", "bundled": true }, "bfilter": { - "version": "2.0.0", - "from": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.0.0", + "version": "2.3.0", "bundled": true, "requires": { - "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.0.4", + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", "bsert": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", "bufio": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", - "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1", - "nan": "git+https://github.com/braydonf/nan.git#semver:=2.14.0" + "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1" } }, "bheep": { "version": "0.1.5", - "from": "git+https://github.com/bcoin-org/bheep.git#semver:~0.1.5", "bundled": true, "requires": { "bsert": "~0.0.10" } }, "binet": { - "version": "0.3.5", - "from": "git+https://github.com/bcoin-org/binet.git#semver:~0.3.5", + "version": "0.3.6", "bundled": true, "requires": { "bs32": "~0.1.5", @@ -338,8 +3497,7 @@ } }, "blgr": { - "version": "0.1.7", - "from": "git+https://github.com/bcoin-org/blgr.git#semver:~0.1.7", + "version": "0.2.0", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -347,7 +3505,6 @@ }, "blru": { "version": "0.1.6", - "from": "git+https://github.com/bcoin-org/blru.git#semver:~0.1.6", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -355,7 +3512,6 @@ }, "blst": { "version": "0.1.5", - "from": "git+https://github.com/bcoin-org/blst.git#semver:~0.1.5", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -363,7 +3519,6 @@ }, "bmutex": { "version": "0.1.6", - "from": "git+https://github.com/bcoin-org/bmutex.git#semver:~0.1.6", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -371,7 +3526,6 @@ }, "brq": { "version": "0.1.8", - "from": "git+https://github.com/bcoin-org/brq.git#semver:~0.1.7", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -379,7 +3533,6 @@ }, "bs32": { "version": "0.1.6", - "from": "git+https://github.com/bcoin-org/bs32.git#semver:=0.1.6", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -387,12 +3540,10 @@ }, "bsert": { "version": "0.0.10", - "from": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", "bundled": true }, "bsock": { "version": "0.1.9", - "from": "git+https://github.com/bcoin-org/bsock.git#semver:~0.1.9", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -400,7 +3551,6 @@ }, "bsocks": { "version": "0.2.6", - "from": "git+https://github.com/bcoin-org/bsocks.git#semver:~0.2.6", "bundled": true, "requires": { "binet": "~0.3.5", @@ -409,22 +3559,18 @@ }, "btcp": { "version": "0.1.5", - "from": "git+https://github.com/bcoin-org/btcp.git#semver:~0.1.5", "bundled": true }, "buffer-map": { "version": "0.0.7", - "from": "git+https://github.com/chjj/buffer-map.git#semver:~0.0.7", "bundled": true }, "bufio": { - "version": "1.0.6", - "from": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", + "version": "1.0.7", "bundled": true }, "bupnp": { "version": "0.2.6", - "from": "git+https://github.com/bcoin-org/bupnp.git#semver:~0.2.6", "bundled": true, "requires": { "binet": "~0.3.5", @@ -434,7 +3580,6 @@ }, "bval": { "version": "0.1.6", - "from": "git+https://github.com/bcoin-org/bval.git#semver:~0.1.6", "bundled": true, "requires": { "bsert": "~0.0.10" @@ -442,7 +3587,6 @@ }, "bweb": { "version": "0.1.9", - "from": "git+https://github.com/bcoin-org/bweb.git#semver:=0.1.9", "bundled": true, "requires": { "bsert": "~0.0.10", @@ -450,35 +3594,32 @@ } }, "loady": { - "version": "0.0.1", - "from": "git+https://github.com/chjj/loady.git#semver:~0.0.1", + "version": "0.0.5", "bundled": true }, "n64": { "version": "0.2.10", - "from": "git+https://github.com/chjj/n64.git#semver:~0.2.10", "bundled": true }, "nan": { "version": "2.14.0", - "from": "git+https://github.com/braydonf/nan.git#semver:=2.14.0", "bundled": true } } }, "bcrypto": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-5.3.0.tgz", - "integrity": "sha512-SP48cpoc4BkEPNOErdsZ1VjbtdXY/C0f5wAywWniLne/Fd/5oOBqLbC6ZavngLvk4oik76g4I7PO5KduJoqECQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-5.4.0.tgz", + "integrity": "sha512-KDX2CR29o6ZoqpQndcCxFZAtYA1jDMnXU3jmCfzP44g++Cu7AHHtZN/JbrN/MXAg9SLvtQ8XISG+eVD9zH1+Jg==", "requires": { "bufio": "~1.0.7", "loady": "~0.0.5" } }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { @@ -507,9 +3648,9 @@ "dev": true }, "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "bufio": { @@ -520,7 +3661,7 @@ "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", "dev": true, "requires": { "callsites": "^0.2.0" @@ -529,19 +3670,19 @@ "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -552,14 +3693,14 @@ } }, "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -576,7 +3717,7 @@ "cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", "dev": true, "requires": { "restore-cursor": "^1.0.1" @@ -589,46 +3730,46 @@ "dev": true }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" } } } @@ -636,13 +3777,13 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true }, "color-convert": { @@ -663,7 +3804,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "concat-stream": { @@ -685,9 +3826,9 @@ "dev": true }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, "d": { @@ -710,21 +3851,21 @@ } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "doctrine": { @@ -737,26 +3878,26 @@ } }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" } }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, "requires": { "d": "1", @@ -767,7 +3908,7 @@ "es6-map": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==", "dev": true, "requires": { "d": "1", @@ -779,27 +3920,24 @@ } }, "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", + "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "es6-iterator": "~2.0.3", + "es6-symbol": "^3.1.3", + "event-emitter": "^0.3.5", + "type": "^2.7.2" }, "dependencies": { - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true } } }, @@ -825,16 +3963,22 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "escope": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==", "dev": true, "requires": { "es6-map": "^0.1.3", @@ -846,7 +3990,7 @@ "eslint": { "version": "3.19.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==", "dev": true, "requires": { "babel-code-frame": "^6.16.0", @@ -912,18 +4056,18 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -938,9 +4082,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -960,7 +4104,7 @@ "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dev": true, "requires": { "d": "1", @@ -970,22 +4114,22 @@ "exit-hook": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", "dev": true }, "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, "requires": { - "type": "^2.0.0" + "type": "^2.7.2" }, "dependencies": { "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", "dev": true } } @@ -993,13 +4137,13 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5", @@ -1009,7 +4153,7 @@ "file-entry-cache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", "dev": true, "requires": { "flat-cache": "^1.2.1", @@ -1056,7 +4200,7 @@ "flow-bin": { "version": "0.45.0", "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", - "integrity": "sha1-AJ3Q9Xej9mXHTKi+gnrowt2P1rU=", + "integrity": "sha512-ReN7RtA5PZ/q3VJHkMCTZsPIgpwGsDlHcMfw05+e8ynSR+I62VJSgc1Yh0ROPEAZysyXNS2p270CBziAzpc5fg==", "dev": true }, "flow-remove-types": { @@ -1072,13 +4216,13 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -1100,7 +4244,7 @@ "generate-object-property": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", "dev": true, "requires": { "is-property": "^1.0.0" @@ -1113,23 +4257,23 @@ "dev": true }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -1142,15 +4286,15 @@ "dev": true }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "graph-theory-ford-fulkerson": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", - "integrity": "sha1-LDHSHXDxp9KCiZX+BnZFdv9/nik=" + "integrity": "sha512-HntwL+yfi+2uduSpn/vjdlH4uGmpDgce86/zbk0t88pUGApl8cFhjTrbAFrJzEu/JQSeoa6SgtWsazIt5Ww+Nw==" }, "growl": { "version": "1.10.5", @@ -1170,16 +4314,16 @@ "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "he": { @@ -1197,13 +4341,13 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -1219,7 +4363,7 @@ "inquirer": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==", "dev": true, "requires": { "ansi-escapes": "^1.1.0", @@ -1262,9 +4406,9 @@ } }, "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", "dev": true, "requires": { "has": "^1.0.3" @@ -1273,43 +4417,43 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", + "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", "dev": true }, "is-my-json-valid": { - "version": "2.20.5", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", - "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", + "version": "2.20.6", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", + "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", "dev": true, "requires": { "generate-function": "^2.0.0", "generate-object-property": "^1.1.0", "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", + "jsonpointer": "^5.0.0", "xtend": "^4.0.0" } }, @@ -1328,7 +4472,7 @@ "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", "dev": true }, "is-resolvable": { @@ -1340,19 +4484,19 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", "dev": true }, "js-yaml": { @@ -1366,36 +4510,36 @@ } }, "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", + "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", "dev": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "^0.0.1" } }, "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", "dev": true }, "jsonpointer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", - "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true }, "just-extend": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", - "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -1417,15 +4561,15 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "log-symbols": { @@ -1447,21 +4591,15 @@ } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1489,103 +4627,127 @@ } }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" } }, "mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", + "js-yaml": "4.0.0", "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", + "ms": "2.1.3", + "nanoid": "3.1.20", "serialize-javascript": "5.0.1", "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "brace-expansion": "^1.1.7" } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "strip-json-comments": { @@ -1595,9 +4757,9 @@ "dev": true }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -1608,31 +4770,31 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "mute-stream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==", "dev": true }, "nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, "nise": { @@ -1678,19 +4840,19 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -1699,7 +4861,7 @@ "onetime": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", "dev": true }, "optionator": { @@ -1719,7 +4881,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true }, "p-limit": { @@ -1740,12 +4902,6 @@ "p-limit": "^3.0.2" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1755,19 +4911,19 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { @@ -1782,27 +4938,27 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true } } }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pluralize": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==", "dev": true }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true }, "process-nextick-args": { @@ -1814,7 +4970,7 @@ "progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", "dev": true }, "randombytes": { @@ -1827,9 +4983,9 @@ } }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -1853,7 +5009,7 @@ "readline2": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -1864,7 +5020,7 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "requires": { "resolve": "^1.1.6" @@ -1879,19 +5035,13 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", "dev": true, "requires": { "caller-path": "^0.1.0", @@ -1899,25 +5049,26 @@ } }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dev": true, "requires": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", "dev": true }, "restore-cursor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", "dev": true, "requires": { "exit-hook": "^1.0.0", @@ -1936,7 +5087,7 @@ "run-async": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==", "dev": true, "requires": { "once": "^1.3.0" @@ -1945,7 +5096,7 @@ "rx-lite": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==", "dev": true }, "safe-buffer": { @@ -1969,16 +5120,10 @@ "randombytes": "^2.1.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "shelljs": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==", "dev": true, "requires": { "glob": "^7.0.0", @@ -1989,7 +5134,7 @@ "should": { "version": "11.2.1", "resolved": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", - "integrity": "sha1-kPVRRVUtAc/CAGZuToGKHJZw7aI=", + "integrity": "sha512-TsX7f9e6f7h+ijEJwga7baYTCspzs0KJRJafafCqiPpgp2/eZ1b7LK3RNZZ5uIK8J0nhFOXVvpbcRwy09piO4w==", "dev": true, "requires": { "should-equal": "^1.0.0", @@ -2002,7 +5147,7 @@ "should-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", - "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", + "integrity": "sha512-V78BKdBq92TbvEHjVJRwWItXtV6G813dMBviJZ01sn57sdOqb8pJUPHZhs9vUa8e6wQOHzPW7RTWv5wFFyJYmQ==", "dev": true, "requires": { "should-type": "^1.0.0" @@ -2011,7 +5156,7 @@ "should-format": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, "requires": { "should-type": "^1.3.0", @@ -2021,13 +5166,14 @@ "should-sinon": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.5.tgz", - "integrity": "sha1-/8ioUb9FB2fn0K0i/4cVZQvpUOQ=", - "dev": true + "integrity": "sha512-X9kFJwgRqxXFpP7RupHSzTMPnG7e9g92/EpmrKr3Xv9a4bkECPG1Gg58igERECSM2F7OqACzNrIYX5lPudARsg==", + "dev": true, + "requires": {} }, "should-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "dev": true }, "should-type-adaptors": { @@ -2061,6 +5207,18 @@ "type-detect": "^4.0.8" }, "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2075,24 +5233,33 @@ "slice-ansi": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==", "dev": true }, "sorted-set": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", - "integrity": "sha1-POAVeFtkdPH6A6HGn/8ymFL8N+M=" + "integrity": "sha512-Qr0pN64VzHGGQS5BwYophLZMMkx0cAbzH07JQ6JpFw5AiDwGGDxQ8HsFUzbYPpijZGIVC4WONgZvwRzYolkN8g==" }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -2100,19 +5267,10 @@ "strip-ansi": "^3.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -2121,25 +5279,31 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, "table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==", "dev": true, "requires": { "ajv": "^4.7.0", @@ -2151,15 +5315,15 @@ }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "string-width": { @@ -2175,7 +5339,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -2186,19 +5350,19 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", "dev": true }, "to-regex-range": { @@ -2219,7 +5383,7 @@ "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, "requires": { "prelude-ls": "~1.1.2" @@ -2234,13 +5398,13 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, "user-home": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==", "dev": true, "requires": { "os-homedir": "^1.0.0" @@ -2249,7 +5413,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "vlq": { @@ -2267,12 +5431,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -2289,76 +5447,61 @@ "dev": true }, "workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-convert": "^2.0.1" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" } } } @@ -2366,13 +5509,13 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", "dev": true, "requires": { "mkdirp": "^0.5.1" @@ -2385,115 +5528,65 @@ "dev": true }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" } } } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { "version": "2.0.0", @@ -2505,20 +5598,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } } }, "yocto-queue": { From 8ac2a12c286119869e20e5f059e0176d8dad18a9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 17 May 2023 17:20:29 +0100 Subject: [PATCH 534/540] Fix vulnerabilities automatically --- package-lock.json | 3473 ++++++++++++++++++--------------------------- package.json | 4 +- 2 files changed, 1364 insertions(+), 2113 deletions(-) diff --git a/package-lock.json b/package-lock.json index b0467f7..808b696 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,16 +17,201 @@ }, "devDependencies": { "babel-eslint": "^7.2.3", - "eslint": "^3.19.0", + "eslint": "^8.40.0", "eslint-plugin-flowtype": "^2.50.3", "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.3", - "mocha": "^8.2.1", + "mocha": "^10.2.0", "should": "^11.2.1", "should-sinon": "0.0.5", "sinon": "^5.1.1" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -62,16 +247,10 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "node_modules/acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -81,43 +260,28 @@ } }, "node_modules/acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", - "dev": true, - "dependencies": { - "acorn": "^3.0.4" - } - }, - "node_modules/acorn-jsx/node_modules/acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "node_modules/ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==", - "dev": true, - "peerDependencies": { - "ajv": ">=4.10.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-colors": { @@ -129,15 +293,6 @@ "node": ">=6" } }, - "node_modules/ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -170,13 +325,10 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/array-from": { "version": "2.1.1", @@ -695,12 +847,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "node_modules/bufio": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", @@ -709,25 +855,13 @@ "node": ">=8.0.0" } }, - "node_modules/caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", - "dev": true, - "dependencies": { - "callsites": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/camelcase": { @@ -759,51 +893,44 @@ } }, "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" + "fsevents": "~2.3.2" } }, - "node_modules/circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", - "dev": true - }, - "node_modules/cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "restore-cursor": "^1.0.1" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -824,29 +951,6 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -859,25 +963,6 @@ "node": ">=8" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -902,21 +987,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "node_modules/core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", @@ -925,20 +995,18 @@ "dev": true, "hasInstallScript": true }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, "node_modules/debug": { @@ -978,15 +1046,15 @@ } }, "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, "node_modules/emoji-regex": { @@ -995,91 +1063,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "node_modules/es6-set": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", - "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "es6-iterator": "~2.0.3", - "es6-symbol": "^3.1.3", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-set/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1098,68 +1081,61 @@ "node": ">=0.8.0" } }, - "node_modules/escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==", - "dev": true, - "dependencies": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-plugin-flowtype": { @@ -1177,30 +1153,163 @@ "eslint": ">=2.0.0" } }, - "node_modules/espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "dependencies": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { @@ -1215,15 +1324,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -1236,7 +1336,7 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", @@ -1245,15 +1345,6 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -1263,38 +1354,16 @@ "node": ">=0.10.0" } }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "node_modules/fast-levenshtein": { @@ -1303,30 +1372,25 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - }, - "engines": { - "node": ">=0.10.0" + "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=0.10.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { @@ -1367,20 +1431,24 @@ } }, "node_modules/flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=0.10.0" + "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, "node_modules/flow-bin": { "version": "0.45.0", "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", @@ -1427,30 +1495,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "dependencies": { - "is-property": "^1.0.2" - } - }, - "node_modules/generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", - "dev": true, - "dependencies": { - "is-property": "^1.0.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1461,15 +1505,15 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -1481,15 +1525,15 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/globals": { @@ -1501,37 +1545,16 @@ "node": ">=0.10.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "node_modules/graph-theory-ford-fulkerson": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", "integrity": "sha512-HntwL+yfi+2uduSpn/vjdlH4uGmpDgce86/zbk0t88pUGApl8cFhjTrbAFrJzEu/JQSeoa6SgtWsazIt5Ww+Nw==" }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true }, "node_modules/has-ansi": { "version": "2.0.0", @@ -1564,10 +1587,29 @@ } }, "node_modules/ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/imurmurhash": { "version": "0.1.4", @@ -1594,36 +1636,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -1645,18 +1657,6 @@ "node": ">=8" } }, - "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1667,15 +1667,12 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/is-glob": { @@ -1690,25 +1687,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-my-ip-valid": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", - "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", - "dev": true - }, - "node_modules/is-my-json-valid": { - "version": "2.20.6", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", - "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", - "dev": true, - "dependencies": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^5.0.0", - "xtend": "^4.0.0" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1718,6 +1696,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -1727,22 +1714,22 @@ "node": ">=8" } }, - "node_modules/is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", - "dev": true - }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "node_modules/isexe": { @@ -1751,6 +1738,16 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -1758,47 +1755,28 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, - "node_modules/json-stable-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", - "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", - "dev": true, - "dependencies": { - "jsonify": "^0.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/just-extend": { "version": "4.2.1", @@ -1807,13 +1785,13 @@ "dev": true }, "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -1854,16 +1832,26 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols/node_modules/ansi-styles": { @@ -1939,81 +1927,59 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "dependencies": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 10.12.0" + "node": ">= 14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/argparse": { + "node_modules/mocha/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } }, "node_modules/mocha/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2045,48 +2011,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/mocha/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/mocha/node_modules/ms": { @@ -2095,18 +2029,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mocha/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -2128,16 +2050,10 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==", - "dev": true - }, "node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -2152,12 +2068,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, "node_modules/nise": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", @@ -2199,24 +2109,6 @@ "node": ">=0.10.0" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2226,41 +2118,23 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2291,6 +2165,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2309,17 +2195,14 @@ "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/path-to-regexp": { "version": "1.8.0", @@ -2330,12 +2213,6 @@ "isarray": "0.0.1" } }, - "node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2348,36 +2225,44 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==", - "dev": true - }, "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -2387,25 +2272,10 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" @@ -2414,29 +2284,6 @@ "node": ">=8.10.0" } }, - "node_modules/readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", @@ -2452,90 +2299,82 @@ "node": ">=0.10.0" } }, - "node_modules/require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", - "dev": true, - "dependencies": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "dependencies": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - }, "engines": { + "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "once": "^1.3.0" + "queue-microtask": "^1.2.2" } }, - "node_modules/rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==", - "dev": true - }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/samsam": { "version": "1.3.0", @@ -2545,30 +2384,33 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { "randombytes": "^2.1.0" } }, - "node_modules/shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" + "shebang-regex": "^3.0.0" }, "engines": { - "iojs": "*", - "node": ">=0.11.0" + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/should": { @@ -2679,15 +2521,6 @@ "node": ">=4" } }, - "node_modules/slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sorted-set": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", @@ -2696,33 +2529,39 @@ "node": "*" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/strip-ansi": { @@ -2737,22 +2576,16 @@ "node": ">=0.10.0" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { @@ -2764,87 +2597,12 @@ "node": ">=0.8.0" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==", - "dev": true, - "dependencies": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -2866,19 +2624,13 @@ "node": ">=8.0" } }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" @@ -2893,29 +2645,26 @@ "node": ">=4" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "dependencies": { - "os-homedir": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } }, "node_modules/vlq": { "version": "0.2.3", @@ -2938,15 +2687,6 @@ "node": ">= 8" } }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -2957,9 +2697,9 @@ } }, "node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "node_modules/wrap-ansi": { @@ -3003,29 +2743,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3044,27 +2761,6 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -3116,64 +2812,150 @@ "node": ">=10" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + } + }, + "dependencies": { + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "eslint-visitor-keys": "^3.3.0" } }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, - "engines": { - "node": ">=8" + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" }, - "engines": { - "node": ">=8" + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } - } - }, - "dependencies": { + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -3209,64 +2991,37 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", - "dev": true - } - } - }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==", - "dev": true, - "requires": {} - }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", - "dev": true - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -3290,13 +3045,10 @@ } }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-from": { "version": "2.1.1", @@ -3647,30 +3399,15 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "bufio": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", "integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==" }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { @@ -3693,42 +3430,32 @@ } }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3746,23 +3473,6 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3774,18 +3484,6 @@ } } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3807,38 +3505,21 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", "dev": true }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "debug": { @@ -3869,9 +3550,9 @@ "dev": true }, "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3883,86 +3564,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-set": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", - "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "es6-iterator": "~2.0.3", - "es6-symbol": "^3.1.3", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3975,59 +3576,127 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "eslint-plugin-flowtype": { @@ -4039,22 +3708,33 @@ "lodash": "^4.17.10" } }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true }, + "espree": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, "esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -4062,14 +3742,6 @@ "dev": true, "requires": { "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, "esrecurse": { @@ -4079,20 +3751,12 @@ "dev": true, "requires": { "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "esutils": { @@ -4101,38 +3765,17 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -4140,24 +3783,22 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "reusify": "^1.0.4" } }, "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^3.0.4" } }, "fill-range": { @@ -4186,17 +3827,21 @@ "dev": true }, "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, "flow-bin": { "version": "0.45.0", "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.45.0.tgz", @@ -4226,30 +3871,6 @@ "dev": true, "optional": true }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "requires": { - "is-property": "^1.0.2" - } - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -4257,26 +3878,26 @@ "dev": true }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "globals": { @@ -4285,32 +3906,17 @@ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "graph-theory-ford-fulkerson": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", "integrity": "sha512-HntwL+yfi+2uduSpn/vjdlH4uGmpDgce86/zbk0t88pUGApl8cFhjTrbAFrJzEu/JQSeoa6SgtWsazIt5Ww+Nw==" }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -4333,11 +3939,21 @@ "dev": true }, "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4360,33 +3976,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -4405,15 +3994,6 @@ "binary-extensions": "^2.0.0" } }, - "is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4421,13 +4001,10 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "is-glob": { "version": "4.0.3", @@ -4438,53 +4015,34 @@ "is-extglob": "^2.1.1" } }, - "is-my-ip-valid": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", - "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.20.6", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", - "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^5.0.0", - "xtend": "^4.0.0" - } - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", - "dev": true - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "isexe": { @@ -4493,6 +4051,12 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true + }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -4500,34 +4064,24 @@ "dev": true }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-stable-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", - "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "jsonify": "^0.0.1" + "argparse": "^2.0.1" } }, - "jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "just-extend": { @@ -4537,13 +4091,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "loady": { @@ -4572,13 +4126,20 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "dependencies": { "ansi-styles": { @@ -4635,64 +4196,48 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, "mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "requires": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { - "argparse": { + "brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -4712,36 +4257,13 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "ms": { @@ -4750,12 +4272,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4773,16 +4289,10 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==", - "dev": true - }, "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true }, "natural-compare": { @@ -4791,12 +4301,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, "nise": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", @@ -4837,18 +4341,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4858,32 +4350,20 @@ "wrappy": "1" } }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", - "dev": true - }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4902,6 +4382,15 @@ "p-limit": "^3.0.2" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4914,16 +4403,10 @@ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-to-regexp": { @@ -4933,14 +4416,6 @@ "dev": true, "requires": { "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - } } }, "picomatch": { @@ -4949,28 +4424,22 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==", - "dev": true - }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "randombytes": { @@ -4982,50 +4451,15 @@ "safe-buffer": "^5.1.0" } }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" } }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", @@ -5038,71 +4472,40 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "requires": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==", + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { - "once": "^1.3.0" + "queue-microtask": "^1.2.2" } }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==", - "dev": true - }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "samsam": { @@ -5112,25 +4515,29 @@ "dev": true }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" } }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==", + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "shebang-regex": "^3.0.0" } }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "should": { "version": "11.2.1", "resolved": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", @@ -5230,41 +4637,37 @@ } } }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==", - "dev": true - }, "sorted-set": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", "integrity": "sha512-Qr0pN64VzHGGQS5BwYophLZMMkx0cAbzH07JQ6JpFw5AiDwGGDxQ8HsFUzbYPpijZGIVC4WONgZvwRzYolkN8g==" }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "strip-ansi": { @@ -5276,16 +4679,10 @@ "ansi-regex": "^2.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { @@ -5294,71 +4691,12 @@ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==", - "dev": true, - "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -5374,19 +4712,13 @@ "is-number": "^7.0.0" } }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -5395,27 +4727,21 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==", + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { - "os-homedir": "^1.0.0" + "punycode": "^2.1.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, "vlq": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", @@ -5431,15 +4757,6 @@ "isexe": "^2.0.0" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -5447,9 +4764,9 @@ "dev": true }, "workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { @@ -5478,23 +4795,6 @@ "color-convert": "^2.0.1" } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -5512,21 +4812,6 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -5546,40 +4831,6 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, "yargs-parser": { diff --git a/package.json b/package.json index 8f88766..ce895cd 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,11 @@ "homepage": "https://github.com/decrypto-org/TrustIsRisk.js#readme", "devDependencies": { "babel-eslint": "^7.2.3", - "eslint": "^3.19.0", + "eslint": "^8.40.0", "eslint-plugin-flowtype": "^2.50.3", "flow-bin": "^0.45.0", "flow-remove-types": "^1.2.3", - "mocha": "^8.2.1", + "mocha": "^10.2.0", "should": "^11.2.1", "should-sinon": "0.0.5", "sinon": "^5.1.1" From 5ee8448c447f5a7581d3d3aff9104eaff2bd5e62 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 17 May 2023 17:23:38 +0100 Subject: [PATCH 535/540] Update from babel-eslint to @babel/eslint-parser --- .eslintrc.json | 2 +- package-lock.json | 2108 ++++++++++++++++++++++++++++++--------------- package.json | 2 +- 3 files changed, 1424 insertions(+), 688 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2d511eb..3b20bf9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,5 @@ { - "parser": "babel-eslint", + "parser": "@babel/eslint-parser", "plugins": [ "eslint-plugin-flowtype" ], diff --git a/package-lock.json b/package-lock.json index 808b696..82642c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "sorted-set": "^0.3.0" }, "devDependencies": { - "babel-eslint": "^7.2.3", + "@babel/eslint-parser": "^7.21.8", "eslint": "^8.40.0", "eslint-plugin-flowtype": "^2.50.3", "flow-bin": "^0.45.0", @@ -27,6 +27,349 @@ "sinon": "^5.1.1" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", + "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "dev": true, + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", + "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", + "dev": true, + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.21.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", + "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.21.5", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.21.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", + "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", + "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.21.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", + "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "dev": true, + "peer": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -42,6 +385,18 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", @@ -74,23 +429,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -106,12 +444,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@eslint/js": { "version": "8.40.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", @@ -135,29 +467,6 @@ "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -177,6 +486,75 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true, + "peer": true + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "dependencies": { + "eslint-scope": "5.1.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -294,21 +672,25 @@ } }, "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/anymatch": { @@ -336,81 +718,6 @@ "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", "dev": true }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", - "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "node_modules/babel-eslint": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", - "integrity": "sha512-i2yKOhjgwUbUrJ8oJm6QqRzltIoFahGNPZ0HF22lUN4H1DW03JQyJm7WSv+I1LURQWjDNhVqFo04acYa07rhOQ==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.22.0", - "babel-traverse": "^6.23.1", - "babel-types": "^6.23.0", - "babylon": "^6.17.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", - "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "node_modules/babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", - "dev": true, - "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, "node_modules/babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", @@ -847,6 +1154,35 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/bufio": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", @@ -876,20 +1212,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001488", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz", + "integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true + }, "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "peer": true, "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/chokidar": { @@ -942,44 +1298,22 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "peer": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true }, "node_modules/concat-map": { "version": "0.0.1", @@ -987,13 +1321,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true, - "hasInstallScript": true + "peer": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -1010,12 +1343,20 @@ } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decamelize": { @@ -1057,6 +1398,13 @@ "node": ">=6.0.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.4.397", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.397.tgz", + "integrity": "sha512-jwnPxhh350Q/aMatQia31KAIQdhEsYS0fFZ0BQQlN9tfvOEwShu6ZNwI4kL/xBabjcB/nTy6lSt17kNIluJZ8Q==", + "dev": true, + "peer": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1077,6 +1425,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "peer": true, "engines": { "node": ">=0.8.0" } @@ -1154,40 +1503,25 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=8.0.0" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/eslint/node_modules/ansi-styles": { @@ -1221,23 +1555,24 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "color-name": "~1.1.4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=7.0.0" } }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1250,6 +1585,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/eslint/node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -1265,20 +1637,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { "node": ">=8" } @@ -1312,6 +1675,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -1324,6 +1699,15 @@ "node": ">=0.10" } }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -1336,7 +1720,7 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { + "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", @@ -1345,6 +1729,15 @@ "node": ">=4.0" } }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -1495,6 +1888,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1537,12 +1940,13 @@ } }, "node_modules/globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/graph-theory-ford-fulkerson": { @@ -1556,25 +1960,13 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/he": { @@ -1636,15 +2028,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1749,10 +2132,11 @@ } }, "node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "peer": true }, "node_modules/js-yaml": { "version": "4.1.0", @@ -1766,6 +2150,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1778,6 +2175,19 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", @@ -1874,15 +2284,42 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=8" } }, "node_modules/log-symbols/node_modules/supports-color": { @@ -1903,16 +2340,14 @@ "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "peer": true, "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" + "yallist": "^3.0.2" } }, "node_modules/minimatch": { @@ -1976,29 +2411,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -2011,6 +2423,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/mocha/node_modules/minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -2045,9 +2466,9 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/nanoid": { @@ -2100,6 +2521,13 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true, + "peer": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2213,6 +2641,13 @@ "isarray": "0.0.1" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, + "peer": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2284,12 +2719,6 @@ "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2383,6 +2812,15 @@ "deprecated": "This package has been deprecated in favour of @sinonjs/samsam", "dev": true }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -2500,27 +2938,6 @@ "node": ">=0.3.1" } }, - "node_modules/sinon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/sinon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/sorted-set": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sorted-set/-/sorted-set-0.3.0.tgz", @@ -2543,16 +2960,7 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -2564,18 +2972,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2589,12 +2985,15 @@ } }, "node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=4" } }, "node_modules/text-table": { @@ -2604,12 +3003,13 @@ "dev": true }, "node_modules/to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/to-regex-range": { @@ -2657,6 +3057,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2719,15 +3150,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2743,18 +3165,24 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">=8" + "node": ">=7.0.0" } }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -2770,6 +3198,13 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "peer": true + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -2826,6 +3261,266 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "peer": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "peer": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", + "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "dev": true, + "peer": true + }, + "@babel/core": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "dev": true, + "peer": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + } + }, + "@babel/eslint-parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", + "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", + "dev": true, + "requires": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + } + }, + "@babel/generator": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.21.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", + "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", + "dev": true, + "peer": true, + "requires": { + "@babel/compat-data": "^7.21.5", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "dev": true, + "peer": true + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "peer": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.21.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", + "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", + "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.21.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true, + "peer": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "peer": true + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true, + "peer": true + }, + "@babel/helpers": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", + "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "dev": true, + "peer": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "dev": true, + "peer": true + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2833,6 +3528,14 @@ "dev": true, "requires": { "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true + } } }, "@eslint-community/regexpp": { @@ -2858,15 +3561,6 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -2875,12 +3569,6 @@ "requires": { "type-fest": "^0.20.2" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, @@ -2892,30 +3580,13 @@ }, "@humanwhocodes/config-array": { "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" } }, "@humanwhocodes/module-importer": { @@ -2930,6 +3601,68 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "peer": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "peer": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "peer": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "peer": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "peer": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true, + "peer": true + } + } + }, + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "requires": { + "eslint-scope": "5.1.1" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3023,16 +3756,20 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^1.9.0" + } }, "anymatch": { "version": "3.1.3", @@ -3056,77 +3793,6 @@ "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-eslint": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", - "integrity": "sha512-i2yKOhjgwUbUrJ8oJm6QqRzltIoFahGNPZ0HF22lUN4H1DW03JQyJm7WSv+I1LURQWjDNhVqFo04acYa07rhOQ==", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "babel-traverse": "^6.23.1", - "babel-types": "^6.23.0", - "babylon": "^6.17.0" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", @@ -3399,6 +4065,19 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "peer": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, "bufio": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", @@ -3416,17 +4095,23 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001488", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz", + "integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==", + "dev": true, + "peer": true + }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "peer": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chokidar": { @@ -3465,39 +4150,24 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "peer": true, "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true }, "concat-map": { "version": "0.0.1", @@ -3505,11 +4175,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "dev": true + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "peer": true }, "cross-spawn": { "version": "7.0.3", @@ -3523,12 +4194,12 @@ } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, "decamelize": { @@ -3558,6 +4229,13 @@ "esutils": "^2.0.2" } }, + "electron-to-chromium": { + "version": "1.4.397", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.397.tgz", + "integrity": "sha512-jwnPxhh350Q/aMatQia31KAIQdhEsYS0fFZ0BQQlN9tfvOEwShu6ZNwI4kL/xBabjcB/nTy6lSt17kNIluJZ8Q==", + "dev": true, + "peer": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3574,7 +4252,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "dev": true, + "peer": true }, "eslint": { "version": "8.40.0", @@ -3624,12 +4303,6 @@ "text-table": "^0.2.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -3649,21 +4322,49 @@ "supports-color": "^7.1.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ms": "2.1.2" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, "globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -3673,21 +4374,12 @@ "type-fest": "^0.20.2" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3709,19 +4401,19 @@ } }, "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" } }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { @@ -3733,6 +4425,14 @@ "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true + } } }, "esquery": { @@ -3742,6 +4442,14 @@ "dev": true, "requires": { "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "esrecurse": { @@ -3751,12 +4459,20 @@ "dev": true, "requires": { "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { @@ -3871,6 +4587,13 @@ "dev": true, "optional": true }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "peer": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3901,10 +4624,11 @@ } }, "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "peer": true }, "graph-theory-ford-fulkerson": { "version": "1.0.0", @@ -3917,19 +4641,10 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "he": { @@ -3976,15 +4691,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4058,10 +4764,11 @@ "dev": true }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "peer": true }, "js-yaml": { "version": "4.1.0", @@ -4072,6 +4779,13 @@ "argparse": "^2.0.1" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "peer": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4084,6 +4798,13 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "peer": true + }, "just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", @@ -4161,6 +4882,27 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4178,13 +4920,14 @@ "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "peer": true, "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "yallist": "^3.0.2" } }, "minimatch": { @@ -4234,29 +4977,18 @@ "balanced-match": "^1.0.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -4284,9 +5016,9 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "nanoid": { @@ -4335,6 +5067,13 @@ } } }, + "node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true, + "peer": true + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4418,6 +5157,13 @@ "isarray": "0.0.1" } }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, + "peer": true + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -4460,12 +5206,6 @@ "picomatch": "^2.2.1" } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4514,6 +5254,12 @@ "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -4619,21 +5365,6 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -4651,32 +5382,15 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" } }, "strip-json-comments": { @@ -4686,10 +5400,13 @@ "dev": true }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } }, "text-table": { "version": "0.2.0", @@ -4698,10 +5415,11 @@ "dev": true }, "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "peer": true }, "to-regex-range": { "version": "5.0.1", @@ -4733,6 +5451,17 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "peer": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4780,12 +5509,6 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4795,14 +5518,20 @@ "color-convert": "^2.0.1" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "color-name": "~1.1.4" } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, @@ -4818,6 +5547,13 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "peer": true + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/package.json b/package.json index ce895cd..8bae9fa 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ }, "homepage": "https://github.com/decrypto-org/TrustIsRisk.js#readme", "devDependencies": { - "babel-eslint": "^7.2.3", + "@babel/eslint-parser": "^7.21.8", "eslint": "^8.40.0", "eslint-plugin-flowtype": "^2.50.3", "flow-bin": "^0.45.0", From 347adcb8efe263f8b72206d1f9339b13f7811446 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 5 Jun 2023 20:23:43 +0300 Subject: [PATCH 536/540] Remove wallets when done --- test/full_node.js | 3 +++ test/helpers.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/test/full_node.js b/test/full_node.js index b72ac10..a23b4f9 100644 --- a/test/full_node.js +++ b/test/full_node.js @@ -65,6 +65,7 @@ describe("FullNode", () => { }); afterEach("tear node down", async () => { + await testHelpers.removeWallet(walletDB, "wallet"); node.stopSync(); await node.tearDown(); }); @@ -93,6 +94,8 @@ describe("FullNode", () => { await testHelpers.flushEvents(); node.trust.addTX.should.have.been.calledOnce(); + await testHelpers.removeWallet(walletDB, "sender"); + await testHelpers.removeWallet(walletDB, "receiver"); }); describe("with the nobodyLikesFrank.json example", () => { diff --git a/test/helpers.js b/test/helpers.js index f50f4b7..3edcc57 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -19,6 +19,10 @@ var testHelpers = { return walletDB.create(options); }, + removeWallet: async (walletDB, id) => { + walletDB.remove(id); + }, + mineBlock: async (node, rewardAddress) => { var block = await node.miner.mineBlock(node.chain.tip, rewardAddress); await node.chain.add(block); From 738388bf225b2a0fe1584a292201ad5bc310477b Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Mon, 21 Aug 2023 15:15:00 +0100 Subject: [PATCH 537/540] Update --- package-lock.json | 884 ++++++++++++++++++++++------------------------ 1 file changed, 423 insertions(+), 461 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82642c3..d4b6e49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,15 @@ "sinon": "^5.1.1" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -42,22 +51,23 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", + "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", "dev": true, "peer": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.10", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.21.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", - "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, "peer": true, "engines": { @@ -65,27 +75,27 @@ } }, "node_modules/@babel/core": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", - "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", + "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", "dev": true, "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.10", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.10", + "@babel/parser": "^7.22.10", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -96,31 +106,31 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", - "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.10.tgz", + "integrity": "sha512-0J8DNPRXQRLeR9rPaUMM3fA+RbixjnVLe/MRMYCkp3hzgsSuxCHQ8NN8xQG1wIHKJ4a1DTROTvFJdW+B5/eOsg==", "dev": true, "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || >=14.0.0" }, "peerDependencies": { - "@babel/core": ">=7.11.0", + "@babel/core": "^7.11.0", "eslint": "^7.5.0 || ^8.0.0" } }, "node_modules/@babel/generator": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", - "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", + "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.21.5", + "@babel/types": "^7.22.10", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -130,29 +140,26 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", - "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", + "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", "dev": true, "peer": true, "dependencies": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", - "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true, "peer": true, "engines": { @@ -160,95 +167,95 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dev": true, "peer": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", - "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", + "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", - "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, "peer": true, "engines": { @@ -256,9 +263,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "dev": true, "peer": true, "engines": { @@ -266,9 +273,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "peer": true, "engines": { @@ -276,29 +283,29 @@ } }, "node_modules/@babel/helpers": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", - "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", + "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", "dev": true, "peer": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", + "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -306,9 +313,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", - "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", + "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", "dev": true, "peer": true, "bin": { @@ -319,35 +326,35 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, "peer": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", - "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", + "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", "dev": true, "peer": true, "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.10", + "@babel/types": "^7.22.10", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -356,14 +363,14 @@ } }, "node_modules/@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", + "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -386,9 +393,9 @@ } }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -398,23 +405,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -430,9 +437,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -445,18 +452,18 @@ } }, "node_modules/@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -502,9 +509,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "peer": true, "engines": { @@ -529,23 +536,16 @@ "peer": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "peer": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true, - "peer": true - }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -626,9 +626,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1155,9 +1155,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -1167,14 +1167,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" }, "bin": { "browserslist": "cli.js" @@ -1213,9 +1217,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001488", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz", - "integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==", + "version": "1.0.30001522", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz", + "integrity": "sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==", "dev": true, "funding": [ { @@ -1399,9 +1403,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.397", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.397.tgz", - "integrity": "sha512-jwnPxhh350Q/aMatQia31KAIQdhEsYS0fFZ0BQQlN9tfvOEwShu6ZNwI4kL/xBabjcB/nTy6lSt17kNIluJZ8Q==", + "version": "1.4.496", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz", + "integrity": "sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==", "dev": true, "peer": true }, @@ -1431,27 +1435,27 @@ } }, "node_modules/eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -1459,22 +1463,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -1586,9 +1587,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -1602,9 +1603,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1623,9 +1624,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1659,12 +1660,12 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -1676,9 +1677,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1954,10 +1955,10 @@ "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", "integrity": "sha512-HntwL+yfi+2uduSpn/vjdlH4uGmpDgce86/zbk0t88pUGApl8cFhjTrbAFrJzEu/JQSeoa6SgtWsazIt5Ww+Nw==" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has-flag": { @@ -2121,16 +2122,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2522,9 +2513,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true, "peer": true }, @@ -2547,17 +2538,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -2813,9 +2804,9 @@ "dev": true }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3118,15 +3109,6 @@ "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -3261,6 +3243,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -3273,251 +3261,249 @@ } }, "@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", + "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", "dev": true, "peer": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.10", + "chalk": "^2.4.2" } }, "@babel/compat-data": { - "version": "7.21.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", - "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, "peer": true }, "@babel/core": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", - "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", + "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", "dev": true, "peer": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.10", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.10", + "@babel/parser": "^7.22.10", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", - "semver": "^6.3.0" + "semver": "^6.3.1" } }, "@babel/eslint-parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", - "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.10.tgz", + "integrity": "sha512-0J8DNPRXQRLeR9rPaUMM3fA+RbixjnVLe/MRMYCkp3hzgsSuxCHQ8NN8xQG1wIHKJ4a1DTROTvFJdW+B5/eOsg==", "dev": true, "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" + "semver": "^6.3.1" } }, "@babel/generator": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", - "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", + "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.21.5", + "@babel/types": "^7.22.10", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" } }, "@babel/helper-compilation-targets": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", - "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", + "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", "dev": true, "peer": true, "requires": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" } }, "@babel/helper-environment-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", - "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true, "peer": true }, "@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dev": true, "peer": true, "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-transforms": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", - "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", + "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" } }, "@babel/helper-simple-access": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", - "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.21.5" + "@babel/types": "^7.22.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, "peer": true }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "dev": true, "peer": true }, "@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "peer": true }, "@babel/helpers": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", - "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", + "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", "dev": true, "peer": true, "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10" } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", + "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", - "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", + "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", "dev": true, "peer": true }, "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, "peer": true, "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" } }, "@babel/traverse": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", - "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", + "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", "dev": true, "peer": true, "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.10", + "@babel/types": "^7.22.10", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", + "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", "dev": true, "peer": true, "requires": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" } }, @@ -3531,28 +3517,28 @@ }, "dependencies": { "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true } } }, "@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true }, "@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -3562,9 +3548,9 @@ }, "dependencies": { "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -3573,15 +3559,15 @@ } }, "@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -3614,9 +3600,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "peer": true }, @@ -3635,23 +3621,14 @@ "peer": true }, "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "peer": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true, - "peer": true - } + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@nicolo-ribaudo/eslint-scope-5-internals": { @@ -3725,9 +3702,9 @@ "dev": true }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -4066,16 +4043,16 @@ "dev": true }, "browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "peer": true, "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" } }, "bufio": { @@ -4096,9 +4073,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001488", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz", - "integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==", + "version": "1.0.30001522", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz", + "integrity": "sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==", "dev": true, "peer": true }, @@ -4230,9 +4207,9 @@ } }, "electron-to-chromium": { - "version": "1.4.397", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.397.tgz", - "integrity": "sha512-jwnPxhh350Q/aMatQia31KAIQdhEsYS0fFZ0BQQlN9tfvOEwShu6ZNwI4kL/xBabjcB/nTy6lSt17kNIluJZ8Q==", + "version": "1.4.496", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz", + "integrity": "sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==", "dev": true, "peer": true }, @@ -4256,27 +4233,27 @@ "peer": true }, "eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4284,22 +4261,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -4344,9 +4318,9 @@ "dev": true }, "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -4354,9 +4328,9 @@ } }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "estraverse": { @@ -4366,9 +4340,9 @@ "dev": true }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -4417,20 +4391,20 @@ "dev": true }, "espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "dependencies": { "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true } } @@ -4635,10 +4609,10 @@ "resolved": "https://registry.npmjs.org/graph-theory-ford-fulkerson/-/graph-theory-ford-fulkerson-1.0.0.tgz", "integrity": "sha512-HntwL+yfi+2uduSpn/vjdlH4uGmpDgce86/zbk0t88pUGApl8cFhjTrbAFrJzEu/JQSeoa6SgtWsazIt5Ww+Nw==" }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has-flag": { @@ -4757,12 +4731,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5068,9 +5036,9 @@ } }, "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true, "peer": true }, @@ -5090,17 +5058,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { @@ -5255,9 +5223,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "serialize-javascript": { @@ -5486,12 +5454,6 @@ "isexe": "^2.0.0" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", From 31e8e6a18aa7ca3837590bcc00ab26c5594869db Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 7 Nov 2023 09:39:27 +0000 Subject: [PATCH 538/540] Update --- package-lock.json | 661 +++++++++++++++++++++++++--------------------- 1 file changed, 354 insertions(+), 307 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4b6e49..90a7cab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,13 +51,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "peer": true, "dependencies": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" }, "engines": { @@ -65,9 +65,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", "dev": true, "peer": true, "engines": { @@ -75,26 +75,26 @@ } }, "node_modules/@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", "dev": true, "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -106,9 +106,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.10.tgz", - "integrity": "sha512-0J8DNPRXQRLeR9rPaUMM3fA+RbixjnVLe/MRMYCkp3hzgsSuxCHQ8NN8xQG1wIHKJ4a1DTROTvFJdW+B5/eOsg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz", + "integrity": "sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==", "dev": true, "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -124,13 +124,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -140,14 +140,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "peer": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -157,9 +157,9 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "peer": true, "engines": { @@ -167,14 +167,14 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "peer": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -194,30 +194,30 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -263,9 +263,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "peer": true, "engines": { @@ -273,9 +273,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "peer": true, "engines": { @@ -283,28 +283,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "dev": true, "peer": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -313,9 +313,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "peer": true, "bin": { @@ -326,35 +326,35 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "peer": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "peer": true, "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -363,14 +363,14 @@ } }, "node_modules/@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -405,18 +405,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -437,9 +437,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -452,21 +452,21 @@ } }, "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -488,9 +488,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@jridgewell/gen-mapping": { @@ -536,9 +536,9 @@ "peer": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "peer": true, "dependencies": { @@ -625,10 +625,16 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1155,9 +1161,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "funding": [ { @@ -1175,10 +1181,10 @@ ], "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -1217,9 +1223,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001522", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz", - "integrity": "sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==", + "version": "1.0.30001561", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", + "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", "dev": true, "funding": [ { @@ -1326,9 +1332,9 @@ "dev": true }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "peer": true }, @@ -1403,9 +1409,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.496", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz", - "integrity": "sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==", + "version": "1.4.577", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.577.tgz", + "integrity": "sha512-/5xHPH6f00SxhHw6052r+5S1xO7gHNc89hV7tqlvnStvKbSrDqc/u6AlwPvVWWNj+s4/KL6T6y8ih+nOY0qYNA==", "dev": true, "peer": true }, @@ -1435,18 +1441,19 @@ } }, "node_modules/eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -1624,9 +1631,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1825,22 +1832,23 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "node_modules/flow-bin": { @@ -1876,9 +1884,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -2154,6 +2162,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2185,6 +2199,15 @@ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2661,9 +2684,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -2909,6 +2932,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.1.1.tgz", "integrity": "sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw==", + "deprecated": "16.1.1", "dev": true, "dependencies": { "@sinonjs/formatio": "^2.0.0", @@ -3049,9 +3073,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -3261,51 +3285,51 @@ } }, "@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "peer": true, "requires": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" } }, "@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", "dev": true, "peer": true }, "@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", "dev": true, "peer": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" } }, "@babel/eslint-parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.10.tgz", - "integrity": "sha512-0J8DNPRXQRLeR9rPaUMM3fA+RbixjnVLe/MRMYCkp3hzgsSuxCHQ8NN8xQG1wIHKJ4a1DTROTvFJdW+B5/eOsg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz", + "integrity": "sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==", "dev": true, "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -3314,48 +3338,48 @@ } }, "@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" } }, "@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "peer": true, "requires": { "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "peer": true }, "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "peer": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { @@ -3369,27 +3393,27 @@ } }, "@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" } }, "@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", "dev": true, "peer": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-simple-access": { @@ -3420,90 +3444,90 @@ "peer": true }, "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "peer": true }, "@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "peer": true }, "@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "dev": true, "peer": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" } }, "@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "peer": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "peer": true }, "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "peer": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "peer": true, "requires": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "peer": true, "requires": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -3525,15 +3549,15 @@ } }, "@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -3548,9 +3572,9 @@ }, "dependencies": { "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -3559,18 +3583,18 @@ } }, "@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" } @@ -3582,9 +3606,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "@jridgewell/gen-mapping": { @@ -3621,9 +3645,9 @@ "peer": true }, "@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "peer": true, "requires": { @@ -3701,10 +3725,16 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true }, "acorn-jsx": { @@ -4043,16 +4073,16 @@ "dev": true }, "browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "peer": true, "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" } }, "bufio": { @@ -4073,9 +4103,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001522", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz", - "integrity": "sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==", + "version": "1.0.30001561", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", + "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", "dev": true, "peer": true }, @@ -4153,9 +4183,9 @@ "dev": true }, "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "peer": true }, @@ -4207,9 +4237,9 @@ } }, "electron-to-chromium": { - "version": "1.4.496", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz", - "integrity": "sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==", + "version": "1.4.577", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.577.tgz", + "integrity": "sha512-/5xHPH6f00SxhHw6052r+5S1xO7gHNc89hV7tqlvnStvKbSrDqc/u6AlwPvVWWNj+s4/KL6T6y8ih+nOY0qYNA==", "dev": true, "peer": true }, @@ -4233,18 +4263,19 @@ "peer": true }, "eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4340,9 +4371,9 @@ "dev": true }, "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -4517,19 +4548,20 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "flow-bin": { @@ -4555,9 +4587,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -4754,6 +4786,12 @@ "dev": true, "peer": true }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4779,6 +4817,15 @@ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5145,9 +5192,9 @@ "dev": true }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "queue-microtask": { @@ -5420,9 +5467,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "peer": true, "requires": { From 748020286230e11abebc0f899c81261e19289d41 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 14 Nov 2023 09:50:59 +0000 Subject: [PATCH 539/540] Update --- package-lock.json | 170 +++++++++++++++++++++++----------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/package-lock.json b/package-lock.json index 90a7cab..618df46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,9 +65,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", - "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", "dev": true, "peer": true, "engines": { @@ -75,22 +75,22 @@ } }, "node_modules/@babel/core": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", - "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", "dev": true, "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", + "@babel/generator": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.0", + "@babel/parser": "^7.23.3", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -106,9 +106,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz", - "integrity": "sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz", + "integrity": "sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw==", "dev": true, "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -124,13 +124,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.23.0", + "@babel/types": "^7.23.3", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -207,9 +207,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", - "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "peer": true, "dependencies": { @@ -313,9 +313,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", + "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", "dev": true, "peer": true, "bin": { @@ -341,20 +341,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", "dev": true, "peer": true, "dependencies": { "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", + "@babel/generator": "^7.23.3", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -363,9 +363,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", + "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", "dev": true, "peer": true, "dependencies": { @@ -1223,9 +1223,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001561", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", - "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", + "version": "1.0.30001562", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001562.tgz", + "integrity": "sha512-kfte3Hym//51EdX4239i+Rmp20EsLIYGdPkERegTgU19hQWCRhsRFGKHTliUlsry53tv17K7n077Kqa0WJU4ng==", "dev": true, "funding": [ { @@ -1409,9 +1409,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.577", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.577.tgz", - "integrity": "sha512-/5xHPH6f00SxhHw6052r+5S1xO7gHNc89hV7tqlvnStvKbSrDqc/u6AlwPvVWWNj+s4/KL6T6y8ih+nOY0qYNA==", + "version": "1.4.582", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.582.tgz", + "integrity": "sha512-89o0MGoocwYbzqUUjc+VNpeOFSOK9nIdC5wY4N+PVUarUK0MtjyTjks75AZS2bW4Kl8MdewdFsWaH0jLy+JNoA==", "dev": true, "peer": true }, @@ -1832,9 +1832,9 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", @@ -1842,7 +1842,7 @@ "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { @@ -3296,29 +3296,29 @@ } }, "@babel/compat-data": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", - "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", "dev": true, "peer": true }, "@babel/core": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", - "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", "dev": true, "peer": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", + "@babel/generator": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.0", + "@babel/parser": "^7.23.3", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -3327,9 +3327,9 @@ } }, "@babel/eslint-parser": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz", - "integrity": "sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz", + "integrity": "sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw==", "dev": true, "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -3338,13 +3338,13 @@ } }, "@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.23.0", + "@babel/types": "^7.23.3", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -3403,9 +3403,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", - "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "peer": true, "requires": { @@ -3482,9 +3482,9 @@ } }, "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", + "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", "dev": true, "peer": true }, @@ -3501,28 +3501,28 @@ } }, "@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", "dev": true, "peer": true, "requires": { "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", + "@babel/generator": "^7.23.3", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", + "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", "dev": true, "peer": true, "requires": { @@ -4103,9 +4103,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001561", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", - "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", + "version": "1.0.30001562", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001562.tgz", + "integrity": "sha512-kfte3Hym//51EdX4239i+Rmp20EsLIYGdPkERegTgU19hQWCRhsRFGKHTliUlsry53tv17K7n077Kqa0WJU4ng==", "dev": true, "peer": true }, @@ -4237,9 +4237,9 @@ } }, "electron-to-chromium": { - "version": "1.4.577", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.577.tgz", - "integrity": "sha512-/5xHPH6f00SxhHw6052r+5S1xO7gHNc89hV7tqlvnStvKbSrDqc/u6AlwPvVWWNj+s4/KL6T6y8ih+nOY0qYNA==", + "version": "1.4.582", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.582.tgz", + "integrity": "sha512-89o0MGoocwYbzqUUjc+VNpeOFSOK9nIdC5wY4N+PVUarUK0MtjyTjks75AZS2bW4Kl8MdewdFsWaH0jLy+JNoA==", "dev": true, "peer": true }, @@ -4548,9 +4548,9 @@ "dev": true }, "flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { "flatted": "^3.2.9", From 4b92a15ab240c8c9dbd33a06506829c0482077b7 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Wed, 29 Jan 2025 15:54:40 +0000 Subject: [PATCH 540/540] Start working on making spv work --- package-lock.json | 39 +++++++++++++++++++++++++++++++++++++++ package.json | 1 + test/spv_node.js | 24 +++++++++++++++++------- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 618df46..65910ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "bcoin": "git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", "bcrypto": "^5.3.0", "graph-theory-ford-fulkerson": "^1.0.0", + "p-event": "^5.0.1", "sorted-set": "^0.3.0" }, "devDependencies": { @@ -2577,6 +2578,20 @@ "node": ">= 0.8.0" } }, + "node_modules/p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dependencies": { + "p-timeout": "^5.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2607,6 +2622,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5118,6 +5144,14 @@ "type-check": "^0.4.0" } }, + "p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "requires": { + "p-timeout": "^5.0.2" + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5136,6 +5170,11 @@ "p-limit": "^3.0.2" } }, + "p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", diff --git a/package.json b/package.json index 8bae9fa..72288f8 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "bcoin": "git+https://github.com/bcoin-org/bcoin.git#semver:^2.1.2", "bcrypto": "^5.3.0", "graph-theory-ford-fulkerson": "^1.0.0", + "p-event": "^5.0.1", "sorted-set": "^0.3.0" } } diff --git a/test/spv_node.js b/test/spv_node.js index 706bd19..88f64bb 100644 --- a/test/spv_node.js +++ b/test/spv_node.js @@ -23,9 +23,21 @@ var fixtures = require("./fixtures"); require("should-sinon"); const COIN = consensus.COIN; + const regtest = bcoin.Network.get().toString(); +const spvNet1 = new bcoin.Network(bcoin.network); +const spvNet2 = new bcoin.Network('regtest'); +const minerNet = new bcoin.Network('regtest'); +console.log(spvNet1.port, spvNet2.port, minerNet.port) + +describe.only("lala", () => { +}); + describe("SPVNode", () => { + let spvNet1 = null; + let spvNet2 = null; + let minerNet = null; var spvNode1 = null; var spvNode2 = null; var miner = null; @@ -42,15 +54,13 @@ describe("SPVNode", () => { beforeEach("create SPV nodes", async () => { spvNode1 = new Trust.SPVNode({ - network: regtest, - httpPort: 48445, + network: spvNet1, passphrase: "secret", nodes: ["127.0.0.1:48448"] }); spvNode2 = new Trust.SPVNode({ - network: regtest, - httpPort: 48446, + network: spvNet2, passphrase: "secret", nodes: ["127.0.0.1:48448"] }); @@ -83,8 +93,7 @@ describe("SPVNode", () => { beforeEach("create full node", async () => { miner = new Trust.FullNode({ - network: regtest, - port: 48448, + network: minerNet, bip37: true, //logConsole: true, //logLevel: "debug", @@ -246,7 +255,7 @@ describe("SPVNode", () => { miner.trust.addTX.should.have.been.calledThrice(); }); - describe.skip("with the nobodyLikesFrank.json example", () => { + describe("with the nobodyLikesFrank.json example", () => { var minerNames = { "alice": "alice", "bob": "bob", @@ -406,6 +415,7 @@ describe("SPVNode", () => { node.origin.sendTX(tx); await watcher.origin.waitForTX(tx); + // TODO: below gets stuck await watcher.dest.waitForTX(tx); prevout[origin] = {hash: tx.hash(), index: 1};